@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
@@ -10,7 +10,8 @@
10
10
  import type { ReactNode } from 'react'
11
11
  import { AlertTriangle, ChevronLeft, ChevronRight, Loader2 } from 'lucide-react'
12
12
  import { StatusBadge, type StatusBadgeTone } from '../ui/StatusBadge.js'
13
- import type { FormFieldType, FormStatus } from '../../lib/forms-service.js'
13
+ import { CountChip } from '../ui/CountChip.js'
14
+ import type { EntryCounts, FormFieldType, FormStatus } from '../../lib/forms-service.js'
14
15
 
15
16
  // ─── Field-type badges ─────────────────────────────────────────────────────
16
17
 
@@ -28,7 +29,7 @@ function fieldTypeTone(type: FormFieldType): string {
28
29
  case 'select':
29
30
  case 'multiselect':
30
31
  case 'radio':
31
- return 'bg-warning/10 text-warning'
32
+ return 'bg-warn-l text-warning'
32
33
  case 'checkbox':
33
34
  case 'consent':
34
35
  return 'bg-success/10 text-success'
@@ -95,29 +96,44 @@ export function UnreadBadge({ count, className = '' }: { count: number; classNam
95
96
  )
96
97
  }
97
98
 
98
- // ─── Summary chips ───────────────────────────────────────────────────────
99
+ // ─── Entry count chips ───────────────────────────────────────────────────
99
100
 
100
- export function SummaryChip({
101
- value,
102
- label,
103
- tone = 'neutral',
101
+ /** The inbox status filters a count chip can switch on. */
102
+ type EntryChipFilter = 'unread' | 'starred'
103
+
104
+ /**
105
+ * The inbox's header counts (Inbox.html `.stat-pills`), shared by All
106
+ * Entries and each form's entries. "unread" and "starred" are toggles for
107
+ * the matching status filter, selected while it is on; a second click goes
108
+ * back to all entries. "this week" is repo-only.
109
+ */
110
+ export function EntryCountChips({
111
+ counts,
112
+ filter,
113
+ onFilter,
104
114
  }: {
105
- value: ReactNode
106
- label: string
107
- tone?: 'neutral' | 'success' | 'warning' | 'destructive'
115
+ counts: Pick<EntryCounts, 'total' | 'unread' | 'starred' | 'thisWeek'>
116
+ /** The view's current status filter. */
117
+ filter: string
118
+ onFilter: (next: 'all' | EntryChipFilter) => void
108
119
  }) {
109
- const valueCls =
110
- tone === 'success'
111
- ? 'text-success'
112
- : tone === 'warning'
113
- ? 'text-warning'
114
- : tone === 'destructive'
115
- ? 'text-destructive'
116
- : 'text-foreground'
120
+ const toggle = (chip: EntryChipFilter) => () => onFilter(filter === chip ? 'all' : chip)
117
121
  return (
118
- <div className="border-border bg-card flex items-baseline gap-1.5 rounded-lg border px-3 py-2">
119
- <span className={`text-base font-medium tabular-nums ${valueCls}`}>{value}</span>
120
- <span className="text-muted-foreground text-sm">{label}</span>
122
+ <div className="flex flex-wrap gap-1.5">
123
+ <CountChip n={counts.total} label="total" />
124
+ <CountChip
125
+ n={counts.unread}
126
+ label="unread"
127
+ selected={filter === 'unread'}
128
+ onClick={toggle('unread')}
129
+ />
130
+ <CountChip
131
+ n={counts.starred}
132
+ label="starred"
133
+ selected={filter === 'starred'}
134
+ onClick={toggle('starred')}
135
+ />
136
+ <CountChip n={counts.thisWeek} label="this week" />
121
137
  </div>
122
138
  )
123
139
  }
@@ -10,7 +10,8 @@ import { paletteFor, TAG_COLOR_KEYS, type TagColorKey } from '../posts/badges.js
10
10
  * colored dot so tags don't rely on color alone.
11
11
  *
12
12
  * Both resolve color through the shared `paletteFor` palette so they
13
- * stay consistent with Post Type badges and work in light/dark mode.
13
+ * stay consistent with Post Type badges and work in light/dark mode, and
14
+ * neither wraps its label ("Landing Pages" stays on one line).
14
15
  */
15
16
 
16
17
  export { TAG_COLOR_KEYS }
@@ -49,7 +50,7 @@ export function PageTagChip({
49
50
  type="button"
50
51
  onClick={onToggle}
51
52
  aria-pressed={selected}
52
- className={`focus-visible:ring-ring inline-flex items-center gap-1.5 rounded-full border px-2.5 py-1 text-xs font-medium transition-colors focus:outline-none focus-visible:ring-2 ${
53
+ className={`focus-visible:ring-ring inline-flex items-center gap-1.5 rounded-full border px-2.5 py-1 text-xs font-medium whitespace-nowrap transition-colors focus:outline-none focus-visible:ring-2 ${
53
54
  selected
54
55
  ? `${p.bg} ${p.text} border-transparent ring-1 ${p.ring}`
55
56
  : 'border-border bg-background text-foreground hover:bg-accent'
@@ -68,7 +69,7 @@ export function PageTagPill({ name, color }: { name: string; color: string | nul
68
69
  const p = paletteFor(color)
69
70
  return (
70
71
  <span
71
- className={`inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-xs font-medium ${p.bg} ${p.text}`}
72
+ className={`inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-xs font-medium whitespace-nowrap ${p.bg} ${p.text}`}
72
73
  >
73
74
  <span aria-hidden className={`h-1.5 w-1.5 rounded-full ${tagDotColor(color)}`} />
74
75
  {name}
@@ -76,7 +76,7 @@ function CheckRow({ check }: { check: AuditCheck }) {
76
76
  <span
77
77
  aria-hidden
78
78
  className={`mt-0.5 h-4 w-4 shrink-0 rounded ${
79
- na ? 'bg-muted' : pass ? 'bg-success/15 text-success' : 'bg-warning/15 text-warning'
79
+ na ? 'bg-muted' : pass ? 'bg-success/15 text-success' : 'bg-warn-l text-warning'
80
80
  }`}
81
81
  />
82
82
  <div className="min-w-0">
@@ -122,7 +122,7 @@ function CheckGroup({ result, title }: { result: AuditGroupResult; title: string
122
122
  band === 'good'
123
123
  ? 'bg-success/15 text-success'
124
124
  : band === 'fair'
125
- ? 'bg-warning/15 text-warning'
125
+ ? 'bg-warn-l text-warning'
126
126
  : band === 'poor'
127
127
  ? 'bg-destructive/15 text-destructive'
128
128
  : 'bg-muted text-muted-foreground'
@@ -7,10 +7,10 @@
7
7
  * they see them, so an editor can judge a title and description as a result
8
8
  * rather than as two form fields.
9
9
  *
10
- * The link blue is a literal, not a token: it is Google's result colour, and
11
- * the point of the card is to look like the thing being previewed. Tokenising
12
- * it would let a brand accent repaint it and quietly stop it being a preview.
13
- * `#8ab4f8` is the dark-scheme equivalent.
10
+ * The link blue is Google's result colour (`--serp-link`, with its own dark
11
+ * value), never the accent: the point of the card is to look like the thing
12
+ * being previewed, and letting a brand accent repaint it would quietly stop
13
+ * it being a preview.
14
14
  */
15
15
  export interface SerpPreviewProps {
16
16
  title: string
@@ -29,7 +29,7 @@ export function SerpPreview({ title, url, description }: SerpPreviewProps) {
29
29
  <p className="truncate text-[11px] text-emerald-700 dark:text-emerald-400">
30
30
  {url || 'https://example.com/page'}
31
31
  </p>
32
- <p className="truncate text-[14px] leading-snug text-[#1a0dab] dark:text-[#8ab4f8]">
32
+ <p className="truncate text-[14px] leading-snug text-[var(--serp-link)]">
33
33
  {title || 'Untitled page'}
34
34
  </p>
35
35
  {/* Two lines is what a result gets; more written here simply is not read. */}
@@ -25,7 +25,7 @@ export function gradeMeta(grade: SeoGrade): GradeMeta {
25
25
  case 'good':
26
26
  return { label: 'Good', text: 'text-success', bg: 'bg-success/10', dot: 'bg-success' }
27
27
  case 'fair':
28
- return { label: 'Fair', text: 'text-warning', bg: 'bg-warning/10', dot: 'bg-warning' }
28
+ return { label: 'Fair', text: 'text-warning', bg: 'bg-warn-l', dot: 'bg-warning' }
29
29
  case 'poor':
30
30
  return {
31
31
  label: 'Poor',
@@ -94,7 +94,7 @@ export function severityMeta(severity: SeoSeverity): GradeMeta {
94
94
  dot: 'bg-destructive',
95
95
  }
96
96
  case 'warning':
97
- return { label: 'Warning', text: 'text-warning', bg: 'bg-warning/10', dot: 'bg-warning' }
97
+ return { label: 'Warning', text: 'text-warning', bg: 'bg-warn-l', dot: 'bg-warning' }
98
98
  default:
99
99
  return {
100
100
  label: 'Info',
@@ -7,18 +7,19 @@
7
7
  * feed and the Pages/Posts list tables so an author always looks the
8
8
  * same everywhere.
9
9
  *
10
- * The palette is intentionally raw hex applied via inline style — the
11
- * design-system exception for truly dynamic values (see Dashboard.tsx
12
- * note). All swatches keep ≥4.5:1 contrast with white text.
10
+ * The palette is the `--avatar-*` tokens (tokens.json), applied via inline
11
+ * style because the pick is computed. Every swatch keeps ≥4.5:1 with the
12
+ * white initials; the token drift test enforces it.
13
13
  */
14
14
  export const AVATAR_COLORS = [
15
- '#7C3AED', // purple-600 — 5.70:1 on white
16
- '#E11D48', // rose-600 — 4.70:1 on white
17
- '#047857', // emerald-700 — 5.48:1 (#059669 is 3.77:1)
18
- '#0E7490', // cyan-700 — 5.36:1 (#0891B2 is 3.68:1)
19
- '#92400E', // amber-800 — 7.09:1 (#D97706 is 3.18:1)
20
- '#4F46E5', // indigo-600 — 6.29:1 on white
21
- '#DC2626', // red-600 — 4.83:1 on white
15
+ 'var(--avatar-1)',
16
+ 'var(--avatar-2)',
17
+ 'var(--avatar-3)',
18
+ 'var(--avatar-4)',
19
+ 'var(--avatar-5)',
20
+ 'var(--avatar-6)',
21
+ 'var(--avatar-7)',
22
+ 'var(--avatar-8)',
22
23
  ] as const
23
24
 
24
25
  function hashString(s: string): number {
@@ -6,7 +6,7 @@ const badge = cv('inline-flex items-center rounded-full px-2.5 py-0.5 text-xs fo
6
6
  tone: {
7
7
  neutral: 'bg-muted text-muted-foreground',
8
8
  success: 'bg-success/10 text-success',
9
- warning: 'bg-warning/10 text-warning',
9
+ warning: 'bg-warn-l text-warning',
10
10
  danger: 'bg-destructive/10 text-destructive',
11
11
  info: 'bg-info/10 text-info',
12
12
  primary: 'bg-[var(--primary)]/15 text-[var(--primary)] dark:bg-[var(--primary)]/25',
@@ -0,0 +1,109 @@
1
+ 'use client'
2
+
3
+ import { Fragment, type MouseEvent, type ReactNode } from 'react'
4
+ import { useAdminLinks } from './admin-links.js'
5
+
6
+ export interface BreadcrumbItem {
7
+ label: string
8
+ /**
9
+ * Admin path, e.g. `/posts`. Renders a real link (base path included) and
10
+ * routes plain clicks in-app. Preferred over `href` / `onClick`.
11
+ */
12
+ path?: string
13
+ /** Real URL for the crumb. With `onClick`, plain clicks go to `onClick` instead. */
14
+ href?: string
15
+ /** In-app navigation, e.g. `() => onNavigate('/posts')`. */
16
+ onClick?: () => void
17
+ /** Optional leading icon (13px). */
18
+ icon?: ReactNode
19
+ }
20
+
21
+ export interface BreadcrumbProps {
22
+ /** Ancestors first. The last item is the current page. */
23
+ items: BreadcrumbItem[]
24
+ className?: string
25
+ }
26
+
27
+ // Explicit size and leading: the admin base layer styles `button` at 13px / 1.5.
28
+ const LINK_CLASS =
29
+ 'inline-flex cursor-pointer items-center gap-[5px] border-0 bg-transparent p-0 text-sm2 leading-[normal] font-[450] text-sub no-underline hover:text-acc'
30
+
31
+ function isPlainClick(event: MouseEvent) {
32
+ return event.button === 0 && !event.metaKey && !event.ctrlKey && !event.shiftKey && !event.altKey
33
+ }
34
+
35
+ /**
36
+ * Breadcrumb for second-level screens only (SHELL.md §4 "Breadcrumb rule"):
37
+ * `Dashboard / Section / Screen`. Top-level pages have none. Pass it to
38
+ * `PageHeader` as `breadcrumb`.
39
+ */
40
+ export function Breadcrumb({ items, className = '' }: BreadcrumbProps) {
41
+ const links = useAdminLinks()
42
+ if (items.length === 0) return null
43
+ return (
44
+ <nav aria-label="Breadcrumb" className={className}>
45
+ <ol className="text-sm2 text-faint m-0 flex list-none flex-wrap items-center gap-[7px] p-0 leading-[normal]">
46
+ {items.map((raw, index) => {
47
+ const current = index === items.length - 1
48
+ // Kit crumbs are `<a href>`: a path becomes a real link that still
49
+ // navigates in-app on a plain click.
50
+ const navigate = links.navigate
51
+ const item: BreadcrumbItem = raw.path
52
+ ? {
53
+ ...raw,
54
+ href: links.href(raw.path),
55
+ onClick: navigate ? () => navigate(raw.path!) : raw.onClick,
56
+ }
57
+ : raw
58
+ return (
59
+ <Fragment key={`${index}-${item.label}`}>
60
+ {index > 0 ? (
61
+ <li aria-hidden="true" className="text-faint flex">
62
+ /
63
+ </li>
64
+ ) : null}
65
+ <li className="flex min-w-0 items-center whitespace-nowrap">
66
+ {current ? (
67
+ <span
68
+ aria-current="page"
69
+ className="text-txt inline-flex items-center gap-[5px] font-[550]"
70
+ >
71
+ {item.icon}
72
+ {item.label}
73
+ </span>
74
+ ) : item.href ? (
75
+ <a
76
+ href={item.href}
77
+ className={LINK_CLASS}
78
+ onClick={
79
+ item.onClick
80
+ ? (event) => {
81
+ if (!isPlainClick(event)) return
82
+ event.preventDefault()
83
+ item.onClick?.()
84
+ }
85
+ : undefined
86
+ }
87
+ >
88
+ {item.icon}
89
+ {item.label}
90
+ </a>
91
+ ) : item.onClick ? (
92
+ <button type="button" className={LINK_CLASS} onClick={item.onClick}>
93
+ {item.icon}
94
+ {item.label}
95
+ </button>
96
+ ) : (
97
+ <span className="text-sub inline-flex items-center gap-[5px] font-[450]">
98
+ {item.icon}
99
+ {item.label}
100
+ </span>
101
+ )}
102
+ </li>
103
+ </Fragment>
104
+ )
105
+ })}
106
+ </ol>
107
+ </nav>
108
+ )
109
+ }
@@ -3,26 +3,42 @@
3
3
  import { forwardRef, type ButtonHTMLAttributes, type ReactNode } from 'react'
4
4
  import { cv, type VariantProps } from '../../lib/cv.js'
5
5
 
6
+ // Kit buttons (SHELL.md §5, `.jb-btn` in jobs-view.jsx). Focus uses the
7
+ // admin-wide `:focus-visible` outline (2px --acc, offset 2px).
6
8
  const button = cv(
7
- // Base classes apply to every variant.
8
- 'focus-visible:ring-offset-background inline-flex items-center justify-center gap-2 rounded-[var(--r-control)] font-medium transition-colors duration-[var(--motion-fast)] focus-visible:ring-2 focus-visible:ring-[var(--ring)] focus-visible:ring-offset-2 focus-visible:outline-none disabled:pointer-events-none disabled:opacity-50',
9
+ 'inline-flex shrink-0 cursor-pointer items-center justify-center gap-1.5 border font-semibold whitespace-nowrap disabled:pointer-events-none disabled:opacity-50',
9
10
  {
10
11
  variants: {
11
12
  variant: {
12
- primary: 'bg-[var(--primary)] text-[var(--primary-foreground)] hover:opacity-90',
13
- secondary: 'bg-[var(--secondary)] text-[var(--secondary-foreground)] hover:opacity-80',
14
- danger: 'bg-[var(--destructive)] text-[var(--destructive-foreground)] hover:opacity-90',
15
- ghost: 'bg-transparent text-[var(--foreground)] hover:bg-[var(--accent)]',
16
- outline:
17
- 'border border-[var(--border)] bg-transparent text-[var(--foreground)] hover:bg-[var(--accent)]',
18
- link: 'bg-transparent text-[var(--primary)] underline-offset-4 hover:underline',
13
+ primary: 'border-acc bg-acc text-acc-on hover:brightness-[1.07]',
14
+ /** Card surface with a hairline border. */
15
+ secondary: 'border-bdr bg-card text-txt hover:border-acc-m hover:text-acc',
16
+ /** @deprecated Use `secondary`; kept for existing callers. */
17
+ outline: 'border-bdr bg-card text-txt hover:border-acc-m hover:text-acc',
18
+ ghost: 'text-sub hover:bg-bg hover:text-txt border-transparent bg-transparent',
19
+ /** Outline danger; fills with the error tint on hover. */
20
+ danger:
21
+ 'bg-card text-err hover:bg-err-l border-[color-mix(in_srgb,var(--err)_35%,var(--bdr))]',
22
+ /**
23
+ * AI gradient. Keeps its text label at tablet width, where other
24
+ * header actions collapse to icons (`data-keep-label`); on mobile every
25
+ * header action is a 44px icon, AI included (cms-layouts.css).
26
+ */
27
+ ai: 'text-acc-on border-0 bg-[linear-gradient(135deg,var(--ai1),var(--ai2))] hover:brightness-[1.07] active:translate-y-px',
28
+ /** Row and toolbar icon button: quiet until hovered. */
29
+ icon: 'text-sub hover:border-bdr hover:bg-bg hover:text-txt border-transparent bg-transparent',
30
+ /** Inline text link; ignores the size's height and padding. */
31
+ link: 'text-acc h-auto! border-transparent bg-transparent px-0! underline-offset-4 hover:underline',
19
32
  },
20
33
  size: {
21
- xs: 'h-7 px-2 text-xs',
22
- sm: 'h-8 px-2.5 text-xs',
23
- md: 'h-9 px-4 text-sm',
24
- lg: 'h-10 px-6 text-base',
25
- icon: 'h-9 w-9 p-0',
34
+ /** 34px, 13px text. */
35
+ md: 'rounded-8 text-body h-[34px] px-[13px]',
36
+ /** 28px, 12px text. */
37
+ sm: 'rounded-8 text-meta h-7 px-2.5',
38
+ /** 30×30 row icon button. */
39
+ icon: 'rounded-7 h-[30px] w-[30px] p-0',
40
+ /** 34×34 topbar / header icon button. */
41
+ 'icon-lg': 'rounded-8 h-[34px] w-[34px] p-0',
26
42
  },
27
43
  },
28
44
  defaultVariants: {
@@ -65,6 +81,10 @@ export const Button = forwardRef<HTMLButtonElement, ButtonProps>(function Button
65
81
  ref={ref}
66
82
  disabled={disabled || loading}
67
83
  aria-busy={loading || undefined}
84
+ // The variant decides how a header action collapses at tablet and
85
+ // mobile (responsive.css, `[data-header-actions]`).
86
+ data-variant={variant ?? 'primary'}
87
+ data-keep-label={variant === 'ai' ? '' : undefined}
68
88
  className={button({
69
89
  variant,
70
90
  size,
@@ -73,7 +93,12 @@ export const Button = forwardRef<HTMLButtonElement, ButtonProps>(function Button
73
93
  {...rest}
74
94
  >
75
95
  {loading ? (
76
- <svg className="h-4 w-4 animate-spin" viewBox="0 0 24 24" fill="none" aria-hidden>
96
+ <svg
97
+ className="h-3.5 w-3.5 motion-safe:animate-spin"
98
+ viewBox="0 0 24 24"
99
+ fill="none"
100
+ aria-hidden
101
+ >
77
102
  <circle
78
103
  className="opacity-25"
79
104
  cx="12"
@@ -1,32 +1,31 @@
1
1
  import { forwardRef, type HTMLAttributes, type ReactNode } from 'react'
2
2
  import { cv, type VariantProps } from '../../lib/cv.js'
3
3
 
4
- const card = cv(
5
- 'overflow-hidden rounded-[var(--r)] border border-[var(--bdr)] bg-[var(--card)] text-[var(--txt)]',
6
- {
7
- variants: {
8
- padding: {
9
- none: 'p-0',
10
- /** Stat / compact surfaces (`.dstat`). */
11
- sm: 'px-4 py-3.5',
12
- /** Simple padded panel (`.dcard-b`). */
13
- md: 'px-6 py-4',
14
- lg: 'px-6 py-6',
15
- },
16
- elevation: {
17
- flat: 'shadow-none',
18
- resting: 'shadow-[var(--shd)]',
19
- elevated: 'shadow-[var(--shd2)]',
20
- },
4
+ // Kit card (SHELL.md §7, `.ap-card` / `.ap-ch`): --card, 1px --bdr, radius 12,
5
+ // --shd. Header row 13px 16px with a bottom border; body 14px 16px.
6
+ const card = cv('rounded-12 border-bdr bg-card text-txt overflow-hidden border', {
7
+ variants: {
8
+ padding: {
9
+ none: 'p-0',
10
+ /** Stat / compact surfaces (`.dstat`). */
11
+ sm: 'px-4 py-3.5',
12
+ /** Card body padding (`.ap-cb`). */
13
+ md: 'px-4 py-3.5',
14
+ lg: 'px-6 py-6',
15
+ },
16
+ elevation: {
17
+ flat: 'shadow-none',
18
+ resting: 'shadow-shd',
19
+ elevated: 'shadow-shd2',
21
20
  },
22
- defaultVariants: { padding: 'none', elevation: 'resting' },
23
21
  },
24
- )
22
+ defaultVariants: { padding: 'none', elevation: 'resting' },
23
+ })
25
24
 
26
25
  type CardVariants = VariantProps<typeof card>
27
26
 
28
27
  const INTERACTIVE_CLASS =
29
- 'motion-safe:transition-shadow motion-safe:duration-[var(--motion-fast)] hover:shadow-[var(--shd2)] focus-within:shadow-[var(--shd2)]'
28
+ 'motion-safe:transition-shadow motion-safe:duration-[var(--mo-fast)] hover:shadow-shd2 focus-within:shadow-shd2'
30
29
 
31
30
  export interface CardProps extends HTMLAttributes<HTMLDivElement>, CardVariants {
32
31
  /** Apply hover/focus elevation transitions (e.g. for clickable cards). */
@@ -46,7 +45,7 @@ export const Card = forwardRef<HTMLDivElement, CardProps>(function Card(
46
45
  )
47
46
  })
48
47
 
49
- /** Header slot — `.dcard-h` in the design system handoff. */
48
+ /** Header row (`.ap-ch`): a flex row, gap 10, padding 13px 16px, bottom hairline. */
50
49
  export function CardHeader({
51
50
  className = '',
52
51
  bordered = true,
@@ -55,7 +54,11 @@ export function CardHeader({
55
54
  }: HTMLAttributes<HTMLDivElement> & { bordered?: boolean }) {
56
55
  return (
57
56
  <div
58
- className={[bordered ? 'border-b border-[var(--bdr)] px-6 pt-6 pb-4' : '', className]
57
+ className={[
58
+ 'flex items-center gap-2.5 px-4 py-[13px]',
59
+ bordered ? 'border-bdr border-b' : '',
60
+ className,
61
+ ]
59
62
  .filter(Boolean)
60
63
  .join(' ')}
61
64
  {...rest}
@@ -65,40 +68,40 @@ export function CardHeader({
65
68
  )
66
69
  }
67
70
 
71
+ /** Card heading (`.ap-ch h2`): 13.5px / 650, takes the row's free space. */
68
72
  export function CardTitle({
73
+ as: Heading = 'h3',
69
74
  className = '',
70
75
  children,
71
76
  ...rest
72
- }: HTMLAttributes<HTMLHeadingElement>) {
77
+ }: HTMLAttributes<HTMLHeadingElement> & { as?: 'h2' | 'h3' }) {
73
78
  return (
74
- <h3
75
- className={`text-[length:var(--fs-card)] font-semibold text-[var(--txt)] ${className}`}
79
+ <Heading
80
+ className={`text-card-title text-txt min-w-0 flex-1 leading-[normal] font-[650] ${className}`}
76
81
  {...rest}
77
82
  >
78
83
  {children}
79
- </h3>
84
+ </Heading>
80
85
  )
81
86
  }
82
87
 
88
+ /** Card subline (`.ap-ch p`): 12px --sub, 1px below the title. */
83
89
  export function CardDescription({
84
90
  className = '',
85
91
  children,
86
92
  ...rest
87
93
  }: HTMLAttributes<HTMLParagraphElement>) {
88
94
  return (
89
- <p className={`mt-px text-[length:var(--fs-hint)] text-[var(--muted)] ${className}`} {...rest}>
95
+ <p className={`text-meta text-sub mt-px leading-[normal] ${className}`} {...rest}>
90
96
  {children}
91
97
  </p>
92
98
  )
93
99
  }
94
100
 
95
- /** Body slot — `.dcard-b` in the design system handoff. */
101
+ /** Body slot: padding 14px 16px. */
96
102
  export function CardContent({ className = '', children, ...rest }: HTMLAttributes<HTMLDivElement>) {
97
103
  return (
98
- <div
99
- className={`px-6 pt-4 pb-6 text-[length:var(--fs-body)] leading-[1.55] text-[var(--sub)] ${className}`}
100
- {...rest}
101
- >
104
+ <div className={`text-body text-sub px-4 py-3.5 leading-[1.55] ${className}`} {...rest}>
102
105
  {children}
103
106
  </div>
104
107
  )
@@ -0,0 +1,90 @@
1
+ 'use client'
2
+
3
+ type Dir = 'asc' | 'desc'
4
+
5
+ export interface CardSortOption<F extends string> {
6
+ field: F
7
+ label: string
8
+ }
9
+
10
+ export interface CardListControlsProps<F extends string> {
11
+ /** Select all / none, as the table header's checkbox does. */
12
+ selectAll?: {
13
+ checked: boolean
14
+ onChange: (checked: boolean) => void
15
+ disabled?: boolean
16
+ }
17
+ /** The columns the header can sort by, as one select with both directions. */
18
+ sort?: {
19
+ options: CardSortOption<F>[]
20
+ field: F | null
21
+ dir: Dir
22
+ onChange: (field: F, dir: Dir) => void
23
+ }
24
+ /** Spacing from the screen's own layout. */
25
+ className?: string
26
+ }
27
+
28
+ /**
29
+ * Below 769px a list table is drawn as cards (`table[data-cards]`), and the
30
+ * header row holding its sort buttons and select-all checkbox is hidden: it
31
+ * is clipped to nothing, and responsive.css takes its controls out of the tab
32
+ * order. This row brings both back for phones, at 44px. At 769px and up it is
33
+ * `display: none`, since the header has them. The checkbox is named by its
34
+ * visible "Select all": it sits right above the cards, and only one of it and
35
+ * the header's checkbox is ever exposed.
36
+ */
37
+ export function CardListControls<F extends string>({
38
+ selectAll,
39
+ sort,
40
+ className,
41
+ }: CardListControlsProps<F>) {
42
+ if (!selectAll && !sort) return null
43
+ const value = sort?.field ? `${sort.field}:${sort.dir}` : ''
44
+ return (
45
+ <div
46
+ className={`not-mobile:hidden flex shrink-0 flex-wrap items-center gap-x-3 gap-y-2 ${className ?? ''}`}
47
+ >
48
+ {selectAll ? (
49
+ <label className="flex min-h-11 cursor-pointer items-center gap-2.5 text-sm text-[var(--txt)]">
50
+ <input
51
+ type="checkbox"
52
+ checked={selectAll.checked}
53
+ disabled={selectAll.disabled}
54
+ onChange={(e) => selectAll.onChange(e.target.checked)}
55
+ className="h-6 w-6 cursor-pointer accent-[var(--acc)]"
56
+ />
57
+ Select all
58
+ </label>
59
+ ) : null}
60
+ {sort ? (
61
+ <label className="ml-auto flex items-center gap-2 text-sm text-[var(--sub)]">
62
+ Sort
63
+ <select
64
+ aria-label="Sort by"
65
+ value={value}
66
+ onChange={(e) => {
67
+ const [field, dir] = e.target.value.split(':') as [F, Dir]
68
+ if (field) sort.onChange(field, dir)
69
+ }}
70
+ className="rounded-8 min-h-11 border border-[var(--bdr)] bg-[var(--card)] px-2.5 text-sm text-[var(--txt)]"
71
+ >
72
+ {sort.field ? null : (
73
+ <option value="" disabled>
74
+ Default order
75
+ </option>
76
+ )}
77
+ {sort.options.flatMap((option) => [
78
+ <option key={`${option.field}:asc`} value={`${option.field}:asc`}>
79
+ {option.label}, ascending
80
+ </option>,
81
+ <option key={`${option.field}:desc`} value={`${option.field}:desc`}>
82
+ {option.label}, descending
83
+ </option>,
84
+ ])}
85
+ </select>
86
+ </label>
87
+ ) : null}
88
+ </div>
89
+ )
90
+ }