@kerfjs/ui 5.0.0-beta.50 → 5.0.0-beta.52

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 (212) hide show
  1. package/README.md +29 -5
  2. package/ai/compile-time-contracts-v1.json +5 -2
  3. package/ai/component-catalog-v2.d.ts +19 -1
  4. package/ai/component-catalog-v2.json +842 -127
  5. package/ai/component-catalog-v2.schema.json +33 -1
  6. package/ai/component-catalog.json +603 -126
  7. package/ai/component-catalog.schema.json +21 -1
  8. package/ai/public-api-signatures-v1.md +218 -31
  9. package/ai/skill.md +27 -24
  10. package/ai/webawesome-jsx-signatures-v1.md +1 -1
  11. package/analyzer/index.mjs +105 -35
  12. package/dist/app-tab.d.ts +10 -1
  13. package/dist/app-tab.js +1 -1
  14. package/dist/catalog-resources.d.ts +1 -1
  15. package/dist/catalog.d.ts +28 -5
  16. package/dist/catalog.js +66 -25
  17. package/dist/catalog.js.map +1 -1
  18. package/dist/{chunk-OL4TC3U2.js → chunk-2CE22Q2K.js} +9 -2
  19. package/dist/chunk-2CE22Q2K.js.map +1 -0
  20. package/dist/{chunk-SIU2AC5W.js → chunk-2S7OWAEV.js} +3 -3
  21. package/dist/{chunk-SIU2AC5W.js.map → chunk-2S7OWAEV.js.map} +1 -1
  22. package/dist/{chunk-2YOUUEWR.js → chunk-3S7OUHUN.js} +4 -4
  23. package/dist/{chunk-2YOUUEWR.js.map → chunk-3S7OUHUN.js.map} +1 -1
  24. package/dist/{chunk-2WMSE4MK.js → chunk-4XE2CDYB.js} +2 -2
  25. package/dist/{chunk-2WMSE4MK.js.map → chunk-4XE2CDYB.js.map} +1 -1
  26. package/dist/{chunk-V6RZWDII.js → chunk-7GUQYHKA.js} +19 -2
  27. package/dist/chunk-7GUQYHKA.js.map +1 -0
  28. package/dist/{chunk-ZNZ2JDBW.js → chunk-7IUSV4XG.js} +1 -1
  29. package/dist/chunk-7IUSV4XG.js.map +1 -0
  30. package/dist/{chunk-UMGY5JSP.js → chunk-7XJO4D6A.js} +22 -2
  31. package/dist/chunk-7XJO4D6A.js.map +1 -0
  32. package/dist/{chunk-KKNK3JUT.js → chunk-ABAXNUXU.js} +5 -5
  33. package/dist/chunk-ABAXNUXU.js.map +1 -0
  34. package/dist/{chunk-AQSKJ6U6.js → chunk-DNCOFEUL.js} +21 -2
  35. package/dist/chunk-DNCOFEUL.js.map +1 -0
  36. package/dist/chunk-EKYZCRCX.js +256 -0
  37. package/dist/chunk-EKYZCRCX.js.map +1 -0
  38. package/dist/{chunk-COUPLRZG.js → chunk-IR53BQUJ.js} +16 -12
  39. package/dist/chunk-IR53BQUJ.js.map +1 -0
  40. package/dist/{chunk-3V75EQIP.js → chunk-JGFZ42ZF.js} +3 -3
  41. package/dist/{chunk-3V75EQIP.js.map → chunk-JGFZ42ZF.js.map} +1 -1
  42. package/dist/{chunk-54HM36IQ.js → chunk-KAQUUTZR.js} +4 -2
  43. package/dist/chunk-KAQUUTZR.js.map +1 -0
  44. package/dist/{chunk-ZSYLBVWG.js → chunk-LIOXPQ7N.js} +4 -4
  45. package/dist/chunk-LIOXPQ7N.js.map +1 -0
  46. package/dist/{chunk-S6ZTTTV7.js → chunk-M6GLI6A6.js} +3 -3
  47. package/dist/{chunk-S6ZTTTV7.js.map → chunk-M6GLI6A6.js.map} +1 -1
  48. package/dist/{chunk-OQI7RCRP.js → chunk-MTM43SJO.js} +7 -1
  49. package/dist/chunk-MTM43SJO.js.map +1 -0
  50. package/dist/{chunk-5CE64WGC.js → chunk-OSCL5TKR.js} +3 -3
  51. package/dist/{chunk-5CE64WGC.js.map → chunk-OSCL5TKR.js.map} +1 -1
  52. package/dist/{chunk-DARTMI5Z.js → chunk-SV22UIW4.js} +2 -2
  53. package/dist/{chunk-DARTMI5Z.js.map → chunk-SV22UIW4.js.map} +1 -1
  54. package/dist/{chunk-ELRMBQEC.js → chunk-T7C2VZUB.js} +17 -2
  55. package/dist/chunk-T7C2VZUB.js.map +1 -0
  56. package/dist/{chunk-DJKWFYAA.js → chunk-YZV2PTY4.js} +3 -3
  57. package/dist/{chunk-DJKWFYAA.js.map → chunk-YZV2PTY4.js.map} +1 -1
  58. package/dist/collapsible-panel.d.ts +1 -1
  59. package/dist/collapsible-panel.js.map +1 -1
  60. package/dist/css-values.d.ts +41 -3
  61. package/dist/css-values.js +1 -1
  62. package/dist/grid.d.ts +15 -1
  63. package/dist/grid.js +2 -1
  64. package/dist/index.d.ts +1 -1
  65. package/dist/index.js +19 -19
  66. package/dist/list-action-row.js +1 -1
  67. package/dist/list-header.js +1 -1
  68. package/dist/list-item.js +1 -1
  69. package/dist/list.d.ts +21 -2
  70. package/dist/list.js +2 -1
  71. package/dist/nav-stack.js +1 -1
  72. package/dist/pane.d.ts +17 -2
  73. package/dist/pane.js +1 -1
  74. package/dist/row.d.ts +19 -1
  75. package/dist/row.js +2 -1
  76. package/dist/segmented-control.js +1 -1
  77. package/dist/select.d.ts +13 -3
  78. package/dist/select.js +1 -1
  79. package/dist/skeleton.d.ts +5 -1
  80. package/dist/skeleton.js +1 -1
  81. package/dist/spacer.js +1 -1
  82. package/dist/split-view.js +1 -1
  83. package/dist/state-banner.js +1 -1
  84. package/dist/styles/app-tab.css +9 -0
  85. package/dist/styles/catalog/components/catalog-example-stack.css +4 -1
  86. package/dist/styles/catalog/components/catalog-example.css +145 -0
  87. package/dist/styles/collapsible-panel.css +132 -4
  88. package/dist/styles/document.css +23 -0
  89. package/dist/styles/foundation.css +21 -7
  90. package/dist/styles/grid.css +10 -0
  91. package/dist/styles/list-header.css +45 -0
  92. package/dist/styles/list-inset-control.css +8 -1
  93. package/dist/styles/list-item.css +6 -0
  94. package/dist/styles/list.css +11 -0
  95. package/dist/styles/nav-stack.css +89 -2
  96. package/dist/styles/pane.css +86 -1
  97. package/dist/styles/resizable-region.css +93 -5
  98. package/dist/styles/row.css +10 -0
  99. package/dist/styles/select.css +39 -4
  100. package/dist/styles/skeleton.css +4 -1
  101. package/dist/styles/split-view.css +107 -1
  102. package/dist/styles/tab-scaffold.css +64 -1
  103. package/dist/styles/text.css +6 -0
  104. package/dist/styles/toolbar-control-group.css +90 -11
  105. package/dist/styles/toolbar-text.css +4 -1
  106. package/dist/styles/toolbar.css +130 -38
  107. package/dist/styles/webawesome.css +48 -2
  108. package/dist/styles/workbench.css +136 -4
  109. package/dist/text.d.ts +4 -3
  110. package/dist/text.js +1 -1
  111. package/dist/toolbar-text.js +1 -1
  112. package/dist/toolbar.d.ts +24 -3
  113. package/dist/toolbar.js +1 -1
  114. package/dist/{types-CzgSrFXP.d.ts → types-CEsieBZi.d.ts} +6 -1
  115. package/dist/value-table.js +1 -1
  116. package/dist/wire-resizable-regions.js +1 -1
  117. package/dist/wire-sidebar.d.ts +18 -3
  118. package/dist/wire-sidebar.js +96 -15
  119. package/dist/wire-sidebar.js.map +1 -1
  120. package/docs/accessibility.md +49 -9
  121. package/docs/app-layouts.md +73 -0
  122. package/docs/catalog.md +23 -2
  123. package/docs/collapsible-panel.md +83 -9
  124. package/docs/component-contract.md +36 -12
  125. package/docs/component-integration.md +9 -4
  126. package/docs/component-selection.md +25 -6
  127. package/docs/design/templates/list/stack-dark.svg +1 -1
  128. package/docs/design/templates/list/stack.svg +1 -1
  129. package/docs/design/templates/list-dark.svg +1 -1
  130. package/docs/design/templates/list-header/action-dark.svg +1 -1
  131. package/docs/design/templates/list-header/action.svg +1 -1
  132. package/docs/design/templates/list-header/count-dark.svg +1 -1
  133. package/docs/design/templates/list-header/count.svg +1 -1
  134. package/docs/design/templates/list-header/inline-action-dark.svg +1 -1
  135. package/docs/design/templates/list-header/inline-action.svg +1 -1
  136. package/docs/design/templates/list-header/toggle-expanded-dark.svg +1 -1
  137. package/docs/design/templates/list-header/toggle-expanded.svg +1 -1
  138. package/docs/design/templates/list-header-dark.svg +1 -1
  139. package/docs/design/templates/list-header.svg +1 -1
  140. package/docs/design/templates/list.svg +1 -1
  141. package/docs/design/templates/state-banner/info-badge-dark.svg +1 -1
  142. package/docs/design/templates/state-banner/info-badge.svg +1 -1
  143. package/docs/design/templates/state-banner-dark.svg +1 -1
  144. package/docs/design/templates/state-banner.svg +1 -1
  145. package/docs/design/templates/toolbar/title-and-actions-dark.svg +1 -1
  146. package/docs/design/templates/toolbar/title-and-actions.svg +1 -1
  147. package/docs/design/templates/toolbar-control-group/with-text-dark.svg +1 -1
  148. package/docs/design/templates/toolbar-control-group/with-text.svg +1 -1
  149. package/docs/design/templates/toolbar-control-group-dark.svg +1 -1
  150. package/docs/design/templates/toolbar-control-group.svg +1 -1
  151. package/docs/design/templates/toolbar-dark.svg +1 -1
  152. package/docs/design/templates/toolbar-text/default-dark.svg +1 -1
  153. package/docs/design/templates/toolbar-text/default.svg +1 -1
  154. package/docs/design/templates/toolbar-text/large-dark.svg +1 -1
  155. package/docs/design/templates/toolbar-text/large.svg +1 -1
  156. package/docs/design/templates/toolbar-text/small-dark.svg +1 -1
  157. package/docs/design/templates/toolbar-text/small.svg +1 -1
  158. package/docs/design/templates/toolbar-text-dark.svg +1 -1
  159. package/docs/design/templates/toolbar-text.svg +1 -1
  160. package/docs/design/templates/toolbar.svg +1 -1
  161. package/docs/document-baseline.md +31 -0
  162. package/docs/layout.md +86 -21
  163. package/docs/nav-stack.md +8 -0
  164. package/docs/recipes.md +81 -44
  165. package/docs/split-view.md +8 -0
  166. package/docs/tab-scaffold.md +4 -2
  167. package/docs/type-contracts.md +21 -17
  168. package/docs/ui-analyzer.md +19 -0
  169. package/docs/ui-evaluator.md +17 -0
  170. package/docs/ux-demo.md +5 -5
  171. package/docs/webawesome-theme.md +20 -2
  172. package/docs/workbench.md +20 -1
  173. package/evaluator/index.mjs +73 -8
  174. package/llms.txt +32 -14
  175. package/package.json +4 -2
  176. package/ux-demo/recipes/app-shell.tsx +209 -178
  177. package/ux-demo/recipes/collapsible-sidebar.tsx +189 -159
  178. package/ux-demo/recipes/compact-toolbar.tsx +48 -35
  179. package/ux-demo/recipes/composer-form.tsx +87 -79
  180. package/ux-demo/recipes/list-detail-dialog.tsx +124 -142
  181. package/ux-demo/recipes/list-workspace-states.tsx +83 -83
  182. package/ux-demo/recipes/loaders.ts +5 -2
  183. package/ux-demo/recipes/loading-inspector.tsx +157 -160
  184. package/ux-demo/recipes/navigation-sidebar.tsx +111 -109
  185. package/ux-demo/recipes/navigation-stack.tsx +50 -49
  186. package/ux-demo/recipes/types.ts +14 -0
  187. package/ux-demo/recipes/workspace-header.tsx +73 -56
  188. package/dist/chunk-54HM36IQ.js.map +0 -1
  189. package/dist/chunk-AQSKJ6U6.js.map +0 -1
  190. package/dist/chunk-COUPLRZG.js.map +0 -1
  191. package/dist/chunk-ELRMBQEC.js.map +0 -1
  192. package/dist/chunk-J3EE6XWD.js +0 -115
  193. package/dist/chunk-J3EE6XWD.js.map +0 -1
  194. package/dist/chunk-KKNK3JUT.js.map +0 -1
  195. package/dist/chunk-OL4TC3U2.js.map +0 -1
  196. package/dist/chunk-OQI7RCRP.js.map +0 -1
  197. package/dist/chunk-UMGY5JSP.js.map +0 -1
  198. package/dist/chunk-V6RZWDII.js.map +0 -1
  199. package/dist/chunk-ZNZ2JDBW.js.map +0 -1
  200. package/dist/chunk-ZSYLBVWG.js.map +0 -1
  201. package/ux-demo/recipes/app-shell.css +0 -87
  202. package/ux-demo/recipes/collapsible-sidebar.css +0 -83
  203. package/ux-demo/recipes/compact-toolbar.css +0 -35
  204. package/ux-demo/recipes/composer-form.css +0 -19
  205. package/ux-demo/recipes/list-detail-dialog.css +0 -42
  206. package/ux-demo/recipes/list-workspace-states.css +0 -30
  207. package/ux-demo/recipes/loading-inspector.css +0 -7
  208. package/ux-demo/recipes/navigation-sidebar.css +0 -12
  209. package/ux-demo/recipes/navigation-stack.css +0 -12
  210. package/ux-demo/recipes/recipe-root.css +0 -67
  211. package/ux-demo/recipes/recipe-root.tsx +0 -87
  212. package/ux-demo/recipes/workspace-header.css +0 -7
@@ -92,7 +92,27 @@
92
92
  "wiring": {
93
93
  "type": "object",
94
94
  "required": ["export", "import", "required"],
95
- "properties": { "export": { "type": "string" }, "import": { "type": "string" }, "required": { "type": "boolean" }, "reason": { "type": "string" } },
95
+ "properties": {
96
+ "export": { "type": "string" },
97
+ "import": { "type": "string" },
98
+ "required": { "type": "boolean" },
99
+ "reason": { "type": "string" },
100
+ "stateAttributes": {
101
+ "description": "Wiring-owned state attributes: data-* attributes this helper writes at runtime on the entry's elements. The application must not render, remove, or treat them as its own state.",
102
+ "type": "array",
103
+ "items": { "$ref": "#/$defs/stateAttribute" }
104
+ }
105
+ },
106
+ "additionalProperties": false
107
+ },
108
+ "stateAttribute": {
109
+ "type": "object",
110
+ "required": ["name", "on", "meaning"],
111
+ "properties": {
112
+ "name": { "type": "string", "minLength": 1, "pattern": "^data-[a-z0-9]+(-[a-z0-9]+)*$" },
113
+ "on": { "type": "string", "minLength": 1, "description": "The element that carries it: a public class, or the element passed to the helper." },
114
+ "meaning": { "type": "string", "minLength": 1, "description": "What its presence or value means." }
115
+ },
96
116
  "additionalProperties": false
97
117
  },
98
118
  "delivery": {
@@ -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.50` and `kerfjs@5.0.0-beta.50`. 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.52` and `kerfjs@5.0.0-beta.52`. 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
 
@@ -10,6 +10,7 @@ declare const cssLengthBrand: unique symbol;
10
10
  declare const cssLengthExpressionBrand: unique symbol;
11
11
  declare const cssFlexBrand: unique symbol;
12
12
  declare const cssColorBrand: unique symbol;
13
+ declare const cssForegroundColorBrand: unique symbol;
13
14
  /**
14
15
  * A complete typed CSS value minted by a property-specific Kerf UI builder.
15
16
  *
@@ -42,6 +43,18 @@ type CssFlex = CssValue & {
42
43
  type CssColor = CssValue & {
43
44
  readonly [cssColorBrand]: 'CssColor';
44
45
  };
46
+ /**
47
+ * A complete CSS color meant to paint a foreground: text or an icon drawn over
48
+ * a surface. Mint it with {@link uiColor} and a foreground token name
49
+ * ({@link UiForegroundColorName}) or with {@link foregroundColorVar}. It is a
50
+ * {@link CssColor}, but a plain `CssColor` is not a foreground color: fill,
51
+ * border, and surface tokens (including the `success` / `warning` / `danger` /
52
+ * `pop` fill aliases) are pale backgrounds that leave a foreground nearly
53
+ * invisible.
54
+ */
55
+ type CssForegroundColor = CssColor & {
56
+ readonly [cssForegroundColorBrand]: 'CssForegroundColor';
57
+ };
45
58
  type CssFlexKeyword = 'none' | 'auto' | 'initial';
46
59
  type CssFlexBasis = CssLength | 'auto' | 'content' | 'min-content' | 'max-content' | 'fit-content';
47
60
  type CssSizeKeyword = 'auto' | 'min-content' | 'max-content' | 'fit-content';
@@ -50,12 +63,21 @@ type CssSize = CssLength | CssSizeKeyword;
50
63
  declare const uiColorNames: readonly ["accent", "accent-text", "border", "border-quiet", "brand-border-loud", "brand-border-normal", "brand-border-quiet", "brand-fill-loud", "brand-fill-normal", "brand-fill-quiet", "brand-on-fill", "brand-on-loud", "brand-on-normal", "brand-on-quiet", "danger", "danger-border-loud", "danger-border-normal", "danger-border-quiet", "danger-fill-loud", "danger-fill-normal", "danger-fill-quiet", "danger-on-loud", "danger-on-normal", "danger-on-quiet", "danger-text", "neutral-border-loud", "neutral-border-normal", "neutral-border-quiet", "neutral-fill-loud", "neutral-fill-normal", "neutral-fill-quiet", "neutral-on-loud", "neutral-on-normal", "neutral-on-quiet", "pop", "pop-border-loud", "pop-border-normal", "pop-border-quiet", "pop-fill-loud", "pop-fill-normal", "pop-fill-quiet", "pop-on-fill", "pop-on-loud", "pop-on-normal", "pop-on-quiet", "pop-text", "success", "success-border-loud", "success-border-normal", "success-border-quiet", "success-fill-loud", "success-fill-normal", "success-fill-quiet", "success-on-fill", "success-on-loud", "success-on-normal", "success-on-quiet", "success-text", "surface", "surface-lowered", "surface-raised", "text", "text-link", "text-quiet", "warning", "warning-border-loud", "warning-border-normal", "warning-border-quiet", "warning-fill-loud", "warning-fill-normal", "warning-fill-quiet", "warning-on-fill", "warning-on-loud", "warning-on-normal", "warning-on-quiet", "warning-text"];
51
64
  /** Names of the public `--kui-color-*` semantic tokens. */
52
65
  type UiColorName = (typeof uiColorNames)[number];
66
+ /**
67
+ * The semantic tokens that paint a foreground: the `*-on-*` roles, the text
68
+ * roles, and their `*-text` compatibility aliases. The bare `success`,
69
+ * `warning`, `danger`, `pop`, and `accent` aliases are quiet fills, not
70
+ * foregrounds.
71
+ */
72
+ type UiForegroundColorName = Extract<UiColorName, `${string}-on-${string}` | `${string}-text` | 'text' | 'text-quiet' | 'text-link'>;
53
73
  /** Kerf UI's complete spacing-token vocabulary. `s` and `xl` are exceptions. */
54
74
  type UiSpaceName = 'none' | '2xs' | 'xs' | 's' | 'm' | 'l' | 'xl';
55
75
  /** Create a complete pixel length. */
56
76
  declare function px(value: number): CssLength;
57
77
  /** Create a complete root-font-relative length. */
58
78
  declare function rem(value: number): CssLength;
79
+ /** Converts a pixel value into rem units by dividing by 16. */
80
+ declare function remify(value: number): CssLength;
59
81
  /** Create a complete current-font-relative length. */
60
82
  declare function em(value: number): CssLength;
61
83
  /** Create a complete percentage length. */
@@ -74,12 +96,28 @@ declare function plus(first: CssLength, second: CssLength, ...rest: readonly Css
74
96
  declare function calc(expression: CssLengthExpression): CssLength;
75
97
  /** Build a complete, structured CSS flex shorthand. */
76
98
  declare function flex(grow: number, shrink?: number, basis?: CssFlexBasis): CssFlex;
77
- /** Resolve a public Kerf UI semantic color token. */
78
- declare function uiColor(name: UiColorName): CssColor;
99
+ /**
100
+ * The brand {@link uiColor} returns for a token name: a
101
+ * {@link CssForegroundColor} for a foreground token, otherwise a plain
102
+ * {@link CssColor}.
103
+ */
104
+ type UiColor<Name extends UiColorName> = Name extends UiForegroundColorName ? CssForegroundColor : CssColor;
105
+ /**
106
+ * Resolve a public Kerf UI semantic color token. A foreground token name
107
+ * (`success-on-quiet`, `text-quiet`, …) returns a {@link CssForegroundColor};
108
+ * any other token returns a plain {@link CssColor}.
109
+ */
110
+ declare function uiColor<Name extends UiColorName>(name: Name): UiColor<Name>;
79
111
  /** Reference an application-owned custom property whose contract is a color. */
80
112
  declare function colorVar(name: `--${string}`, fallback?: CssColor): CssColor;
113
+ /**
114
+ * Reference an application-owned custom property whose contract is a
115
+ * foreground color (text or an icon over a surface). Use it where a prop
116
+ * accepts only {@link CssForegroundColor}, such as `SelectChoice.color`.
117
+ */
118
+ declare function foregroundColorVar(name: `--${string}`, fallback?: CssForegroundColor): CssForegroundColor;
81
119
 
82
- export { type CssColor, type CssFlex, type CssFlexBasis, type CssFlexKeyword, type CssLength, type CssLengthExpression, type CssSize, type CssSizeKeyword, type CssValue, type UiColorName, type UiSpaceName, calc, colorVar, em, flex, lengthVar, pct, plus, px, rem, space, uiColor };
120
+ 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 UiSpaceName, calc, colorVar, em, flex, foregroundColorVar, lengthVar, pct, plus, px, rem, remify, space, uiColor };
83
121
  ```
84
122
 
85
123
  ## `@kerfjs/ui/disclosure-arrow`
@@ -108,6 +146,7 @@ export { DisclosureArrow, type DisclosureArrowProps, type DisclosureDirection };
108
146
  ```ts
109
147
  import * as kerfjs from 'kerfjs';
110
148
  import { D as DividerSides } from './divider-sides-BzB6rphT.js';
149
+ import { PaneSeparatorSide } from './pane.js';
111
150
  import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
112
151
 
113
152
  interface ToolbarProps {
@@ -119,15 +158,35 @@ interface ToolbarProps {
119
158
  dividerSides?: DividerSides;
120
159
  /** Horizontal treatment of the center zone. Defaults to centered content. */
121
160
  centerAlign?: 'center' | 'stretch';
122
- /** Component-owned responsive layout; applications choose the policy rather than restyling toolbar internals. */
123
- responsive?: 'none' | 'stack' | 'center-priority';
161
+ /**
162
+ * Component-owned responsive layout; applications choose the policy rather
163
+ * than restyling toolbar internals. Under every policy the trailing zone
164
+ * wraps its groups instead of clipping an action.
165
+ * - `none` keeps one row; the leading identity truncates first.
166
+ * - `stack` stacks the zones at `responsiveAt`, wrapping stacked control
167
+ * groups onto further rows.
168
+ * - `wrap` keeps one row while every zone fits at its natural width, and
169
+ * otherwise moves the trailing zone below a whole leading identity.
170
+ * - `center-priority` gives an expanded center control the full row.
171
+ */
172
+ responsive?: 'none' | 'stack' | 'wrap' | 'center-priority';
124
173
  /** Container width at which `responsive="stack"` activates. */
125
174
  responsiveAt?: 'compact' | 'narrow';
175
+ /**
176
+ * Screen edges this toolbar claims for device safe-area compensation, for an
177
+ * app bar or bottom bar that sits directly at a screen edge rather than in a
178
+ * Pane header or footer. Each listed side pads by the inset its surrounding
179
+ * layout reports through `--kui-edge-inset-*`, or the full device inset when
180
+ * nothing routes that edge, while the toolbar's box and dividers paint
181
+ * through. Omitted, the toolbar pads only the inline edges an owner such as
182
+ * a Pane header hands it, and never a block edge.
183
+ */
184
+ safeAreaEdges?: readonly PaneSeparatorSide[];
126
185
  className?: string;
127
186
  /** Native named-slot assignment when composed inside a web component. */
128
187
  slot?: string;
129
188
  }
130
- declare function Toolbar({ leading, center, trailing, label, dividerSides, centerAlign, responsive, responsiveAt, className, slot, }: ToolbarProps): kerfjs.SafeHtml;
189
+ declare function Toolbar({ leading, center, trailing, label, dividerSides, centerAlign, responsive, responsiveAt, safeAreaEdges, className, slot, }: ToolbarProps): kerfjs.SafeHtml;
131
190
 
132
191
  export { DividerSides, Toolbar, type ToolbarProps };
133
192
  ```
@@ -389,12 +448,29 @@ import { H as HorizontalAlignment, L as ListVerticalAlignment } from './flex-ali
389
448
  export { V as VerticalAlignment } from './flex-alignment-4ms8ZbV8.js';
390
449
  import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
391
450
 
451
+ type ListRootAttributes = Readonly<Record<`data-${string}`, string | undefined> & {
452
+ 'data-component'?: never;
453
+ 'data-gap'?: never;
454
+ 'data-flex'?: never;
455
+ 'data-fill'?: never;
456
+ 'data-h-align'?: never;
457
+ 'data-v-align'?: never;
458
+ 'data-scrollable'?: never;
459
+ 'data-text-insets'?: never;
460
+ 'data-control-insets'?: never;
461
+ }>;
392
462
  interface ListProps {
393
463
  children?: KerfUiContent;
394
464
  /** Use the standard item gap, a named UI spacing token, or a typed CSS length. Defaults to no gap. */
395
465
  gap?: boolean | UiSpaceName | CssLength;
396
466
  /** Allow this list to grow/shrink, use a keyword, or supply a typed CSS flex shorthand. */
397
467
  flex?: boolean | CssFlexKeyword | CssFlex;
468
+ /**
469
+ * Fill the height of a parent with a definite height, such as an app root or
470
+ * a fixed-height frame, when this list is that parent's layout root. Inside a
471
+ * flex layout use `flex` instead. Defaults to false.
472
+ */
473
+ fill?: boolean;
398
474
  /** Horizontal alignment. Defaults to full to preserve stretch-aligned list children. */
399
475
  hAlign?: HorizontalAlignment;
400
476
  /** Vertical distribution. Defaults to top. */
@@ -408,11 +484,13 @@ interface ListProps {
408
484
  /** Physical sides that receive the standard 8px control inset. Text insets win on overlap. */
409
485
  controlInsets?: Sides;
410
486
  className?: string;
487
+ /** Safe `data-*` metadata; List-owned structural attributes remain protected. */
488
+ rootAttributes?: ListRootAttributes;
411
489
  /** Native named-slot assignment when composed inside a web component. */
412
490
  slot?: string;
413
491
  }
414
- /** A stretch-aligned vertical stack with optional gap, flex, scroll, and dividers. */
415
- declare function List({ children, gap, flex, hAlign, vAlign, scrollable, dividerSides, textInsets, controlInsets, className, slot, }: ListProps): kerfjs.SafeHtml;
492
+ /** A stretch-aligned vertical stack with optional gap, flex, fill, scroll, and dividers. */
493
+ declare function List({ children, gap, flex, fill, hAlign, vAlign, scrollable, dividerSides, textInsets, controlInsets, className, rootAttributes, slot, }: ListProps): kerfjs.SafeHtml;
416
494
 
417
495
  export { CssFlex, CssFlexKeyword, CssLength, DividerSides, HorizontalAlignment, List, type ListProps, ListVerticalAlignment, Sides, UiSpaceName };
418
496
  ```
@@ -668,11 +746,20 @@ interface AppTabProps {
668
746
  className?: string;
669
747
  /** Render as an unanimated loading skeleton, disabling select/close and dragging. */
670
748
  placeholder?: boolean;
749
+ /**
750
+ * Dormant but named: the tab is known and still opening. Keeps `name`
751
+ * visible in the quiet text color and as the tab's accessible name, shows
752
+ * `trailing` (for example a `LoadingSpinner`), and disables select, close,
753
+ * and dragging with `aria-busy`, like `placeholder`. Same pill geometry as
754
+ * the live tab, so swapping it in place does not shift the bar.
755
+ * `placeholder` wins when both are set.
756
+ */
757
+ pending?: boolean;
671
758
  rootAttributes?: AppTabRootAttributes;
672
759
  /** Native named-slot assignment when composed inside a web component. */
673
760
  slot?: string;
674
761
  }
675
- declare function AppTab({ id, name, selected, closable, draggable, leading, trailing, presentation, size, labelMaxWidth, closeIcon, selectAction, closeAction, className, placeholder, rootAttributes, slot, }: AppTabProps): SafeHtml;
762
+ declare function AppTab({ id, name, selected, closable, draggable, leading, trailing, presentation, size, labelMaxWidth, closeIcon, selectAction, closeAction, className, placeholder, pending, rootAttributes, slot, }: AppTabProps): SafeHtml;
676
763
 
677
764
  export { AppTab, type AppTabPresentation, type AppTabProps, type AppTabSize };
678
765
  ```
@@ -887,7 +974,10 @@ export { SplitView, type SplitViewProps, type SplitViewResizable };
887
974
  import * as kerfjs from 'kerfjs';
888
975
  import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
889
976
 
890
- /** Logical sides that can show a {@link Pane} separator. */
977
+ /**
978
+ * Logical pane sides: where a {@link Pane} can show a separator and where it can
979
+ * compensate for a device safe-area inset.
980
+ */
891
981
  type PaneSeparatorSide = 'block-start' | 'block-end' | 'inline-start' | 'inline-end';
892
982
  /** Semantic root elements supported by {@link Pane}. */
893
983
  type PaneElement = 'article' | 'aside' | 'div' | 'main' | 'section';
@@ -899,6 +989,10 @@ type PaneRootAttributes = Readonly<Record<`data-${string}`, string | undefined>
899
989
  'data-separator-block-end'?: never;
900
990
  'data-separator-inline-start'?: never;
901
991
  'data-separator-inline-end'?: never;
992
+ 'data-safe-area-block-start'?: never;
993
+ 'data-safe-area-block-end'?: never;
994
+ 'data-safe-area-inline-start'?: never;
995
+ 'data-safe-area-inline-end'?: never;
902
996
  }>;
903
997
  interface PaneProps {
904
998
  /** Optional fixed chrome above the scrolling content, arranged vertically. */
@@ -913,6 +1007,14 @@ interface PaneProps {
913
1007
  contentElement?: PaneContentElement;
914
1008
  /** Independent logical-edge separator lines. Defaults to none. */
915
1009
  separators?: readonly PaneSeparatorSide[];
1010
+ /**
1011
+ * Sides on which the pane may compensate for a device safe-area inset.
1012
+ * Defaults to every side: the pane pads its slots for each side that still
1013
+ * reaches an unsafe screen edge, as its surrounding layout reports, while its
1014
+ * background and separators paint through. List only the sides an app-owned
1015
+ * layout places at a screen edge, or pass `[]` to opt out.
1016
+ */
1017
+ safeAreaEdges?: readonly PaneSeparatorSide[];
916
1018
  id?: string;
917
1019
  /** Accessible name for a landmark root such as `aside` or `main`. */
918
1020
  label?: string;
@@ -933,7 +1035,7 @@ interface PaneProps {
933
1035
  * each logical edge, so the same component works as a sidebar, main area,
934
1036
  * inspector, or dialog column.
935
1037
  */
936
- declare function Pane({ header, children, footer, element, contentElement, separators, id, label, contentLabel, className, headerClassName, contentClassName, footerClassName, rootAttributes, slot, }: PaneProps): kerfjs.SafeHtml;
1038
+ declare function Pane({ header, children, footer, element, contentElement, separators, safeAreaEdges, id, label, contentLabel, className, headerClassName, contentClassName, footerClassName, rootAttributes, slot, }: PaneProps): kerfjs.SafeHtml;
937
1039
 
938
1040
  export { Pane, type PaneContentElement, type PaneElement, type PaneProps, type PaneSeparatorSide };
939
1041
  ```
@@ -1066,7 +1168,7 @@ interface CollapsiblePanelProps {
1066
1168
  * underneath the transform transition. The app owns the `collapsed` signal;
1067
1169
  * pair it with `wireSidebar` for the toggle, focus, compact-overlay, keyboard,
1068
1170
  * and persistence semantics, and with `CollapsiblePanelToggle` for the standard
1069
- * affordance. See `docs/24-collapsible-panel.md`.
1171
+ * affordance. See `ui/docs/collapsible-panel.md` and `docs/23-app-layouts.md`.
1070
1172
  */
1071
1173
  declare function CollapsiblePanel({ id, side, collapsed, size, label, children, separator, collapseMotion, contentOverflow, presentation, restoreControl, restorePosition, className, }: CollapsiblePanelProps): SafeHtml;
1072
1174
 
@@ -1092,9 +1194,18 @@ interface WireSidebarPanel {
1092
1194
  collapsed: Signal<boolean>;
1093
1195
  /** `data-action` value the panel's toggle button(s) carry. */
1094
1196
  toggleAction: string;
1095
- /** When set, the collapsed state is loaded from and saved to `storage` under
1096
- * this key (a persistence hook), so the panel remembers its state. */
1197
+ /** When set, the panel's inline collapsed state is loaded from and saved to
1198
+ * `storage` under this key (a persistence hook), so the panel remembers the
1199
+ * user's inline choice. A compact overlay's open/closed state is transient
1200
+ * and is never persisted. */
1097
1201
  storageKey?: string;
1202
+ /** The panel's inline (non-compact) collapsed state when `storage` holds no
1203
+ * choice for it; wire-up seeds the signal with it. Defaults to the signal's
1204
+ * own value. Set it when the app seeds the signal from the device class
1205
+ * (`signal(device.value.compact)`) so a compact first render already starts
1206
+ * collapsed while a later crossing to a wide class still restores this
1207
+ * inline default. */
1208
+ inlineCollapsed?: boolean;
1098
1209
  }
1099
1210
  interface WireSidebarOptions {
1100
1211
  panels: readonly WireSidebarPanel[];
@@ -1104,6 +1215,12 @@ interface WireSidebarOptions {
1104
1215
  * dismissable backdrop, Escape and backdrop-click collapse it, and focus is
1105
1216
  * trapped within the open panel (the ARIA dialog pattern). Without it the panel
1106
1217
  * is always inline.
1218
+ *
1219
+ * An overlay is transient and user-initiated: whenever the compact overlay
1220
+ * presentation begins (wire-up on a compact device, or a crossing from a wide
1221
+ * class), every panel starts collapsed so nothing blocks the page until the
1222
+ * user opens it. The inline state is remembered and restored when the device
1223
+ * crosses back to a wide class (and on disposal).
1107
1224
  */
1108
1225
  deviceClass?: ReadonlySignal<DeviceClass>;
1109
1226
  /** Compact devices either overlay the panels (default) or hide them in favor
@@ -1119,7 +1236,7 @@ interface WireSidebarOptions {
1119
1236
  * delegation with focus restore, focus-into on open, an optional compact overlay
1120
1237
  * (backdrop + Escape + focus trap) driven by {@link deviceClass}, and an optional
1121
1238
  * persistence hook. The app owns each `collapsed` signal and the layout; this wire
1122
- * owns the interaction. Returns a disposer. See `docs/24-collapsible-panel.md`.
1239
+ * owns the interaction. Returns a disposer. See `ui/docs/collapsible-panel.md` and `docs/23-app-layouts.md`.
1123
1240
  */
1124
1241
  declare function wireSidebar(root: HTMLElement, { panels, deviceClass, compactPresentation, exclusiveCompact, storage, }: WireSidebarOptions): () => void;
1125
1242
 
@@ -1321,15 +1438,34 @@ export { DEFAULT_BREAKPOINTS, type DeviceBreakpoints, type DeviceClass, type Dev
1321
1438
  ```ts
1322
1439
  import * as kerfjs from 'kerfjs';
1323
1440
  import { SafeHtml } from 'kerfjs';
1324
- import { a as CatalogProps } from './types-CzgSrFXP.js';
1325
- export { b as CatalogBrand, c as CatalogEntry, d as CatalogRelated, C as CatalogResource, e as CatalogSecondaryGroup, f as CatalogSection } from './types-CzgSrFXP.js';
1441
+ import { a as CatalogProps } from './types-CEsieBZi.js';
1442
+ export { b as CatalogBrand, c as CatalogEntry, d as CatalogRelated, C as CatalogResource, e as CatalogSecondaryGroup, f as CatalogSection, g as CatalogStageRootAttributes } from './types-CEsieBZi.js';
1326
1443
  import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
1327
1444
 
1328
1445
  /** Controlled, stateless component-catalog shell. */
1329
- declare function Catalog({ brand, sections, active, content, collapsed, theme, headerActions, secondarySections, sidebarFooter, status, geometryOverlay, selectAction, toggleSidebarAction, toggleThemeAction, toggleSecondaryAction, className, slot, }: CatalogProps): kerfjs.SafeHtml;
1446
+ declare function Catalog({ brand, sections, active, content, collapsed, theme, headerActions, secondarySections, sidebarFooter, status, geometryOverlay, stageRootAttributes, selectAction, toggleSidebarAction, toggleThemeAction, toggleSecondaryAction, className, slot, }: CatalogProps): kerfjs.SafeHtml;
1330
1447
 
1331
1448
  /** How a specimen aligns its visible edge with its `ListHeader` label. */
1332
1449
  type CatalogExampleAlign = 'glyph' | 'inline-control' | 'none';
1450
+ interface CatalogExampleViewport {
1451
+ layout?: 'grid' | 'flex' | 'flex-column';
1452
+ width?: 'full' | 'compact' | 'medium' | 'wide' | 'text' | 'control';
1453
+ /** Fixed specimen height; `app` frames an application-sized recipe or layout.
1454
+ * A fixed height is definite, so a child that fills with `height: 100%`
1455
+ * (a horizontal `ResizableRegion`, say) spans the whole frame. */
1456
+ height?: 'short' | 'reduced' | 'medium' | 'tall' | 'app';
1457
+ /** A minimum the frame may grow past. It is not a definite height: a child
1458
+ * sized with `height: 100%` falls back to its content height, so use
1459
+ * `height` when the specimen must fill the frame. */
1460
+ minHeight?: 'short' | 'medium';
1461
+ frame?: 'solid' | 'dashed';
1462
+ surface?: 'default' | 'lowered';
1463
+ overflow?: 'hidden' | 'auto-x';
1464
+ responsive?: 'roomy-only';
1465
+ shadow?: boolean;
1466
+ /** Public component custom properties applied to the specimen viewport. */
1467
+ tokens?: Readonly<Record<`--${string}`, string>>;
1468
+ }
1333
1469
  type CatalogExampleRootAttributes = Readonly<Record<`data-${string}`, string | undefined> & {
1334
1470
  'data-catalog-example'?: never;
1335
1471
  'data-catalog-example-stack'?: never;
@@ -1341,6 +1477,10 @@ interface CatalogExampleProps {
1341
1477
  label?: string;
1342
1478
  note?: SafeHtml | string;
1343
1479
  align?: CatalogExampleAlign;
1480
+ /** Optional catalog-owned constraints for demonstrating layout components. */
1481
+ viewport?: CatalogExampleViewport;
1482
+ /** Replacement guidance shown when a roomy-only viewport is hidden. */
1483
+ compactFallback?: SafeHtml | string;
1344
1484
  rootAttributes?: CatalogExampleRootAttributes;
1345
1485
  className?: string;
1346
1486
  children?: KerfUiContent;
@@ -1348,7 +1488,7 @@ interface CatalogExampleProps {
1348
1488
  slot?: string;
1349
1489
  }
1350
1490
  /** A labeled catalog specimen with optional explanatory text and alignment. */
1351
- declare function CatalogExample({ label, note, align, rootAttributes, className, children, slot, }: CatalogExampleProps): SafeHtml;
1491
+ declare function CatalogExample({ label, note, align, viewport, compactFallback, rootAttributes, className, children, slot, }: CatalogExampleProps): SafeHtml;
1352
1492
 
1353
1493
  type CatalogExampleStackRootAttributes = Readonly<Record<`data-${string}`, string | undefined> & {
1354
1494
  'data-catalog-example'?: never;
@@ -1368,13 +1508,13 @@ interface CatalogExampleStackProps {
1368
1508
  /** A vertically stacked group of catalog examples. */
1369
1509
  declare function CatalogExampleStack({ label, rootAttributes, className, children, slot, }: CatalogExampleStackProps): kerfjs.SafeHtml;
1370
1510
 
1371
- export { Catalog, CatalogExample, type CatalogExampleAlign, type CatalogExampleProps, CatalogExampleStack, type CatalogExampleStackProps, CatalogProps };
1511
+ export { Catalog, CatalogExample, type CatalogExampleAlign, type CatalogExampleProps, CatalogExampleStack, type CatalogExampleStackProps, type CatalogExampleViewport, CatalogProps };
1372
1512
  ```
1373
1513
 
1374
1514
  ## `@kerfjs/ui/catalog-resources`
1375
1515
 
1376
1516
  ```ts
1377
- import { C as CatalogResource } from './types-CzgSrFXP.js';
1517
+ import { C as CatalogResource } from './types-CEsieBZi.js';
1378
1518
  import './semantic-content-BbzjvSu9.js';
1379
1519
  import 'kerfjs';
1380
1520
 
@@ -1515,7 +1655,7 @@ export { SegmentedControl, type SegmentedControlAppearance, type SegmentedContro
1515
1655
 
1516
1656
  ```ts
1517
1657
  import { SafeHtml } from 'kerfjs';
1518
- import { CssColor } from './css-values.js';
1658
+ import { CssForegroundColor } from './css-values.js';
1519
1659
  import { LucideNode } from './lucide-icon.js';
1520
1660
  import 'lucide';
1521
1661
 
@@ -1524,9 +1664,19 @@ interface SelectChoice<Value extends string = string> {
1524
1664
  label: string;
1525
1665
  icon?: LucideNode;
1526
1666
  iconName?: string;
1527
- /** Typed semantic or application-owned color for the optional icon. */
1528
- color?: CssColor;
1667
+ /**
1668
+ * Foreground color for the optional icon: a semantic foreground token such
1669
+ * as `uiColor('success-on-quiet')`, or an application-owned
1670
+ * `foregroundColorVar('--app-icon-color')`. Fill tokens such as
1671
+ * `uiColor('success')` are pale background tints and do not type-check.
1672
+ */
1673
+ color?: CssForegroundColor;
1529
1674
  group?: string;
1675
+ /**
1676
+ * Draw a divider between this choice and the previous choice in the same
1677
+ * list. A group boundary is already a separator, so the first choice of a
1678
+ * group (or of the whole menu) never draws a second one.
1679
+ */
1530
1680
  separatorBefore?: boolean;
1531
1681
  }
1532
1682
  type SelectAccessibleName = {
@@ -1653,6 +1803,10 @@ interface SkeletonProps {
1653
1803
  radius?: CssLength;
1654
1804
  /** Render this many stacked lines (the last one shorter), for multi-line text. */
1655
1805
  lines?: number;
1806
+ /** Lay the block out as `display: block` instead of the default
1807
+ * `inline-block`, so it takes no text line of its own: no baseline gap
1808
+ * below it, and it centers like an icon in a slot. Defaults to `false`. */
1809
+ block?: boolean;
1656
1810
  /** Accessible label. Omit to keep the block decorative (`aria-hidden`). */
1657
1811
  label?: string;
1658
1812
  className?: string;
@@ -1665,7 +1819,7 @@ interface SkeletonProps {
1665
1819
  * `placeholder` prop. Decorative by default (`aria-hidden`); pass `label` to
1666
1820
  * announce it. Sizes to its slot unless `width`/`height` are given.
1667
1821
  */
1668
- declare function Skeleton({ width, height, radius, lines, label, className, slot, }: SkeletonProps): kerfjs.SafeHtml;
1822
+ declare function Skeleton({ width, height, radius, lines, block, label, className, slot, }: SkeletonProps): kerfjs.SafeHtml;
1669
1823
 
1670
1824
  export { Skeleton, type SkeletonProps };
1671
1825
  ```
@@ -2051,14 +2205,14 @@ import * as kerfjs from 'kerfjs';
2051
2205
  import { KerfBaseAttrs } from 'kerfjs/jsx-runtime';
2052
2206
  import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
2053
2207
 
2054
- type TextVariant = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'p';
2208
+ type TextVariant = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'p' | 'span';
2055
2209
  type TextTone = 'default' | 'quiet' | 'danger';
2056
2210
  type TextSize = 'default' | 'compact';
2057
2211
  type TextFont = 'default' | 'monospace';
2058
2212
  type TextBorder = 'transparent' | 'none';
2059
2213
  type TextContent = KerfUiContent | string | number | readonly TextContent[];
2060
2214
  type TextProps = Omit<KerfBaseAttrs, 'children' | 'class' | 'className'> & {
2061
- /** Native heading or paragraph element to render. Defaults to `p`. */
2215
+ /** Native heading, paragraph, or inline span element to render. Defaults to `p`. */
2062
2216
  variant?: TextVariant;
2063
2217
  /** Semantic foreground treatment. Defaults to the inherited foreground. */
2064
2218
  tone?: TextTone;
@@ -2073,7 +2227,8 @@ type TextProps = Omit<KerfBaseAttrs, 'children' | 'class' | 'className'> & {
2073
2227
  className?: string;
2074
2228
  };
2075
2229
  /**
2076
- * Semantic heading or paragraph text with the standard content-item padding.
2230
+ * Semantic heading, paragraph, or inline text. Block variants use the standard
2231
+ * content-item padding; `span` adds no box geometry.
2077
2232
  * All ordinary native heading/paragraph attributes pass through to the element.
2078
2233
  */
2079
2234
  declare function Text({ variant: Variant, tone, size, font, border, children, class: classValue, className, ...attributes }: TextProps): kerfjs.SafeHtml;
@@ -2090,6 +2245,16 @@ import { S as Sides } from './divider-sides-BzB6rphT.js';
2090
2245
  import { H as HorizontalAlignment, V as VerticalAlignment } from './flex-alignment-4ms8ZbV8.js';
2091
2246
  import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
2092
2247
 
2248
+ type RowRootAttributes = Readonly<Record<`data-${string}`, string | undefined> & {
2249
+ 'data-component'?: never;
2250
+ 'data-h-align'?: never;
2251
+ 'data-v-align'?: never;
2252
+ 'data-flex'?: never;
2253
+ 'data-fill'?: never;
2254
+ 'data-wrap'?: never;
2255
+ 'data-text-insets'?: never;
2256
+ 'data-control-insets'?: never;
2257
+ }>;
2093
2258
  interface RowProps {
2094
2259
  children?: KerfUiContent;
2095
2260
  /** Horizontal distribution. Defaults to left. */
@@ -2100,6 +2265,12 @@ interface RowProps {
2100
2265
  gap?: UiSpaceName | CssLength;
2101
2266
  /** Allow this row to grow/shrink, use a keyword, or supply a typed CSS flex shorthand. */
2102
2267
  flex?: boolean | CssFlexKeyword | CssFlex;
2268
+ /**
2269
+ * Fill the height of a parent with a definite height, such as an app root or
2270
+ * a fixed-height frame, when this row is that parent's layout root. Inside a
2271
+ * flex layout use `flex` instead. Defaults to false.
2272
+ */
2273
+ fill?: boolean;
2103
2274
  /** Allow children to wrap onto additional lines. */
2104
2275
  wrap?: boolean;
2105
2276
  /** Physical sides that receive the standard 17px text inset. */
@@ -2107,11 +2278,13 @@ interface RowProps {
2107
2278
  /** Physical sides that receive the standard 8px control inset. Text insets win on overlap. */
2108
2279
  controlInsets?: Sides;
2109
2280
  className?: string;
2281
+ /** Safe `data-*` metadata; Row-owned structural attributes remain protected. */
2282
+ rootAttributes?: RowRootAttributes;
2110
2283
  /** Native named-slot assignment when composed inside a web component. */
2111
2284
  slot?: string;
2112
2285
  }
2113
2286
  /** A horizontal flex row with explicit physical-axis alignment and spacing. */
2114
- declare function Row({ children, hAlign, vAlign, gap, flex, wrap, textInsets, controlInsets, className, slot, }: RowProps): kerfjs.SafeHtml;
2287
+ declare function Row({ children, hAlign, vAlign, gap, flex, fill, wrap, textInsets, controlInsets, className, rootAttributes, slot, }: RowProps): kerfjs.SafeHtml;
2115
2288
 
2116
2289
  export { CssFlex, CssFlexKeyword, CssLength, HorizontalAlignment, Row, type RowProps, Sides, UiSpaceName, VerticalAlignment };
2117
2290
  ```
@@ -2123,6 +2296,12 @@ import * as kerfjs from 'kerfjs';
2123
2296
  import { UiSpaceName, CssLength, CssFlexKeyword, CssFlex } from './css-values.js';
2124
2297
  import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
2125
2298
 
2299
+ type GridRootAttributes = Readonly<Record<`data-${string}`, string | undefined> & {
2300
+ 'data-component'?: never;
2301
+ 'data-columns'?: never;
2302
+ 'data-flex'?: never;
2303
+ 'data-fill'?: never;
2304
+ }>;
2126
2305
  interface GridProps {
2127
2306
  children?: KerfUiContent;
2128
2307
  /** Number of equal-width columns. Must be a positive safe integer. */
@@ -2131,12 +2310,20 @@ interface GridProps {
2131
2310
  gap?: UiSpaceName | CssLength;
2132
2311
  /** Allow this grid to grow/shrink, use a keyword, or supply a typed CSS flex shorthand. */
2133
2312
  flex?: boolean | CssFlexKeyword | CssFlex;
2313
+ /**
2314
+ * Fill the height of a parent with a definite height, such as an app root or
2315
+ * a fixed-height frame, when this grid is that parent's layout root. Inside a
2316
+ * flex layout use `flex` instead. Defaults to false.
2317
+ */
2318
+ fill?: boolean;
2134
2319
  className?: string;
2320
+ /** Safe `data-*` metadata; Grid-owned structural attributes remain protected. */
2321
+ rootAttributes?: GridRootAttributes;
2135
2322
  /** Native named-slot assignment when composed inside a web component. */
2136
2323
  slot?: string;
2137
2324
  }
2138
2325
  /** A fixed-count grid whose columns share the available width equally. */
2139
- declare function Grid({ children, columns, gap, flex, className, slot, }: GridProps): kerfjs.SafeHtml;
2326
+ declare function Grid({ children, columns, gap, flex, fill, className, rootAttributes, slot, }: GridProps): kerfjs.SafeHtml;
2140
2327
 
2141
2328
  export { CssFlex, CssFlexKeyword, CssLength, Grid, type GridProps, UiSpaceName };
2142
2329
  ```