@kerfjs/ui 5.0.0-beta.97 → 5.0.0-beta.99

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 (416) hide show
  1. package/README.md +42 -1
  2. package/ai/application-ui-diagnostic-ids-v1.json +1 -0
  3. package/ai/component-catalog.json +487 -66
  4. package/ai/component-catalog.schema.json +1 -1
  5. package/ai/component-composition-rules.json +22 -2
  6. package/ai/component-composition.json +360 -33
  7. package/ai/component-composition.schema.json +1 -1
  8. package/ai/components/README.md +18 -17
  9. package/ai/components/anchored-surface.md +13 -0
  10. package/ai/components/application-tabs.md +1 -1
  11. package/ai/components/chip.md +9 -5
  12. package/ai/components/choice-chips.md +15 -8
  13. package/ai/components/collapsible-panel.md +3 -2
  14. package/ai/components/composer.md +83 -0
  15. package/ai/components/content-item.md +2 -2
  16. package/ai/components/corner-status.md +1 -1
  17. package/ai/components/document-baseline.md +3 -3
  18. package/ai/components/foundation.md +2 -2
  19. package/ai/components/layout.md +1 -1
  20. package/ai/components/list-action-row.md +5 -1
  21. package/ai/components/list-item.md +5 -1
  22. package/ai/components/list.md +19 -3
  23. package/ai/components/nav-stack.md +11 -2
  24. package/ai/components/pane.md +13 -4
  25. package/ai/components/popup-menu.md +4 -4
  26. package/ai/components/recipe-app-shell.md +3 -3
  27. package/ai/components/recipe-collapsible-sidebar.md +3 -3
  28. package/ai/components/recipe-compact-toolbar.md +1 -1
  29. package/ai/components/recipe-composer-form.md +3 -3
  30. package/ai/components/recipe-list-detail-dialog.md +2 -2
  31. package/ai/components/recipe-list-workspace-states.md +3 -3
  32. package/ai/components/recipe-loading-inspector.md +1 -1
  33. package/ai/components/recipe-navigation-sidebar.md +3 -3
  34. package/ai/components/recipe-navigation-stack.md +3 -3
  35. package/ai/components/recipe-workspace-header.md +3 -3
  36. package/ai/components/resize.md +2 -2
  37. package/ai/components/split-view.md +4 -2
  38. package/ai/components/sunken-panel.md +2 -2
  39. package/ai/components/surface-scaffold.md +15 -3
  40. package/ai/components/tab-bar.md +1 -0
  41. package/ai/components/tab-navigator.md +4 -0
  42. package/ai/components/toolbar-control-group.md +2 -0
  43. package/ai/components/toolbar-text.md +1 -0
  44. package/ai/components/toolbar.md +1 -0
  45. package/ai/components/workbench.md +1 -0
  46. package/ai/public-api-signatures-v1.md +504 -80
  47. package/ai/skill.md +41 -14
  48. package/ai/webawesome-jsx-signatures-v1.md +1 -1
  49. package/analyzer/component-ownership.mjs +1 -1
  50. package/analyzer/index.mjs +41 -14
  51. package/dist/anchored-surface.d.ts +30 -2
  52. package/dist/anchored-surface.js +1 -1
  53. package/dist/app-tab.js +1 -1
  54. package/dist/browser/composer.js +4 -0
  55. package/dist/catalog-resources.d.ts +3 -2
  56. package/dist/catalog-resources.js +4 -4
  57. package/dist/catalog-resources.js.map +1 -1
  58. package/dist/catalog.d.ts +39 -8
  59. package/dist/catalog.js +55 -32
  60. package/dist/catalog.js.map +1 -1
  61. package/dist/chip.d.ts +41 -9
  62. package/dist/chip.js +1 -1
  63. package/dist/choice-chips.d.ts +40 -16
  64. package/dist/choice-chips.js +1 -1
  65. package/dist/chunk-34U4ANDJ.js +119 -0
  66. package/dist/chunk-34U4ANDJ.js.map +1 -0
  67. package/dist/{chunk-36TL6BCR.js → chunk-3GLYIIFR.js} +34 -6
  68. package/dist/chunk-3GLYIIFR.js.map +1 -0
  69. package/dist/{chunk-HWY4BSLS.js → chunk-3VXDSIBJ.js} +2 -2
  70. package/dist/{chunk-HWY4BSLS.js.map → chunk-3VXDSIBJ.js.map} +1 -1
  71. package/dist/chunk-3WYREXW4.js +120 -0
  72. package/dist/chunk-3WYREXW4.js.map +1 -0
  73. package/dist/chunk-AV7CPAPT.js +82 -0
  74. package/dist/chunk-AV7CPAPT.js.map +1 -0
  75. package/dist/{chunk-XK4E225T.js → chunk-B53PS2LE.js} +2 -2
  76. package/dist/{chunk-XK4E225T.js.map → chunk-B53PS2LE.js.map} +1 -1
  77. package/dist/{chunk-R42D2BAO.js → chunk-CA7LNX3J.js} +2 -2
  78. package/dist/{chunk-R42D2BAO.js.map → chunk-CA7LNX3J.js.map} +1 -1
  79. package/dist/{chunk-AYHC62OZ.js → chunk-CMETHPKR.js} +26 -29
  80. package/dist/chunk-CMETHPKR.js.map +1 -0
  81. package/dist/{chunk-Y43B6DS3.js → chunk-CVD5IZGB.js} +2 -2
  82. package/dist/{chunk-Y43B6DS3.js.map → chunk-CVD5IZGB.js.map} +1 -1
  83. package/dist/{chunk-6STQXRT4.js → chunk-CXZXHZTR.js} +121 -12
  84. package/dist/chunk-CXZXHZTR.js.map +1 -0
  85. package/dist/{chunk-GZE2XVKC.js → chunk-DZJ4GBSP.js} +3 -3
  86. package/dist/{chunk-GZE2XVKC.js.map → chunk-DZJ4GBSP.js.map} +1 -1
  87. package/dist/chunk-ELCMSQNJ.js +49 -0
  88. package/dist/chunk-ELCMSQNJ.js.map +1 -0
  89. package/dist/{chunk-P74VXMB6.js → chunk-EOO6PYGF.js} +7 -14
  90. package/dist/chunk-EOO6PYGF.js.map +1 -0
  91. package/dist/{chunk-PRG4CL3Q.js → chunk-FR76ZJQC.js} +21 -19
  92. package/dist/chunk-FR76ZJQC.js.map +1 -0
  93. package/dist/{chunk-QQ3TTWFH.js → chunk-G3J7JDP6.js} +1 -1
  94. package/dist/{chunk-QQ3TTWFH.js.map → chunk-G3J7JDP6.js.map} +1 -1
  95. package/dist/{chunk-IGTWXPTN.js → chunk-HGV7J4T6.js} +3 -3
  96. package/dist/{chunk-IGTWXPTN.js.map → chunk-HGV7J4T6.js.map} +1 -1
  97. package/dist/{chunk-YWQGSUF2.js → chunk-HLDRH23D.js} +3 -3
  98. package/dist/{chunk-YWQGSUF2.js.map → chunk-HLDRH23D.js.map} +1 -1
  99. package/dist/{chunk-PBT3CPPY.js → chunk-HQZYKJ56.js} +24 -4
  100. package/dist/chunk-HQZYKJ56.js.map +1 -0
  101. package/dist/{chunk-V6W56V3N.js → chunk-HZPHCSCS.js} +16 -3
  102. package/dist/chunk-HZPHCSCS.js.map +1 -0
  103. package/dist/{chunk-GJYQ27C2.js → chunk-INI4WDWC.js} +8 -1
  104. package/dist/chunk-INI4WDWC.js.map +1 -0
  105. package/dist/{chunk-U657IHFB.js → chunk-IQSRHXZR.js} +10 -4
  106. package/dist/chunk-IQSRHXZR.js.map +1 -0
  107. package/dist/{chunk-KQDU7Z7P.js → chunk-K4AT3V3J.js} +2 -1
  108. package/dist/chunk-K4AT3V3J.js.map +1 -0
  109. package/dist/{chunk-QIAPOWHH.js → chunk-KCS6NJ3O.js} +2 -2
  110. package/dist/{chunk-QIAPOWHH.js.map → chunk-KCS6NJ3O.js.map} +1 -1
  111. package/dist/{chunk-UKKRPP56.js → chunk-LOSRXZAH.js} +2 -2
  112. package/dist/{chunk-UKKRPP56.js.map → chunk-LOSRXZAH.js.map} +1 -1
  113. package/dist/{chunk-ROZLJULF.js → chunk-MF6ZUUJZ.js} +8 -3
  114. package/dist/chunk-MF6ZUUJZ.js.map +1 -0
  115. package/dist/{chunk-6IVNMC6R.js → chunk-MHMWQ7RB.js} +2 -2
  116. package/dist/{chunk-6IVNMC6R.js.map → chunk-MHMWQ7RB.js.map} +1 -1
  117. package/dist/{chunk-JYD7G4RG.js → chunk-PIVY32AE.js} +15 -5
  118. package/dist/chunk-PIVY32AE.js.map +1 -0
  119. package/dist/{chunk-BU23Z5HZ.js → chunk-PYBBYSZ3.js} +13 -18
  120. package/dist/chunk-PYBBYSZ3.js.map +1 -0
  121. package/dist/chunk-QDSZTQXL.js +28 -0
  122. package/dist/chunk-QDSZTQXL.js.map +1 -0
  123. package/dist/{chunk-YXOMI7ES.js → chunk-QIG4IGUP.js} +2 -2
  124. package/dist/{chunk-YXOMI7ES.js.map → chunk-QIG4IGUP.js.map} +1 -1
  125. package/dist/{chunk-6BRRUPJY.js → chunk-QROYYGWU.js} +3 -3
  126. package/dist/chunk-QROYYGWU.js.map +1 -0
  127. package/dist/{chunk-FOQK4F3L.js → chunk-RHD7RKGI.js} +28 -7
  128. package/dist/chunk-RHD7RKGI.js.map +1 -0
  129. package/dist/{chunk-BBU2SPRE.js → chunk-T4WJ5VGP.js} +4 -4
  130. package/dist/{chunk-BBU2SPRE.js.map → chunk-T4WJ5VGP.js.map} +1 -1
  131. package/dist/{chunk-6NOLL5KG.js → chunk-TGLUDQP2.js} +3 -3
  132. package/dist/{chunk-6NOLL5KG.js.map → chunk-TGLUDQP2.js.map} +1 -1
  133. package/dist/{chunk-HO6FU3G7.js → chunk-TLMMFQWM.js} +4 -4
  134. package/dist/{chunk-HO6FU3G7.js.map → chunk-TLMMFQWM.js.map} +1 -1
  135. package/dist/chunk-UMKV7YVQ.js +20 -0
  136. package/dist/chunk-UMKV7YVQ.js.map +1 -0
  137. package/dist/{chunk-M2NRCFRO.js → chunk-VFYO3UGZ.js} +2 -2
  138. package/dist/{chunk-M2NRCFRO.js.map → chunk-VFYO3UGZ.js.map} +1 -1
  139. package/dist/{chunk-YOKEL75M.js → chunk-WVS6CUCT.js} +2 -2
  140. package/dist/{chunk-YOKEL75M.js.map → chunk-WVS6CUCT.js.map} +1 -1
  141. package/dist/{chunk-MN3POJFN.js → chunk-YMUIQRWK.js} +2 -2
  142. package/dist/{chunk-MN3POJFN.js.map → chunk-YMUIQRWK.js.map} +1 -1
  143. package/dist/{chunk-Y3LC7JQO.js → chunk-YOA5W5ZH.js} +2 -2
  144. package/dist/{chunk-Y3LC7JQO.js.map → chunk-YOA5W5ZH.js.map} +1 -1
  145. package/dist/{chunk-44A6LP54.js → chunk-YQ2AC4E2.js} +2 -2
  146. package/dist/{chunk-44A6LP54.js.map → chunk-YQ2AC4E2.js.map} +1 -1
  147. package/dist/chunk-ZNROKDSZ.js +54 -0
  148. package/dist/chunk-ZNROKDSZ.js.map +1 -0
  149. package/dist/collapsible-panel.d.ts +3 -2
  150. package/dist/collapsible-panel.js +4 -3
  151. package/dist/collapsible-panel.js.map +1 -1
  152. package/dist/composer.d.ts +62 -0
  153. package/dist/composer.js +5 -0
  154. package/dist/composer.js.map +1 -0
  155. package/dist/corner-status.d.ts +1 -1
  156. package/dist/corner-status.js +1 -1
  157. package/dist/css-values.d.ts +9 -1
  158. package/dist/css-values.js +1 -1
  159. package/dist/disclosure-arrow.js +1 -1
  160. package/dist/empty-state.js +1 -1
  161. package/dist/grid.js +1 -1
  162. package/dist/icon-button.js +1 -1
  163. package/dist/icon-toggle-button.js +1 -1
  164. package/dist/index.d.ts +10 -5
  165. package/dist/index.js +40 -37
  166. package/dist/list-action-row.d.ts +10 -2
  167. package/dist/list-action-row.js +1 -1
  168. package/dist/list-header.js +1 -1
  169. package/dist/list-icon-tile-B8dr97OW.d.ts +18 -0
  170. package/dist/list-item.d.ts +10 -3
  171. package/dist/list-item.js +1 -1
  172. package/dist/list.d.ts +36 -4
  173. package/dist/list.js +1 -1
  174. package/dist/loading-spinner.js +1 -1
  175. package/dist/lucide-icon.js +1 -1
  176. package/dist/{nav-stack-BvSKY448.d.ts → nav-stack-VXTumzKa.d.ts} +53 -4
  177. package/dist/nav-stack.d.ts +3 -2
  178. package/dist/nav-stack.js +2 -1
  179. package/dist/pane.d.ts +40 -3
  180. package/dist/pane.js +1 -1
  181. package/dist/{panel-toolbar-CL9tYOkh.d.ts → panel-toolbar-vg6Ir5Dy.d.ts} +6 -1
  182. package/dist/popup-menu-register.d.ts +2 -1
  183. package/dist/popup-menu-register.js +97 -22
  184. package/dist/popup-menu-register.js.map +1 -1
  185. package/dist/popup-menu.js +1 -1
  186. package/dist/row.js +1 -1
  187. package/dist/scroll-clearance-BikHljTc.d.ts +14 -0
  188. package/dist/select-register.js +11 -0
  189. package/dist/select-register.js.map +1 -1
  190. package/dist/select.js +1 -1
  191. package/dist/skeleton.js +1 -1
  192. package/dist/spacer.js +1 -1
  193. package/dist/split-button.js +1 -1
  194. package/dist/split-view.d.ts +7 -5
  195. package/dist/split-view.js +6 -3
  196. package/dist/split-view.js.map +1 -1
  197. package/dist/state-banner.d.ts +6 -1
  198. package/dist/state-banner.js +1 -1
  199. package/dist/styles/anchored-surface.css +27 -1
  200. package/dist/styles/catalog/components/catalog-example-stack.css +5 -0
  201. package/dist/styles/catalog/components/catalog-example.css +33 -0
  202. package/dist/styles/catalog/components/catalog-stage.css +7 -0
  203. package/dist/styles/chip.css +70 -0
  204. package/dist/styles/components/actions/popup-menu/popup-menu.css +21 -4
  205. package/dist/styles/components/actions/toolbar/toolbar.css +19 -0
  206. package/dist/styles/components/actions/toolbar-control-group/toolbar-control-group.css +75 -1
  207. package/dist/styles/components/actions/toolbar-text/toolbar-text.css +75 -0
  208. package/dist/styles/components/collections/list/list.css +77 -7
  209. package/dist/styles/components/collections/list-action-row/list-action-row.css +177 -22
  210. package/dist/styles/components/collections/list-item/list-item.css +158 -11
  211. package/dist/styles/components/feedback/anchored-surface/anchored-surface.css +27 -1
  212. package/dist/styles/components/feedback/chip/chip.css +70 -0
  213. package/dist/styles/components/feedback/state-banner/state-banner.css +24 -13
  214. package/dist/styles/components/forms/composer/composer.css +100 -0
  215. package/dist/styles/components/forms/select/select.css +1 -0
  216. package/dist/styles/components/forms/token-search-field/token-search-field.css +13 -2
  217. package/dist/styles/components/layout/pane/pane.css +81 -2
  218. package/dist/styles/components/navigation/nav-stack/nav-stack.css +84 -0
  219. package/dist/styles/components/navigation/tab-bar/tab-bar.css +15 -4
  220. package/dist/styles/components/navigation/tab-navigator/tab-navigator.css +79 -4
  221. package/dist/styles/components/surfaces/surface-scaffold/surface-scaffold.css +195 -0
  222. package/dist/styles/composer.css +100 -0
  223. package/dist/styles/foundation.css +66 -0
  224. package/dist/styles/list-action-row.css +177 -22
  225. package/dist/styles/list-item.css +158 -11
  226. package/dist/styles/list.css +77 -7
  227. package/dist/styles/nav-stack.css +84 -0
  228. package/dist/styles/pane.css +81 -2
  229. package/dist/styles/popup-menu.css +21 -4
  230. package/dist/styles/select.css +1 -0
  231. package/dist/styles/state-banner.css +24 -13
  232. package/dist/styles/styles.css +1 -0
  233. package/dist/styles/surface-scaffold.css +195 -0
  234. package/dist/styles/tab-bar.css +15 -4
  235. package/dist/styles/tab-navigator.css +79 -4
  236. package/dist/styles/token-search-field.css +13 -2
  237. package/dist/styles/toolbar-control-group.css +75 -1
  238. package/dist/styles/toolbar-text.css +75 -0
  239. package/dist/styles/toolbar.css +19 -0
  240. package/dist/styles/webawesome.css +18 -0
  241. package/dist/surface-scaffold-register.d.ts +6 -1
  242. package/dist/surface-scaffold-register.js +89 -3
  243. package/dist/surface-scaffold-register.js.map +1 -1
  244. package/dist/surface-scaffold.d.ts +66 -7
  245. package/dist/surface-scaffold.js +1 -1
  246. package/dist/tab-navigator.d.ts +23 -2
  247. package/dist/tab-navigator.js +2 -0
  248. package/dist/tab-navigator.js.map +1 -1
  249. package/dist/token-search-field.d.ts +1 -1
  250. package/dist/token-search-field.js +1 -1
  251. package/dist/{token-search-model-DTcTXWMS.d.ts → token-search-model-aYR0YAei.d.ts} +32 -2
  252. package/dist/token-search-model.d.ts +1 -1
  253. package/dist/toolbar-control-group.js +1 -1
  254. package/dist/toolbar-text.js +1 -1
  255. package/dist/toolbar.d.ts +1 -0
  256. package/dist/value-table.js +1 -1
  257. package/dist/wire-catalog.d.ts +3 -2
  258. package/dist/wire-catalog.js +2 -2
  259. package/dist/wire-composers.d.ts +16 -0
  260. package/dist/wire-composers.js +3 -0
  261. package/dist/wire-composers.js.map +1 -0
  262. package/dist/wire-list-focus-scroll.d.ts +16 -0
  263. package/dist/wire-list-focus-scroll.js +3 -0
  264. package/dist/wire-list-focus-scroll.js.map +1 -0
  265. package/dist/wire-nav-stack.js +135 -0
  266. package/dist/wire-nav-stack.js.map +1 -1
  267. package/dist/wire-scroll-dividers.d.ts +9 -0
  268. package/dist/wire-scroll-dividers.js +1 -1
  269. package/dist/wire-tab-bars.js +1 -1
  270. package/dist/wire-tab-navigator.d.ts +3 -1
  271. package/dist/wire-tab-navigator.js +133 -1
  272. package/dist/wire-tab-navigator.js.map +1 -1
  273. package/dist/wire-token-search-fields.d.ts +1 -1
  274. package/dist/wire-token-search-fields.js +1 -1
  275. package/dist/workbench.d.ts +8 -3
  276. package/dist/workbench.js +2 -1
  277. package/docs/accessibility.md +132 -3
  278. package/docs/anchored-surface.md +46 -4
  279. package/docs/app-layouts.md +23 -2
  280. package/docs/apple-hig.md +1 -0
  281. package/docs/catalog.md +61 -9
  282. package/docs/collapsible-panel.md +9 -6
  283. package/docs/component-contract.md +46 -13
  284. package/docs/component-selection.md +147 -20
  285. package/docs/composer.md +143 -0
  286. package/docs/design/templates/choice-chips/multiple-dark.svg +1 -0
  287. package/docs/design/templates/choice-chips/multiple.svg +1 -0
  288. package/docs/design/templates/choice-chips-dark.svg +1 -1
  289. package/docs/design/templates/choice-chips.svg +1 -1
  290. package/docs/design/templates/composer/chat-dark.svg +1 -0
  291. package/docs/design/templates/composer/chat.svg +1 -0
  292. package/docs/design/templates/composer/prompt-dark.svg +1 -0
  293. package/docs/design/templates/composer/prompt.svg +1 -0
  294. package/docs/design/templates/composer-dark.svg +1 -0
  295. package/docs/design/templates/composer.svg +1 -0
  296. package/docs/design/templates/empty-state/filtered-dark.svg +1 -1
  297. package/docs/design/templates/empty-state/filtered.svg +1 -1
  298. package/docs/design/templates/empty-state/with-action-dark.svg +1 -1
  299. package/docs/design/templates/empty-state/with-action.svg +1 -1
  300. package/docs/design/templates/empty-state-dark.svg +1 -1
  301. package/docs/design/templates/empty-state.svg +1 -1
  302. package/docs/design/templates/list/compact-dark.svg +1 -1
  303. package/docs/design/templates/list/compact.svg +1 -1
  304. package/docs/design/templates/list-action-row/default-dark.svg +1 -1
  305. package/docs/design/templates/list-action-row/default.svg +1 -1
  306. package/docs/design/templates/list-action-row/icon-tile-dark.svg +1 -0
  307. package/docs/design/templates/list-action-row/icon-tile.svg +1 -0
  308. package/docs/design/templates/list-action-row/selected-dark.svg +1 -1
  309. package/docs/design/templates/list-action-row/selected.svg +1 -1
  310. package/docs/design/templates/list-action-row/trailing-menu-dark.svg +1 -1
  311. package/docs/design/templates/list-action-row/trailing-menu.svg +1 -1
  312. package/docs/design/templates/list-action-row-dark.svg +1 -1
  313. package/docs/design/templates/list-action-row.svg +1 -1
  314. package/docs/design/templates/list-dark.svg +1 -1
  315. package/docs/design/templates/list-header/size-l-dark.svg +1 -1
  316. package/docs/design/templates/list-header/size-l.svg +1 -1
  317. package/docs/design/templates/list-header/size-m-dark.svg +1 -1
  318. package/docs/design/templates/list-header/size-m.svg +1 -1
  319. package/docs/design/templates/list-header/size-xl-dark.svg +1 -1
  320. package/docs/design/templates/list-header/size-xl.svg +1 -1
  321. package/docs/design/templates/list-header-dark.svg +1 -1
  322. package/docs/design/templates/list-header.svg +1 -1
  323. package/docs/design/templates/list-item/icon-tile-dark.svg +1 -0
  324. package/docs/design/templates/list-item/icon-tile.svg +1 -0
  325. package/docs/design/templates/list-item/selected-dark.svg +1 -1
  326. package/docs/design/templates/list-item/selected.svg +1 -1
  327. package/docs/design/templates/list-item-dark.svg +1 -1
  328. package/docs/design/templates/list-item.svg +1 -1
  329. package/docs/design/templates/list.svg +1 -1
  330. package/docs/design/templates/segmented-control-dark.svg +1 -1
  331. package/docs/design/templates/segmented-control.svg +1 -1
  332. package/docs/design/templates/skeleton-dark.svg +1 -1
  333. package/docs/design/templates/skeleton.svg +1 -1
  334. package/docs/design/templates/state-banner/danger-dark.svg +1 -1
  335. package/docs/design/templates/state-banner/danger.svg +1 -1
  336. package/docs/design/templates/state-banner/info-badge-dark.svg +1 -1
  337. package/docs/design/templates/state-banner/info-badge.svg +1 -1
  338. package/docs/design/templates/state-banner/info-dark.svg +1 -1
  339. package/docs/design/templates/state-banner/info.svg +1 -1
  340. package/docs/design/templates/state-banner/strip-dark.svg +1 -1
  341. package/docs/design/templates/state-banner/strip.svg +1 -1
  342. package/docs/design/templates/state-banner/success-dark.svg +1 -1
  343. package/docs/design/templates/state-banner/success.svg +1 -1
  344. package/docs/design/templates/state-banner/warning-dark.svg +1 -1
  345. package/docs/design/templates/state-banner/warning.svg +1 -1
  346. package/docs/design/templates/state-banner-dark.svg +1 -1
  347. package/docs/design/templates/state-banner.svg +1 -1
  348. package/docs/design/templates/tab-bar-dark.svg +1 -1
  349. package/docs/design/templates/tab-bar.svg +1 -1
  350. package/docs/design/templates/token-search-field-dark.svg +1 -1
  351. package/docs/design/templates/token-search-field.svg +1 -1
  352. package/docs/design/templates/toolbar-control-group-dark.svg +1 -1
  353. package/docs/design/templates/toolbar-control-group.svg +1 -1
  354. package/docs/design/templates/toolbar-dark.svg +1 -1
  355. package/docs/design/templates/toolbar-text/default-dark.svg +1 -1
  356. package/docs/design/templates/toolbar-text/default.svg +1 -1
  357. package/docs/design/templates/toolbar-text/large-dark.svg +1 -1
  358. package/docs/design/templates/toolbar-text/large.svg +1 -1
  359. package/docs/design/templates/toolbar-text-dark.svg +1 -1
  360. package/docs/design/templates/toolbar-text.svg +1 -1
  361. package/docs/design/templates/toolbar.svg +1 -1
  362. package/docs/design/templates/value-table/details-dark.svg +1 -1
  363. package/docs/design/templates/value-table/details.svg +1 -1
  364. package/docs/design/templates/value-table-dark.svg +1 -1
  365. package/docs/design/templates/value-table.svg +1 -1
  366. package/docs/design-philosophy.md +9 -1
  367. package/docs/examples/command-palette-adapter.tsx +3 -3
  368. package/docs/layout.md +147 -14
  369. package/docs/nav-stack.md +132 -8
  370. package/docs/recipes.md +9 -9
  371. package/docs/split-view.md +3 -3
  372. package/docs/sunken-panel.md +2 -2
  373. package/docs/surface-scaffold.md +138 -7
  374. package/docs/tab-navigator.md +38 -1
  375. package/docs/type-contracts.md +16 -16
  376. package/docs/ui-analyzer.md +3 -1
  377. package/docs/ui-doctor.md +71 -0
  378. package/docs/ux-demo.md +6 -6
  379. package/docs/webawesome-theme.md +7 -0
  380. package/docs/workbench.md +10 -6
  381. package/docs/writing.md +152 -0
  382. package/doctor/copy-capitalization-checks.mjs +591 -0
  383. package/doctor/index.mjs +17 -8
  384. package/llms.txt +105 -11
  385. package/package.json +15 -1
  386. package/ux-demo/recipes/app-shell.tsx +11 -11
  387. package/ux-demo/recipes/collapsible-sidebar.tsx +12 -11
  388. package/ux-demo/recipes/compact-toolbar.tsx +10 -10
  389. package/ux-demo/recipes/composer-form.tsx +8 -8
  390. package/ux-demo/recipes/list-detail-dialog.tsx +13 -13
  391. package/ux-demo/recipes/list-workspace-states.tsx +13 -13
  392. package/ux-demo/recipes/loading-inspector.tsx +10 -10
  393. package/ux-demo/recipes/navigation-sidebar.tsx +7 -7
  394. package/ux-demo/recipes/navigation-stack.tsx +5 -5
  395. package/ux-demo/recipes/workspace-header.tsx +5 -5
  396. package/dist/chunk-36TL6BCR.js.map +0 -1
  397. package/dist/chunk-4LOK4634.js +0 -21
  398. package/dist/chunk-4LOK4634.js.map +0 -1
  399. package/dist/chunk-6BRRUPJY.js.map +0 -1
  400. package/dist/chunk-6STQXRT4.js.map +0 -1
  401. package/dist/chunk-76PWEN5Y.js +0 -64
  402. package/dist/chunk-76PWEN5Y.js.map +0 -1
  403. package/dist/chunk-AYHC62OZ.js.map +0 -1
  404. package/dist/chunk-BU23Z5HZ.js.map +0 -1
  405. package/dist/chunk-DQDTZE4W.js +0 -70
  406. package/dist/chunk-DQDTZE4W.js.map +0 -1
  407. package/dist/chunk-FOQK4F3L.js.map +0 -1
  408. package/dist/chunk-GJYQ27C2.js.map +0 -1
  409. package/dist/chunk-JYD7G4RG.js.map +0 -1
  410. package/dist/chunk-KQDU7Z7P.js.map +0 -1
  411. package/dist/chunk-P74VXMB6.js.map +0 -1
  412. package/dist/chunk-PBT3CPPY.js.map +0 -1
  413. package/dist/chunk-PRG4CL3Q.js.map +0 -1
  414. package/dist/chunk-ROZLJULF.js.map +0 -1
  415. package/dist/chunk-U657IHFB.js.map +0 -1
  416. package/dist/chunk-V6W56V3N.js.map +0 -1
@@ -23,10 +23,15 @@ focusable anchor on close (or the previously focused element for a nonfocusable
23
23
  anchor). Pass `initialFocus: false` for read-only
24
24
  help that leaves focus on its trigger. Escape and an outside press dismiss it;
25
25
  `dismiss`, `onDismiss`, and `outsideIgnore` can customize that behavior.
26
- `placement` (`bottom` or `top`), `align` (`start` or `end`), and `gap` feed the
27
- shared `kerfjs/overlay` positioning core: it flips vertically when the other
28
- side fits, clamps horizontally, and follows scroll and resize. Content taller
29
- than the viewport scrolls inside the surface.
26
+ `placement` (`bottom` or `top`), `align` (`start` or `end`), `gap`, and
27
+ `viewportMargin` feed the shared `kerfjs/overlay` positioning core: it flips
28
+ vertically when the other side fits, keeps the surface `viewportMargin` (default
29
+ 8px) inside the viewport edges, and follows scroll and resize. The surface fits
30
+ its height to the room beside the anchor: when neither side holds it, it opens
31
+ on the roomier side, caps its height to that room, and scrolls its content.
32
+ The room is exposed to the content as `--kui-anchored-surface-available-height`
33
+ and refreshed on every reposition, so a tall help surface fits beside a field on
34
+ a phone without application media queries or `max-height` overrides.
30
35
 
31
36
  ```tsx
32
37
  openAnchoredSurfaceAt(
@@ -52,6 +57,43 @@ Closing the anchor's modal dialog also closes the surface. Escape closes only
52
57
  the surface; the dialog beneath stays open. The temporary pointer anchor is
53
58
  removed when the surface closes.
54
59
 
60
+ ## Dark tone for media chrome
61
+
62
+ A popup anchored to dark media chrome (a volume control in a
63
+ `ToolbarControlGroup tone="dark"` over a video or image preview) passes
64
+ `tone: 'dark'`:
65
+
66
+ ```tsx
67
+ openAnchoredSurface(volumeButton, () => <VolumeControls />, {
68
+ label: 'Volume',
69
+ tone: 'dark',
70
+ placement: 'top',
71
+ });
72
+ ```
73
+
74
+ The tone is the same loud, inverse tone as a dark `ToolbarControlGroup` or
75
+ `ToolbarText`: dark beside a light page and light beside a dark one, so the
76
+ popup matches the group that opened it. When the surface opens it takes the
77
+ opposite of the anchor's color scheme (an explicit `color-scheme` on the anchor
78
+ or an ancestor wins; `light dark` follows the user's preference), and the
79
+ surface is marked `data-tone="dark"`. Nothing else changes. Every semantic
80
+ color token is a `light-dark()` pair, so the surface fill, border, and shadow,
81
+ and the text, borders, and focus rings of the Kerf UI and Web Awesome
82
+ components inside it (a `ListItem` mute row, a `wa-slider`), resolve to the
83
+ other side by inheritance. The content needs no tone props and no overrides.
84
+ Text and focus rings keep WCAG AA in both page schemes. A theme that replaces a
85
+ semantic token with a single color instead of a `light-dark()` pair opts that
86
+ token out of the flip. While the surface is open it follows a live switch: an
87
+ OS preference change, or a theme class, attribute, or inline `color-scheme`
88
+ changed on the anchor or one of its ancestors, flips it to the new opposite
89
+ (the content's own color transitions run, as the page's do). A scheme changed
90
+ only by swapping a stylesheet is not observed. `openAnchoredSurfaceAt` reads the
91
+ scheme from its `context` (the element under the pointer), so a region with its
92
+ own `color-scheme` is honored; without a connected `context` it reads the modal
93
+ scope's (or the page's).
94
+
95
+ ## Theming
96
+
55
97
  Override `--kui-anchored-surface-inset` and
56
98
  `--kui-anchored-surface-radius` for a theme; content can compose any Kerf UI
57
99
  components without the surface applying action policy. Prefer `PopupMenu` for
@@ -41,8 +41,19 @@ the layouts handle the insets for you. There is nothing to configure:
41
41
  status bar or home indicator but its first and last items can always be
42
42
  scrolled clear.
43
43
  - **Interior edges get nothing.** A `Workbench` center next to an expanded rail,
44
- a `SplitView` detail beside its list, or a `NavStack` view under its chrome is
45
- not inset on that edge. Collapse the rail and the center picks up the edge.
44
+ a `SplitView` detail beside its list, or a `NavStack` view under its docked
45
+ chrome is not inset on that edge. Collapse the rail and the center picks up
46
+ the edge. A `NavStack` with `chromePresentation="overlay"` is the exception
47
+ by design: its views reach under the translucent chrome, and the measured
48
+ chrome height (top safe area included) becomes their block-start inset, so
49
+ content scrolls beneath the bar yet rests clear of it (see
50
+ [Navigation stack › Overlay chrome](nav-stack.md#overlay-chrome)). Its
51
+ `bottomToolbarPresentation="overlay"` does the same at the bottom: the
52
+ measured toolbar height (bottom safe area included) becomes the views'
53
+ block-end inset, so the last item rests just above the toolbar. A
54
+ `TabNavigator` with `barPresentation="overlay"` does the same for its tab
55
+ bar: the measured bar height (bottom safe area included) becomes the
56
+ scenes' block-end inset.
46
57
  - **No double inset.** Whichever region applies an inset clears it for its
47
58
  descendants. A layout region whose only child is a `Pane` or another layout
48
59
  lets that child own the insets. That child fills the region — a `Workbench`
@@ -130,6 +141,16 @@ single scrolling slot; the negative margins change only its inline reach. The
130
141
  [`Pane` UX catalog example](../ux-demo/demos/pane.tsx) shows both `deepInset`
131
142
  states with the same table component.
132
143
 
144
+ ### Scrolling beneath overlaying chrome
145
+
146
+ `Pane.scrollClearance` (`"block-start"`, `"block-end"`, or `"both"`) lets the
147
+ scrolling slot pass beneath chrome laid over the pane's edge, such as a
148
+ `DialogSurface` floating footer over a filling Pane. The slot adds the
149
+ inherited `--kui-scroll-clearance-block-*` context that the chrome publishes to
150
+ its block padding and `scroll-padding`, alongside the safe-area and
151
+ `deepInset` insets, so its first and last items still rest clear of the
152
+ chrome. See `docs/layout.md` "Scroll clearance".
153
+
133
154
  ## Decision matrix
134
155
 
135
156
  | Situation | Layout | Device threshold |
package/docs/apple-hig.md CHANGED
@@ -12,6 +12,7 @@ Native Apple applications should use native platform controls and follow the Hum
12
12
  - Use one icon family and one metaphor per action. Directional icons may mirror in RTL; checkmarks, logos, and real-world objects do not.
13
13
  - Motion is brief, causal, and optional. Honor reduced-motion and reduced-transparency preferences; repeating indicators stop moving under reduced motion.
14
14
  - Writing is concise, specific, and action-led. Labels describe the result, not implementation details.
15
+ - Capitalize by element type, consistently: names of commands, controls, views, and fields use title style; descriptions, messages, tooltips, and option text use sentence style. See [Writing interface copy](./writing.md#capitalization).
15
16
 
16
17
  ## Interaction
17
18
 
package/docs/catalog.md CHANGED
@@ -85,7 +85,7 @@ action. Filtering does not change the selected
85
85
  entry or its preview.
86
86
 
87
87
  Per-entry `resources` render as "open in new tab" links in the footer, and
88
- `related` renders a "Related entries" `PopupMenu` in a `single`
88
+ `related` renders a "Related Entries" `PopupMenu` in a `single`
89
89
  `ToolbarControlGroup` (grouped by each entry's `group`), so register its elements
90
90
  with `@kerfjs/ui/popup-menu/register` when you use it.
91
91
 
@@ -132,22 +132,74 @@ entry's `tags` array.
132
132
  Pass `label` when the stack needs an accessible name: the rendered `section`
133
133
  is then exposed as a named region. An unlabeled stack remains an ordinary
134
134
  grouping rather than adding an unnecessary landmark.
135
+ A stack holds a 736px reading measure by default; pass `width="full"` for
136
+ application-width compositions (boards, app shells, drawers, split views) so
137
+ the stack spans the stage like a `viewport.width: "full"` row instead of
138
+ clipping them.
135
139
  - `CatalogExample` is one row: optional generated `ListHeader` label, optional
136
140
  generated note, then one specimen or one intentionally coupled specimen
137
141
  cluster. Use one row per variant/state; do not hand-author the helper's private
138
- classes.
142
+ classes. A supplied `label` also names the row's `section`, so each specimen
143
+ is a named region that assistive technology and
144
+ `getByRole("region", { name })` can address.
145
+ - Example and stack labels are headings, so they use title style ("Heading
146
+ Identity Stays Whole", "Icon Trigger in a Toolbar Group"); the `note` that
147
+ explains a specimen stays sentence style. Write a label as a name, not a
148
+ sentence. See [Writing interface copy](./writing.md#capitalization);
149
+ `kerf-ui-doctor` reports a sentence-case label as `KUI-D040`.
139
150
  - Focused demos do not import local stylesheets, use inline `style`, or invent
140
151
  styling-only `demo-*` classes. Prefer a public Kerf component, then a Web
141
152
  Awesome surface when Kerf has no equivalent, then ordinary semantic HTML.
142
153
  Use `CatalogExample.viewport` for bounded specimen width, height, frame,
143
154
  surface, overflow, responsive visibility, and public custom-property values;
144
155
  keep those constraints catalog-owned instead of recreating a demo stylesheet.
156
+ Widths run `sidebar` (272px, a production rail, for sidebar-pane content),
157
+ `compact` (440px), `medium` (640px), and `wide` (864px), each capped at the
158
+ stage, plus `full`; `text` and `control` size a single label or control.
145
159
  Component heights run `short` (220px) through `tall` (360px); frame an app
146
160
  shell, whole-screen layout, or other application-sized recipe with
147
161
  `height: "app"` (592px), and give its root `fill` rather than a frame `Pane`.
148
162
  An app frame stands in for the screen: it is the containing block for
149
163
  screen-fixed chrome, so a compact `CollapsiblePanel` overlay, its backdrop,
150
164
  and restore controls dock to the frame's edges rather than the page's.
165
+ `minHeight` (`short`, `medium`, or `app` at 592px) is a floor the frame
166
+ may grow past rather than a definite height.
167
+ - A top-layer specimen (a `popover`, a modal) that production anchors to a
168
+ named region with CSS anchor positioning anchors to the frame instead when
169
+ the frame takes that name: `viewport.anchorName` is a CSS dashed-ident
170
+ (`"--app-shell-main"`, validated; anything else throws) that becomes the
171
+ frame's `anchor-name`, so the specimen's own `position-anchor` rule resolves
172
+ to the frame. Do not wrap the specimen in a stage element to name it. Anchor
173
+ names are document-wide, so give each frame on a page its own. The frame
174
+ only names the anchor: the specimen keeps owning its placement, and as a
175
+ top-layer element it is not clipped by the frame or the stage. Chromium,
176
+ Firefox, and WebKit with CSS anchor positioning place it against the frame;
177
+ an engine without anchor positioning ignores the name, and the specimen
178
+ falls back to whatever placement its own CSS gives it there.
179
+ - For a centered reading column inside a wider frame, set
180
+ `viewport.contentWidth` (`compact` 440px, `medium` 640px, or `wide` 864px,
181
+ each capped at the frame) and `contentAlign: "center"` (the default is
182
+ `start`). Each in-flow child fills that column; `[popover]` children keep
183
+ their own geometry. The column applies to block, `grid`, and `flex-column`
184
+ frames, and `contentAlign` does nothing without `contentWidth`.
185
+
186
+ ```tsx
187
+ <CatalogExample
188
+ label="Request Docked to the Main Column"
189
+ viewport={{
190
+ layout: "flex-column",
191
+ width: "full",
192
+ minHeight: "app",
193
+ anchorName: "--app-shell-main",
194
+ contentWidth: "medium",
195
+ contentAlign: "center",
196
+ }}
197
+ >
198
+ <Transcript />
199
+ <PermissionRequestPopup /> {/* its CSS: position-anchor: --app-shell-main */}
200
+ </CatalogExample>
201
+ ```
202
+
151
203
  - The specimen is an immediate child of `CatalogExample`. A focused component
152
204
  row should place the component root there, without a decorative card or
153
205
  spacing wrapper. A composition row may place the composition root there.
@@ -165,7 +217,7 @@ import { CatalogExample, CatalogExampleStack } from "@kerfjs/ui/catalog";
165
217
 
166
218
  const buttonPreview = (
167
219
  <CatalogExampleStack
168
- label="Button variants"
220
+ label="Button Variants"
169
221
  rootAttributes={{ "data-demo": "button" }}
170
222
  >
171
223
  <CatalogExample label="Icon" note="A bare glyph." align="glyph">
@@ -174,7 +226,7 @@ const buttonPreview = (
174
226
  <CatalogExample label="Control" align="inline-control">
175
227
  <SegmentedControl id="view" label="View" value="list" choices={choices} />
176
228
  </CatalogExample>
177
- <CatalogExample label="Authoring note" note="Explain the specimen below.">
229
+ <CatalogExample label="Authoring Note" note="Explain the specimen below.">
178
230
  <p>Use the public helper contract.</p>
179
231
  </CatalogExample>
180
232
  </CatalogExampleStack>
@@ -361,23 +413,23 @@ const sections: CatalogSection[] = [
361
413
  const renderers: Record<string, () => SafeHtml> = {
362
414
  button: () => (
363
415
  <CatalogExampleStack
364
- label="Button states"
416
+ label="Button States"
365
417
  rootAttributes={{ "data-demo": "button" }}
366
418
  >
367
419
  <CatalogExample label="Default" align="inline-control">
368
420
  <Button label="Save" />
369
421
  </CatalogExample>
370
- <CatalogExample label="Authoring note" note="Explain the specimen below.">
422
+ <CatalogExample label="Authoring Note" note="Explain the specimen below.">
371
423
  <p>The application owns product copy and actions.</p>
372
424
  </CatalogExample>
373
425
  </CatalogExampleStack>
374
426
  ),
375
427
  "profile-form": () => (
376
428
  <CatalogExampleStack
377
- label="Profile form composition"
429
+ label="Profile Form Composition"
378
430
  rootAttributes={{ "data-demo": "profile-form" }}
379
431
  >
380
- <CatalogExample label="Complete composition">
432
+ <CatalogExample label="Complete Composition">
381
433
  <ProfileForm />
382
434
  </CatalogExample>
383
435
  </CatalogExampleStack>
@@ -493,7 +545,7 @@ revealCatalogEntry(app, initial, { block: "center" });
493
545
 
494
546
  ## UX Review capture
495
547
 
496
- On a local Vite dev or preview server the catalog can offer a **Capture region**
548
+ On a local Vite dev or preview server the catalog can offer a **Capture Region**
497
549
  header link that starts a UX Review region screenshot, preset with the project
498
550
  and the active entry. Static hosting has no local project, so the link never
499
551
  appears there. Three pieces wire it:
@@ -147,7 +147,9 @@ top toolbar over a `Pane`:
147
147
  place groups wherever the open panel needs them;
148
148
  - a `ToolbarControlGroup` marked `relocateOnCollapse` stays available in the
149
149
  work area when the panel closes; the standard `toggle: { action, name,
150
- showLabel?, hideLabel? }` is always the final group.
150
+ showLabel?, hideLabel? }` is always the final group. Give `name` as the
151
+ panel's title-style name ("Navigator"), which labels the toggle group and
152
+ completes "Show Navigator" / "Hide Navigator".
151
153
 
152
154
  Busy groups keep their inert control, spinner, and adjacent live status together
153
155
  when relocated. Clearing `busy` restores the same action in its current toolbar;
@@ -166,7 +168,8 @@ divider of its own unless `dividerSides` says so. The `Pane` under it draws
166
168
  the line under the toolbar only while its content is scrolled (see
167
169
  [Scroll dividers](./layout.md#scroll-dividers)), and takes the panel's `pane`
168
170
  (`PaneConfig`: `contentElement`, `contentLabel`, `separators`,
169
- `safeAreaEdges`, `chromeDividers`) — for example `{ contentElement: "nav",
171
+ `safeAreaEdges`, `chromeDividers`, `appearance`, `deepInset`,
172
+ `scrollClearance`, `headerPresentation`, `tabIndex`, `outlined`) — for example `{ contentElement: "nav",
170
173
  contentLabel: "Sections" }` for a navigation rail. An omitted or `undefined`
171
174
  field keeps the `Pane` default; without a `toolbar` there is no `Pane`, so
172
175
  `pane` is ignored.
@@ -187,8 +190,8 @@ inert; avoid duplicate `id` attributes on marked groups.
187
190
  const toolbar: CollapsiblePanelToolbar = {
188
191
  label: "Navigator",
189
192
  leading: <NewFileGroup />,
190
- trailing: <ToolbarControlGroup relocateOnCollapse label="Search files"><SearchButton /></ToolbarControlGroup>,
191
- toggle: { action: "toggle-nav", name: "navigator" },
193
+ trailing: <ToolbarControlGroup relocateOnCollapse label="Search Files"><SearchButton /></ToolbarControlGroup>,
194
+ toggle: { action: "toggle-nav", name: "Navigator" },
192
195
  };
193
196
 
194
197
  <Row fill gap="none">
@@ -307,7 +310,7 @@ mount(app, () => (
307
310
  side="left"
308
311
  collapsed
309
312
  action="toggle-nav"
310
- label="Show navigator"
313
+ label="Show Navigator"
311
314
  />
312
315
  )}
313
316
  {/* content */}
@@ -362,7 +365,7 @@ sizes, content, and any per-project persistence — exactly as with the other la
362
365
 
363
366
  ## Recipe and coverage
364
367
 
365
- The catalog ships a runnable **Collapsible sidebar** recipe — a left rail and a
368
+ The catalog ships a runnable **Collapsible Sidebar** recipe — a left rail and a
366
369
  bottom drawer with the standard toggles, the compact overlay, and per-panel
367
370
  persistence: [open it](../ux-demo/?component=recipe-collapsible-sidebar) or read
368
371
  [`recipes.md`](recipes.md#collapsible-sidebar) · [TSX source](../ux-demo/recipes/collapsible-sidebar.tsx).
@@ -89,8 +89,12 @@ only cataloged `descendantElements` and composed JSX evidence.
89
89
  An entry's optional `cssValueProps` makes CSS-adjacent prop grammar equally
90
90
  machine-evaluable. Each path records the property grammar, finite shorthands,
91
91
  canonical versus exceptional spacing choices, standalone and expression-only
92
- helpers, raw/unsafe policy, and serialization examples. Nested paths use the
93
- bounded `items[].property` form. Consumer catalogs can publish the same facts;
92
+ helpers, raw/unsafe policy, and serialization examples. Nested paths are
93
+ dot-separated object members, each optionally suffixed with `[]` to visit
94
+ every array element: `items[].property` for a value inside each array item,
95
+ `iconTile.color` for a member of an object-valued prop. A member that is not a
96
+ literal object or array (a tone string such as `iconTile="brand"`, a variable)
97
+ is skipped rather than guessed. Consumer catalogs can publish the same facts;
94
98
  ESLint, `kerf-ui-analyze`, and `kerf-ui-doctor` then issue the same stable
95
99
  `KUI-L013`–`KUI-L017` feedback for application and third-party components.
96
100
 
@@ -246,10 +250,10 @@ product that genuinely needs one of these elements records a narrow `KUI-L301`
246
250
  profile exception for the file that renders it.
247
251
 
248
252
  Catalog detail footers use one standard resource vocabulary and order. Build
249
- them with `catalogResources()` from `@kerfjs/ui/catalog-resources`: `Demo source`
250
- first, optional `Component source` and `Design template`, then `Guidance`.
253
+ them with `catalogResources()` from `@kerfjs/ui/catalog-resources`: `Demo Source`
254
+ first, optional `Component Source` and `Design Template`, then `Guidance`.
251
255
  Third-party entries use the typed `integrationGuidance` kind, which renders
252
- `Integration guidance`, and omit `Component source` when the implementation is
256
+ `Integration Guidance`, and omit `Component Source` when the implementation is
253
257
  not owned by the catalog's project. Prefer these semantic kinds over local labels
254
258
  such as “View source” or “Read UI guidance”; the helper makes that convention a
255
259
  compile-time choice while still returning ordinary `CatalogResource[]` values.
@@ -333,6 +337,8 @@ visual anchor.
333
337
 
334
338
  `ToolbarControlGroup.tileTone` selects `neutral`, `brand`, `success`, `warning`, or `danger` quiet fill, matching quiet border, and on-quiet foreground for a non-interactive icon tile. Compose a contained `single` group whose only child is a direct decorative LucideIcon (`aria-hidden="true"`). Omission preserves the normal group palette. The prop does not recolor interactive, mixed, multi-control, or borderless groups; keep real actions in controls with their existing focus/hover/pressed treatments.
335
339
 
340
+ `ListItem`, `ListItemLink`, and `ListActionRow` take `iconTile` to present their leading `icon` in a filled 32px rounded tile holding an 18px glyph, for settings or command rows that identify each entry by color. Pass a tone (`neutral`, `brand`, `success`, `warning`, or `danger`) for the same quiet fill, matching quiet border, and on-quiet foreground as `ToolbarControlGroup.tileTone`, or `{ color, foreground? }` for an application color: `color` is a `CssColor` (`uiColor()`, `colorVar()`, or `fillColor('#e5484d')`) and `foreground` a `CssForegroundColor`; without one, the glyph is black or white, whichever contrasts with the fill. The tile sits 6px clear of a standard 44px row (a compact row is at least 42px tall), moves the label to the tile's edge, and keeps its colors when the row is hovered or selected. Never wrap the icon in your own tile or resize the row's icon slot.
341
+
336
342
  ### Public CSS anatomy
337
343
 
338
344
  The `publicClasses` array on each entry in
@@ -396,7 +402,12 @@ The documented exceptions live with their reasons in
396
402
  check, so the list only shrinks. The layout regions' inherited edge-inset
397
403
  context (`--kui-edge-inset-*` handed to a sole Pane or layout child and cleared
398
404
  for any other content, and a Toolbar clearing it for its zones) is the one
399
- design exception; the others name the open fix ticket.
405
+ design exception; the others name the open fix ticket. The scroll-clearance
406
+ context (`--kui-scroll-clearance-block-*`) needs no exception: overlaying
407
+ chrome publishes it on its own element (a `DialogSurface` on its dialog body,
408
+ a `Pane` overlay header, through `wireScrollDividers`, on its own Pane root).
409
+ A scroll owner reads it only through its own `scrollClearance` prop, or, for an
410
+ overlay-header Pane's content, through its own `headerPresentation`.
400
411
 
401
412
  Applications and component packages built on the package follow the same
402
413
  rules, and the downstream tools enforce them against the composition catalog
@@ -623,11 +634,19 @@ own inset (8px for a raw `wa-dropdown`, the Select listbox's 4px for a
623
634
  `PopupMenu`), while `compact` and `list-zero` apply to every nested menu. A
624
635
  `PopupMenu` and a `Select` draw one popup: the same caret that turns to face the
625
636
  open popup, fade-in surface, surface inset, row height and padding, current-row
626
- fill, and group titles, all read from one private popup-choice contract in
627
- `foundation.css`. Checkbox items reserve a check column; plain commands start
628
- at the checkmark's leading edge, beside the group title rather than the
629
- farther-in Select option label. Checked submenu items keep their checkmark and
630
- label inside the submenu surface. Compact mixed controls retain the standard
637
+ fill, group titles, and scroll cue, all read from one private popup-choice
638
+ contract in `foundation.css`. A capped popup that scrolls (a long listbox, a
639
+ menu, or a phone submenu) shows a soft shadow along each edge with more
640
+ choices beyond it, so overlay scrollbars never leave it looking complete; the
641
+ cue is CSS-only, appears only toward hidden rows, and a popup whose choices
642
+ all fit draws none. Checkbox items reserve a check column, and so does every
643
+ plain command in a level (the top menu or one submenu) that holds a checkbox
644
+ item, through an `aria-hidden` icon-slot spacer, so check, icon, and label
645
+ columns align across the level. A level without a checkbox item keeps the
646
+ compact start: plain commands begin at the checkmark's leading edge, beside the
647
+ group title rather than the farther-in Select option label. Checked submenu
648
+ items keep their checkmark inside the submenu surface with the same check-column
649
+ advance as the top level. Compact mixed controls retain the standard
631
650
  item padding, omit an internal separator, and let the raised selected item paint
632
651
  over the outer border instead of shrinking to an inset highlight. The Web
633
652
  Awesome trigger's shadow base owns max-content sizing, so icons, localized text,
@@ -739,7 +758,12 @@ propagating before the window, or a press without a click, collapses in the
739
758
  next task instead.
740
759
  `TokenSearchField.trailingAction` supplies an icon, accessible `label`, delegated
741
760
  `action`, and optional `id`; the field renders a 24px wide button that fills its
742
- 34px line slot, including the hit target, disabled state, hover, and focus ring.
761
+ 34px line slot (32px in `toolbar-group`), including the hit target, disabled
762
+ state, hover, focus ring, and the clear button's radius in each presentation.
763
+ `expanded` renders `aria-expanded` and `pressed` renders `aria-pressed` (one or
764
+ the other, never both); either `true` state keeps the hover fill at full text
765
+ strength. `controls` and `haspopup` render `aria-controls` and `aria-haspopup`,
766
+ and `attributes` carries domain `data-*` metadata but never `data-action`.
743
767
  Use `trailing` for passive content. The two props are mutually exclusive.
744
768
  For a collapsible search in a stretched Toolbar center, `fill` lets the expanded
745
769
  field and its enclosing search `ToolbarControlGroup` consume the available width;
@@ -782,7 +806,16 @@ When a leading AppTab is pinned, the leading scroll divider appears at that
782
806
  tab's trailing edge while peer tabs scroll beneath it, including in RTL.
783
807
  With `snapTabs`, `wireTabBars` measures the pinned tab and settles peers at
784
808
  whole-tab starts after scroll and selection changes, reserving end room so the
785
- last peer can align there. The application still owns selection and tab order.
809
+ last peer can align there. That room is scrollable content after the last tab,
810
+ inside the strip, so it lengthens the scroll range without widening the strip:
811
+ the strip still shrinks to its allocation, and `trailing` and `end` stay inside
812
+ the bar. The room is still in-flow content, so it counts toward the strip's
813
+ content-based flex basis: when another zone also shrinks (a trailing zone
814
+ given `--kui-tab-bar-trailing-flex: 0 1 auto` with shrinkable content), the
815
+ strip keeps a proportionally larger share. The share converges within a few
816
+ frames and never pushes `trailing` or `end` out of the bar; keep the trailing
817
+ zone non-shrinking with `snapTabs` to avoid it. The application still owns
818
+ selection and tab order.
786
819
  ResizeObserver notifications coalesce snap measurements into the next animation
787
820
  frame, so inset writes cannot resize the observed strip during observer delivery.
788
821
  `wireTabBars` watches the whole root it is given, but a mutation re-measures only