@adia-ai/web-components 0.7.27 → 0.8.0

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 (166) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/components/accordion/accordion.css +13 -4
  3. package/components/action-list/action-list.css +3 -3
  4. package/components/agent-artifact/agent-artifact.css +4 -4
  5. package/components/agent-questions/agent-questions.css +8 -8
  6. package/components/agent-reasoning/agent-reasoning.css +6 -6
  7. package/components/agent-trace/agent-trace.css +4 -4
  8. package/components/agent-trace/agent-trace.js +1 -1
  9. package/components/alert/alert.css +16 -16
  10. package/components/avatar/avatar.css +3 -3
  11. package/components/badge/badge.css +32 -32
  12. package/components/blockquote/blockquote.css +1 -1
  13. package/components/breadcrumb/breadcrumb.css +2 -2
  14. package/components/button/button.css +14 -14
  15. package/components/calendar-grid/calendar-grid.a2ui.json +3 -3
  16. package/components/calendar-grid/calendar-grid.css +10 -10
  17. package/components/calendar-grid/calendar-grid.yaml +3 -3
  18. package/components/calendar-picker/calendar-picker.css +11 -11
  19. package/components/canvas/canvas.css +2 -2
  20. package/components/card/card.css +15 -15
  21. package/components/chart/chart.a2ui.json +1 -1
  22. package/components/chart/chart.css +23 -23
  23. package/components/chart/chart.yaml +2 -0
  24. package/components/chart-legend/chart-legend.css +2 -2
  25. package/components/chat-thread/chat-input.css +6 -6
  26. package/components/chat-thread/chat-thread.css +7 -7
  27. package/components/check/check.css +4 -4
  28. package/components/code/code-editor.js +1 -1
  29. package/components/code/code.css +45 -22
  30. package/components/color-picker/color-picker.css +4 -4
  31. package/components/combobox/combobox.css +6 -6
  32. package/components/command/command.class.js +14 -3
  33. package/components/command/command.css +4 -4
  34. package/components/context-menu/context-menu.css +2 -2
  35. package/components/date-range-picker/date-range-picker.a2ui.json +3 -3
  36. package/components/date-range-picker/date-range-picker.css +8 -8
  37. package/components/date-range-picker/date-range-picker.yaml +3 -3
  38. package/components/datetime-picker/datetime-picker.css +6 -6
  39. package/components/demo-toggle/demo-toggle.css +4 -4
  40. package/components/description-list/description-list.css +1 -1
  41. package/components/display-field/display-field.css +2 -2
  42. package/components/divider/divider.css +1 -1
  43. package/components/drawer/drawer.css +7 -7
  44. package/components/embed/embed.css +1 -1
  45. package/components/empty-state/empty-state.css +5 -5
  46. package/components/feed/feed.css +7 -7
  47. package/components/field/field.css +2 -2
  48. package/components/heatmap/heatmap.css +8 -8
  49. package/components/inline-edit/inline-edit.a2ui.json +1 -1
  50. package/components/inline-edit/inline-edit.css +3 -3
  51. package/components/inline-edit/inline-edit.yaml +1 -1
  52. package/components/inline-message/inline-message.css +4 -4
  53. package/components/input/input.css +1 -1
  54. package/components/inspector/inspector.css +1 -1
  55. package/components/integration-card/integration-card.css +3 -3
  56. package/components/kbd/kbd.a2ui.json +4 -0
  57. package/components/kbd/kbd.css +2 -2
  58. package/components/kbd/kbd.d.ts +2 -0
  59. package/components/kbd/kbd.yaml +5 -0
  60. package/components/link/link.css +2 -2
  61. package/components/list/list.css +10 -10
  62. package/components/list-window/list-window.css +2 -2
  63. package/components/mark/mark.css +9 -9
  64. package/components/menu/menu.css +9 -9
  65. package/components/modal/modal.css +4 -4
  66. package/components/nav/nav.css +1 -1
  67. package/components/nav-group/nav-group.css +7 -16
  68. package/components/nav-item/nav-item.css +1 -1
  69. package/components/noodles/noodles.a2ui.json +1 -1
  70. package/components/noodles/noodles.css +3 -3
  71. package/components/noodles/noodles.d.ts +1 -1
  72. package/components/noodles/noodles.yaml +1 -1
  73. package/components/option-card/option-card.css +11 -11
  74. package/components/otp-input/otp-input.css +1 -1
  75. package/components/page/page.css +2 -2
  76. package/components/pane/pane.css +5 -5
  77. package/components/password-strength/password-strength.css +1 -1
  78. package/components/pipeline-status/pipeline-status.css +9 -9
  79. package/components/popover/popover.css +2 -2
  80. package/components/preview/preview.css +14 -3
  81. package/components/progress/progress.a2ui.json +1 -1
  82. package/components/progress/progress.css +1 -1
  83. package/components/progress/progress.d.ts +1 -1
  84. package/components/progress/progress.yaml +1 -1
  85. package/components/progress-row/progress-row.css +2 -2
  86. package/components/radio/radio.css +4 -4
  87. package/components/range/range.css +2 -2
  88. package/components/rating/rating.css +2 -2
  89. package/components/richtext/richtext.class.js +4 -0
  90. package/components/richtext/richtext.css +5 -5
  91. package/components/richtext/richtext.yaml +1 -0
  92. package/components/row/row.css +1 -1
  93. package/components/select/select.css +8 -8
  94. package/components/skip-nav/skip-nav.a2ui.json +2 -2
  95. package/components/skip-nav/skip-nav.css +3 -3
  96. package/components/skip-nav/skip-nav.yaml +2 -2
  97. package/components/slider/slider.css +5 -5
  98. package/components/spinner/spinner.css +2 -2
  99. package/components/spinner/spinner.test.js +4 -2
  100. package/components/stat/stat.css +1 -1
  101. package/components/step-progress/step-progress.a2ui.json +1 -1
  102. package/components/step-progress/step-progress.class.js +1 -1
  103. package/components/step-progress/step-progress.css +2 -2
  104. package/components/step-progress/step-progress.d.ts +1 -1
  105. package/components/step-progress/step-progress.yaml +1 -1
  106. package/components/stepper/stepper.css +22 -22
  107. package/components/stream/stream.css +2 -2
  108. package/components/swatch/swatch.class.js +1 -1
  109. package/components/swatch/swatch.css +11 -11
  110. package/components/swiper/swiper.css +5 -5
  111. package/components/switch/switch.css +5 -5
  112. package/components/table/cell-types.js +32 -3
  113. package/components/table/table.a2ui.json +1 -1
  114. package/components/table/table.css +16 -11
  115. package/components/table/table.test.js +37 -0
  116. package/components/table/table.yaml +2 -0
  117. package/components/table-toolbar/table-toolbar.css +8 -8
  118. package/components/tabs/tabs.css +5 -5
  119. package/components/tag/tag.css +41 -29
  120. package/components/tag/tag.test.js +22 -29
  121. package/components/tags-input/tags-input.a2ui.json +1 -1
  122. package/components/tags-input/tags-input.css +3 -3
  123. package/components/tags-input/tags-input.yaml +5 -3
  124. package/components/text/text.css +4 -4
  125. package/components/textarea/textarea.css +1 -1
  126. package/components/time-picker/time-picker.css +2 -2
  127. package/components/timeline/timeline.css +31 -31
  128. package/components/toast/toast.css +19 -19
  129. package/components/toc/toc.a2ui.json +1 -1
  130. package/components/toc/toc.css +3 -3
  131. package/components/toc/toc.yaml +1 -1
  132. package/components/toggle-group/toggle-group.css +3 -3
  133. package/components/toolbar/toolbar.css +3 -3
  134. package/components/tooltip/tooltip.css +9 -9
  135. package/components/tour/tour.css +3 -3
  136. package/components/tree/tree.css +2 -2
  137. package/components/upload/upload.css +7 -7
  138. package/core/markdown.js +1 -1
  139. package/dist/host.min.css +1 -1
  140. package/dist/host.sheet.js +1 -1
  141. package/dist/theme-provider.min.js +7 -7
  142. package/dist/themes.min.css +1 -1
  143. package/dist/themes.sheet.js +1 -1
  144. package/dist/web-components.min.css +1 -1
  145. package/dist/web-components.min.js +62 -62
  146. package/dist/web-components.sheet.js +1 -1
  147. package/package.json +3 -3
  148. package/styles/api/text.css +1 -1
  149. package/styles/colors/bridges/material-bridge.css +30 -0
  150. package/styles/colors/index.css +19 -1
  151. package/styles/colors/material-static.css +771 -0
  152. package/styles/colors/parameters.css +40 -4
  153. package/styles/colors/primitives-primary.css +89 -0
  154. package/styles/colors/primitives-secondary.css +89 -0
  155. package/styles/colors/primitives-tertiary.css +89 -0
  156. package/styles/colors/primitives.css +3 -1
  157. package/styles/colors/scrims.css +19 -180
  158. package/styles/colors/semantics/aliases.css +25 -11
  159. package/styles/colors/semantics/buckets.css +28 -12
  160. package/styles/colors/semantics/core.css +323 -202
  161. package/styles/colors/semantics/data-viz.css +13 -13
  162. package/styles/colors/semantics/features.css +31 -13
  163. package/styles/colors/surfaces.css +41 -31
  164. package/styles/resets.css +15 -1
  165. package/styles/themes.css +15 -15
  166. package/styles/colors/primitives-accent.css +0 -89
@@ -389,3 +389,40 @@ describe('table-ui — F6 per-row expand suppression (rowExpandable)', () => {
389
389
  expect(el.expanded).toContain(1);
390
390
  });
391
391
  });
392
+
393
+ describe('table-ui — "markdown" cell type (TKT-0008)', () => {
394
+ it('renders inline `code`/**bold**/*italic*/[link](href) as real elements, not literal syntax', async () => {
395
+ const el = mount('<table-ui></table-ui>');
396
+ el.columns = [{ key: 'desc', label: 'Description', type: 'markdown' }];
397
+ el.data = [{ desc: 'Semantic status: `new` | `updated` | **beta** or *deprecated*, see [docs](/site/components/badge).' }];
398
+ await raf();
399
+
400
+ const cell = el.querySelector('[role="gridcell"][data-key="desc"]');
401
+ expect([...cell.querySelectorAll('code')].map((c) => c.textContent)).toEqual(['new', 'updated']);
402
+ expect(cell.querySelector('strong').textContent).toBe('beta');
403
+ expect(cell.querySelector('em').textContent).toBe('deprecated');
404
+ expect(cell.querySelector('a').getAttribute('href')).toBe('/site/components/badge');
405
+ expect(cell.textContent).not.toMatch(/`|\*\*|\[docs\]/); // no literal markdown syntax leaked through
406
+ });
407
+
408
+ it('sets [title] to the plain-text (tag-stripped) version, for the truncation tooltip', async () => {
409
+ const el = mount('<table-ui></table-ui>');
410
+ el.columns = [{ key: 'prop', label: 'Prop', type: 'markdown' }];
411
+ el.data = [{ prop: '`variant`' }];
412
+ await raf();
413
+
414
+ const cell = el.querySelector('[role="gridcell"][data-key="prop"]');
415
+ expect(cell.title).toBe('variant');
416
+ });
417
+
418
+ it('a plain value with no markdown syntax renders as ordinary text (no stray elements)', async () => {
419
+ const el = mount('<table-ui></table-ui>');
420
+ el.columns = [{ key: 'desc', label: 'Description', type: 'markdown' }];
421
+ el.data = [{ desc: 'Plain sentence, no special characters.' }];
422
+ await raf();
423
+
424
+ const cell = el.querySelector('[role="gridcell"][data-key="desc"]');
425
+ expect(cell.querySelector('code, strong, em, a')).toBeNull();
426
+ expect(cell.textContent).toBe('Plain sentence, no special characters.');
427
+ });
428
+ });
@@ -27,6 +27,8 @@ props:
27
27
  data:
28
28
  description: Row records. Array of plain objects keyed to columns[].key.
29
29
  type: array
30
+ items:
31
+ type: object
30
32
  default: []
31
33
  dynamic: true # JS-set collection prop with a custom setter — deliberately not in static properties
32
34
  density:
@@ -33,7 +33,7 @@
33
33
  :scope {
34
34
  box-sizing: border-box;
35
35
  display: block;
36
- color: var(--a-fg);
36
+ color: var(--md-sys-color-neutral-on-surface);
37
37
  }
38
38
 
39
39
  [data-toolbar] {
@@ -54,8 +54,8 @@
54
54
  base styles". */
55
55
 
56
56
  :scope[variant="card"] {
57
- --table-toolbar-bg: var(--a-bg);
58
- --table-toolbar-border: var(--a-border-subtle);
57
+ --table-toolbar-bg: var(--md-sys-color-neutral-background);
58
+ --table-toolbar-border: var(--md-sys-color-neutral-outline-variant);
59
59
  --table-toolbar-border-width: 1px;
60
60
  --table-toolbar-py: var(--a-space-3);
61
61
  --table-toolbar-px: var(--a-space-4);
@@ -126,8 +126,8 @@
126
126
  [data-toolbar-popover]:popover-open {
127
127
  margin: 0;
128
128
  padding: var(--a-space-1);
129
- background: var(--a-canvas-bright);
130
- color: var(--a-fg);
129
+ background: var(--md-sys-color-neutral-surface-bright);
130
+ color: var(--md-sys-color-neutral-on-surface);
131
131
  border: 1px solid var(--a-ui-border);
132
132
  border-radius: var(--a-radius);
133
133
  box-shadow: var(--a-shadow-lg);
@@ -180,7 +180,7 @@
180
180
 
181
181
  [data-toolbar-popover] [data-popover-action] {
182
182
  margin-top: var(--a-space-1);
183
- border-top: 1px solid var(--a-border-subtle);
183
+ border-top: 1px solid var(--md-sys-color-neutral-outline-variant);
184
184
  padding-top: var(--a-space-1);
185
185
  }
186
186
 
@@ -198,7 +198,7 @@
198
198
  for exactly this. Stays inside the menu-item-ui token contract. */
199
199
  [data-toolbar-popover] [data-sort-row][data-active] {
200
200
  --menu-item-bg: var(--a-bg-selected);
201
- --menu-item-fg: var(--a-fg);
202
- --menu-item-icon-fg: var(--a-fg);
201
+ --menu-item-fg: var(--md-sys-color-neutral-on-surface);
202
+ --menu-item-icon-fg: var(--md-sys-color-neutral-on-surface);
203
203
  font-weight: var(--a-ui-weight, var(--a-weight-medium));
204
204
  }
@@ -9,10 +9,10 @@
9
9
  --tabs-font-size: var(--a-ui-md);
10
10
  --tabs-font-family: var(--a-font-family-ui);
11
11
  --tabs-gap: var(--a-space-1);
12
- --tabs-indicator-color: var(--a-primary);
12
+ --tabs-indicator-color: var(--md-sys-color-primary);
13
13
  --tabs-indicator-height: 2px;
14
- --tabs-fg: var(--a-fg-subtle);
15
- --tabs-fg-hover: var(--a-fg);
14
+ --tabs-fg: var(--md-sys-color-neutral-on-surface-variant);
15
+ --tabs-fg-hover: var(--md-sys-color-neutral-on-surface);
16
16
  --tabs-fg-active: var(--a-fg-selected);
17
17
  --tabs-fg-disabled: var(--a-ui-text-disabled);
18
18
 
@@ -47,8 +47,8 @@
47
47
 
48
48
  /* Bordered variant — baseline border under the tab strip.
49
49
  The active indicator sits on top of the border for a clean join. */
50
- :scope[variant="bordered"] { --tabs-border: var(--a-border-subtle); }
51
- :scope[divider] { --tabs-border: var(--a-border-subtle); }
50
+ :scope[variant="bordered"] { --tabs-border: var(--md-sys-color-neutral-outline-variant); }
51
+ :scope[divider] { --tabs-border: var(--md-sys-color-neutral-outline-variant); }
52
52
 
53
53
  /* Vertical orientation: strip on the left, panels on the right */
54
54
  :scope[orientation="vertical"] {
@@ -8,7 +8,7 @@ tag-ui[removable]:not([disabled]):hover {
8
8
  :where(:scope) {
9
9
  /* ── Tokens ── */
10
10
  --tag-bg: var(--a-bg-muted);
11
- --tag-fg: var(--a-fg);
11
+ --tag-fg: var(--md-sys-color-neutral-on-surface);
12
12
  --tag-border: transparent;
13
13
  --tag-radius: var(--a-radius-full);
14
14
  --tag-px: var(--a-space-1-5);
@@ -51,6 +51,16 @@ tag-ui[removable]:not([disabled]):hover {
51
51
  box-sizing: border-box;
52
52
  display: inline-flex;
53
53
  align-items: center;
54
+ /* align-self: start — TKT-0021. A flex-column ancestor (col-ui
55
+ defaults to align-items: stretch) otherwise stretches a bare
56
+ tag-ui to the column's full width; a chip should size to its own
57
+ content regardless of ancestor. justify-content: center is the
58
+ matching defensive default badge-ui/button-ui already carry
59
+ (badge.css/button.css) — if the box is ever wider than its
60
+ content for any other reason, the label still centers instead of
61
+ reading left-aligned in an oversized pill. */
62
+ align-self: start;
63
+ justify-content: center;
54
64
  gap: var(--tag-gap);
55
65
  padding: var(--tag-py) var(--tag-px);
56
66
  border-radius: var(--tag-radius);
@@ -85,26 +95,28 @@ tag-ui[removable]:not([disabled]):hover {
85
95
  metadata-chip surfaces in dense lists. */
86
96
  :scope[variant="info"] {
87
97
  --tag-bg: var(--a-info-bg);
88
- --tag-fg: var(--a-info-fg);
98
+ --tag-fg: var(--md-sys-color-info-on-info);
89
99
  }
90
100
 
91
101
  :scope[variant="success"] {
92
102
  --tag-bg: var(--a-success-bg);
93
- --tag-fg: var(--a-success-fg);
103
+ --tag-fg: var(--md-sys-color-success-on-success);
94
104
  }
95
105
 
96
- /* `--a-warning-bg` is the bright-amber step (semantics.css L3 redirect
97
- to `-20-tint`) paired with `--a-warning-fg` (dark brown text) — the
98
- canonical caution-tape pair. Pre-v0.6.36 this rule had a local
99
- `-20-tint` override; that workaround moved to the token system. */
106
+ /* Same shape as the sibling families since the Material static-token
107
+ migration: amber fill + the palette's own fixed-light on-color
108
+ (`on-warning`, white in both schemes per Material's on-color law).
109
+ The pre-migration dark-brown-text override is gone its
110
+ lower-than-siblings contrast is a known, operator-accepted
111
+ consequence (TKT-0018, wontfix pending palette adjustment). */
100
112
  :scope[variant="warning"] {
101
113
  --tag-bg: var(--a-warning-bg);
102
- --tag-fg: var(--a-warning-fg);
114
+ --tag-fg: var(--md-sys-color-warning-on-warning);
103
115
  }
104
116
 
105
117
  :scope[variant="danger"] {
106
118
  --tag-bg: var(--a-danger-bg);
107
- --tag-fg: var(--a-danger-fg);
119
+ --tag-fg: var(--md-sys-color-danger-on-danger);
108
120
  }
109
121
 
110
122
  /* `default` (no family) stays as quiet chrome — a stark fg/bg-inverse
@@ -112,7 +124,7 @@ tag-ui[removable]:not([disabled]):hover {
112
124
  stamp via `[tone="solid"]` when you want a high-contrast neutral pill. */
113
125
  :scope[variant="default"] {
114
126
  --tag-bg: var(--a-bg-muted);
115
- --tag-fg: var(--a-fg);
127
+ --tag-fg: var(--md-sys-color-neutral-on-surface);
116
128
  }
117
129
 
118
130
  /* ── Tone modifier — orthogonal to [variant] ──
@@ -122,28 +134,28 @@ tag-ui[removable]:not([disabled]):hover {
122
134
  uses as its default. Use on metadata chips in dense lists where the
123
135
  saturated default would compete for attention. */
124
136
  :scope[tone="muted"][variant="info"] {
125
- --tag-bg: var(--a-info-muted);
126
- --tag-fg: var(--a-info-text);
137
+ --tag-bg: var(--md-sys-color-info-container);
138
+ --tag-fg: var(--md-sys-color-info-on-surface);
127
139
  }
128
140
  :scope[tone="muted"][variant="success"] {
129
- --tag-bg: var(--a-success-muted);
130
- --tag-fg: var(--a-success-text);
141
+ --tag-bg: var(--md-sys-color-success-container);
142
+ --tag-fg: var(--md-sys-color-success-on-surface);
131
143
  }
132
144
  :scope[tone="muted"][variant="warning"] {
133
- --tag-bg: var(--a-warning-muted);
134
- --tag-fg: var(--a-warning-text);
145
+ --tag-bg: var(--md-sys-color-warning-container);
146
+ --tag-fg: var(--md-sys-color-warning-on-surface);
135
147
  }
136
148
  :scope[tone="muted"][variant="danger"] {
137
- --tag-bg: var(--a-danger-muted);
138
- --tag-fg: var(--a-danger-text);
149
+ --tag-bg: var(--md-sys-color-danger-container);
150
+ --tag-fg: var(--md-sys-color-danger-on-surface);
139
151
  }
140
152
 
141
153
  /* `[tone="solid"]` on the neutral default (or no variant) inverts the
142
154
  chrome — solid fg-color bg with bg-color text. High-contrast neutral
143
155
  stamp. Explicit opt-in; the variant-less default stays quiet chrome. */
144
156
  :scope[tone="solid"]:not([variant="info"]):not([variant="success"]):not([variant="warning"]):not([variant="danger"]) {
145
- --tag-bg: var(--a-fg);
146
- --tag-fg: var(--a-bg);
157
+ --tag-bg: var(--md-sys-color-neutral-on-surface);
158
+ --tag-fg: var(--md-sys-color-neutral-background);
147
159
  }
148
160
 
149
161
  /* ── `[tone="outline"]` — transparent bg + family-colored border + text ──
@@ -155,25 +167,25 @@ tag-ui[removable]:not([disabled]):hover {
155
167
  --tag-bg: transparent;
156
168
  }
157
169
  :scope[tone="outline"][variant="info"] {
158
- --tag-fg: var(--a-info-text);
159
- --tag-border: var(--a-info-border);
170
+ --tag-fg: var(--md-sys-color-info-on-surface);
171
+ --tag-border: var(--md-sys-color-info-outline);
160
172
  }
161
173
  :scope[tone="outline"][variant="success"] {
162
- --tag-fg: var(--a-success-text);
163
- --tag-border: var(--a-success-border);
174
+ --tag-fg: var(--md-sys-color-success-on-surface);
175
+ --tag-border: var(--md-sys-color-success-outline);
164
176
  }
165
177
  :scope[tone="outline"][variant="warning"] {
166
- --tag-fg: var(--a-warning-text);
167
- --tag-border: var(--a-warning-border);
178
+ --tag-fg: var(--md-sys-color-warning-on-surface);
179
+ --tag-border: var(--md-sys-color-warning-outline);
168
180
  }
169
181
  :scope[tone="outline"][variant="danger"] {
170
- --tag-fg: var(--a-danger-text);
171
- --tag-border: var(--a-danger-border);
182
+ --tag-fg: var(--md-sys-color-danger-on-surface);
183
+ --tag-border: var(--md-sys-color-danger-outline);
172
184
  }
173
185
  /* Outline on neutral (no family) — fg-muted text + subtle border. */
174
186
  :scope[tone="outline"]:not([variant="info"]):not([variant="success"]):not([variant="warning"]):not([variant="danger"]) {
175
187
  --tag-fg: var(--a-fg-muted);
176
- --tag-border: var(--a-border);
188
+ --tag-border: var(--md-sys-color-neutral-outline);
177
189
  }
178
190
 
179
191
  /* Size handled by universal [size] attribute system. */
@@ -50,50 +50,43 @@ describe('tag-ui — content: attr(text) gating', () => {
50
50
  // ── Tone defaults (solid by default for families; muted as opt-out) ──
51
51
  //
52
52
  // Default tone is `solid` for family variants — the base `:scope[variant=…]`
53
- // rules use the saturated-fill pair `--a-{family}-bg` + `--a-{family}-fg`
54
- // (the chip IS the state). `[tone="muted"]` opts back into the canonical
55
- // muted pair `--a-{family}-muted` + `--a-{family}-text` (same look as
53
+ // rules pair the saturated `--a-{family}-bg` fill with the palette's own
54
+ // Material on-color `--md-sys-color-{family}-on-{family}` (the chip IS the
55
+ // state). `[tone="muted"]` opts back into the Material container pair
56
+ // `--md-sys-color-{family}-container` + `-on-surface` (same look as
56
57
  // <badge-ui>'s default). The `default` (no-family) variant stays quiet
57
- // chrome unless `[tone="solid"]` is set explicitly (then it inverts
58
- // to fg/bg for a high-contrast neutral stamp).
58
+ // chrome unless `[tone="solid"]` is set explicitly (then it inverts to a
59
+ // high-contrast neutral stamp). Token names updated for the Material
60
+ // static-token migration (material-color-bridge-contract.md, 2026-07-15).
59
61
 
60
62
  describe('tag-ui — variant defaults to solid fill', () => {
61
63
  it.each([
62
64
  ['info'],
63
65
  ['success'],
66
+ ['warning'],
64
67
  ['danger'],
65
- ])('[variant="%s"] base rule uses --a-{family}-bg + --a-{family}-fg', (family) => {
68
+ ])('[variant="%s"] base rule uses --a-{family}-bg + --md-sys-color-{family}-on-{family}', (family) => {
66
69
  const block = new RegExp(
67
70
  `:scope\\[variant="${family}"\\]\\s*\\{[^}]*` +
68
71
  `--tag-bg:\\s*var\\(--a-${family}-bg\\)[^}]*` +
69
- `--tag-fg:\\s*var\\(--a-${family}-fg\\)`,
72
+ `--tag-fg:\\s*var\\(--md-sys-color-${family}-on-${family}\\)`,
70
73
  's'
71
74
  );
72
75
  expect(TAG_CSS).toMatch(block);
73
76
  });
74
-
75
- it('[variant="warning"] uses the canonical --a-warning-bg + --a-warning-fg pair', () => {
76
- // v0.6.36 token-system fix: --a-warning-bg now redirects to
77
- // --a-warning-20-tint at the L3 layer (semantics.css), so consumers
78
- // can pair `-bg` + `-fg` cleanly without local overrides. The pair
79
- // resolves to bright-amber-bg + dark-brown-text in both schemes.
80
- expect(TAG_CSS).toMatch(
81
- /:scope\[variant="warning"\]\s*\{[^}]*--tag-bg:\s*var\(--a-warning-bg\)[^}]*--tag-fg:\s*var\(--a-warning-fg\)/s
82
- );
83
- });
84
77
  });
85
78
 
86
- describe('tag-ui — [tone="muted"] opts out to canonical muted pair', () => {
79
+ describe('tag-ui — [tone="muted"] opts out to the Material container pair', () => {
87
80
  it.each([
88
81
  ['info'],
89
82
  ['success'],
90
83
  ['warning'],
91
84
  ['danger'],
92
- ])('[tone="muted"][variant="%s"] uses --a-{family}-muted + --a-{family}-text', (family) => {
85
+ ])('[tone="muted"][variant="%s"] uses -container + -on-surface', (family) => {
93
86
  const block = new RegExp(
94
87
  `:scope\\[tone="muted"\\]\\[variant="${family}"\\]\\s*\\{[^}]*` +
95
- `--tag-bg:\\s*var\\(--a-${family}-muted\\)[^}]*` +
96
- `--tag-fg:\\s*var\\(--a-${family}-text\\)`,
88
+ `--tag-bg:\\s*var\\(--md-sys-color-${family}-container\\)[^}]*` +
89
+ `--tag-fg:\\s*var\\(--md-sys-color-${family}-on-surface\\)`,
97
90
  's'
98
91
  );
99
92
  expect(TAG_CSS).toMatch(block);
@@ -101,15 +94,15 @@ describe('tag-ui — [tone="muted"] opts out to canonical muted pair', () => {
101
94
  });
102
95
 
103
96
  describe('tag-ui — neutral default + explicit solid stamp', () => {
104
- it('[variant="default"] stays quiet chrome (--a-bg-muted + --a-fg)', () => {
97
+ it('[variant="default"] stays quiet chrome (--a-bg-muted + neutral on-surface)', () => {
105
98
  expect(TAG_CSS).toMatch(
106
- /:scope\[variant="default"\]\s*\{[^}]*--tag-bg:\s*var\(--a-bg-muted\)[^}]*--tag-fg:\s*var\(--a-fg\)/s
99
+ /:scope\[variant="default"\]\s*\{[^}]*--tag-bg:\s*var\(--a-bg-muted\)[^}]*--tag-fg:\s*var\(--md-sys-color-neutral-on-surface\)/s
107
100
  );
108
101
  });
109
102
 
110
- it('[tone="solid"] without a family inverts to fg/bg high-contrast stamp', () => {
103
+ it('[tone="solid"] without a family inverts to a high-contrast neutral stamp', () => {
111
104
  expect(TAG_CSS).toMatch(
112
- /:scope\[tone="solid"\]:not\(\[variant="info"\]\)[\s\S]*?--tag-bg:\s*var\(--a-fg\)[\s\S]*?--tag-fg:\s*var\(--a-bg\)/
105
+ /:scope\[tone="solid"\]:not\(\[variant="info"\]\)[\s\S]*?--tag-bg:\s*var\(--md-sys-color-neutral-on-surface\)[\s\S]*?--tag-fg:\s*var\(--md-sys-color-neutral-background\)/
113
106
  );
114
107
  });
115
108
  });
@@ -129,16 +122,16 @@ describe('tag-ui — [tone="outline"] strips fill + colors border', () => {
129
122
  ])('[tone="outline"][variant="%s"] colors fg + border per family', (family) => {
130
123
  const block = new RegExp(
131
124
  `:scope\\[tone="outline"\\]\\[variant="${family}"\\]\\s*\\{[^}]*` +
132
- `--tag-fg:\\s*var\\(--a-${family}-text\\)[^}]*` +
133
- `--tag-border:\\s*var\\(--a-${family}-border\\)`,
125
+ `--tag-fg:\\s*var\\(--md-sys-color-${family}-on-surface\\)[^}]*` +
126
+ `--tag-border:\\s*var\\(--md-sys-color-${family}-outline\\)`,
134
127
  's'
135
128
  );
136
129
  expect(TAG_CSS).toMatch(block);
137
130
  });
138
131
 
139
- it('[tone="outline"] on neutral uses --a-fg-muted text + --a-border ring', () => {
132
+ it('[tone="outline"] on neutral uses --a-fg-muted text + neutral outline ring', () => {
140
133
  expect(TAG_CSS).toMatch(
141
- /:scope\[tone="outline"\]:not\(\[variant="info"\]\)[\s\S]*?--tag-fg:\s*var\(--a-fg-muted\)[\s\S]*?--tag-border:\s*var\(--a-border\)/
134
+ /:scope\[tone="outline"\]:not\(\[variant="info"\]\)[\s\S]*?--tag-fg:\s*var\(--a-fg-muted\)[\s\S]*?--tag-border:\s*var\(--md-sys-color-neutral-outline\)/
142
135
  );
143
136
  });
144
137
  });
@@ -227,7 +227,7 @@
227
227
  ],
228
228
  "slots": {
229
229
  "chip": {
230
- "description": "Custom chip template receives `{value, index}` per token.\nWhen absent, each token renders as a default\n`<tag-ui removable text=\"<value>\">`."
230
+ "description": "Planned: custom chip template, receiving `{value, index}` per\ntoken NOT YET IMPLEMENTED (TKT-0023; the template mechanism's\nshape needs a design decision before it's built). Every token\ncurrently renders as the fixed default,\n`<tag-ui removable text=\"<value>\">`, with no override path."
231
231
  }
232
232
  },
233
233
  "states": [
@@ -25,10 +25,10 @@
25
25
  --tags-input-easing: var(--a-easing);
26
26
 
27
27
  /* ── Chip overrides — cascaded into nested <tag-ui> ── */
28
- --tags-input-chip-bg-invalid: var(--a-danger-muted);
28
+ --tags-input-chip-bg-invalid: var(--md-sys-color-danger-container);
29
29
 
30
30
  /* ── Suggestions popover ── */
31
- --tags-input-suggestions-bg: var(--a-canvas-bright);
31
+ --tags-input-suggestions-bg: var(--md-sys-color-neutral-surface-bright);
32
32
  --tags-input-suggestions-border: var(--a-ui-border);
33
33
  --tags-input-suggestions-radius: var(--a-radius);
34
34
  --tags-input-suggestions-shadow: var(--a-shadow-lg);
@@ -169,7 +169,7 @@ tags-input-ui [data-suggestions] {
169
169
  padding: var(--a-space-1);
170
170
  border: 1px solid var(--a-ui-border);
171
171
  border-radius: var(--a-radius);
172
- background: var(--a-canvas-bright);
172
+ background: var(--md-sys-color-neutral-surface-bright);
173
173
  box-shadow: var(--a-shadow-lg);
174
174
  font-family: inherit;
175
175
  font-size: var(--a-ui-size);
@@ -186,9 +186,11 @@ events:
186
186
  slots:
187
187
  chip:
188
188
  description: |-
189
- Custom chip template receives `{value, index}` per token.
190
- When absent, each token renders as a default
191
- `<tag-ui removable text="<value>">`.
189
+ Planned: custom chip template, receiving `{value, index}` per
190
+ token NOT YET IMPLEMENTED (TKT-0023; the template mechanism's
191
+ shape needs a design decision before it's built). Every token
192
+ currently renders as the fixed default,
193
+ `<tag-ui removable text="<value>">`, with no override path.
192
194
  states:
193
195
  - name: idle
194
196
  description: No tokens; no typed text.
@@ -8,7 +8,7 @@
8
8
  --text-leading: var(--a-body-leading);
9
9
  --text-tracking: var(--a-body-tracking);
10
10
  --text-case: var(--a-body-case);
11
- --text-color: var(--a-fg);
11
+ --text-color: var(--md-sys-color-neutral-on-surface);
12
12
  --text-color-strong: var(--a-fg-strong);
13
13
  }
14
14
 
@@ -38,7 +38,7 @@
38
38
  }
39
39
 
40
40
  /* ── Variants ── */
41
- :scope[variant="body"] { --text-family: var(--a-body-family); --text-weight: var(--a-body-weight); --text-size: var(--a-body-size); --text-leading: var(--a-body-leading); --text-tracking: var(--a-body-tracking); --text-case: var(--a-body-case); --text-color: var(--a-fg); }
41
+ :scope[variant="body"] { --text-family: var(--a-body-family); --text-weight: var(--a-body-weight); --text-size: var(--a-body-size); --text-leading: var(--a-body-leading); --text-tracking: var(--a-body-tracking); --text-case: var(--a-body-case); --text-color: var(--md-sys-color-neutral-on-surface); }
42
42
  :scope[variant="display"] { --text-family: var(--a-display-family); --text-weight: var(--a-display-weight); --text-size: var(--a-display-size); --text-leading: var(--a-display-leading); --text-tracking: var(--a-display-tracking); --text-case: var(--a-display-case); --text-color: var(--a-display-color); }
43
43
  :scope[variant="title"] { --text-family: var(--a-title-family); --text-weight: var(--a-title-weight); --text-size: var(--a-title-size); --text-leading: var(--a-title-leading); --text-tracking: var(--a-title-tracking); --text-case: var(--a-title-case); --text-color: var(--a-title-color); }
44
44
  :scope[variant="heading"] { --text-family: var(--a-heading-family); --text-weight: var(--a-heading-weight); --text-size: var(--a-heading-size); --text-leading: var(--a-heading-leading); --text-tracking: var(--a-heading-tracking); --text-case: var(--a-heading-case); --text-color: var(--a-heading-color); }
@@ -78,10 +78,10 @@
78
78
 
79
79
  /* color — default | subtle | strong | accent | danger | success | warning
80
80
  (no value = variant default; "default" is an explicit reset). */
81
- :scope[color="default"] { --text-color: var(--a-fg); }
81
+ :scope[color="default"] { --text-color: var(--md-sys-color-neutral-on-surface); }
82
82
  :scope[color="subtle"] { --text-color: var(--a-fg-muted); }
83
83
  :scope[color="strong"] { --text-color: var(--a-fg-strong); }
84
- :scope[color="accent"] { --text-color: var(--a-accent); }
84
+ :scope[color="accent"] { --text-color: var(--md-sys-color-primary); }
85
85
  :scope[color="danger"] { --text-color: var(--a-danger-bg); }
86
86
  :scope[color="success"] { --text-color: var(--a-success-bg); }
87
87
  :scope[color="warning"] { --text-color: var(--a-warning-bg); }
@@ -34,7 +34,7 @@ textarea-ui:not([disabled]) [slot="text"]:hover {
34
34
  /* ── State ── */
35
35
  --textarea-bg-hover: var(--a-ui-bg-hover);
36
36
  --textarea-fg-hover: var(--a-ui-text-hover);
37
- --textarea-label-fg-focus: var(--a-fg-subtle);
37
+ --textarea-label-fg-focus: var(--md-sys-color-neutral-on-surface-variant);
38
38
  --textarea-bg-disabled: var(--a-ui-bg-disabled);
39
39
  --textarea-fg-disabled: var(--a-ui-text-disabled);
40
40
  text-align: start; /* §text-align-reset — blocks inheritance from centered ancestors */
@@ -15,8 +15,8 @@
15
15
 
16
16
  --time-picker-segment-radius: var(--a-radius-sm);
17
17
  --time-picker-segment-px: var(--a-space-1);
18
- --time-picker-segment-bg-focus: var(--a-accent);
19
- --time-picker-segment-fg-focus: var(--a-accent-fg);
18
+ --time-picker-segment-bg-focus: var(--md-sys-color-primary);
19
+ --time-picker-segment-fg-focus: var(--md-sys-color-primary-on-primary);
20
20
 
21
21
  --time-picker-separator-fg: var(--a-fg-muted);
22
22
 
@@ -24,20 +24,20 @@
24
24
 
25
25
  /* Dot */
26
26
  --timeline-dot-size: 0.625rem;
27
- --timeline-dot-bg: var(--a-border);
28
- --timeline-dot-bg-active: var(--a-accent-bg);
27
+ --timeline-dot-bg: var(--md-sys-color-neutral-outline);
28
+ --timeline-dot-bg-active: var(--a-primary-bg);
29
29
  --timeline-dot-bg-done: var(--a-success-bg);
30
30
  --timeline-dot-bg-error: var(--a-danger-bg);
31
31
  --timeline-dot-bg-warning: var(--a-warning-bg);
32
32
 
33
33
  /* Sub-dot (outcomes) */
34
34
  --timeline-subdot-size: 4px;
35
- --timeline-subdot-bg: var(--a-fg-subtle);
35
+ --timeline-subdot-bg: var(--md-sys-color-neutral-on-surface-variant);
36
36
 
37
37
  /* Connector line */
38
38
  --timeline-line-size: 2px;
39
- --timeline-line-fg: var(--a-border-subtle);
40
- --timeline-line-fg-done: var(--a-border);
39
+ --timeline-line-fg: var(--md-sys-color-neutral-outline-variant);
40
+ --timeline-line-fg-done: var(--md-sys-color-neutral-outline);
41
41
 
42
42
  /* Marker box — the shared circular footprint the icon marker fills and
43
43
  the dot / spinner center within (the column track --timeline-marker-w
@@ -49,23 +49,23 @@
49
49
  /* Icon (replaces dot) */
50
50
  --timeline-icon-size: var(--timeline-marker-box-size);
51
51
  --timeline-icon-bg: var(--a-bg-muted);
52
- --timeline-icon-fg: var(--a-fg-subtle);
53
- --timeline-icon-border: var(--a-border-subtle);
54
- --timeline-icon-bg-success: var(--a-success-muted);
52
+ --timeline-icon-fg: var(--md-sys-color-neutral-on-surface-variant);
53
+ --timeline-icon-border: var(--md-sys-color-neutral-outline-variant);
54
+ --timeline-icon-bg-success: var(--md-sys-color-success-container);
55
55
  --timeline-icon-fg-success: var(--a-success-strong);
56
- --timeline-icon-bg-accent: var(--a-accent-muted);
57
- --timeline-icon-fg-accent: var(--a-accent);
58
- --timeline-icon-bg-warning: var(--a-warning-muted);
59
- --timeline-icon-fg-warning: var(--a-warning);
60
- --timeline-icon-bg-danger: var(--a-danger-muted);
56
+ --timeline-icon-bg-accent: var(--md-sys-color-primary-container);
57
+ --timeline-icon-fg-accent: var(--md-sys-color-primary);
58
+ --timeline-icon-bg-warning: var(--md-sys-color-warning-container);
59
+ --timeline-icon-fg-warning: var(--md-sys-color-warning);
60
+ --timeline-icon-bg-danger: var(--md-sys-color-danger-container);
61
61
  --timeline-icon-fg-danger: var(--a-danger-strong);
62
62
 
63
63
  /* Typography */
64
64
  --timeline-label-weight: var(--a-weight-medium);
65
65
  --timeline-label-size: var(--a-ui-size);
66
- --timeline-label-fg: var(--a-fg);
66
+ --timeline-label-fg: var(--md-sys-color-neutral-on-surface);
67
67
  --timeline-label-fg-muted: var(--a-fg-muted);
68
- --timeline-desc-fg: var(--a-fg-subtle);
68
+ --timeline-desc-fg: var(--md-sys-color-neutral-on-surface-variant);
69
69
  --timeline-desc-size: var(--a-ui-sm);
70
70
  --timeline-time-fg: var(--a-fg-muted);
71
71
  --timeline-time-size: var(--a-ui-sm);
@@ -129,18 +129,18 @@ agent-reasoning-ui timeline-ui:not([orientation="horizontal"]),
129
129
  --timeline-item-gap-row: var(--timeline-gap-row, var(--a-space-3));
130
130
 
131
131
  --timeline-item-dot-size: var(--timeline-dot-size, 0.625rem);
132
- --timeline-item-dot-bg: var(--timeline-dot-bg, var(--a-border));
133
- --timeline-item-dot-bg-active: var(--timeline-dot-bg-active, var(--a-accent-bg));
132
+ --timeline-item-dot-bg: var(--timeline-dot-bg, var(--md-sys-color-neutral-outline));
133
+ --timeline-item-dot-bg-active: var(--timeline-dot-bg-active, var(--a-primary-bg));
134
134
  --timeline-item-dot-bg-done: var(--timeline-dot-bg-done, var(--a-success-bg));
135
135
  --timeline-item-dot-bg-error: var(--timeline-dot-bg-error, var(--a-danger-bg));
136
136
  --timeline-item-dot-bg-warning: var(--timeline-dot-bg-warning, var(--a-warning-bg));
137
137
 
138
138
  --timeline-item-subdot-size: var(--timeline-subdot-size, 4px);
139
- --timeline-item-subdot-bg: var(--timeline-subdot-bg, var(--a-fg-subtle));
139
+ --timeline-item-subdot-bg: var(--timeline-subdot-bg, var(--md-sys-color-neutral-on-surface-variant));
140
140
 
141
141
  --timeline-item-line-size: var(--timeline-line-size, 2px);
142
- --timeline-item-line-fg: var(--timeline-line-fg, var(--a-border-subtle));
143
- --timeline-item-line-fg-done: var(--timeline-line-fg-done, var(--a-border));
142
+ --timeline-item-line-fg: var(--timeline-line-fg, var(--md-sys-color-neutral-outline-variant));
143
+ --timeline-item-line-fg-done: var(--timeline-line-fg-done, var(--md-sys-color-neutral-outline));
144
144
 
145
145
  /* Reads the override THEN the inherited -default (set on timeline-ui,
146
146
  and shrunk by [size="sm"]) THEN a literal — so the marker box scales
@@ -148,22 +148,22 @@ agent-reasoning-ui timeline-ui:not([orientation="horizontal"]),
148
148
  --timeline-item-marker-box-size: var(--timeline-marker-box-size, var(--timeline-marker-box-size, 1rem));
149
149
  --timeline-item-icon-size: var(--timeline-icon-size, var(--timeline-item-marker-box-size));
150
150
  --timeline-item-icon-bg: var(--timeline-icon-bg, var(--a-bg-muted));
151
- --timeline-item-icon-fg: var(--timeline-icon-fg, var(--a-fg-subtle));
152
- --timeline-item-icon-border: var(--timeline-icon-border, var(--a-border-subtle));
153
- --timeline-item-icon-bg-success: var(--timeline-icon-bg-success, var(--a-success-muted));
151
+ --timeline-item-icon-fg: var(--timeline-icon-fg, var(--md-sys-color-neutral-on-surface-variant));
152
+ --timeline-item-icon-border: var(--timeline-icon-border, var(--md-sys-color-neutral-outline-variant));
153
+ --timeline-item-icon-bg-success: var(--timeline-icon-bg-success, var(--md-sys-color-success-container));
154
154
  --timeline-item-icon-fg-success: var(--timeline-icon-fg-success, var(--a-success-strong));
155
- --timeline-item-icon-bg-accent: var(--timeline-icon-bg-accent, var(--a-accent-muted));
156
- --timeline-item-icon-fg-accent: var(--timeline-icon-fg-accent, var(--a-accent));
157
- --timeline-item-icon-bg-warning: var(--timeline-icon-bg-warning, var(--a-warning-muted));
158
- --timeline-item-icon-fg-warning: var(--timeline-icon-fg-warning, var(--a-warning));
159
- --timeline-item-icon-bg-danger: var(--timeline-icon-bg-danger, var(--a-danger-muted));
155
+ --timeline-item-icon-bg-accent: var(--timeline-icon-bg-accent, var(--md-sys-color-primary-container));
156
+ --timeline-item-icon-fg-accent: var(--timeline-icon-fg-accent, var(--md-sys-color-primary));
157
+ --timeline-item-icon-bg-warning: var(--timeline-icon-bg-warning, var(--md-sys-color-warning-container));
158
+ --timeline-item-icon-fg-warning: var(--timeline-icon-fg-warning, var(--md-sys-color-warning));
159
+ --timeline-item-icon-bg-danger: var(--timeline-icon-bg-danger, var(--md-sys-color-danger-container));
160
160
  --timeline-item-icon-fg-danger: var(--timeline-icon-fg-danger, var(--a-danger-strong));
161
161
 
162
162
  --timeline-item-label-weight: var(--timeline-label-weight, var(--a-weight-medium));
163
163
  --timeline-item-label-size: var(--timeline-label-size, var(--a-ui-size));
164
- --timeline-item-label-fg: var(--timeline-label-fg, var(--a-fg));
164
+ --timeline-item-label-fg: var(--timeline-label-fg, var(--md-sys-color-neutral-on-surface));
165
165
  --timeline-item-label-fg-muted: var(--timeline-label-fg-muted, var(--a-fg-muted));
166
- --timeline-item-desc-fg: var(--timeline-desc-fg, var(--a-fg-subtle));
166
+ --timeline-item-desc-fg: var(--timeline-desc-fg, var(--md-sys-color-neutral-on-surface-variant));
167
167
  --timeline-item-desc-size: var(--timeline-desc-size, var(--a-ui-sm));
168
168
  --timeline-item-time-fg: var(--timeline-time-fg, var(--a-fg-muted));
169
169
  --timeline-item-time-size: var(--timeline-time-size, var(--a-ui-sm));
@@ -387,7 +387,7 @@ agent-reasoning-ui timeline-ui:not([orientation="horizontal"]),
387
387
 
388
388
  :scope > [data-timeline-toggle]:hover {
389
389
  background: var(--a-bg-subtle);
390
- color: var(--timeline-item-label-fg, var(--a-fg));
390
+ color: var(--timeline-item-label-fg, var(--md-sys-color-neutral-on-surface));
391
391
  }
392
392
 
393
393
  /* Reserve room so the time isn't overlapped by the caret */