@adia-ai/web-components 0.0.18 → 0.0.20

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 (90) hide show
  1. package/components/accordion/accordion.css +101 -102
  2. package/components/agent-feedback-bar/agent-feedback-bar.js +8 -8
  3. package/components/agent-questions/agent-questions.css +2 -1
  4. package/components/agent-questions/agent-questions.js +6 -6
  5. package/components/agent-reasoning/agent-reasoning.js +20 -5
  6. package/components/agent-trace/agent-trace.a2ui.json +5 -5
  7. package/components/agent-trace/agent-trace.js +7 -5
  8. package/components/agent-trace/agent-trace.yaml +2 -2
  9. package/components/alert/alert.a2ui.json +1 -2
  10. package/components/alert/alert.css +4 -4
  11. package/components/alert/alert.yaml +1 -2
  12. package/components/avatar/avatar.a2ui.json +3 -3
  13. package/components/avatar/avatar.js +10 -0
  14. package/components/avatar/avatar.yaml +6 -6
  15. package/components/button/button.a2ui.json +14 -2
  16. package/components/button/button.css +19 -2
  17. package/components/button/button.js +1 -0
  18. package/components/button/button.yaml +20 -2
  19. package/components/calendar-picker/calendar-picker.css +2 -1
  20. package/components/calendar-picker/calendar-picker.js +12 -1
  21. package/components/chart/chart.css +11 -11
  22. package/components/chart/chart.js +26 -18
  23. package/components/chart-legend/chart-legend.a2ui.json +2 -2
  24. package/components/chart-legend/chart-legend.js +4 -1
  25. package/components/chart-legend/chart-legend.yaml +2 -2
  26. package/components/chat/chat-input.js +13 -5
  27. package/components/chat/chat.a2ui.json +2 -2
  28. package/components/chat/chat.js +14 -3
  29. package/components/chat/chat.yaml +2 -2
  30. package/components/code/code.css +16 -6
  31. package/components/command/command.js +9 -1
  32. package/components/field/field.a2ui.json +0 -5
  33. package/components/field/field.css +2 -2
  34. package/components/field/field.js +53 -5
  35. package/components/field/field.yaml +5 -8
  36. package/components/heatmap/heatmap.css +32 -23
  37. package/components/input/input.js +30 -1
  38. package/components/kbd/kbd.a2ui.json +5 -1
  39. package/components/kbd/kbd.yaml +5 -1
  40. package/components/menu/menu.css +20 -8
  41. package/components/menu/menu.js +9 -1
  42. package/components/modal/modal.css +101 -108
  43. package/components/noodles/noodles.js +25 -8
  44. package/components/pipeline-status/pipeline-status.css +4 -4
  45. package/components/pipeline-status/pipeline-status.js +6 -4
  46. package/components/popover/popover.js +4 -0
  47. package/components/progress-row/progress-row.a2ui.json +3 -2
  48. package/components/progress-row/progress-row.yaml +2 -1
  49. package/components/range/range.js +7 -0
  50. package/components/richtext/richtext.css +2 -2
  51. package/components/richtext/richtext.js +4 -1
  52. package/components/segment/segment.css +1 -1
  53. package/components/segmented/segmented.js +7 -1
  54. package/components/select/select.css +7 -4
  55. package/components/slider/slider.js +15 -8
  56. package/components/stepper/stepper.css +181 -144
  57. package/components/stepper/stepper.js +5 -2
  58. package/components/swiper/swiper.a2ui.json +3 -3
  59. package/components/swiper/swiper.css +11 -77
  60. package/components/swiper/swiper.js +6 -5
  61. package/components/swiper/swiper.yaml +3 -3
  62. package/components/switch/switch.a2ui.json +8 -1
  63. package/components/switch/switch.yaml +8 -1
  64. package/components/table/table.js +9 -1
  65. package/components/table-toolbar/table-toolbar.a2ui.json +21 -21
  66. package/components/table-toolbar/table-toolbar.css +32 -91
  67. package/components/table-toolbar/table-toolbar.js +219 -86
  68. package/components/table-toolbar/table-toolbar.yaml +21 -12
  69. package/components/tabs/tabs.css +3 -2
  70. package/components/tabs/tabs.js +7 -1
  71. package/components/tag/tag.a2ui.json +2 -2
  72. package/components/tag/tag.yaml +2 -2
  73. package/components/timeline/timeline.css +244 -204
  74. package/components/timeline/timeline.js +1 -3
  75. package/components/toast/toast.a2ui.json +2 -3
  76. package/components/toast/toast.yaml +5 -3
  77. package/components/toolbar/toolbar.css +6 -1
  78. package/components/toolbar/toolbar.js +10 -2
  79. package/components/tooltip/tooltip.css +8 -2
  80. package/components/tooltip/tooltip.js +12 -14
  81. package/components/tree/tree.css +21 -0
  82. package/core/icons.js +14 -0
  83. package/core/polyfills.js +17 -7
  84. package/package.json +1 -1
  85. package/patterns/a2ui-root/a2ui-root.js +21 -14
  86. package/patterns/app-shell/css/app-shell.main.css +30 -1
  87. package/patterns/app-shell/css/app-shell.tokens.css +1 -0
  88. package/patterns/gen-ui/gen-ui.js +1 -1
  89. package/styles/colors/semantics.css +59 -2
  90. package/styles/tokens.css +16 -12
@@ -44,13 +44,13 @@
44
44
  --timeline-icon-bg: var(--a-bg-muted);
45
45
  --timeline-icon-fg: var(--a-fg-subtle);
46
46
  --timeline-icon-bg-success: var(--a-success-muted);
47
- --timeline-icon-fg-success: var(--a-success);
47
+ --timeline-icon-fg-success: var(--a-success-strong);
48
48
  --timeline-icon-bg-accent: var(--a-accent-muted);
49
49
  --timeline-icon-fg-accent: var(--a-accent);
50
50
  --timeline-icon-bg-warning: var(--a-warning-muted);
51
51
  --timeline-icon-fg-warning: var(--a-warning);
52
52
  --timeline-icon-bg-danger: var(--a-danger-muted);
53
- --timeline-icon-fg-danger: var(--a-danger);
53
+ --timeline-icon-fg-danger: var(--a-danger-strong);
54
54
 
55
55
  /* Typography */
56
56
  --timeline-label-weight: var(--a-weight-medium);
@@ -110,232 +110,272 @@ agent-reasoning-ui timeline-ui:not([orientation="horizontal"]),
110
110
  grid-column: 1 / -1;
111
111
  }
112
112
 
113
- /* ── Item base: each item is its own subgrid row ── */
114
-
115
- timeline-item-ui {
116
- box-sizing: border-box;
117
- display: grid;
118
- grid-template-columns: subgrid;
119
- grid-column: 1 / -1;
120
- grid-auto-rows: auto;
121
- align-items: baseline;
122
- position: relative;
123
- min-width: 0;
124
- }
125
-
126
- /* Stamp default slot children when the author didn't — see timeline.js */
127
- timeline-item-ui [slot] {
128
- min-width: 0;
129
- }
113
+ /* ── Item co-located in timeline.js, declared here as its own scope ── */
114
+ @scope (timeline-item-ui) {
115
+ :where(:scope) {
116
+ /* Item-local aliases of parent timeline-ui tokens. Co-located items
117
+ legitimately read parent tokens so the dot/line/icon visuals stay
118
+ coherent across the timeline (sanctioned composition pattern). */
119
+ --timeline-item-marker-w: var(--timeline-marker-w, 1.25rem);
120
+ --timeline-item-gap-row: var(--timeline-gap-row, var(--a-space-3));
121
+
122
+ --timeline-item-dot-size: var(--timeline-dot-size, 0.625rem);
123
+ --timeline-item-dot-bg: var(--timeline-dot-bg, var(--a-border));
124
+ --timeline-item-dot-bg-active: var(--timeline-dot-bg-active, var(--a-accent-bg));
125
+ --timeline-item-dot-bg-done: var(--timeline-dot-bg-done, var(--a-success-bg));
126
+ --timeline-item-dot-bg-error: var(--timeline-dot-bg-error, var(--a-danger-bg));
127
+ --timeline-item-dot-bg-warning: var(--timeline-dot-bg-warning, var(--a-warning-bg));
128
+
129
+ --timeline-item-subdot-size: var(--timeline-subdot-size, 4px);
130
+ --timeline-item-subdot-bg: var(--timeline-subdot-bg, var(--a-fg-subtle));
131
+
132
+ --timeline-item-line-size: var(--timeline-line-size, 2px);
133
+ --timeline-item-line-fg: var(--timeline-line-fg, var(--a-border-subtle));
134
+ --timeline-item-line-fg-done: var(--timeline-line-fg-done, var(--a-border));
135
+
136
+ --timeline-item-icon-size: var(--timeline-icon-size, 1rem);
137
+ --timeline-item-icon-bg: var(--timeline-icon-bg, var(--a-bg-muted));
138
+ --timeline-item-icon-fg: var(--timeline-icon-fg, var(--a-fg-subtle));
139
+ --timeline-item-icon-bg-success: var(--timeline-icon-bg-success, var(--a-success-muted));
140
+ --timeline-item-icon-fg-success: var(--timeline-icon-fg-success, var(--a-success-strong));
141
+ --timeline-item-icon-bg-accent: var(--timeline-icon-bg-accent, var(--a-accent-muted));
142
+ --timeline-item-icon-fg-accent: var(--timeline-icon-fg-accent, var(--a-accent));
143
+ --timeline-item-icon-bg-warning: var(--timeline-icon-bg-warning, var(--a-warning-muted));
144
+ --timeline-item-icon-fg-warning: var(--timeline-icon-fg-warning, var(--a-warning));
145
+ --timeline-item-icon-bg-danger: var(--timeline-icon-bg-danger, var(--a-danger-muted));
146
+ --timeline-item-icon-fg-danger: var(--timeline-icon-fg-danger, var(--a-danger-strong));
147
+
148
+ --timeline-item-label-weight: var(--timeline-label-weight, var(--a-weight-medium));
149
+ --timeline-item-label-size: var(--timeline-label-size, var(--a-ui-size));
150
+ --timeline-item-label-fg: var(--timeline-label-fg, var(--a-fg));
151
+ --timeline-item-label-fg-muted: var(--timeline-label-fg-muted, var(--a-fg-muted));
152
+ --timeline-item-desc-fg: var(--timeline-desc-fg, var(--a-fg-subtle));
153
+ --timeline-item-desc-size: var(--timeline-desc-size, var(--a-ui-sm));
154
+ --timeline-item-time-fg: var(--timeline-time-fg, var(--a-fg-muted));
155
+ --timeline-item-time-size: var(--timeline-time-size, var(--a-ui-sm));
156
+ --timeline-item-outcome-fg: var(--timeline-outcome-fg, var(--a-fg-muted));
157
+
158
+ --timeline-item-duration: var(--timeline-duration, var(--a-duration-fast));
159
+ --timeline-item-easing: var(--timeline-easing, var(--a-easing-out));
160
+ --timeline-item-spin-duration: var(--timeline-spin-duration, 0.8s);
161
+
162
+ --timeline-item-toggle-px: var(--a-space-0-5);
163
+ --timeline-item-toggle-time-margin: 1.5rem;
164
+ --timeline-item-outcome-indent: 0.75rem;
165
+ }
130
166
 
131
- /* ═══════ Marker (dot) — positioned absolutely in the marker column ═══════ */
132
-
133
- timeline-item-ui::before {
134
- content: '';
135
- position: absolute;
136
- left: calc((var(--timeline-marker-w) - var(--timeline-dot-size)) / 2);
137
- top: calc((1.4em - var(--timeline-dot-size)) / 2 + 1px);
138
- width: var(--timeline-dot-size);
139
- height: var(--timeline-dot-size);
140
- border-radius: 50%;
141
- background: var(--timeline-dot-bg);
142
- box-sizing: border-box;
143
- z-index: 1;
144
- transition: background var(--timeline-duration) var(--timeline-easing);
145
- }
167
+ :scope {
168
+ box-sizing: border-box;
169
+ display: grid;
170
+ grid-template-columns: subgrid;
171
+ grid-column: 1 / -1;
172
+ grid-auto-rows: auto;
173
+ align-items: baseline;
174
+ position: relative;
175
+ min-width: 0;
176
+ }
146
177
 
147
- /* State: completed success dot */
148
- timeline-item-ui[completed]::before {
149
- background: var(--timeline-dot-bg-done);
150
- }
178
+ /* Stamp default slot children when the author didn't — see timeline.js */
179
+ :scope [slot] {
180
+ min-width: 0;
181
+ }
151
182
 
152
- /* State: active accent dot */
153
- timeline-item-ui[active]::before {
154
- background: var(--timeline-dot-bg-active);
155
- }
183
+ /* ═══════ Marker (dot) positioned absolutely in the marker column ═══════ */
184
+
185
+ :scope::before {
186
+ content: '';
187
+ position: absolute;
188
+ left: calc((var(--timeline-item-marker-w) - var(--timeline-item-dot-size)) / 2);
189
+ top: calc((1.4em - var(--timeline-item-dot-size)) / 2 + 1px);
190
+ width: var(--timeline-item-dot-size);
191
+ height: var(--timeline-item-dot-size);
192
+ border-radius: 50%;
193
+ background: var(--timeline-item-dot-bg);
194
+ box-sizing: border-box;
195
+ z-index: 1;
196
+ transition: background var(--timeline-item-duration) var(--timeline-item-easing);
197
+ }
156
198
 
157
- /* State: error danger dot */
158
- timeline-item-ui[error]::before {
159
- background: var(--timeline-dot-bg-error);
160
- }
199
+ :scope[status="completed"]::before { background: var(--timeline-item-dot-bg-done); }
200
+ :scope[status="active"]::before { background: var(--timeline-item-dot-bg-active); }
201
+ :scope[status="error"]::before { background: var(--timeline-item-dot-bg-error); }
202
+
203
+ /* Variant: success / accent / warning / danger (for non-active items) */
204
+ :scope[variant="success"]:not([status="active"]):not([status="error"])::before { background: var(--timeline-item-dot-bg-done); }
205
+ :scope[variant="accent"]:not([status="active"]):not([status="error"])::before { background: var(--timeline-item-dot-bg-active); }
206
+ :scope[variant="warning"]:not([status="active"]):not([status="error"])::before { background: var(--timeline-item-dot-bg-warning); }
207
+ :scope[variant="danger"]:not([status="active"]):not([status="error"])::before { background: var(--timeline-item-dot-bg-error); }
208
+
209
+ /* Spinner overlay — `[spinner]` is a presentation hint that turns the
210
+ active dot into a spinning ring. Orthogonal to status. */
211
+ :scope[status="active"][spinner]::before {
212
+ background: transparent;
213
+ border: 2px solid var(--timeline-item-dot-bg);
214
+ border-top-color: var(--timeline-item-dot-bg-active);
215
+ animation: tl-spin var(--timeline-item-spin-duration) linear infinite;
216
+ }
161
217
 
162
- /* Variant: success / accent / warning / danger (for non-active items) */
163
- timeline-item-ui[variant="success"]:not([active]):not([error])::before { background: var(--timeline-dot-bg-done); }
164
- timeline-item-ui[variant="accent"]:not([active]):not([error])::before { background: var(--timeline-dot-bg-active); }
165
- timeline-item-ui[variant="warning"]:not([active]):not([error])::before { background: var(--timeline-dot-bg-warning); }
166
- timeline-item-ui[variant="danger"]:not([active]):not([error])::before { background: var(--timeline-dot-bg-error); }
167
-
168
- /* Spinner on active items — render as a ring that spins */
169
- timeline-item-ui[active][spinner]::before {
170
- background: transparent;
171
- border: 2px solid var(--timeline-dot-bg);
172
- border-top-color: var(--timeline-dot-bg-active);
173
- animation: tl-spin var(--timeline-spin-duration) linear infinite;
174
- }
218
+ /* ═══════ Connector line ═══════ */
175
219
 
176
- /* When size=sm, ring is 1.5px so the small dot still looks crisp */
177
- timeline-ui[size="sm"] > timeline-item-ui[active][spinner]::before {
178
- border-width: 1.5px;
179
- }
220
+ :scope::after {
221
+ content: '';
222
+ position: absolute;
223
+ left: calc((var(--timeline-item-marker-w) - var(--timeline-item-line-size)) / 2);
224
+ top: calc((1.4em + var(--timeline-item-dot-size)) / 2 + 2px);
225
+ bottom: calc(-1 * var(--timeline-item-gap-row));
226
+ width: var(--timeline-item-line-size);
227
+ background: var(--timeline-item-line-fg);
228
+ }
180
229
 
181
- /* ═══════ Connector line ═══════ */
230
+ :scope[status="completed"]::after { background: var(--timeline-item-line-fg-done); }
231
+ :scope[data-last]::after { display: none; }
232
+
233
+ /* ═══════ Icon mode — icon-ui in [slot="icon"] replaces the dot ═══════ */
234
+
235
+ :scope:has(> [slot="icon"])::before { display: none; }
236
+
237
+ :scope > [slot="icon"] {
238
+ grid-column: marker;
239
+ grid-row: 1;
240
+ justify-self: center;
241
+ align-self: baseline;
242
+ margin-top: calc((1.4em - var(--timeline-item-icon-size)) / 2);
243
+ width: var(--timeline-item-icon-size);
244
+ height: var(--timeline-item-icon-size);
245
+ border-radius: 50%;
246
+ background: var(--timeline-item-icon-bg);
247
+ color: var(--timeline-item-icon-fg);
248
+ display: inline-flex;
249
+ align-items: center;
250
+ justify-content: center;
251
+ --a-icon-size: calc(var(--timeline-item-icon-size) * 0.625);
252
+ z-index: 1;
253
+ box-sizing: border-box;
254
+ }
182
255
 
183
- timeline-item-ui::after {
184
- content: '';
185
- position: absolute;
186
- left: calc((var(--timeline-marker-w) - var(--timeline-line-size)) / 2);
187
- top: calc((1.4em + var(--timeline-dot-size)) / 2 + 2px);
188
- bottom: calc(-1 * var(--timeline-gap-row));
189
- width: var(--timeline-line-size);
190
- background: var(--timeline-line-fg);
191
- }
256
+ :scope[variant="success"] > [slot="icon"] { background: var(--timeline-item-icon-bg-success); color: var(--timeline-item-icon-fg-success); }
257
+ :scope[variant="accent"] > [slot="icon"] { background: var(--timeline-item-icon-bg-accent); color: var(--timeline-item-icon-fg-accent); }
258
+ :scope[variant="warning"] > [slot="icon"] { background: var(--timeline-item-icon-bg-warning); color: var(--timeline-item-icon-fg-warning); }
259
+ :scope[variant="danger"] > [slot="icon"] { background: var(--timeline-item-icon-bg-danger); color: var(--timeline-item-icon-fg-danger); }
192
260
 
193
- timeline-item-ui[completed]::after { background: var(--timeline-line-fg-done); }
194
- timeline-item-ui[data-last]::after { display: none; }
195
-
196
- /* ═══════ Icon mode — icon-ui in [slot="icon"] replaces the dot ═══════ */
197
-
198
- timeline-item-ui:has(> [slot="icon"])::before { display: none; }
199
-
200
- timeline-item-ui > [slot="icon"] {
201
- grid-column: marker;
202
- grid-row: 1;
203
- justify-self: center;
204
- align-self: baseline;
205
- margin-top: calc((1.4em - var(--timeline-icon-size)) / 2);
206
- width: var(--timeline-icon-size);
207
- height: var(--timeline-icon-size);
208
- border-radius: 50%;
209
- background: var(--timeline-icon-bg);
210
- color: var(--timeline-icon-fg);
211
- display: inline-flex;
212
- align-items: center;
213
- justify-content: center;
214
- --a-icon-size: calc(var(--timeline-icon-size) * 0.625);
215
- z-index: 1;
216
- box-sizing: border-box;
217
- }
218
-
219
- /* Variant icons */
220
- timeline-item-ui[variant="success"] > [slot="icon"] { background: var(--timeline-icon-bg-success); color: var(--timeline-icon-fg-success); }
221
- timeline-item-ui[variant="accent"] > [slot="icon"] { background: var(--timeline-icon-bg-accent); color: var(--timeline-icon-fg-accent); }
222
- timeline-item-ui[variant="warning"] > [slot="icon"] { background: var(--timeline-icon-bg-warning); color: var(--timeline-icon-fg-warning); }
223
- timeline-item-ui[variant="danger"] > [slot="icon"] { background: var(--timeline-icon-bg-danger); color: var(--timeline-icon-fg-danger); }
261
+ /* Push connector line past the icon circle */
262
+ :scope:has(> [slot="icon"])::after {
263
+ top: calc((1.4em + var(--timeline-item-icon-size)) / 2 + 2px);
264
+ }
224
265
 
225
- /* Push connector line past the icon circle */
226
- timeline-item-ui:has(> [slot="icon"])::after {
227
- top: calc((1.4em + var(--timeline-icon-size)) / 2 + 2px);
228
- }
266
+ /* ═══════ Content slots ═══════ */
229
267
 
230
- /* ═══════ Content slots ═══════ */
268
+ :scope > [slot="label"] {
269
+ grid-column: content;
270
+ grid-row: 1;
271
+ font-weight: var(--timeline-item-label-weight);
272
+ font-size: var(--timeline-item-label-size);
273
+ color: var(--timeline-item-label-fg);
274
+ line-height: 1.4;
275
+ overflow-wrap: break-word;
276
+ min-width: 0;
277
+ }
231
278
 
232
- timeline-item-ui > [slot="label"] {
233
- grid-column: content;
234
- grid-row: 1;
235
- font-weight: var(--timeline-label-weight);
236
- font-size: var(--timeline-label-size);
237
- color: var(--timeline-label-fg);
238
- line-height: 1.4;
239
- overflow-wrap: break-word;
240
- min-width: 0;
241
- }
279
+ :scope[status="completed"] > [slot="label"] {
280
+ color: var(--timeline-item-label-fg-muted);
281
+ }
242
282
 
243
- timeline-item-ui[completed] > [slot="label"] {
244
- color: var(--timeline-label-fg-muted);
245
- }
283
+ :scope > [slot="description"] {
284
+ grid-column: content / -1;
285
+ grid-row: 2;
286
+ color: var(--timeline-item-desc-fg);
287
+ font-size: var(--timeline-item-desc-size);
288
+ line-height: 1.5;
289
+ margin-top: var(--a-space-0-5);
290
+ }
246
291
 
247
- timeline-item-ui > [slot="description"] {
248
- grid-column: content / -1;
249
- grid-row: 2;
250
- color: var(--timeline-desc-fg);
251
- font-size: var(--timeline-desc-size);
252
- line-height: 1.5;
253
- margin-top: var(--a-space-0-5);
254
- }
292
+ :scope > [slot="time"] {
293
+ grid-column: aside;
294
+ grid-row: 1;
295
+ color: var(--timeline-item-time-fg);
296
+ font-size: var(--timeline-item-time-size);
297
+ font-variant-numeric: tabular-nums;
298
+ line-height: 1.4;
299
+ white-space: nowrap;
300
+ justify-self: end;
301
+ }
255
302
 
256
- timeline-item-ui > [slot="time"] {
257
- grid-column: aside;
258
- grid-row: 1;
259
- color: var(--timeline-time-fg);
260
- font-size: var(--timeline-time-size);
261
- font-variant-numeric: tabular-nums;
262
- line-height: 1.4;
263
- white-space: nowrap;
264
- justify-self: end;
265
- }
303
+ /* Hide empty slots so they don't steal grid track space */
304
+ :scope > [slot]:empty {
305
+ display: none;
306
+ }
266
307
 
267
- /* Hide empty slots so they don't steal grid track space */
268
- timeline-item-ui > [slot]:empty {
269
- display: none;
270
- }
308
+ /* ═══════ Outcomes nested sub-rows ═══════ */
271
309
 
272
- /* ═══════ Outcomes — nested sub-rows ═══════ */
310
+ :scope > [slot="outcomes"] {
311
+ grid-column: content / -1;
312
+ grid-row: 3;
313
+ margin: var(--a-space-1) 0 0 0;
314
+ padding: 0;
315
+ list-style: none;
316
+ display: flex;
317
+ flex-direction: column;
318
+ gap: var(--a-space-0-5);
319
+ color: var(--timeline-item-outcome-fg);
320
+ font-size: var(--timeline-item-desc-size);
321
+ line-height: 1.4;
322
+ animation: tl-fade var(--timeline-item-duration) var(--timeline-item-easing);
323
+ }
273
324
 
274
- timeline-item-ui > [slot="outcomes"] {
275
- grid-column: content / -1;
276
- grid-row: 3;
277
- margin: var(--a-space-1) 0 0 0;
278
- padding: 0;
279
- list-style: none;
280
- display: flex;
281
- flex-direction: column;
282
- gap: var(--a-space-0-5);
283
- color: var(--timeline-outcome-fg);
284
- font-size: var(--timeline-desc-size);
285
- line-height: 1.4;
286
- animation: tl-fade var(--timeline-duration) var(--timeline-easing);
287
- }
325
+ :scope > [slot="outcomes"][hidden] { display: none; }
288
326
 
289
- timeline-item-ui > [slot="outcomes"][hidden] { display: none; }
327
+ :scope > [slot="outcomes"] > li {
328
+ position: relative;
329
+ padding-left: var(--timeline-item-outcome-indent);
330
+ overflow-wrap: break-word;
331
+ min-width: 0;
332
+ }
290
333
 
291
- timeline-item-ui > [slot="outcomes"] > li {
292
- position: relative;
293
- padding-left: 0.75rem;
294
- overflow-wrap: break-word;
295
- min-width: 0;
296
- }
334
+ :scope > [slot="outcomes"] > li::before {
335
+ content: '';
336
+ position: absolute;
337
+ left: calc((var(--timeline-item-outcome-indent) - var(--timeline-item-subdot-size)) / 2);
338
+ top: calc((1.4em - var(--timeline-item-subdot-size)) / 2 + 1px);
339
+ width: var(--timeline-item-subdot-size);
340
+ height: var(--timeline-item-subdot-size);
341
+ border-radius: 50%;
342
+ background: var(--timeline-item-subdot-bg);
343
+ }
297
344
 
298
- timeline-item-ui > [slot="outcomes"] > li::before {
299
- content: '';
300
- position: absolute;
301
- left: calc((0.75rem - var(--timeline-subdot-size)) / 2);
302
- top: calc((1.4em - var(--timeline-subdot-size)) / 2 + 1px);
303
- width: var(--timeline-subdot-size);
304
- height: var(--timeline-subdot-size);
305
- border-radius: 50%;
306
- background: var(--timeline-subdot-bg);
307
- }
345
+ /* ═══════ Toggle chevron (outcomes) ═══════ */
346
+
347
+ :scope > [data-timeline-toggle] {
348
+ position: absolute;
349
+ inset-inline-end: 0;
350
+ top: calc((1.4em - 1em) / 2);
351
+ background: none;
352
+ border: none;
353
+ padding: 0 var(--timeline-item-toggle-px);
354
+ margin: 0;
355
+ cursor: pointer;
356
+ color: inherit;
357
+ display: inline-flex;
358
+ align-items: center;
359
+ justify-content: center;
360
+ line-height: 0;
361
+ }
308
362
 
309
- /* ═══════ Toggle chevron (outcomes) ═══════ */
310
-
311
- /* Positioned absolutely at the item's trailing edge so it coexists with
312
- [slot="time"] (which also lives in the aside column). The item itself
313
- is position: relative. */
314
- timeline-item-ui > [data-timeline-toggle] {
315
- position: absolute;
316
- inset-inline-end: 0;
317
- top: calc((1.4em - 1em) / 2);
318
- background: none;
319
- border: none;
320
- padding: 0 var(--a-space-0-5);
321
- margin: 0;
322
- cursor: pointer;
323
- color: inherit;
324
- display: inline-flex;
325
- align-items: center;
326
- justify-content: center;
327
- line-height: 0;
328
- }
363
+ /* Reserve room so the time isn't overlapped by the chevron */
364
+ :scope:has(> [data-timeline-toggle]) > [slot="time"] {
365
+ margin-inline-end: var(--timeline-item-toggle-time-margin);
366
+ }
329
367
 
330
- /* Reserve room so the time isn't overlapped by the chevron */
331
- timeline-item-ui:has(> [data-timeline-toggle]) > [slot="time"] {
332
- margin-inline-end: 1.5rem;
368
+ :scope > [data-timeline-toggle]:focus-visible {
369
+ outline: none;
370
+ box-shadow: var(--a-focus-ring);
371
+ border-radius: var(--a-radius-sm);
372
+ }
333
373
  }
334
374
 
335
- timeline-item-ui > [data-timeline-toggle]:focus-visible {
336
- outline: 2px solid var(--a-focus-ring, var(--a-accent));
337
- outline-offset: 2px;
338
- border-radius: var(--a-radius-sm);
375
+ /* When size=sm on the parent, ring is 1.5px so the small dot still looks crisp.
376
+ This rule reaches across the parent→child boundary and stays outside @scope. */
377
+ timeline-ui[size="sm"] > timeline-item-ui[status="active"][spinner]::before {
378
+ border-width: 1.5px;
339
379
  }
340
380
 
341
381
  /* ═══════ Horizontal layout — flow, not grid ═══════ */
@@ -385,5 +425,5 @@ timeline-ui[orientation="horizontal"] > timeline-item-ui > [slot="time"] {
385
425
  }
386
426
 
387
427
  @media (prefers-reduced-motion: reduce) {
388
- timeline-item-ui[active][spinner]::before { animation: none; }
428
+ timeline-item-ui[status="active"][spinner]::before { animation: none; }
389
429
  }
@@ -72,9 +72,7 @@ class AdiaTimelineItem extends AdiaElement {
72
72
  duration: { type: String, default: '', reflect: true },
73
73
  icon: { type: String, default: '', reflect: true },
74
74
  variant: { type: String, default: 'default', reflect: true },
75
- completed: { type: Boolean, default: false, reflect: true },
76
- active: { type: Boolean, default: false, reflect: true },
77
- error: { type: Boolean, default: false, reflect: true },
75
+ status: { type: String, default: 'idle', reflect: true },
78
76
  spinner: { type: Boolean, default: false, reflect: true },
79
77
  };
80
78
 
@@ -40,14 +40,13 @@
40
40
  "default": ""
41
41
  },
42
42
  "variant": {
43
- "description": "Color variant. `error` kept as alias for `danger`.",
43
+ "description": "Semantic variant `default | info | success | warning | danger`. `primary` and `muted` are style hints; canonical \"neutral but interesting\" tone is `info`.",
44
44
  "type": "string",
45
45
  "enum": [
46
46
  "default",
47
+ "info",
47
48
  "success",
48
49
  "warning",
49
- "error",
50
- "info",
51
50
  "danger",
52
51
  "primary",
53
52
  "muted",
@@ -28,15 +28,17 @@ props:
28
28
  type: string
29
29
  default: ""
30
30
  variant:
31
- description: Color variant. `error` kept as alias for `danger`.
31
+ description: >-
32
+ Semantic variant — `default | info | success | warning | danger`.
33
+ `primary` and `muted` are style hints; canonical "neutral but
34
+ interesting" tone is `info`.
32
35
  type: string
33
36
  default: info
34
37
  enum:
35
38
  - default
39
+ - info
36
40
  - success
37
41
  - warning
38
- - error
39
- - info
40
42
  - danger
41
43
  - primary
42
44
  - muted
@@ -8,6 +8,7 @@
8
8
 
9
9
  /* ── Colors ── */
10
10
  --toolbar-bg: transparent;
11
+ --toolbar-fg: var(--a-fg);
11
12
  --toolbar-border: var(--a-border-subtle);
12
13
  }
13
14
 
@@ -20,6 +21,7 @@
20
21
  gap: var(--toolbar-gap);
21
22
  padding: var(--toolbar-py) var(--toolbar-px);
22
23
  border-radius: var(--toolbar-radius);
24
+ color: var(--toolbar-fg);
23
25
  min-width: 0; /* allow shrinking within flex/grid parents */
24
26
  overflow: hidden; /* prevent pre-measurement flash before reflow */
25
27
  }
@@ -66,12 +68,15 @@
66
68
 
67
69
  /* ── toolbar-group-ui: atomic inline-flex cluster ── */
68
70
  @scope (toolbar-group-ui) {
71
+ :where(:scope) {
72
+ --toolbar-group-gap: var(--a-space-1);
73
+ }
69
74
  :scope {
70
75
  box-sizing: border-box;
71
76
  display: inline-flex;
72
77
  flex-direction: row;
73
78
  align-items: center;
74
- gap: var(--toolbar-gap, var(--a-space-1));
79
+ gap: var(--toolbar-group-gap);
75
80
  min-width: 0;
76
81
  }
77
82
  }
@@ -36,7 +36,7 @@ class AdiaToolbar extends AdiaElement {
36
36
  static properties = {
37
37
  gap: { type: String, default: 'sm', reflect: true },
38
38
  align: { type: String, default: 'start', reflect: true },
39
- overflow: { type: String, default: 'menu', reflect: true }, // menu | none
39
+ overflow: { type: String, default: 'menu', reflect: true },
40
40
  };
41
41
 
42
42
  static template = () => null;
@@ -48,6 +48,7 @@ class AdiaToolbar extends AdiaElement {
48
48
  #spilloverCleanup = null;
49
49
  #measuring = false;
50
50
  #reflowQueued = false;
51
+ #reflowRaf = null;
51
52
  #rafId = null;
52
53
 
53
54
  connected() {
@@ -64,6 +65,11 @@ class AdiaToolbar extends AdiaElement {
64
65
  }
65
66
 
66
67
  disconnected() {
68
+ if (this.#reflowRaf != null) {
69
+ cancelAnimationFrame(this.#reflowRaf);
70
+ this.#reflowRaf = null;
71
+ }
72
+ this.#reflowQueued = false;
67
73
  this.#ro?.disconnect();
68
74
  this.#mo?.disconnect();
69
75
  this.#closeSpillover();
@@ -188,8 +194,10 @@ class AdiaToolbar extends AdiaElement {
188
194
  #queueReflow() {
189
195
  if (this.#reflowQueued) return;
190
196
  this.#reflowQueued = true;
191
- requestAnimationFrame(() => {
197
+ this.#reflowRaf = requestAnimationFrame(() => {
198
+ this.#reflowRaf = null;
192
199
  this.#reflowQueued = false;
200
+ if (!this.isConnected) return;
193
201
  this.#reflow();
194
202
  });
195
203
  }
@@ -1,8 +1,14 @@
1
1
  @scope (tooltip-ui) {
2
+ :where(:scope) {
3
+ /* Host (anchor) tokens. The popover itself escapes to top-layer and
4
+ cannot inherit these — top-layer rules below reference --a-*
5
+ directly per documented exception. */
6
+ --tooltip-host-display: inline-flex;
7
+ }
2
8
  :scope {
3
9
  /* ── Base ── */
4
10
  box-sizing: border-box;
5
- display: inline-flex;
11
+ display: var(--tooltip-host-display);
6
12
  position: relative;
7
13
  }
8
14
  }
@@ -94,7 +100,7 @@
94
100
  grid-template-columns: auto 1fr auto;
95
101
  align-items: center;
96
102
  gap: var(--a-space-1) var(--a-space-2);
97
- padding: 1px 0;
103
+ padding: var(--a-space-px) 0;
98
104
  }
99
105
 
100
106
  /* Multi-series mode: the row the pointer is actually over gets a