themelia-react-ui 2.0.4 → 2.0.5

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 (588) hide show
  1. package/CHANGELOG.md +135 -0
  2. package/README.md +113 -18
  3. package/dist/{accordion-96o0pN62.js → accordion-B9MHG0cT.js} +11 -11
  4. package/dist/accordion-B9MHG0cT.js.map +1 -0
  5. package/dist/{action-menu-CHgs8vmj.js → action-menu-Dr8K-ghE.js} +48 -45
  6. package/dist/action-menu-Dr8K-ghE.js.map +1 -0
  7. package/dist/{affordance-geometry.generated-B8yGOr8-.js → affordance-geometry.generated-P-aVJisu.js} +36 -36
  8. package/dist/affordance-geometry.generated-P-aVJisu.js.map +1 -0
  9. package/dist/{ai-artifact-BZUGwBq6.js → ai-artifact-C58tQcBy.js} +210 -174
  10. package/dist/ai-artifact-C58tQcBy.js.map +1 -0
  11. package/dist/app-shell-B_IuNWOo.js +321 -0
  12. package/dist/app-shell-B_IuNWOo.js.map +1 -0
  13. package/dist/{attachment-DkoqHPPl.js → attachment-Dg_69lPS.js} +9 -9
  14. package/dist/{attachment-DkoqHPPl.js.map → attachment-Dg_69lPS.js.map} +1 -1
  15. package/dist/{auth-D2FVZ1MH.js → auth-DTkkshS8.js} +43 -46
  16. package/dist/auth-DTkkshS8.js.map +1 -0
  17. package/dist/{avatar-DWO_HHhB.js → avatar-CeZaFmNH.js} +8 -8
  18. package/dist/avatar-CeZaFmNH.js.map +1 -0
  19. package/dist/{badge-DErMA7ul.js → badge-xIiV_E7f.js} +5 -5
  20. package/dist/{badge-DErMA7ul.js.map → badge-xIiV_E7f.js.map} +1 -1
  21. package/dist/base/accordion.js +1 -1
  22. package/dist/base/action-menu.js +1 -1
  23. package/dist/base/attachment.js +1 -1
  24. package/dist/base/avatar.js +1 -1
  25. package/dist/base/badge.js +1 -1
  26. package/dist/base/batch-action-bar.js +1 -1
  27. package/dist/base/buttons.js +1 -1
  28. package/dist/base/cards.js +2 -2
  29. package/dist/base/carousel.js +3 -3
  30. package/dist/base/cascader.js +2 -372
  31. package/dist/base/chart.js +1 -1
  32. package/dist/base/choice-inputs.js +2 -2
  33. package/dist/base/code-block.js +1 -1
  34. package/dist/base/combobox.js +2 -2
  35. package/dist/base/command.js +1 -1
  36. package/dist/base/copyable.js +1 -1
  37. package/dist/base/date-pickers.js +2 -2
  38. package/dist/base/display.js +6 -6
  39. package/dist/base/feedback.js +3 -3
  40. package/dist/base/forms-numeric.js +1 -1
  41. package/dist/base/forms.js +2 -2
  42. package/dist/base/inline-edit.js +10 -10
  43. package/dist/base/item.js +1 -1
  44. package/dist/base/media-gallery.js +1 -1
  45. package/dist/base/metadata-list.js +1 -1
  46. package/dist/base/navigation.js +7 -7
  47. package/dist/base/popover-menu.js +1 -1
  48. package/dist/base/popover.js +1 -1
  49. package/dist/base/qr-code.js +1 -1
  50. package/dist/base/repeaters.js +12 -12
  51. package/dist/base/repeaters.js.map +1 -1
  52. package/dist/base/sheet.js +1 -1
  53. package/dist/base/sidebar.js +2 -2
  54. package/dist/base/signature-pad.js +7 -7
  55. package/dist/base/signature-pad.js.map +1 -1
  56. package/dist/base/skeleton.js +1 -1
  57. package/dist/base/spinner.js +4 -4
  58. package/dist/base/structure.js +1 -1
  59. package/dist/base/table.js +1 -1
  60. package/dist/base/text-inputs.js +2 -2
  61. package/dist/base/toaster.js +36 -36
  62. package/dist/base/toaster.js.map +1 -1
  63. package/dist/base/tree.js +1 -1
  64. package/dist/base/upload-queue.js +1 -1
  65. package/dist/base/upload.js +3 -3
  66. package/dist/base/value-inputs.js +1 -1
  67. package/dist/{batch-action-bar-CdfIkCsV.js → batch-action-bar-Cb8cuvyy.js} +6 -6
  68. package/dist/batch-action-bar-Cb8cuvyy.js.map +1 -0
  69. package/dist/blocks/admin.js +21 -21
  70. package/dist/blocks/admin.js.map +1 -1
  71. package/dist/blocks/ai.js +230 -216
  72. package/dist/blocks/ai.js.map +1 -1
  73. package/dist/blocks/analytics/usage-card.js +1 -1
  74. package/dist/blocks/analytics.js +325 -306
  75. package/dist/blocks/analytics.js.map +1 -1
  76. package/dist/blocks/collaboration.js +1 -1
  77. package/dist/blocks/commerce/receipt.js +1 -1
  78. package/dist/blocks/commerce.js +1259 -1184
  79. package/dist/blocks/commerce.js.map +1 -1
  80. package/dist/blocks/data-display.js +2 -2
  81. package/dist/blocks/onboarding.js +6 -6
  82. package/dist/blocks/onboarding.js.map +1 -1
  83. package/dist/blocks/planning.js +11 -11
  84. package/dist/blocks/timelines.js +1 -1
  85. package/dist/{breadcrumbs-B-WFKecD.js → breadcrumbs-J-K2kl4c.js} +6 -6
  86. package/dist/{breadcrumbs-B-WFKecD.js.map → breadcrumbs-J-K2kl4c.js.map} +1 -1
  87. package/dist/{button-DkmK-z8E.js → button-S2Cubiiz.js} +3 -3
  88. package/dist/button-S2Cubiiz.js.map +1 -0
  89. package/dist/{buttons-BbfzgczK.js → buttons-BedGfygC.js} +16 -16
  90. package/dist/buttons-BedGfygC.js.map +1 -0
  91. package/dist/cards-rNX1M4Xn.js +69 -0
  92. package/dist/cards-rNX1M4Xn.js.map +1 -0
  93. package/dist/cascader-B1MiqkBq.js +439 -0
  94. package/dist/cascader-B1MiqkBq.js.map +1 -0
  95. package/dist/chart-Darg_0Kv.js +162 -0
  96. package/dist/chart-Darg_0Kv.js.map +1 -0
  97. package/dist/{checkbox-CzYUTPeJ.js → checkbox-fflqmODR.js} +2 -2
  98. package/dist/{checkbox-CzYUTPeJ.js.map → checkbox-fflqmODR.js.map} +1 -1
  99. package/dist/{choice-inputs-JLtij2y4.js → choice-inputs-zUgBZfE4.js} +258 -257
  100. package/dist/choice-inputs-zUgBZfE4.js.map +1 -0
  101. package/dist/{code-block-CGNaUtAE.js → code-block-BzmM9Eig.js} +8 -8
  102. package/dist/code-block-BzmM9Eig.js.map +1 -0
  103. package/dist/{collapsible-Do4G0zcC.js → collapsible-BkAI_XD4.js} +5 -5
  104. package/dist/{collapsible-Do4G0zcC.js.map → collapsible-BkAI_XD4.js.map} +1 -1
  105. package/dist/{collection-content-C0e8SsTm.js → collection-content-gDh1v6O4.js} +3 -3
  106. package/dist/{collection-content-C0e8SsTm.js.map → collection-content-gDh1v6O4.js.map} +1 -1
  107. package/dist/combobox-BEx0vJgF.js +362 -0
  108. package/dist/combobox-BEx0vJgF.js.map +1 -0
  109. package/dist/{combobox-CBJDs6w_.js → combobox-BwzoXFSG.js} +254 -247
  110. package/dist/combobox-BwzoXFSG.js.map +1 -0
  111. package/dist/{command-D8NrBj-b.js → command-CrlPIL6m.js} +11 -11
  112. package/dist/command-CrlPIL6m.js.map +1 -0
  113. package/dist/{comments-Di4w0H_S.js → comments-Dmpp0YIc.js} +29 -29
  114. package/dist/{comments-Di4w0H_S.js.map → comments-Dmpp0YIc.js.map} +1 -1
  115. package/dist/components/base/action-menu/action-menu.d.ts +7 -1
  116. package/dist/components/base/buttons/button-group.recipes.d.ts +2 -2
  117. package/dist/components/base/cards/card.recipes.d.ts +6 -4
  118. package/dist/components/base/cards/partials/card-primitives.d.ts +9 -2
  119. package/dist/components/base/cards/partials/smart-card-header-row.d.ts +3 -1
  120. package/dist/components/base/cards/smart-card.types.d.ts +3 -4
  121. package/dist/components/base/cascader/cascader-panel.d.ts +76 -0
  122. package/dist/components/base/chart/chart.d.ts +6 -1
  123. package/dist/components/base/choice-inputs/choice-types.d.ts +1 -1
  124. package/dist/components/base/combobox/index.d.ts +4 -2
  125. package/dist/components/base/feedback/alert.d.ts +1 -1
  126. package/dist/components/base/forms/form-sizing.d.ts +7 -7
  127. package/dist/components/base/forms/workflow.d.ts +7 -1
  128. package/dist/components/base/forms-numeric/coordinates-input.d.ts +4 -0
  129. package/dist/components/base/metadata-list/metadata-list.d.ts +1 -1
  130. package/dist/components/base/navigation/dropdown-menu.d.ts +1 -1
  131. package/dist/components/base/navigation/page-header/page-header-commands.d.ts +14 -7
  132. package/dist/components/base/navigation/page-header/page-header.d.ts +10 -3
  133. package/dist/components/base/popover/popover.d.ts +3 -3
  134. package/dist/components/base/popover/popover.recipes.d.ts +10 -6
  135. package/dist/components/base/sheet/sheet.d.ts +2 -0
  136. package/dist/components/base/sidebar/index.d.ts +1 -1
  137. package/dist/components/base/sidebar/sidebar.d.ts +27 -5
  138. package/dist/components/base/toaster/index.d.ts +1 -0
  139. package/dist/components/blocks/ai/ai-file-tree/types.d.ts +1 -1
  140. package/dist/components/blocks/ai/ai-tool-call/types.d.ts +3 -1
  141. package/dist/components/blocks/ai/ai.strings.d.ts +2 -0
  142. package/dist/components/blocks/analytics/metric-comparison/metric-comparison.d.ts +2 -0
  143. package/dist/components/blocks/analytics/usage-card/usage-card.strings.d.ts +2 -0
  144. package/dist/components/blocks/commerce/cart-summary/cart-summary.d.ts +1 -1
  145. package/dist/components/blocks/commerce/cart-summary/types.d.ts +3 -1
  146. package/dist/components/blocks/commerce/discount-stack/discount-stack.d.ts +1 -1
  147. package/dist/components/blocks/commerce/discount-stack/types.d.ts +3 -1
  148. package/dist/components/blocks/commerce/fulfillment-group/fulfillment-group.d.ts +1 -1
  149. package/dist/components/blocks/commerce/fulfillment-group/types.d.ts +11 -2
  150. package/dist/components/blocks/commerce/index.d.ts +7 -6
  151. package/dist/components/blocks/commerce/inventory-section/inventory-section.d.ts +1 -1
  152. package/dist/components/blocks/commerce/inventory-section/types.d.ts +7 -2
  153. package/dist/components/blocks/commerce/invoice-header/index.d.ts +2 -1
  154. package/dist/components/blocks/commerce/invoice-header/invoice-header.d.ts +1 -1
  155. package/dist/components/blocks/commerce/invoice-header/types.d.ts +20 -6
  156. package/dist/components/blocks/commerce/invoice-line-items/invoice-line-items.d.ts +1 -1
  157. package/dist/components/blocks/commerce/invoice-line-items/types.d.ts +24 -7
  158. package/dist/components/blocks/commerce/invoice-mini/index.d.ts +2 -1
  159. package/dist/components/blocks/commerce/invoice-mini/types.d.ts +7 -1
  160. package/dist/components/blocks/commerce/order-customer/order-customer.d.ts +1 -1
  161. package/dist/components/blocks/commerce/order-customer/types.d.ts +9 -1
  162. package/dist/components/blocks/commerce/refund-status/refund-status.d.ts +1 -1
  163. package/dist/components/blocks/commerce/refund-status/types.d.ts +3 -1
  164. package/dist/components/blocks/commerce/shipment-tracking/shipment-tracking.d.ts +1 -1
  165. package/dist/components/blocks/commerce/shipment-tracking/types.d.ts +3 -1
  166. package/dist/components/blocks/commerce/tax-breakdown/tax-breakdown.d.ts +1 -1
  167. package/dist/components/blocks/commerce/tax-breakdown/types.d.ts +3 -1
  168. package/dist/components/features/activities/activities.types.d.ts +8 -2
  169. package/dist/components/features/activities/partials/activity-marker.d.ts +7 -3
  170. package/dist/components/features/activities/partials/activity-row.d.ts +24 -0
  171. package/dist/components/features/event-calendar/colors.d.ts +2 -2
  172. package/dist/components/features/event-calendar/event-calendar.types.d.ts +4 -0
  173. package/dist/components/features/filters/facets/select-facet.d.ts +2 -1
  174. package/dist/components/features/filters/filters.strings.d.ts +4 -0
  175. package/dist/components/features/filters/filters.types.d.ts +3 -0
  176. package/dist/components/features/filters/partials/filter-editor-header.d.ts +16 -0
  177. package/dist/components/features/filters/partials/filter-popover-content.d.ts +1 -1
  178. package/dist/components/features/filters/partials/nested-filter-options.d.ts +21 -0
  179. package/dist/components/features/filters/partials/regular-filter-content.d.ts +2 -1
  180. package/dist/components/features/filters/utils/filter-utils.d.ts +21 -3
  181. package/dist/components/features/global-search/global-search.types.d.ts +2 -0
  182. package/dist/components/features/global-search/partials/global-search-input.d.ts +10 -0
  183. package/dist/components/features/global-search/partials/global-search-result-row.d.ts +7 -1
  184. package/dist/components/features/media-library/media-library.strings.d.ts +2 -0
  185. package/dist/components/features/media-library/media-library.types.d.ts +14 -4
  186. package/dist/components/features/media-library/partials/media-library-partials.d.ts +1 -1
  187. package/dist/components/features/products/components/product-options-matrix.d.ts +1 -1
  188. package/dist/components/features/products/components/product-variant-editor.d.ts +1 -1
  189. package/dist/components/features/products/components/product-variants-manager.d.ts +1 -1
  190. package/dist/components/features/products/products.strings.d.ts +9 -1
  191. package/dist/components/features/products/products.types.d.ts +43 -6
  192. package/dist/components/features/resource/resource.d.ts +5 -1
  193. package/dist/components/features/resource/resource.types.d.ts +12 -1
  194. package/dist/components/features/rich-text-editor/partials/image-uploads.d.ts +1 -1
  195. package/dist/components/features/rich-text-editor/rich-text-editor.recipes.d.ts +12 -2
  196. package/dist/components/features/table/partials/resource-cell.d.ts +22 -5
  197. package/dist/components/features/table/table.types.d.ts +1 -1
  198. package/dist/components/layout/app-shell/app-shell.types.d.ts +35 -6
  199. package/dist/components/layout/app-shell/index.d.ts +1 -1
  200. package/dist/components/layout/app-shell/shell-regions.d.ts +27 -0
  201. package/dist/components/layout/app-shell/sidebar-inset-layout.d.ts +1 -1
  202. package/dist/components/layout/app-shell/stacked-layout.d.ts +1 -1
  203. package/dist/components/layout/app-shell/topbar-sidebar-layout.d.ts +1 -1
  204. package/dist/components/layout/containers/two-column-layout.d.ts +2 -0
  205. package/dist/components/layout/header/header.recipes.d.ts +6 -0
  206. package/dist/components/layout/header/header.types.d.ts +6 -6
  207. package/dist/components/layout/navigation/section-nav/section-nav.d.ts +5 -0
  208. package/dist/components/layout/page/index.d.ts +2 -1
  209. package/dist/components/layout/page/page.d.ts +1 -0
  210. package/dist/components/layout/page/page.strings.d.ts +11 -0
  211. package/dist/components/layout/page/page.types.d.ts +69 -17
  212. package/dist/components/layout/page/partials/page-header.d.ts +1 -1
  213. package/dist/components/layout/settings/settings.d.ts +9 -2
  214. package/dist/components/layout/sidebar/app-sidebar.d.ts +1 -1
  215. package/dist/components/layout/sidebar/components/sidebar-grouped-navigation.d.ts +1 -1
  216. package/dist/components/layout/sidebar/components/sidebar-navigation.d.ts +1 -1
  217. package/dist/components/layout/sidebar/index.d.ts +2 -1
  218. package/dist/components/layout/sidebar/sidebar-navigation-rail.d.ts +36 -0
  219. package/dist/components/layout/sidebar/sidebar.context.d.ts +5 -7
  220. package/dist/components/layout/sidebar/sidebar.types.d.ts +48 -10
  221. package/dist/components/layout/sidebar/sidebar.utils.d.ts +9 -1
  222. package/dist/components/layout/workspace/workspace.types.d.ts +8 -1
  223. package/dist/components/ui/alert-dialog.d.ts +2 -2
  224. package/dist/components/ui/combobox.d.ts +1 -1
  225. package/dist/components/ui/dialog.d.ts +2 -2
  226. package/dist/components/ui/overlay-layer.d.ts +18 -0
  227. package/dist/components/ui/sheet.d.ts +5 -1
  228. package/dist/components/ui/sidebar-state.d.ts +82 -0
  229. package/dist/components/ui/sidebar.d.ts +5 -17
  230. package/dist/{containers-CRmHf7GP.js → containers-CIxwbZt5.js} +26 -18
  231. package/dist/containers-CIxwbZt5.js.map +1 -0
  232. package/dist/{control-group-recipes-DBXmfh2E.js → control-group-recipes-fMuFo0H7.js} +6 -6
  233. package/dist/control-group-recipes-fMuFo0H7.js.map +1 -0
  234. package/dist/{copyable-CnGCZdX4.js → copyable-DIznBqiT.js} +7 -7
  235. package/dist/{copyable-CnGCZdX4.js.map → copyable-DIznBqiT.js.map} +1 -1
  236. package/dist/{data-display-D4oujtx0.js → data-display-BdgCAw8T.js} +268 -277
  237. package/dist/data-display-BdgCAw8T.js.map +1 -0
  238. package/dist/{date-Q7jnXxpk.js → date-Cq8ioE4o.js} +5 -5
  239. package/dist/{date-Q7jnXxpk.js.map → date-Cq8ioE4o.js.map} +1 -1
  240. package/dist/{date-picker-zOt1oNss.js → date-picker-RlIzKom_.js} +446 -437
  241. package/dist/date-picker-RlIzKom_.js.map +1 -0
  242. package/dist/{date-pickers-cj8IXbDC.js → date-pickers-DY-CpXS1.js} +12 -12
  243. package/dist/{date-pickers-cj8IXbDC.js.map → date-pickers-DY-CpXS1.js.map} +1 -1
  244. package/dist/{display-BB4BL_-K.js → display-KsZLw9Ov.js} +9 -9
  245. package/dist/{display-BB4BL_-K.js.map → display-KsZLw9Ov.js.map} +1 -1
  246. package/dist/dropdown-menu-CLs8Lihj.js +194 -0
  247. package/dist/dropdown-menu-CLs8Lihj.js.map +1 -0
  248. package/dist/features/activities.js +302 -253
  249. package/dist/features/activities.js.map +1 -1
  250. package/dist/features/ai-chat.js +15 -14
  251. package/dist/features/ai-chat.js.map +1 -1
  252. package/dist/features/appointment-calendar.js +22 -22
  253. package/dist/features/appointment-calendar.js.map +1 -1
  254. package/dist/features/async-preview.js +11 -10
  255. package/dist/features/async-preview.js.map +1 -1
  256. package/dist/features/combobox.js +1 -1
  257. package/dist/features/comments.js +1 -1
  258. package/dist/features/data-view.js +13 -13
  259. package/dist/features/data-view.js.map +1 -1
  260. package/dist/features/email-composer.js +237 -238
  261. package/dist/features/email-composer.js.map +1 -1
  262. package/dist/features/event-calendar.js +140 -146
  263. package/dist/features/event-calendar.js.map +1 -1
  264. package/dist/features/filters.js +1 -1
  265. package/dist/features/global-search.js +167 -138
  266. package/dist/features/global-search.js.map +1 -1
  267. package/dist/features/kanban.js +6 -7
  268. package/dist/features/kanban.js.map +1 -1
  269. package/dist/features/map.js +269 -260
  270. package/dist/features/map.js.map +1 -1
  271. package/dist/features/media-library.js +375 -326
  272. package/dist/features/media-library.js.map +1 -1
  273. package/dist/features/mentions.js +1 -1
  274. package/dist/features/overlays.js +1 -1
  275. package/dist/features/products.js +1266 -1193
  276. package/dist/features/products.js.map +1 -1
  277. package/dist/features/questionnaire.js +13 -13
  278. package/dist/features/questionnaire.js.map +1 -1
  279. package/dist/features/resource-assignment.js +8 -8
  280. package/dist/features/resource.js +69 -66
  281. package/dist/features/resource.js.map +1 -1
  282. package/dist/features/rich-text-editor.js +2 -2
  283. package/dist/features/schema-form.js +13 -13
  284. package/dist/features/suggestions.js +3 -3
  285. package/dist/features/sync.js +3 -3
  286. package/dist/features/table.js +1 -1
  287. package/dist/features/theme-tweaker.js +94 -95
  288. package/dist/features/theme-tweaker.js.map +1 -1
  289. package/dist/{feedback-DZNL5Lg1.js → feedback-Dm4izqFn.js} +80 -79
  290. package/dist/feedback-Dm4izqFn.js.map +1 -0
  291. package/dist/{field-affordance-recipes-DjwGx8eM.js → field-affordance-recipes-DWcNcOjh.js} +4 -4
  292. package/dist/field-affordance-recipes-DWcNcOjh.js.map +1 -0
  293. package/dist/{filters-BcT-uoFy.js → filters-DzgSJpMK.js} +693 -645
  294. package/dist/filters-DzgSJpMK.js.map +1 -0
  295. package/dist/{form-field-CsgRmdit.js → form-field-BriWAXyg.js} +6 -6
  296. package/dist/{form-field-CsgRmdit.js.map → form-field-BriWAXyg.js.map} +1 -1
  297. package/dist/{form-sizing-NXgjkmBG.js → form-sizing-Bs2qFUeE.js} +4 -4
  298. package/dist/form-sizing-Bs2qFUeE.js.map +1 -0
  299. package/dist/{forms-BV5m5aQF.js → forms-C0RGnJTe.js} +17 -13
  300. package/dist/forms-C0RGnJTe.js.map +1 -0
  301. package/dist/{forms-numeric-Cd33AKbD.js → forms-numeric-DIhghX1Q.js} +86 -82
  302. package/dist/forms-numeric-DIhghX1Q.js.map +1 -0
  303. package/dist/{header-BA697l4a.js → header-DMMxG__r.js} +67 -63
  304. package/dist/header-DMMxG__r.js.map +1 -0
  305. package/dist/header.recipes-BigdJjw1.js +6 -0
  306. package/dist/header.recipes-BigdJjw1.js.map +1 -0
  307. package/dist/{hooks-BQ-L7Uu2.js → hooks-DB6CJ4MR.js} +26 -14
  308. package/dist/hooks-DB6CJ4MR.js.map +1 -0
  309. package/dist/{icon-badge-COWbCCWu.js → icon-badge-DZF-YjQp.js} +4 -4
  310. package/dist/{icon-badge-COWbCCWu.js.map → icon-badge-DZF-YjQp.js.map} +1 -1
  311. package/dist/index.js +4 -5
  312. package/dist/{input-Cdw4k0fb.js → input-CvyDQlY7.js} +8 -8
  313. package/dist/{input-Cdw4k0fb.js.map → input-CvyDQlY7.js.map} +1 -1
  314. package/dist/input-DMBwAZmr.js +21 -0
  315. package/dist/input-DMBwAZmr.js.map +1 -0
  316. package/dist/{item-BvZ2DR_x.js → item-DjCcM18E.js} +16 -16
  317. package/dist/item-DjCcM18E.js.map +1 -0
  318. package/dist/layout/app-shell.js +1 -1
  319. package/dist/layout/auth.js +1 -1
  320. package/dist/layout/containers.js +1 -1
  321. package/dist/layout/header.js +1 -1
  322. package/dist/layout/hooks.js +1 -1
  323. package/dist/layout/navigation.js +1 -1
  324. package/dist/layout/page.js +2 -2
  325. package/dist/layout/settings.js +1 -1
  326. package/dist/layout/sidebar.js +3 -3
  327. package/dist/layout/workspace.js +1 -1
  328. package/dist/layout.js +11 -11
  329. package/dist/lib/affordance-geometry.generated.d.ts +35 -35
  330. package/dist/lib/control-group-recipes.d.ts +5 -5
  331. package/dist/lib/field-affordance-recipes.d.ts +2 -2
  332. package/dist/lib/motion-recipes.d.ts +3 -0
  333. package/dist/lib/navigation-row-recipes.d.ts +7 -7
  334. package/dist/lib/overlay-anatomy-recipes.d.ts +3 -3
  335. package/dist/lib/portal-recipes.d.ts +3 -0
  336. package/dist/lib/token-merge.generated.d.ts +13 -10
  337. package/dist/lib/utils.js +1 -1
  338. package/dist/map-demo-tile.svg +1 -1
  339. package/dist/{media-gallery-CSl5W1Fy.js → media-gallery-C-vChPmE.js} +6 -6
  340. package/dist/{media-gallery-CSl5W1Fy.js.map → media-gallery-C-vChPmE.js.map} +1 -1
  341. package/dist/{mentions-RKOQaaIB.js → mentions-0_4nWuI-.js} +10 -10
  342. package/dist/{mentions-RKOQaaIB.js.map → mentions-0_4nWuI-.js.map} +1 -1
  343. package/dist/{message-INU2xsxu.js → message-g8p7eVtN.js} +7 -7
  344. package/dist/message-g8p7eVtN.js.map +1 -0
  345. package/dist/{metadata-list-qVV7AVxa.js → metadata-list-C3MkU-Om.js} +64 -64
  346. package/dist/metadata-list-C3MkU-Om.js.map +1 -0
  347. package/dist/{motion-recipes-ChBg4HBq.js → motion-recipes-DitYv6P2.js} +10 -2
  348. package/dist/motion-recipes-DitYv6P2.js.map +1 -0
  349. package/dist/navigation-C90-oQFq.js +255 -0
  350. package/dist/navigation-C90-oQFq.js.map +1 -0
  351. package/dist/{navigation-BQNcg1jT.js → navigation-DaRjthVk.js} +101 -82
  352. package/dist/navigation-DaRjthVk.js.map +1 -0
  353. package/dist/{navigation-row-recipes-WZEs-hYo.js → navigation-row-recipes-BGVLvU_O.js} +9 -9
  354. package/dist/navigation-row-recipes-BGVLvU_O.js.map +1 -0
  355. package/dist/{number-E_OiIfJz.js → number-CRU3kGuk.js} +5 -5
  356. package/dist/{number-E_OiIfJz.js.map → number-CRU3kGuk.js.map} +1 -1
  357. package/dist/overflow-tab-bar-IVFVQFV6.js +172 -0
  358. package/dist/overflow-tab-bar-IVFVQFV6.js.map +1 -0
  359. package/dist/overlays-BSgCtM2v.js +1013 -0
  360. package/dist/overlays-BSgCtM2v.js.map +1 -0
  361. package/dist/page-DUUKDAjo.js +331 -0
  362. package/dist/page-DUUKDAjo.js.map +1 -0
  363. package/dist/page-header-commands-7P3sfE9u.js +193 -0
  364. package/dist/page-header-commands-7P3sfE9u.js.map +1 -0
  365. package/dist/{pagination-Ch8X_47u.js → pagination-CgCjElfu.js} +7 -7
  366. package/dist/{pagination-Ch8X_47u.js.map → pagination-CgCjElfu.js.map} +1 -1
  367. package/dist/popover-B85RenIl.js +201 -0
  368. package/dist/popover-B85RenIl.js.map +1 -0
  369. package/dist/{popover-menu-BYaCdFhf.js → popover-menu-DlnQ2zlR.js} +7 -7
  370. package/dist/{popover-menu-BYaCdFhf.js.map → popover-menu-DlnQ2zlR.js.map} +1 -1
  371. package/dist/{popover.recipes-D3j8R8Yp.js → popover.recipes-DdiEp0rd.js} +18 -11
  372. package/dist/popover.recipes-DdiEp0rd.js.map +1 -0
  373. package/dist/portal-recipes-BpsV_iRw.js +9 -0
  374. package/dist/portal-recipes-BpsV_iRw.js.map +1 -0
  375. package/dist/{primitives-Du64iDbb.js → primitives-ByWgGUgt.js} +5 -5
  376. package/dist/{primitives-Du64iDbb.js.map → primitives-ByWgGUgt.js.map} +1 -1
  377. package/dist/primitives.js +4 -4
  378. package/dist/{progress-BvF2oCdV.js → progress-BJhQP9WX.js} +9 -9
  379. package/dist/{progress-BvF2oCdV.js.map → progress-BJhQP9WX.js.map} +1 -1
  380. package/dist/{receipt-D789Jwyy.js → receipt-tOc7B3hw.js} +7 -7
  381. package/dist/receipt-tOc7B3hw.js.map +1 -0
  382. package/dist/{rich-text-CLJEf76s.js → rich-text-Dth5E882.js} +3 -3
  383. package/dist/{rich-text-CLJEf76s.js.map → rich-text-Dth5E882.js.map} +1 -1
  384. package/dist/{rich-text-editor-Cm1dpUpQ.js → rich-text-editor-C1fOjBTd.js} +429 -430
  385. package/dist/rich-text-editor-C1fOjBTd.js.map +1 -0
  386. package/dist/{rich-text-editor-toolbar-L__e4x47.js → rich-text-editor-toolbar-laT3tpBT.js} +32 -28
  387. package/dist/rich-text-editor-toolbar-laT3tpBT.js.map +1 -0
  388. package/dist/{scroll-area-La5RXsEk.js → scroll-area-B0dB2cBi.js} +2 -2
  389. package/dist/{scroll-area-La5RXsEk.js.map → scroll-area-B0dB2cBi.js.map} +1 -1
  390. package/dist/{separator-DAEV0w65.js → separator-Bb17I4pu.js} +2 -2
  391. package/dist/{separator-DAEV0w65.js.map → separator-Bb17I4pu.js.map} +1 -1
  392. package/dist/{separator-GNfPG-90.js → separator-Ct_WSWTJ.js} +3 -3
  393. package/dist/{separator-GNfPG-90.js.map → separator-Ct_WSWTJ.js.map} +1 -1
  394. package/dist/services/actions.js +1 -1
  395. package/dist/{settings-BA2iboic.js → settings-Bar5wiSo.js} +31 -38
  396. package/dist/settings-Bar5wiSo.js.map +1 -0
  397. package/dist/sheet-BGPERY55.js +250 -0
  398. package/dist/sheet-BGPERY55.js.map +1 -0
  399. package/dist/sidebar-D-JYMMbY.js +686 -0
  400. package/dist/sidebar-D-JYMMbY.js.map +1 -0
  401. package/dist/sidebar-f9gRWXIR.js +1001 -0
  402. package/dist/sidebar-f9gRWXIR.js.map +1 -0
  403. package/dist/skeleton-BapcJd9C.js +265 -0
  404. package/dist/skeleton-BapcJd9C.js.map +1 -0
  405. package/dist/smart-card-CW0hjetE.js +617 -0
  406. package/dist/smart-card-CW0hjetE.js.map +1 -0
  407. package/dist/{structure-C0V0_Fyf.js → structure-DuxKl954.js} +2 -2
  408. package/dist/{structure-C0V0_Fyf.js.map → structure-DuxKl954.js.map} +1 -1
  409. package/dist/style.css +1 -1
  410. package/dist/{table-CpvnzJn9.js → table-B4TE7iOV.js} +3 -3
  411. package/dist/{table-CpvnzJn9.js.map → table-B4TE7iOV.js.map} +1 -1
  412. package/dist/{table-DH7rozUv.js → table-CFOWY9pQ.js} +394 -388
  413. package/dist/table-CFOWY9pQ.js.map +1 -0
  414. package/dist/{tabs-eqVsJZWO.js → tabs-e7ko9S2o.js} +11 -11
  415. package/dist/tabs-e7ko9S2o.js.map +1 -0
  416. package/dist/{text-inputs-DXItiR0O.js → text-inputs-B1culiSK.js} +17 -17
  417. package/dist/text-inputs-B1culiSK.js.map +1 -0
  418. package/dist/theme.css +40 -37
  419. package/dist/{timelines-DmtztAY_.js → timelines-D3Sl9ueq.js} +13 -12
  420. package/dist/timelines-D3Sl9ueq.js.map +1 -0
  421. package/dist/tooltip-8wz5S_Zr.js +113 -0
  422. package/dist/tooltip-8wz5S_Zr.js.map +1 -0
  423. package/dist/{tree-CV11PURP.js → tree-CzUJHnFs.js} +8 -8
  424. package/dist/{tree-CV11PURP.js.map → tree-CzUJHnFs.js.map} +1 -1
  425. package/dist/typography/rich-text.js +1 -1
  426. package/dist/{typography-CSyJrh28.js → typography-BQnine1k.js} +12 -12
  427. package/dist/{typography-CSyJrh28.js.map → typography-BQnine1k.js.map} +1 -1
  428. package/dist/typography.js +1 -1
  429. package/dist/ui-provider-C-74NVLc.js +178 -0
  430. package/dist/ui-provider-C-74NVLc.js.map +1 -0
  431. package/dist/ui-provider.js +2 -3
  432. package/dist/{upload-C9SA0X-8.js → upload-BOW6U2tI.js} +25 -24
  433. package/dist/upload-BOW6U2tI.js.map +1 -0
  434. package/dist/{upload-queue-DhQJiSRc.js → upload-queue-qUXn1ykN.js} +16 -14
  435. package/dist/upload-queue-qUXn1ykN.js.map +1 -0
  436. package/dist/{usage-card-DVTRDmGz.js → usage-card-BeSLY0i0.js} +24 -17
  437. package/dist/usage-card-BeSLY0i0.js.map +1 -0
  438. package/dist/{utils-CF3c95Io.js → utils-B6kKb8jB.js} +237 -141
  439. package/dist/utils-B6kKb8jB.js.map +1 -0
  440. package/dist/value-inputs-skdVB2zh.js +980 -0
  441. package/dist/value-inputs-skdVB2zh.js.map +1 -0
  442. package/dist/{value-typography-ClupF0Gz.js → value-typography-uAmWUAL1.js} +2 -2
  443. package/dist/{value-typography-ClupF0Gz.js.map → value-typography-uAmWUAL1.js.map} +1 -1
  444. package/dist/{workspace-9EFVXUyk.js → workspace-DHeHv0qw.js} +50 -49
  445. package/dist/workspace-DHeHv0qw.js.map +1 -0
  446. package/docs/consumer-skill/SKILL.md +4 -3
  447. package/docs/consumer-skill/agents/themelia-ui-designer.md +96 -0
  448. package/docs/consumer-skill/examples/app-layout.tsx +52 -1
  449. package/docs/consumer-skill/examples/commerce-lines.tsx +271 -0
  450. package/docs/consumer-skill/examples/custom-composition.tsx +21 -0
  451. package/docs/consumer-skill/examples/detail.tsx +5 -4
  452. package/docs/consumer-skill/examples/editable-sections.tsx +38 -0
  453. package/docs/consumer-skill/examples/index-table.tsx +4 -4
  454. package/docs/consumer-skill/examples/manifest.json +38 -1
  455. package/docs/consumer-skill/examples/product-media.tsx +41 -0
  456. package/docs/consumer-skill/examples/product-parts.tsx +81 -0
  457. package/docs/consumer-skill/examples/rhf-edit-page.tsx +1 -1
  458. package/docs/consumer-skill/examples/rhf-overlay-form.tsx +24 -11
  459. package/docs/consumer-skill/examples/token-domain-structure.tsx +68 -0
  460. package/docs/consumer-skill/references/agents-md.md +19 -17
  461. package/docs/consumer-skill/references/analytics.md +18 -1
  462. package/docs/consumer-skill/references/commerce-composition.md +97 -0
  463. package/docs/consumer-skill/references/component-contracts.json +7131 -1754
  464. package/docs/consumer-skill/references/composition-mapping.md +17 -3
  465. package/docs/consumer-skill/references/composition.md +159 -31
  466. package/docs/consumer-skill/references/critique-rubric.md +98 -0
  467. package/docs/consumer-skill/references/custom-composition.md +261 -0
  468. package/docs/consumer-skill/references/data-reading.md +79 -0
  469. package/docs/consumer-skill/references/design-contract.md +11 -9
  470. package/docs/consumer-skill/references/discovery.md +27 -3
  471. package/docs/consumer-skill/references/domain-structures.md +124 -0
  472. package/docs/consumer-skill/references/installation.md +15 -4
  473. package/docs/consumer-skill/references/integration.md +35 -0
  474. package/docs/consumer-skill/references/product-composition.md +94 -0
  475. package/docs/consumer-skill/references/public-api.json +2881 -420
  476. package/docs/consumer-skill/references/review.md +39 -2
  477. package/docs/consumer-skill/references/rhf-workflows.md +7 -0
  478. package/docs/consumer-skill/references/screen-archetypes.md +19 -7
  479. package/docs/consumer-skill/references/screen-decisions.md +126 -0
  480. package/docs/consumer-skill/references/theming.md +17 -18
  481. package/docs/consumer-skill/references/tokens.json +9 -9
  482. package/docs/consumer-skill/references/view-craft.md +153 -0
  483. package/docs/consumer-skill/references/view-spec.md +73 -0
  484. package/docs/consumer-skill/references/workflows.md +7 -1
  485. package/docs/consumer-skill/scripts/composition-policy.mjs +39 -3
  486. package/docs/consumer-skill/scripts/composition-schema.mjs +1 -1
  487. package/docs/consumer-skill/scripts/composition.mjs +61 -5
  488. package/docs/consumer-skill/scripts/discovery.mjs +54 -0
  489. package/docs/consumer-skill/scripts/inspect-component.mjs +1 -1
  490. package/docs/consumer-skill/scripts/inspection.mjs +73 -18
  491. package/docs/consumer-skill/scripts/setup-skills.mjs +41 -6
  492. package/docs/consumer-skill/scripts/surface-policy.mjs +5 -5
  493. package/docs/consumer-skills/themelia-components/SKILL.md +14 -13
  494. package/docs/consumer-skills/themelia-composition/SKILL.md +16 -17
  495. package/docs/consumer-skills/themelia-design/SKILL.md +55 -0
  496. package/docs/consumer-skills/themelia-foundation/SKILL.md +2 -1
  497. package/docs/consumer-skills/themelia-tokenization/SKILL.md +24 -17
  498. package/package.json +1 -1
  499. package/dist/accordion-96o0pN62.js.map +0 -1
  500. package/dist/action-menu-CHgs8vmj.js.map +0 -1
  501. package/dist/affordance-geometry.generated-B8yGOr8-.js.map +0 -1
  502. package/dist/ai-artifact-BZUGwBq6.js.map +0 -1
  503. package/dist/app-shell-D63ATkIK.js +0 -237
  504. package/dist/app-shell-D63ATkIK.js.map +0 -1
  505. package/dist/auth-D2FVZ1MH.js.map +0 -1
  506. package/dist/avatar-DWO_HHhB.js.map +0 -1
  507. package/dist/base/cascader.js.map +0 -1
  508. package/dist/batch-action-bar-CdfIkCsV.js.map +0 -1
  509. package/dist/button-DkmK-z8E.js.map +0 -1
  510. package/dist/buttons-BbfzgczK.js.map +0 -1
  511. package/dist/cards-4JTWqvVe.js +0 -68
  512. package/dist/cards-4JTWqvVe.js.map +0 -1
  513. package/dist/chart-C19flDQb.js +0 -155
  514. package/dist/chart-C19flDQb.js.map +0 -1
  515. package/dist/choice-inputs-JLtij2y4.js.map +0 -1
  516. package/dist/code-block-CGNaUtAE.js.map +0 -1
  517. package/dist/combobox-CBJDs6w_.js.map +0 -1
  518. package/dist/combobox-hbhSS18O.js +0 -355
  519. package/dist/combobox-hbhSS18O.js.map +0 -1
  520. package/dist/command-D8NrBj-b.js.map +0 -1
  521. package/dist/containers-CRmHf7GP.js.map +0 -1
  522. package/dist/control-group-recipes-DBXmfh2E.js.map +0 -1
  523. package/dist/data-display-D4oujtx0.js.map +0 -1
  524. package/dist/date-picker-zOt1oNss.js.map +0 -1
  525. package/dist/dropdown-menu-CjY8Vt7W.js +0 -193
  526. package/dist/dropdown-menu-CjY8Vt7W.js.map +0 -1
  527. package/dist/feedback-DZNL5Lg1.js.map +0 -1
  528. package/dist/field-affordance-recipes-DjwGx8eM.js.map +0 -1
  529. package/dist/filters-BcT-uoFy.js.map +0 -1
  530. package/dist/form-sizing-NXgjkmBG.js.map +0 -1
  531. package/dist/forms-BV5m5aQF.js.map +0 -1
  532. package/dist/forms-numeric-Cd33AKbD.js.map +0 -1
  533. package/dist/header-BA697l4a.js.map +0 -1
  534. package/dist/hooks-BQ-L7Uu2.js.map +0 -1
  535. package/dist/input-DOPL5_QE.js +0 -21
  536. package/dist/input-DOPL5_QE.js.map +0 -1
  537. package/dist/item-BvZ2DR_x.js.map +0 -1
  538. package/dist/message-INU2xsxu.js.map +0 -1
  539. package/dist/metadata-list-qVV7AVxa.js.map +0 -1
  540. package/dist/motion-recipes-ChBg4HBq.js.map +0 -1
  541. package/dist/navigation-BQNcg1jT.js.map +0 -1
  542. package/dist/navigation-DLF3E1IC.js +0 -145
  543. package/dist/navigation-DLF3E1IC.js.map +0 -1
  544. package/dist/navigation-row-recipes-WZEs-hYo.js.map +0 -1
  545. package/dist/overflow-tab-bar-CrbqMteP.js +0 -284
  546. package/dist/overflow-tab-bar-CrbqMteP.js.map +0 -1
  547. package/dist/overlays-BlKynmde.js +0 -1004
  548. package/dist/overlays-BlKynmde.js.map +0 -1
  549. package/dist/page-CIwNUtGr.js +0 -227
  550. package/dist/page-CIwNUtGr.js.map +0 -1
  551. package/dist/page-header-commands-DFMlNYzN.js +0 -128
  552. package/dist/page-header-commands-DFMlNYzN.js.map +0 -1
  553. package/dist/popover-uwzX2vo7.js +0 -198
  554. package/dist/popover-uwzX2vo7.js.map +0 -1
  555. package/dist/popover.recipes-D3j8R8Yp.js.map +0 -1
  556. package/dist/receipt-D789Jwyy.js.map +0 -1
  557. package/dist/rich-text-editor-Cm1dpUpQ.js.map +0 -1
  558. package/dist/rich-text-editor-toolbar-L__e4x47.js.map +0 -1
  559. package/dist/settings-BA2iboic.js.map +0 -1
  560. package/dist/sheet-DoAxTb2J.js +0 -213
  561. package/dist/sheet-DoAxTb2J.js.map +0 -1
  562. package/dist/sidebar-ByqKR_W5.js +0 -512
  563. package/dist/sidebar-ByqKR_W5.js.map +0 -1
  564. package/dist/sidebar-D2iSnGJ7.js +0 -619
  565. package/dist/sidebar-D2iSnGJ7.js.map +0 -1
  566. package/dist/skeleton-CUj8O5Bd.js +0 -264
  567. package/dist/skeleton-CUj8O5Bd.js.map +0 -1
  568. package/dist/smart-card-CqkzQsK-.js +0 -614
  569. package/dist/smart-card-CqkzQsK-.js.map +0 -1
  570. package/dist/table-DH7rozUv.js.map +0 -1
  571. package/dist/tabs-eqVsJZWO.js.map +0 -1
  572. package/dist/text-inputs-DXItiR0O.js.map +0 -1
  573. package/dist/theme-scope-BJ6eE2xt.js +0 -50
  574. package/dist/theme-scope-BJ6eE2xt.js.map +0 -1
  575. package/dist/timelines-DmtztAY_.js.map +0 -1
  576. package/dist/tooltip-B4hjKtoV.js +0 -111
  577. package/dist/tooltip-B4hjKtoV.js.map +0 -1
  578. package/dist/ui-provider-CQCuCBcy.js +0 -136
  579. package/dist/ui-provider-CQCuCBcy.js.map +0 -1
  580. package/dist/upload-C9SA0X-8.js.map +0 -1
  581. package/dist/upload-queue-DhQJiSRc.js.map +0 -1
  582. package/dist/usage-card-DVTRDmGz.js.map +0 -1
  583. package/dist/use-mobile-vaLKwgyf.js +0 -15
  584. package/dist/use-mobile-vaLKwgyf.js.map +0 -1
  585. package/dist/utils-CF3c95Io.js.map +0 -1
  586. package/dist/value-inputs-C0o70p-U.js +0 -980
  587. package/dist/value-inputs-C0o70p-U.js.map +0 -1
  588. package/dist/workspace-9EFVXUyk.js.map +0 -1
@@ -27,7 +27,9 @@ TypeScript, optional component peers or the consumer's application code.
27
27
  in the main region and record facts in the supporting region. A responsibility
28
28
  is a role tag reported by `--roles`; a complete business brief is not a role.
29
29
  2. Use `--role` to inspect a role's mapped owners. Role names accept spaces or
30
- kebab-case. A qualified `themelia-react-ui/<family>#<Symbol>` selector chooses
30
+ kebab-case. A phrase that matches no role stays `unresolved` and may list
31
+ `suggestedRoles` that share its words; retry with one of them only when it
32
+ names the same job. A qualified `themelia-react-ui/<family>#<Symbol>` selector chooses
31
33
  an exact mapped contract when a role has several candidates.
32
34
  3. Select a pattern and repeat `--main` or `--aside` for each subject. Supported
33
35
  patterns are `record-detail`, `collection`, `edit`, `analytics` and `embedded`.
@@ -46,11 +48,23 @@ installed setup and matching versions. An empty additional list does not remove
46
48
  React or Base UI requirements.
47
49
 
48
50
  The record-detail example resolves a route owner and, because support is
49
- requested, a main/support layout. Its `tree.slots` uses actual insertion props
50
- such as `children`, `main` and `aside`. Parent-surface content can receive a
51
+ requested, Page's mapped aside slot. Without support, edit/detail plans recommend narrow when its contract supports that prop. Its `tree.slots` uses actual insertion props
52
+ such as `children` and Page's direct `aside`. Older bundles without Page aside anatomy retain their explicit main/support layout. Parent-surface content can receive a
51
53
  subject Card at that boundary. Already framed owners keep their own surface;
52
54
  variant-dependent owners require inspection before choosing framing.
53
55
 
56
+ Collection plans can place an explicit toolbar need in the table seam:
57
+
58
+ ```sh
59
+ node node_modules/themelia-react-ui/docs/consumer-skill/scripts/map-composition.mjs --pattern collection --main comparison-table --main query-toolbar
60
+ ```
61
+
62
+ The mapped FilterLayout goes into DataTable's topbarContent with compact/clear
63
+ props, and the mapped FilterProvider wraps that table. Supply its definitions,
64
+ activeFilters and onFilterChange using the app's query transport. Toolbar order
65
+ in the request does not matter. Missing/ambiguous table seams or context mappings
66
+ remain unresolved; no detached filter strip or guessed provider is emitted.
67
+
54
68
  For an existing Card boundary:
55
69
 
56
70
  ```sh
@@ -16,6 +16,12 @@ keep placement, width, wrapping and overflow with the surrounding composition.
16
16
  | Reusable subject presentation | Blocks |
17
17
  | Editing/selection/async lifecycle | Features with app callbacks |
18
18
 
19
+ Base controls, layouts and blocks also own their local interaction and
20
+ accessibility; features coordinate a complete business workflow. For choosing
21
+ compound APIs and building token-backed app content, read
22
+ [app-owned composites](custom-composition.md). It includes disclosure sections,
23
+ layer boundaries and a custom comparison seam.
24
+
19
25
  ## Compose from the task
20
26
 
21
27
  Identify the user's next decision before selecting components. Establish fixed
@@ -29,11 +35,11 @@ a detail workspace or a form; they need different information hierarchies.
29
35
  | DataView | Its coordinated query, view and collection lifecycle fits | DataTable with app-owned query transport and native toolbar slots when coordination differs; base Table for presentation without TanStack behavior |
30
36
  | ResourceCell | Identity inside a table cell | Item for independent list entries; MetadataList for label/value facts about one subject |
31
37
  | Page / application shell | Route identity, navigation, content bounds and page commands | Card for an independent subject within that route; do not repeat the same heading merely to frame a table |
32
- | Card | One subject needs a frame and headed regions | `surface="flat" padding="none"` inside an existing boundary; nested DataTable uses its own `surface="flat"` |
38
+ | Card | One subject needs a frame and headed regions | `surface="flat" padding="none"` inside an existing boundary; prefer DataTable directly in the layout, or Card padding="none" with a flat table |
33
39
  | Metric / MetricGrid / MetricBar | A KPI needs formatted value, comparison/trend or peer layout | UsageCard for used/limit quotas; InlineStat for one plain fact, MetadataList for several record facts |
34
40
  | FormField / InlineEdit | A field needs label/hint/error, or isolated save/cancel | Complete feature/overlay for a workflow; app form owns whole-record submission |
35
41
 
36
- For a DataTable composition, put queries in `topbarContent`, exports or collection
42
+ For a DataTable composition, wrap it in FilterProvider and put `FilterLayout variant="compact" showClearFilters` in `topbarContent`, exports or collection
37
43
  tools in `topbarEnd`, selection commands in `bulkActions`, and record commands
38
44
  in `rowActions`. `bulkActions` render in the shared `BatchActionBar`, docked to
39
45
  the viewport while rows are selected (`selectionToolbarPlacement="inline"` keeps
@@ -57,18 +63,22 @@ or supported comparison controls. Avoid automatically appending every hidden
57
63
  column to identity metadata. There is no universal row-line limit: long names,
58
64
  accessibility needs and the task can justify richer rows. Explain the priority.
59
65
  Custom ResourceCell metadata is caller content; use shared supporting typography
60
- and CellStack where its smaller secondary-value contract fits.
66
+ and CellStack where its smaller secondary-value contract fits. ResourceCell draws
67
+ its media circle only when you pass `imageUrl`, `icon` or `fallback`: order and
68
+ invoice identifiers stay plain text, and a person opts in with
69
+ `fallback={<Initials value={name} />}`.
61
70
 
62
71
  Commands need explicit importance as well as scope. Describe page commands by
63
72
  role in Page's header: `primaryAction` is the route's one main command, and
64
73
  `secondaryActions` lists supporting commands in priority order. The header owns
65
74
  their treatment and order: outline secondary buttons, the solid primary button,
66
75
  then a More actions menu for overflow, destructive commands and narrow screens,
67
- which always ends the row. WorkspaceRecordHeader, ResourceHeader, the resource
76
+ which always ends the desktop row. Below 40rem of actual header width, every
77
+ command, including primary, moves into one More actions menu. WorkspaceRecordHeader, ResourceHeader, the resource
68
78
  shells and SettingsShell take the same props and render the same row. Choosing which
69
79
  command is primary, which are `destructive`, and which are `visible` remains an
70
80
  application decision; confirm destructive commands in their handler. Use
71
- `actions` only for non-command controls such as a period select. A back link,
81
+ the compatible direct `actions` prop for non-command controls such as a period select. A back link,
72
82
  export and destructive command should not all inherit the same visual emphasis.
73
83
 
74
84
  ```tsx
@@ -92,7 +102,7 @@ leave the others plain.
92
102
  ```tsx
93
103
  <Page header={{
94
104
  title: member.name,
95
- titleBadges: [{ label: 'Needs attention', tone: 'warning' }],
105
+ slots: { titleSuffix: <Badge tone="warning">Needs attention</Badge> },
96
106
  primaryAction: { label: 'Generate report', onClick: onReport },
97
107
  secondaryActions: [
98
108
  { label: 'Update profile', onClick: onEdit },
@@ -210,7 +220,7 @@ See the [website example](../examples/website.tsx) for both hero and section emp
210
220
 
211
221
  ## Card anatomy
212
222
 
213
- Card surface="card" is the ordinary bordered surface; surface="framed" retains its ring recipe; surface="flat" padding="none" composes within an existing boundary. headerPlacement="frame" places title/icon/actions above an inset body, retaining default corners and using rounded-inner on that body.
223
+ Card surface="card" is the ordinary bordered surface; surface="framed" retains its ring recipe; surface="flat" padding="none" composes within an existing boundary. headerPlacement="frame" places title/icon/actions above an inset body, retaining the surface corner and using rounded-radius on that body.
214
224
 
215
225
  Choose one ordinary Card surface through UIProvider's `card.defaultSurface` and
216
226
  let sibling subjects inherit it. Explicit per-card surfaces win: mixing `card`
@@ -223,9 +233,9 @@ for richer content. Facts and rows follow the same rule: one glyph repeated on
223
233
  every MetadataList item or Item row is decoration, so leave `icon`/media empty.
224
234
 
225
235
  Card `gap` owns spacing between regions; `contentGap` owns direct body-child
226
- spacing; `textGap` owns title/supporting-copy rhythm. `contentGap` is unset by
227
- default, so raw body children retain their inline or caller-owned layout.
228
- Choose `contentGap="xl"` for related siblings and `contentGap="2xl"` for
236
+ spacing; `textGap` owns title/supporting-copy rhythm. Body children default to
237
+ the shared related `xl` gap (16px at default roots).
238
+ Use `contentGap="2xl"` for
229
239
  independent sections. Omit it around an existing Grid/Stack or a single feature
230
240
  that already owns its layout:
231
241
 
@@ -325,26 +335,27 @@ primitives rather than replacing labels and values with undifferentiated Text.
325
335
 
326
336
  ## Menus and controls
327
337
 
328
- PopoverContent type="display" owns substantive-content padding; type="menu" compact collection padding around already-padded rows. Popover and Command share inset="default" and inset="compact" paradigms. Mixed searchable shells use inset="flush"; public header/search/list/footer anatomy owns its insets automatically. CommandInput composes the public Input for control geometry and focus styling; its search region adds only outer spacing. Do not pass padding through className, contentClassName or inline styles. Compact header controls and footer actions align with row highlight edges; header text and footer captions align with row labels. Use PopoverHeader start for a leading control and PopoverFooter caption for supporting content alongside trailing action children. Dividers use the same semantic recipe. density selects vertical row rhythm without changing inline padding. ActionMenu owns action definitions, PopoverMenu searchable selection, DropdownMenu bespoke menu anatomy. Shared appearance preserves their accessible menu/listbox/dialog behavior.
338
+ PopoverContent type="display" owns substantive-content padding; type="menu" compact collection padding around already-padded rows. Popover and Command share inset="default" and inset="compact" paradigms. Mixed searchable shells use inset="flush"; public header/search/list/footer anatomy owns its insets automatically. CommandInput composes the public Input for control geometry and focus styling; its search region adds only outer spacing. Do not pass padding through className, contentClassName or inline styles. Compact header controls and footer actions align with row highlight edges and the search field; header text and footer captions sit one small step inside that edge. Use PopoverHeader start for a leading control and PopoverFooter caption for supporting content alongside trailing action children. Dividers use the same semantic recipe. density selects vertical row rhythm without changing inline padding. ActionMenu owns action definitions, PopoverMenu searchable selection, DropdownMenu bespoke menu anatomy. Shared appearance preserves their accessible menu/listbox/dialog behavior.
329
339
 
330
340
  | Choice | Responsibility |
331
341
  | --- | --- |
332
342
  | PopoverContent type="display" / type="menu" | Display versus collection anatomy and typography |
333
- | inset="default" / "compact" | Full versus half surface-root inset |
343
+ | inset="default" / "compact" | Rich surface inset versus small collection shell |
334
344
  | inset="flush" | Delegate insets to owned regions; not a density |
335
345
  | density="compact" / "default" / "comfortable" | Collection row block rhythm, independent from inline spacing |
336
346
  | size="sm" / "md" / "lg" | Supported control's scale; consult its declaration and provider precedence |
337
347
 
338
- Input, Button, Select and filter-facet triggers share bounded inner corners
339
- and corresponding heights; Card and popup shells use the global outer radius. Omitted sizes inherit the provider; explicit sizes win.
348
+ Input, Button, Select, filter-facet triggers and badges share the default
349
+ `rounded-radius` corner and corresponding heights; Card and popup shells use the
350
+ larger `rounded-surface`. Omitted sizes inherit the provider; explicit sizes win.
340
351
  Keep action/control roots equal when those controls adjoin. Compact menu rows,
341
- surface insets and control sizes remain independent; density can tighten the
342
- inner-radius height bound without changing outer corners.
352
+ surface insets and control sizes remain independent; density does not change
353
+ the corner.
343
354
  Inset segmented children use the supported compound owner's same-height frame.
344
355
 
345
356
  PopoverContent defaults to display/default; Command defaults to compact. An explicit PopoverContent type controls anatomy; explicit inset controls padding and takes precedence over the type's inferred inset. Without type, compact implies menu, other insets imply display. Put type="menu" inset="flush" on PopoverContent for a headed searchable picker. Popover is the interaction root and receives no surface props. PopoverMenu already assembles that picker anatomy; use its declared selection/search props. ComboboxPopup is flush because ComboboxList owns its inset. Do not add another wrapper inset around a normal collection list.
346
357
 
347
- At shipped roots, compact shell padding is 8px; row inline padding is 12px; default row block padding is 8px and minimum height 36px. Compact/comfortable rows use 6/10px block padding and 32/40px minimum heights. Content can grow when it wraps. These are token-derived measurements, not app constants. Flush compact header/footer shell padding matches the list (8px inline). Header text bodies without a leading control and footer captions add the row inset once, aligning text at 20px. Actions keep the 8px shell edge. Nested public slots do not repeat these insets.
358
+ At shipped roots, rich display padding is 24px and compact collection shell padding is 8px; row inline padding is 12px; default row block padding is 8px and minimum height 32px. Compact/comfortable rows use 6/10px block padding and 32/40px minimum heights. Content can grow when it wraps. These are token-derived measurements, not app constants. Flush compact header/footer shell padding matches the list (4px inline). Header text and footer captions add a small xs step (4px) to the md band inset (8px), rather than the full row inset. Actions keep the 4px shell edge. Nested public slots do not repeat these insets.
348
359
 
349
360
  Input frames and outline buttons share the input semantic token; collection dividers use border/60; focus uses ring separately and draws one indicator everywhere (a full-strength edge inside a soft halo). Equal responsibilities share recipes, while different semantic roles retain their own treatment. CommandInput keeps its existing onValueChange search contract and native refs; use the actual public Input through its default composition rather than restyling an unframed native field.
350
361
 
@@ -446,6 +457,40 @@ to the existing shell and retains its typed slots; topbar props and toolbar
446
457
  props are specific to their variants. The low-level TopbarSidebarLayout,
447
458
  SidebarInsetLayout and StackedLayout remain available for deliberate composition.
448
459
 
460
+ Choose the structure before its options: a global Header above navigation, a
461
+ full-height AppSidebar beside the content Header, or the shadcn-style inset page
462
+ beside navigation. The catalogue leads with these three structures and reuses
463
+ the exact AppSidebar example from the Sidebar page. Single/dual navigation,
464
+ attached/floating frames and icon/offcanvas collapse configure a structure.
465
+ Example child destinations are text-only; an explicit child icon is reserved
466
+ for a case where it carries information.
467
+
468
+ Header-first light/dark variants accept `contentSurface="inset"` for a quiet
469
+ secondary canvas around the card-colored main surface; omission keeps plain.
470
+ SidebarInsetLayout retains `surface="inset" | "flush"`, and the sidebar/inset
471
+ presets retain their defaults. AppSidebar/LayoutSidebar `surface="transparent"`
472
+ shares the docked canvas; drawer surfaces remain opaque. This uses the existing
473
+ theme roles and structural roots.
474
+
475
+ The shared global header-height root defaults to 4rem. Use the playground's
476
+ full-viewport `?page=shells&layout=header|sidebar|inset` views to inspect
477
+ the composition, optionally with `&theme=dark`.
478
+
479
+ Sidebar shells accept `slots.sidebar` (primary) and `slots.secondarySidebar`
480
+ (contextual navigation). Each missing region removes its track. `sidebarWidth`
481
+ and `secondarySidebarWidth` size their own expanded region, with the
482
+ shared shell width as fallback. `sidebarPresentation="rail"` selects dedicated
483
+ primary navigation geometry independently of full-sidebar icon collapse. Use SidebarNavigationRail from
484
+ layout/sidebar for area navigation with items, value/onValueChange and
485
+ renderLink; it preserves accessible labels/tooltips and defaults to
486
+ collapsible="none". Its default background surface and divider distinguish it
487
+ from the contextual canvas. The 48px default derives from a 32px action plus
488
+ two 8px insets; full-sidebar icon collapse remains 60px. These are private
489
+ recipes, not extra consumer knobs. SidebarRail remains the collapse affordance.
490
+ The rail also accepts header, beforeNavigation, afterNavigation and footer
491
+ nodes or render callbacks with named state. Header/footer are pinned;
492
+ before/after content scrolls with its navigation.
493
+
449
494
  The shell owns one PageViewport and framing. Give the root a constrained height
450
495
  (`h-svh min-h-0` for full-screen apps). Page owns width, page gutters and
451
496
  header/body rhythm, Card owns its insets, and Stack/Grid owns peer gaps. With
@@ -453,12 +498,49 @@ stacked/contained content, use Page gutter="none" to avoid repeating the shell's
453
498
  Container gutter. Metric card size changes copy/media scale, keeping the default
454
499
  surface inset in ready, loading and error states.
455
500
 
456
- Compose LayoutSidebarProvider around AppSidebar and SidebarTrigger. Use
457
- `adaptTo="container"` on the provider for embedded workspaces: it measures its
458
- own width and switches navigation to the same mobile drawer below 768px, even
459
- on a wide viewport. The default remains viewport-driven. Account/search/page
460
- actions remain application callbacks. Do not add another scroll viewport
461
- inside the page. Header menus retain the header theme through their portal host.
501
+ Keep the dual area rail docked on the left beside the full navigation panel,
502
+ and choose that panel's AppSidebar/LayoutSidebar `collapsible` independently
503
+ of its skin or AppLayout variant. `icon` minimizes it to a second compact
504
+ column, `offcanvas` hides it and leaves only the original rail, and `none`
505
+ keeps it expanded. Current examples default to `icon` and expose a preview
506
+ selector for the same modes; standalone navigation supports the same choice.
507
+ The primary area rail keeps its own `collapsible="none"` policy. One explicit
508
+ trigger controls the contextual panel; selecting an area opens it. At narrow widths the inline cluster pans a
509
+ minimum page canvas while its area rail stays pinned. It preserves the chosen
510
+ expansion state rather than silently minimizing. Do not repeat a contextual
511
+ group heading already supplied by its pinned
512
+ header. KPI peers use MetricGrid. Shared header/page/navigation recipes own the
513
+ spacing; Page remains the one page-padding owner.
514
+
515
+ Compose one LayoutSidebarProvider around the shell and its triggers. Shell slots
516
+ establish named scopes, so AppSidebar, LayoutSidebar and useLayoutSidebar() infer
517
+ their panel ID; ordinary compositions need no repeated IDs or nested provider.
518
+ Manual compositions can pass a panel ID explicitly. `SidebarTrigger panelId`
519
+ targets primary/secondary/aside; omission uses provider `navigationPanel`
520
+ (primary by default). That also selects the Ctrl/Command+B shortcut target;
521
+ keyboardShortcut changes the key or accepts false.
522
+
523
+ Desktop expansion uses openPanels/defaultOpenPanels/onOpenPanelsChange. Closed
524
+ icon panels leave a rail, offcanvas removes their track, and none remains visible.
525
+ Controlled openPanels wins over legacy primary open; otherwise open controls
526
+ primary and the provider owns other regions. defaultOpenPanels defines the
527
+ initial uncontrolled set; without it, defaultOpen keeps its primary meaning.
528
+ Primary changes notify onOpenChange and set changes notify onOpenPanelsChange.
529
+ The app accepts controlled proposals by updating the matching props; additional
530
+ persistence remains application-owned.
531
+
532
+ mobilePanel/onMobilePanelChange select one active undocked drawer, preserving
533
+ desktop preferences. Context presentation is docked/drawer; isMobile is its
534
+ drawer alias, including when a contextual panel undocks on a desktop viewport.
535
+ Other panel/drawer compositions retain default thresholds of 768/1024/1440px
536
+ for primary/secondary/aside against available shell width. The featured dual
537
+ cluster uses `mobileSidebarMode="inline"` to keep the rail and its adjacent
538
+ collapsible panel docked. Use adaptTo="container" on embedded providers to contain
539
+ their drawer and backdrop inside that provider. Essential
540
+ undocked regions need reachable targeted triggers. Account/search/page actions
541
+ remain application callbacks. Do not add another scroll viewport inside Page.
542
+ Use Header partials in shell slots to retain one header/inset owner. Header menus
543
+ retain the header theme through their portal host.
462
544
 
463
545
  Header forwards native attributes, handlers and refs. PageHeader supports
464
546
  textGap="normal" or "dense" without changing control or page insets. Header
@@ -471,12 +553,23 @@ The installed [app-shell recipe](../examples/app-layout.tsx) exports a copyable
471
553
  `WorkspaceLayout` that hosts route children directly. Put `AccountDetailPage` or
472
554
  another route Page inside it. `WorkspaceExamplePage` separately demonstrates a
473
555
  Workspace title, Create callback and narrow measure; replace that example when
474
- composing a real route. This recipe name is local to the copied file; the public
556
+ composing a real route. `WorkspaceRegionsLayout` accepts primaryNavigation and
557
+ sidebarPresentation="rail" for a static SidebarNavigationRail beside contextual
558
+ navigation; omitted primaryNavigation builds the alternative grouped sidebar.
559
+ It coordinates controlled named state under one provider. The app's area rail
560
+ can use useLayoutSidebar('secondary') to open context when an area is selected.
561
+ A defined
562
+ secondarySidebar replacement wins over contextualNavigationGroups; null removes
563
+ that region. Without a replacement, groups build the standard AppSidebar with
564
+ `contextualCollapsible?: AppSidebarProps['collapsible']`, defaulting to `icon`.
565
+ Pass `offcanvas` to hide it or `none` to retain expanded navigation; a supplied
566
+ secondarySidebar owns its own policy. These recipe names are
567
+ local to the copied file; the public
475
568
  `WorkspaceLayout` from `layout/workspace` is the record shell described below.
476
569
 
477
570
  PageViewport owns scrolling and adds no padding. Page defaults to `gutter="lg"`
478
571
  and `padding="lg"` (32px at shipped roots), so it owns inline/block space once.
479
- `narrow` selects centered `md` width; explicit `maxWidth` wins. Header copy
572
+ `narrow` selects centered `md` width (48rem); otherwise an aside selects `xl` (80rem), and a single column uses `lg` (64rem). Explicit `maxWidth` wins over both. Header copy
480
573
  defaults to dense; `textGap="normal"` is an explicit alternative. Do not assume
481
574
  an app shell supplies gutters because it supplies a viewport. Set `gutter="none"`
482
575
  only when an actual parent Container/surface supplies the inline inset, such as
@@ -484,14 +577,33 @@ StackedLayout's contained mode. Block padding remains independent.
484
577
  That contained measure uses the same large gutter as Page; ordinary Container
485
578
  defaults remain unchanged.
486
579
 
580
+
581
+ Page is the canonical route owner for new index/detail/edit screens. Its header
582
+ keeps title, description, back navigation, commands and tabs. Add content through
583
+ `header.slots.beforeTitle`, `titleSuffix`, `afterDescription` and `actions`.
584
+ Each accepts a React node or a callback receiving `{ renderLink, defaultContent }`.
585
+ Compose Badge for a title status and MetadataList for facts below the description;
586
+ there is no automatic metadata item shape or avatar column. Title, description and afterDescription stay in one tight left copy column;
587
+ actions occupy a separate right column aligned to the top. beforeTitle spans
588
+ above the columns, and tabs sit below. An actions renderer
589
+ can wrap or return `defaultContent` to retain the responsive command row; replacing
590
+ it owns its own command semantics. Legacy `slots.back`, `titleBadges`, `titleIcon`
591
+ and direct `actions` remain compatible. Direct toolbar, aside and lifecycle props compose at that
592
+ same boundary; explicit slots override matching direct regions. beforeHeader
593
+ precedes the header; afterHeader is the compatible toolbar fallback. Loading
594
+ precedes error, then empty, replacing only the main body while the header,
595
+ toolbar and aside remain mounted. Customize state strings or loading/error/empty
596
+ slots and wire onRetry. ResourceHeader/ResourceIndexShell/ResourceShowShell/
597
+ TabbedResourceShell retain legacy embedding behavior for migration.
598
+
487
599
  Select width from the task: a single focused resource/form can use `narrow`;
488
- a record with a supporting aside can retain the default `lg` measure and use
489
- TwoColumnLayout. A wide comparison/directory can deliberately use `maxWidth="full"`.
600
+ a record with supporting context uses Page `aside` and infers `xl` (80rem).
601
+ An explicit TwoColumnLayout inside Page should set `maxWidth="xl"`; it retains its own split contract. A wide comparison/directory can deliberately use `maxWidth="full"`.
490
602
  Setting full on every route defeats the resource measure. Do not remove Page's
491
603
  gutters to make its title touch the sidebar; align the header and body through
492
604
  the same Page. Density, container measure and page inset are separate choices.
493
605
  The [detail recipe](../examples/detail.tsx) includes `AccountDetailPage`: the
494
- default record measure, a status badge, route-level commands and section tabs in
606
+ narrow record measure, a status badge, route-level commands and section tabs in
495
607
  the header, and MetadataList facts in one framed Card, with no duplicated subject
496
608
  header or gutter.
497
609
 
@@ -499,9 +611,23 @@ Compose HeaderUserMenu in topbar `slots.headerEnd` or a local toolbar, and
499
611
  SidebarNavigationUser in AppSidebar `slots.footer` when account access belongs
500
612
  in navigation. Use SidebarWorkspaceDropdown for workspace links, or add a
501
613
  custom control through `slots.headerEnd` alongside the logo. `headerStart` and
502
- `headerEnd` stay inside the padded, fixed header; `slots.header` replaces it all.
503
- `beforeNavigation` scrolls with the links. SidebarFooter owns its rule and inset.
504
- LayoutSidebarProvider defaults to compact row gaps; explicit density still wins.
614
+ `headerEnd` stay inside the padded, fixed header. The four header,
615
+ beforeNavigation, afterNavigation and footer slots accept nodes or callbacks
616
+ receiving `{ panelId, collapsed, presentation, isMobile, renderLink, defaultContent }`.
617
+ A legacy header node replaces the entire header; a callback supplies content
618
+ inside its library-owned inset. Both footer forms retain SidebarFooter's rule and
619
+ inset. Before/after navigation content scrolls with the links, so tall supporting
620
+ content belongs there. Ordered `{ id, label?, items }` navigation groups supplement
621
+ the Record form; use stable item IDs for branch state and live badges.
622
+ renderItemContent changes noninteractive row content while preserving the owning
623
+ link/disclosure/focus treatment; renderItem remains the full row escape hatch.
624
+ Current matching selects the most-specific href; render contexts expose ancestor
625
+ state separately from current active state. In icon mode, searchable
626
+ AppSidebar preserves its search band as an icon button that expands and focuses
627
+ the field without clearing the query. LayoutSidebarProvider defaults to
628
+ comfortable rows with a shared xs gap. Default keeps that gap with smaller
629
+ rows; compact uses a tighter 2xs gap. Caption and group spacing keep their own
630
+ larger roles. Explicit density still wins.
505
631
  WorkspaceLayout owns its own bounded content inset; do not add a padded Page
506
632
  inside it. WorkspaceRecordHeader and WorkspaceLocaleStrip align to the same
507
633
  large inline surface role. Record copy supports textGap with a dense default.
@@ -526,3 +652,5 @@ formatted-value and structure owners. Drawn rings and mini charts retain private
526
652
  geometry and semantic chart/status colors. Read the
527
653
  [workflow contracts](workflows.md#task-summaries-usage-and-inline-editing) and
528
654
  [typed workspace recipe](../examples/planning-usage-edit.tsx) for integration.
655
+
656
+ Explicit `type="display" inset="compact"` retains the small rich-surface tier (12px); collection compact insets use 8px. Display/default remains 24px. Chart tooltips and explicit small async previews retain their rich-content surface sizing.
@@ -0,0 +1,98 @@
1
+ # Critique rubric
2
+
3
+ Use to judge a rendered view: after building one, before handing it back, or when
4
+ reviewing someone else's screen. Judge screenshots and measurements, not source.
5
+ Valid API usage, passing checks and a correct data model do not make a view
6
+ clear.
7
+
8
+ Render the view at 390×844 and 1440×900, in light and dark, with the states the
9
+ task touches (opened menu or editor, error, accepted). Run the census below at
10
+ each width, then score every criterion.
11
+
12
+ ## Criteria
13
+
14
+ Score each criterion 0 (fails), 1 (partly) or 2 (passes). Criteria marked
15
+ **blocking** must score 2 before the work is handed back.
16
+
17
+ | # | Criterion | Question | How to measure |
18
+ | --- | --- | --- | --- |
19
+ | 1 | Five-second test (**blocking**) | From the first viewport alone, can you say what this is, what state it is in and what to do next? | Write the three answers from the screenshot before reading source. Compare them with the data brief's decision and facts |
20
+ | 2 | Focal point | Is there one dominant element per view and per region, and is it the one the brief chose? | Look at a reduced screenshot; census `focalCandidates` lists the largest text and its position. The focal element is in the first viewport at both widths |
21
+ | 3 | Hierarchy (**blocking**) | Does each region use at most three text levels, ordered title, value, supporting? | Census `regions[].textLevels`; above 4 needs a reason (a badge or a value primitive's secondary part). Compare `textStyles` outliers with their owners |
22
+ | 4 | Emphasis budget | One solid primary command per page or surface; tones only where status changes the action? | Census `primaryCommands`: 0 means the next action has no emphasis, 2 or more on one surface means competition. Read each toned badge and name the status it states |
23
+ | 5 | Data integrity (**blocking**) | Do figures, units, signs and totals match the records; zero and missing differ; nothing invented? | Check three figures against the data and recompute one total or delta |
24
+ | 6 | Encoding fit | Does each chart answer a question you can write in one sentence, and does each table compare rows on shared columns? | Write the question beside each chart. Name the compared column for each table |
25
+ | 7 | Grouping and rhythm | Do gaps grow from within a group to between groups to between sections, without filler or box-in-box? | Census `regions[].insideFrame` lists frames inside frames. Measure sibling gaps in the DOM; equal gaps at every level fail |
26
+ | 8 | Alignment | Do peer regions share content start edges, and do numbers right-align on one axis? | Census `regions[].left` and `inset`: peers differ by at most 1px. A leading badge adds its own padding to `inset`; check it in the image |
27
+ | 9 | Narrow reading order | At 390 wide, does the decision content come before evidence, with no sideways page scroll? | `overflowX` is 0. Scroll position of the focal element and the primary command. Tables may scroll inside their own region |
28
+ | 10 | Theme and states | Does dark keep the same hierarchy and contrast, and are loading, empty, error and accepted states designed? | Dark screenshots of the same viewports; trigger each state the view supports |
29
+
30
+ Hand back at 16 of 20 or more with every blocking criterion at 2. Otherwise fix
31
+ the lowest-scoring criterion at its owner and score again. After three rounds,
32
+ stop and report what remains and why.
33
+
34
+ ## Census
35
+
36
+ Run in the page through the browser tool's JavaScript evaluation. It reads
37
+ computed styles only and changes nothing.
38
+
39
+ ```js
40
+ (() => {
41
+ const shown = el => { const r = el.getBoundingClientRect(); const s = getComputedStyle(el); return r.width > 0 && r.height > 0 && s.visibility !== 'hidden' && s.opacity !== '0'; };
42
+ const hasText = el => [...el.childNodes].some(node => node.nodeType === 3 && node.textContent.trim());
43
+ const words = el => (el.getAttribute('aria-label') || el.textContent || '').trim().replace(/\s+/g, ' ').slice(0, 40);
44
+ const probe = document.body.appendChild(Object.assign(document.createElement('span'), { style: 'background: var(--primary)' }));
45
+ const primary = getComputedStyle(probe).backgroundColor; probe.remove();
46
+ const all = [...document.querySelectorAll('body *')].filter(shown);
47
+ const texts = all.filter(hasText);
48
+ const style = el => { const s = getComputedStyle(el); return `${s.fontSize} ${s.fontWeight}`; };
49
+ const isFrame = el => { const s = getComputedStyle(el); const r = el.getBoundingClientRect();
50
+ return ['Top', 'Right', 'Bottom', 'Left'].every(side => parseFloat(s[`border${side}Width`]) > 0) && r.height >= 64 && r.width >= 160
51
+ && !el.matches('input, textarea, select, button, [role="combobox"], [role="group"]') && !el.querySelector('h1'); };
52
+ const frames = all.filter(isFrame);
53
+ const owner = el => frames.filter(frame => frame !== el && frame.contains(el)).at(-1);
54
+ const regions = frames.map(frame => {
55
+ const own = texts.filter(el => frame.contains(el) && owner(el) === frame);
56
+ const first = own[0];
57
+ return { region: first ? words(first) : '(no text)', top: Math.round(frame.getBoundingClientRect().top + scrollY), left: Math.round(frame.getBoundingClientRect().left),
58
+ inset: first ? Math.round(first.getBoundingClientRect().left - frame.getBoundingClientRect().left) : null,
59
+ textLevels: new Set(own.map(style)).size, insideFrame: owner(frame) ? words(texts.find(el => owner(frame).contains(el)) || owner(frame)) : null };
60
+ }).sort((a, b) => a.top - b.top || a.left - b.left);
61
+ const counts = new Map(texts.map(style).map(key => [key, 0]));
62
+ for (const el of texts) counts.set(style(el), counts.get(style(el)) + 1);
63
+ return {
64
+ viewport: `${innerWidth}x${innerHeight}`,
65
+ overflowX: document.documentElement.scrollWidth - document.documentElement.clientWidth,
66
+ primaryCommands: all.filter(el => el.matches('button, a') && getComputedStyle(el).backgroundColor === primary).map(words),
67
+ focalCandidates: texts.map(el => ({ el, size: parseFloat(getComputedStyle(el).fontSize) })).sort((a, b) => b.size - a.size).slice(0, 3).map(({ el, size }) => `${size}px ${words(el)} @${Math.round(el.getBoundingClientRect().top + scrollY)}`),
68
+ textStyles: [...counts].sort((a, b) => b[1] - a[1]).map(([key, count]) => `${key} ×${count}`),
69
+ regions,
70
+ };
71
+ })()
72
+ ```
73
+
74
+ The census lists signals, not verdicts. The application shell's frame (any frame
75
+ containing the page `h1`) is excluded. Frames are bordered regions at least
76
+ 160×64px, so tables, cards and drawers appear. A surface without a border is not
77
+ listed: judge it in the image.
78
+
79
+ ## Write findings
80
+
81
+ One finding per problem, most severe first:
82
+
83
+ ```text
84
+ [criterion #] <where: route, region, width/theme>
85
+ Seen: <what the screenshot or census shows>
86
+ Why it matters: <the user's decision or reading it harms>
87
+ Fix: <owner and prop, or the content to remove or move>
88
+ ```
89
+
90
+ A finding names the owner that should change. "Looks cluttered" is not a
91
+ finding; "Purchased goods uses 9 text levels at 1440, so quantity, SKU and
92
+ location compete with the product name" is.
93
+
94
+ ## Report the score
95
+
96
+ State the score per criterion, with the measurement behind each 1 or 0, for
97
+ every width and theme inspected. Say which states were not rendered: an
98
+ unrendered state is unverified, not passed.