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

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 (95) hide show
  1. package/README.md +1 -0
  2. package/ai/component-catalog.json +129 -19
  3. package/ai/component-composition-rules.json +8 -0
  4. package/ai/component-composition.d.ts +10 -0
  5. package/ai/component-composition.json +109 -7
  6. package/ai/component-composition.schema.json +21 -0
  7. package/ai/components/README.md +5 -4
  8. package/ai/components/chip.md +72 -0
  9. package/ai/components/grid.md +10 -7
  10. package/ai/components/list-item.md +10 -7
  11. package/ai/components/select.md +5 -2
  12. package/ai/components/tabs.md +8 -4
  13. package/ai/components/toolbar.md +3 -2
  14. package/ai/public-api-signatures-v1.md +90 -14
  15. package/ai/skill.md +21 -3
  16. package/ai/webawesome-jsx-signatures-v1.md +1 -1
  17. package/dist/app-tab.d.ts +12 -2
  18. package/dist/app-tab.js +1 -1
  19. package/dist/browser/chip.js +3 -0
  20. package/dist/catalog.js +6 -6
  21. package/dist/chip.d.ts +29 -0
  22. package/dist/chip.js +3 -0
  23. package/dist/chip.js.map +1 -0
  24. package/dist/{chunk-F7F7KRO2.js → chunk-4SQK27MR.js} +33 -18
  25. package/dist/chunk-4SQK27MR.js.map +1 -0
  26. package/dist/{chunk-46263QLK.js → chunk-C4OYOKWX.js} +18 -6
  27. package/dist/chunk-C4OYOKWX.js.map +1 -0
  28. package/dist/chunk-EAC4CDY7.js +57 -0
  29. package/dist/chunk-EAC4CDY7.js.map +1 -0
  30. package/dist/{chunk-T57AXDFM.js → chunk-NYL63PSD.js} +2 -2
  31. package/dist/{chunk-T57AXDFM.js.map → chunk-NYL63PSD.js.map} +1 -1
  32. package/dist/{chunk-T66UNBXL.js → chunk-Q6YU3BT7.js} +11 -2
  33. package/dist/chunk-Q6YU3BT7.js.map +1 -0
  34. package/dist/chunk-SWVW56CV.js +188 -0
  35. package/dist/chunk-SWVW56CV.js.map +1 -0
  36. package/dist/{chunk-WPLIO5WJ.js → chunk-TEYARRAK.js} +37 -5
  37. package/dist/chunk-TEYARRAK.js.map +1 -0
  38. package/dist/{chunk-AGXQQFKZ.js → chunk-UCKKT6KO.js} +13 -4
  39. package/dist/chunk-UCKKT6KO.js.map +1 -0
  40. package/dist/{chunk-UWONG4QE.js → chunk-VCBTX62E.js} +11 -3
  41. package/dist/chunk-VCBTX62E.js.map +1 -0
  42. package/dist/{chunk-2OXQHM7I.js → chunk-Y74NWGQW.js} +3 -3
  43. package/dist/{chunk-2OXQHM7I.js.map → chunk-Y74NWGQW.js.map} +1 -1
  44. package/dist/collapsible-panel.js +2 -2
  45. package/dist/grid.d.ts +13 -5
  46. package/dist/grid.js +1 -1
  47. package/dist/index.d.ts +4 -3
  48. package/dist/index.js +14 -13
  49. package/dist/list-item.d.ts +11 -1
  50. package/dist/list-item.js +1 -1
  51. package/dist/popup-menu.d.ts +2 -2
  52. package/dist/popup-menu.js +1 -1
  53. package/dist/select-register.js +46 -0
  54. package/dist/select-register.js.map +1 -1
  55. package/dist/select.d.ts +14 -0
  56. package/dist/select.js +1 -1
  57. package/dist/styles/app-tab.css +35 -0
  58. package/dist/styles/chip.css +118 -0
  59. package/dist/styles/grid.css +7 -0
  60. package/dist/styles/list-item.css +14 -9
  61. package/dist/styles/popup-menu.css +2 -1
  62. package/dist/styles/segmented-control.css +2 -1
  63. package/dist/styles/select.css +30 -0
  64. package/dist/styles/styles.css +1 -0
  65. package/dist/styles/toolbar.css +8 -5
  66. package/dist/{token-search-field-CCke1yvQ.d.ts → token-search-field-DvgFLhLL.d.ts} +6 -2
  67. package/dist/token-search-field.d.ts +1 -1
  68. package/dist/token-search-model.d.ts +1 -1
  69. package/dist/token-search-model.js +1 -1
  70. package/dist/wire-catalog.js +1 -1
  71. package/dist/wire-tab-bars.js +1 -1
  72. package/dist/wire-token-search-fields.d.ts +1 -1
  73. package/dist/workbench.js +1 -1
  74. package/docs/accessibility.md +29 -3
  75. package/docs/component-contract.md +5 -0
  76. package/docs/component-selection.md +66 -4
  77. package/docs/design/templates/segmented-control/equal-dark.svg +1 -1
  78. package/docs/design/templates/segmented-control/equal.svg +1 -1
  79. package/docs/design/templates/segmented-control/pill-small-dark.svg +1 -1
  80. package/docs/design/templates/segmented-control/pill-small.svg +1 -1
  81. package/docs/design/templates/segmented-control-dark.svg +1 -1
  82. package/docs/design/templates/segmented-control.svg +1 -1
  83. package/docs/layout.md +20 -9
  84. package/docs/sunken-panel.md +5 -0
  85. package/docs/webawesome-theme.md +32 -0
  86. package/llms.txt +36 -8
  87. package/package.json +7 -1
  88. package/dist/chunk-46263QLK.js.map +0 -1
  89. package/dist/chunk-5I7OHCIP.js +0 -96
  90. package/dist/chunk-5I7OHCIP.js.map +0 -1
  91. package/dist/chunk-AGXQQFKZ.js.map +0 -1
  92. package/dist/chunk-F7F7KRO2.js.map +0 -1
  93. package/dist/chunk-T66UNBXL.js.map +0 -1
  94. package/dist/chunk-UWONG4QE.js.map +0 -1
  95. package/dist/chunk-WPLIO5WJ.js.map +0 -1
@@ -72,6 +72,8 @@ import { Row } from "@kerfjs/ui/row";
72
72
  ```
73
73
 
74
74
  `CssValue` is the common branded base, not an arbitrary-string constructor.
75
+ For a responsive equal-width form, pass `Grid minColumnWidth={px(376)}` instead
76
+ of `columns`; the Grid's container width decides when the tracks collapse.
75
77
  Raw strings such as `"0.25rem"` do not satisfy `Row.gap`, `Grid.gap`, or `List.gap`; this
76
78
  contract lands before the 5.0 stable release so misspelled tokens and incomplete
77
79
  expressions fail during typechecking rather than in the browser.
@@ -141,7 +143,7 @@ an upstream component or recipe request.
141
143
  | Toolbar identity text — `ToolbarText` | A toolbar needs extra-large (page/panel title), large, default, or compact textual identity. | Plain text is not a heading by default; when a title needs heading semantics pass `headingLevel`. Sizes below `xlarge` are intentionally quiet identity text with no tone option — do not use them as a normal-color subsection title; use `Text` with an `h2`–`h6` variant, or `ListHeader` for a list section. | Optional `headingLevel` for `role="heading"` + `aria-level`. Defaults to one line, ellipsized when it does not fit; `wrap` flows onto multiple lines, `ellipsis` toggles the trailing …, and `maxLines` caps a wrap. | Text, heading level, overflow behavior, and responsive priority. | `@kerfjs/ui/toolbar-text` | [Toolbar composition](../README.md#component-subpaths) |
142
144
  | Semantic block or inline text — `Text` | Ordinary application copy needs native `h1`–`h6` or `p` semantics plus standard geometry, or inline secondary copy needs a native `span` without box geometry. | Do not choose heading levels for appearance alone or recreate muted, error, small, or code utility classes. Use `ToolbarText` for toolbar identity/title content and `ListInsetText` when list-aligned prose needs full margin/border/padding geometry. | Omit `variant` for the default `p`, choose `h1`–`h6` from the document outline, or choose `span` inside a row, label, or table cell. Independently compose `tone="quiet | danger"`, `size="compact"`, and `font="monospace"`; ordinary native global, `data-_`, and `aria-_` attributes pass through. | Copy, localization, semantic variant, presentation roles, and document heading hierarchy. | `@kerfjs/ui/text` | [Text](./layout.md#text) |
143
145
  | Vertical stack — `List` | Rows, sections, or arbitrary components need a consistent vertical stretch layout, optional standard/custom gap, flex growth, one vertical scroll owner, or edge dividers. | It is layout-only and does not provide `ul`/`ol` semantics. Do not nest scroll owners or use it when a horizontal layout is required. | Choose `gap`, `flex`, `scrollable`, and canonical `dividerSides` (`t`, `r`, `b`, `l` combinations in that order); bound the block size when scrolling. | Child semantics/content, containing height, and which optional layout behaviors apply. | `@kerfjs/ui/list` | [Pane geometry](../README.md#pane-and-content-geometry) |
144
- | Equal-width columns — `Grid` | A fixed positive number of sibling columns must divide the available width evenly, including when child content has different intrinsic widths. | Do not use it for intrinsic, asymmetric, spanning, auto-fit, or masonry tracks; use application-owned CSS grid. Do not use it for a user-operable separator; use `ResizableRegion`. | Choose `columns`, a typed `gap`, and optional typed `flex`; preserve source order when the app changes the count responsively. | Child semantics/content, the column count and responsive policy, and typed gap/flex choices. | `@kerfjs/ui/grid` | [Grid](./layout.md#grid) |
146
+ | Equal-width columns — `Grid` | Equal-width sibling columns need a fixed count or should collapse as their container narrows, while preserving equal tracks despite intrinsic child widths. | Do not use it for intrinsic, asymmetric, spanning, or masonry tracks; use application-owned CSS grid. Do not use it for a user-operable separator; use `ResizableRegion`. | Choose fixed `columns` or typed `minColumnWidth`, plus a typed `gap` and optional `flex`; responsive tracks preserve source order. | Child semantics/content, outer width, fixed count or minimum width, and typed gap/flex choices. | `@kerfjs/ui/grid` | [Grid](./layout.md#grid) |
145
147
  | Navigation row — `ListItem` | A pane or navigation area needs a selectable, disabled, dormant-trailing, or multiline action row. | Do not put a control in `trailing`; use `ListActionRow` when the trailing region must be independently interactive. Use an `<a>` for navigation that must retain link behavior, a native `<button>` for an ordinary action, or implement the complete ARIA menu widget. | Delegate its `data-action`; compose inside a `.kui-content` section. Put domain event/drop metadata in `rootAttributes` rather than adding wrapper markup. The rounded root clips overflowing descendants; set `multiline` when the primary label should wrap. | Routing, selection, permissions, copy, action handling, and domain `data-*` values. | `@kerfjs/ui/list-item` | [Pane geometry](../README.md#pane-and-content-geometry) |
146
148
  | Navigation row with trailing action — `ListActionRow` | A full-width row needs a selectable primary action and an independently focusable trailing action. | Use `ListItem` when trailing content is dormant metadata. Do not put controls inside the row's `label`, `icon`, or `trailingActionIcon` SafeHtml slots. Do not use `AppTab` outside tablist semantics or `ToolbarControlGroup` outside a toolbar. | Delegate both action strings; update controlled selection and any popover/context-menu state in the app. | Routing, selection, both action policies, domain metadata, and popover/context-menu behavior. | `@kerfjs/ui/list-action-row` | [Accessibility](./accessibility.md#listactionrow) |
147
149
  | Navigation section heading — `ListHeader` | A menu section needs a full-width label, semantic count, non-count badge, logical-end action, or real disclosure state. | Do not concatenate counts into `label` or put numeric content in `badge`; use `count` with the localized full phrase in `countLabel`. Do not add a disclosure arrow to navigation that reveals nothing. Keep its 44px hit target; do not resize its 36px square. Do not use it as a page, panel, or dialog title; use a heading `Toolbar`. | Delegate its optional action; the app controls expanded state and revealed content. Toggle mode supplies `DisclosureArrow` unless `actionIcon` replaces it. Use `triggerAttributes` only for domain `data-*` or a native popover relationship. | Section organization, valid count and localized count label, disclosure state and content, non-count badge content, popover target behavior, and policy. | `@kerfjs/ui/list-header` | [Pane geometry](../README.md#pane-and-content-geometry) |
@@ -194,6 +196,18 @@ whole label. `divider` owns a before or after separator. Set
194
196
  `--kui-list-item-*` tokens control its row, icon, label, and trailing geometry
195
197
  and color. `ListHeader` exposes `--kui-list-header-min-height`, title padding,
196
198
  title minimum height, and border-width tokens for section density.
199
+ For a filled command list, set `--kui-list-item-background` and
200
+ `--kui-list-item-border` on the list or row. The matching
201
+ `--kui-list-item-hover-border` and `--kui-list-item-selected-border` tokens
202
+ set state outlines without replacing ListItem CSS or neutralizing global
203
+ semantic border colors.
204
+
205
+ Use `ListItemLink` from `@kerfjs/ui/list-item` for a navigation row with a
206
+ real `href`. It shares `ListItem` content slots, density, selection, and row
207
+ geometry while rendering a native anchor. `external` opens a new tab with
208
+ `noopener noreferrer` and announces that behavior in the default accessible
209
+ name. Disabled and loading links omit `href` and leave the tab order. Use
210
+ `ListItem` for an application action dispatched through `action`.
197
211
 
198
212
  Use `Toolbar responsive="trailing-priority"` for a collapsible search in the
199
213
  trailing zone that should take a full second row when expanded. `responsiveAt`
@@ -202,6 +216,10 @@ in the first row. `--kui-toolbar-leading-min-width`,
202
216
  `--kui-toolbar-trailing-gap`, `--kui-toolbar-trailing-justify`, and the
203
217
  `--kui-toolbar-*-padding-inline` zone tokens adjust local geometry without
204
218
  selecting toolbar anatomy from application CSS.
219
+ Set `--kui-toolbar-inset: 0px` on an embedded Toolbar that should have no outer
220
+ padding while keeping its `--kui-toolbar-gap` between control zones. The token
221
+ also reduces its minimum height by the removed inset; safe-area compensation
222
+ still adds to the chosen inset on claimed edges.
205
223
 
206
224
  For compact dialog copy, use `Text flush lineHeight="tight"`; block Text still
207
225
  resets native margins. `ValueTable density="compact"` reduces row padding and
@@ -217,10 +235,18 @@ required.
217
235
 
218
236
  Use `AppTab presentation="icon-only"` with its `name` kept as the accessible
219
237
  tab name, and `labelMaxWidth` for an ellipsized visible name. Set `attention`
220
- to color a tab's name with `--kui-app-tab-attention-color`. A `TabBar` owns its
238
+ to color a tab's name with `--kui-app-tab-attention-color`. Set `dropTarget`
239
+ while an app drag is over a tab's content; the tab keeps its selection semantics
240
+ and uses the `--kui-app-tab-drop-target-*` tokens for its highlight. Set
241
+ `nameOverflow="visible"` when an inline loading treatment needs the full name
242
+ instead of the default ellipsis. A `TabBar` owns its
221
243
  scrolling strip; its public `--kui-tab-bar-strip-*` tokens configure strip
222
244
  height, spacing, border, radius, background, and scroll inset without styling
223
245
  its internal classes. `--kui-tab-bar-trailing-flex` controls the trailing zone.
246
+ Set `pinned` on the first `AppTab` when that tab must remain visible as peers
247
+ scroll. It stays inside the tablist and keyboard order. Set the public
248
+ `--kui-app-tab-pinned-background` token if the surrounding surface differs from
249
+ the default; the pinned tab must cover peers as they scroll beneath it.
224
250
 
225
251
  - `StateBanner` persists beside affected work; `EmptyState` replaces absent content; `wa-callout` is contextual ecosystem content; `wa-toast` and `wa-toast-item` are transient and must not carry the only copy of important state.
226
252
 
@@ -237,6 +263,13 @@ Custom `renderSelected` text inherits the control color by default; the
237
263
  `--kui-select-selected-font-weight` tokens configure its typography. Plain
238
264
  selected text stays on one ellipsized line when the trigger narrows.
239
265
 
266
+ For an unavailable entry, set `SelectChoice.disabled` and optionally
267
+ `disabledReason`; the option stays visible but cannot be chosen. A multiple
268
+ `Select` can opt in to `selectAllLabel` and `clearLabel` footer buttons.
269
+ Select all includes only enabled choices, Clear removes the selection, and
270
+ both report changes through the normal `input` and `change` events. The app
271
+ still owns the controlled `value` and localized action labels.
272
+
240
273
  - `ResizableRegion` is an interactive controlled pane. `Grid` is the right answer for static equal-width columns; application CSS grid remains the answer for asymmetric or intrinsic tracks.
241
274
  - A `ResizableRegion`'s content spans the whole region, like its separator. Give
242
275
  it one child — normally a `Pane` — and that child fills the region, so the
@@ -271,6 +304,9 @@ selected text stays on one ellipsized line when the trigger narrows.
271
304
  - `TokenSearchField` is a structured editor. A native input or `wa-input` is the right answer for ordinary text.
272
305
 
273
306
  For common structured search, use `createTokenSearchModel` from `@kerfjs/ui/token-search-model`, pass the model to `TokenSearchField`, and register it under the field id in `wireTokenSearchFields(root, { models })`. Rules parse `name:value` expressions and provide suggestions; the model owns chips, selection, removal, clear, and an optional evaluation result. Omit `model` and `models` for full manual control.
307
+ `TokenSearchRule.suggest(input, state)` receives the unfinished value and current committed tokens, so a rule can omit values already selected. Existing one-argument suggestion callbacks continue to work.
308
+ For a sibling date picker or other app helper, call `model.commit(value)` while a `name:` prefix is active. It parses and commits that value for the active rule even when it is absent from suggestions, replacing the unfinished prefix text. Invalid values and calls without an active prefix leave the query unchanged; `choose(value)` remains restricted to suggested tokens.
309
+ To apply a saved search or restore a query programmatically, call `model.replace({ query, tokens })`. It publishes parsed state and rebuilds the DOM-owned editor text even when no chip changed. For a field without a model, change the field's `revision` prop when setting `query` yourself.
274
310
  When one root contains both kinds of field, a registered model enables chip keyboard behavior only for its own field. Other fields keep native editing unless the root opts into `keyboard` with an application removal callback.
275
311
 
276
312
  ## Toolbar composition
@@ -338,7 +374,8 @@ menu.
338
374
 
339
375
  Nested decisions use an item with `submenu`. Children keep their own actions,
340
376
  `attributes` metadata, icons, `checked` state, disabled state and
341
- `disabledReason` tooltip. `tone: 'danger'` maps to the Web Awesome destructive
377
+ `disabledReason` tooltip. Nested `heading` and `divider` entries group those
378
+ commands without entering keyboard navigation. `tone: 'danger'` maps to the Web Awesome destructive
342
379
  variant. A parent can sit among ordinary commands and dividers, so the same
343
380
  items shape covers single-line and batch actions; compute each batch child's
344
381
  `disabled` state from the current selection.
@@ -349,8 +386,11 @@ items shape covers single-line and batch actions; compute each batch child's
349
386
  items={[
350
387
  { label: 'Copy reference', action: 'copy-reference', attributes: { 'data-item-id': lineId } },
351
388
  { label: 'Decide', submenu: [
389
+ { kind: 'heading', label: 'Review' },
352
390
  { label: 'Approve', action: 'decide', checked: current === 'approve', attributes: { 'data-item-id': lineId, 'data-decision': 'approve' } },
353
391
  { label: 'Reject', action: 'decide', tone: 'danger', disabled: needsPrice, disabledReason: needsPrice ? 'Add a price first' : undefined, attributes: { 'data-item-id': lineId, 'data-decision': 'reject' } },
392
+ { kind: 'divider' },
393
+ { label: 'Other…', action: 'choose-other' },
354
394
  ] },
355
395
  { kind: 'divider' },
356
396
  { label: 'Remove', action: 'remove', tone: 'danger' },
@@ -421,6 +461,28 @@ forks the package anatomy and spacing contract.
421
461
  </aside>
422
462
  ```
423
463
 
464
+ ## Removable tags
465
+
466
+ Use `Chip` when a short tag has a remove action. `removeAction` becomes the
467
+ native button's `data-action`; `removeLabel` must name the specific tag for
468
+ assistive technology. Use `itemId` for the application's delegated handler.
469
+ The application updates its tag list after the action. `size="compact"` uses a
470
+ 20px chip with a 16px remove button, and `disabled` disables removal. Tone,
471
+ appearance, and shape use the same semantic choices as `Badge`; use `Badge`
472
+ when no removal is needed and the content is status or count metadata.
473
+
474
+ ```tsx
475
+ <Chip
476
+ size="compact"
477
+ tone="brand"
478
+ itemId={tag.id}
479
+ removeAction="remove-tag"
480
+ removeLabel={`Remove ${tag.name} tag`}
481
+ >
482
+ {tag.name}
483
+ </Chip>
484
+ ```
485
+
424
486
  ## Web Awesome overlap policy
425
487
 
426
488
  Web Awesome catalog coverage means supported and themed, not preferred. Import
@@ -437,7 +499,7 @@ replaces it (`PopupMenu` renders `wa-dropdown`; `Select` renders `wa-select` /
437
499
  | ------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
438
500
  | `wa-button`, `wa-dropdown`, `wa-dropdown-item` | Use buttons for actions and `PopupMenu` for a command menu, never raw dropdown markup. Use `ListItem` for a navigation row and `Select` for a value. |
439
501
  | `wa-button-group` | Use only for exceptional grouped actions; use `SegmentedControl` for one-of-many selection. |
440
- | `wa-input`, `wa-tag` | Use for ordinary text and tags; use `TokenSearchField` only when text and ordered filter tokens form one editor. |
502
+ | `wa-input`, `wa-tag` | Use `Chip` for removable or disabled tags; use `TokenSearchField` only when text and ordered filter tokens form one editor. |
441
503
  | `wa-select`, `wa-option` | Use `Select`, which owns Kerf spacing, controlled rendering, icon stability, and explicit registration. |
442
504
  | `wa-tab-group`, `wa-tab`, `wa-tab-panel` | Use `TabBar`/`AppTab` for application tabs or `SegmentedControl` for compact local views. |
443
505
  | `wa-icon` | Use `LucideIcon` in application UI. |
@@ -1 +1 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 460 88" width="460" height="88"><defs><clipPath id="cp0"><rect x="20" y="20" width="210.3" height="44"/></clipPath><clipPath id="ov1"><rect x="21" y="21" width="208.3" height="42" rx="11"/></clipPath><filter id="sh2" x="-50%" y="-50%" width="200%" height="200%"><feGaussianBlur stdDeviation="1.5"/></filter><clipPath id="ct3"><rect x="38.7" y="36" width="35.3" height="12"/></clipPath><clipPath id="ct4"><rect x="114.1" y="36" width="22" height="12"/></clipPath><clipPath id="ct5"><rect x="168.5" y="36" width="50.8" height="12"/></clipPath></defs><g clip-path="url(#cp0)"><rect x="20" y="20" width="210.3" height="44" rx="12" fill="rgb(58,58,60)"/><rect x="20.5" y="20.5" width="209" height="43" rx="11.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/></g><g clip-path="url(#cp0)"><g clip-path="url(#ov1)"><rect x="22" y="23" width="68.8" height="40" rx="10" fill="rgba(0,0,0,0.5)" filter="url(#sh2)"/><rect x="22" y="22" width="68.8" height="40" rx="10" fill="rgb(28,28,30)"/><rect x="22.5" y="22.5" width="68" height="39" rx="9.5" fill="none" stroke="rgb(72,72,74)" stroke-width="1"/><text x="38.7" y="46" font-family="system-ui, &quot;-apple-system&quot;, sans-serif" font-size="12" font-weight="650" fill="rgb(138,203,255)">Board</text><rect x="91.5" y="22.5" width="68" height="39" rx="9.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><text x="114.13" y="46" font-family="system-ui, &quot;-apple-system&quot;, sans-serif" font-size="12" font-weight="650" fill="rgb(174,174,178)">List</text><rect x="160.5" y="22.5" width="67" height="39" rx="9.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><text x="168.5" y="46" font-family="system-ui, &quot;-apple-system&quot;, sans-serif" font-size="12" font-weight="650" fill="rgb(174,174,178)">Timeline</text></g></g></svg>
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 460 88" width="460" height="88"><defs><clipPath id="cp0"><rect x="20" y="20" width="210.3" height="44"/></clipPath><clipPath id="ov1"><rect x="21" y="21" width="208.3" height="42" rx="11"/></clipPath><filter id="sh2" x="-50%" y="-50%" width="200%" height="200%"><feGaussianBlur stdDeviation="1.5"/></filter><clipPath id="ct3"><rect x="38.7" y="36" width="35.3" height="12"/></clipPath><clipPath id="ct4"><rect x="114.1" y="36" width="22" height="12"/></clipPath><clipPath id="ct5"><rect x="168.5" y="36" width="50.8" height="12"/></clipPath></defs><g clip-path="url(#cp0)"><rect x="20" y="20" width="210.3" height="44" rx="12" fill="rgb(58,58,60)"/><rect x="20.5" y="20.5" width="209" height="43" rx="11.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/></g><g clip-path="url(#cp0)"><g clip-path="url(#ov1)"><rect x="22" y="23" width="68.8" height="40" rx="10" fill="rgba(0,0,0,0.5)" filter="url(#sh2)"/><rect x="22" y="22" width="68.8" height="40" rx="10" fill="rgb(28,28,30)"/><rect x="22.5" y="22.5" width="68" height="39" rx="9.5" fill="none" stroke="rgb(72,72,74)" stroke-width="1"/><text x="38.7" y="46" font-family="system-ui, &quot;-apple-system&quot;, sans-serif" font-size="12" font-weight="650" fill="rgb(138,203,255)">Board</text><rect x="91.5" y="22.5" width="68" height="39" rx="9.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><text x="114.13" y="46" font-family="system-ui, &quot;-apple-system&quot;, sans-serif" font-size="12" font-weight="650" fill="rgb(245,245,247)">List</text><rect x="160.5" y="22.5" width="67" height="39" rx="9.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><text x="168.5" y="46" font-family="system-ui, &quot;-apple-system&quot;, sans-serif" font-size="12" font-weight="650" fill="rgb(245,245,247)">Timeline</text></g></g></svg>
@@ -1 +1 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 460 88" width="460" height="88"><defs><clipPath id="cp0"><rect x="20" y="20" width="210.3" height="44"/></clipPath><clipPath id="ov1"><rect x="21" y="21" width="208.3" height="42" rx="11"/></clipPath><filter id="sh2" x="-50%" y="-50%" width="200%" height="200%"><feGaussianBlur stdDeviation="1.5"/></filter><clipPath id="ct3"><rect x="38.7" y="36" width="35.3" height="12"/></clipPath><clipPath id="ct4"><rect x="114.1" y="36" width="22" height="12"/></clipPath><clipPath id="ct5"><rect x="168.5" y="36" width="50.8" height="12"/></clipPath></defs><g clip-path="url(#cp0)"><rect x="20" y="20" width="210.3" height="44" rx="12" fill="rgb(229,229,234)"/><rect x="20.5" y="20.5" width="209" height="43" rx="11.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/></g><g clip-path="url(#cp0)"><g clip-path="url(#ov1)"><rect x="22" y="23" width="68.8" height="40" rx="10" fill="rgba(0,0,0,0.14)" filter="url(#sh2)"/><rect x="22" y="22" width="68.8" height="40" rx="10" fill="rgb(255,255,255)"/><rect x="22.5" y="22.5" width="68" height="39" rx="9.5" fill="none" stroke="rgb(209,209,214)" stroke-width="1"/><text x="38.7" y="46" font-family="system-ui, &quot;-apple-system&quot;, sans-serif" font-size="12" font-weight="650" fill="rgb(12,98,243)">Board</text><rect x="91.5" y="22.5" width="68" height="39" rx="9.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><text x="114.13" y="46" font-family="system-ui, &quot;-apple-system&quot;, sans-serif" font-size="12" font-weight="650" fill="rgb(110,110,115)">List</text><rect x="160.5" y="22.5" width="67" height="39" rx="9.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><text x="168.5" y="46" font-family="system-ui, &quot;-apple-system&quot;, sans-serif" font-size="12" font-weight="650" fill="rgb(110,110,115)">Timeline</text></g></g></svg>
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 460 88" width="460" height="88"><defs><clipPath id="cp0"><rect x="20" y="20" width="210.3" height="44"/></clipPath><clipPath id="ov1"><rect x="21" y="21" width="208.3" height="42" rx="11"/></clipPath><filter id="sh2" x="-50%" y="-50%" width="200%" height="200%"><feGaussianBlur stdDeviation="1.5"/></filter><clipPath id="ct3"><rect x="38.7" y="36" width="35.3" height="12"/></clipPath><clipPath id="ct4"><rect x="114.1" y="36" width="22" height="12"/></clipPath><clipPath id="ct5"><rect x="168.5" y="36" width="50.8" height="12"/></clipPath></defs><g clip-path="url(#cp0)"><rect x="20" y="20" width="210.3" height="44" rx="12" fill="rgb(229,229,234)"/><rect x="20.5" y="20.5" width="209" height="43" rx="11.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/></g><g clip-path="url(#cp0)"><g clip-path="url(#ov1)"><rect x="22" y="23" width="68.8" height="40" rx="10" fill="rgba(0,0,0,0.14)" filter="url(#sh2)"/><rect x="22" y="22" width="68.8" height="40" rx="10" fill="rgb(255,255,255)"/><rect x="22.5" y="22.5" width="68" height="39" rx="9.5" fill="none" stroke="rgb(209,209,214)" stroke-width="1"/><text x="38.7" y="46" font-family="system-ui, &quot;-apple-system&quot;, sans-serif" font-size="12" font-weight="650" fill="rgb(12,98,243)">Board</text><rect x="91.5" y="22.5" width="68" height="39" rx="9.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><text x="114.13" y="46" font-family="system-ui, &quot;-apple-system&quot;, sans-serif" font-size="12" font-weight="650" fill="rgb(29,29,31)">List</text><rect x="160.5" y="22.5" width="67" height="39" rx="9.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><text x="168.5" y="46" font-family="system-ui, &quot;-apple-system&quot;, sans-serif" font-size="12" font-weight="650" fill="rgb(29,29,31)">Timeline</text></g></g></svg>
@@ -1 +1 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 460 88" width="460" height="88"><defs><clipPath id="cp0"><rect x="20" y="20" width="141.4" height="44"/></clipPath><clipPath id="ov1"><rect x="21" y="21" width="139.4" height="42" rx="21"/></clipPath><clipPath id="ct2"><rect x="31.5" y="36.5" width="21.1" height="11"/></clipPath><filter id="sh3" x="-50%" y="-50%" width="200%" height="200%"><feGaussianBlur stdDeviation="1.5"/></filter><clipPath id="ct4"><rect x="70" y="36.5" width="30.3" height="11"/></clipPath><clipPath id="ct5"><rect x="116.3" y="36.5" width="35.1" height="11"/></clipPath></defs><g clip-path="url(#cp0)"><rect x="20" y="20" width="141.4" height="44" rx="22" fill="rgb(58,58,60)"/><rect x="20.5" y="20.5" width="140" height="43" rx="21.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><g clip-path="url(#ov1)"><rect x="22.5" y="22.5" width="39" height="39" rx="19.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><text x="31.47" y="46.5" font-family="system-ui, &quot;-apple-system&quot;, sans-serif" font-size="11" font-weight="650" fill="rgb(174,174,178)">Day</text><rect x="62" y="23" width="46.3" height="40" rx="20" fill="rgba(0,0,0,0.5)" filter="url(#sh3)"/><rect x="62" y="22" width="46.3" height="40" rx="20" fill="rgb(28,28,30)"/><rect x="62.5" y="22.5" width="45" height="39" rx="19.5" fill="none" stroke="rgb(72,72,74)" stroke-width="1"/><text x="70" y="46.5" font-family="system-ui, &quot;-apple-system&quot;, sans-serif" font-size="11" font-weight="650" fill="rgb(138,203,255)">Week</text><rect x="108.5" y="22.5" width="50" height="39" rx="19.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><text x="116.28" y="46.5" font-family="system-ui, &quot;-apple-system&quot;, sans-serif" font-size="11" font-weight="650" fill="rgb(174,174,178)">Month</text></g></g></svg>
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 460 88" width="460" height="88"><defs><clipPath id="cp0"><rect x="20" y="20" width="141.4" height="44"/></clipPath><clipPath id="ov1"><rect x="21" y="21" width="139.4" height="42" rx="21"/></clipPath><clipPath id="ct2"><rect x="31.5" y="36.5" width="21.1" height="11"/></clipPath><filter id="sh3" x="-50%" y="-50%" width="200%" height="200%"><feGaussianBlur stdDeviation="1.5"/></filter><clipPath id="ct4"><rect x="70" y="36.5" width="30.3" height="11"/></clipPath><clipPath id="ct5"><rect x="116.3" y="36.5" width="35.1" height="11"/></clipPath></defs><g clip-path="url(#cp0)"><rect x="20" y="20" width="141.4" height="44" rx="22" fill="rgb(58,58,60)"/><rect x="20.5" y="20.5" width="140" height="43" rx="21.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><g clip-path="url(#ov1)"><rect x="22.5" y="22.5" width="39" height="39" rx="19.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><text x="31.47" y="46.5" font-family="system-ui, &quot;-apple-system&quot;, sans-serif" font-size="11" font-weight="650" fill="rgb(245,245,247)">Day</text><rect x="62" y="23" width="46.3" height="40" rx="20" fill="rgba(0,0,0,0.5)" filter="url(#sh3)"/><rect x="62" y="22" width="46.3" height="40" rx="20" fill="rgb(28,28,30)"/><rect x="62.5" y="22.5" width="45" height="39" rx="19.5" fill="none" stroke="rgb(72,72,74)" stroke-width="1"/><text x="70" y="46.5" font-family="system-ui, &quot;-apple-system&quot;, sans-serif" font-size="11" font-weight="650" fill="rgb(138,203,255)">Week</text><rect x="108.5" y="22.5" width="50" height="39" rx="19.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><text x="116.28" y="46.5" font-family="system-ui, &quot;-apple-system&quot;, sans-serif" font-size="11" font-weight="650" fill="rgb(245,245,247)">Month</text></g></g></svg>
@@ -1 +1 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 460 88" width="460" height="88"><defs><clipPath id="cp0"><rect x="20" y="20" width="141.4" height="44"/></clipPath><clipPath id="ov1"><rect x="21" y="21" width="139.4" height="42" rx="21"/></clipPath><clipPath id="ct2"><rect x="31.5" y="36.5" width="21.1" height="11"/></clipPath><filter id="sh3" x="-50%" y="-50%" width="200%" height="200%"><feGaussianBlur stdDeviation="1.5"/></filter><clipPath id="ct4"><rect x="70" y="36.5" width="30.3" height="11"/></clipPath><clipPath id="ct5"><rect x="116.3" y="36.5" width="35.1" height="11"/></clipPath></defs><g clip-path="url(#cp0)"><rect x="20" y="20" width="141.4" height="44" rx="22" fill="rgb(229,229,234)"/><rect x="20.5" y="20.5" width="140" height="43" rx="21.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><g clip-path="url(#ov1)"><rect x="22.5" y="22.5" width="39" height="39" rx="19.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><text x="31.47" y="46.5" font-family="system-ui, &quot;-apple-system&quot;, sans-serif" font-size="11" font-weight="650" fill="rgb(110,110,115)">Day</text><rect x="62" y="23" width="46.3" height="40" rx="20" fill="rgba(0,0,0,0.14)" filter="url(#sh3)"/><rect x="62" y="22" width="46.3" height="40" rx="20" fill="rgb(255,255,255)"/><rect x="62.5" y="22.5" width="45" height="39" rx="19.5" fill="none" stroke="rgb(209,209,214)" stroke-width="1"/><text x="70" y="46.5" font-family="system-ui, &quot;-apple-system&quot;, sans-serif" font-size="11" font-weight="650" fill="rgb(12,98,243)">Week</text><rect x="108.5" y="22.5" width="50" height="39" rx="19.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><text x="116.28" y="46.5" font-family="system-ui, &quot;-apple-system&quot;, sans-serif" font-size="11" font-weight="650" fill="rgb(110,110,115)">Month</text></g></g></svg>
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 460 88" width="460" height="88"><defs><clipPath id="cp0"><rect x="20" y="20" width="141.4" height="44"/></clipPath><clipPath id="ov1"><rect x="21" y="21" width="139.4" height="42" rx="21"/></clipPath><clipPath id="ct2"><rect x="31.5" y="36.5" width="21.1" height="11"/></clipPath><filter id="sh3" x="-50%" y="-50%" width="200%" height="200%"><feGaussianBlur stdDeviation="1.5"/></filter><clipPath id="ct4"><rect x="70" y="36.5" width="30.3" height="11"/></clipPath><clipPath id="ct5"><rect x="116.3" y="36.5" width="35.1" height="11"/></clipPath></defs><g clip-path="url(#cp0)"><rect x="20" y="20" width="141.4" height="44" rx="22" fill="rgb(229,229,234)"/><rect x="20.5" y="20.5" width="140" height="43" rx="21.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><g clip-path="url(#ov1)"><rect x="22.5" y="22.5" width="39" height="39" rx="19.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><text x="31.47" y="46.5" font-family="system-ui, &quot;-apple-system&quot;, sans-serif" font-size="11" font-weight="650" fill="rgb(29,29,31)">Day</text><rect x="62" y="23" width="46.3" height="40" rx="20" fill="rgba(0,0,0,0.14)" filter="url(#sh3)"/><rect x="62" y="22" width="46.3" height="40" rx="20" fill="rgb(255,255,255)"/><rect x="62.5" y="22.5" width="45" height="39" rx="19.5" fill="none" stroke="rgb(209,209,214)" stroke-width="1"/><text x="70" y="46.5" font-family="system-ui, &quot;-apple-system&quot;, sans-serif" font-size="11" font-weight="650" fill="rgb(12,98,243)">Week</text><rect x="108.5" y="22.5" width="50" height="39" rx="19.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><text x="116.28" y="46.5" font-family="system-ui, &quot;-apple-system&quot;, sans-serif" font-size="11" font-weight="650" fill="rgb(29,29,31)">Month</text></g></g></svg>
@@ -1 +1 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 492 268" width="492" height="268"><defs><clipPath id="cp0"><rect x="16" y="38" width="460" height="88"/></clipPath><clipPath id="cp1"><rect x="16" y="164" width="460" height="88"/></clipPath><clipPath id="ct2"><rect x="16" y="16" width="460" height="22"/></clipPath><clipPath id="irc3"><rect x="16" y="38" width="460" height="88" rx="0"/></clipPath><clipPath id="ct5"><rect x="16" y="142" width="460" height="22"/></clipPath><clipPath id="irc6"><rect x="16" y="164" width="460" height="88" rx="0"/></clipPath></defs><rect x="0" y="0" width="492" height="268" rx="0" fill="rgb(28,28,30)"/><text x="16" y="28" font-family="system-ui, &quot;-apple-system&quot;, sans-serif" font-size="12" font-weight="600" fill="rgb(174,174,178)">Equal-width rounded</text><g clip-path="url(#cp0)"><g clip-path="url(#irc3)"><clipPath id="svgimg4vclip"><rect x="16" y="38" width="460" height="88"/></clipPath><g clip-path="url(#svgimg4vclip)"><g transform="translate(16 38)"><defs><clipPath id="svgimg4cp0"><rect x="20" y="20" width="210.3" height="44"/></clipPath><clipPath id="svgimg4ov1"><rect x="21" y="21" width="208.3" height="42" rx="11"/></clipPath><filter id="svgimg4sh2" x="-50%" y="-50%" width="200%" height="200%"><feGaussianBlur stdDeviation="1.5"/></filter><clipPath id="svgimg4ct3"><rect x="38.7" y="36" width="35.3" height="12"/></clipPath><clipPath id="svgimg4ct4"><rect x="114.1" y="36" width="22" height="12"/></clipPath><clipPath id="svgimg4ct5"><rect x="168.5" y="36" width="50.8" height="12"/></clipPath></defs><g clip-path="url(#svgimg4cp0)"><rect x="20" y="20" width="210.3" height="44" rx="12" fill="rgb(58,58,60)"/><rect x="20.5" y="20.5" width="209" height="43" rx="11.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/></g><g clip-path="url(#svgimg4cp0)"><g clip-path="url(#svgimg4ov1)"><rect x="22" y="23" width="68.8" height="40" rx="10" fill="rgba(0,0,0,0.5)" filter="url(#svgimg4sh2)"/><rect x="22" y="22" width="68.8" height="40" rx="10" fill="rgb(28,28,30)"/><rect x="22.5" y="22.5" width="68" height="39" rx="9.5" fill="none" stroke="rgb(72,72,74)" stroke-width="1"/><text x="38.7" y="46" font-family="system-ui, &quot;-apple-system&quot;, sans-serif" font-size="12" font-weight="650" fill="rgb(138,203,255)">Board</text><rect x="91.5" y="22.5" width="68" height="39" rx="9.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><text x="114.13" y="46" font-family="system-ui, &quot;-apple-system&quot;, sans-serif" font-size="12" font-weight="650" fill="rgb(174,174,178)">List</text><rect x="160.5" y="22.5" width="67" height="39" rx="9.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><text x="168.5" y="46" font-family="system-ui, &quot;-apple-system&quot;, sans-serif" font-size="12" font-weight="650" fill="rgb(174,174,178)">Timeline</text></g></g></g></g></g></g><text x="16" y="154" font-family="system-ui, &quot;-apple-system&quot;, sans-serif" font-size="12" font-weight="600" fill="rgb(174,174,178)">Pill, small</text><g clip-path="url(#cp1)"><g clip-path="url(#irc6)"><clipPath id="svgimg7vclip"><rect x="16" y="164" width="460" height="88"/></clipPath><g clip-path="url(#svgimg7vclip)"><g transform="translate(16 164)"><defs><clipPath id="svgimg7cp0"><rect x="20" y="20" width="141.4" height="44"/></clipPath><clipPath id="svgimg7ov1"><rect x="21" y="21" width="139.4" height="42" rx="21"/></clipPath><clipPath id="svgimg7ct2"><rect x="31.5" y="36.5" width="21.1" height="11"/></clipPath><filter id="svgimg7sh3" x="-50%" y="-50%" width="200%" height="200%"><feGaussianBlur stdDeviation="1.5"/></filter><clipPath id="svgimg7ct4"><rect x="70" y="36.5" width="30.3" height="11"/></clipPath><clipPath id="svgimg7ct5"><rect x="116.3" y="36.5" width="35.1" height="11"/></clipPath></defs><g clip-path="url(#svgimg7cp0)"><rect x="20" y="20" width="141.4" height="44" rx="22" fill="rgb(58,58,60)"/><rect x="20.5" y="20.5" width="140" height="43" rx="21.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><g clip-path="url(#svgimg7ov1)"><rect x="22.5" y="22.5" width="39" height="39" rx="19.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><text x="31.47" y="46.5" font-family="system-ui, &quot;-apple-system&quot;, sans-serif" font-size="11" font-weight="650" fill="rgb(174,174,178)">Day</text><rect x="62" y="23" width="46.3" height="40" rx="20" fill="rgba(0,0,0,0.5)" filter="url(#svgimg7sh3)"/><rect x="62" y="22" width="46.3" height="40" rx="20" fill="rgb(28,28,30)"/><rect x="62.5" y="22.5" width="45" height="39" rx="19.5" fill="none" stroke="rgb(72,72,74)" stroke-width="1"/><text x="70" y="46.5" font-family="system-ui, &quot;-apple-system&quot;, sans-serif" font-size="11" font-weight="650" fill="rgb(138,203,255)">Week</text><rect x="108.5" y="22.5" width="50" height="39" rx="19.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><text x="116.28" y="46.5" font-family="system-ui, &quot;-apple-system&quot;, sans-serif" font-size="11" font-weight="650" fill="rgb(174,174,178)">Month</text></g></g></g></g></g></g></svg>
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 492 268" width="492" height="268"><defs><clipPath id="cp0"><rect x="16" y="38" width="460" height="88"/></clipPath><clipPath id="cp1"><rect x="16" y="164" width="460" height="88"/></clipPath><clipPath id="ct2"><rect x="16" y="16" width="460" height="22"/></clipPath><clipPath id="irc3"><rect x="16" y="38" width="460" height="88" rx="0"/></clipPath><clipPath id="ct5"><rect x="16" y="142" width="460" height="22"/></clipPath><clipPath id="irc6"><rect x="16" y="164" width="460" height="88" rx="0"/></clipPath></defs><rect x="0" y="0" width="492" height="268" rx="0" fill="rgb(28,28,30)"/><text x="16" y="28" font-family="system-ui, &quot;-apple-system&quot;, sans-serif" font-size="12" font-weight="600" fill="rgb(174,174,178)">Equal-width rounded</text><g clip-path="url(#cp0)"><g clip-path="url(#irc3)"><clipPath id="svgimg4vclip"><rect x="16" y="38" width="460" height="88"/></clipPath><g clip-path="url(#svgimg4vclip)"><g transform="translate(16 38)"><defs><clipPath id="svgimg4cp0"><rect x="20" y="20" width="210.3" height="44"/></clipPath><clipPath id="svgimg4ov1"><rect x="21" y="21" width="208.3" height="42" rx="11"/></clipPath><filter id="svgimg4sh2" x="-50%" y="-50%" width="200%" height="200%"><feGaussianBlur stdDeviation="1.5"/></filter><clipPath id="svgimg4ct3"><rect x="38.7" y="36" width="35.3" height="12"/></clipPath><clipPath id="svgimg4ct4"><rect x="114.1" y="36" width="22" height="12"/></clipPath><clipPath id="svgimg4ct5"><rect x="168.5" y="36" width="50.8" height="12"/></clipPath></defs><g clip-path="url(#svgimg4cp0)"><rect x="20" y="20" width="210.3" height="44" rx="12" fill="rgb(58,58,60)"/><rect x="20.5" y="20.5" width="209" height="43" rx="11.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/></g><g clip-path="url(#svgimg4cp0)"><g clip-path="url(#svgimg4ov1)"><rect x="22" y="23" width="68.8" height="40" rx="10" fill="rgba(0,0,0,0.5)" filter="url(#svgimg4sh2)"/><rect x="22" y="22" width="68.8" height="40" rx="10" fill="rgb(28,28,30)"/><rect x="22.5" y="22.5" width="68" height="39" rx="9.5" fill="none" stroke="rgb(72,72,74)" stroke-width="1"/><text x="38.7" y="46" font-family="system-ui, &quot;-apple-system&quot;, sans-serif" font-size="12" font-weight="650" fill="rgb(138,203,255)">Board</text><rect x="91.5" y="22.5" width="68" height="39" rx="9.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><text x="114.13" y="46" font-family="system-ui, &quot;-apple-system&quot;, sans-serif" font-size="12" font-weight="650" fill="rgb(245,245,247)">List</text><rect x="160.5" y="22.5" width="67" height="39" rx="9.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><text x="168.5" y="46" font-family="system-ui, &quot;-apple-system&quot;, sans-serif" font-size="12" font-weight="650" fill="rgb(245,245,247)">Timeline</text></g></g></g></g></g></g><text x="16" y="154" font-family="system-ui, &quot;-apple-system&quot;, sans-serif" font-size="12" font-weight="600" fill="rgb(174,174,178)">Pill, small</text><g clip-path="url(#cp1)"><g clip-path="url(#irc6)"><clipPath id="svgimg7vclip"><rect x="16" y="164" width="460" height="88"/></clipPath><g clip-path="url(#svgimg7vclip)"><g transform="translate(16 164)"><defs><clipPath id="svgimg7cp0"><rect x="20" y="20" width="141.4" height="44"/></clipPath><clipPath id="svgimg7ov1"><rect x="21" y="21" width="139.4" height="42" rx="21"/></clipPath><clipPath id="svgimg7ct2"><rect x="31.5" y="36.5" width="21.1" height="11"/></clipPath><filter id="svgimg7sh3" x="-50%" y="-50%" width="200%" height="200%"><feGaussianBlur stdDeviation="1.5"/></filter><clipPath id="svgimg7ct4"><rect x="70" y="36.5" width="30.3" height="11"/></clipPath><clipPath id="svgimg7ct5"><rect x="116.3" y="36.5" width="35.1" height="11"/></clipPath></defs><g clip-path="url(#svgimg7cp0)"><rect x="20" y="20" width="141.4" height="44" rx="22" fill="rgb(58,58,60)"/><rect x="20.5" y="20.5" width="140" height="43" rx="21.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><g clip-path="url(#svgimg7ov1)"><rect x="22.5" y="22.5" width="39" height="39" rx="19.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><text x="31.47" y="46.5" font-family="system-ui, &quot;-apple-system&quot;, sans-serif" font-size="11" font-weight="650" fill="rgb(245,245,247)">Day</text><rect x="62" y="23" width="46.3" height="40" rx="20" fill="rgba(0,0,0,0.5)" filter="url(#svgimg7sh3)"/><rect x="62" y="22" width="46.3" height="40" rx="20" fill="rgb(28,28,30)"/><rect x="62.5" y="22.5" width="45" height="39" rx="19.5" fill="none" stroke="rgb(72,72,74)" stroke-width="1"/><text x="70" y="46.5" font-family="system-ui, &quot;-apple-system&quot;, sans-serif" font-size="11" font-weight="650" fill="rgb(138,203,255)">Week</text><rect x="108.5" y="22.5" width="50" height="39" rx="19.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><text x="116.28" y="46.5" font-family="system-ui, &quot;-apple-system&quot;, sans-serif" font-size="11" font-weight="650" fill="rgb(245,245,247)">Month</text></g></g></g></g></g></g></svg>
@@ -1 +1 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 492 268" width="492" height="268"><defs><clipPath id="cp0"><rect x="16" y="38" width="460" height="88"/></clipPath><clipPath id="cp1"><rect x="16" y="164" width="460" height="88"/></clipPath><clipPath id="ct2"><rect x="16" y="16" width="460" height="22"/></clipPath><clipPath id="irc3"><rect x="16" y="38" width="460" height="88" rx="0"/></clipPath><clipPath id="ct5"><rect x="16" y="142" width="460" height="22"/></clipPath><clipPath id="irc6"><rect x="16" y="164" width="460" height="88" rx="0"/></clipPath></defs><rect x="0" y="0" width="492" height="268" rx="0" fill="rgb(255,255,255)"/><text x="16" y="28" font-family="system-ui, &quot;-apple-system&quot;, sans-serif" font-size="12" font-weight="600" fill="rgb(110,110,115)">Equal-width rounded</text><g clip-path="url(#cp0)"><g clip-path="url(#irc3)"><clipPath id="svgimg4vclip"><rect x="16" y="38" width="460" height="88"/></clipPath><g clip-path="url(#svgimg4vclip)"><g transform="translate(16 38)"><defs><clipPath id="svgimg4cp0"><rect x="20" y="20" width="210.3" height="44"/></clipPath><clipPath id="svgimg4ov1"><rect x="21" y="21" width="208.3" height="42" rx="11"/></clipPath><filter id="svgimg4sh2" x="-50%" y="-50%" width="200%" height="200%"><feGaussianBlur stdDeviation="1.5"/></filter><clipPath id="svgimg4ct3"><rect x="38.7" y="36" width="35.3" height="12"/></clipPath><clipPath id="svgimg4ct4"><rect x="114.1" y="36" width="22" height="12"/></clipPath><clipPath id="svgimg4ct5"><rect x="168.5" y="36" width="50.8" height="12"/></clipPath></defs><g clip-path="url(#svgimg4cp0)"><rect x="20" y="20" width="210.3" height="44" rx="12" fill="rgb(229,229,234)"/><rect x="20.5" y="20.5" width="209" height="43" rx="11.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/></g><g clip-path="url(#svgimg4cp0)"><g clip-path="url(#svgimg4ov1)"><rect x="22" y="23" width="68.8" height="40" rx="10" fill="rgba(0,0,0,0.14)" filter="url(#svgimg4sh2)"/><rect x="22" y="22" width="68.8" height="40" rx="10" fill="rgb(255,255,255)"/><rect x="22.5" y="22.5" width="68" height="39" rx="9.5" fill="none" stroke="rgb(209,209,214)" stroke-width="1"/><text x="38.7" y="46" font-family="system-ui, &quot;-apple-system&quot;, sans-serif" font-size="12" font-weight="650" fill="rgb(12,98,243)">Board</text><rect x="91.5" y="22.5" width="68" height="39" rx="9.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><text x="114.13" y="46" font-family="system-ui, &quot;-apple-system&quot;, sans-serif" font-size="12" font-weight="650" fill="rgb(110,110,115)">List</text><rect x="160.5" y="22.5" width="67" height="39" rx="9.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><text x="168.5" y="46" font-family="system-ui, &quot;-apple-system&quot;, sans-serif" font-size="12" font-weight="650" fill="rgb(110,110,115)">Timeline</text></g></g></g></g></g></g><text x="16" y="154" font-family="system-ui, &quot;-apple-system&quot;, sans-serif" font-size="12" font-weight="600" fill="rgb(110,110,115)">Pill, small</text><g clip-path="url(#cp1)"><g clip-path="url(#irc6)"><clipPath id="svgimg7vclip"><rect x="16" y="164" width="460" height="88"/></clipPath><g clip-path="url(#svgimg7vclip)"><g transform="translate(16 164)"><defs><clipPath id="svgimg7cp0"><rect x="20" y="20" width="141.4" height="44"/></clipPath><clipPath id="svgimg7ov1"><rect x="21" y="21" width="139.4" height="42" rx="21"/></clipPath><clipPath id="svgimg7ct2"><rect x="31.5" y="36.5" width="21.1" height="11"/></clipPath><filter id="svgimg7sh3" x="-50%" y="-50%" width="200%" height="200%"><feGaussianBlur stdDeviation="1.5"/></filter><clipPath id="svgimg7ct4"><rect x="70" y="36.5" width="30.3" height="11"/></clipPath><clipPath id="svgimg7ct5"><rect x="116.3" y="36.5" width="35.1" height="11"/></clipPath></defs><g clip-path="url(#svgimg7cp0)"><rect x="20" y="20" width="141.4" height="44" rx="22" fill="rgb(229,229,234)"/><rect x="20.5" y="20.5" width="140" height="43" rx="21.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><g clip-path="url(#svgimg7ov1)"><rect x="22.5" y="22.5" width="39" height="39" rx="19.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><text x="31.47" y="46.5" font-family="system-ui, &quot;-apple-system&quot;, sans-serif" font-size="11" font-weight="650" fill="rgb(110,110,115)">Day</text><rect x="62" y="23" width="46.3" height="40" rx="20" fill="rgba(0,0,0,0.14)" filter="url(#svgimg7sh3)"/><rect x="62" y="22" width="46.3" height="40" rx="20" fill="rgb(255,255,255)"/><rect x="62.5" y="22.5" width="45" height="39" rx="19.5" fill="none" stroke="rgb(209,209,214)" stroke-width="1"/><text x="70" y="46.5" font-family="system-ui, &quot;-apple-system&quot;, sans-serif" font-size="11" font-weight="650" fill="rgb(12,98,243)">Week</text><rect x="108.5" y="22.5" width="50" height="39" rx="19.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><text x="116.28" y="46.5" font-family="system-ui, &quot;-apple-system&quot;, sans-serif" font-size="11" font-weight="650" fill="rgb(110,110,115)">Month</text></g></g></g></g></g></g></svg>
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 492 268" width="492" height="268"><defs><clipPath id="cp0"><rect x="16" y="38" width="460" height="88"/></clipPath><clipPath id="cp1"><rect x="16" y="164" width="460" height="88"/></clipPath><clipPath id="ct2"><rect x="16" y="16" width="460" height="22"/></clipPath><clipPath id="irc3"><rect x="16" y="38" width="460" height="88" rx="0"/></clipPath><clipPath id="ct5"><rect x="16" y="142" width="460" height="22"/></clipPath><clipPath id="irc6"><rect x="16" y="164" width="460" height="88" rx="0"/></clipPath></defs><rect x="0" y="0" width="492" height="268" rx="0" fill="rgb(255,255,255)"/><text x="16" y="28" font-family="system-ui, &quot;-apple-system&quot;, sans-serif" font-size="12" font-weight="600" fill="rgb(110,110,115)">Equal-width rounded</text><g clip-path="url(#cp0)"><g clip-path="url(#irc3)"><clipPath id="svgimg4vclip"><rect x="16" y="38" width="460" height="88"/></clipPath><g clip-path="url(#svgimg4vclip)"><g transform="translate(16 38)"><defs><clipPath id="svgimg4cp0"><rect x="20" y="20" width="210.3" height="44"/></clipPath><clipPath id="svgimg4ov1"><rect x="21" y="21" width="208.3" height="42" rx="11"/></clipPath><filter id="svgimg4sh2" x="-50%" y="-50%" width="200%" height="200%"><feGaussianBlur stdDeviation="1.5"/></filter><clipPath id="svgimg4ct3"><rect x="38.7" y="36" width="35.3" height="12"/></clipPath><clipPath id="svgimg4ct4"><rect x="114.1" y="36" width="22" height="12"/></clipPath><clipPath id="svgimg4ct5"><rect x="168.5" y="36" width="50.8" height="12"/></clipPath></defs><g clip-path="url(#svgimg4cp0)"><rect x="20" y="20" width="210.3" height="44" rx="12" fill="rgb(229,229,234)"/><rect x="20.5" y="20.5" width="209" height="43" rx="11.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/></g><g clip-path="url(#svgimg4cp0)"><g clip-path="url(#svgimg4ov1)"><rect x="22" y="23" width="68.8" height="40" rx="10" fill="rgba(0,0,0,0.14)" filter="url(#svgimg4sh2)"/><rect x="22" y="22" width="68.8" height="40" rx="10" fill="rgb(255,255,255)"/><rect x="22.5" y="22.5" width="68" height="39" rx="9.5" fill="none" stroke="rgb(209,209,214)" stroke-width="1"/><text x="38.7" y="46" font-family="system-ui, &quot;-apple-system&quot;, sans-serif" font-size="12" font-weight="650" fill="rgb(12,98,243)">Board</text><rect x="91.5" y="22.5" width="68" height="39" rx="9.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><text x="114.13" y="46" font-family="system-ui, &quot;-apple-system&quot;, sans-serif" font-size="12" font-weight="650" fill="rgb(29,29,31)">List</text><rect x="160.5" y="22.5" width="67" height="39" rx="9.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><text x="168.5" y="46" font-family="system-ui, &quot;-apple-system&quot;, sans-serif" font-size="12" font-weight="650" fill="rgb(29,29,31)">Timeline</text></g></g></g></g></g></g><text x="16" y="154" font-family="system-ui, &quot;-apple-system&quot;, sans-serif" font-size="12" font-weight="600" fill="rgb(110,110,115)">Pill, small</text><g clip-path="url(#cp1)"><g clip-path="url(#irc6)"><clipPath id="svgimg7vclip"><rect x="16" y="164" width="460" height="88"/></clipPath><g clip-path="url(#svgimg7vclip)"><g transform="translate(16 164)"><defs><clipPath id="svgimg7cp0"><rect x="20" y="20" width="141.4" height="44"/></clipPath><clipPath id="svgimg7ov1"><rect x="21" y="21" width="139.4" height="42" rx="21"/></clipPath><clipPath id="svgimg7ct2"><rect x="31.5" y="36.5" width="21.1" height="11"/></clipPath><filter id="svgimg7sh3" x="-50%" y="-50%" width="200%" height="200%"><feGaussianBlur stdDeviation="1.5"/></filter><clipPath id="svgimg7ct4"><rect x="70" y="36.5" width="30.3" height="11"/></clipPath><clipPath id="svgimg7ct5"><rect x="116.3" y="36.5" width="35.1" height="11"/></clipPath></defs><g clip-path="url(#svgimg7cp0)"><rect x="20" y="20" width="141.4" height="44" rx="22" fill="rgb(229,229,234)"/><rect x="20.5" y="20.5" width="140" height="43" rx="21.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><g clip-path="url(#svgimg7ov1)"><rect x="22.5" y="22.5" width="39" height="39" rx="19.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><text x="31.47" y="46.5" font-family="system-ui, &quot;-apple-system&quot;, sans-serif" font-size="11" font-weight="650" fill="rgb(29,29,31)">Day</text><rect x="62" y="23" width="46.3" height="40" rx="20" fill="rgba(0,0,0,0.14)" filter="url(#svgimg7sh3)"/><rect x="62" y="22" width="46.3" height="40" rx="20" fill="rgb(255,255,255)"/><rect x="62.5" y="22.5" width="45" height="39" rx="19.5" fill="none" stroke="rgb(209,209,214)" stroke-width="1"/><text x="70" y="46.5" font-family="system-ui, &quot;-apple-system&quot;, sans-serif" font-size="11" font-weight="650" fill="rgb(12,98,243)">Week</text><rect x="108.5" y="22.5" width="50" height="39" rx="19.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><text x="116.28" y="46.5" font-family="system-ui, &quot;-apple-system&quot;, sans-serif" font-size="11" font-weight="650" fill="rgb(29,29,31)">Month</text></g></g></g></g></g></g></svg>
package/docs/layout.md CHANGED
@@ -331,26 +331,37 @@ insets.
331
331
 
332
332
  ## Grid
333
333
 
334
- Use `Grid` from `@kerfjs/ui/grid` when a fixed positive number of columns must
335
- share the available width evenly. Every track is `minmax(0, 1fr)`, so a child
336
- with wider intrinsic content cannot make its column wider than its peers. Grid
337
- defaults to the `xs` gap and accepts the same finite spacing names, complete
338
- typed `CssLength` values, and typed flex-participation contract as Row.
334
+ Use `Grid` from `@kerfjs/ui/grid` when equal-width columns must share the
335
+ available width. Set a fixed positive `columns` count or a typed
336
+ `minColumnWidth` for automatic container-width collapse. Fixed tracks use
337
+ `minmax(0, 1fr)`; responsive tracks use `auto-fit` and cap their minimum at
338
+ 100% so a narrow container keeps one column without overflow. Grid defaults
339
+ to the `xs` gap and accepts the same finite spacing names, complete typed
340
+ `CssLength` values, and typed flex-participation contract as Row.
339
341
 
340
342
  ```tsx
341
343
  import { Grid } from "@kerfjs/ui/grid";
344
+ import { px } from "@kerfjs/ui/css-values";
342
345
 
343
346
  <Grid columns={2} gap="m">
344
347
  <label>Quantity <input /></label>
345
348
  <label>Unit <input /></label>
346
349
  </Grid>;
350
+
351
+ <Grid minColumnWidth={px(376)} gap="m">
352
+ <label>Provider <input /></label>
353
+ <label>Endpoint <input /></label>
354
+ </Grid>;
347
355
  ```
348
356
 
349
357
  `columns` must be a positive safe integer; invalid counts throw instead of
350
- silently producing invalid CSS. Grid is layout-only and adds no ARIA grid role.
351
- The application owns child semantics and responsive count changes. Use
352
- application-owned CSS grid for intrinsic, asymmetric, spanning, auto-fit, or
353
- masonry tracks, and use `ResizableRegion` when people must adjust a boundary.
358
+ silently producing invalid CSS. Import `px` from `@kerfjs/ui/css-values` for a
359
+ pixel minimum. `columns` and `minColumnWidth` are mutually exclusive. In the
360
+ responsive mode, the container width decides how many equal tracks fit; constrain
361
+ the Grid's outer width when the form should have a maximum count. Grid is
362
+ layout-only and adds no ARIA grid role. The application owns child semantics.
363
+ Use application-owned CSS grid for intrinsic, asymmetric, spanning, or masonry
364
+ tracks, and use `ResizableRegion` when people must adjust a boundary.
354
365
 
355
366
  ## Row and List alignment
356
367
 
@@ -48,6 +48,11 @@ Override the public properties at the composition boundary:
48
48
  - `--kui-sunken-panel-gap`
49
49
  - `--kui-sunken-panel-radius`
50
50
 
51
+ `--kui-sunken-panel-background` can be overridden for a known backdrop. Keep
52
+ the default lowered surface opaque; a translucent override compounds when
53
+ sunken panels nest. See [Contextual transparency](./webawesome-theme.md#contextual-transparency)
54
+ for the color and contrast evaluation.
55
+
51
56
  The public root class is `.kui-sunken-panel`. Prefer the properties above over
52
57
  styling descendants. The `square` shape deliberately overrides the radius
53
58
  property with zero; use `rounded` when customizing the radius token.
@@ -131,6 +131,38 @@ tiers:
131
131
  content stays compact and the action group has a clearer boundary. These two
132
132
  parts do not inherit the dialog's shared `--spacing` value.
133
133
 
134
+ ## Contextual transparency
135
+
136
+ Keep the shared `--kui-color-*` semantic fills, foregrounds, and borders opaque
137
+ by default. Their light and dark values mirror the Web Awesome theme, and the
138
+ contrast checks in `tests/browser/tone-contrast.spec.ts` assume known surfaces.
139
+ Compositing those tokens over arbitrary app backgrounds changes text contrast
140
+ and makes the same token mean a different visible color in each container.
141
+
142
+ The strongest candidate for transparency is a **component-scoped sunken
143
+ background**, through the existing `--kui-sunken-panel-background` and
144
+ `--kui-wa-sunken-background` overrides. A simple black overlay of 5.5% over
145
+ white approximates `#f1f1f1`, near the current light lowered surface; a second
146
+ nesting level becomes `#e4e4e4`. Matching the current dark lowered surface from
147
+ `#1c1c1e` takes about 39% black, and a second layer becomes near-black
148
+ `#0a0a0b`. An alpha that works for one level therefore needs a separate nesting
149
+ rule or a lighter dark treatment before it can become a default. The existing
150
+ opaque `--kui-color-surface-lowered` remains appropriate for page backgrounds.
151
+
152
+ | Candidate | Finding |
153
+ | ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
154
+ | Selected `ListItem` fill and border | A translucent brand layer would preserve a tinted or textured backdrop. Keep it in the component's existing `--kui-list-item-selected-*` overrides: making the shared brand fill translucent would also affect components that put `--kui-color-brand-on-fill` text on it. A 16% brand overlay gives about 4.35:1 for that text over the light lowered surface and 3.99:1 over a warm `#eee7dc` surface, below the 4.5:1 text target. |
155
+ | `ToolbarControlGroup` fill and border | A light 10% black layer approximates the current fill over white, and a dark 13% white layer approximates it over the dark surface. On a warm `#eee7dc` backdrop, the light layer puts the existing quiet text at about 3.31:1. Its dark tone already uses a translucent fill. Keep default control chrome opaque until a backdrop matrix validates its text, icons, borders, and selected state. |
156
+ | Quiet or disabled text and icons | Keep normal and quiet text/foreground tokens opaque; alpha changes their contrast with every backdrop. Disabled controls may use component-owned opacity, as they do now, without weakening shared foreground tokens. |
157
+ | Dividers and borders | Decorative separators can use scoped alpha over a known surface. Control boundaries and focus indicators need reliable contrast; do not replace the shared border or focus tokens with alpha globally. |
158
+
159
+ The numeric examples are sRGB compositing estimates, not a browser acceptance
160
+ test. Before changing a default, inspect one and two sunken levels on default,
161
+ lowered, warm, and textured backdrops in light and dark; verify text and control
162
+ contrast, forced contrast, and Web Awesome parity. The opt-in sunken prototype
163
+ is tracked by `KF-1HDSZF` and should include Pane once `KF-RGNS18` establishes
164
+ its sunken appearance.
165
+
134
166
  Add `class="hide-actions"` to a `wa-dialog` when the dialog supplies its own
135
167
  dismissal affordance and should omit Web Awesome's header action region. The
136
168
  theme sets `display: none` on the directly exported `header-actions` part; it
package/llms.txt CHANGED
@@ -161,6 +161,9 @@ headingLevel`, `TokenSearchField clearIcon`, `ContentItem frame="framed"` for a
161
161
  expanded trailing control to a full second row at `responsiveAt`; the leading
162
162
  title remains above it. Public leading-min-width, trailing-gap/justify, and
163
163
  per-zone inline-padding tokens cover app-specific toolbar geometry.
164
+ `--kui-toolbar-inset: 0px` removes an embedded Toolbar's outer padding and
165
+ corresponding minimum-height allowance while preserving its zone gap and
166
+ safe-area compensation.
164
167
  - **Position region restore controls declaratively.** A ResizableRegion has a
165
168
  background token, `contentOverflow="visible"` for an anchored popup,
166
169
  top/bottom `restorePosition`, typed `restoreInset`, and
@@ -172,6 +175,9 @@ headingLevel`, `TokenSearchField clearIcon`, `ContentItem frame="framed"` for a
172
175
  `divider` owns row separators and `state="drag-target"` paints the drop
173
176
  target. Public ListItem tokens set row, icon, label, and trailing geometry;
174
177
  ListHeader height, title padding, and border tokens tune section density.
178
+ For a filled command list, scope `--kui-list-item-background`,
179
+ `--kui-list-item-border`, `--kui-list-item-hover-border`, and
180
+ `--kui-list-item-selected-border` at the list or row boundary.
175
181
  - **Use `Row` for horizontal and `List` for vertical layout.** Both expose
176
182
  physical `hAlign`/`vAlign` props and typed gaps. Row defaults to left/full,
177
183
  an `xs` gap, and no wrapping; List retains full/top and zero-gap defaults.
@@ -190,11 +196,11 @@ headingLevel`, `TokenSearchField clearIcon`, `ContentItem frame="framed"` for a
190
196
  or `foregroundColorVar()`; fill tokens such as `uiColor('success-fill-quiet')` do not
191
197
  type-check. These brands are intentionally
192
198
  not interchangeable; rows use classes/tokens/props rather than raw `style`.
193
- - **Use `Grid` for a fixed positive count of equal-width columns.** It uses
194
- zero-minimum fractional tracks, so intrinsic content cannot make one column
195
- wider than its peers. The app owns responsive count changes; use custom CSS
196
- grid for asymmetric/intrinsic tracks and `ResizableRegion` for adjustable
197
- boundaries. `Grid.gap` and `Grid.flex` use the same typed grammars as Row.
199
+ - **Use `Grid` for equal-width columns.** Set a fixed positive `columns` count
200
+ or typed `minColumnWidth` for automatic container-width collapse, never both.
201
+ The app owns the outer width and child semantics; use custom CSS grid for
202
+ asymmetric/intrinsic tracks and `ResizableRegion` for adjustable boundaries.
203
+ `Grid.gap` and `Grid.flex` use the same typed grammars as Row.
198
204
  - **Give a layout root `fill`, not a frame `Pane`.** A Row, List, or Grid that
199
205
  is the sole layout root of a definite-height parent takes its full height
200
206
  with `fill` and carries safe `data-*` markers through `rootAttributes`.
@@ -234,6 +240,11 @@ headingLevel`, `TokenSearchField clearIcon`, `ContentItem frame="framed"` for a
234
240
  toolbar filter menu adds `selectedPresentation="icon-only"` and a fixed
235
241
  `triggerIcon`: the trigger shows that icon plus a count badge while any
236
242
  choice is chosen, and its accessible name ends with the chosen labels.
243
+ `SelectChoice.disabled` keeps an unavailable option visible but unselectable;
244
+ `disabledReason` adds its tooltip. For multiple selects, opt in to
245
+ `selectAllLabel` and `clearLabel` footer buttons to select enabled choices
246
+ or clear the value through ordinary change events. The app owns the updated
247
+ controlled value and localized action labels.
237
248
  Icon-only Selects (single or multiple) and icon-only `PopupMenu`s show an
238
249
  `aria-hidden` Web Awesome help tag repeating that name (and a Select's
239
250
  choice) on hover and keyboard focus, hidden while the popup is open; the
@@ -264,7 +275,8 @@ headingLevel`, `TokenSearchField clearIcon`, `ContentItem frame="framed"` for a
264
275
  in a `single` `ToolbarControlGroup` with `nestedDropdown`; never hand-write
265
276
  `wa-dropdown` markup for a menu. Let the group size the trigger from its icon,
266
277
  localized text, and caret. `PopupMenu` items also support nested `submenu`
267
- actions, checked or trailing choice marks, danger tone, and disabled reasons;
278
+ actions, headings, dividers, checked or trailing choice marks, danger tone,
279
+ and disabled reasons; nested headings/dividers stay out of keyboard choices;
268
280
  use `context` with `openPopupMenuAt`/`closePopupMenu` for pointer-anchored row
269
281
  menus. Do not force a dropdown or button width. Nothing
270
282
  wraps inside a group: an icon sits beside its label on one row, and a
@@ -358,7 +370,14 @@ headingLevel`, `TokenSearchField clearIcon`, `ContentItem frame="framed"` for a
358
370
  Select All deletion does the same; deletion
359
371
  restoration finishes before the next keystroke rather than on a delayed frame.
360
372
  Persist both query and remaining tokens read from an edited field; change
361
- `revision` to replace its DOM-owned text programmatically. The one richer case is `wireTokenSearchFields`, which manages the
373
+ `revision` to replace unmanaged DOM-owned text programmatically, or call
374
+ `model.replace({ query, tokens })` for a model-managed field. In grammar-assisted
375
+ search, a model rule's `suggest(input, state)` receives current committed tokens
376
+ so suggestions can omit selected values; one-argument callbacks still work.
377
+ A sibling helper can call `model.commit(value)` for the active `name:` prefix
378
+ even when that value is not suggested; invalid values and missing prefixes
379
+ leave state unchanged.
380
+ The one richer case is `wireTokenSearchFields`, which manages the
362
381
  collapsible field's expand/collapse/focus by default (on, per-behavior opt-out) and
363
382
  exposes the `expanded` signal on its handle — bind it in render or hand in your own
364
383
  via `collapsible.signals`. Do not hand-roll open/collapse/focus that helper
@@ -404,8 +423,13 @@ headingLevel`, `TokenSearchField clearIcon`, `ContentItem frame="framed"` for a
404
423
  closed value ellipsizes when space runs out.
405
424
  - **Configure application tabs at their owners.** AppTab's `icon-only`
406
425
  presentation keeps `name` accessible, `labelMaxWidth` ellipsizes a long name,
407
- and `attention` uses `--kui-app-tab-attention-color`. TabBar's public
426
+ `nameOverflow="visible"` shows the full name during inline loading, and
427
+ `dropTarget` highlights a drag-over without changing selection. `attention`
428
+ uses `--kui-app-tab-attention-color`. TabBar's public
408
429
  `--kui-tab-bar-strip-*` tokens set compact strip geometry.
430
+ Set `pinned` on the first AppTab to keep it visible within a scrolling
431
+ tablist; it remains in keyboard order. Use `--kui-app-tab-pinned-background`
432
+ for the surrounding surface and keep that backdrop opaque.
409
433
  - **Use `Badge` for compact non-interactive metadata.** Configure its semantic
410
434
  tone, appearance, shape, and size instead of creating badge CSS in an app or
411
435
  consuming component. Use a real button or link for interactive content.
@@ -413,6 +437,10 @@ headingLevel`, `TokenSearchField clearIcon`, `ContentItem frame="framed"` for a
413
437
  takes no children, and needs a `label` (announced as an image) or
414
438
  `ariaHidden` when its owner announces it. A `TabScaffold` tab shows the dot
415
439
  with `badge: true` plus its required `badgeLabel`.
440
+ - **Use `Chip` for removable tags.** Give the native remove button a delegated
441
+ `removeAction` and a specific `removeLabel`; the application updates the tag
442
+ list. `itemId` identifies the chip to the action handler. `size="compact"`
443
+ gives a 20px chip and 16px remove button; `disabled` disables removal.
416
444
 
417
445
  ## Public exports
418
446
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kerfjs/ui",
3
- "version": "5.0.0-beta.60",
3
+ "version": "5.0.0-beta.61",
4
4
  "description": "Accessible, composable UI primitives for kerf applications.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -65,6 +65,11 @@
65
65
  "browser": "./dist/browser/badge.js",
66
66
  "import": "./dist/badge.js"
67
67
  },
68
+ "./chip": {
69
+ "types": "./dist/chip.d.ts",
70
+ "browser": "./dist/browser/chip.js",
71
+ "import": "./dist/chip.js"
72
+ },
68
73
  "./toolbar": {
69
74
  "types": "./dist/toolbar.d.ts",
70
75
  "browser": "./dist/browser/toolbar.js",
@@ -336,6 +341,7 @@
336
341
  "./styles.css": "./dist/styles/styles.css",
337
342
  "./lucide-icon.css": "./dist/styles/lucide-icon.css",
338
343
  "./badge.css": "./dist/styles/badge.css",
344
+ "./chip.css": "./dist/styles/chip.css",
339
345
  "./disclosure-arrow.css": "./dist/styles/disclosure-arrow.css",
340
346
  "./toolbar.css": "./dist/styles/toolbar.css",
341
347
  "./toolbar-control-group.css": "./dist/styles/toolbar-control-group.css",