@kerfjs/ui 5.0.0-beta.59 → 5.0.0-beta.60

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 (117) hide show
  1. package/ai/component-catalog.json +99 -10
  2. package/ai/component-composition.json +78 -6
  3. package/ai/components/README.md +1 -1
  4. package/ai/components/floating-toolbar.md +3 -1
  5. package/ai/components/list-header.md +1 -1
  6. package/ai/components/list-item.md +4 -1
  7. package/ai/components/resize.md +6 -1
  8. package/ai/components/select.md +5 -3
  9. package/ai/components/state-banner.md +3 -1
  10. package/ai/components/tab-bar.md +1 -1
  11. package/ai/components/tabs.md +2 -1
  12. package/ai/components/text.md +2 -1
  13. package/ai/components/token-search-field.md +1 -1
  14. package/ai/components/toolbar-text.md +4 -2
  15. package/ai/components/toolbar.md +2 -1
  16. package/ai/components/value-table.md +2 -1
  17. package/ai/public-api-signatures-v1.md +55 -18
  18. package/ai/skill.md +18 -6
  19. package/ai/webawesome-jsx-signatures-v1.md +1 -1
  20. package/dist/app-tab.d.ts +4 -1
  21. package/dist/app-tab.js +1 -1
  22. package/dist/catalog.js +6 -6
  23. package/dist/{chunk-2CCMJTVY.js → chunk-2OXQHM7I.js} +5 -5
  24. package/dist/{chunk-2CCMJTVY.js.map → chunk-2OXQHM7I.js.map} +1 -1
  25. package/dist/{chunk-XDKAYSVD.js → chunk-3SXMEK3B.js} +1 -1
  26. package/dist/chunk-3SXMEK3B.js.map +1 -0
  27. package/dist/{chunk-QOWG4ZCL.js → chunk-5I7OHCIP.js} +5 -2
  28. package/dist/chunk-5I7OHCIP.js.map +1 -0
  29. package/dist/{chunk-W4XKTST6.js → chunk-5PESG2VP.js} +3 -3
  30. package/dist/{chunk-W4XKTST6.js.map → chunk-5PESG2VP.js.map} +1 -1
  31. package/dist/{chunk-UX2VVXZ3.js → chunk-5Q3N6EV7.js} +2 -2
  32. package/dist/{chunk-UX2VVXZ3.js.map → chunk-5Q3N6EV7.js.map} +1 -1
  33. package/dist/{chunk-UFYZHYWU.js → chunk-A3CKOW2R.js} +4 -3
  34. package/dist/chunk-A3CKOW2R.js.map +1 -0
  35. package/dist/{chunk-UXT7TE6B.js → chunk-AUKT3KMG.js} +5 -1
  36. package/dist/chunk-AUKT3KMG.js.map +1 -0
  37. package/dist/{chunk-EVYKTVBQ.js → chunk-GLDWRCAM.js} +5 -1
  38. package/dist/chunk-GLDWRCAM.js.map +1 -0
  39. package/dist/{chunk-M7QV3IHH.js → chunk-I3Q7KKYM.js} +5 -1
  40. package/dist/chunk-I3Q7KKYM.js.map +1 -0
  41. package/dist/{chunk-3CGQ7ZNO.js → chunk-IA7TMD4Y.js} +2 -2
  42. package/dist/{chunk-3CGQ7ZNO.js.map → chunk-IA7TMD4Y.js.map} +1 -1
  43. package/dist/{chunk-VHADGP3B.js → chunk-KLJKU6ZL.js} +5 -1
  44. package/dist/chunk-KLJKU6ZL.js.map +1 -0
  45. package/dist/{chunk-6YFHCLHG.js → chunk-MERWRTBG.js} +1 -1
  46. package/dist/chunk-MERWRTBG.js.map +1 -0
  47. package/dist/{chunk-KH6VUGHU.js → chunk-NNMLEDMD.js} +2 -2
  48. package/dist/{chunk-KH6VUGHU.js.map → chunk-NNMLEDMD.js.map} +1 -1
  49. package/dist/{chunk-6CINWX2E.js → chunk-P7D3EMXM.js} +3 -1
  50. package/dist/chunk-P7D3EMXM.js.map +1 -0
  51. package/dist/{chunk-QPUPLNNB.js → chunk-T57AXDFM.js} +2 -2
  52. package/dist/{chunk-QPUPLNNB.js.map → chunk-T57AXDFM.js.map} +1 -1
  53. package/dist/{chunk-WOUF7YXM.js → chunk-T66UNBXL.js} +5 -2
  54. package/dist/chunk-T66UNBXL.js.map +1 -0
  55. package/dist/{chunk-XQV2B4IL.js → chunk-UIDKY4UB.js} +2 -2
  56. package/dist/{chunk-XQV2B4IL.js.map → chunk-UIDKY4UB.js.map} +1 -1
  57. package/dist/{chunk-OUK6QRDR.js → chunk-WPLIO5WJ.js} +5 -2
  58. package/dist/chunk-WPLIO5WJ.js.map +1 -0
  59. package/dist/collapsible-panel.d.ts +1 -0
  60. package/dist/collapsible-panel.js +2 -2
  61. package/dist/floating-toolbar.d.ts +8 -2
  62. package/dist/floating-toolbar.js +1 -1
  63. package/dist/index.js +13 -13
  64. package/dist/list-header.js +1 -1
  65. package/dist/list-item.d.ts +5 -2
  66. package/dist/list-item.js +1 -1
  67. package/dist/nav-stack.js +1 -1
  68. package/dist/resizable-region.d.ts +8 -3
  69. package/dist/resizable-region.js +1 -1
  70. package/dist/select.d.ts +4 -1
  71. package/dist/select.js +1 -1
  72. package/dist/split-view.d.ts +1 -0
  73. package/dist/split-view.js +2 -2
  74. package/dist/state-banner.d.ts +8 -2
  75. package/dist/state-banner.js +1 -1
  76. package/dist/styles/app-tab.css +3 -0
  77. package/dist/styles/floating-toolbar.css +56 -4
  78. package/dist/styles/list-header.css +15 -7
  79. package/dist/styles/list-item.css +60 -18
  80. package/dist/styles/resizable-region.css +33 -1
  81. package/dist/styles/select.css +26 -0
  82. package/dist/styles/state-banner.css +37 -0
  83. package/dist/styles/tab-bar.css +25 -10
  84. package/dist/styles/text.css +9 -0
  85. package/dist/styles/token-search-field.css +1 -1
  86. package/dist/styles/toolbar-text.css +4 -0
  87. package/dist/styles/toolbar.css +83 -1
  88. package/dist/styles/value-table.css +16 -3
  89. package/dist/text.d.ts +7 -2
  90. package/dist/text.js +1 -1
  91. package/dist/toolbar-text.d.ts +1 -1
  92. package/dist/toolbar-text.js +1 -1
  93. package/dist/toolbar.d.ts +4 -2
  94. package/dist/toolbar.js +1 -1
  95. package/dist/value-table.d.ts +3 -1
  96. package/dist/value-table.js +1 -1
  97. package/dist/wire-catalog.js +1 -1
  98. package/dist/wire-resizable-regions.js +1 -1
  99. package/dist/wire-token-search-fields.js +1 -1
  100. package/dist/wire-workbench.js +1 -1
  101. package/dist/workbench.js +1 -1
  102. package/docs/collapsible-panel.md +7 -1
  103. package/docs/component-selection.md +61 -0
  104. package/docs/document-baseline.md +3 -0
  105. package/llms.txt +32 -0
  106. package/package.json +1 -1
  107. package/dist/chunk-6CINWX2E.js.map +0 -1
  108. package/dist/chunk-6YFHCLHG.js.map +0 -1
  109. package/dist/chunk-EVYKTVBQ.js.map +0 -1
  110. package/dist/chunk-M7QV3IHH.js.map +0 -1
  111. package/dist/chunk-OUK6QRDR.js.map +0 -1
  112. package/dist/chunk-QOWG4ZCL.js.map +0 -1
  113. package/dist/chunk-UFYZHYWU.js.map +0 -1
  114. package/dist/chunk-UXT7TE6B.js.map +0 -1
  115. package/dist/chunk-VHADGP3B.js.map +0 -1
  116. package/dist/chunk-WOUF7YXM.js.map +0 -1
  117. package/dist/chunk-XDKAYSVD.js.map +0 -1
@@ -38,6 +38,7 @@ Exact prop names and types: [`@kerfjs/ui/text`](../public-api-signatures-v1.md#k
38
38
  - default, quiet, or danger tone
39
39
  - compact, default, large, or xlarge size
40
40
  - default or monospace font
41
+ - flush item geometry and tight line height
41
42
 
42
43
  ## Composition
43
44
 
@@ -55,7 +56,7 @@ No wiring helper.
55
56
 
56
57
  Margin: none · border: self · padding: self (layout role: structure). `self` means the component already owns it — do not add wrapper padding, margin, or borders around it.
57
58
 
58
- - Block Text variants reset native margins and add a 1px transparent border plus the standard 8px item padding; span has no margin, border, or padding.
59
+ - Block Text variants reset native margins and add a 1px transparent border plus the standard 8px item padding; flush removes the border and padding. Tight line height is available for compact copy. Span has no margin, border, or padding.
59
60
 
60
61
  ## Accessibility
61
62
 
@@ -88,7 +88,7 @@ Public class hooks (select for layout placement only, never to change the compon
88
88
 
89
89
  Never put `kui-token-search`, `kui-token-search__clear`, `kui-token-search__editor`, `kui-token-search__expand`, `kui-token-search__leading`, `kui-token-search__token`, `kui-token-search__token-edit`, `kui-token-search__token-remove`, `kui-token-search__suggestions`, `kui-token-search__suggestion`, `kui-token-search__trailing` on an element you write; render `TokenSearchField` instead (`KUI-L103`).
90
90
 
91
- Public tokens it reads: `--kui-color-brand-fill-normal`, `--kui-color-brand-on-quiet`, `--kui-color-neutral-border-normal`, `--kui-color-text-link`, `--kui-color-surface`, `--kui-color-text`, `--kui-color-text-quiet`, `--kui-focus-ring`, `--kui-font-s`, `--kui-font-xs`, `--kui-radius-pill`, `--kui-token-search-background`, `--kui-token-search-border`, `--kui-token-search-line-size`, `--kui-token-search-token-background`, `--kui-token-search-token-foreground`, `--kui-token-search-expanded-width`. Set a token only where its public contract allows; prefer a prop.
91
+ Public tokens it reads: `--kui-color-brand-fill-normal`, `--kui-color-brand-on-quiet`, `--kui-color-neutral-border-normal`, `--kui-color-text-link`, `--kui-color-surface`, `--kui-color-text`, `--kui-color-text-quiet`, `--kui-focus-ring`, `--kui-font-s`, `--kui-font-xs`, `--kui-radius-pill`, `--kui-token-search-background`, `--kui-token-search-border`, `--kui-token-search-editor-min-width`, `--kui-token-search-line-size`, `--kui-token-search-token-background`, `--kui-token-search-token-foreground`, `--kui-token-search-expanded-width`. Set a token only where its public contract allows; prefer a prop.
92
92
 
93
93
  Everything else is internal: `kerf-ui-analyze` reports private or unknown `.kui-*` selectors (`KUI-L001`, `KUI-L010`), unknown or private tokens (`KUI-L002`, `KUI-L012`), and any application rule that restyles the component, forced dimensions included (`KUI-L019`).
94
94
 
@@ -6,7 +6,7 @@
6
6
 
7
7
  ## When to use
8
8
 
9
- Large, default, and compact toolbar identity text.
9
+ Extra-large through extra-small toolbar identity text.
10
10
 
11
11
  - Render toolbar identity or heading text at a supported hierarchy size; pass headingLevel for heading semantics.
12
12
 
@@ -32,9 +32,11 @@ Exact prop names and types: [`@kerfjs/ui/toolbar-text`](../public-api-signatures
32
32
 
33
33
  **Variants (configure, do not restyle):**
34
34
 
35
+ - xlarge
35
36
  - large
36
37
  - default
37
38
  - small
39
+ - xsmall
38
40
  - placeholder (loading)
39
41
 
40
42
  ## Composition
@@ -65,7 +67,7 @@ Public class hooks (select for layout placement only, never to change the compon
65
67
 
66
68
  Never put `kui-toolbar-text` on an element you write; render `ToolbarText` instead (`KUI-L103`).
67
69
 
68
- Public tokens it reads: `--kui-color-neutral-on-quiet`, `--kui-color-text`, `--kui-font-2xl`, `--kui-font-l`, `--kui-font-m`, `--kui-font-s`, `--kui-font-xs`. Set a token only where its public contract allows; prefer a prop.
70
+ Public tokens it reads: `--kui-color-neutral-on-quiet`, `--kui-color-text`, `--kui-font-2xs`, `--kui-font-2xl`, `--kui-font-l`, `--kui-font-m`, `--kui-font-s`, `--kui-font-xs`. Set a token only where its public contract allows; prefer a prop.
69
71
 
70
72
  Everything else is internal: `kerf-ui-analyze` reports private or unknown `.kui-*` selectors (`KUI-L001`, `KUI-L010`), unknown or private tokens (`KUI-L002`, `KUI-L012`), and any application rule that restyles the component, forced dimensions included (`KUI-L019`).
71
73
 
@@ -34,6 +34,7 @@ Exact prop names and types: [`@kerfjs/ui/toolbar`](../public-api-signatures-v1.m
34
34
  - stacked zones at compact or narrow widths
35
35
  - content-driven wrap that keeps a heading title whole
36
36
  - center priority for an expanded center control
37
+ - trailing priority for an expanded trailing control at compact or narrow widths
37
38
  - trailing groups wrap instead of clipping
38
39
  - app bar or bottom bar claiming its screen edges (safeAreaEdges)
39
40
 
@@ -80,7 +81,7 @@ Public class hooks (select for layout placement only, never to change the compon
80
81
 
81
82
  Never put `kui-toolbar`, `kui-toolbar__center`, `kui-toolbar__leading`, `kui-toolbar__trailing` on an element you write; render `Toolbar` instead (`KUI-L103`).
82
83
 
83
- Public tokens it reads: `--kui-color-neutral-border-normal`, `--kui-font-sans`, `--kui-toolbar-divider-color`. Set a token only where its public contract allows; prefer a prop.
84
+ Public tokens it reads: `--kui-color-neutral-border-normal`, `--kui-font-sans`, `--kui-toolbar-center-padding-inline`, `--kui-toolbar-divider-color`, `--kui-toolbar-leading-min-width`, `--kui-toolbar-leading-padding-inline`, `--kui-toolbar-trailing-gap`, `--kui-toolbar-trailing-justify`, `--kui-toolbar-trailing-justify-self`, `--kui-toolbar-trailing-padding-inline`, `--kui-toolbar-zone-padding-inline`. Set a token only where its public contract allows; prefer a prop.
84
85
 
85
86
  Everything else is internal: `kerf-ui-analyze` reports private or unknown `.kui-*` selectors (`KUI-L001`, `KUI-L010`), unknown or private tokens (`KUI-L002`, `KUI-L012`), and any application rule that restyles the component, forced dimensions included (`KUI-L019`).
86
87
 
@@ -30,6 +30,7 @@ Exact prop names and types: [`@kerfjs/ui/value-table`](../public-api-signatures-
30
30
 
31
31
  - icon rows
32
32
  - iconless rows
33
+ - compact density
33
34
  - placeholder (loading)
34
35
 
35
36
  ## Composition
@@ -61,7 +62,7 @@ Public class hooks (select for layout placement only, never to change the compon
61
62
 
62
63
  Never put `kui-value-table`, `kui-value-table__row`, `kui-value-table__icon`, `kui-value-table__label` on an element you write; render `ValueTable` instead (`KUI-L103`).
63
64
 
64
- Public tokens it reads: `--kui-color-neutral-border-normal`, `--kui-color-surface-lowered`, `--kui-color-text`, `--kui-color-text-quiet`, `--kui-font-weight-semibold`, `--kui-layout-inline-margin`, `--kui-layout-item-gap`, `--kui-layout-item-padding`, `--kui-space-2xs`, `--kui-value-table-background`, `--kui-value-table-border`, `--kui-value-table-icon-size`. Set a token only where its public contract allows; prefer a prop.
65
+ Public tokens it reads: `--kui-color-neutral-border-normal`, `--kui-color-surface-lowered`, `--kui-color-text`, `--kui-color-text-quiet`, `--kui-font-weight-semibold`, `--kui-layout-inline-margin`, `--kui-layout-item-gap`, `--kui-layout-item-padding`, `--kui-space-2xs`, `--kui-value-table-background`, `--kui-value-table-border`, `--kui-value-table-icon-size`, `--kui-value-table-row-columns`, `--kui-value-table-row-padding-block`, `--kui-value-table-row-gap`. Set a token only where its public contract allows; prefer a prop.
65
66
 
66
67
  Everything else is internal: `kerf-ui-analyze` reports private or unknown `.kui-*` selectors (`KUI-L001`, `KUI-L010`), unknown or private tokens (`KUI-L002`, `KUI-L012`), and any application rule that restyles the component, forced dimensions included (`KUI-L019`).
67
68
 
@@ -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.59` and `kerfjs@5.0.0-beta.59`. 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.60` and `kerfjs@5.0.0-beta.60`. 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
 
@@ -174,9 +174,11 @@ interface ToolbarProps {
174
174
  * - `wrap` keeps one row while every zone fits at its natural width, and
175
175
  * otherwise moves the trailing zone below a whole leading identity.
176
176
  * - `center-priority` gives an expanded center control the full row.
177
+ * - `trailing-priority` moves an expanded trailing control to a full row
178
+ * below the leading identity at `responsiveAt`.
177
179
  */
178
- responsive?: 'none' | 'stack' | 'wrap' | 'center-priority';
179
- /** Container width at which `responsive="stack"` activates. */
180
+ responsive?: 'none' | 'stack' | 'wrap' | 'center-priority' | 'trailing-priority';
181
+ /** Container width at which `stack` or `trailing-priority` activates. */
180
182
  responsiveAt?: 'compact' | 'narrow';
181
183
  /**
182
184
  * Screen edges this toolbar claims for device safe-area compensation, for an
@@ -208,7 +210,7 @@ export { Sides, Toolbar, type ToolbarConfig, type ToolbarProps };
208
210
  ```ts
209
211
  import * as kerfjs from 'kerfjs';
210
212
 
211
- type ToolbarTextSize = 'xlarge' | 'large' | 'default' | 'small';
213
+ type ToolbarTextSize = 'xlarge' | 'large' | 'default' | 'small' | 'xsmall';
212
214
  /** ARIA heading level for a title exposed as a heading landmark. */
213
215
  type HeadingLevel = 1 | 2 | 3 | 4 | 5 | 6;
214
216
  interface ToolbarTextBaseProps {
@@ -351,6 +353,8 @@ interface FloatingToolbarProps {
351
353
  * Default: `'bottom-end'`.
352
354
  */
353
355
  position?: FloatingToolbarPosition;
356
+ /** Keep the toolbar in normal document flow instead of floating over content. */
357
+ placement?: 'floating' | 'inline';
354
358
  /**
355
359
  * Distance from the container edges named by `position`. Default:
356
360
  * `space('m')` (16px, 8px past a top toolbar's own inset). Omit it inside a
@@ -358,6 +362,8 @@ interface FloatingToolbarProps {
358
362
  * corner owns the inset there and sets it to zero.
359
363
  */
360
364
  inset?: CssLength;
365
+ /** Add device or layout-routed safe-area insets to the positioned edges. */
366
+ safeAreaInsets?: boolean;
361
367
  className?: string;
362
368
  /** Native named-slot assignment when composed inside a web component. */
363
369
  slot?: string;
@@ -375,9 +381,11 @@ interface FloatingToolbarProps {
375
381
  * `wireSidebar` compact overlay, an overlay `CollapsiblePanel` or horizontal
376
382
  * `ResizableRegion`), the toolbar is hidden — unfocusable and out of the
377
383
  * accessibility tree — until the overlay closes. The app owns the controls
378
- * and their behavior — wire them with `delegate()` as usual.
384
+ * and their behavior — wire them with `delegate()` as usual. Set
385
+ * `placement="inline"` for normal flow when an owner already positions the
386
+ * control; floating placement can add safe-area insets to its per-edge tokens.
379
387
  */
380
- declare function FloatingToolbar({ children, label, position, inset, className, slot, }: FloatingToolbarProps): kerfjs.SafeHtml;
388
+ declare function FloatingToolbar({ children, label, position, placement, inset, safeAreaInsets, className, slot, }: FloatingToolbarProps): kerfjs.SafeHtml;
381
389
 
382
390
  export { FloatingToolbar, type FloatingToolbarPosition, type FloatingToolbarProps };
383
391
  ```
@@ -741,6 +749,7 @@ type ListItemRootAttributes = Readonly<Record<`data-${string}`, string | undefin
741
749
  'data-busy'?: never;
742
750
  'data-state'?: never;
743
751
  'data-kui-disabled'?: never;
752
+ 'data-icon-align'?: never;
744
753
  }>;
745
754
  interface ListItemProps {
746
755
  label: string | SafeHtml;
@@ -753,7 +762,7 @@ interface ListItemProps {
753
762
  status?: string | SafeHtml;
754
763
  /** Show a progress indicator and expose the row as busy without replacing its content; a placeholder keeps the indicator. */
755
764
  busy?: boolean;
756
- density?: 'standard' | 'compact';
765
+ density?: 'standard' | 'compact' | 'spacious';
757
766
  divider?: 'none' | 'before' | 'after' | 'both';
758
767
  selected?: boolean;
759
768
  action: string;
@@ -763,6 +772,8 @@ interface ListItemProps {
763
772
  accessibleLabel?: string;
764
773
  title?: string;
765
774
  multiline?: boolean;
775
+ /** Alignment of an icon beside a wrapped label. Defaults to its first line. */
776
+ multilineIconAlign?: 'first-line' | 'center';
766
777
  state?: string;
767
778
  disabled?: boolean;
768
779
  tabIndex?: number;
@@ -772,7 +783,7 @@ interface ListItemProps {
772
783
  /** Native named-slot assignment when composed inside a web component. */
773
784
  slot?: string;
774
785
  }
775
- declare function ListItem({ label, description, icon, trailing, status, busy, density, divider, selected, action, itemId, className, pressed, accessibleLabel, title, multiline, state, disabled, tabIndex, placeholder, rootAttributes, slot, }: ListItemProps): SafeHtml;
786
+ declare function ListItem({ label, description, icon, trailing, status, busy, density, divider, selected, action, itemId, className, pressed, accessibleLabel, title, multiline, multilineIconAlign, state, disabled, tabIndex, placeholder, rootAttributes, slot, }: ListItemProps): SafeHtml;
776
787
 
777
788
  export { ListItem, type ListItemProps };
778
789
  ```
@@ -911,12 +922,14 @@ declare function ValueTableRow({ label, value, icon, className, placeholder, slo
911
922
 
912
923
  interface ValueTableProps {
913
924
  label: string;
925
+ /** Compact row spacing for metadata-dense surfaces. */
926
+ density?: 'default' | 'compact';
914
927
  className?: string;
915
928
  children: KerfUiContent;
916
929
  /** Native named-slot assignment when composed inside a web component. */
917
930
  slot?: string;
918
931
  }
919
- declare function ValueTable({ label, className, children, slot, }: ValueTableProps): kerfjs.SafeHtml;
932
+ declare function ValueTable({ label, density, className, children, slot, }: ValueTableProps): kerfjs.SafeHtml;
920
933
 
921
934
  export { ValueTable, type ValueTableProps, ValueTableRow, type ValueTableRowProps };
922
935
  ```
@@ -934,6 +947,7 @@ type AppTabRootAttributes = Readonly<Record<`data-${string}`, string | undefined
934
947
  'data-selected'?: never;
935
948
  'data-tab-dragging'?: never;
936
949
  'data-tab-drop-position'?: never;
950
+ 'data-attention'?: never;
937
951
  }>;
938
952
  type AppTabPresentation = 'pill' | 'segmented' | 'icon-only';
939
953
  type AppTabSize = 'default' | 'compact';
@@ -941,6 +955,8 @@ interface AppTabProps {
941
955
  id: string;
942
956
  name: string;
943
957
  selected?: boolean;
958
+ /** Emphasize the visible tab name with the attention color token. */
959
+ attention?: boolean;
944
960
  closable?: boolean;
945
961
  draggable?: boolean;
946
962
  leading?: KerfUiContent;
@@ -973,7 +989,7 @@ interface AppTabProps {
973
989
  /** Native named-slot assignment when composed inside a web component. */
974
990
  slot?: string;
975
991
  }
976
- declare function AppTab({ id, name, selected, closable, draggable, leading, trailing, presentation, size, labelMaxWidth, closeIcon, selectAction, closeAction, className, placeholder, pending, rootAttributes, slot, }: AppTabProps): SafeHtml;
992
+ declare function AppTab({ id, name, selected, attention, closable, draggable, leading, trailing, presentation, size, labelMaxWidth, closeIcon, selectAction, closeAction, className, placeholder, pending, rootAttributes, slot, }: AppTabProps): SafeHtml;
977
993
 
978
994
  export { AppTab, type AppTabPresentation, type AppTabProps, type AppTabSize };
979
995
  ```
@@ -1262,6 +1278,7 @@ import './toolbar.js';
1262
1278
  import './pane.js';
1263
1279
  import './sides-BPSWde0A.js';
1264
1280
  import './toolbar-text.js';
1281
+ import './css-values.js';
1265
1282
 
1266
1283
  /**
1267
1284
  * The roomy list pane's `ResizableRegion`: its committed `size` and `min` /
@@ -1812,6 +1829,7 @@ import './lucide-icon.js';
1812
1829
  import 'lucide';
1813
1830
  import './toolbar.js';
1814
1831
  import './sides-BPSWde0A.js';
1832
+ import './css-values.js';
1815
1833
 
1816
1834
  /** Which edge a {@link CollapsiblePanel} docks to. */
1817
1835
  type CollapsiblePanelSide = PanelSide;
@@ -2095,6 +2113,7 @@ export { type WireTabScaffoldOptions, wireTabScaffold };
2095
2113
 
2096
2114
  ```ts
2097
2115
  import { SafeHtml } from 'kerfjs';
2116
+ import { CssLength } from './css-values.js';
2098
2117
  import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
2099
2118
 
2100
2119
  type ResizableRegionAxis = 'horizontal' | 'vertical';
@@ -2103,7 +2122,7 @@ type ResizableRegionSeparator = 'auto' | 'hidden';
2103
2122
  type ResizableRegionCollapseMotion = 'none' | 'slide' | 'fade-slide';
2104
2123
  type ResizableRegionContentOverflow = 'clip' | 'auto' | 'visible';
2105
2124
  type ResizableRegionPresentation = 'inline' | 'overlay' | 'hidden';
2106
- type ResizableRegionRestorePosition = 'bottom-start' | 'bottom-end';
2125
+ type ResizableRegionRestorePosition = 'bottom-start' | 'bottom-end' | 'top-start' | 'top-end';
2107
2126
  type ResizableRegionResponsiveFillAt = 'compact' | 'narrow';
2108
2127
  interface ResizableRegionProps {
2109
2128
  id: string;
@@ -2122,7 +2141,7 @@ interface ResizableRegionProps {
2122
2141
  separator?: ResizableRegionSeparator;
2123
2142
  /** Keep the track change instant while optionally sliding the fixed-size content. */
2124
2143
  collapseMotion?: ResizableRegionCollapseMotion;
2125
- /** Overflow policy for content such as an open popup inside a bottom drawer. */
2144
+ /** Use `visible` while an anchored popup must escape the content box; it raises the region to the popup layer. */
2126
2145
  contentOverflow?: ResizableRegionContentOverflow;
2127
2146
  /** Inline layout, an edge overlay, or a responsive replacement that removes the region. */
2128
2147
  presentation?: ResizableRegionPresentation;
@@ -2130,6 +2149,10 @@ interface ResizableRegionProps {
2130
2149
  restoreControl?: SafeHtml;
2131
2150
  /** Safe-area-aware corner of the region's container (not the viewport) for `restoreControl`. */
2132
2151
  restorePosition?: ResizableRegionRestorePosition;
2152
+ /** Position a restore control in its container corner or leave it in normal flow. */
2153
+ restorePlacement?: 'corner' | 'inline';
2154
+ /** Corner distance before the container's safe-area inset. */
2155
+ restoreInset?: CssLength;
2133
2156
  /** Fill the available inline track and hide the separator below a container breakpoint. */
2134
2157
  responsiveFillAt?: ResizableRegionResponsiveFillAt;
2135
2158
  /** Decorative dormant content for the separator handle. Must not contain interactive descendants. */
@@ -2138,7 +2161,7 @@ interface ResizableRegionProps {
2138
2161
  }
2139
2162
  declare const clampRegionSize: (size: number, min: number, max: number) => number;
2140
2163
  declare const resizeRegionFromPointer: (startSize: number, delta: number, edge: ResizableRegionEdge) => number;
2141
- declare function ResizableRegion({ id, label, size, min, max, axis, edge, collapsed, transitioning, separator, collapseMotion, contentOverflow, presentation, restoreControl, restorePosition, responsiveFillAt, handleIcon, children, }: ResizableRegionProps): SafeHtml;
2164
+ declare function ResizableRegion({ id, label, size, min, max, axis, edge, collapsed, transitioning, separator, collapseMotion, contentOverflow, presentation, restoreControl, restorePosition, restorePlacement, restoreInset, responsiveFillAt, handleIcon, children, }: ResizableRegionProps): SafeHtml;
2142
2165
 
2143
2166
  export { ResizableRegion, type ResizableRegionAxis, type ResizableRegionCollapseMotion, type ResizableRegionContentOverflow, type ResizableRegionEdge, type ResizableRegionPresentation, type ResizableRegionProps, type ResizableRegionResponsiveFillAt, type ResizableRegionRestorePosition, type ResizableRegionSeparator, clampRegionSize, resizeRegionFromPointer };
2144
2167
  ```
@@ -2543,6 +2566,7 @@ type SelectPresentation = 'form' | 'toolbar-borderless' | 'navigation';
2543
2566
  type SelectSize = 'default' | 'compact';
2544
2567
  type SelectSelectedPresentation = 'label' | 'icon-only';
2545
2568
  type SelectFocusRingOwner = 'select' | 'group';
2569
+ type SelectTriggerWidth = 'fit-content' | 'max-content' | 'fill';
2546
2570
  interface SelectBaseProps<Value extends string = string> {
2547
2571
  name: string;
2548
2572
  choices: readonly SelectChoice<Value>[];
@@ -2558,6 +2582,8 @@ interface SelectBaseProps<Value extends string = string> {
2558
2582
  /** Form (default), borderless toolbar, or intrinsic navigation chrome. */
2559
2583
  presentation?: SelectPresentation;
2560
2584
  size?: SelectSize;
2585
+ /** Closed trigger width; omit to keep the presentation's default. */
2586
+ triggerWidth?: SelectTriggerWidth;
2561
2587
  /** Let an enclosing ToolbarControlGroup paint the composed focus ring. */
2562
2588
  focusRingOwner?: SelectFocusRingOwner;
2563
2589
  /** Maximum closed-control label width in CSS pixels before ellipsis. */
@@ -2608,7 +2634,7 @@ type SelectMultipleValueProps<Value extends string = string> = SelectMultipleLab
2608
2634
  type SelectProps<Value extends string = string> = SelectBaseProps<Value> & SelectAccessibleName & (SelectSingleValueProps<Value> | SelectMultipleValueProps<Value>);
2609
2635
  declare function Select<Value extends string>(props: SelectProps<Value>): SafeHtml;
2610
2636
 
2611
- export { Select, type SelectChoice, type SelectFocusRingOwner, type SelectMultipleIconProps, type SelectMultipleLabelProps, type SelectMultipleValueProps, type SelectPresentation, type SelectProps, type SelectSelectedPresentation, type SelectSingleValueProps, type SelectSize };
2637
+ export { Select, type SelectChoice, type SelectFocusRingOwner, type SelectMultipleIconProps, type SelectMultipleLabelProps, type SelectMultipleValueProps, type SelectPresentation, type SelectProps, type SelectSelectedPresentation, type SelectSingleValueProps, type SelectSize, type SelectTriggerWidth };
2612
2638
  ```
2613
2639
 
2614
2640
  ## `@kerfjs/ui/state-banner`
@@ -2619,6 +2645,8 @@ import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
2619
2645
 
2620
2646
  type StateBannerTone = 'neutral' | 'info' | 'pop' | 'success' | 'warning' | 'danger';
2621
2647
  type StateBannerUrgency = 'status' | 'alert';
2648
+ type StateBannerCopyLayout = 'inline' | 'stacked';
2649
+ type StateBannerActionPlacement = 'trailing' | 'below';
2622
2650
  interface StateBannerProps {
2623
2651
  title: string;
2624
2652
  detail?: string;
@@ -2628,15 +2656,19 @@ interface StateBannerProps {
2628
2656
  action?: KerfUiContent;
2629
2657
  tone?: StateBannerTone;
2630
2658
  urgency?: StateBannerUrgency;
2659
+ /** Keep the detail beside the title, or give it its own line. */
2660
+ copyLayout?: StateBannerCopyLayout;
2661
+ /** Place the action beside the copy or on a separate trailing row. */
2662
+ actionPlacement?: StateBannerActionPlacement;
2631
2663
  className?: string;
2632
2664
  /** Render the title, badge, and detail as unanimated loading skeletons, keeping the icon and tone. The detail line appears only when `detail` is set, as in the live banner. */
2633
2665
  placeholder?: boolean;
2634
2666
  /** Native named-slot assignment when composed inside a web component. */
2635
2667
  slot?: string;
2636
2668
  }
2637
- declare function StateBanner({ title, detail, badge, icon, action, tone, urgency, className, placeholder, slot, }: StateBannerProps): SafeHtml;
2669
+ declare function StateBanner({ title, detail, badge, icon, action, tone, urgency, copyLayout, actionPlacement, className, placeholder, slot, }: StateBannerProps): SafeHtml;
2638
2670
 
2639
- export { StateBanner, type StateBannerProps, type StateBannerTone, type StateBannerUrgency };
2671
+ export { StateBanner, type StateBannerActionPlacement, type StateBannerCopyLayout, type StateBannerProps, type StateBannerTone, type StateBannerUrgency };
2640
2672
  ```
2641
2673
 
2642
2674
  ## `@kerfjs/ui/empty-state`
@@ -3070,6 +3102,7 @@ type TextTone = 'default' | 'quiet' | 'danger';
3070
3102
  type TextSize = 'compact' | 'default' | 'large' | 'xlarge';
3071
3103
  type TextFont = 'default' | 'monospace';
3072
3104
  type TextBorder = 'transparent' | 'none';
3105
+ type TextLineHeight = 'default' | 'tight';
3073
3106
  type TextContent = KerfUiContent | string | number | readonly TextContent[];
3074
3107
  type TextProps = Omit<KerfBaseAttrs, 'children' | 'class' | 'className'> & {
3075
3108
  /** Native heading, paragraph, or inline span element to render. Defaults to `p`. */
@@ -3082,6 +3115,10 @@ type TextProps = Omit<KerfBaseAttrs, 'children' | 'class' | 'className'> & {
3082
3115
  font?: TextFont;
3083
3116
  /** Transparent alignment border or no border when embedded in owner chrome. */
3084
3117
  border?: TextBorder;
3118
+ /** Remove the block variant's item padding and border in compact content. */
3119
+ flush?: boolean;
3120
+ /** Use compact leading for short dialog or metadata copy. */
3121
+ lineHeight?: TextLineHeight;
3085
3122
  children: TextContent;
3086
3123
  class?: string;
3087
3124
  className?: string;
@@ -3091,9 +3128,9 @@ type TextProps = Omit<KerfBaseAttrs, 'children' | 'class' | 'className'> & {
3091
3128
  * content-item padding; `span` adds no box geometry.
3092
3129
  * All ordinary native heading/paragraph attributes pass through to the element.
3093
3130
  */
3094
- declare function Text({ variant: Variant, tone, size, font, border, children, class: classValue, className, ...attributes }: TextProps): kerfjs.SafeHtml;
3131
+ declare function Text({ variant: Variant, tone, size, font, border, flush, lineHeight, children, class: classValue, className, ...attributes }: TextProps): kerfjs.SafeHtml;
3095
3132
 
3096
- export { Text, type TextBorder, type TextContent, type TextFont, type TextProps, type TextSize, type TextTone, type TextVariant };
3133
+ export { Text, type TextBorder, type TextContent, type TextFont, type TextLineHeight, type TextProps, type TextSize, type TextTone, type TextVariant };
3097
3134
  ```
3098
3135
 
3099
3136
  ## `@kerfjs/ui/row`
package/ai/skill.md CHANGED
@@ -203,12 +203,24 @@ Hard rules:
203
203
  16. Keep a visible collapsible pane's collapse control in its own toolbar. When hidden, move its restore control into the adjacent main toolbar on the corresponding logical edge: leading for an inline-start sidebar and trailing for an inline-end inspector. Collapse the pane completely; do not preserve an empty icon-only rail.
204
204
  16a. Dividers between pinned chrome and scrolling content are scroll state, not decoration: a `Toolbar` draws none by default (`dividerSides` is for a permanent edge only). Call `wireScrollDividers(appRoot)` from `@kerfjs/ui/wire-scroll-dividers` once and retain its disposer; every `Pane` then draws the line under its header only while content is scrolled beneath it and over its footer only while more content lies below (never when the content fits), every `NavStack`'s top chrome and bottom toolbar and every `TabScaffold` bar do the same around the active view or scene (keyed on whatever actually scrolls there, including a sole `Pane`'s content), and every `TabBar` marks each side of its strip with tabs scrolled out of view. Configure a pane with `chromeDividers` (`scroll` default, `always`, `none`, also via `PaneConfig`), and a `NavStack` or `TabScaffold` with its own `chromeDividers` (same values: `always` draws the chrome lines without the wiring, `none` never, even when wired; a `SplitView` forwards it through `compactStack`); a `toolbarConfig.dividerSides` edge stays the Toolbar's own. Name app-owned chrome by id in `targets`. The wiring writes only `data-scroll-overflow` / `data-scroll-divider` state; never write a border onto a component to show a divider.
205
205
  17. The only direct children of a `Toolbar` zone (`leading`/`center`/`trailing`) are `ToolbarText` (identity/title text) and `ToolbarControlGroup`; never drop bare buttons, inputs, links, or arbitrary markup straight into a zone. Put identity/title text directly in the zone as `ToolbarText`; wrap interactive controls and icon tiles in `ToolbarControlGroup`. `SegmentedControl`, `Select`, a collapsible `TokenSearchField`, and Web Awesome controls all live inside a group. Configure zone behavior with `Toolbar.centerAlign` and its `responsive` / `responsiveAt` policy instead of selecting toolbar zone classes. No policy clips an action: trailing (and stacked center) zones wrap whole groups onto another row, and the center zone never compresses below its content (a leading title too long for the row truncates with an ellipsis instead), so never hide or shrink a toolbar control to make it fit; use `responsive="wrap"` for a heading whose title must stay whole, and move genuinely lower-priority commands into an app-owned "More" popup menu. For an ordinary icon/action control inside a group, use a plain `<button>` (the group styles `> button` fully) — that is the default; reach for `wa-button` only when you need a Web Awesome feature. A popup menu in a toolbar is a `PopupMenu` (`@kerfjs/ui/popup-menu`, registered once via `@kerfjs/ui/popup-menu/register`) in a `single` group with `nestedDropdown` and a `menuInset`: give it typed `items` (commands with `action`s, `heading`s, `divider`s) and a trigger `icon` plus visible `text` or an accessible `label`; never hand-write `wa-dropdown` / `wa-dropdown-item` markup for a menu. Let the group size that trigger from its icon, localized text, and caret; do not force a width on the menu or button. Nothing wraps inside a group: an icon sits beside its label on one row and a group's controls never break onto a second line — the group sizes to its content, so if it does not fit, the toolbar's `responsive` policy relocates whole groups. A `ToolbarText` is one line ending in an ellipsis by default; opt into `wrap` (capped by `maxLines`) or `ellipsis={false}` deliberately. Inside a group, a `Select` or `PopupMenu` trigger drops its focus ring while its popup is open (the open popup and its current row show where focus is) and the ring returns when the popup closes; a ring follows the control's shape (a pill for an icon-and-caret trigger, a circle for a compact icon button) — set `focusRingOwner="group"` on a Select whose group paints the composed ring, and never add CSS to show, hide, or reshape a ring. For a compact mixed group, keep the standard item padding and raised selected chrome; the selected item paints over the outer border without an internal separator. For an avatar control, set `content="avatar"` and `avatarImage` on the group instead of inserting an `img`: a lone control paints the contained image on the outer group and a multi-button group paints it only on the pressed selection highlight. Compose panel/dialog/page headings with a direct extra-large `ToolbarText`, optional grouped icon, grouped trailing controls, and app-owned supporting copy below. A non-interactive heading icon is an icon tile: put the `LucideIcon` directly in its `ToolbarControlGroup` (it takes an icon button's 40px slot and centers), never inside a `<button>` that does nothing. A group remains 44px outside (`calc(2px + remify(42px))`) when its border/background are transparent; use 8px between groups and inside items. Each zone item sits in the toolbar's top 44px control band, centered by its own size; a taller item (a wrapped title, a second trailing row) starts at the band's top and grows down without moving the others, so a wrapped `ToolbarText` keeps trailing controls beside its first line — do not add alignment CSS for this. Split dormant and interactive regions: `ListHeader` fills the available inline width by default; set `width="content"` to shrink-wrap while retaining its normal geometry, or `inline` when it belongs in surrounding text without outer margin, border, or padding. It keeps its label and mutually exclusive semantic count or non-count `badge` together, with an independent logical-end action unless disclosure mode makes the title cluster the button. Its action visual defaults to 18px through `--kui-list-header-action-icon-size` inside a fitted 36px hover square whose transparent hit layer keeps the pointer target at least 44px (44px wide by the 36px row in `density="compact"`); never shrink the target to match the visual, and never force the button to 44px. Pass every non-negative safe-integer section quantity through `count` with a localized full spoken `countLabel`; never concatenate it into `label` or put a number in `badge`. `ListItem.trailing` is dormant; use `ListActionRow` when primary and trailing actions need sibling native buttons. Its `label`, `icon`, and `trailingActionIcon` slots are also dormant and cannot contain controls. Let panes relocate at narrow widths instead of shrinking targets. Dividers are chrome and earn their place: a `Toolbar` draws none by default, and the line between pinned chrome and scrolling content comes from scroll state (rule 16a), so never add a border, a permanent `dividerSides`, or a margin to fake or adjust one.
206
- 18. When a recurring concept has no matching export or production recipe, keep its semantics in a thin application adapter while reusing the public layout vocabulary. The composer recipe uses one visible form surface, toolbar title/supporting-copy ids, shared 8px field/action gutters, 24px major rhythm, and a conditional StateBanner as its only nested semantic surface; do not turn every section into a card or double-inset intrinsically bordered controls. The application-local `../docs/examples/command-palette-adapter.tsx` is reference source for one such missing concept, not an `@kerfjs/ui` runtime export or catalog recipe. The application owns its registration, ranking, history, permissions, availability, shortcut policy, focus policy, dispatch, and copy. If a missing concept recurs across products, open an upstream component or recipe request.
207
- 19. Compose `ValueTable` from typed `ValueTableRow` entries instead of handwritten `dt`/`dd` wrappers. Pass `icon` for the optional 24px leading visual; the row owns 8px of root-scaled top and bottom padding, the 8px iconless or 40px icon-bearing separator start, and the common 8px right inset.
208
- 20. Use the standard direct `Toolbar` composition for a panel, dialog, or page heading, not a private wrapper or custom heading row. Put an optional icon in a `ToolbarControlGroup`, the title directly in the leading zone as extra-large `ToolbarText`, and actions in a trailing group. Set `headingLevel` for page/section landmarks. Supporting copy stays below the toolbar as app-owned content. The app owns modal behavior, focus, dismissal, command policy, ids, and action handling.
209
- 21. Space with the official five-step scale, picked by how connected two elements are — not by eye. `0` `--kui-space-none` = no separation (one unit); `4px` `--kui-space-2xs` = very minor air on a connected cluster; `8px` `--kui-space-xs` = standard, between elements within a group; `16px` `--kui-space-m` = minor, between homogeneous groups; `24px` `--kui-space-l` = major, between heterogeneous groups (the `.kui-content` rhythm). The 8px-vs-24px distinction is inside-a-group vs between-major-differing-regions. `--kui-space-s` (12px) and `--kui-space-xl` (32px) are off-scale exceptions. For `Row.gap`, `Grid.gap`, or `List.gap`, pass a finite shorthand such as `gap="xs"` or `gap="m"`; use `Spacer` for one intentional typed empty width/height or a flexible main-axis gap. When one token is insufficient, import typed builders from the CSS-free `@kerfjs/ui/css-values` subpath. Preserve property grammar: lengths for gap/Spacer/Skeleton geometry, `flex()` for Row/Grid/List flex, and a foreground color for choice icons: `uiColor()` with a `*-on-*` or text token (`success-on-quiet`, `text-quiet`) or `foregroundColorVar()`. Fill tokens (`*-fill-*`) are backgrounds, not foregrounds, and `SelectChoice.color` rejects them. Never cast between brands or emit raw row `style` declarations. `plus` is not standalone and must be wrapped in `calc`; `remify()` remains source-CSS syntax and is never a runtime prop value. See `docs/layout.md` "Spacing scale".
210
- 22. Pick a whole-screen layout from the opt-in, tree-shakeable subpaths by data + interaction + device, and derive responsiveness from `@kerfjs/ui/device-class`'s `deviceClass()` (`compact` = handset or portrait tablet = one pane at a time). Simple/flat → `NavStack` with one entry (single pane), plus `TabScaffold` (`@kerfjs/ui/tab-scaffold`, iOS bottom tabs, each tab its own `NavStack`) for 2–5 co-equal sections on `compact`; show an unread count on a tab with its `badge` (a number or short string, rendered as the top-trailing danger `Badge` on the icon) plus a localized `badgeLabel` ("3 unread", folded into the tab's name as "Inbox, 3 unread"), never by concatenating the count into `label` or restyling the badge; for new content without a count pass `badge: true` (the text-free dot) with its required `badgeLabel` ("New activity"). Drill-down → `NavStack` (`@kerfjs/ui/nav-stack`), upgrading to `SplitView` (`@kerfjs/ui/split-view`, list-detail) once both panes fit (`atLeast('tablet')` landscape); `SplitView` collapses to a `NavStack` on `compact`. Keep each stack's ordered views controlled; put view-specific bottom chrome on `NavStackView.bottomToolbar` (or use the component-level persistent fallback), then call `wireNavStack` so content slides while the active view's top and bottom chrome cross-fade and focus moves into the new top view/restores on pop. Mark a preferred initial heading or control with `data-nav-focus` when DOM order is not sufficient. The stack's top chrome is a real `Toolbar`: put a view's groups on `NavStackView.leading` / `center` / `toolbar` (trailing), and configure the bar through `toolbarConfig` (`ToolbarConfig` plus `label`, `titleSize`, `headingLevel`) and `backIcon` / `backText`, never with CSS. `SplitView` forwards both of its inner components: `resizable` takes the list `ResizableRegion`'s `separator`, `handleIcon`, `contentOverflow`, and collapse props (`collapsed`, `transitioning`, `collapseMotion`, `restoreControl`, `restorePosition`), and `compactStack` takes the compact stack's `toolbarConfig`, `backIcon`, `backText`, `hideToolbar`, `bottomToolbar`, plus `list` / `detail` view toolbars (`leading`, `center`, `toolbar`, `bottomToolbar`). Complex tool with peripheral panels → `Workbench` (`@kerfjs/ui/workbench`, collapsible rails + drawer) `atLeast('desktop')`, degrading to `NavStack`/overlays below. Workbench panels are fixed-size unless a panel opts in with `resizable` (`true` or `{ min, max }`); then render `size={sizeSignal.value}` and call `wireWorkbench(root, { id, panels: { leftRail: { size: sizeSignal, storageKey? } }, deviceClass })` from `@kerfjs/ui/wire-workbench` for pointer drags, arrow/Shift+arrow/Home/End on the separator, persistence, and no resizing on `compact` classes. Inline rails, fixed or resizable, leave the work area `mainMinSize` px of width (a `Workbench` prop, default 320, `0` off), and an inline bottom drawer leaves it `mainMinHeight` px of height (default 120, `0` off): resizable panels stop growing there, rails shrink in proportion when the Workbench narrows and the drawer when it gets shorter, so do not add your own main-area `min-width` / `min-height`. Rails present as overlays below the `narrow` Workbench container breakpoint (704px) by default — `responsiveOverlayAt: "compact"` moves that to 448px and `"never"` keeps a rail inline — and a bottom drawer opts in the same way; do not derive `presentation` from `deviceClass`, and overlays never resize. At compact widths an overlay rail fills the Workbench less a 44px dismiss strip (`--kui-workbench-overlay-dismiss-margin`) on the side away from its edge; `compactOverlay: "full"` makes one rail fill it. Pass each such panel's `collapsed` signal to `wireWorkbench` too (`panels: { leftRail: { collapsed: navCollapsed } }`, `size` optional) so the overlay is transient like `wireSidebar`'s compact overlay: it collapses when the breakpoint begins to apply (the inline state returns when it ends), takes focus on its first control and keeps Tab inside it while open, and closes on Escape or an outside press with focus returned to its toggle (give each toggle `aria-controls` naming its panel's derived id, `<workbench id>-left-rail` / `-right-rail` / `-bottom-drawer`, so a panel open at wire-up has a focus target too); opening one overlay closes the other open overlays, so they never cover each other's controls; do not hand-roll those listeners (`dismissOverlays: false` opts out of all of it, `exclusiveOverlays: false` of exclusivity only). Collapse stays the app's `collapsed` flag and keeps the size, so an expanded panel returns at its last size. Let the Workbench compose panel toolbars: give each panel `toolbar: { label, title?, leading?, center?, trailing?, toggle: { action, name, showLabel?, hideLabel? } }` and the work area `mainToolbar` (and `mainBottomToolbar` for a drawer). Each of these toolbars takes the `Toolbar`'s configuration (`ToolbarConfig`: `dividerSides`, `centerAlign`, `responsive`, `responsiveAt`, `safeAreaEdges`); configure a composed toolbar through those props (for example `dividerSides: ""` to drop its divider), never with CSS. Configure the composed panes and chrome lists the same way: a panel's `pane` (and `CollapsiblePanel`'s `pane`) and the Workbench's `mainPane` take `PaneConfig` (`contentElement`, `contentLabel`, `separators`, `safeAreaEdges` — for example `{ contentElement: "nav", contentLabel: "Files" }` for a navigator rail), and `mainHeaderList` / `mainFooterList` take `ListConfig` (`gap`, `hAlign`, `vAlign`, `dividerSides`, `textInsets`, `controlInsets`). Open, a panel's toolbar places groups in its leading, center, and trailing zones, with the toggle last; mark a ToolbarControlGroup relocateOnCollapse to keep it available when closed (pass marked groups directly or in arrays rather than JSX fragments); closed, marked groups follow zone order into the work area before the toggle — a left rail's lead `mainToolbar`, a right rail's end it, a drawer's trail `mainBottomToolbar` or float in a corner `FloatingToolbar` — and panel-only groups stay behind. A control sits near where its effect appears: a collapsed drawer's restore belongs in the bottom toolbar or a `FloatingToolbar` beside the drawer, not in a distant top toolbar. Do not hand-place panel toggles in the work-area toolbar or render a second copy, and handle only the toggle's `data-action`. A collapsed panel renders `inert` and `aria-hidden` by itself, on the rail/drawer and its content (its `restoreControl` stays outside and reachable), so do not add your own `tabindex`, `aria-hidden`, or `inert` to hide it. These are declarative (the app owns the stack/selection/collapsed/active state as signals) with disposer-returning `wire…` helpers; each stays out of the barrel, and its CSS-aware browser import loads the layout's CSS plus that of every component it renders (`Pane`, `Toolbar`, `List`, …), so do not hand-import `pane.css` or the other internal stylesheets; the companion `.css` subpath is only for pipelines without the `browser` condition. For a standalone collapsible rail or bottom drawer outside a full shell, use `CollapsiblePanel` + `CollapsiblePanelToggle` (`@kerfjs/ui/collapsible-panel`) with `wireSidebar` (`@kerfjs/ui/wire-sidebar`): the standard collapse animation and per-side icon convention (`PanelLeft*`/`PanelRight*`/`PanelBottom*`) plus toggle, focus, compact overlay, and persistence semantics. Give a standalone panel the same `toolbar` roles and render `CollapsiblePanelRelocated` in your work-area toolbar (first in leading for a left rail, last in trailing for a right rail, a bottom toolbar or a `FloatingToolbar` restoreControl for a drawer) instead of hand-placing a second toggle. A collapsed `CollapsiblePanel`, `ResizableRegion`, or Workbench panel renders `inert` and `aria-hidden` by itself, so do not hide collapsed content yourself either. Likewise an open side overlay (a Workbench rail overlay, a `wireSidebar` compact overlay, an overlay `CollapsiblePanel` or horizontal `ResizableRegion`) hides the covered work area's `FloatingToolbar`s and restore corners by itself until it closes, so do not hide them from overlay state. A compact overlay opens only on a user action: wire-up on a compact device and a wide-to-compact crossing collapse every panel, and a wide crossing restores the inline state. Seed the signal with `signal(device.value.compact)` and pass the panel's `inlineCollapsed` default so the first compact render has no overlay. Dialogs pick the same inner layout, then present per device class (full-screen modal on `compact`, inline on desktop). A list-detail dialog is a Workbench-shaped layout on roomy devices: a full-height list sidebar and a full-height main column, each a `Pane` with its own top `Toolbar`; the main column holds the primary xl title, the close control (`data-dialog="close"` in a `without-header` Web Awesome dialog), and the record actions, never a header spanning both columns. A top-level percentage-height shell needs a definite containing height: opt into `@kerfjs/ui/document.css` and put `.kui-app-root` on the one direct mount container, or provide equivalent application-owned geometry. The global baseline is deliberately absent from `styles.css` and component imports. See `docs/app-layouts.md`, `docs/document-baseline.md`, and `docs/collapsible-panel.md`.
211
- 23. Layouts and `Pane` are safe-area aware without configuration: backgrounds, separators, and dividers paint through a device's unsafe areas (a collapsible rail or drawer grows by the inset it docks to), content is padded only on the sides a region actually reaches, and block insets are scroll padding inside the scroller so first/last content can always be scrolled clear. Interior edges get nothing, and a collapsed rail hands its edge back to the center. Never add your own `env(safe-area-inset-*)` padding around a kerf layout or pane — that double-insets. In an app-owned arrangement of panes, pass `Pane.safeAreaEdges` (the sides that pane reaches; `[]` opts out); give an app bar or bottom bar that sits at a screen edge outside a Pane header or footer `Toolbar.safeAreaEdges` for the sides it reaches (for example `['block-start', 'inline-start', 'inline-end']`); the Workbench `mainToolbar` / `mainBottomToolbar` and panel `toolbar` configurations forward the same `safeAreaEdges` to their `Toolbar`. Do not set the internal `--kui-edge-inset-*` context yourself. The device insets are `--kui-safe-area-*` (defaulting to `env()`), overridable on `:root`. See `docs/app-layouts.md` "Safe areas".
206
+ 18. When a recurring concept has no matching export or production recipe, keep its semantics in a thin application adapter while reusing the public layout vocabulary. The composer recipe uses one visible form surface, toolbar title/supporting-copy ids, shared 8px field/action gutters, 24px major rhythm, and a conditional StateBanner as its only nested semantic surface; do not turn every section into a card or double-inset intrinsically bordered controls. For multi-line banner copy use `copyLayout="stacked"`; use `actionPlacement="below"` for an action on its own trailing row. The application-local `../docs/examples/command-palette-adapter.tsx` is reference source for one such missing concept, not an `@kerfjs/ui` runtime export or catalog recipe. The application owns its registration, ranking, history, permissions, availability, shortcut policy, focus policy, dispatch, and copy. If a missing concept recurs across products, open an upstream component or recipe request.
207
+
208
+ For compact `Select` triggers, set `triggerWidth` to `fit-content`, `max-content`,
209
+ or `fill` and use `--kui-select-trigger-max-width` for a cap. Style custom
210
+ selected content with the public selected color, font-size, and font-weight
211
+ tokens; plain text ellipsizes in a narrow trigger.
212
+
213
+ 19. Compose `ValueTable` from typed `ValueTableRow` entries instead of handwritten `dt`/`dd` wrappers. Pass `icon` for the optional 24px leading visual; the row owns 8px of root-scaled top and bottom padding, the 8px iconless or 40px icon-bearing separator start, and the common 8px right inset. 20. Use the standard direct `Toolbar` composition for a panel, dialog, or page heading, not a private wrapper or custom heading row. Put an optional icon in a `ToolbarControlGroup`, the title directly in the leading zone as extra-large `ToolbarText`, and actions in a trailing group. Set `headingLevel` for page/section landmarks. Supporting copy stays below the toolbar as app-owned content. The app owns modal behavior, focus, dismissal, command policy, ids, and action handling. 21. Space with the official five-step scale, picked by how connected two elements are — not by eye. `0` `--kui-space-none` = no separation (one unit); `4px` `--kui-space-2xs` = very minor air on a connected cluster; `8px` `--kui-space-xs` = standard, between elements within a group; `16px` `--kui-space-m` = minor, between homogeneous groups; `24px` `--kui-space-l` = major, between heterogeneous groups (the `.kui-content` rhythm). The 8px-vs-24px distinction is inside-a-group vs between-major-differing-regions. `--kui-space-s` (12px) and `--kui-space-xl` (32px) are off-scale exceptions. For `Row.gap`, `Grid.gap`, or `List.gap`, pass a finite shorthand such as `gap="xs"` or `gap="m"`; use `Spacer` for one intentional typed empty width/height or a flexible main-axis gap. When one token is insufficient, import typed builders from the CSS-free `@kerfjs/ui/css-values` subpath. Preserve property grammar: lengths for gap/Spacer/Skeleton geometry, `flex()` for Row/Grid/List flex, and a foreground color for choice icons: `uiColor()` with a `*-on-*` or text token (`success-on-quiet`, `text-quiet`) or `foregroundColorVar()`. Fill tokens (`*-fill-*`) are backgrounds, not foregrounds, and `SelectChoice.color` rejects them. Never cast between brands or emit raw row `style` declarations. `plus` is not standalone and must be wrapped in `calc`; `remify()` remains source-CSS syntax and is never a runtime prop value. See `docs/layout.md` "Spacing scale". 22. Pick a whole-screen layout from the opt-in, tree-shakeable subpaths by data + interaction + device, and derive responsiveness from `@kerfjs/ui/device-class`'s `deviceClass()` (`compact` = handset or portrait tablet = one pane at a time). Simple/flat → `NavStack` with one entry (single pane), plus `TabScaffold` (`@kerfjs/ui/tab-scaffold`, iOS bottom tabs, each tab its own `NavStack`) for 2–5 co-equal sections on `compact`; show an unread count on a tab with its `badge` (a number or short string, rendered as the top-trailing danger `Badge` on the icon) plus a localized `badgeLabel` ("3 unread", folded into the tab's name as "Inbox, 3 unread"), never by concatenating the count into `label` or restyling the badge; for new content without a count pass `badge: true` (the text-free dot) with its required `badgeLabel` ("New activity"). Drill-down → `NavStack` (`@kerfjs/ui/nav-stack`), upgrading to `SplitView` (`@kerfjs/ui/split-view`, list-detail) once both panes fit (`atLeast('tablet')` landscape); `SplitView` collapses to a `NavStack` on `compact`. Keep each stack's ordered views controlled; put view-specific bottom chrome on `NavStackView.bottomToolbar` (or use the component-level persistent fallback), then call `wireNavStack` so content slides while the active view's top and bottom chrome cross-fade and focus moves into the new top view/restores on pop. Mark a preferred initial heading or control with `data-nav-focus` when DOM order is not sufficient. The stack's top chrome is a real `Toolbar`: put a view's groups on `NavStackView.leading` / `center` / `toolbar` (trailing), and configure the bar through `toolbarConfig` (`ToolbarConfig` plus `label`, `titleSize`, `headingLevel`) and `backIcon` / `backText`, never with CSS. `SplitView` forwards both of its inner components: `resizable` takes the list `ResizableRegion`'s `separator`, `handleIcon`, `contentOverflow`, and collapse props (`collapsed`, `transitioning`, `collapseMotion`, `restoreControl`, `restorePosition`), and `compactStack` takes the compact stack's `toolbarConfig`, `backIcon`, `backText`, `hideToolbar`, `bottomToolbar`, plus `list` / `detail` view toolbars (`leading`, `center`, `toolbar`, `bottomToolbar`). Complex tool with peripheral panels → `Workbench` (`@kerfjs/ui/workbench`, collapsible rails + drawer) `atLeast('desktop')`, degrading to `NavStack`/overlays below. Workbench panels are fixed-size unless a panel opts in with `resizable` (`true` or `{ min, max }`); then render `size={sizeSignal.value}` and call `wireWorkbench(root, { id, panels: { leftRail: { size: sizeSignal, storageKey? } }, deviceClass })` from `@kerfjs/ui/wire-workbench` for pointer drags, arrow/Shift+arrow/Home/End on the separator, persistence, and no resizing on `compact` classes. Inline rails, fixed or resizable, leave the work area `mainMinSize` px of width (a `Workbench` prop, default 320, `0` off), and an inline bottom drawer leaves it `mainMinHeight` px of height (default 120, `0` off): resizable panels stop growing there, rails shrink in proportion when the Workbench narrows and the drawer when it gets shorter, so do not add your own main-area `min-width` / `min-height`. Rails present as overlays below the `narrow` Workbench container breakpoint (704px) by default — `responsiveOverlayAt: "compact"` moves that to 448px and `"never"` keeps a rail inline — and a bottom drawer opts in the same way; do not derive `presentation` from `deviceClass`, and overlays never resize. At compact widths an overlay rail fills the Workbench less a 44px dismiss strip (`--kui-workbench-overlay-dismiss-margin`) on the side away from its edge; `compactOverlay: "full"` makes one rail fill it. Pass each such panel's `collapsed` signal to `wireWorkbench` too (`panels: { leftRail: { collapsed: navCollapsed } }`, `size` optional) so the overlay is transient like `wireSidebar`'s compact overlay: it collapses when the breakpoint begins to apply (the inline state returns when it ends), takes focus on its first control and keeps Tab inside it while open, and closes on Escape or an outside press with focus returned to its toggle (give each toggle `aria-controls` naming its panel's derived id, `<workbench id>-left-rail` / `-right-rail` / `-bottom-drawer`, so a panel open at wire-up has a focus target too); opening one overlay closes the other open overlays, so they never cover each other's controls; do not hand-roll those listeners (`dismissOverlays: false` opts out of all of it, `exclusiveOverlays: false` of exclusivity only). Collapse stays the app's `collapsed` flag and keeps the size, so an expanded panel returns at its last size. Let the Workbench compose panel toolbars: give each panel `toolbar: { label, title?, leading?, center?, trailing?, toggle: { action, name, showLabel?, hideLabel? } }` and the work area `mainToolbar` (and `mainBottomToolbar` for a drawer). Each of these toolbars takes the `Toolbar`'s configuration (`ToolbarConfig`: `dividerSides`, `centerAlign`, `responsive`, `responsiveAt`, `safeAreaEdges`); configure a composed toolbar through those props (for example `dividerSides: ""` to drop its divider), never with CSS. Configure the composed panes and chrome lists the same way: a panel's `pane` (and `CollapsiblePanel`'s `pane`) and the Workbench's `mainPane` take `PaneConfig` (`contentElement`, `contentLabel`, `separators`, `safeAreaEdges` — for example `{ contentElement: "nav", contentLabel: "Files" }` for a navigator rail), and `mainHeaderList` / `mainFooterList` take `ListConfig` (`gap`, `hAlign`, `vAlign`, `dividerSides`, `textInsets`, `controlInsets`). Open, a panel's toolbar places groups in its leading, center, and trailing zones, with the toggle last; mark a ToolbarControlGroup relocateOnCollapse to keep it available when closed (pass marked groups directly or in arrays rather than JSX fragments); closed, marked groups follow zone order into the work area before the toggle — a left rail's lead `mainToolbar`, a right rail's end it, a drawer's trail `mainBottomToolbar` or float in a corner `FloatingToolbar` — and panel-only groups stay behind. A control sits near where its effect appears: a collapsed drawer's restore belongs in the bottom toolbar or a `FloatingToolbar` beside the drawer, not in a distant top toolbar. Do not hand-place panel toggles in the work-area toolbar or render a second copy, and handle only the toggle's `data-action`. A collapsed panel renders `inert` and `aria-hidden` by itself, on the rail/drawer and its content (its `restoreControl` stays outside and reachable), so do not add your own `tabindex`, `aria-hidden`, or `inert` to hide it. These are declarative (the app owns the stack/selection/collapsed/active state as signals) with disposer-returning `wire…` helpers; each stays out of the barrel, and its CSS-aware browser import loads the layout's CSS plus that of every component it renders (`Pane`, `Toolbar`, `List`, …), so do not hand-import `pane.css` or the other internal stylesheets; the companion `.css` subpath is only for pipelines without the `browser` condition. For a standalone collapsible rail or bottom drawer outside a full shell, use `CollapsiblePanel` + `CollapsiblePanelToggle` (`@kerfjs/ui/collapsible-panel`) with `wireSidebar` (`@kerfjs/ui/wire-sidebar`): the standard collapse animation and per-side icon convention (`PanelLeft*`/`PanelRight*`/`PanelBottom*`) plus toggle, focus, compact overlay, and persistence semantics. Give a standalone panel the same `toolbar` roles and render `CollapsiblePanelRelocated` in your work-area toolbar (first in leading for a left rail, last in trailing for a right rail, a bottom toolbar or a `FloatingToolbar` restoreControl for a drawer) instead of hand-placing a second toggle. A collapsed `CollapsiblePanel`, `ResizableRegion`, or Workbench panel renders `inert` and `aria-hidden` by itself, so do not hide collapsed content yourself either. Likewise an open side overlay (a Workbench rail overlay, a `wireSidebar` compact overlay, an overlay `CollapsiblePanel` or horizontal `ResizableRegion`) hides the covered work area's `FloatingToolbar`s and restore corners by itself until it closes, so do not hide them from overlay state. A compact overlay opens only on a user action: wire-up on a compact device and a wide-to-compact crossing collapse every panel, and a wide crossing restores the inline state. Seed the signal with `signal(device.value.compact)` and pass the panel's `inlineCollapsed` default so the first compact render has no overlay. Dialogs pick the same inner layout, then present per device class (full-screen modal on `compact`, inline on desktop). A list-detail dialog is a Workbench-shaped layout on roomy devices: a full-height list sidebar and a full-height main column, each a `Pane` with its own top `Toolbar`; the main column holds the primary xl title, the close control (`data-dialog="close"` in a `without-header` Web Awesome dialog), and the record actions, never a header spanning both columns. A top-level percentage-height shell needs a definite containing height: opt into `@kerfjs/ui/document.css` and put `.kui-app-root` on the one direct mount container, or provide equivalent application-owned geometry. The global baseline is deliberately absent from `styles.css` and component imports. See `docs/app-layouts.md`, `docs/document-baseline.md`, and `docs/collapsible-panel.md`. 23. Layouts and `Pane` are safe-area aware without configuration: backgrounds, separators, and dividers paint through a device's unsafe areas (a collapsible rail or drawer grows by the inset it docks to), content is padded only on the sides a region actually reaches, and block insets are scroll padding inside the scroller so first/last content can always be scrolled clear. Interior edges get nothing, and a collapsed rail hands its edge back to the center. Never add your own `env(safe-area-inset-*)` padding around a kerf layout or pane — that double-insets. In an app-owned arrangement of panes, pass `Pane.safeAreaEdges` (the sides that pane reaches; `[]` opts out); give an app bar or bottom bar that sits at a screen edge outside a Pane header or footer `Toolbar.safeAreaEdges` for the sides it reaches (for example `['block-start', 'inline-start', 'inline-end']`); the Workbench `mainToolbar` / `mainBottomToolbar` and panel `toolbar` configurations forward the same `safeAreaEdges` to their `Toolbar`. Do not set the internal `--kui-edge-inset-*` context yourself. The device insets are `--kui-safe-area-*` (defaulting to `env()`), overridable on `:root`. See `docs/app-layouts.md` "Safe areas".
214
+
215
+ For application tabs, `AppTab presentation="icon-only"` retains its accessible `name`, `labelMaxWidth` truncates the visible name, and `attention` colors it through `--kui-app-tab-attention-color`. Configure TabBar strip geometry through public `--kui-tab-bar-strip-*` tokens.
216
+
217
+ Use `--kui-resizable-region-background` for a region surface and `contentOverflow="visible"` while its anchored popup needs to escape. Choose a top or bottom `restorePosition`, typed `restoreInset`, or `restorePlacement="inline"` for its collapsed restore control. `FloatingToolbar placement="inline"` stays in normal flow; its per-edge inset tokens and `safeAreaInsets` configure floating placement.
218
+
219
+ Use `ListItem density="spacious"` for larger option rows, `multiline` plus `multilineIconAlign="center"` when its icon should center on wrapped copy, `divider` for row separators, and `state="drag-target"` for the drop target treatment. Public `--kui-list-item-*` tokens adjust row, icon, label, and trailing geometry and color; ListHeader height, title padding, and border tokens adjust section density.
220
+
221
+ Use `Toolbar responsive="trailing-priority"` when an expanded trailing search needs a full second row below its heading at `responsiveAt`. Configure a leading minimum width, trailing gap and justification, or zone inline padding with the public `--kui-toolbar-*` tokens rather than selectors into toolbar zones.
222
+
223
+ For compact dialog copy, use `Text flush lineHeight="tight"`; for compact metadata, use `ValueTable density="compact"` and its public row columns/padding/gap tokens. `ToolbarText size="xsmall"` fits a dense rail heading. A `TokenSearchField` editor shrinks inside a narrow group by default; set `--kui-token-search-editor-min-width` when a minimum is needed. A full-height shell uses the one `.kui-app-root` mount container documented in `docs/document-baseline.md`.
212
224
 
213
225
  Common mistakes:
214
226
 
@@ -1,6 +1,6 @@
1
1
  # Web Awesome JSX signatures for the UI authoring corpus
2
2
 
3
- Generated from the emitted `@kerfjs/ui@5.0.0-beta.59` declaration boundary. Import `@kerfjs/ui/webawesome` for type effects when authoring direct `wa-*` JSX. The module emits no runtime behavior and does not register custom elements.
3
+ Generated from the emitted `@kerfjs/ui@5.0.0-beta.60` declaration boundary. Import `@kerfjs/ui/webawesome` for type effects when authoring direct `wa-*` JSX. The module emits no runtime behavior and does not register custom elements.
4
4
 
5
5
  ```ts
6
6
  import { KerfCustomElement } from 'kerfjs/jsx-runtime';
package/dist/app-tab.d.ts CHANGED
@@ -8,6 +8,7 @@ type AppTabRootAttributes = Readonly<Record<`data-${string}`, string | undefined
8
8
  'data-selected'?: never;
9
9
  'data-tab-dragging'?: never;
10
10
  'data-tab-drop-position'?: never;
11
+ 'data-attention'?: never;
11
12
  }>;
12
13
  type AppTabPresentation = 'pill' | 'segmented' | 'icon-only';
13
14
  type AppTabSize = 'default' | 'compact';
@@ -15,6 +16,8 @@ interface AppTabProps {
15
16
  id: string;
16
17
  name: string;
17
18
  selected?: boolean;
19
+ /** Emphasize the visible tab name with the attention color token. */
20
+ attention?: boolean;
18
21
  closable?: boolean;
19
22
  draggable?: boolean;
20
23
  leading?: KerfUiContent;
@@ -47,6 +50,6 @@ interface AppTabProps {
47
50
  /** Native named-slot assignment when composed inside a web component. */
48
51
  slot?: string;
49
52
  }
50
- declare function AppTab({ id, name, selected, closable, draggable, leading, trailing, presentation, size, labelMaxWidth, closeIcon, selectAction, closeAction, className, placeholder, pending, rootAttributes, slot, }: AppTabProps): SafeHtml;
53
+ declare function AppTab({ id, name, selected, attention, closable, draggable, leading, trailing, presentation, size, labelMaxWidth, closeIcon, selectAction, closeAction, className, placeholder, pending, rootAttributes, slot, }: AppTabProps): SafeHtml;
51
54
 
52
55
  export { AppTab, type AppTabPresentation, type AppTabProps, type AppTabSize };
package/dist/app-tab.js CHANGED
@@ -1,4 +1,4 @@
1
- export { AppTab } from './chunk-WOUF7YXM.js';
1
+ export { AppTab } from './chunk-T66UNBXL.js';
2
2
 
3
3
 
4
4
 
package/dist/catalog.js CHANGED
@@ -1,24 +1,24 @@
1
- import { Workbench } from './chunk-2CCMJTVY.js';
1
+ import { Workbench } from './chunk-2OXQHM7I.js';
2
2
 
3
3
  import { PopupMenu } from './chunk-UWONG4QE.js';
4
4
 
5
5
  import { Row } from './chunk-VZOFZPSO.js';
6
6
  import { ListInsetText } from './chunk-DG6G5EPF.js';
7
- import { ListItem } from './chunk-QOWG4ZCL.js';
7
+ import { ListItem } from './chunk-5I7OHCIP.js';
8
8
  import { List } from './chunk-NAPE7WUS.js';
9
9
 
10
- import { ToolbarText } from './chunk-XDKAYSVD.js';
10
+ import { ToolbarText } from './chunk-3SXMEK3B.js';
11
11
 
12
12
 
13
13
 
14
- import { ListHeader } from './chunk-UX2VVXZ3.js';
15
- import { Text } from './chunk-UXT7TE6B.js';
14
+ import { ListHeader } from './chunk-5Q3N6EV7.js';
15
+ import { Text } from './chunk-AUKT3KMG.js';
16
16
 
17
17
 
18
18
 
19
19
 
20
20
  import { ToolbarControlGroup, ToolbarActionLink } from './chunk-7JUBXOIV.js';
21
- import { Toolbar } from './chunk-6YFHCLHG.js';
21
+ import { Toolbar } from './chunk-MERWRTBG.js';
22
22
 
23
23
  import { LucideIcon } from './chunk-4R777DUZ.js';
24
24
  import { filterDataAttributes } from './chunk-SRSJO5QE.js';
@@ -1,9 +1,9 @@
1
1
  import { WORKBENCH_MAIN_MIN_SIZE, WORKBENCH_MAIN_MIN_HEIGHT, workbenchRegionId, WORKBENCH_RESIZE_DEFAULTS } from './chunk-PSHUSWQH.js';
2
- import { clampRegionSize, ResizeGrip } from './chunk-VHADGP3B.js';
2
+ import { clampRegionSize, ResizeGrip } from './chunk-KLJKU6ZL.js';
3
3
  import { List } from './chunk-NAPE7WUS.js';
4
- import { FloatingToolbar } from './chunk-M7QV3IHH.js';
5
- import { composedPanelBody, relocatedPanelGroups } from './chunk-QPUPLNNB.js';
6
- import { Toolbar } from './chunk-6YFHCLHG.js';
4
+ import { FloatingToolbar } from './chunk-I3Q7KKYM.js';
5
+ import { composedPanelBody, relocatedPanelGroups } from './chunk-T57AXDFM.js';
6
+ import { Toolbar } from './chunk-MERWRTBG.js';
7
7
  import { Pane } from './chunk-EZVNC4J6.js';
8
8
  import { jsxs, jsx, Fragment } from 'kerfjs/jsx-runtime';
9
9
 
@@ -415,4 +415,4 @@ function Workbench({
415
415
 
416
416
  export { Workbench };
417
417
 
418
- //# sourceMappingURL=chunk-2CCMJTVY.js.map
418
+ //# sourceMappingURL=chunk-2OXQHM7I.js.map