@kerfjs/ui 5.0.0-beta.98 → 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 (407) 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 +487 -77
  47. package/ai/skill.md +40 -13
  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 +22 -5
  59. package/dist/catalog.js +50 -31
  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-AZWE2FB5.js → chunk-CMETHPKR.js} +12 -15
  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-527IAEWG.js → chunk-PYBBYSZ3.js} +10 -17
  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-Cp3Y8kJ9.d.ts → nav-stack-VXTumzKa.d.ts} +48 -3
  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.js +1 -1
  189. package/dist/skeleton.js +1 -1
  190. package/dist/spacer.js +1 -1
  191. package/dist/split-button.js +1 -1
  192. package/dist/split-view.d.ts +7 -5
  193. package/dist/split-view.js +6 -3
  194. package/dist/split-view.js.map +1 -1
  195. package/dist/state-banner.d.ts +6 -1
  196. package/dist/state-banner.js +1 -1
  197. package/dist/styles/anchored-surface.css +27 -1
  198. package/dist/styles/catalog/components/catalog-example.css +33 -0
  199. package/dist/styles/catalog/components/catalog-stage.css +7 -0
  200. package/dist/styles/chip.css +70 -0
  201. package/dist/styles/components/actions/popup-menu/popup-menu.css +14 -4
  202. package/dist/styles/components/actions/toolbar-control-group/toolbar-control-group.css +75 -1
  203. package/dist/styles/components/actions/toolbar-text/toolbar-text.css +66 -0
  204. package/dist/styles/components/collections/list/list.css +77 -7
  205. package/dist/styles/components/collections/list-action-row/list-action-row.css +177 -22
  206. package/dist/styles/components/collections/list-item/list-item.css +158 -11
  207. package/dist/styles/components/feedback/anchored-surface/anchored-surface.css +27 -1
  208. package/dist/styles/components/feedback/chip/chip.css +70 -0
  209. package/dist/styles/components/feedback/state-banner/state-banner.css +24 -13
  210. package/dist/styles/components/forms/composer/composer.css +100 -0
  211. package/dist/styles/components/forms/token-search-field/token-search-field.css +13 -2
  212. package/dist/styles/components/layout/pane/pane.css +81 -2
  213. package/dist/styles/components/navigation/nav-stack/nav-stack.css +84 -0
  214. package/dist/styles/components/navigation/tab-bar/tab-bar.css +15 -4
  215. package/dist/styles/components/navigation/tab-navigator/tab-navigator.css +79 -4
  216. package/dist/styles/components/surfaces/surface-scaffold/surface-scaffold.css +195 -0
  217. package/dist/styles/composer.css +100 -0
  218. package/dist/styles/foundation.css +40 -0
  219. package/dist/styles/list-action-row.css +177 -22
  220. package/dist/styles/list-item.css +158 -11
  221. package/dist/styles/list.css +77 -7
  222. package/dist/styles/nav-stack.css +84 -0
  223. package/dist/styles/pane.css +81 -2
  224. package/dist/styles/popup-menu.css +14 -4
  225. package/dist/styles/state-banner.css +24 -13
  226. package/dist/styles/styles.css +1 -0
  227. package/dist/styles/surface-scaffold.css +195 -0
  228. package/dist/styles/tab-bar.css +15 -4
  229. package/dist/styles/tab-navigator.css +79 -4
  230. package/dist/styles/token-search-field.css +13 -2
  231. package/dist/styles/toolbar-control-group.css +75 -1
  232. package/dist/styles/toolbar-text.css +66 -0
  233. package/dist/surface-scaffold-register.d.ts +6 -1
  234. package/dist/surface-scaffold-register.js +89 -3
  235. package/dist/surface-scaffold-register.js.map +1 -1
  236. package/dist/surface-scaffold.d.ts +66 -7
  237. package/dist/surface-scaffold.js +1 -1
  238. package/dist/tab-navigator.d.ts +23 -2
  239. package/dist/tab-navigator.js +2 -0
  240. package/dist/tab-navigator.js.map +1 -1
  241. package/dist/token-search-field.d.ts +1 -1
  242. package/dist/token-search-field.js +1 -1
  243. package/dist/{token-search-model-DTcTXWMS.d.ts → token-search-model-aYR0YAei.d.ts} +32 -2
  244. package/dist/token-search-model.d.ts +1 -1
  245. package/dist/toolbar-control-group.js +1 -1
  246. package/dist/toolbar-text.js +1 -1
  247. package/dist/toolbar.d.ts +1 -0
  248. package/dist/value-table.js +1 -1
  249. package/dist/wire-catalog.d.ts +3 -2
  250. package/dist/wire-catalog.js +2 -2
  251. package/dist/wire-composers.d.ts +16 -0
  252. package/dist/wire-composers.js +3 -0
  253. package/dist/wire-composers.js.map +1 -0
  254. package/dist/wire-list-focus-scroll.d.ts +16 -0
  255. package/dist/wire-list-focus-scroll.js +3 -0
  256. package/dist/wire-list-focus-scroll.js.map +1 -0
  257. package/dist/wire-nav-stack.js +135 -0
  258. package/dist/wire-nav-stack.js.map +1 -1
  259. package/dist/wire-scroll-dividers.d.ts +9 -0
  260. package/dist/wire-scroll-dividers.js +1 -1
  261. package/dist/wire-tab-bars.js +1 -1
  262. package/dist/wire-tab-navigator.d.ts +3 -1
  263. package/dist/wire-tab-navigator.js +133 -1
  264. package/dist/wire-tab-navigator.js.map +1 -1
  265. package/dist/wire-token-search-fields.d.ts +1 -1
  266. package/dist/wire-token-search-fields.js +1 -1
  267. package/dist/workbench.d.ts +8 -3
  268. package/dist/workbench.js +2 -1
  269. package/docs/accessibility.md +132 -3
  270. package/docs/anchored-surface.md +46 -4
  271. package/docs/app-layouts.md +23 -2
  272. package/docs/apple-hig.md +1 -0
  273. package/docs/catalog.md +54 -8
  274. package/docs/collapsible-panel.md +9 -6
  275. package/docs/component-contract.md +41 -12
  276. package/docs/component-selection.md +143 -19
  277. package/docs/composer.md +143 -0
  278. package/docs/design/templates/choice-chips/multiple-dark.svg +1 -0
  279. package/docs/design/templates/choice-chips/multiple.svg +1 -0
  280. package/docs/design/templates/choice-chips-dark.svg +1 -1
  281. package/docs/design/templates/choice-chips.svg +1 -1
  282. package/docs/design/templates/composer/chat-dark.svg +1 -0
  283. package/docs/design/templates/composer/chat.svg +1 -0
  284. package/docs/design/templates/composer/prompt-dark.svg +1 -0
  285. package/docs/design/templates/composer/prompt.svg +1 -0
  286. package/docs/design/templates/composer-dark.svg +1 -0
  287. package/docs/design/templates/composer.svg +1 -0
  288. package/docs/design/templates/empty-state/filtered-dark.svg +1 -1
  289. package/docs/design/templates/empty-state/filtered.svg +1 -1
  290. package/docs/design/templates/empty-state/with-action-dark.svg +1 -1
  291. package/docs/design/templates/empty-state/with-action.svg +1 -1
  292. package/docs/design/templates/empty-state-dark.svg +1 -1
  293. package/docs/design/templates/empty-state.svg +1 -1
  294. package/docs/design/templates/list/compact-dark.svg +1 -1
  295. package/docs/design/templates/list/compact.svg +1 -1
  296. package/docs/design/templates/list-action-row/default-dark.svg +1 -1
  297. package/docs/design/templates/list-action-row/default.svg +1 -1
  298. package/docs/design/templates/list-action-row/icon-tile-dark.svg +1 -0
  299. package/docs/design/templates/list-action-row/icon-tile.svg +1 -0
  300. package/docs/design/templates/list-action-row/selected-dark.svg +1 -1
  301. package/docs/design/templates/list-action-row/selected.svg +1 -1
  302. package/docs/design/templates/list-action-row/trailing-menu-dark.svg +1 -1
  303. package/docs/design/templates/list-action-row/trailing-menu.svg +1 -1
  304. package/docs/design/templates/list-action-row-dark.svg +1 -1
  305. package/docs/design/templates/list-action-row.svg +1 -1
  306. package/docs/design/templates/list-dark.svg +1 -1
  307. package/docs/design/templates/list-header/size-l-dark.svg +1 -1
  308. package/docs/design/templates/list-header/size-l.svg +1 -1
  309. package/docs/design/templates/list-header/size-m-dark.svg +1 -1
  310. package/docs/design/templates/list-header/size-m.svg +1 -1
  311. package/docs/design/templates/list-header/size-xl-dark.svg +1 -1
  312. package/docs/design/templates/list-header/size-xl.svg +1 -1
  313. package/docs/design/templates/list-header-dark.svg +1 -1
  314. package/docs/design/templates/list-header.svg +1 -1
  315. package/docs/design/templates/list-item/icon-tile-dark.svg +1 -0
  316. package/docs/design/templates/list-item/icon-tile.svg +1 -0
  317. package/docs/design/templates/list-item/selected-dark.svg +1 -1
  318. package/docs/design/templates/list-item/selected.svg +1 -1
  319. package/docs/design/templates/list-item-dark.svg +1 -1
  320. package/docs/design/templates/list-item.svg +1 -1
  321. package/docs/design/templates/list.svg +1 -1
  322. package/docs/design/templates/segmented-control-dark.svg +1 -1
  323. package/docs/design/templates/segmented-control.svg +1 -1
  324. package/docs/design/templates/skeleton-dark.svg +1 -1
  325. package/docs/design/templates/skeleton.svg +1 -1
  326. package/docs/design/templates/state-banner/danger-dark.svg +1 -1
  327. package/docs/design/templates/state-banner/danger.svg +1 -1
  328. package/docs/design/templates/state-banner/info-badge-dark.svg +1 -1
  329. package/docs/design/templates/state-banner/info-badge.svg +1 -1
  330. package/docs/design/templates/state-banner/info-dark.svg +1 -1
  331. package/docs/design/templates/state-banner/info.svg +1 -1
  332. package/docs/design/templates/state-banner/strip-dark.svg +1 -1
  333. package/docs/design/templates/state-banner/strip.svg +1 -1
  334. package/docs/design/templates/state-banner/success-dark.svg +1 -1
  335. package/docs/design/templates/state-banner/success.svg +1 -1
  336. package/docs/design/templates/state-banner/warning-dark.svg +1 -1
  337. package/docs/design/templates/state-banner/warning.svg +1 -1
  338. package/docs/design/templates/state-banner-dark.svg +1 -1
  339. package/docs/design/templates/state-banner.svg +1 -1
  340. package/docs/design/templates/tab-bar-dark.svg +1 -1
  341. package/docs/design/templates/tab-bar.svg +1 -1
  342. package/docs/design/templates/token-search-field-dark.svg +1 -1
  343. package/docs/design/templates/token-search-field.svg +1 -1
  344. package/docs/design/templates/toolbar-control-group-dark.svg +1 -1
  345. package/docs/design/templates/toolbar-control-group.svg +1 -1
  346. package/docs/design/templates/toolbar-dark.svg +1 -1
  347. package/docs/design/templates/toolbar-text/default-dark.svg +1 -1
  348. package/docs/design/templates/toolbar-text/default.svg +1 -1
  349. package/docs/design/templates/toolbar-text/large-dark.svg +1 -1
  350. package/docs/design/templates/toolbar-text/large.svg +1 -1
  351. package/docs/design/templates/toolbar-text-dark.svg +1 -1
  352. package/docs/design/templates/toolbar-text.svg +1 -1
  353. package/docs/design/templates/toolbar.svg +1 -1
  354. package/docs/design/templates/value-table/details-dark.svg +1 -1
  355. package/docs/design/templates/value-table/details.svg +1 -1
  356. package/docs/design/templates/value-table-dark.svg +1 -1
  357. package/docs/design/templates/value-table.svg +1 -1
  358. package/docs/design-philosophy.md +9 -1
  359. package/docs/examples/command-palette-adapter.tsx +3 -3
  360. package/docs/layout.md +147 -14
  361. package/docs/nav-stack.md +112 -2
  362. package/docs/recipes.md +9 -9
  363. package/docs/split-view.md +3 -3
  364. package/docs/sunken-panel.md +2 -2
  365. package/docs/surface-scaffold.md +138 -7
  366. package/docs/tab-navigator.md +38 -1
  367. package/docs/type-contracts.md +16 -16
  368. package/docs/ui-analyzer.md +3 -1
  369. package/docs/ui-doctor.md +71 -0
  370. package/docs/ux-demo.md +6 -6
  371. package/docs/workbench.md +10 -6
  372. package/docs/writing.md +152 -0
  373. package/doctor/copy-capitalization-checks.mjs +591 -0
  374. package/doctor/index.mjs +17 -8
  375. package/llms.txt +105 -11
  376. package/package.json +15 -1
  377. package/ux-demo/recipes/app-shell.tsx +11 -11
  378. package/ux-demo/recipes/collapsible-sidebar.tsx +12 -11
  379. package/ux-demo/recipes/compact-toolbar.tsx +10 -10
  380. package/ux-demo/recipes/composer-form.tsx +8 -8
  381. package/ux-demo/recipes/list-detail-dialog.tsx +13 -13
  382. package/ux-demo/recipes/list-workspace-states.tsx +13 -13
  383. package/ux-demo/recipes/loading-inspector.tsx +10 -10
  384. package/ux-demo/recipes/navigation-sidebar.tsx +7 -7
  385. package/ux-demo/recipes/navigation-stack.tsx +5 -5
  386. package/ux-demo/recipes/workspace-header.tsx +5 -5
  387. package/dist/chunk-36TL6BCR.js.map +0 -1
  388. package/dist/chunk-4LOK4634.js +0 -21
  389. package/dist/chunk-4LOK4634.js.map +0 -1
  390. package/dist/chunk-527IAEWG.js.map +0 -1
  391. package/dist/chunk-6BRRUPJY.js.map +0 -1
  392. package/dist/chunk-6STQXRT4.js.map +0 -1
  393. package/dist/chunk-76PWEN5Y.js +0 -64
  394. package/dist/chunk-76PWEN5Y.js.map +0 -1
  395. package/dist/chunk-AZWE2FB5.js.map +0 -1
  396. package/dist/chunk-DQDTZE4W.js +0 -70
  397. package/dist/chunk-DQDTZE4W.js.map +0 -1
  398. package/dist/chunk-FOQK4F3L.js.map +0 -1
  399. package/dist/chunk-GJYQ27C2.js.map +0 -1
  400. package/dist/chunk-JYD7G4RG.js.map +0 -1
  401. package/dist/chunk-KQDU7Z7P.js.map +0 -1
  402. package/dist/chunk-P74VXMB6.js.map +0 -1
  403. package/dist/chunk-PBT3CPPY.js.map +0 -1
  404. package/dist/chunk-PRG4CL3Q.js.map +0 -1
  405. package/dist/chunk-ROZLJULF.js.map +0 -1
  406. package/dist/chunk-U657IHFB.js.map +0 -1
  407. package/dist/chunk-V6W56V3N.js.map +0 -1
@@ -1,6 +1,6 @@
1
1
  # Public API signatures for the UI authoring corpus
2
2
 
3
- Generated from emitted declarations for `@kerfjs/ui@5.0.0-beta.98` and `kerfjs@5.0.0-beta.98`. This bounded reference covers only APIs used by the seven-task corpus. It is interface evidence, not an implementation or runtime guarantee.
3
+ Generated from emitted declarations for `@kerfjs/ui@5.0.0-beta.99` and `kerfjs@5.0.0-beta.99`. This bounded reference covers only APIs used by the seven-task corpus. It is interface evidence, not an implementation or runtime guarantee.
4
4
 
5
5
  ## `@kerfjs/ui/css-values`
6
6
 
@@ -122,8 +122,16 @@ declare function foregroundColorVar(name: `--${string}`, fallback?: CssForegroun
122
122
  * resolves the color syntax; this checks only that it is one declaration value.
123
123
  */
124
124
  declare function foregroundColor(value: string): CssForegroundColor;
125
+ /**
126
+ * Use an application-chosen CSS color as a fill: a `ChoiceChips` swatch, a list
127
+ * row's `iconTile` color, or any other prop that takes a plain
128
+ * {@link CssColor}. It returns a `CssColor`, not a {@link CssForegroundColor},
129
+ * so a fill literal cannot reach a prop that paints text or an icon. The browser
130
+ * resolves the color syntax; this checks only that it is one declaration value.
131
+ */
132
+ declare function fillColor(value: string): CssColor;
125
133
 
126
- export { type CssColor, type CssFlex, type CssFlexBasis, type CssFlexKeyword, type CssForegroundColor, type CssLength, type CssLengthExpression, type CssSize, type CssSizeKeyword, type CssValue, type UiColor, type UiColorName, type UiForegroundColorName, type UiGap, type UiGapValue, type UiSpaceName, calc, colorVar, em, flex, foregroundColor, foregroundColorVar, lengthVar, pct, plus, px, rem, remify, space, uiColor };
134
+ export { type CssColor, type CssFlex, type CssFlexBasis, type CssFlexKeyword, type CssForegroundColor, type CssLength, type CssLengthExpression, type CssSize, type CssSizeKeyword, type CssValue, type UiColor, type UiColorName, type UiForegroundColorName, type UiGap, type UiGapValue, type UiSpaceName, calc, colorVar, em, fillColor, flex, foregroundColor, foregroundColorVar, lengthVar, pct, plus, px, rem, remify, space, uiColor };
127
135
  ```
128
136
 
129
137
  ## `@kerfjs/ui/disclosure-arrow`
@@ -157,6 +165,7 @@ import * as kerfjs from 'kerfjs';
157
165
  import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
158
166
  import { S as Sides } from './sides-BPSWde0A.js';
159
167
  import { PaneSeparatorSide } from './pane.js';
168
+ import './scroll-clearance-BikHljTc.js';
160
169
 
161
170
  type ToolbarPosition = 'header' | 'footer';
162
171
  /** Control-band density: `default` (60px with 44px groups) or `compact`. */
@@ -714,9 +723,10 @@ import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
714
723
  import { S as StructuralRootAttributes } from './extension-attributes-mu8MFUl0.js';
715
724
  import { H as HorizontalAlignment, L as ListVerticalAlignment } from './flex-alignment-4ms8ZbV8.js';
716
725
  export { V as VerticalAlignment } from './flex-alignment-4ms8ZbV8.js';
726
+ import { S as ScrollClearance } from './scroll-clearance-BikHljTc.js';
717
727
  import { S as Sides } from './sides-BPSWde0A.js';
718
- import { UiGap, CssFlexKeyword, CssFlex } from './css-values.js';
719
- export { CssLength, UiGapValue, UiSpaceName } from './css-values.js';
728
+ import { UiGap, CssFlexKeyword, CssFlex, CssLength } from './css-values.js';
729
+ export { UiGapValue, UiSpaceName } from './css-values.js';
720
730
 
721
731
  type ListRootAttributes = StructuralRootAttributes & Readonly<{
722
732
  'data-component'?: never;
@@ -726,6 +736,8 @@ type ListRootAttributes = StructuralRootAttributes & Readonly<{
726
736
  'data-h-align'?: never;
727
737
  'data-v-align'?: never;
728
738
  'data-scrollable'?: never;
739
+ 'data-scroll-clearance'?: never;
740
+ 'data-frame'?: never;
729
741
  'data-surface'?: never;
730
742
  'data-inset'?: never;
731
743
  'data-text-insets'?: never;
@@ -770,6 +782,35 @@ interface ListProps {
770
782
  * column and use `flex`; `fill` needs a definite-height parent.
771
783
  */
772
784
  scrollable?: boolean;
785
+ /**
786
+ * Clear chrome that lies over this scrollable List's block-start and/or
787
+ * block-end edge, such as a `DialogSurface` floating footer. The List adds
788
+ * the inherited `--kui-scroll-clearance-block-*` context that chrome
789
+ * publishes to its own block padding and `scroll-padding`, so its rows
790
+ * scroll visibly beneath the chrome while the first and last rows (and any
791
+ * row focused or scrolled into view) can still rest clear of it. Opt in only
792
+ * the one scroller that reaches the covered edge. Defaults to none.
793
+ */
794
+ scrollClearance?: ScrollClearance;
795
+ /**
796
+ * Draw a bordered, rounded frame around the stack: a 1px neutral border,
797
+ * the standard control radius, and a 4px inset on every side that keeps the
798
+ * first and last rows' focus rings inside a scrolling frame's clip. It
799
+ * replaces any `inset`/`textInsets`/`controlInsets`. With `scrollable` and
800
+ * `maxHeight` it is a bounded result picker of `ListItem` rows.
801
+ */
802
+ frame?: boolean;
803
+ /**
804
+ * The List's maximum block size, a typed `CssLength` from
805
+ * `@kerfjs/ui/css-values` (such as `rem(14)`). Pair it with `scrollable` so
806
+ * rows beyond it scroll; it bounds the List without a flex-column ancestor.
807
+ */
808
+ maxHeight?: CssLength;
809
+ /**
810
+ * The List's minimum block size, a typed `CssLength` (such as `rem(4.25)`),
811
+ * so a short or empty result set keeps a stable box. Defaults to no minimum.
812
+ */
813
+ minHeight?: CssLength;
773
814
  /**
774
815
  * Paint a solid surface behind the stack, including its insets: for a strip
775
816
  * of chrome (a banner above a sunken work area) that must not show the
@@ -802,16 +843,19 @@ interface ListProps {
802
843
  */
803
844
  type ListConfig = Pick<ListProps, 'gap' | 'hAlign' | 'vAlign' | 'dividerSides' | 'textInsets' | 'controlInsets'>;
804
845
  /** A stretch-aligned vertical stack with optional gap, flex, fill, scroll, and dividers. */
805
- declare function List({ children, selectionMode, ariaLabel, gap, flex, fill, hAlign, vAlign, scrollable, surface, inset, dividerSides, textInsets, controlInsets, className, rootAttributes, slot, }: ListProps): kerfjs.SafeHtml;
846
+ declare function List({ children, selectionMode, ariaLabel, gap, flex, fill, hAlign, vAlign, scrollable, scrollClearance, frame, maxHeight, minHeight, surface, inset, dividerSides, textInsets, controlInsets, className, rootAttributes, slot, }: ListProps): kerfjs.SafeHtml;
806
847
 
807
- export { CssFlex, CssFlexKeyword, HorizontalAlignment, List, type ListConfig, type ListInset, type ListProps, type ListSurface, ListVerticalAlignment, Sides, UiGap };
848
+ export { CssFlex, CssFlexKeyword, CssLength, HorizontalAlignment, List, type ListConfig, type ListInset, type ListProps, type ListSurface, ListVerticalAlignment, ScrollClearance, Sides, UiGap };
808
849
  ```
809
850
 
810
851
  ## `@kerfjs/ui/list-action-row`
811
852
 
812
853
  ```ts
813
854
  import { SafeHtml } from 'kerfjs';
855
+ import { L as ListIconTile } from './list-icon-tile-B8dr97OW.js';
856
+ export { a as ListIconTileColor, b as ListIconTileTone } from './list-icon-tile-B8dr97OW.js';
814
857
  import { PopupMenuEntry, PopupMenuPlacement } from './popup-menu.js';
858
+ import './css-values.js';
815
859
  import './semantic-content-BbzjvSu9.js';
816
860
 
817
861
  type ListActionRowRootAttributes = Readonly<Record<`data-${string}`, string | undefined> & {
@@ -819,6 +863,8 @@ type ListActionRowRootAttributes = Readonly<Record<`data-${string}`, string | un
819
863
  'data-action'?: never;
820
864
  'data-item-id'?: never;
821
865
  'data-has-icon'?: never;
866
+ 'data-icon-tile'?: never;
867
+ 'data-icon-tile-tone'?: never;
822
868
  'data-multiline'?: never;
823
869
  'data-density'?: never;
824
870
  'data-divider'?: never;
@@ -878,10 +924,13 @@ interface ListActionRowCommonProps {
878
924
  description?: string | SafeHtml;
879
925
  status?: string | SafeHtml;
880
926
  busy?: boolean;
927
+ /** Row height: `standard` is 44px; `compact` is 36px (42px with `iconTile`), the height of a compact `ListItem`. */
881
928
  density?: 'standard' | 'compact';
882
929
  divider?: 'none' | 'before' | 'after' | 'both';
883
930
  /** Decorative dormant content for the primary button. Must not contain interactive descendants. */
884
931
  icon?: SafeHtml;
932
+ /** Present `icon` in a filled 32px rounded tile with an 18px glyph: a quiet tone preset, or `{ color, foreground? }` for an application color. */
933
+ iconTile?: ListIconTile;
885
934
  action: string;
886
935
  itemId?: string;
887
936
  selected?: boolean;
@@ -908,16 +957,19 @@ interface ListActionRowCommonProps {
908
957
  }
909
958
  /** Exactly one trailing control: a native button (`trailingAction*`) or an overflow menu (`trailingMenu`). */
910
959
  type ListActionRowProps = ListActionRowCommonProps & (ListActionRowTrailingButtonProps | ListActionRowTrailingMenuProps);
911
- declare function ListActionRow({ label, description, status, busy, density, divider, icon, action, itemId, selected, pressed, accessibleLabel, title, multiline, state, disabled, tabIndex, placeholder, draggable, dragging, dropPosition, trailingAction, trailingActionLabel, trailingActionIcon, trailingActionDisabled, trailingActionTitle, trailingActionVisibility, trailingMenu, className, rootAttributes, trailingActionAttributes, slot, }: ListActionRowProps): SafeHtml;
960
+ declare function ListActionRow({ label, description, status, busy, density, divider, icon, iconTile, action, itemId, selected, pressed, accessibleLabel, title, multiline, state, disabled, tabIndex, placeholder, draggable, dragging, dropPosition, trailingAction, trailingActionLabel, trailingActionIcon, trailingActionDisabled, trailingActionTitle, trailingActionVisibility, trailingMenu, className, rootAttributes, trailingActionAttributes, slot, }: ListActionRowProps): SafeHtml;
912
961
 
913
- export { ListActionRow, type ListActionRowProps, type ListActionRowTrailingMenu };
962
+ export { ListActionRow, type ListActionRowProps, type ListActionRowTrailingMenu, ListIconTile };
914
963
  ```
915
964
 
916
965
  ## `@kerfjs/ui/list-item`
917
966
 
918
967
  ```ts
919
968
  import { SafeHtml } from 'kerfjs';
969
+ import { L as ListIconTile } from './list-icon-tile-B8dr97OW.js';
970
+ export { a as ListIconTileColor, b as ListIconTileTone } from './list-icon-tile-B8dr97OW.js';
920
971
  import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
972
+ import './css-values.js';
921
973
 
922
974
  type ListItemRootAttributes = Readonly<Record<`data-${string}`, string | undefined> & {
923
975
  'data-component'?: never;
@@ -932,6 +984,8 @@ type ListItemRootAttributes = Readonly<Record<`data-${string}`, string | undefin
932
984
  'data-state'?: never;
933
985
  'data-kui-disabled'?: never;
934
986
  'data-icon-align'?: never;
987
+ 'data-icon-tile'?: never;
988
+ 'data-icon-tile-tone'?: never;
935
989
  'data-dragging'?: never;
936
990
  'data-drop-position'?: never;
937
991
  }>;
@@ -940,6 +994,8 @@ interface ListItemProps {
940
994
  /** App-owned supporting text rendered in the component's stable label stack. */
941
995
  description?: string | SafeHtml;
942
996
  icon?: SafeHtml;
997
+ /** Present `icon` in a filled 32px rounded tile with an 18px glyph: a quiet tone preset, or `{ color, foreground? }` for an application color. */
998
+ iconTile?: ListIconTile;
943
999
  /** Dormant author content at the row's end; a placeholder renders it as a skeleton. */
944
1000
  trailing?: KerfUiContent;
945
1001
  /** Dormant status metadata rendered before trailing content; a placeholder renders it as a skeleton. */
@@ -981,11 +1037,11 @@ interface ListItemLinkProps extends Omit<ListItemProps, 'action' | 'pressed'> {
981
1037
  action?: never;
982
1038
  pressed?: never;
983
1039
  }
984
- declare function ListItem({ label, description, icon, trailing, status, busy, density, divider, selected, action, itemId, className, pressed, accessibleLabel, title, multiline, multilineIconAlign, state, disabled, tabIndex, placeholder, draggable, dragging, dropPosition, rootAttributes, slot, }: ListItemProps): SafeHtml;
1040
+ declare function ListItem({ label, description, icon, iconTile, trailing, status, busy, density, divider, selected, action, itemId, className, pressed, accessibleLabel, title, multiline, multilineIconAlign, state, disabled, tabIndex, placeholder, draggable, dragging, dropPosition, rootAttributes, slot, }: ListItemProps): SafeHtml;
985
1041
  /** A navigation row with native link activation and ListItem geometry. */
986
- declare function ListItemLink({ href, external, label, description, icon, trailing, status, busy, density, divider, selected, itemId, className, accessibleLabel, title, multiline, multilineIconAlign, state, disabled, tabIndex, placeholder, draggable, dragging, dropPosition, rootAttributes, slot, }: ListItemLinkProps): SafeHtml;
1042
+ declare function ListItemLink({ href, external, label, description, icon, iconTile, trailing, status, busy, density, divider, selected, itemId, className, accessibleLabel, title, multiline, multilineIconAlign, state, disabled, tabIndex, placeholder, draggable, dragging, dropPosition, rootAttributes, slot, }: ListItemLinkProps): SafeHtml;
987
1043
 
988
- export { ListItem, ListItemLink, type ListItemLinkProps, type ListItemProps };
1044
+ export { ListIconTile, ListItem, ListItemLink, type ListItemLinkProps, type ListItemProps };
989
1045
  ```
990
1046
 
991
1047
  ## `@kerfjs/ui/list-inset-control`
@@ -1447,6 +1503,15 @@ type Root = HTMLElement | Document;
1447
1503
  * - each app-owned `targets` pairing: a `Toolbar` or `List` named as chrome
1448
1504
  * draws the divider on its facing side.
1449
1505
  *
1506
+ * It also measures every `Pane` header laid over its content
1507
+ * (`headerPresentation="overlay"`, with fixed chrome placement): it publishes
1508
+ * the header's border-box block size on the Pane root as the inherited
1509
+ * `--kui-scroll-clearance-block-start` context, and marks the root
1510
+ * `data-header-overlay="measured"`, which moves the header over the content
1511
+ * and has the content clear it. The measurement follows the header as it
1512
+ * wraps, zooms, or changes content, and both are restored before paint if a
1513
+ * re-render drops them.
1514
+ *
1450
1515
  * Structure is re-read after every DOM change below root that can change a
1451
1516
  * pairing — a structural element or target id added, removed, or re-classed;
1452
1517
  * mutations inside scrolled content (a row's class, a list's rows) do not
@@ -1512,19 +1577,41 @@ declare function wireListReorder(root: HTMLElement | Document, { onReorder }: Wi
1512
1577
  export { type ListDropPosition, type ListReorder, type ListReorderSource, type ListReorderTarget, type WireListReorderOptions, reorderListItems, wireListReorder };
1513
1578
  ```
1514
1579
 
1580
+ ## `@kerfjs/ui/wire-list-focus-scroll`
1581
+
1582
+ ```ts
1583
+ type Root = HTMLElement | Document;
1584
+ /**
1585
+ * Bring a keyboard-focused row of a `scrollable` List below `root` fully into
1586
+ * view, focus ring included. Engines differ on how `focus()` scrolls a partly
1587
+ * hidden row: Chromium scrolls it to the nearest edge plus scroll padding,
1588
+ * Firefox waits until about half of it is hidden and then centers it, and
1589
+ * WebKit leaves it where it is. On `focusin`, when the newly focused element
1590
+ * matches `:focus-visible` and its ring crosses the nearest scrollable List's
1591
+ * clip, this calls `scrollIntoView({ block: 'nearest', inline: 'nearest' })`,
1592
+ * which honors the List's ring-room scroll padding in every engine. Pointer
1593
+ * focus is left alone, so a click never scrolls the row out from under the
1594
+ * pointer. Returns a disposer.
1595
+ */
1596
+ declare function wireListFocusScroll(root: Root): () => void;
1597
+
1598
+ export { wireListFocusScroll };
1599
+ ```
1600
+
1515
1601
  ## `@kerfjs/ui/nav-stack`
1516
1602
 
1517
1603
  ```ts
1518
- export { c as NavStack, N as NavStackProps, d as NavStackToolbarConfig, a as NavStackView, e as NavStackViewBottomToolbar, f as NavStackViewToolbar } from './nav-stack-Cp3Y8kJ9.js';
1604
+ export { c as NavStack, d as NavStackBottomToolbarPresentation, e as NavStackChromePresentation, N as NavStackProps, f as NavStackToolbarConfig, a as NavStackView, g as NavStackViewBottomToolbar, h as NavStackViewToolbar } from './nav-stack-VXTumzKa.js';
1519
1605
  import 'kerfjs';
1520
1606
  import './semantic-content-BbzjvSu9.js';
1521
1607
  import './list.js';
1522
1608
  import './extension-attributes-mu8MFUl0.js';
1523
1609
  import './flex-alignment-4ms8ZbV8.js';
1610
+ import './scroll-clearance-BikHljTc.js';
1524
1611
  import './sides-BPSWde0A.js';
1525
1612
  import './css-values.js';
1526
1613
  import './pane.js';
1527
- import './panel-toolbar-CL9tYOkh.js';
1614
+ import './panel-toolbar-vg6Ir5Dy.js';
1528
1615
  import './toolbar.js';
1529
1616
  import './lucide-icon.js';
1530
1617
  import 'lucide';
@@ -1559,15 +1646,16 @@ export { type WireNavStackOptions, wireNavStack };
1559
1646
  ```ts
1560
1647
  import * as kerfjs from 'kerfjs';
1561
1648
  import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
1562
- import { N as NavStackProps, a as NavStackView } from './nav-stack-Cp3Y8kJ9.js';
1649
+ import { N as NavStackProps, a as NavStackView } from './nav-stack-VXTumzKa.js';
1563
1650
  import { ResizableRegionProps } from './resizable-region.js';
1564
1651
  import './list.js';
1565
1652
  import './extension-attributes-mu8MFUl0.js';
1566
1653
  import './flex-alignment-4ms8ZbV8.js';
1654
+ import './scroll-clearance-BikHljTc.js';
1567
1655
  import './sides-BPSWde0A.js';
1568
1656
  import './css-values.js';
1569
1657
  import './pane.js';
1570
- import './panel-toolbar-CL9tYOkh.js';
1658
+ import './panel-toolbar-vg6Ir5Dy.js';
1571
1659
  import './toolbar.js';
1572
1660
  import './lucide-icon.js';
1573
1661
  import 'lucide';
@@ -1589,10 +1677,11 @@ interface SplitViewResizable extends Pick<ResizableRegionProps, 'separator' | 'h
1589
1677
  type SplitViewCompactViewToolbars = Pick<NavStackView, 'toolbar' | 'bottomToolbar'>;
1590
1678
  /**
1591
1679
  * The compact `NavStack`'s configuration: its toolbar configuration, back
1592
- * control, persistent bottom toolbar, and chrome dividers forward to the
1593
- * stack, and `list` / `detail` give each view its own toolbar groups.
1680
+ * control, persistent bottom toolbar, chrome dividers, and chrome and
1681
+ * bottom-toolbar presentations forward to the stack, and `list` / `detail`
1682
+ * give each view its own toolbar groups.
1594
1683
  */
1595
- interface SplitViewCompactStack extends Pick<NavStackProps, 'toolbarConfig' | 'backIcon' | 'backText' | 'hideToolbar' | 'bottomToolbar' | 'chromeDividers'> {
1684
+ interface SplitViewCompactStack extends Pick<NavStackProps, 'toolbarConfig' | 'backIcon' | 'backText' | 'hideToolbar' | 'bottomToolbar' | 'chromeDividers' | 'chromePresentation' | 'bottomToolbarPresentation'> {
1596
1685
  /** Toolbar content for the list (root) view. */
1597
1686
  list?: SplitViewCompactViewToolbars;
1598
1687
  /** Toolbar content for the pushed detail view. */
@@ -1661,6 +1750,7 @@ export { SplitView, type SplitViewCompactStack, type SplitViewCompactViewToolbar
1661
1750
  ```ts
1662
1751
  import * as kerfjs from 'kerfjs';
1663
1752
  import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
1753
+ import { S as ScrollClearance } from './scroll-clearance-BikHljTc.js';
1664
1754
 
1665
1755
  /**
1666
1756
  * Logical pane sides: where a {@link Pane} can show a separator and where it can
@@ -1686,6 +1776,9 @@ type PaneRootAttributes = Readonly<Record<`data-${string}`, string | undefined>
1686
1776
  'data-appearance'?: never;
1687
1777
  'data-deep-inset'?: never;
1688
1778
  'data-outlined'?: never;
1779
+ 'data-scroll-clearance'?: never;
1780
+ 'data-header-presentation'?: never;
1781
+ 'data-header-overlay'?: never;
1689
1782
  }>;
1690
1783
  /** How a Pane's header and footer relate to its scrolling content. */
1691
1784
  type PaneChromePlacement = 'fixed' | 'auto';
@@ -1695,6 +1788,12 @@ type PaneChromePlacement = 'fixed' | 'auto';
1695
1788
  * chrome, as `wireScrollDividers` reports; `always`; or `none`.
1696
1789
  */
1697
1790
  type PaneChromeDividers = 'scroll' | 'always' | 'none';
1791
+ /**
1792
+ * How a Pane's header relates to its scrolling content: `docked` in its own
1793
+ * row above the content, or `overlay` laid over the content's top edge on the
1794
+ * translucent chrome material, so content scrolls visibly beneath it.
1795
+ */
1796
+ type PaneHeaderPresentation = 'docked' | 'overlay';
1698
1797
  /** Background treatment of the Pane's scrolling work surface. */
1699
1798
  type PaneAppearance = 'default' | 'sunken';
1700
1799
  interface PaneProps {
@@ -1723,8 +1822,35 @@ interface PaneProps {
1723
1822
  * The line is drawn inside the chrome, so no state moves the content.
1724
1823
  */
1725
1824
  chromeDividers?: PaneChromeDividers;
1825
+ /**
1826
+ * `docked` (default) gives the header its own row above the scrolling
1827
+ * content. `overlay` lays the header over the content's top edge on the
1828
+ * translucent chrome material (`--kui-chrome-material`, opaque under
1829
+ * `prefers-reduced-transparency`, forced colors, or without
1830
+ * `backdrop-filter`), so content scrolls visibly beneath it. Once
1831
+ * `wireScrollDividers` (`@kerfjs/ui/wire-scroll-dividers`) is wired above
1832
+ * the pane it measures the header and publishes its height as the
1833
+ * `--kui-scroll-clearance-block-start` context, which the content adds to
1834
+ * its block-start padding and `scroll-padding` without any
1835
+ * `scrollClearance` prop, so the first item, and anything focused or
1836
+ * scrolled into view, rests clear of the header. Until then, and with
1837
+ * `chromePlacement="auto"`, the header stays docked. Keep overlay header
1838
+ * text in the normal text color: quiet text can fall below AA over the
1839
+ * content passing beneath it.
1840
+ */
1841
+ headerPresentation?: PaneHeaderPresentation;
1726
1842
  /** Paint the scrolling work surface with the shared lowered-surface color. */
1727
1843
  appearance?: PaneAppearance;
1844
+ /**
1845
+ * Clear chrome that lies over the scrolling content's block-start and/or
1846
+ * block-end edge, such as a `DialogSurface` floating footer over a filling
1847
+ * Pane. The content scroller adds the inherited
1848
+ * `--kui-scroll-clearance-block-*` context that chrome publishes to its block
1849
+ * padding and `scroll-padding`, so content scrolls visibly beneath the chrome
1850
+ * while its first and last items (and anything focused or scrolled into
1851
+ * view) can still rest clear of it. Defaults to none.
1852
+ */
1853
+ scrollClearance?: ScrollClearance;
1728
1854
  /** Add 8px to every side of scrolling content (default: false). */
1729
1855
  deepInset?: boolean;
1730
1856
  /** Opt into keyboard (`0`) or programmatic (`-1`) focus on the Pane root. */
@@ -1765,16 +1891,16 @@ interface PaneProps {
1765
1891
  * or a CollapsiblePanel) forwards, so the app configures that pane instead of
1766
1892
  * styling it. An omitted or `undefined` field keeps the composite's default.
1767
1893
  */
1768
- type PaneConfig = Pick<PaneProps, 'contentElement' | 'contentLabel' | 'separators' | 'safeAreaEdges' | 'chromeDividers' | 'appearance' | 'deepInset' | 'tabIndex' | 'outlined'>;
1894
+ type PaneConfig = Pick<PaneProps, 'contentElement' | 'contentLabel' | 'separators' | 'safeAreaEdges' | 'chromeDividers' | 'headerPresentation' | 'appearance' | 'deepInset' | 'scrollClearance' | 'tabIndex' | 'outlined'>;
1769
1895
  /**
1770
1896
  * An unpadded application column with optional fixed header/footer slots and one
1771
1897
  * scrolling vertical content owner. Separator lines are independently opt-in on
1772
1898
  * each logical edge, so the same component works as a sidebar, main area,
1773
1899
  * inspector, or dialog column.
1774
1900
  */
1775
- declare function Pane({ header, children, footer, chromePlacement, chromeDividers, appearance, deepInset, tabIndex, outlined, element, contentElement, separators, safeAreaEdges, id, label, contentLabel, className, headerClassName, contentClassName, footerClassName, rootAttributes, slot, }: PaneProps): kerfjs.SafeHtml;
1901
+ declare function Pane({ header, children, footer, chromePlacement, chromeDividers, headerPresentation, appearance, deepInset, scrollClearance, tabIndex, outlined, element, contentElement, separators, safeAreaEdges, id, label, contentLabel, className, headerClassName, contentClassName, footerClassName, rootAttributes, slot, }: PaneProps): kerfjs.SafeHtml;
1776
1902
 
1777
- export { Pane, type PaneAppearance, type PaneChromeDividers, type PaneChromePlacement, type PaneConfig, type PaneContentElement, type PaneElement, type PaneProps, type PaneSeparatorSide };
1903
+ export { Pane, type PaneAppearance, type PaneChromeDividers, type PaneChromePlacement, type PaneConfig, type PaneContentElement, type PaneElement, type PaneHeaderPresentation, type PaneProps, type PaneSeparatorSide, ScrollClearance };
1778
1904
  ```
1779
1905
 
1780
1906
  ## `@kerfjs/ui/workbench`
@@ -1782,16 +1908,17 @@ export { Pane, type PaneAppearance, type PaneChromeDividers, type PaneChromePlac
1782
1908
  ```ts
1783
1909
  import { SafeHtml } from 'kerfjs';
1784
1910
  import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
1785
- import { b as NavPane, N as NavStackProps } from './nav-stack-Cp3Y8kJ9.js';
1911
+ import { b as NavPane, N as NavStackProps } from './nav-stack-VXTumzKa.js';
1786
1912
  import { ListConfig } from './list.js';
1787
1913
  import { PaneConfig } from './pane.js';
1788
1914
  import { ResizableRegionSeparator, ResizableRegionCollapseMotion, ResizableRegionContentOverflow, ResizableRegionPresentation, ResizableRegionRestorePosition } from './resizable-region.js';
1789
- import { a as PanelToolbar, c as PanelBottomToolbar, b as PanelChromePlacement, d as PanelToggle } from './panel-toolbar-CL9tYOkh.js';
1915
+ import { a as PanelToolbar, c as PanelBottomToolbar, b as PanelChromePlacement, d as PanelToggle } from './panel-toolbar-vg6Ir5Dy.js';
1790
1916
  import { ToolbarConfig } from './toolbar.js';
1791
1917
  import './toolbar-text.js';
1792
1918
  import './css-values.js';
1793
1919
  import './extension-attributes-mu8MFUl0.js';
1794
1920
  import './flex-alignment-4ms8ZbV8.js';
1921
+ import './scroll-clearance-BikHljTc.js';
1795
1922
  import './sides-BPSWde0A.js';
1796
1923
  import './lucide-icon.js';
1797
1924
  import 'lucide';
@@ -1882,7 +2009,11 @@ interface WorkbenchPanelBase {
1882
2009
  * with `wireWorkbench` from `@kerfjs/ui/wire-workbench`.
1883
2010
  */
1884
2011
  resizable?: boolean | WorkbenchPanelResizable;
1885
- /** Accessible name for the panel region. */
2012
+ /**
2013
+ * Accessible name for the panel region, in title style. A resizable
2014
+ * panel's handle is named "Resize {label}", or "Resize Left Rail" /
2015
+ * "Resize Right Rail" / "Resize Bottom Drawer" without one.
2016
+ */
1886
2017
  label?: string;
1887
2018
  /** Opt into keyboard (`0`) or programmatic (`-1`) focus on the panel region. */
1888
2019
  tabIndex?: 0 | -1;
@@ -2179,8 +2310,8 @@ export { type WireWorkbenchOptions, type WireWorkbenchPanel, type WorkbenchPanel
2179
2310
  ```ts
2180
2311
  import { SafeHtml } from 'kerfjs';
2181
2312
  import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
2182
- import { P as PanelSide, a as PanelToolbar, b as PanelChromePlacement, c as PanelBottomToolbar, d as PanelToggle } from './panel-toolbar-CL9tYOkh.js';
2183
- export { e as collapsiblePanelToggleIcon } from './panel-toolbar-CL9tYOkh.js';
2313
+ import { P as PanelSide, a as PanelToolbar, b as PanelChromePlacement, c as PanelBottomToolbar, d as PanelToggle } from './panel-toolbar-vg6Ir5Dy.js';
2314
+ export { e as collapsiblePanelToggleIcon } from './panel-toolbar-vg6Ir5Dy.js';
2184
2315
  import { ToolbarConfig } from './toolbar.js';
2185
2316
  import { ListConfig } from './list.js';
2186
2317
  import { PaneConfig } from './pane.js';
@@ -2191,6 +2322,7 @@ import './css-values.js';
2191
2322
  import './sides-BPSWde0A.js';
2192
2323
  import './extension-attributes-mu8MFUl0.js';
2193
2324
  import './flex-alignment-4ms8ZbV8.js';
2325
+ import './scroll-clearance-BikHljTc.js';
2194
2326
 
2195
2327
  /** Which edge a {@link CollapsiblePanel} docks to. */
2196
2328
  type CollapsiblePanelSide = PanelSide;
@@ -2397,6 +2529,7 @@ export { type SidebarStorage, type WireSidebarOptions, type WireSidebarPanel, wi
2397
2529
  import { SafeHtml } from 'kerfjs';
2398
2530
  import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
2399
2531
  import { PaneAppearance } from './pane.js';
2532
+ import './scroll-clearance-BikHljTc.js';
2400
2533
 
2401
2534
  interface TabNavigatorTabBase<Id extends string> {
2402
2535
  id: Id;
@@ -2448,6 +2581,12 @@ interface TabNavigatorTabDotBadge {
2448
2581
  }
2449
2582
  /** One bottom-bar destination: its label, optional icon and badge, and content. */
2450
2583
  type TabNavigatorTab<Id extends string = string> = TabNavigatorTabBase<Id> & (TabNavigatorTabCountBadge | TabNavigatorTabDotBadge);
2584
+ /**
2585
+ * How a {@link TabNavigator}'s tab bar relates to the active scene: `docked`
2586
+ * below it, or `overlay` laid over its bottom edge on the translucent chrome
2587
+ * material, so the scene's content scrolls visibly beneath the bar.
2588
+ */
2589
+ type TabNavigatorBarPresentation = 'docked' | 'overlay';
2451
2590
  interface TabNavigatorProps<Id extends string = string> {
2452
2591
  id: string;
2453
2592
  /** Accessible name for the tab bar. */
@@ -2472,6 +2611,20 @@ interface TabNavigatorProps<Id extends string = string> {
2472
2611
  * is the bar's own 1px top border, so no state moves the bar or a tab.
2473
2612
  */
2474
2613
  chromeDividers?: 'scroll' | 'always' | 'none';
2614
+ /**
2615
+ * `docked` (default) gives the tab bar its own band below the scenes.
2616
+ * `overlay` lays it over the active scene's bottom edge on the translucent
2617
+ * chrome material (opaque under reduced transparency, increased contrast,
2618
+ * or without `backdrop-filter`; `Canvas` in forced colors), so content
2619
+ * scrolls visibly beneath it, as under an iOS tab bar. `wireTabNavigator`
2620
+ * measures the live bar (bottom safe area included) and the scenes hand
2621
+ * its height to their content as the block-end `--kui-edge-inset-*`
2622
+ * context, so a plain scene, a sole `Pane`, or a `NavStack` (and its own
2623
+ * bottom toolbar, which then sits above the bar) rests its last item clear
2624
+ * of it. Until then it stays docked. Unselected tab labels lift halfway
2625
+ * toward the normal text color to keep AA over the content beneath.
2626
+ */
2627
+ barPresentation?: TabNavigatorBarPresentation;
2475
2628
  className?: string;
2476
2629
  /** Native named-slot assignment when composed inside a web component. */
2477
2630
  slot?: string;
@@ -2484,9 +2637,9 @@ interface TabNavigatorProps<Id extends string = string> {
2484
2637
  * On larger classes, promote the tabs to a `Workbench` rail or sidebar instead of
2485
2638
  * a bottom bar. See `docs/23-app-layouts.md` §3.4.
2486
2639
  */
2487
- declare function TabNavigator<Id extends string>({ id, label, tabs, active, separator, chromeDividers, className, slot, }: TabNavigatorProps<Id>): SafeHtml;
2640
+ declare function TabNavigator<Id extends string>({ id, label, tabs, active, separator, chromeDividers, barPresentation, className, slot, }: TabNavigatorProps<Id>): SafeHtml;
2488
2641
 
2489
- export { TabNavigator, type TabNavigatorProps, type TabNavigatorTab };
2642
+ export { TabNavigator, type TabNavigatorBarPresentation, type TabNavigatorProps, type TabNavigatorTab };
2490
2643
  ```
2491
2644
 
2492
2645
  ## `@kerfjs/ui/wire-tab-navigator`
@@ -2498,7 +2651,9 @@ interface WireTabNavigatorOptions {
2498
2651
  }
2499
2652
  /**
2500
2653
  * Wire a `TabNavigator`'s bottom tab bar: clicking a tab calls `onSelect` with its
2501
- * id (the app then updates its controlled `active`). Returns a disposer.
2654
+ * id (the app then updates its controlled `active`). With
2655
+ * `barPresentation="overlay"` it also measures the live bar and lays it over
2656
+ * the scenes (see `TabNavigatorProps.barPresentation`). Returns a disposer.
2502
2657
  */
2503
2658
  declare function wireTabNavigator(root: Element, options: WireTabNavigatorOptions): () => void;
2504
2659
 
@@ -2661,13 +2816,14 @@ import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
2661
2816
  import './toolbar.js';
2662
2817
  import './sides-BPSWde0A.js';
2663
2818
  import './pane.js';
2819
+ import './scroll-clearance-BikHljTc.js';
2664
2820
  import './workbench.js';
2665
- import './nav-stack-Cp3Y8kJ9.js';
2821
+ import './nav-stack-VXTumzKa.js';
2666
2822
  import './list.js';
2667
2823
  import './extension-attributes-mu8MFUl0.js';
2668
2824
  import './flex-alignment-4ms8ZbV8.js';
2669
2825
  import './css-values.js';
2670
- import './panel-toolbar-CL9tYOkh.js';
2826
+ import './panel-toolbar-vg6Ir5Dy.js';
2671
2827
  import './lucide-icon.js';
2672
2828
  import 'lucide';
2673
2829
  import './toolbar-text.js';
@@ -2688,15 +2844,31 @@ declare function Catalog({ id, brand, sections, active, content, collapsed, them
2688
2844
  type CatalogExampleAlign = 'glyph' | 'inline-control' | 'text-trigger' | 'none';
2689
2845
  interface CatalogExampleViewport {
2690
2846
  layout?: 'grid' | 'flex' | 'flex-column';
2691
- width?: 'full' | 'compact' | 'medium' | 'wide' | 'text' | 'control';
2847
+ /** Specimen width. `sidebar` (272px, capped at the stage) shows a sidebar
2848
+ * pane's content at a production rail's width. */
2849
+ width?: 'full' | 'sidebar' | 'compact' | 'medium' | 'wide' | 'text' | 'control';
2692
2850
  /** Fixed specimen height; `app` frames an application-sized recipe or layout.
2693
2851
  * A fixed height is definite, so a child that fills with `height: 100%`
2694
2852
  * (a horizontal `ResizableRegion`, say) spans the whole frame. */
2695
2853
  height?: 'short' | 'reduced' | 'medium' | 'tall' | 'app';
2696
2854
  /** A minimum the frame may grow past. It is not a definite height: a child
2697
2855
  * sized with `height: 100%` falls back to its content height, so use
2698
- * `height` when the specimen must fill the frame. */
2699
- minHeight?: 'short' | 'medium';
2856
+ * `height` when the specimen must fill the frame. `app` (592px) is the
2857
+ * application frame's height as a floor, for a stage that hosts a
2858
+ * frame-anchored top-layer specimen above in-flow content. */
2859
+ minHeight?: 'short' | 'medium' | 'app';
2860
+ /** Names the frame as a CSS anchor (`anchor-name`), so a top-layer
2861
+ * specimen whose own CSS sets `position-anchor` to this dashed-ident
2862
+ * positions against the frame as it would against its production anchor.
2863
+ * Anchor names are document-wide: give each frame on a page its own. */
2864
+ anchorName?: `--${string}`;
2865
+ /** Caps each in-flow child at a centered-or-start content column:
2866
+ * `compact` (440px), `medium` (640px), or `wide` (864px), each capped at
2867
+ * the frame. `[popover]` children keep their own geometry. Applies to
2868
+ * block, `grid`, and `flex-column` flows. */
2869
+ contentWidth?: 'compact' | 'medium' | 'wide';
2870
+ /** Where a `contentWidth` column sits in the frame; default `start`. */
2871
+ contentAlign?: 'start' | 'center';
2700
2872
  frame?: 'solid' | 'dashed';
2701
2873
  surface?: 'default' | 'lowered';
2702
2874
  overflow?: 'hidden' | 'auto-x';
@@ -2799,13 +2971,14 @@ import 'kerfjs';
2799
2971
  import './semantic-content-BbzjvSu9.js';
2800
2972
  import './sides-BPSWde0A.js';
2801
2973
  import './pane.js';
2974
+ import './scroll-clearance-BikHljTc.js';
2802
2975
  import './workbench.js';
2803
- import './nav-stack-Cp3Y8kJ9.js';
2976
+ import './nav-stack-VXTumzKa.js';
2804
2977
  import './list.js';
2805
2978
  import './extension-attributes-mu8MFUl0.js';
2806
2979
  import './flex-alignment-4ms8ZbV8.js';
2807
2980
  import './css-values.js';
2808
- import './panel-toolbar-CL9tYOkh.js';
2981
+ import './panel-toolbar-vg6Ir5Dy.js';
2809
2982
  import './lucide-icon.js';
2810
2983
  import 'lucide';
2811
2984
  import './toolbar-text.js';
@@ -2853,13 +3026,14 @@ import './toolbar.js';
2853
3026
  import './semantic-content-BbzjvSu9.js';
2854
3027
  import './sides-BPSWde0A.js';
2855
3028
  import './pane.js';
3029
+ import './scroll-clearance-BikHljTc.js';
2856
3030
  import './workbench.js';
2857
- import './nav-stack-Cp3Y8kJ9.js';
3031
+ import './nav-stack-VXTumzKa.js';
2858
3032
  import './list.js';
2859
3033
  import './extension-attributes-mu8MFUl0.js';
2860
3034
  import './flex-alignment-4ms8ZbV8.js';
2861
3035
  import './css-values.js';
2862
- import './panel-toolbar-CL9tYOkh.js';
3036
+ import './panel-toolbar-vg6Ir5Dy.js';
2863
3037
  import './lucide-icon.js';
2864
3038
  import 'lucide';
2865
3039
  import './toolbar-text.js';
@@ -3027,7 +3201,7 @@ import { CssColor } from './css-values.js';
3027
3201
  type ChoiceChipsSize = 'default' | 'compact';
3028
3202
  /**
3029
3203
  * A leading color dot: a {@link CssColor} from `uiColor()`, `colorVar()`, or
3030
- * `foregroundColor()`, or `'transparent'` for the no-color swatch (an outlined
3204
+ * `fillColor()`, or `'transparent'` for the no-color swatch (an outlined
3031
3205
  * dot struck through by a diagonal line).
3032
3206
  */
3033
3207
  type ChoiceChipsSwatch = CssColor | 'transparent';
@@ -3044,41 +3218,153 @@ interface ChoiceChipsChoice<Value extends string = string> {
3044
3218
  disabled?: boolean;
3045
3219
  }
3046
3220
  interface ChoiceChipsCommonProps<Value extends string> {
3047
- /** Native radio `name`: the form field the selected value submits under. */
3221
+ /**
3222
+ * Native input `name`: the form field the selected value (or, with
3223
+ * `multiple`, every checked value) submits under.
3224
+ */
3048
3225
  name: string;
3049
- /** The selected value. Omit (or pass `undefined`) for no selection. */
3050
- value?: NoInfer<Value>;
3051
3226
  choices: readonly ChoiceChipsChoice<Value>[];
3052
- /** Delegated `data-action` on every radio; listen for `change`. */
3227
+ /** Delegated `data-action` on every input; listen for `change`. */
3053
3228
  action?: string;
3054
3229
  size?: ChoiceChipsSize;
3055
3230
  /** Disable the whole group. */
3056
3231
  disabled?: boolean;
3057
- /** Require a selection for native form validation. */
3058
- required?: boolean;
3059
- /** Associate the radios with a form outside their ancestor chain. */
3232
+ /** Associate the inputs with a form outside their ancestor chain. */
3060
3233
  form?: string;
3061
3234
  id?: string;
3062
3235
  className?: string;
3063
3236
  /** Native named-slot assignment when composed inside a web component. */
3064
3237
  slot?: string;
3065
3238
  }
3066
- /** A radio group is named either by a string or by a visible heading's id. */
3067
- type ChoiceChipsProps<Value extends string = string> = ChoiceChipsCommonProps<Value> & ({
3239
+ /** One exclusive value (the default), backed by native radios. */
3240
+ interface ChoiceChipsSingleProps<Value extends string = string> {
3241
+ multiple?: false;
3242
+ /** The selected value. Omit (or pass `undefined`) for no selection. */
3243
+ value?: NoInfer<Value>;
3244
+ /** Require a selection for native form validation. */
3245
+ required?: boolean;
3246
+ }
3247
+ /**
3248
+ * Any number of values, backed by native checkboxes: each pill is its own Tab
3249
+ * stop, Space toggles it, and every checked value submits under `name`.
3250
+ */
3251
+ interface ChoiceChipsMultipleProps<Value extends string = string> {
3252
+ multiple: true;
3253
+ /** The checked values. Omit (or pass `[]`) for none. */
3254
+ value?: readonly NoInfer<Value>[];
3255
+ /**
3256
+ * Native `required` on a checkbox demands that one box, so a multiple group
3257
+ * has no "at least one" requirement; validate the checked set in the app.
3258
+ */
3259
+ required?: never;
3260
+ }
3261
+ /** A group is named either by a string or by a visible heading's id. */
3262
+ type ChoiceChipsNaming = {
3068
3263
  label: string;
3069
3264
  labelledBy?: never;
3070
3265
  } | {
3071
3266
  labelledBy: string;
3072
3267
  label?: never;
3073
- });
3268
+ };
3269
+ type ChoiceChipsProps<Value extends string = string> = ChoiceChipsCommonProps<Value> & (ChoiceChipsSingleProps<Value> | ChoiceChipsMultipleProps<Value>) & ChoiceChipsNaming;
3270
+ /**
3271
+ * A wrapping set of pill chips backed by native inputs. By default it is an
3272
+ * exclusive radio group: one Tab stop, arrow-key selection, and a real form
3273
+ * value. With `multiple` it is a checkbox group: each pill toggles on its own
3274
+ * and every checked value submits. Each choice may lead with a color swatch
3275
+ * (including a struck-through transparent swatch) or an icon.
3276
+ */
3277
+ declare function ChoiceChips<Value extends string>(props: ChoiceChipsProps<Value>): SafeHtml;
3278
+
3279
+ export { ChoiceChips, type ChoiceChipsChoice, type ChoiceChipsMultipleProps, type ChoiceChipsNaming, type ChoiceChipsProps, type ChoiceChipsSingleProps, type ChoiceChipsSize, type ChoiceChipsSwatch };
3280
+ ```
3281
+
3282
+ ## `@kerfjs/ui/composer`
3283
+
3284
+ ```ts
3285
+ import * as kerfjs from 'kerfjs';
3286
+ import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
3287
+
3074
3288
  /**
3075
- * An exclusive, wrapping set of pill chips backed by native radios: one Tab
3076
- * stop, arrow-key selection, and a real form value. Each choice may lead with
3077
- * a color swatch (including a struck-through transparent swatch) or an icon.
3289
+ * Application `data-*` identity on the Composer root, such as `data-key`;
3290
+ * the composer's own configuration attributes stay protected.
3078
3291
  */
3079
- declare function ChoiceChips<Value extends string>({ name, value, choices, action, size, disabled, required, form, id, className, slot, label, labelledBy, }: ChoiceChipsProps<Value>): SafeHtml;
3292
+ type ComposerRootAttributes = Readonly<Record<`data-${string}`, string | undefined>>;
3293
+ interface ComposerProps {
3294
+ /** The message field's accessible name, in title style ("Message"). */
3295
+ label: string;
3296
+ /** Native textarea `name`: the form field the message submits under. */
3297
+ name: string;
3298
+ /**
3299
+ * The textarea id. With a `hint`, the hint takes `<id>-hint` and becomes
3300
+ * the field's accessible description.
3301
+ */
3302
+ id?: string;
3303
+ /** The field's text: a draft to restore, or `''` after sending. */
3304
+ value?: string;
3305
+ /** Sentence-style example of what to write ("Ask about this build"). */
3306
+ placeholder?: string;
3307
+ /**
3308
+ * Visible lines while the field is empty or short (default 1). The field
3309
+ * grows with its content from here.
3310
+ */
3311
+ minRows?: number;
3312
+ /**
3313
+ * Lines the field grows to before it scrolls (default 8). At least
3314
+ * `minRows`.
3315
+ */
3316
+ maxRows?: number;
3317
+ /** Quiet, sentence-style supporting copy at the start of the action row. */
3318
+ hint?: string;
3319
+ /** Trailing controls in the action row, normally one brand Send button. */
3320
+ actions: KerfUiContent;
3321
+ /** Disable the field; the app disables its own actions. */
3322
+ disabled?: boolean;
3323
+ /**
3324
+ * Opt in to Enter-to-send: with `wireComposers` running over an ancestor,
3325
+ * Enter (or Cmd/Ctrl+Enter) in the field activates the first trailing
3326
+ * action, Shift+Enter inserts a newline, and an Enter that commits an IME
3327
+ * composition or meets an empty message does not send. The field announces
3328
+ * the shortcut with `aria-keyshortcuts`.
3329
+ */
3330
+ submitOnEnter?: boolean;
3331
+ /** Safe `data-*` identity on the root. */
3332
+ rootAttributes?: ComposerRootAttributes;
3333
+ className?: string;
3334
+ /** Native named-slot assignment, such as a `wa-dialog`'s `footer`. */
3335
+ slot?: string;
3336
+ }
3337
+ /**
3338
+ * A chat or prompt composer: a raised frame whose border turns brand while
3339
+ * focus is within, holding a borderless message field that grows with its
3340
+ * content between `minRows` and `maxRows` lines, above an action row with an
3341
+ * optional hint and trailing actions. The app owns the value and sending;
3342
+ * `submitOnEnter` with `wireComposers` adds Enter-to-send.
3343
+ */
3344
+ declare function Composer({ label, name, id, value, placeholder, minRows, maxRows, hint, actions, disabled, submitOnEnter, rootAttributes, className, slot, }: ComposerProps): kerfjs.SafeHtml;
3080
3345
 
3081
- export { ChoiceChips, type ChoiceChipsChoice, type ChoiceChipsProps, type ChoiceChipsSize, type ChoiceChipsSwatch };
3346
+ export { Composer, type ComposerProps, type ComposerRootAttributes };
3347
+ ```
3348
+
3349
+ ## `@kerfjs/ui/wire-composers`
3350
+
3351
+ ```ts
3352
+ type Root = HTMLElement | Document;
3353
+ /**
3354
+ * Enter-to-send for every `Composer` rendered with `submitOnEnter` below
3355
+ * root. In its field, Enter (alone or with Cmd or Ctrl) activates the
3356
+ * composer's first trailing action, so a keyboard send runs the same
3357
+ * delegated handler as a click. Shift+Enter and Alt+Enter insert a newline.
3358
+ * Nothing is sent, and no newline is inserted, when the message is empty or
3359
+ * whitespace-only, the key is auto-repeating, or the first action is
3360
+ * disabled, loading, or `aria-disabled`. An Enter that commits an IME
3361
+ * composition (`isComposing`, keyCode 229, or between `compositionstart` and
3362
+ * `compositionend`) is left to the input method. Dispose with the owning
3363
+ * application.
3364
+ */
3365
+ declare function wireComposers(root: Root): () => void;
3366
+
3367
+ export { wireComposers };
3082
3368
  ```
3083
3369
 
3084
3370
  ## `@kerfjs/ui/select`
@@ -3237,7 +3523,12 @@ interface StateBannerProps {
3237
3523
  urgency?: StateBannerUrgency;
3238
3524
  /** Keep the detail beside the title, or give it its own line. */
3239
3525
  copyLayout?: StateBannerCopyLayout;
3240
- /** Place the action beside the copy or on a separate trailing row. */
3526
+ /**
3527
+ * `trailing` (the default) puts the action beside the copy while the copy
3528
+ * keeps its minimum readable width, and otherwise wraps it onto its own
3529
+ * end-aligned trailing row, at any viewport or container width. `below`
3530
+ * always gives the action that separate trailing row.
3531
+ */
3241
3532
  actionPlacement?: StateBannerActionPlacement;
3242
3533
  /**
3243
3534
  * `card` (the default) is an inset, rounded, fully bordered banner beside
@@ -3391,7 +3682,7 @@ export { SunkenPanel, type SunkenPanelProps, type SunkenPanelShape, ensureSunken
3391
3682
  ## `@kerfjs/ui/token-search-field`
3392
3683
 
3393
3684
  ```ts
3394
- export { T as TokenSearchEditorAttributes, a as TokenSearchField, b as TokenSearchFieldProps, c as TokenSearchFieldValue, j as TokenSearchToken, k as TokenSearchTrailingAction, p as placeTokenSearchCaret, r as readTokenSearchField } from './token-search-model-DTcTXWMS.js';
3685
+ export { T as TokenSearchEditorAttributes, a as TokenSearchField, b as TokenSearchFieldProps, c as TokenSearchFieldValue, j as TokenSearchToken, k as TokenSearchTrailingAction, l as TokenSearchTrailingActionAttributes, p as placeTokenSearchCaret, r as readTokenSearchField } from './token-search-model-aYR0YAei.js';
3395
3686
  import 'kerfjs';
3396
3687
  import './semantic-content-BbzjvSu9.js';
3397
3688
  ```
@@ -3400,7 +3691,7 @@ import './semantic-content-BbzjvSu9.js';
3400
3691
 
3401
3692
  ```ts
3402
3693
  import { Signal } from 'kerfjs';
3403
- import { d as TokenSearchModel } from './token-search-model-DTcTXWMS.js';
3694
+ import { d as TokenSearchModel } from './token-search-model-aYR0YAei.js';
3404
3695
  import './semantic-content-BbzjvSu9.js';
3405
3696
 
3406
3697
  interface TokenSearchSubmit {
@@ -3689,10 +3980,16 @@ import { S as SemanticTone } from './semantic-tone-CdW013KF.js';
3689
3980
  import { BadgeAppearance, BadgeShape, BadgeSize } from './badge.js';
3690
3981
  import './css-values.js';
3691
3982
 
3983
+ /**
3984
+ * A chip color role: a shared semantic tone, or `inherit`, which follows the
3985
+ * surrounding foreground (a chip inside a `brand-loud` ContentItem bubble)
3986
+ * and derives its fill, border, and focus ring from `currentColor`.
3987
+ */
3988
+ type ChipTone = SemanticTone | 'inherit';
3692
3989
  interface ChipCommonProps {
3693
3990
  /** Decorative leading icon, normally an unsized LucideIcon. */
3694
3991
  icon?: SafeHtml;
3695
- tone?: SemanticTone;
3992
+ tone?: ChipTone;
3696
3993
  appearance?: BadgeAppearance;
3697
3994
  shape?: BadgeShape;
3698
3995
  size?: BadgeSize;
@@ -3703,24 +4000,50 @@ interface ChipCommonProps {
3703
4000
  /** Native named-slot assignment when composed inside a web component. */
3704
4001
  slot?: string;
3705
4002
  }
3706
- /** A removable chip needs both a delegated action and a specific accessible name. */
3707
- type ChipProps = ChipCommonProps & ({
4003
+ type ChipLabelProps = {
3708
4004
  children: SafeHtml | string | number;
3709
4005
  truncate?: false;
3710
4006
  } | {
3711
4007
  children: string;
3712
4008
  truncate: true;
3713
- }) & ({
4009
+ };
4010
+ interface ChipNoLinkProps {
4011
+ href?: never;
4012
+ download?: never;
4013
+ external?: never;
4014
+ }
4015
+ /**
4016
+ * A link chip renders a native `<a>` with Chip geometry. It cannot also carry
4017
+ * a remove button, because a button inside a link is invalid.
4018
+ */
4019
+ interface ChipLinkProps {
4020
+ /** Native destination; the chip renders as an `<a>`. */
4021
+ href: string;
4022
+ /** Download the destination: `true`, or the suggested file name. */
4023
+ download?: string | boolean;
4024
+ /** Open in a new tab with a safe rel and announce that behavior. */
4025
+ external?: boolean;
4026
+ removeAction?: never;
4027
+ removeLabel?: never;
4028
+ }
4029
+ /**
4030
+ * A plain chip, a removable chip (a delegated action plus a specific
4031
+ * accessible name), or a link chip (`href`, optional `download`/`external`).
4032
+ */
4033
+ type ChipProps = ChipCommonProps & ChipLabelProps & (({
3714
4034
  removeAction: string;
3715
4035
  removeLabel: string;
3716
- } | {
4036
+ } & ChipNoLinkProps) | ({
3717
4037
  removeAction?: never;
3718
4038
  removeLabel?: never;
3719
- });
3720
- /** A short label with an optional native remove button. The application owns removal. */
3721
- declare function Chip({ children, icon, truncate, tone, appearance, shape, size, disabled, itemId, className, slot, ...remove }: ChipProps): SafeHtml;
4039
+ } & ChipNoLinkProps) | ChipLinkProps);
4040
+ /**
4041
+ * A short label with an optional native remove button, or a native link when
4042
+ * `href` is set. The application owns removal and the link destination.
4043
+ */
4044
+ declare function Chip({ children, icon, truncate, tone, appearance, shape, size, disabled, itemId, className, slot, href, download, external, removeAction, removeLabel, }: ChipProps): SafeHtml;
3722
4045
 
3723
- export { Chip, type ChipProps };
4046
+ export { Chip, type ChipProps, type ChipTone };
3724
4047
  ```
3725
4048
 
3726
4049
  ## `@kerfjs/ui/lucide-icon`
@@ -3788,9 +4111,24 @@ type DialogSurfaceHeight = CssLength | 'viewport';
3788
4111
  /**
3789
4112
  * How the dialog body lays out its children: `flow` (default) scrolls ordinary
3790
4113
  * content in the body; `fill` gives one child the body's whole height and
3791
- * lets it own scrolling (a SplitView, a Pane, an editor).
4114
+ * lets it own scrolling (a SplitView, a Pane, an editor); `fill-last` stacks
4115
+ * the leading children at their natural height and gives the last child the
4116
+ * remaining height to own its scrolling (a heading and notices above a
4117
+ * scrolling transcript).
4118
+ */
4119
+ type DialogSurfaceBodyLayout = 'flow' | 'fill' | 'fill-last';
4120
+ /**
4121
+ * Where the dialog footer sits: `docked` (default) below the body, or
4122
+ * `floating` over the body's block end, inset from the panel's inline and
4123
+ * block-end edges on a transparent background (a chat composer).
4124
+ */
4125
+ type DialogSurfaceFooterPresentation = 'docked' | 'floating';
4126
+ /**
4127
+ * Where the dialog header sits: `docked` (default) above the body, or
4128
+ * `floating` over the body's block-start edge on the translucent chrome
4129
+ * material, so content scrolls visibly beneath the title bar.
3792
4130
  */
3793
- type DialogSurfaceBodyLayout = 'flow' | 'fill';
4131
+ type DialogSurfaceHeaderPresentation = 'docked' | 'floating';
3794
4132
  /**
3795
4133
  * Application `data-*` identity on the DialogSurface root, such as
3796
4134
  * `data-key`; the surface's own configuration attributes stay protected.
@@ -3813,8 +4151,43 @@ interface DialogSurfaceProps {
3813
4151
  * height to fill. Takes precedence over `maxHeight`.
3814
4152
  */
3815
4153
  height?: DialogSurfaceHeight;
3816
- /** Body layout (default `flow`); `fill` lets one child own the body. */
4154
+ /**
4155
+ * Body layout (default `flow`); `fill` lets one child own the body and
4156
+ * `fill-last` stacks fixed rows above one filling last child.
4157
+ */
3817
4158
  bodyLayout?: DialogSurfaceBodyLayout;
4159
+ /**
4160
+ * Header placement (default `docked`); `floating` lays the dialog's header
4161
+ * (its title and close control) over the body's block-start edge on the
4162
+ * translucent chrome material (`--kui-chrome-material-raised`, opaque under
4163
+ * `prefers-reduced-transparency`, increased contrast, forced colors, or
4164
+ * without `backdrop-filter`). The `/register` entry measures the header;
4165
+ * the body reserves that height before its own inset, so its first content
4166
+ * rests below the title bar. A `fill`/`fill-last` child that is the body's
4167
+ * only child and opts into block-start `scrollClearance` (a `List` or
4168
+ * `Pane`) takes the clearance inside its own scroll area instead, published
4169
+ * as `--kui-scroll-clearance-block-start`, so its content scrolls visibly
4170
+ * beneath the header. Unmeasured (without the register), the header stays
4171
+ * docked. Keep header text in the normal text color: quiet text can fall
4172
+ * below AA over the content passing beneath it.
4173
+ */
4174
+ headerPresentation?: DialogSurfaceHeaderPresentation;
4175
+ /**
4176
+ * Footer placement (default `docked`); `floating` lays the footer over the
4177
+ * body's block end. The body reserves the footer's measured height so its
4178
+ * last content is never hidden beneath it. A `fill`/`fill-last` child that
4179
+ * opts into block-end `scrollClearance` (a `List` or `Pane`) takes that
4180
+ * clearance inside its own scroll area instead, published as
4181
+ * `--kui-scroll-clearance-block-end`, so its content scrolls visibly beneath
4182
+ * the transparent footer.
4183
+ */
4184
+ footerPresentation?: DialogSurfaceFooterPresentation;
4185
+ /**
4186
+ * A floating footer's clearance from the panel's inline and block-end edges
4187
+ * (default the 16px container inset). Choose a phone value such as
4188
+ * `remify(8)` from `deviceClass()`; the scaffold adds no breakpoint.
4189
+ */
4190
+ footerOffset?: CssLength;
3818
4191
  /**
3819
4192
  * Safe `data-*` identity on the root. Give sibling dialogs distinct
3820
4193
  * `data-key`s so a re-render morphs each surface into itself instead of
@@ -3827,7 +4200,7 @@ interface DialogSurfaceProps {
3827
4200
  slot?: string;
3828
4201
  }
3829
4202
  /** Configure recurring Web Awesome dialog geometry without consumer ::part() CSS. */
3830
- declare function DialogSurface({ children, size, presentation, preferredWidth, bodyInset, footerInset, viewportGutter, maxHeight, height, bodyLayout, rootAttributes, className, slot, }: DialogSurfaceProps): kerfjs.SafeHtml;
4203
+ declare function DialogSurface({ children, size, presentation, preferredWidth, bodyInset, footerInset, viewportGutter, maxHeight, height, bodyLayout, headerPresentation, footerPresentation, footerOffset, rootAttributes, className, slot, }: DialogSurfaceProps): kerfjs.SafeHtml;
3831
4204
  /** Where a PopoverDialogSurface appears: the top layer, or in flow. */
3832
4205
  type PopoverDialogSurfacePresentation = 'overlay' | 'embedded';
3833
4206
  /** Application `data-*` metadata on the surface root. */
@@ -3842,6 +4215,12 @@ type PopoverDialogSurfaceName = {
3842
4215
  type PopoverDialogSurfaceProps = PopoverDialogSurfaceName & {
3843
4216
  /** The root id: what an opening control's `popovertarget` names. */
3844
4217
  id?: string;
4218
+ /**
4219
+ * Id of the element whose text is the dialog's accessible description,
4220
+ * such as a title `ToolbarText`'s `descriptionId`; rendered as
4221
+ * `aria-describedby` on the `role="dialog"` root.
4222
+ */
4223
+ describedBy?: string;
3845
4224
  children: KerfUiContent;
3846
4225
  /**
3847
4226
  * `overlay` (default) is a native `popover="auto"` in the top layer:
@@ -3859,7 +4238,10 @@ type PopoverDialogSurfaceProps = PopoverDialogSurfaceName & {
3859
4238
  maxHeight?: DialogSurfaceMaxHeight;
3860
4239
  /** Edge clearance on each side of the viewport (default 16px). */
3861
4240
  viewportGutter?: CssLength;
3862
- /** Body layout (default `flow`); `fill` lets one child own the surface. */
4241
+ /**
4242
+ * Body layout (default `flow`); `fill` lets one child own the surface and
4243
+ * `fill-last` stacks fixed rows above one filling last child.
4244
+ */
3863
4245
  bodyLayout?: DialogSurfaceBodyLayout;
3864
4246
  rootAttributes?: PopoverDialogSurfaceDataAttributes;
3865
4247
  className?: string;
@@ -3873,7 +4255,7 @@ type PopoverDialogSurfaceProps = PopoverDialogSurfaceName & {
3873
4255
  * dismisses and leaves the page interactive. Use `DialogSurface` with
3874
4256
  * `wa-dialog` when the task must block the page.
3875
4257
  */
3876
- declare function PopoverDialogSurface({ id, children, label, labelledBy, presentation, size, preferredWidth, height, maxHeight, viewportGutter, bodyLayout, rootAttributes, className, slot, }: PopoverDialogSurfaceProps): kerfjs.SafeHtml;
4258
+ declare function PopoverDialogSurface({ id, children, label, labelledBy, describedBy, presentation, size, preferredWidth, height, maxHeight, viewportGutter, bodyLayout, rootAttributes, className, slot, }: PopoverDialogSurfaceProps): kerfjs.SafeHtml;
3877
4259
  type PopupSurfaceInset = 'standard' | 'compact' | 'list-zero';
3878
4260
  interface PopupSurfaceProps {
3879
4261
  children: KerfUiContent;
@@ -3885,7 +4267,7 @@ interface PopupSurfaceProps {
3885
4267
  /** Configure recurring Web Awesome dropdown-menu geometry without consumer ::part() CSS. */
3886
4268
  declare function PopupSurface({ children, inset, className, slot, }: PopupSurfaceProps): kerfjs.SafeHtml;
3887
4269
 
3888
- export { DialogSurface, type DialogSurfaceBodyLayout, type DialogSurfaceHeight, type DialogSurfaceMaxHeight, type DialogSurfacePresentation, type DialogSurfaceProps, type DialogSurfaceRootAttributes, type DialogSurfaceSize, PopoverDialogSurface, type PopoverDialogSurfaceDataAttributes, type PopoverDialogSurfacePresentation, type PopoverDialogSurfaceProps, PopupSurface, type PopupSurfaceInset, type PopupSurfaceProps, type SurfaceInset };
4270
+ export { DialogSurface, type DialogSurfaceBodyLayout, type DialogSurfaceFooterPresentation, type DialogSurfaceHeaderPresentation, type DialogSurfaceHeight, type DialogSurfaceMaxHeight, type DialogSurfacePresentation, type DialogSurfaceProps, type DialogSurfaceRootAttributes, type DialogSurfaceSize, PopoverDialogSurface, type PopoverDialogSurfaceDataAttributes, type PopoverDialogSurfacePresentation, type PopoverDialogSurfaceProps, PopupSurface, type PopupSurfaceInset, type PopupSurfaceProps, type SurfaceInset };
3889
4271
  ```
3890
4272
 
3891
4273
  ## `@kerfjs/ui/text`
@@ -4336,7 +4718,7 @@ export { CssLength, Spacer, type SpacerProps, UiSpaceName };
4336
4718
  ## `@kerfjs/ui/token-search-model`
4337
4719
 
4338
4720
  ```ts
4339
- export { d as TokenSearchModel, e as TokenSearchModelOptions, f as TokenSearchResolvedToken, g as TokenSearchRule, h as TokenSearchState, i as TokenSearchSuggestion, l as createTokenSearchModel } from './token-search-model-DTcTXWMS.js';
4721
+ export { d as TokenSearchModel, e as TokenSearchModelOptions, f as TokenSearchResolvedToken, g as TokenSearchRule, h as TokenSearchState, i as TokenSearchSuggestion, m as createTokenSearchModel } from './token-search-model-aYR0YAei.js';
4340
4722
  import 'kerfjs';
4341
4723
  import './semantic-content-BbzjvSu9.js';
4342
4724
  ```
@@ -4395,6 +4777,12 @@ import { PopoverOptions, OverlayContent, OverlayHandle } from 'kerfjs/overlay';
4395
4777
  interface AnchoredSurfaceOptions extends Pick<PopoverOptions, 'placement' | 'align' | 'gap' | 'dismiss' | 'initialFocus' | 'onDismiss' | 'outsideIgnore' | 'container'> {
4396
4778
  /** Accessible name for the non-modal dialog. */
4397
4779
  label: string;
4780
+ /**
4781
+ * Gutter in px kept between the surface and the viewport edges when it is
4782
+ * clamped horizontally and fitted vertically. Default `8`, the same gutter as
4783
+ * the surface's maximum size.
4784
+ */
4785
+ viewportMargin?: number;
4398
4786
  /**
4399
4787
  * Where to append the surface. Default: inside the anchor's open modal
4400
4788
  * dialog — a native `<dialog>`'s host slot, or a slot kerf creates in a
@@ -4403,20 +4791,42 @@ interface AnchoredSurfaceOptions extends Pick<PopoverOptions, 'placement' | 'ali
4403
4791
  * cannot resolve; an element inside an open modal closes the surface with it.
4404
4792
  */
4405
4793
  container?: Element;
4794
+ /**
4795
+ * Surface tone. `'default'` follows the anchor's color scheme. `'dark'` is
4796
+ * the loud, inverse tone of a `ToolbarControlGroup` / `ToolbarText`
4797
+ * `tone="dark"`, for a popup anchored to dark media chrome (a volume popup
4798
+ * over a video preview): dark beside a light page and light beside a dark
4799
+ * one, so the popup matches the control group that opened it. The surface
4800
+ * takes the opposite of the anchor's color scheme, so it and every Kerf UI
4801
+ * or Web Awesome component inside it resolve the same semantic
4802
+ * `light-dark()` tokens to the other side: no new colors, no child
4803
+ * overrides. While open it follows a live switch of that scheme (the OS
4804
+ * preference, or an app theme class or attribute on an ancestor). Default
4805
+ * `'default'`.
4806
+ */
4807
+ tone?: AnchoredSurfaceTone;
4406
4808
  }
4809
+ /** {@link AnchoredSurfaceOptions.tone}: follow the anchor's scheme, or invert it. */
4810
+ type AnchoredSurfaceTone = 'default' | 'dark';
4407
4811
  /** A viewport pointer location; `context` is the element under the pointer. */
4408
4812
  interface AnchoredSurfacePoint {
4409
4813
  x: number;
4410
4814
  y: number;
4411
4815
  /**
4412
4816
  * Pass the event target when opening from inside a modal dialog, native or
4413
- * Web Awesome (`wa-dialog`, `wa-drawer`).
4817
+ * Web Awesome (`wa-dialog`, `wa-drawer`). The dark tone also reads its
4818
+ * color scheme from `context`, so a region with its own `color-scheme` is
4819
+ * honored; without it the scheme is the modal scope's (or the page's).
4414
4820
  */
4415
4821
  context?: Element;
4416
4822
  }
4417
4823
  /**
4418
4824
  * Open app-owned content beside an element. The surface owns its Kerf UI chrome;
4419
4825
  * kerfjs/overlay owns positioning, top-layer/modal hosting, focus, and dismissal.
4826
+ * The surface stays `viewportMargin` inside the viewport edges and fits its
4827
+ * height to the room beside the anchor (the roomier side when neither holds it),
4828
+ * scrolling its content; `--kui-anchored-surface-available-height` exposes that
4829
+ * room to the content, updated as the page scrolls or resizes.
4420
4830
  * The caller owns content, action policy, and calling `close()` when an action
4421
4831
  * completes. `initialFocus` defaults to the first focusable descendant; set it
4422
4832
  * to `false` for read-only help that should leave focus on its trigger.
@@ -4429,7 +4839,7 @@ declare function openAnchoredSurface(anchor: Element, content: OverlayContent, o
4429
4839
  */
4430
4840
  declare function openAnchoredSurfaceAt(point: AnchoredSurfacePoint, content: OverlayContent, options: AnchoredSurfaceOptions): OverlayHandle;
4431
4841
 
4432
- export { type AnchoredSurfaceOptions, type AnchoredSurfacePoint, openAnchoredSurface, openAnchoredSurfaceAt };
4842
+ export { type AnchoredSurfaceOptions, type AnchoredSurfacePoint, type AnchoredSurfaceTone, openAnchoredSurface, openAnchoredSurfaceAt };
4433
4843
  ```
4434
4844
 
4435
4845
  ## `@kerfjs/ui/icon-button`
@@ -4674,7 +5084,7 @@ interface CornerStatusProps {
4674
5084
  }
4675
5085
  /**
4676
5086
  * A non-dismissible status surface pinned to a viewport corner — "Loading…",
4677
- * "Updating tickets… 3 of 12" — for app-level progress that has no better
5087
+ * "Updating Tickets… 3 of 12" — for app-level progress that has no better
4678
5088
  * home beside the affected work. The application owns its lifetime: render it
4679
5089
  * while the work runs and remove it when the work ends. It carries no role of
4680
5090
  * its own; the composed `StateBanner` is the polite live region. Use a toast