@kerfjs/ui 5.0.0-beta.62 → 5.0.0-beta.63

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 (154) hide show
  1. package/README.md +4 -0
  2. package/ai/component-catalog-extension.schema.json +13 -0
  3. package/ai/component-catalog.json +8 -2
  4. package/ai/component-composition.json +9 -2
  5. package/ai/components/list-item.md +1 -1
  6. package/ai/components/workbench.md +3 -2
  7. package/ai/public-api-signatures-v1.md +136 -38
  8. package/ai/skill.md +9 -5
  9. package/ai/webawesome-jsx-signatures-v1.md +1 -1
  10. package/analyzer/index.mjs +3 -2
  11. package/catalog-projection-cli.mjs +96 -0
  12. package/catalog-projection.d.mts +55 -0
  13. package/catalog-projection.mjs +62 -0
  14. package/dist/browser/catalog.js +1 -1
  15. package/dist/browser/collapsible-panel.js +2 -0
  16. package/dist/browser/nav-stack.js +1 -0
  17. package/dist/browser/split-view.js +1 -0
  18. package/dist/browser/toolbar-control-group.js +1 -0
  19. package/dist/browser/workbench.js +1 -0
  20. package/dist/catalog-resources.d.ts +1 -1
  21. package/dist/catalog.d.ts +1 -1
  22. package/dist/catalog.js +11 -10
  23. package/dist/catalog.js.map +1 -1
  24. package/dist/chip.d.ts +9 -3
  25. package/dist/chip.js +1 -1
  26. package/dist/{chunk-OD2VXAPL.js → chunk-3BYFWTP3.js} +4 -3
  27. package/dist/chunk-3BYFWTP3.js.map +1 -0
  28. package/dist/{chunk-5Q3N6EV7.js → chunk-5IJ6UGNZ.js} +3 -3
  29. package/dist/{chunk-5Q3N6EV7.js.map → chunk-5IJ6UGNZ.js.map} +1 -1
  30. package/dist/chunk-7AKGPBCC.js +76 -0
  31. package/dist/chunk-7AKGPBCC.js.map +1 -0
  32. package/dist/{chunk-KROD7KZK.js → chunk-AUVG54KC.js} +2 -2
  33. package/dist/{chunk-KROD7KZK.js.map → chunk-AUVG54KC.js.map} +1 -1
  34. package/dist/{chunk-AUKT3KMG.js → chunk-CQHN45XR.js} +17 -2
  35. package/dist/chunk-CQHN45XR.js.map +1 -0
  36. package/dist/{chunk-SWVW56CV.js → chunk-EN4LDR5Y.js} +2 -2
  37. package/dist/{chunk-SWVW56CV.js.map → chunk-EN4LDR5Y.js.map} +1 -1
  38. package/dist/{chunk-4MG3KXJM.js → chunk-F7OCOBTG.js} +2 -2
  39. package/dist/{chunk-4MG3KXJM.js.map → chunk-F7OCOBTG.js.map} +1 -1
  40. package/dist/{chunk-KYDDCJXU.js → chunk-HXCMWANP.js} +4 -4
  41. package/dist/{chunk-KYDDCJXU.js.map → chunk-HXCMWANP.js.map} +1 -1
  42. package/dist/{chunk-ENGVYQPG.js → chunk-IA4D5XNT.js} +60 -10
  43. package/dist/chunk-IA4D5XNT.js.map +1 -0
  44. package/dist/{chunk-F4QMLOXJ.js → chunk-IAOAZUOO.js} +2 -2
  45. package/dist/{chunk-F4QMLOXJ.js.map → chunk-IAOAZUOO.js.map} +1 -1
  46. package/dist/{chunk-X6ADHJNI.js → chunk-KFYANKJI.js} +25 -6
  47. package/dist/chunk-KFYANKJI.js.map +1 -0
  48. package/dist/chunk-MOSIE4Z2.js +51 -0
  49. package/dist/chunk-MOSIE4Z2.js.map +1 -0
  50. package/dist/{chunk-7JUBXOIV.js → chunk-NXWE5S57.js} +25 -6
  51. package/dist/chunk-NXWE5S57.js.map +1 -0
  52. package/dist/{chunk-NNMLEDMD.js → chunk-OBAFAH5B.js} +36 -8
  53. package/dist/chunk-OBAFAH5B.js.map +1 -0
  54. package/dist/{chunk-A3CKOW2R.js → chunk-R75GGNWY.js} +123 -20
  55. package/dist/chunk-R75GGNWY.js.map +1 -0
  56. package/dist/chunk-RGS4WX2M.js +44 -0
  57. package/dist/chunk-RGS4WX2M.js.map +1 -0
  58. package/dist/{chunk-RRB26JRJ.js → chunk-RTJNJTG3.js} +2 -2
  59. package/dist/{chunk-RRB26JRJ.js.map → chunk-RTJNJTG3.js.map} +1 -1
  60. package/dist/{chunk-EAC4CDY7.js → chunk-SMZGAPCU.js} +15 -2
  61. package/dist/chunk-SMZGAPCU.js.map +1 -0
  62. package/dist/{chunk-6ZXOQEAN.js → chunk-WF75U3V4.js} +7 -1
  63. package/dist/chunk-WF75U3V4.js.map +1 -0
  64. package/dist/{chunk-VCBTX62E.js → chunk-ZRWXFDDS.js} +2 -2
  65. package/dist/chunk-ZRWXFDDS.js.map +1 -0
  66. package/dist/collapsible-panel.d.ts +18 -7
  67. package/dist/collapsible-panel.js +19 -3
  68. package/dist/collapsible-panel.js.map +1 -1
  69. package/dist/content-item.d.ts +36 -5
  70. package/dist/content-item.js +1 -1
  71. package/dist/disclosure-arrow.js +2 -1
  72. package/dist/index.d.ts +2 -2
  73. package/dist/index.js +19 -19
  74. package/dist/list-action-row.js +1 -1
  75. package/dist/list-header.js +1 -1
  76. package/dist/list-item.js +1 -1
  77. package/dist/lucide-icon.d.ts +5 -2
  78. package/dist/lucide-icon.js +2 -1
  79. package/dist/nav-stack.js +2 -1
  80. package/dist/pane.d.ts +2 -1
  81. package/dist/pane.js +1 -1
  82. package/dist/{panel-toolbar-DqwtBxQL.d.ts → panel-toolbar-DDKh4uKd.d.ts} +11 -2
  83. package/dist/popup-menu-register.js +38 -1
  84. package/dist/popup-menu-register.js.map +1 -1
  85. package/dist/popup-menu.d.ts +2 -2
  86. package/dist/popup-menu.js +1 -1
  87. package/dist/select.js +1 -1
  88. package/dist/split-view.js +2 -1
  89. package/dist/split-view.js.map +1 -1
  90. package/dist/styles/chip.css +14 -0
  91. package/dist/styles/content-item.css +36 -0
  92. package/dist/styles/list-action-row.css +4 -3
  93. package/dist/styles/list-header.css +4 -3
  94. package/dist/styles/list-item.css +21 -11
  95. package/dist/styles/lucide-icon.css +5 -0
  96. package/dist/styles/pane.css +3 -2
  97. package/dist/styles/popup-menu.css +15 -10
  98. package/dist/styles/select.css +11 -0
  99. package/dist/styles/sunken-panel.css +7 -0
  100. package/dist/styles/text.css +29 -0
  101. package/dist/styles/token-search-field.css +29 -6
  102. package/dist/styles/toolbar-control-group.css +35 -0
  103. package/dist/styles/workbench.css +148 -2
  104. package/dist/sunken-panel.d.ts +6 -1
  105. package/dist/sunken-panel.js +1 -1
  106. package/dist/text.d.ts +14 -3
  107. package/dist/text.js +1 -1
  108. package/dist/token-search-field.js +2 -1
  109. package/dist/toolbar-control-group.d.ts +5 -1
  110. package/dist/toolbar-control-group.js +2 -1
  111. package/dist/toolbar.d.ts +5 -2
  112. package/dist/toolbar.js +1 -1
  113. package/dist/wire-catalog.js +1 -1
  114. package/dist/wire-content-items.d.ts +9 -0
  115. package/dist/wire-content-items.js +62 -0
  116. package/dist/wire-content-items.js.map +1 -0
  117. package/dist/wire-token-search-fields.js +2 -1
  118. package/dist/wire-workbench.d.ts +7 -0
  119. package/dist/wire-workbench.js +1 -1
  120. package/dist/workbench.d.ts +24 -8
  121. package/dist/workbench.js +2 -1
  122. package/docs/accessibility.md +21 -5
  123. package/docs/catalog.md +36 -0
  124. package/docs/collapsible-panel.md +8 -1
  125. package/docs/component-contract.md +10 -4
  126. package/docs/component-selection.md +39 -8
  127. package/docs/design/templates/toolbar/title-and-actions-dark.svg +1 -1
  128. package/docs/design/templates/toolbar/title-and-actions.svg +1 -1
  129. package/docs/design/templates/toolbar-dark.svg +1 -1
  130. package/docs/design/templates/toolbar.svg +1 -1
  131. package/docs/examples/component-catalog-extension.json +6 -0
  132. package/docs/layout.md +30 -3
  133. package/docs/sunken-panel.md +22 -0
  134. package/docs/ui-analyzer.md +4 -0
  135. package/docs/workbench.md +38 -4
  136. package/llms.txt +9 -5
  137. package/package.json +16 -2
  138. package/scripts/component-catalog-extension-validation.mjs +28 -0
  139. package/dist/chunk-4R777DUZ.js +0 -34
  140. package/dist/chunk-4R777DUZ.js.map +0 -1
  141. package/dist/chunk-6ZXOQEAN.js.map +0 -1
  142. package/dist/chunk-7JUBXOIV.js.map +0 -1
  143. package/dist/chunk-A3CKOW2R.js.map +0 -1
  144. package/dist/chunk-AUKT3KMG.js.map +0 -1
  145. package/dist/chunk-EAC4CDY7.js.map +0 -1
  146. package/dist/chunk-ENGVYQPG.js.map +0 -1
  147. package/dist/chunk-MA73TA6D.js +0 -42
  148. package/dist/chunk-MA73TA6D.js.map +0 -1
  149. package/dist/chunk-N2DRU35S.js +0 -45
  150. package/dist/chunk-N2DRU35S.js.map +0 -1
  151. package/dist/chunk-NNMLEDMD.js.map +0 -1
  152. package/dist/chunk-OD2VXAPL.js.map +0 -1
  153. package/dist/chunk-VCBTX62E.js.map +0 -1
  154. package/dist/chunk-X6ADHJNI.js.map +0 -1
package/docs/catalog.md CHANGED
@@ -215,6 +215,42 @@ border, and padding. Catalogs for downstream components should conform to the
215
215
  contract and can start from the checked
216
216
  [`component-catalog-extension.json`](./examples/component-catalog-extension.json)
217
217
  example; provide those entries beside Kerf's shipped catalog to AI tools.
218
+ An extension entry may declare `uses` with direct Kerf or extension entry ids,
219
+ plus repository-relative `source` and `demoSource` paths. Keep the ids unique
220
+ and resolvable across both catalogs; paths use `/` separators and cannot
221
+ traverse outside the repository. These fields let consumer demos derive source
222
+ links and composition relationships from the catalog.
223
+
224
+ For a consumer UX demo, `@kerfjs/ui/catalog-projection` exports
225
+ `projectConsumerCatalog(extension, kerfCatalog, options)` and
226
+ `projectCatalogEntries(entries, options)`. The projection maps `purpose` to
227
+ `description`, `uses` to related-entry ids, `source` to `componentSource`, and
228
+ `demoSource` to the demo source link. It defaults the source identity to
229
+ `consumer` and category to `Application`. Explicit paths in an extension entry
230
+ take precedence over templates. Template placeholders are `{id}`, `{name}`,
231
+ `{kind}`, and `{package}`. Design templates are omitted unless configured.
232
+
233
+ The package also ships `kerf-catalog-demo` for a committed TypeScript module:
234
+
235
+ ```sh
236
+ kerf-catalog-demo --extension ai/component-catalog-extension.json \
237
+ --out ux-demo/catalog.generated.ts \
238
+ --repo-base https://github.com/acme/app/blob/main/ \
239
+ --source-template 'src/{id}.tsx' \
240
+ --demo-template 'ux-demo/demos/{id}.tsx' --write
241
+ kerf-catalog-demo --extension ai/component-catalog-extension.json \
242
+ --out ux-demo/catalog.generated.ts \
243
+ --repo-base https://github.com/acme/app/blob/main/ \
244
+ --source-template 'src/{id}.tsx' \
245
+ --demo-template 'ux-demo/demos/{id}.tsx' --check
246
+ ```
247
+
248
+ The command uses the Kerf catalog shipped with the package to resolve `uses`;
249
+ `--kerf-catalog` selects another catalog file. `--category`,
250
+ `--documentation-template`, and `--design-template` configure optional row
251
+ fields. `--check` fails if the generated file is missing or stale. The output
252
+ exports `generatedConsumerCatalog` and `catalogRepositoryBlobUrl`; the latter
253
+ is normalized to a trailing slash for source and documentation links.
218
254
 
219
255
  ### Automated conformance and reviewed exceptions
220
256
 
@@ -134,7 +134,7 @@ and that of the components it renders (`Pane`, `Toolbar`, `ToolbarControlGroup`,
134
134
 
135
135
  Give a panel a `toolbar` (the same roles as a
136
136
  [Workbench panel toolbar](workbench.md#panel-toolbars)) and it composes its own
137
- top toolbar over a `Pane`, with an optional `footer` below its content:
137
+ top toolbar over a `Pane`:
138
138
 
139
139
  - `title` precedes the `leading` zone; `leading`, `center`, and `trailing`
140
140
  place groups wherever the open panel needs them;
@@ -142,6 +142,13 @@ top toolbar over a `Pane`, with an optional `footer` below its content:
142
142
  work area when the panel closes; the standard `toggle: { action, name,
143
143
  showLabel?, hideLabel? }` is always the final group.
144
144
 
145
+ The panel can also take `header` under its toolbar, `footer` below its content,
146
+ `bottomToolbar` below that, `headerList` / `footerList` for those fixed content
147
+ stacks, and `headerPlacement` / `footerPlacement` (`fixed`, `scroll`, or `auto`).
148
+ These slots share the panel's one `Pane` scroll owner; the bottom toolbar uses
149
+ footer semantics. With no `toolbar`, the panel renders its children directly
150
+ and ignores the chrome slots.
151
+
145
152
  The toolbar also takes the `Toolbar`'s configuration (`dividerSides`,
146
153
  `centerAlign`, `responsive`, `responsiveAt`, `safeAreaEdges`); it draws no
147
154
  divider of its own unless `dividerSides` says so. The `Pane` under it draws
@@ -243,6 +243,9 @@ example. Keep app and Kerf entries as package-qualified inputs, then let people
243
243
  or AI tools search their combined entries and compare `geometry` before adding
244
244
  wrappers or insets. Do not add app-owned entries to Kerf's canonical catalog or
245
245
  claim Kerf delivery paths for them.
246
+ Extension entries may add `uses` for direct composition dependencies and
247
+ repository-relative `source` and `demoSource` files. Resolve each dependency
248
+ against the combined Kerf and consumer catalogs; do not duplicate a Kerf id.
246
249
 
247
250
  - Components own semantic markup, stable anatomy, documented variants, ARIA projection, and package CSS hooks.
248
251
  - Applications own signals/stores, product copy, domain-state mapping, persistence, routing, permissions, and transport.
@@ -504,9 +507,10 @@ without application `::part(menu)` CSS; the default `standard` keeps each menu's
504
507
  own inset (8px for a raw `wa-dropdown`, the Select listbox's 4px for a
505
508
  `PopupMenu`), while `compact` and `list-zero` apply to every nested menu. A
506
509
  `PopupMenu` and a `Select` draw one popup: the same caret that turns to face the
507
- open popup, fade-in surface, surface inset, row height and padding, reserved
508
- check column, current-row fill, and group titles, all read from one private
509
- popup-choice contract in `foundation.css`. Compact mixed controls retain the standard
510
+ open popup, fade-in surface, surface inset, row height and padding, current-row
511
+ fill, and group titles, all read from one private popup-choice contract in
512
+ `foundation.css`. Checkbox items reserve a check column; plain commands start
513
+ at the checkmark's leading edge. Compact mixed controls retain the standard
510
514
  item padding, omit an internal separator, and let the raised selected item paint
511
515
  over the outer border instead of shrinking to an inset highlight. The Web
512
516
  Awesome trigger's shadow base owns max-content sizing, so icons, localized text,
@@ -578,7 +582,9 @@ by default it also owns the collapsible field's transient expand/collapse/focus
578
582
  state in a signal it exposes on the returned handle. An app reads that signal in
579
583
  render, hands in its own via `collapsible.signals`, drives it through
580
584
  `handle.open`/`handle.close`, or disables any individual behavior — so transient
581
- UI is consistent by default without every app reinventing it.
585
+ UI is consistent by default without every app reinventing it. A collapsed
586
+ field may reveal its editor after the current microtask; the helper keeps a
587
+ bounded render-frame focus handoff for that reveal and cancels it on disposal.
582
588
 
583
589
  A public subpath that exposes several visual components is a folder-backed
584
590
  surface. Put each component in its own source file and give each visual
@@ -202,11 +202,16 @@ whole label. `divider` owns a before or after separator. Set
202
202
  `--kui-list-item-*` tokens control its row, icon, label, and trailing geometry
203
203
  and color. `ListHeader` exposes `--kui-list-header-min-height`, title padding,
204
204
  title minimum height, and border-width tokens for section density.
205
+ Set `--kui-list-group-divider-color` on a containing `List` to give
206
+ `ListHeader`, `ListItem`, and `ListActionRow` the same before/after divider
207
+ color; each row otherwise uses the quiet neutral border tone.
205
208
  For a filled command list, set `--kui-list-item-background` and
206
- `--kui-list-item-border` on the list or row. The matching
207
- `--kui-list-item-hover-border` and `--kui-list-item-selected-border` tokens
208
- set state outlines without replacing ListItem CSS or neutralizing global
209
- semantic border colors.
209
+ `--kui-list-item-border` on the list or row. Scope `--kui-list-item-color`,
210
+ `--kui-list-item-hover-background`, `--kui-list-item-selected-color`, and
211
+ `--kui-list-item-selected-background` at the same boundary for text and state
212
+ fills. The matching `--kui-list-item-hover-border` and
213
+ `--kui-list-item-selected-border` tokens set state outlines without replacing
214
+ ListItem CSS or neutralizing global semantic border colors.
210
215
 
211
216
  Use `ListItemLink` from `@kerfjs/ui/list-item` for a navigation row with a
212
217
  real `href`. It shares `ListItem` content slots, density, selection, and row
@@ -276,7 +281,8 @@ For a compact `Select`, set `triggerWidth` to `"fit-content"`, `"max-content"`,
276
281
  or `"fill"` and cap it with `--kui-select-trigger-max-width` when needed.
277
282
  For a round icon-only toolbar trigger, set `selectedPresentation="icon-only"`
278
283
  and `caret={false}`. The control keeps its accessible name, current choice help
279
- tag, and keyboard-operated listbox; the default keeps the visible caret.
284
+ tag, and keyboard-operated listbox; the selected icon stays centered even when
285
+ `renderSelected` supplies it. The default keeps the visible caret.
280
286
  Custom `renderSelected` text inherits the control color by default; the
281
287
  `--kui-select-selected-color`, `--kui-select-selected-font-size`, and
282
288
  `--kui-select-selected-font-weight` tokens configure its typography. Plain
@@ -357,8 +363,18 @@ example `b`, `tr`, or `trbl`) only when the toolbar owns a permanent separator
357
363
  edge. Dividers earn their place: never fake one with a border or pad below one
358
364
  to make it look right.
359
365
 
366
+ `Toolbar` renders a semantic `header` by default. Set `position="footer"`
367
+ for a toolbar at the bottom of a pane or page; Workbench's
368
+ `mainBottomToolbar` and the catalog resource bar apply this automatically.
369
+ The position changes the HTML element without changing zones or geometry.
370
+
360
371
  Common toolbar patterns:
361
372
 
373
+ For a long-running icon action, set `busy` on its single-control
374
+ `ToolbarControlGroup` and supply a descriptive `busyLabel`. The group preserves
375
+ the control's dimensions, shows `LoadingSpinner` in its icon slot, sets
376
+ `aria-busy`, and makes the control inert until the app clears `busy`.
377
+
362
378
  | Want | Put in the zone | Notes |
363
379
  | ----------------------------- | -------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
364
380
  | Identity or title text | `<ToolbarText text="…" size="large" />` (or `xlarge` for a page/panel title that fits) | Wrap in a `single` borderless group only when it must align with adjacent control pills |
@@ -418,9 +434,12 @@ items shape covers single-line and batch actions; compute each batch child's
418
434
  ```
419
435
 
420
436
  For a flat command menu with persistent sort choices, group commands under
421
- `heading` entries and set `details` to a safe trailing tick for the chosen
422
- item. Set `checked` when checkbox menu semantics fit. Commands still dispatch
423
- their own `data-action` once on pointer and keyboard selection.
437
+ `heading` entries and set `checked` explicitly on each choice. Checked rows
438
+ show a checkmark; the background marks the current keyboard row, as in `Select`.
439
+ Only items with `checked: true` or `checked: false` reserve checkmark space.
440
+ Omit `checked` for a plain command, including one beside checkbox items.
441
+ Commands still dispatch their own `data-action` once on pointer and keyboard
442
+ selection.
424
443
 
425
444
  For a row opened by right-click, render `PopupMenu` with `context`, `label`,
426
445
  and a stable root `data-*` marker. Its trigger is an invisible anchor removed
@@ -469,6 +488,12 @@ geometry and 44px targets.
469
488
  </Pane>
470
489
  ```
471
490
 
491
+ When that child is a selectable card, configure `ContentItem` with
492
+ `interactive`, `action`, `itemId`, and a `selectionMode`; wire
493
+ `wireContentItems` once for Enter and Space. The component owns selection,
494
+ hover, focus, and disabled paint in its reserved 1px frame (see
495
+ [Content items](./layout.md#content-items)).
496
+
472
497
  Incorrect: duplicating component-like rows and compensating for nested padding
473
498
  forks the package anatomy and spacing contract.
474
499
 
@@ -489,6 +514,12 @@ The application updates its tag list after the action. `size="compact"` uses a
489
514
  20px chip with a 16px remove button, and `disabled` disables removal. Tone,
490
515
  appearance, and shape use the same semantic choices as `Badge`; use `Badge`
491
516
  when no removal is needed and the content is status or count metadata.
517
+ Pass an unsized, decorative `LucideIcon` through `icon` for a leading glyph;
518
+ Chip sizes it to its own type scale and aligns it beside the label. For a long
519
+ plain-text label, set `truncate`: the chip can shrink within a `Row`, its label
520
+ gets a one-line ellipsis, and the full string is the label's native `title`.
521
+ Keep a price or other unbreakable sibling in `Text wrap="nowrap"`. `truncate`
522
+ requires a string label so the title cannot lose text hidden inside markup.
492
523
 
493
524
  ```tsx
494
525
  <Chip
@@ -1 +1 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 104" width="640" height="104"><defs><clipPath id="cp0"><rect x="28" y="28" width="452" height="44"/></clipPath><clipPath id="ov1"><rect x="28" y="28" width="452" height="44" rx="0"/></clipPath><clipPath id="cp2"><rect x="30" y="30" width="88.1" height="40"/></clipPath><clipPath id="ov3"><rect x="30" y="30" width="88.1" height="40" rx="0"/></clipPath><clipPath id="cp4"><rect x="38" y="40.4" width="72.1" height="19.2"/></clipPath><clipPath id="ct5"><rect x="38" y="40.4" width="72.1" height="19.2"/></clipPath><clipPath id="cp6"><rect x="502" y="42" width="16" height="16"/></clipPath><clipPath id="cp8"><rect x="542" y="42" width="16" height="16"/></clipPath><clipPath id="cp10"><rect x="582" y="42" width="16" height="16"/></clipPath></defs><g clip-path="url(#cp0)"><g clip-path="url(#ov1)"><rect x="28.5" y="28.5" width="91" height="43" rx="21.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><g clip-path="url(#cp2)"><g clip-path="url(#ov3)"><g clip-path="url(#cp4)"><g clip-path="url(#ct5)"><text x="38" y="55.41" font-family="&quot;ui-sans-serif&quot;, &quot;-apple-system&quot;, &quot;system-ui&quot;, &quot;Segoe UI&quot;, sans-serif" font-size="16" font-weight="650" fill="rgb(174,174,178)">Northstar</text></g></g></g></g></g></g><rect x="488" y="28" width="124" height="44" rx="22" fill="rgb(58,58,60)"/><rect x="488.5" y="28.5" width="123" height="43" rx="21.5" fill="none" stroke="rgb(72,72,74)" stroke-width="1"/><rect x="490.5" y="30.5" width="39" height="39" rx="19.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><g clip-path="url(#cp6)"><g color="rgb(174, 174, 178)"><clipPath id="svgic7"><rect x="502" y="42" width="16" height="16"/></clipPath><g clip-path="url(#svgic7)"><g transform="translate(502 42)scale(.66667)"><path d="M3 5z" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(174, 174, 178)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M3 12z" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(174, 174, 178)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M3 19z" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(174, 174, 178)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M8 5h13" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(174, 174, 178)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M8 12h13" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(174, 174, 178)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M8 19h13" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(174, 174, 178)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/></g></g></g></g><rect x="530.5" y="30.5" width="39" height="39" rx="19.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><g clip-path="url(#cp8)"><g color="rgb(174, 174, 178)"><clipPath id="svgic9"><rect x="542" y="42" width="16" height="16"/></clipPath><g clip-path="url(#svgic9)"><g transform="translate(542 42)scale(.66667)"><rect width="18" height="18" x="3" y="3" rx="2" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(174, 174, 178)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M9 3v18" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(174, 174, 178)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M15 3v18" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(174, 174, 178)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/></g></g></g></g><rect x="570.5" y="30.5" width="39" height="39" rx="19.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><g clip-path="url(#cp10)"><g color="rgb(174, 174, 178)"><clipPath id="svgic11"><rect x="582" y="42" width="16" height="16"/></clipPath><g clip-path="url(#svgic11)"><g transform="translate(582 42)scale(.66667)"><path d="M9.7 4.1a2.3 2.3 0 0 1 4.6 0 2.3 2.3 0 0 0 3.3 2 2.3 2.3 0 0 1 2.4 4 2.3 2.3 0 0 0 0 3.8 2.3 2.3 0 0 1-2.4 4 2.3 2.3 0 0 0-3.3 2 2.3 2.3 0 0 1-4.6 0 2.3 2.3 0 0 0-3.3-2A2.3 2.3 0 0 1 4 14a2.3 2.3 0 0 0 0-3.8 2.3 2.3 0 0 1 2.3-4 2.3 2.3 0 0 0 3.4-2" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(174, 174, 178)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><circle cx="12" cy="12" r="3" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(174, 174, 178)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/></g></g></g></g></svg>
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 104" width="640" height="104"><defs><clipPath id="cp0"><rect x="28" y="28" width="452" height="44"/></clipPath><clipPath id="ov1"><rect x="28" y="28" width="452" height="44" rx="0"/></clipPath><clipPath id="cp2"><rect x="30" y="30" width="88.1" height="40"/></clipPath><clipPath id="ov3"><rect x="30" y="30" width="88.1" height="40" rx="0"/></clipPath><clipPath id="cp4"><rect x="38" y="40.4" width="72.1" height="19.2"/></clipPath><clipPath id="ct5"><rect x="38" y="40.4" width="72.1" height="19.2"/></clipPath><clipPath id="cp6"><rect x="502" y="42" width="16" height="16"/></clipPath><clipPath id="cp8"><rect x="542" y="42" width="16" height="16"/></clipPath><clipPath id="cp10"><rect x="582" y="42" width="16" height="16"/></clipPath></defs><g clip-path="url(#cp0)"/><g clip-path="url(#ov1)"><rect x="28.5" y="28.5" width="91" height="43" rx="21.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><g clip-path="url(#cp2)"><g clip-path="url(#ov3)"><g clip-path="url(#cp4)"><g clip-path="url(#ct5)"><text x="38" y="55.41" font-family="&quot;ui-sans-serif&quot;, &quot;-apple-system&quot;, &quot;system-ui&quot;, &quot;Segoe UI&quot;, sans-serif" font-size="16" font-weight="650" fill="rgb(174,174,178)">Northstar</text></g></g></g></g></g><rect x="488" y="28" width="124" height="44" rx="22" fill="rgb(58,58,60)"/><rect x="488.5" y="28.5" width="123" height="43" rx="21.5" fill="none" stroke="rgb(72,72,74)" stroke-width="1"/><rect x="490.5" y="30.5" width="39" height="39" rx="19.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><g clip-path="url(#cp6)"><g color="rgb(174, 174, 178)"><clipPath id="svgic7"><rect x="502" y="42" width="16" height="16"/></clipPath><g clip-path="url(#svgic7)"><g transform="translate(502 42)scale(.66667)"><path d="M3 5z" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(174, 174, 178)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M3 12z" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(174, 174, 178)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M3 19z" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(174, 174, 178)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M8 5h13" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(174, 174, 178)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M8 12h13" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(174, 174, 178)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M8 19h13" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(174, 174, 178)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/></g></g></g></g><rect x="530.5" y="30.5" width="39" height="39" rx="19.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><g clip-path="url(#cp8)"><g color="rgb(174, 174, 178)"><clipPath id="svgic9"><rect x="542" y="42" width="16" height="16"/></clipPath><g clip-path="url(#svgic9)"><g transform="translate(542 42)scale(.66667)"><rect width="18" height="18" x="3" y="3" rx="2" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(174, 174, 178)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M9 3v18" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(174, 174, 178)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M15 3v18" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(174, 174, 178)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/></g></g></g></g><rect x="570.5" y="30.5" width="39" height="39" rx="19.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><g clip-path="url(#cp10)"><g color="rgb(174, 174, 178)"><clipPath id="svgic11"><rect x="582" y="42" width="16" height="16"/></clipPath><g clip-path="url(#svgic11)"><g transform="translate(582 42)scale(.66667)"><path d="M9.7 4.1a2.3 2.3 0 0 1 4.6 0 2.3 2.3 0 0 0 3.3 2 2.3 2.3 0 0 1 2.4 4 2.3 2.3 0 0 0 0 3.8 2.3 2.3 0 0 1-2.4 4 2.3 2.3 0 0 0-3.3 2 2.3 2.3 0 0 1-4.6 0 2.3 2.3 0 0 0-3.3-2A2.3 2.3 0 0 1 4 14a2.3 2.3 0 0 0 0-3.8 2.3 2.3 0 0 1 2.3-4 2.3 2.3 0 0 0 3.4-2" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(174, 174, 178)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><circle cx="12" cy="12" r="3" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(174, 174, 178)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/></g></g></g></g></svg>
@@ -1 +1 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 104" width="640" height="104"><defs><clipPath id="cp0"><rect x="28" y="28" width="452" height="44"/></clipPath><clipPath id="ov1"><rect x="28" y="28" width="452" height="44" rx="0"/></clipPath><clipPath id="cp2"><rect x="30" y="30" width="88.1" height="40"/></clipPath><clipPath id="ov3"><rect x="30" y="30" width="88.1" height="40" rx="0"/></clipPath><clipPath id="cp4"><rect x="38" y="40.4" width="72.1" height="19.2"/></clipPath><clipPath id="ct5"><rect x="38" y="40.4" width="72.1" height="19.2"/></clipPath><clipPath id="cp6"><rect x="502" y="42" width="16" height="16"/></clipPath><clipPath id="cp8"><rect x="542" y="42" width="16" height="16"/></clipPath><clipPath id="cp10"><rect x="582" y="42" width="16" height="16"/></clipPath></defs><g clip-path="url(#cp0)"><g clip-path="url(#ov1)"><rect x="28.5" y="28.5" width="91" height="43" rx="21.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><g clip-path="url(#cp2)"><g clip-path="url(#ov3)"><g clip-path="url(#cp4)"><g clip-path="url(#ct5)"><text x="38" y="55.41" font-family="&quot;ui-sans-serif&quot;, &quot;-apple-system&quot;, &quot;system-ui&quot;, &quot;Segoe UI&quot;, sans-serif" font-size="16" font-weight="650" fill="rgb(110,110,115)">Northstar</text></g></g></g></g></g></g><rect x="488" y="28" width="124" height="44" rx="22" fill="rgb(229,229,234)"/><rect x="488.5" y="28.5" width="123" height="43" rx="21.5" fill="none" stroke="rgb(209,209,214)" stroke-width="1"/><rect x="490.5" y="30.5" width="39" height="39" rx="19.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><g clip-path="url(#cp6)"><g color="rgb(110, 110, 115)"><clipPath id="svgic7"><rect x="502" y="42" width="16" height="16"/></clipPath><g clip-path="url(#svgic7)"><g transform="translate(502 42)scale(.66667)"><path d="M3 5z" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(110, 110, 115)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M3 12z" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(110, 110, 115)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M3 19z" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(110, 110, 115)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M8 5h13" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(110, 110, 115)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M8 12h13" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(110, 110, 115)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M8 19h13" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(110, 110, 115)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/></g></g></g></g><rect x="530.5" y="30.5" width="39" height="39" rx="19.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><g clip-path="url(#cp8)"><g color="rgb(110, 110, 115)"><clipPath id="svgic9"><rect x="542" y="42" width="16" height="16"/></clipPath><g clip-path="url(#svgic9)"><g transform="translate(542 42)scale(.66667)"><rect width="18" height="18" x="3" y="3" rx="2" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(110, 110, 115)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M9 3v18" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(110, 110, 115)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M15 3v18" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(110, 110, 115)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/></g></g></g></g><rect x="570.5" y="30.5" width="39" height="39" rx="19.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><g clip-path="url(#cp10)"><g color="rgb(110, 110, 115)"><clipPath id="svgic11"><rect x="582" y="42" width="16" height="16"/></clipPath><g clip-path="url(#svgic11)"><g transform="translate(582 42)scale(.66667)"><path d="M9.7 4.1a2.3 2.3 0 0 1 4.6 0 2.3 2.3 0 0 0 3.3 2 2.3 2.3 0 0 1 2.4 4 2.3 2.3 0 0 0 0 3.8 2.3 2.3 0 0 1-2.4 4 2.3 2.3 0 0 0-3.3 2 2.3 2.3 0 0 1-4.6 0 2.3 2.3 0 0 0-3.3-2A2.3 2.3 0 0 1 4 14a2.3 2.3 0 0 0 0-3.8 2.3 2.3 0 0 1 2.3-4 2.3 2.3 0 0 0 3.4-2" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(110, 110, 115)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><circle cx="12" cy="12" r="3" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(110, 110, 115)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/></g></g></g></g></svg>
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 104" width="640" height="104"><defs><clipPath id="cp0"><rect x="28" y="28" width="452" height="44"/></clipPath><clipPath id="ov1"><rect x="28" y="28" width="452" height="44" rx="0"/></clipPath><clipPath id="cp2"><rect x="30" y="30" width="88.1" height="40"/></clipPath><clipPath id="ov3"><rect x="30" y="30" width="88.1" height="40" rx="0"/></clipPath><clipPath id="cp4"><rect x="38" y="40.4" width="72.1" height="19.2"/></clipPath><clipPath id="ct5"><rect x="38" y="40.4" width="72.1" height="19.2"/></clipPath><clipPath id="cp6"><rect x="502" y="42" width="16" height="16"/></clipPath><clipPath id="cp8"><rect x="542" y="42" width="16" height="16"/></clipPath><clipPath id="cp10"><rect x="582" y="42" width="16" height="16"/></clipPath></defs><g clip-path="url(#cp0)"/><g clip-path="url(#ov1)"><rect x="28.5" y="28.5" width="91" height="43" rx="21.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><g clip-path="url(#cp2)"><g clip-path="url(#ov3)"><g clip-path="url(#cp4)"><g clip-path="url(#ct5)"><text x="38" y="55.41" font-family="&quot;ui-sans-serif&quot;, &quot;-apple-system&quot;, &quot;system-ui&quot;, &quot;Segoe UI&quot;, sans-serif" font-size="16" font-weight="650" fill="rgb(110,110,115)">Northstar</text></g></g></g></g></g><rect x="488" y="28" width="124" height="44" rx="22" fill="rgb(229,229,234)"/><rect x="488.5" y="28.5" width="123" height="43" rx="21.5" fill="none" stroke="rgb(209,209,214)" stroke-width="1"/><rect x="490.5" y="30.5" width="39" height="39" rx="19.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><g clip-path="url(#cp6)"><g color="rgb(110, 110, 115)"><clipPath id="svgic7"><rect x="502" y="42" width="16" height="16"/></clipPath><g clip-path="url(#svgic7)"><g transform="translate(502 42)scale(.66667)"><path d="M3 5z" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(110, 110, 115)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M3 12z" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(110, 110, 115)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M3 19z" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(110, 110, 115)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M8 5h13" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(110, 110, 115)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M8 12h13" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(110, 110, 115)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M8 19h13" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(110, 110, 115)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/></g></g></g></g><rect x="530.5" y="30.5" width="39" height="39" rx="19.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><g clip-path="url(#cp8)"><g color="rgb(110, 110, 115)"><clipPath id="svgic9"><rect x="542" y="42" width="16" height="16"/></clipPath><g clip-path="url(#svgic9)"><g transform="translate(542 42)scale(.66667)"><rect width="18" height="18" x="3" y="3" rx="2" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(110, 110, 115)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M9 3v18" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(110, 110, 115)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M15 3v18" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(110, 110, 115)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/></g></g></g></g><rect x="570.5" y="30.5" width="39" height="39" rx="19.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><g clip-path="url(#cp10)"><g color="rgb(110, 110, 115)"><clipPath id="svgic11"><rect x="582" y="42" width="16" height="16"/></clipPath><g clip-path="url(#svgic11)"><g transform="translate(582 42)scale(.66667)"><path d="M9.7 4.1a2.3 2.3 0 0 1 4.6 0 2.3 2.3 0 0 0 3.3 2 2.3 2.3 0 0 1 2.4 4 2.3 2.3 0 0 0 0 3.8 2.3 2.3 0 0 1-2.4 4 2.3 2.3 0 0 0-3.3 2 2.3 2.3 0 0 1-4.6 0 2.3 2.3 0 0 0-3.3-2A2.3 2.3 0 0 1 4 14a2.3 2.3 0 0 0 0-3.8 2.3 2.3 0 0 1 2.3-4 2.3 2.3 0 0 0 3.4-2" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(110, 110, 115)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><circle cx="12" cy="12" r="3" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(110, 110, 115)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/></g></g></g></g></svg>
@@ -1 +1 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 672 158" width="672" height="158"><defs><clipPath id="cp0"><rect x="16" y="38" width="640" height="104"/></clipPath><clipPath id="ct1"><rect x="16" y="16" width="640" height="22"/></clipPath><clipPath id="irc2"><rect x="16" y="38" width="640" height="104" rx="0"/></clipPath></defs><rect x="0" y="0" width="672" height="158" 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)">Title with a trailing group</text><g clip-path="url(#cp0)"><g clip-path="url(#irc2)"><clipPath id="svgimg3vclip"><rect x="16" y="38" width="640" height="104"/></clipPath><g clip-path="url(#svgimg3vclip)"><g transform="translate(16 38)"><defs><clipPath id="svgimg3cp0"><rect x="28" y="28" width="452" height="44"/></clipPath><clipPath id="svgimg3ov1"><rect x="28" y="28" width="452" height="44" rx="0"/></clipPath><clipPath id="svgimg3cp2"><rect x="30" y="30" width="88.1" height="40"/></clipPath><clipPath id="svgimg3ov3"><rect x="30" y="30" width="88.1" height="40" rx="0"/></clipPath><clipPath id="svgimg3cp4"><rect x="38" y="40.4" width="72.1" height="19.2"/></clipPath><clipPath id="svgimg3ct5"><rect x="38" y="40.4" width="72.1" height="19.2"/></clipPath><clipPath id="svgimg3cp6"><rect x="502" y="42" width="16" height="16"/></clipPath><clipPath id="svgimg3cp8"><rect x="542" y="42" width="16" height="16"/></clipPath><clipPath id="svgimg3cp10"><rect x="582" y="42" width="16" height="16"/></clipPath></defs><g clip-path="url(#svgimg3cp0)"><g clip-path="url(#svgimg3ov1)"><rect x="28.5" y="28.5" width="91" height="43" rx="21.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><g clip-path="url(#svgimg3cp2)"><g clip-path="url(#svgimg3ov3)"><g clip-path="url(#svgimg3cp4)"><g clip-path="url(#svgimg3ct5)"><text x="38" y="55.41" font-family="&quot;ui-sans-serif&quot;, &quot;-apple-system&quot;, &quot;system-ui&quot;, &quot;Segoe UI&quot;, sans-serif" font-size="16" font-weight="650" fill="rgb(174,174,178)">Northstar</text></g></g></g></g></g></g><rect x="488" y="28" width="124" height="44" rx="22" fill="rgb(58,58,60)"/><rect x="488.5" y="28.5" width="123" height="43" rx="21.5" fill="none" stroke="rgb(72,72,74)" stroke-width="1"/><rect x="490.5" y="30.5" width="39" height="39" rx="19.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><g clip-path="url(#svgimg3cp6)"><g color="rgb(174, 174, 178)"><clipPath id="svgimg3svgic7"><rect x="502" y="42" width="16" height="16"/></clipPath><g clip-path="url(#svgimg3svgic7)"><g transform="translate(502 42)scale(.66667)"><path d="M3 5z" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(174, 174, 178)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M3 12z" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(174, 174, 178)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M3 19z" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(174, 174, 178)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M8 5h13" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(174, 174, 178)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M8 12h13" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(174, 174, 178)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M8 19h13" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(174, 174, 178)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/></g></g></g></g><rect x="530.5" y="30.5" width="39" height="39" rx="19.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><g clip-path="url(#svgimg3cp8)"><g color="rgb(174, 174, 178)"><clipPath id="svgimg3svgic9"><rect x="542" y="42" width="16" height="16"/></clipPath><g clip-path="url(#svgimg3svgic9)"><g transform="translate(542 42)scale(.66667)"><rect width="18" height="18" x="3" y="3" rx="2" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(174, 174, 178)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M9 3v18" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(174, 174, 178)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M15 3v18" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(174, 174, 178)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/></g></g></g></g><rect x="570.5" y="30.5" width="39" height="39" rx="19.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><g clip-path="url(#svgimg3cp10)"><g color="rgb(174, 174, 178)"><clipPath id="svgimg3svgic11"><rect x="582" y="42" width="16" height="16"/></clipPath><g clip-path="url(#svgimg3svgic11)"><g transform="translate(582 42)scale(.66667)"><path d="M9.7 4.1a2.3 2.3 0 0 1 4.6 0 2.3 2.3 0 0 0 3.3 2 2.3 2.3 0 0 1 2.4 4 2.3 2.3 0 0 0 0 3.8 2.3 2.3 0 0 1-2.4 4 2.3 2.3 0 0 0-3.3 2 2.3 2.3 0 0 1-4.6 0 2.3 2.3 0 0 0-3.3-2A2.3 2.3 0 0 1 4 14a2.3 2.3 0 0 0 0-3.8 2.3 2.3 0 0 1 2.3-4 2.3 2.3 0 0 0 3.4-2" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(174, 174, 178)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><circle cx="12" cy="12" r="3" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(174, 174, 178)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/></g></g></g></g></g></g></g></g></svg>
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 672 158" width="672" height="158"><defs><clipPath id="cp0"><rect x="16" y="38" width="640" height="104"/></clipPath><clipPath id="ct1"><rect x="16" y="16" width="640" height="22"/></clipPath><clipPath id="irc2"><rect x="16" y="38" width="640" height="104" rx="0"/></clipPath></defs><rect x="0" y="0" width="672" height="158" 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)">Title with a trailing group</text><g clip-path="url(#cp0)"><g clip-path="url(#irc2)"><clipPath id="svgimg3vclip"><rect x="16" y="38" width="640" height="104"/></clipPath><g clip-path="url(#svgimg3vclip)"><g transform="translate(16 38)"><defs><clipPath id="svgimg3cp0"><rect x="28" y="28" width="452" height="44"/></clipPath><clipPath id="svgimg3ov1"><rect x="28" y="28" width="452" height="44" rx="0"/></clipPath><clipPath id="svgimg3cp2"><rect x="30" y="30" width="88.1" height="40"/></clipPath><clipPath id="svgimg3ov3"><rect x="30" y="30" width="88.1" height="40" rx="0"/></clipPath><clipPath id="svgimg3cp4"><rect x="38" y="40.4" width="72.1" height="19.2"/></clipPath><clipPath id="svgimg3ct5"><rect x="38" y="40.4" width="72.1" height="19.2"/></clipPath><clipPath id="svgimg3cp6"><rect x="502" y="42" width="16" height="16"/></clipPath><clipPath id="svgimg3cp8"><rect x="542" y="42" width="16" height="16"/></clipPath><clipPath id="svgimg3cp10"><rect x="582" y="42" width="16" height="16"/></clipPath></defs><g clip-path="url(#svgimg3cp0)"/><g clip-path="url(#svgimg3ov1)"><rect x="28.5" y="28.5" width="91" height="43" rx="21.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><g clip-path="url(#svgimg3cp2)"><g clip-path="url(#svgimg3ov3)"><g clip-path="url(#svgimg3cp4)"><g clip-path="url(#svgimg3ct5)"><text x="38" y="55.41" font-family="&quot;ui-sans-serif&quot;, &quot;-apple-system&quot;, &quot;system-ui&quot;, &quot;Segoe UI&quot;, sans-serif" font-size="16" font-weight="650" fill="rgb(174,174,178)">Northstar</text></g></g></g></g></g><rect x="488" y="28" width="124" height="44" rx="22" fill="rgb(58,58,60)"/><rect x="488.5" y="28.5" width="123" height="43" rx="21.5" fill="none" stroke="rgb(72,72,74)" stroke-width="1"/><rect x="490.5" y="30.5" width="39" height="39" rx="19.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><g clip-path="url(#svgimg3cp6)"><g color="rgb(174, 174, 178)"><clipPath id="svgimg3svgic7"><rect x="502" y="42" width="16" height="16"/></clipPath><g clip-path="url(#svgimg3svgic7)"><g transform="translate(502 42)scale(.66667)"><path d="M3 5z" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(174, 174, 178)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M3 12z" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(174, 174, 178)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M3 19z" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(174, 174, 178)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M8 5h13" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(174, 174, 178)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M8 12h13" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(174, 174, 178)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M8 19h13" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(174, 174, 178)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/></g></g></g></g><rect x="530.5" y="30.5" width="39" height="39" rx="19.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><g clip-path="url(#svgimg3cp8)"><g color="rgb(174, 174, 178)"><clipPath id="svgimg3svgic9"><rect x="542" y="42" width="16" height="16"/></clipPath><g clip-path="url(#svgimg3svgic9)"><g transform="translate(542 42)scale(.66667)"><rect width="18" height="18" x="3" y="3" rx="2" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(174, 174, 178)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M9 3v18" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(174, 174, 178)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M15 3v18" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(174, 174, 178)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/></g></g></g></g><rect x="570.5" y="30.5" width="39" height="39" rx="19.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><g clip-path="url(#svgimg3cp10)"><g color="rgb(174, 174, 178)"><clipPath id="svgimg3svgic11"><rect x="582" y="42" width="16" height="16"/></clipPath><g clip-path="url(#svgimg3svgic11)"><g transform="translate(582 42)scale(.66667)"><path d="M9.7 4.1a2.3 2.3 0 0 1 4.6 0 2.3 2.3 0 0 0 3.3 2 2.3 2.3 0 0 1 2.4 4 2.3 2.3 0 0 0 0 3.8 2.3 2.3 0 0 1-2.4 4 2.3 2.3 0 0 0-3.3 2 2.3 2.3 0 0 1-4.6 0 2.3 2.3 0 0 0-3.3-2A2.3 2.3 0 0 1 4 14a2.3 2.3 0 0 0 0-3.8 2.3 2.3 0 0 1 2.3-4 2.3 2.3 0 0 0 3.4-2" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(174, 174, 178)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><circle cx="12" cy="12" r="3" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(174, 174, 178)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/></g></g></g></g></g></g></g></g></svg>
@@ -1 +1 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 672 158" width="672" height="158"><defs><clipPath id="cp0"><rect x="16" y="38" width="640" height="104"/></clipPath><clipPath id="ct1"><rect x="16" y="16" width="640" height="22"/></clipPath><clipPath id="irc2"><rect x="16" y="38" width="640" height="104" rx="0"/></clipPath></defs><rect x="0" y="0" width="672" height="158" 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)">Title with a trailing group</text><g clip-path="url(#cp0)"><g clip-path="url(#irc2)"><clipPath id="svgimg3vclip"><rect x="16" y="38" width="640" height="104"/></clipPath><g clip-path="url(#svgimg3vclip)"><g transform="translate(16 38)"><defs><clipPath id="svgimg3cp0"><rect x="28" y="28" width="452" height="44"/></clipPath><clipPath id="svgimg3ov1"><rect x="28" y="28" width="452" height="44" rx="0"/></clipPath><clipPath id="svgimg3cp2"><rect x="30" y="30" width="88.1" height="40"/></clipPath><clipPath id="svgimg3ov3"><rect x="30" y="30" width="88.1" height="40" rx="0"/></clipPath><clipPath id="svgimg3cp4"><rect x="38" y="40.4" width="72.1" height="19.2"/></clipPath><clipPath id="svgimg3ct5"><rect x="38" y="40.4" width="72.1" height="19.2"/></clipPath><clipPath id="svgimg3cp6"><rect x="502" y="42" width="16" height="16"/></clipPath><clipPath id="svgimg3cp8"><rect x="542" y="42" width="16" height="16"/></clipPath><clipPath id="svgimg3cp10"><rect x="582" y="42" width="16" height="16"/></clipPath></defs><g clip-path="url(#svgimg3cp0)"><g clip-path="url(#svgimg3ov1)"><rect x="28.5" y="28.5" width="91" height="43" rx="21.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><g clip-path="url(#svgimg3cp2)"><g clip-path="url(#svgimg3ov3)"><g clip-path="url(#svgimg3cp4)"><g clip-path="url(#svgimg3ct5)"><text x="38" y="55.41" font-family="&quot;ui-sans-serif&quot;, &quot;-apple-system&quot;, &quot;system-ui&quot;, &quot;Segoe UI&quot;, sans-serif" font-size="16" font-weight="650" fill="rgb(110,110,115)">Northstar</text></g></g></g></g></g></g><rect x="488" y="28" width="124" height="44" rx="22" fill="rgb(229,229,234)"/><rect x="488.5" y="28.5" width="123" height="43" rx="21.5" fill="none" stroke="rgb(209,209,214)" stroke-width="1"/><rect x="490.5" y="30.5" width="39" height="39" rx="19.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><g clip-path="url(#svgimg3cp6)"><g color="rgb(110, 110, 115)"><clipPath id="svgimg3svgic7"><rect x="502" y="42" width="16" height="16"/></clipPath><g clip-path="url(#svgimg3svgic7)"><g transform="translate(502 42)scale(.66667)"><path d="M3 5z" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(110, 110, 115)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M3 12z" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(110, 110, 115)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M3 19z" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(110, 110, 115)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M8 5h13" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(110, 110, 115)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M8 12h13" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(110, 110, 115)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M8 19h13" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(110, 110, 115)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/></g></g></g></g><rect x="530.5" y="30.5" width="39" height="39" rx="19.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><g clip-path="url(#svgimg3cp8)"><g color="rgb(110, 110, 115)"><clipPath id="svgimg3svgic9"><rect x="542" y="42" width="16" height="16"/></clipPath><g clip-path="url(#svgimg3svgic9)"><g transform="translate(542 42)scale(.66667)"><rect width="18" height="18" x="3" y="3" rx="2" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(110, 110, 115)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M9 3v18" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(110, 110, 115)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M15 3v18" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(110, 110, 115)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/></g></g></g></g><rect x="570.5" y="30.5" width="39" height="39" rx="19.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><g clip-path="url(#svgimg3cp10)"><g color="rgb(110, 110, 115)"><clipPath id="svgimg3svgic11"><rect x="582" y="42" width="16" height="16"/></clipPath><g clip-path="url(#svgimg3svgic11)"><g transform="translate(582 42)scale(.66667)"><path d="M9.7 4.1a2.3 2.3 0 0 1 4.6 0 2.3 2.3 0 0 0 3.3 2 2.3 2.3 0 0 1 2.4 4 2.3 2.3 0 0 0 0 3.8 2.3 2.3 0 0 1-2.4 4 2.3 2.3 0 0 0-3.3 2 2.3 2.3 0 0 1-4.6 0 2.3 2.3 0 0 0-3.3-2A2.3 2.3 0 0 1 4 14a2.3 2.3 0 0 0 0-3.8 2.3 2.3 0 0 1 2.3-4 2.3 2.3 0 0 0 3.4-2" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(110, 110, 115)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><circle cx="12" cy="12" r="3" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(110, 110, 115)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/></g></g></g></g></g></g></g></g></svg>
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 672 158" width="672" height="158"><defs><clipPath id="cp0"><rect x="16" y="38" width="640" height="104"/></clipPath><clipPath id="ct1"><rect x="16" y="16" width="640" height="22"/></clipPath><clipPath id="irc2"><rect x="16" y="38" width="640" height="104" rx="0"/></clipPath></defs><rect x="0" y="0" width="672" height="158" 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)">Title with a trailing group</text><g clip-path="url(#cp0)"><g clip-path="url(#irc2)"><clipPath id="svgimg3vclip"><rect x="16" y="38" width="640" height="104"/></clipPath><g clip-path="url(#svgimg3vclip)"><g transform="translate(16 38)"><defs><clipPath id="svgimg3cp0"><rect x="28" y="28" width="452" height="44"/></clipPath><clipPath id="svgimg3ov1"><rect x="28" y="28" width="452" height="44" rx="0"/></clipPath><clipPath id="svgimg3cp2"><rect x="30" y="30" width="88.1" height="40"/></clipPath><clipPath id="svgimg3ov3"><rect x="30" y="30" width="88.1" height="40" rx="0"/></clipPath><clipPath id="svgimg3cp4"><rect x="38" y="40.4" width="72.1" height="19.2"/></clipPath><clipPath id="svgimg3ct5"><rect x="38" y="40.4" width="72.1" height="19.2"/></clipPath><clipPath id="svgimg3cp6"><rect x="502" y="42" width="16" height="16"/></clipPath><clipPath id="svgimg3cp8"><rect x="542" y="42" width="16" height="16"/></clipPath><clipPath id="svgimg3cp10"><rect x="582" y="42" width="16" height="16"/></clipPath></defs><g clip-path="url(#svgimg3cp0)"/><g clip-path="url(#svgimg3ov1)"><rect x="28.5" y="28.5" width="91" height="43" rx="21.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><g clip-path="url(#svgimg3cp2)"><g clip-path="url(#svgimg3ov3)"><g clip-path="url(#svgimg3cp4)"><g clip-path="url(#svgimg3ct5)"><text x="38" y="55.41" font-family="&quot;ui-sans-serif&quot;, &quot;-apple-system&quot;, &quot;system-ui&quot;, &quot;Segoe UI&quot;, sans-serif" font-size="16" font-weight="650" fill="rgb(110,110,115)">Northstar</text></g></g></g></g></g><rect x="488" y="28" width="124" height="44" rx="22" fill="rgb(229,229,234)"/><rect x="488.5" y="28.5" width="123" height="43" rx="21.5" fill="none" stroke="rgb(209,209,214)" stroke-width="1"/><rect x="490.5" y="30.5" width="39" height="39" rx="19.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><g clip-path="url(#svgimg3cp6)"><g color="rgb(110, 110, 115)"><clipPath id="svgimg3svgic7"><rect x="502" y="42" width="16" height="16"/></clipPath><g clip-path="url(#svgimg3svgic7)"><g transform="translate(502 42)scale(.66667)"><path d="M3 5z" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(110, 110, 115)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M3 12z" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(110, 110, 115)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M3 19z" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(110, 110, 115)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M8 5h13" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(110, 110, 115)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M8 12h13" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(110, 110, 115)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M8 19h13" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(110, 110, 115)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/></g></g></g></g><rect x="530.5" y="30.5" width="39" height="39" rx="19.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><g clip-path="url(#svgimg3cp8)"><g color="rgb(110, 110, 115)"><clipPath id="svgimg3svgic9"><rect x="542" y="42" width="16" height="16"/></clipPath><g clip-path="url(#svgimg3svgic9)"><g transform="translate(542 42)scale(.66667)"><rect width="18" height="18" x="3" y="3" rx="2" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(110, 110, 115)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M9 3v18" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(110, 110, 115)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M15 3v18" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(110, 110, 115)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/></g></g></g></g><rect x="570.5" y="30.5" width="39" height="39" rx="19.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><g clip-path="url(#svgimg3cp10)"><g color="rgb(110, 110, 115)"><clipPath id="svgimg3svgic11"><rect x="582" y="42" width="16" height="16"/></clipPath><g clip-path="url(#svgimg3svgic11)"><g transform="translate(582 42)scale(.66667)"><path d="M9.7 4.1a2.3 2.3 0 0 1 4.6 0 2.3 2.3 0 0 0 3.3 2 2.3 2.3 0 0 1 2.4 4 2.3 2.3 0 0 0 0 3.8 2.3 2.3 0 0 1-2.4 4 2.3 2.3 0 0 0-3.3 2 2.3 2.3 0 0 1-4.6 0 2.3 2.3 0 0 0-3.3-2A2.3 2.3 0 0 1 4 14a2.3 2.3 0 0 0 0-3.8 2.3 2.3 0 0 1 2.3-4 2.3 2.3 0 0 0 3.4-2" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(110, 110, 115)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><circle cx="12" cy="12" r="3" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(110, 110, 115)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/></g></g></g></g></g></g></g></g></svg>
@@ -17,6 +17,9 @@
17
17
  ],
18
18
  "publicClasses": ["acme-filter-chip"],
19
19
  "publicTokens": ["--acme-filter-chip-accent"],
20
+ "uses": ["chip"],
21
+ "source": "src/filter-chip.tsx",
22
+ "demoSource": "ux-demo/demos/filter-chip.tsx",
20
23
  "geometry": {
21
24
  "margin": "none",
22
25
  "border": "self",
@@ -31,6 +34,9 @@
31
34
  "purpose": "An application inspector composed from Kerf panel, content, and value primitives.",
32
35
  "useWhen": ["A selected record needs a titled fact-and-action region."],
33
36
  "avoidWhen": ["A ValueTable alone expresses the complete interaction."],
37
+ "uses": ["acme-filter-chip", "toolbar", "value-table"],
38
+ "source": "src/inspector.tsx",
39
+ "demoSource": "ux-demo/demos/inspector.tsx",
34
40
  "geometry": {
35
41
  "margin": "parent",
36
42
  "border": "child",
package/docs/layout.md CHANGED
@@ -45,6 +45,9 @@ content scroller; with `chromePlacement="auto"`, the Pane root paints the
45
45
  surface because it becomes the scroller in a short viewport. Header and footer
46
46
  chrome stay on the normal surface. No second scroll container or
47
47
  `SunkenPanel` wrapper is needed.
48
+ Sunken panes draw their header/footer dividers by default, even when short
49
+ content does not scroll. Pass `chromeDividers="scroll"` to restore scroll-state
50
+ dividers or `"none"` to hide them.
48
51
  For custom chrome colors in auto mode, set `--kui-pane-chrome-background`
49
52
  on the Pane; it defaults to `--kui-color-surface`.
50
53
 
@@ -116,9 +119,10 @@ Toolbar, and List stylesheets draw from those. The line is an inset shadow or a
116
119
  inside the component, so no state ever moves the chrome, the content, or a tab.
117
120
  Never write a border onto a component to show one.
118
121
 
119
- Configure a pane with `chromeDividers`: `scroll` (the default) follows the
120
- scroll state and draws nothing until the wiring runs; `always` keeps both lines;
121
- `none` drops them. Layouts forward it through `PaneConfig`
122
+ Configure a pane with `chromeDividers`: `scroll` (the plain-pane default) follows
123
+ the scroll state and draws nothing until the wiring runs; `always` (the sunken
124
+ pane default) keeps both lines; `none` drops them. Explicit values override
125
+ either default. Layouts forward it through `PaneConfig`
122
126
  (`mainPane.chromeDividers`, a panel's `pane.chromeDividers`). A `NavStack` and a
123
127
  `TabScaffold` take the same `chromeDividers` for their own chrome (the stack's
124
128
  top chrome and bottom toolbar, the scaffold's bar), and a `SplitView` forwards
@@ -200,6 +204,18 @@ region (`role="region"`), and `focusTarget` to make the item a programmatic
200
204
  focus target (`tabindex="-1"`), for example a NavStack view's `data-nav-focus`
201
205
  target.
202
206
 
207
+ For a selectable card, set `interactive`, a delegated `action`, and an optional
208
+ `itemId`. Wire `wireContentItems(root)` once on the containing app root; it
209
+ activates focused cards with Enter or Space and forwards the resulting click to
210
+ the app's ordinary `data-action` handler. `selectionMode="toggle"` maps
211
+ `selected` to a button's `aria-pressed`; `selectionMode="single"` maps it to an
212
+ option's `aria-selected` and belongs in an app-owned `role="listbox"` container.
213
+ An interactive card is a Tab stop, and `disabled` removes its action and Tab
214
+ stop while exposing `aria-disabled`. Keep interactive descendants outside a
215
+ card; a card is one action target. Hover, pressed, focus, and selected paints
216
+ reuse the reserved border without changing geometry. `rootAttributes` still
217
+ accepts safe app `data-*` metadata, while the card owns its interaction data.
218
+
203
219
  The rendered classes — `.kui-content-item`, `.kui-content-item--framed`, and
204
220
  `.kui-content-item--pill` — stay public for the rare element that must carry the
205
221
  geometry itself (for example a `<ul>` list or a `Text` paragraph in an
@@ -322,6 +338,14 @@ display copy, and `font="monospace"` for code or identifiers (the
322
338
  finite props compose with each other and with every semantic `variant`; omit
323
339
  them to inherit the surrounding color, size, and font.
324
340
 
341
+ Control long copy with `wrap`: `normal` (default) restores ordinary wrapping,
342
+ `anywhere` breaks long unbroken strings, `nowrap` holds one line, and
343
+ `truncate` holds one line with an ellipsis. `truncate` sets `min-width: 0`, so
344
+ Text can shrink beside a fixed-size sibling in a `Row`; the sibling keeps its
345
+ width. On `normal` or `anywhere`, set a positive integer `maxLines` to clamp
346
+ wrapped text with an ellipsis. Omit `maxLines` for unlimited lines. The cap is
347
+ incompatible with `nowrap` and `truncate`.
348
+
325
349
  ```tsx
326
350
  import { Text } from "@kerfjs/ui/text";
327
351
 
@@ -333,6 +357,9 @@ import { Text } from "@kerfjs/ui/text";
333
357
  <Text variant="h2" size="xlarge">A display-sized section title</Text>;
334
358
  <strong>Inbox<Text variant="span" tone="quiet" size="compact"> · 3 msg</Text></strong>;
335
359
  <Text tone="danger" font="monospace">ERR_INVALID_ID</Text>;
360
+ <Text wrap="anywhere">A-very-long-unbroken-identifier</Text>;
361
+ <Text wrap="truncate" variant="span">Long vendor name</Text>;
362
+ <Text wrap="normal" maxLines={2}>A long summary capped at two lines.</Text>;
336
363
  ```
337
364
 
338
365
  ## Spacer
@@ -23,6 +23,28 @@ The default `shape="rounded"` uses the shared rounded-rectangle radius. Choose
23
23
  </SunkenPanel>
24
24
  ```
25
25
 
26
+ ## Filling a work area
27
+
28
+ Set `fill` when the panel is the direct layout root of a parent with a definite
29
+ height. Inside a flex column, use `flex` so it takes the remaining space and
30
+ can shrink with its parent. Like `Grid`, `flex` accepts `true` (equivalent to
31
+ `1 1 auto`), a CSS flex keyword, or a typed `CssFlex` value. The panel keeps
32
+ `min-height: 0`, allowing its parent to own scrolling.
33
+
34
+ ```tsx
35
+ <List fill>
36
+ <Toolbar label="Work area" />
37
+ <SunkenPanel flex>
38
+ <WorkArea />
39
+ </SunkenPanel>
40
+ </List>
41
+ ```
42
+
43
+ Inside a `Pane`, the Pane's content remains the scroll owner. Place a
44
+ `SunkenPanel fill` in a definite-height Pane content region when the surface
45
+ itself needs to cover empty space, or use `flex` when a flex parent allocates
46
+ the remaining space. The panel does not add another scroller.
47
+
26
48
  ## Ownership
27
49
 
28
50
  The root owns its lowered background, 8px padding, and 8px vertical gap.
@@ -80,6 +80,10 @@ policy, or analysis inputs to the containing application.
80
80
  | `KUI-L021` | error | CSS overrides a component token that a typed prop sets. |
81
81
  | `KUI-L022` | error | A class placed on a component's root is styled by the application (a hook class). |
82
82
 
83
+ For `KUI-L004` and `KUI-L007`, scroll and inset declarations belong to the
84
+ subject of each CSS selector. An ancestor class used only to qualify a
85
+ descendant selector is not treated as a scroll owner or inset source.
86
+
83
87
  Errors are provable contract violations and make the command exit 1. Review
84
88
  findings are deliberately heuristic and do not fail by default; pass
85
89
  `--fail-on-review` when a project has reviewed its baseline and wants them to
package/docs/workbench.md CHANGED
@@ -89,10 +89,20 @@ an optional `label`. Common shell behavior is configured rather than restyled:
89
89
  each exactly at its configured size (its separator border included, as in
90
90
  flow) up to the viewport-relative overlay maximum; the content fills the
91
91
  panel inside its border, so it is clamped with it;
92
- - `responsiveOverlayAt: "narrow" | "compact" | "never"` presents a rail or the
92
+ - `overlayBackdrop` on the Workbench opts in to a `--kui-color-scrim` backdrop
93
+ whenever a static or responsive rail/drawer overlay is open. It sits below
94
+ the panel and above the work area, absorbs an outside press, and lets
95
+ `wireWorkbench` close the overlay without activating the control underneath.
96
+ It is off by default; without it, the compact rail's dismiss strip remains
97
+ transparent. Pair it with `wireWorkbench` for outside-press dismissal;
98
+ - `responsiveOverlayAt: "narrow" | "compact" | "never" | number` presents a rail or the
93
99
  bottom drawer as an overlay below a Workbench container breakpoint — 704px
94
100
  or less for `narrow`, 448px or less for `compact`, the breakpoints of
95
- `ResizableRegion`'s `responsiveFillAt` — and inline above it. **Rails
101
+ `ResizableRegion`'s `responsiveFillAt` — and inline above it. A positive
102
+ number such as `1024` uses that many CSS pixels of Workbench width. Numeric
103
+ thresholds require `wireWorkbench` with that panel's `collapsed` signal;
104
+ its resize observer applies the overlay layout and the collapse/restore
105
+ transition together. **Rails
96
106
  default to `narrow`**, so on a small screen a sidebar covers the work area
97
107
  (and an open drawer) instead of squeezing it; pass `never` to keep a rail
98
108
  inline. The drawer stays inline unless it opts in. On a compact (448px or
@@ -219,6 +229,17 @@ it pinned while the work area is tall enough and lets it scroll with `main`
219
229
  when the work area is short (the Pane's `chromePlacement="auto"`; it applies to
220
230
  the pinned header and footer together).
221
231
 
232
+ A toolbar panel has the same fixed chrome sequence: `toolbar`, optional
233
+ `header`, scrolling `content`, optional `footer`, and optional
234
+ `bottomToolbar`. `header` sits below the panel toolbar, so an inspector can
235
+ keep its title, notices, and section tabs visible while its detail content
236
+ scrolls in the one `Pane` scroll owner. `headerList` and `footerList` configure
237
+ their `List` wrappers. `headerPlacement` and `footerPlacement` accept
238
+ `"fixed"` (default), `"scroll"`, or `"auto"` with the same behavior as the
239
+ work area's placement props. The panel's bottom toolbar renders a semantic
240
+ `footer`. These panel slots apply only when the panel has a `toolbar`; a panel
241
+ without one continues to render `content` as supplied.
242
+
222
243
  Every toolbar the Workbench composes — `mainToolbar`, `mainBottomToolbar`, and
223
244
  each panel's `toolbar` — takes the `Toolbar`'s configuration (`ToolbarConfig`):
224
245
  `dividerSides`, `centerAlign`, `responsive`, `responsiveAt`, and
@@ -245,7 +266,8 @@ configurable the same way:
245
266
  in — for example `{ contentElement: "nav", contentLabel: "Files" }` for a
246
267
  navigator rail. Without a toolbar, `appearance: "sunken"` paints the panel
247
268
  scroll region;
248
- - `mainHeaderList` / `mainFooterList` (`ListConfig`: `gap`, `hAlign`,
269
+ - `mainHeaderList` / `mainFooterList` and a panel's `headerList` /
270
+ `footerList` (`ListConfig`: `gap`, `hAlign`,
249
271
  `vAlign`, `dividerSides`, `textInsets`, `controlInsets`) configure the
250
272
  `List`s holding `mainHeader` / `mainFooter`.
251
273
 
@@ -356,6 +378,13 @@ const stop = wireWorkbench(root, {
356
378
  `"compact"` (448px or less) instead: below that breakpoint it presents as a
357
379
  full-size overlay over the work area rather than squeezing beside it (see
358
380
  the catalog's resizable and responsive-drawer Workbench examples).
381
+ A numeric value measures the Workbench container, not the viewport. If the
382
+ rest of an app switches by viewport width and its Workbench can be narrower
383
+ than the viewport, keep the app's viewport decision in
384
+ `presentation: "overlay"` and pass its `collapsed` signals to
385
+ `wireWorkbench`. On entering that mode, collapse the panels; after leaving,
386
+ restore their preferred inline state once the inline presentation has
387
+ rendered, so exclusive overlay handling cannot close a sibling rail.
359
388
  - **Collapse:** `collapsed` never changes a size. A collapsed panel keeps its
360
389
  size (its content slides out at that width), its separator leaves the tab
361
390
  order, and expanding it returns it at the size it had.
@@ -402,7 +431,12 @@ presents as one, mirroring `wireSidebar`'s compact overlay:
402
431
  - **Outside press:** a pointer press that starts and ends outside an open
403
432
  overlay panel closes it. The app's own toggle still works: its click closes
404
433
  the panel before the wiring looks, and the press that opens a panel never
405
- closes it.
434
+ closes it. For a body-level menu, dialog, or other portal opened from a
435
+ panel, set that panel's `keepOpenOn: (target) => target === portalRoot` in
436
+ `wireWorkbench`. The predicate receives each node in the press's composed
437
+ path, so matching the portal root keeps the panel open when the press starts
438
+ or ends anywhere inside the portal. Escape and Tab inside that portal remain
439
+ with its own keyboard handler. Other outside presses still close the panel.
406
440
  - **Focus:** when a panel closes with focus inside it — whatever closed it,
407
441
  including the app's own control inside the panel — focus returns to the
408
442
  control that had it when the panel opened (typically its toggle; one inside