@adia-ai/web-components 0.8.32 → 0.8.34

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 (100) hide show
  1. package/CHANGELOG.md +51 -0
  2. package/MIGRATION.md +136 -0
  3. package/components/accordion/accordion-item.a2ui.json +8 -0
  4. package/components/accordion/accordion-item.yaml +6 -0
  5. package/components/accordion/accordion.css +3 -1
  6. package/components/agent-reasoning/agent-reasoning.a2ui.json +1 -1
  7. package/components/agent-reasoning/agent-reasoning.yaml +3 -3
  8. package/components/alert/alert.a2ui.json +3 -5
  9. package/components/alert/alert.class.js +3 -3
  10. package/components/alert/alert.css +5 -12
  11. package/components/alert/alert.d.ts +2 -2
  12. package/components/alert/alert.yaml +6 -5
  13. package/components/badge/badge.a2ui.json +6 -9
  14. package/components/badge/badge.class.js +4 -4
  15. package/components/badge/badge.css +111 -77
  16. package/components/badge/badge.d.ts +34 -12
  17. package/components/badge/badge.examples.md +1 -1
  18. package/components/badge/badge.yaml +37 -16
  19. package/components/button/button.a2ui.json +1 -1
  20. package/components/button/button.css +16 -2
  21. package/components/button/button.d.ts +2 -2
  22. package/components/button/button.yaml +1 -1
  23. package/components/card/card.yaml +1 -1
  24. package/components/chart/chart.class.js +8 -4
  25. package/components/combobox/combobox.a2ui.json +1 -1
  26. package/components/combobox/combobox.yaml +3 -0
  27. package/components/command/command.a2ui.json +4 -0
  28. package/components/command/command.class.js +54 -4
  29. package/components/command/command.d.ts +2 -0
  30. package/components/command/command.yaml +25 -3
  31. package/components/date-range-picker/date-range-picker.a2ui.json +1 -1
  32. package/components/date-range-picker/date-range-picker.class.js +42 -43
  33. package/components/date-range-picker/date-range-picker.css +11 -0
  34. package/components/date-range-picker/date-range-picker.yaml +6 -3
  35. package/components/description-list/description-list.css +16 -4
  36. package/components/integration-card/integration-card.class.js +11 -2
  37. package/components/mark/mark.a2ui.json +6 -7
  38. package/components/mark/mark.class.js +1 -1
  39. package/components/mark/mark.css +7 -4
  40. package/components/mark/mark.d.ts +2 -2
  41. package/components/mark/mark.examples.md +0 -4
  42. package/components/mark/mark.yaml +16 -6
  43. package/components/modal/modal.class.js +43 -2
  44. package/components/modal/modal.css +23 -0
  45. package/components/nav-group/nav-group.css +15 -4
  46. package/components/nav-item/nav-item.css +11 -3
  47. package/components/option-card/option-card.examples.md +1 -1
  48. package/components/popover/popover.a2ui.json +5 -0
  49. package/components/popover/popover.class.js +9 -4
  50. package/components/popover/popover.css +5 -2
  51. package/components/popover/popover.yaml +8 -0
  52. package/components/preview/preview.examples.md +1 -1
  53. package/components/richtext/richtext.css +5 -1
  54. package/components/segment/segment.css +10 -0
  55. package/components/step-progress/step-progress.css +16 -3
  56. package/components/table/cell-types.js +20 -1
  57. package/components/table/table.a2ui.json +1 -1
  58. package/components/table/table.class.js +11 -0
  59. package/components/table/table.css +9 -0
  60. package/components/table/table.d.ts +1 -1
  61. package/components/table/table.yaml +1 -1
  62. package/components/table-toolbar/table-toolbar.class.js +1 -1
  63. package/components/tabs/tabs.css +3 -1
  64. package/components/tag/tag.a2ui.json +5 -5
  65. package/components/tag/tag.class.js +1 -1
  66. package/components/tag/tag.css +93 -77
  67. package/components/tag/tag.d.ts +17 -11
  68. package/components/tag/tag.yaml +30 -19
  69. package/components/toast/toast.a2ui.json +2 -4
  70. package/components/toast/toast.css +0 -12
  71. package/components/toast/toast.yaml +3 -4
  72. package/core/element.js +31 -0
  73. package/core/signals.js +3 -1
  74. package/dist/theme-provider.min.js +2 -2
  75. package/dist/web-components.min.css +1 -1
  76. package/dist/web-components.min.js +67 -67
  77. package/dist/web-components.sheet.js +1 -1
  78. package/package.json +1 -1
  79. package/patterns/admin-keys-and-export/admin-keys-and-export.examples.html +1 -1
  80. package/patterns/agent-memory/agent-memory.examples.html +5 -5
  81. package/patterns/agent-prompt-library/agent-prompt-library.examples.html +2 -2
  82. package/patterns/audit-log/audit-log.examples.js +12 -5
  83. package/patterns/bulk-action-toolbar/bulk-action-toolbar.examples.js +4 -1
  84. package/patterns/changelog-feed/changelog-feed.examples.html +1 -1
  85. package/patterns/comments-and-collaboration/comments-and-collaboration.examples.html +1 -1
  86. package/patterns/conversion-funnel/conversion-funnel.examples.html +1 -1
  87. package/patterns/diff-review/diff-review.examples.html +9 -9
  88. package/patterns/filter-bar/filter-bar.examples.html +12 -8
  89. package/patterns/filter-bar/filter-bar.examples.js +4 -1
  90. package/patterns/marketing-engagement/marketing-engagement.examples.html +1 -1
  91. package/patterns/notifications-bell-and-digest/notifications-bell-and-digest.examples.html +1 -1
  92. package/patterns/permissions-matrix/permissions-matrix.examples.html +1 -1
  93. package/patterns/permissions-sharing/permissions-sharing.examples.html +1 -1
  94. package/patterns/profile-public-and-verification/profile-public-and-verification.examples.html +2 -2
  95. package/patterns/record-detail-drawer/record-detail-drawer.examples.html +1 -1
  96. package/patterns/responsive-shell-sidebar/responsive-shell-sidebar.examples.html +135 -147
  97. package/patterns/retention-cohort/retention-cohort.examples.html +1 -1
  98. package/patterns/retention-cohort/retention-cohort.examples.js +4 -1
  99. package/patterns/system-banners/system-banners.examples.html +3 -3
  100. package/styles/colors/semantics/core.css +22 -2
@@ -40,11 +40,19 @@ nav-item-ui[selected] [slot="icon"]:empty::before {
40
40
  --nav-item-font-size-sm: var(--a-ui-sm);
41
41
  --nav-item-font-size-lg: var(--a-ui-lg);
42
42
  --nav-item-font-weight: var(--a-weight-normal);
43
- --nav-item-fg: var(--a-ui-text-subtle);
43
+ /* State color spec (gh#968, operator ruling 2026-08-11):
44
+ idle — bg transparent · icon NEUTRAL · text NEUTRAL-HIGH
45
+ hover — bg container-low · icon + text ON-SURFACE
46
+ selected — bg container · icon + text ON-SURFACE
47
+ Idle sits two quiet steps down (icon quieter than text); hover and
48
+ selected converge on on-surface. The selected ICON no longer takes
49
+ the primary accent (supersedes gh#522 for the glyph) — the accent
50
+ BAR remains the primary selection marker. */
51
+ --nav-item-fg: var(--md-sys-color-neutral-high);
44
52
  --nav-item-fg-hover: var(--a-ui-text-hover);
45
53
  --nav-item-fg-selected: var(--a-ui-text-selected);
46
- --nav-item-icon-fg: var(--a-ui-text-muted);
47
- --nav-item-icon-fg-selected: var(--nav-item-accent);
54
+ --nav-item-icon-fg: var(--md-sys-color-neutral);
55
+ --nav-item-icon-fg-selected: var(--a-ui-text-selected);
48
56
  /* Two real container roles, one mechanism — no opacity synth.
49
57
  hover = --a-bg-muted (--md-sys-color-neutral-container-low, 10%),
50
58
  matching nav-group-ui's own --nav-group-bg-hover exactly.
@@ -24,7 +24,7 @@
24
24
  <span slot="heading">
25
25
  Pro
26
26
  <text-ui color="subtle" size="sm">· $49/mo</text-ui>
27
- <badge-ui text="14-day trial" variant="accent"></badge-ui>
27
+ <badge-ui text="14-day trial" variant="primary"></badge-ui>
28
28
  </span>
29
29
  </option-card-ui>
30
30
  <option-card-ui name="demo-plan" value="team" description="Everything in Pro · SSO · audit log · 1 TB storage">
@@ -21,6 +21,11 @@
21
21
  "type": "number",
22
22
  "default": 4
23
23
  },
24
+ "match-width": {
25
+ "description": "Size the content panel to the trigger's width instead of max-content. Opt-in — the default (unset) keeps every existing consumer's content-sized panel unchanged.",
26
+ "type": "boolean",
27
+ "default": false
28
+ },
24
29
  "open": {
25
30
  "description": "Controls visibility via showPopover()/hidePopover()",
26
31
  "type": "boolean",
@@ -24,6 +24,9 @@
24
24
  * (see @core/anchor.js).
25
25
  *
26
26
  * Triggers: click | hover | manual. ESC closes click/manual popovers.
27
+ *
28
+ * Set [match-width] to size the panel to the trigger's width instead of
29
+ * max-content (opt-in — see @core/anchor.js's `matchWidth` option).
27
30
  */
28
31
 
29
32
  import { UIElement } from '../../core/element.js';
@@ -33,10 +36,11 @@ const HOVER_CLOSE_DELAY = 120;
33
36
 
34
37
  export class UIPopover extends UIElement {
35
38
  static properties = {
36
- placement: { type: String, default: 'bottom', reflect: true },
37
- gap: { type: Number, default: 4, reflect: true },
38
- open: { type: Boolean, default: false, reflect: true },
39
- trigger: { type: String, default: 'click', reflect: true },
39
+ placement: { type: String, default: 'bottom', reflect: true },
40
+ gap: { type: Number, default: 4, reflect: true },
41
+ open: { type: Boolean, default: false, reflect: true },
42
+ trigger: { type: String, default: 'click', reflect: true },
43
+ matchWidth: { type: Boolean, default: false, reflect: true, attribute: 'match-width' },
40
44
  };
41
45
 
42
46
  static template = () => null;
@@ -104,6 +108,7 @@ export class UIPopover extends UIElement {
104
108
  this.#anchorCleanup = anchorPopover(trigger, content, {
105
109
  placement: this.placement,
106
110
  gap: this.gap,
111
+ matchWidth: this.matchWidth,
107
112
  });
108
113
 
109
114
  if (this.trigger === 'click' || this.trigger === 'manual') {
@@ -12,9 +12,12 @@
12
12
  mode (dimmer = neutral-925, darker than the neutral-875 page it floats
13
13
  over — the panel read near-black). Matches select-ui's own dropdown
14
14
  surface exactly, so the two overlays on a shell's topbar (a select
15
- menu and a popover panel) sit on one plane. */
15
+ menu and a popover panel) sit on one plane. Border matches too
16
+ (gh#857) — `--a-ui-border` (→ outline), same token select-ui's
17
+ `[slot="listbox"]` uses, not outline-variant (that's for internal
18
+ dividers — separators, group rules — a different role). */
16
19
  --popover-bg: var(--md-sys-color-neutral-surface-bright);
17
- --popover-border: var(--md-sys-color-neutral-outline-variant);
20
+ --popover-border: var(--a-ui-border);
18
21
  --popover-shadow: var(--a-shadow-lg);
19
22
  }
20
23
 
@@ -13,6 +13,14 @@ props:
13
13
  description: Pixel offset between the anchor and the popover
14
14
  type: number
15
15
  default: 4
16
+ match-width:
17
+ description: >-
18
+ Size the content panel to the trigger's width instead of
19
+ max-content. Opt-in — the default (unset) keeps every existing
20
+ consumer's content-sized panel unchanged.
21
+ type: boolean
22
+ default: false
23
+ reflect: true
16
24
  open:
17
25
  description: Controls visibility via showPopover()/hidePopover()
18
26
  type: boolean
@@ -13,7 +13,7 @@
13
13
 
14
14
  ```html
15
15
  <preview-ui layout="split">
16
- <badge-ui text="New" variant="accent"></badge-ui>
16
+ <badge-ui text="New" variant="primary"></badge-ui>
17
17
  <badge-ui text="Beta" variant="warning"></badge-ui>
18
18
  <badge-ui text="Stable" variant="success"></badge-ui>
19
19
  </preview-ui>
@@ -15,7 +15,11 @@
15
15
  --richtext-fg: var(--md-sys-color-neutral-on-surface);
16
16
  --richtext-fg-muted: var(--a-fg-muted);
17
17
  --richtext-fg-subtle: var(--md-sys-color-neutral-on-surface-variant);
18
- --richtext-code-bg: var(--a-canvas-2);
18
+ /* Container-low (10% alpha), not an opaque canvas tier (gh#972): the
19
+ inline chip must RECEDE behind prose and composite consistently on
20
+ any stacked surface — an opaque canvas-2 chip read heavy on the
21
+ page and inverted inside cards. Same tier as --a-bg-muted/hover. */
22
+ --richtext-code-bg: var(--md-sys-color-neutral-container-low);
19
23
  --richtext-border: var(--md-sys-color-neutral-outline-variant);
20
24
  --richtext-link: var(--a-primary-bg);
21
25
  --richtext-link-hover: var(--md-sys-color-primary);
@@ -19,6 +19,13 @@ segment-ui[selected] {
19
19
  --segment-font-size: var(--a-ui-size);
20
20
  --segment-font-weight: var(--a-ui-weight);
21
21
  --segment-font-family: var(--a-font-family-ui);
22
+ /* Leading for the [text] label box ONLY — never the host. The host's
23
+ `line-height: 1` is deliberate, but the label's ::after clips to its
24
+ own line box, so inheriting 1 makes half-leading negative and shears
25
+ descenders (g/j/p/q/y, parentheses) by ~0.93px at the default size —
26
+ gh#906. Snug (1.3) contains the font's content box at every [size];
27
+ mirrors --button-label-line-height. */
28
+ --segment-label-line-height: var(--a-leading-snug);
22
29
 
23
30
  /* ── Colors ── */
24
31
  --segment-fg: var(--a-ui-text-subtle);
@@ -92,6 +99,9 @@ segment-ui[selected] {
92
99
  overflow: hidden;
93
100
  text-overflow: ellipsis;
94
101
  white-space: nowrap;
102
+ /* `overflow: hidden` (needed for the ellipsis) makes this line box the
103
+ clip box — give it leading tall enough to contain the descenders. */
104
+ line-height: var(--segment-label-line-height);
95
105
  }
96
106
 
97
107
  /* States — hover + [selected] rules moved outside @scope; see Safari 17.x bug note at top. */
@@ -14,9 +14,15 @@
14
14
  --step-progress-caption-fg: var(--a-fg-muted);
15
15
  --step-progress-caption-size: var(--a-ui-sm);
16
16
 
17
- /* Sizing — match the bespoke flex shape in registration + onboarding
18
- (flex:0 1 18rem; min-width:10rem). Consumers can override. */
19
- --step-progress-flex: 0 1 18rem;
17
+ /* Sizing — 18rem of track width, shrinkable to 10rem, matching the
18
+ bespoke shape in registration + onboarding. Expressed as inline-size
19
+ rather than flex-basis (gh#942): a flex-basis of 18rem is
20
+ direction-fragile — inside a COLUMN-direction flex parent (col-ui,
21
+ any stacked wizard) the same basis constrains HEIGHT, inflating the
22
+ ~30px component to 288px. inline-size constrains width in both flex
23
+ directions. Consumers can override. */
24
+ --step-progress-flex: 0 1 auto;
25
+ --step-progress-inline-size: 18rem;
20
26
  --step-progress-min-width: 10rem;
21
27
  }
22
28
 
@@ -25,6 +31,13 @@
25
31
  flex-direction: column;
26
32
  gap: var(--step-progress-gap);
27
33
  flex: var(--step-progress-flex);
34
+ /* Deliberate SCOPE-EXTENT exception: this component has always shipped
35
+ a default extent (previously flex-basis 18rem + min-width 10rem —
36
+ extent by another name, just direction-fragile). Both remain
37
+ token-overridable; going fully size-agnostic would silently reflow
38
+ the registration/onboarding row-header consumers. */
39
+ inline-size: var(--step-progress-inline-size);
40
+ max-inline-size: 100%;
28
41
  min-width: var(--step-progress-min-width);
29
42
  }
30
43
 
@@ -173,7 +173,18 @@ registerCellType('badge', {
173
173
  }
174
174
  el.setAttribute('text', String(value ?? ''));
175
175
  const variants = meta?.variants || {};
176
- el.setAttribute('variant', variants[value] || 'neutral');
176
+ const variant = variants[value];
177
+ // Unmapped value → family-less badge, tone="muted" (quiet chrome) —
178
+ // `variant="neutral"` retired (variant/color/tone convention cut,
179
+ // gh#873/874). Element is reused across renders, so both attributes
180
+ // are explicitly set/cleared rather than only ever added.
181
+ if (variant) {
182
+ el.setAttribute('variant', variant);
183
+ el.removeAttribute('tone');
184
+ } else {
185
+ el.removeAttribute('variant');
186
+ el.setAttribute('tone', 'muted');
187
+ }
177
188
  },
178
189
  format(value) {
179
190
  return String(value ?? '');
@@ -271,10 +282,18 @@ registerCellType('progress', {
271
282
  wrapper = document.createElement('row-ui');
272
283
  wrapper.setAttribute('gap', '2');
273
284
  wrapper.setAttribute('align', 'center');
285
+ // The gridcell is a flex container; without an explicit flex the
286
+ // wrapper shrinks to content — and a progress bar has no intrinsic
287
+ // width, so the whole cell collapsed to ~33px and the value span
288
+ // ellipsized to "7.." (gh#940). Fill the cell; keep the numeric
289
+ // label un-shrinkable so the BAR absorbs the flexing instead.
290
+ wrapper.style.flex = '1';
291
+ wrapper.style.minWidth = '0';
274
292
  const prog = document.createElement('progress-ui');
275
293
  prog.setAttribute('size', 'sm');
276
294
  prog.style.flex = '1';
277
295
  const span = document.createElement('span');
296
+ span.style.flexShrink = '0';
278
297
  wrapper.appendChild(prog);
279
298
  wrapper.appendChild(span);
280
299
  cell.appendChild(wrapper);
@@ -14,7 +14,7 @@
14
14
  ],
15
15
  "properties": {
16
16
  "columns": {
17
- "description": "Column definitions. Array of {key, label, type?, width?, minWidth?, maxWidth?, flex?, sortable?, resizable?, filterable?, pinned?, hidden?, wrap?, valign?, accessor?, format?, render?, sortFn?, filterType?, meta?}. `valign` ('top'|'center') overrides the host [valign] for that column's body cells only — header cells always stay centered. Alternative to declarative <col-def> children (<col-def valign=\"top\">).",
17
+ "description": "Column definitions. Array of {key, label, type?, width?, minWidth?, maxWidth?, flex?, sortable?, resizable?, filterable?, pinned?, hidden?, wrap?, valign?, accessor?, format?, render?, sortFn?, filterType?, meta?}. `valign` ('top'|'center') overrides the host [valign] for that column's body cells only — header cells always stay centered. Alternative to declarative <col-def> children (<col-def valign=\"top\">); col-def also accepts `meta` as a JSON attribute (gh#925) — e.g. <col-def type=\"badge\" meta='{\"variants\":{\"Online\":\"success\"}}'> — so cell-type meta (badge variant maps, currency codes) is expressible in static HTML.",
18
18
  "$ref": "common_types.json#/$defs/DynamicStringList"
19
19
  },
20
20
  "component": {
@@ -432,6 +432,17 @@ export class UITable extends UIElement {
432
432
  const flex = el.getAttribute('flex');
433
433
  if (flex) col.flex = Number(flex);
434
434
 
435
+ /* gh#925 — cell-type meta (e.g. the badge type's per-value variant
436
+ map, currency's currency code) had no declarative form: columns[]
437
+ carries `meta` but col-def never parsed it, so a static-HTML badge
438
+ column was structurally stuck at the unmapped tone="muted"
439
+ fallback. JSON attribute, same silent-on-malformed discipline as
440
+ the host's `data` attribute (gh#288). */
441
+ const meta = el.getAttribute('meta');
442
+ if (meta) {
443
+ try { col.meta = JSON.parse(meta); } catch (_) { /* malformed JSON — ignored */ }
444
+ }
445
+
435
446
  cols.push(col);
436
447
  el.remove();
437
448
  }
@@ -313,8 +313,17 @@
313
313
  white-space: nowrap;
314
314
  }
315
315
 
316
+ /* Must match the span/a rule above: without flex:1, row-ui (a flex
317
+ child with default flex:0 1 auto) sizes to its own shrink-to-fit
318
+ content instead of filling the cell — avatar/progress composite
319
+ types then split that tiny intrinsic width between their
320
+ progress-ui/avatar-ui and label span, clipping the label (gh#940:
321
+ stock "71%" rendered as "7.."). Generalizes the per-renderer inline
322
+ flex fix from PR #945 to every composite cell type; adopted from
323
+ PR #943's analysis. */
316
324
  [data-body] [role="gridcell"] > row-ui {
317
325
  min-width: 0;
326
+ flex: 1;
318
327
  overflow: hidden;
319
328
  }
320
329
 
@@ -86,7 +86,7 @@ export interface TableSortEventDetail {
86
86
  export type TableSortEvent = CustomEvent<TableSortEventDetail>;
87
87
 
88
88
  export class UITable extends UIElement {
89
- /** Column definitions. Array of {key, label, type?, width?, minWidth?, maxWidth?, flex?, sortable?, resizable?, filterable?, pinned?, hidden?, wrap?, valign?, accessor?, format?, render?, sortFn?, filterType?, meta?}. `valign` ('top'|'center') overrides the host [valign] for that column's body cells only — header cells always stay centered. Alternative to declarative <col-def> children (<col-def valign="top">). */
89
+ /** Column definitions. Array of {key, label, type?, width?, minWidth?, maxWidth?, flex?, sortable?, resizable?, filterable?, pinned?, hidden?, wrap?, valign?, accessor?, format?, render?, sortFn?, filterType?, meta?}. `valign` ('top'|'center') overrides the host [valign] for that column's body cells only — header cells always stay centered. Alternative to declarative <col-def> children (<col-def valign="top">); col-def also accepts `meta` as a JSON attribute (gh#925) — e.g. <col-def type="badge" meta='{"variants":{"Online":"success"}}'> — so cell-type meta (badge variant maps, currency codes) is expressible in static HTML. */
90
90
  columns: string;
91
91
  /** JS property (set programmatically — `el.data = [...]`) — row records, an array of plain objects keyed to columns[].key. May also be supplied declaratively as a JSON-array `data="[…]"` attribute, hydrated once at connect (gh#288) — the same pattern chart-ui's `data` attribute uses. Custom accessor on the element class, not a reflected attribute. */
92
92
  data: string;
@@ -20,7 +20,7 @@ composes:
20
20
  - badge-ui
21
21
  props:
22
22
  columns:
23
- description: Column definitions. Array of {key, label, type?, width?, minWidth?, maxWidth?, flex?, sortable?, resizable?, filterable?, pinned?, hidden?, wrap?, valign?, accessor?, format?, render?, sortFn?, filterType?, meta?}. `valign` ('top'|'center') overrides the host [valign] for that column's body cells only — header cells always stay centered. Alternative to declarative <col-def> children (<col-def valign="top">).
23
+ description: Column definitions. Array of {key, label, type?, width?, minWidth?, maxWidth?, flex?, sortable?, resizable?, filterable?, pinned?, hidden?, wrap?, valign?, accessor?, format?, render?, sortFn?, filterType?, meta?}. `valign` ('top'|'center') overrides the host [valign] for that column's body cells only — header cells always stay centered. Alternative to declarative <col-def> children (<col-def valign="top">); col-def also accepts `meta` as a JSON attribute (gh#925) — e.g. <col-def type="badge" meta='{"variants":{"Online":"success"}}'> — so cell-type meta (badge variant maps, currency codes) is expressible in static HTML.
24
24
  type: array
25
25
  default: []
26
26
  dynamic: true # JS-set collection prop with a custom setter — deliberately not in static properties
@@ -272,7 +272,7 @@ export class UITableToolbar extends UIElement {
272
272
  const badge = document.createElement('badge-ui');
273
273
  badge.setAttribute('data-count-badge', '');
274
274
  badge.setAttribute('size', 'sm');
275
- badge.setAttribute('variant', 'muted');
275
+ badge.setAttribute('tone', 'muted');
276
276
  badge.hidden = true;
277
277
  title.appendChild(badge);
278
278
 
@@ -5,7 +5,9 @@
5
5
  --tabs-bg: transparent;
6
6
  --tabs-radius: var(--a-radius-md);
7
7
  --tabs-button-height: var(--a-size);
8
- --tabs-font-size: var(--a-ui-md);
8
+ /* One rung UP the --a-ui-* scale (gh#965): tab labels are primary
9
+ navigation, not control chrome. */
10
+ --tabs-font-size: var(--a-ui-lg);
9
11
  --tabs-font-family: var(--a-font-family-ui);
10
12
  /* Strip owns the button-to-button spacing — 4px base gap + one
11
13
  padding unit (8px) folded in, since tab-button carries no
@@ -46,25 +46,25 @@
46
46
  "$ref": "common_types.json#/$defs/DynamicString"
47
47
  },
48
48
  "tone": {
49
- "description": "Fill style — orthogonal to [variant]. Three values:\n - `solid` (default for EVERY variant, including the family-less\n `default`, since gh#794) saturated bg + on-strong (near-white)\n text. The chip IS the state. A bare `<tag-ui text=\"…\">` renders\n this look with no attributes at all.\n - `muted` — tinted bg with scheme-paired text. Matches <badge-ui>'s\n default look, and is the pre-gh#794 look for the family-less\n `default` variant. Use on metadata / citation chips in dense\n lists or tables where the saturated default would compete for\n attention (gh#778's oversized-pill concern).\n - `outline` — transparent bg + family-colored border + family-colored\n text. The lightest visual weight; good in dense data tables or\n faceted filter rows where multiple chips would otherwise compete.\n`tone` is a declarative presentational attribute (not a reactive\nprop — see tag.class.js) so its schema `default` here is documentation\nof the rendered-by-default look, not a reflected attribute value.\n",
49
+ "description": "Fill style — orthogonal to [variant]. Three values:\n - `muted` (default for the family variants info/success/warning/\n danger/primary gh#864: tag and badge were swapped relative to\n their reported default formulas; this restores tag's own)\n — tinted bg with scheme-paired text. Matches <badge-ui>'s\n `[tone=\"muted\"]` look. Use on metadata / citation chips in dense\n lists or tables where a saturated fill would compete for\n attention (gh#778's oversized-pill concern). Does NOT apply to\n the family-less `default` variant, which stays solid\n unconditionally (gh#794, unaffected by gh#864) — a bare\n `<tag-ui text=\"…\">` still renders that solid look with no\n attributes at all.\n - `solid` — saturated bg + on-strong (near-white) text. The chip\n IS the state. Opt in explicitly for a family variant (gh#864),\n or it's already the unconditional look for the family-less\n `default` variant (gh#794).\n - `outline` — transparent bg + family-colored border + family-colored\n text. The lightest visual weight; good in dense data tables or\n faceted filter rows where multiple chips would otherwise compete.\n`tone` is a declarative presentational attribute (not a reactive\nprop — see tag.class.js) so its schema `default` here is documentation\nof the rendered-by-default look, not a reflected attribute value.\n",
50
50
  "type": "string",
51
51
  "enum": [
52
52
  "solid",
53
53
  "muted",
54
54
  "outline"
55
55
  ],
56
- "default": "solid"
56
+ "default": "muted"
57
57
  },
58
58
  "variant": {
59
- "description": "Semantic variant — `default | accent | info | success | warning | danger`. `accent` is brand-primary emphasis for non-semantic labels — a filter chip or taxonomy tag that shouldn't imply a success/warning/danger state. Mirrors <badge-ui>'s `accent` variant token-for-token.",
59
+ "description": "Semantic variant — `default | info | success | warning | danger | primary`. `primary` is brand emphasis for non-semantic labels — a filter chip or taxonomy tag that shouldn't imply a success/warning/danger state. Mirrors <badge-ui>'s `primary` variant token-for-token (`accent` retired, gh#874 — the capability survives renamed, sibling parity with badge preserved).",
60
60
  "type": "string",
61
61
  "enum": [
62
62
  "default",
63
- "accent",
64
63
  "info",
65
64
  "success",
66
65
  "warning",
67
- "danger"
66
+ "danger",
67
+ "primary"
68
68
  ],
69
69
  "default": "default"
70
70
  }
@@ -17,7 +17,7 @@
17
17
  * Inline tag / chip. Pill-shaped, text rendered via CSS attr().
18
18
  * Optional dismiss button dispatches a 'remove' CustomEvent.
19
19
  *
20
- * Variants: default, info, success, warning, danger
20
+ * Variants: default, info, success, warning, danger, primary
21
21
  * Sizes: sm, md (default)
22
22
  *
23
23
  * Events: