@artooi/ag-ui-web-component 0.20.0 → 0.21.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 (41) hide show
  1. package/CHANGELOG.md +135 -1
  2. package/README.md +286 -20
  3. package/dist/ag-ui-web-component.bundle.js +407 -382
  4. package/dist/ag-ui-web-component.bundle.js.map +4 -4
  5. package/dist/core/ag_ui_chat.d.ts +82 -1
  6. package/dist/core/ag_ui_chat.d.ts.map +1 -1
  7. package/dist/core/create_http_agent.d.ts +9 -0
  8. package/dist/core/create_http_agent.d.ts.map +1 -1
  9. package/dist/core/remote_conversation_store.d.ts +8 -1
  10. package/dist/core/remote_conversation_store.d.ts.map +1 -1
  11. package/dist/core/run_index.d.ts +8 -1
  12. package/dist/core/run_index.d.ts.map +1 -1
  13. package/dist/core/transcribe_audio.d.ts +7 -0
  14. package/dist/core/transcribe_audio.d.ts.map +1 -1
  15. package/dist/core/upload_attachment.d.ts +9 -0
  16. package/dist/core/upload_attachment.d.ts.map +1 -1
  17. package/dist/core/utils.d.ts +12 -0
  18. package/dist/core/utils.d.ts.map +1 -0
  19. package/dist/dom/animations.d.ts +51 -11
  20. package/dist/dom/animations.d.ts.map +1 -1
  21. package/dist/dom/dom_driver.d.ts +12 -7
  22. package/dist/dom/dom_driver.d.ts.map +1 -1
  23. package/dist/index.d.ts +1 -1
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +766 -430
  26. package/dist/index.js.map +3 -3
  27. package/dist/ui/styles.d.ts +1 -1
  28. package/dist/ui/styles.d.ts.map +1 -1
  29. package/package.json +1 -1
  30. package/src/core/ag_ui_chat.ts +292 -31
  31. package/src/core/create_http_agent.ts +14 -3
  32. package/src/core/remote_conversation_store.ts +25 -6
  33. package/src/core/run_index.ts +27 -5
  34. package/src/core/transcribe_audio.ts +20 -5
  35. package/src/core/upload_attachment.ts +13 -0
  36. package/src/core/utils.ts +18 -0
  37. package/src/dom/animations.ts +175 -31
  38. package/src/dom/dom_driver.ts +18 -12
  39. package/src/index.ts +2 -0
  40. package/src/ui/styles.ts +377 -352
  41. package/src/version.ts +1 -1
package/src/ui/styles.ts CHANGED
@@ -3,151 +3,186 @@
3
3
  // CSS pipeline. Scoped by the shadow boundary, so class names stay terse.
4
4
 
5
5
  export const STYLES = `
6
+ /* ── Token defaults ─────────────────────────────────────────────────────────
7
+ Every public --ag-ui-* token is read here into a private --_* alias, and
8
+ only the alias is used by the rules below.
9
+
10
+ The indirection is what makes ancestor theming work. Declaring the public
11
+ name on :host would set it *on the host element*, and a value on an element
12
+ always beats one inherited from an ancestor — so a page that put the tokens
13
+ on a wrapper would see no effect at all, which is the one thing the API is
14
+ documented to support. Reading the public name with the default as a var()
15
+ fallback leaves it undeclared on the element, so an ancestor's value is
16
+ inherited normally while a value aimed at the element still wins over it.
17
+
18
+ Two invariants hold this together:
19
+ 1. No rule outside this file's :host blocks may reference a public name
20
+ directly. A public name read outside these blocks resolves to nothing and
21
+ silently drops its declaration rather than erroring, so the miss shows up
22
+ as a missing colour, not a failure.
23
+ 2. Every --_* alias in use is declared here. Aliases inherit like any custom
24
+ property, so an undeclared one would pick up a same-named property from
25
+ the host page; declaring it on :host shields the shadow tree from that. */
6
26
  :host {
7
27
  /* Colors */
8
- --ag-ui-bg: #ffffff;
9
- --ag-ui-fg: #1a1a2e;
10
- --ag-ui-accent: #4f46e5;
11
- --ag-ui-user-bg: #4f46e5;
12
- --ag-ui-user-fg: #ffffff;
13
- --ag-ui-assistant-bg: #f1f1f6;
14
- --ag-ui-hover: #e7e7ee;
15
- --ag-ui-input-bg: var(--ag-ui-bg);
16
- --ag-ui-tool-bg: var(--ag-ui-assistant-bg);
17
- --ag-ui-tool-fg: var(--ag-ui-accent);
18
- --ag-ui-header-bg: var(--ag-ui-accent);
19
- --ag-ui-header-fg: #ffffff;
20
- --ag-ui-border: #e2e2ec;
21
- --ag-ui-radius: 12px;
28
+ --_bg: var(--ag-ui-bg, #ffffff);
29
+ --_fg: var(--ag-ui-fg, #1a1a2e);
30
+ --_accent: var(--ag-ui-accent, #4f46e5);
31
+ --_user-bg: var(--ag-ui-user-bg, #4f46e5);
32
+ --_user-fg: var(--ag-ui-user-fg, #ffffff);
33
+ --_assistant-bg: var(--ag-ui-assistant-bg, #f1f1f6);
34
+ --_hover: var(--ag-ui-hover, #e7e7ee);
35
+ --_input-bg: var(--ag-ui-input-bg, var(--_bg));
36
+ --_tool-bg: var(--ag-ui-tool-bg, var(--_assistant-bg));
37
+ --_tool-fg: var(--ag-ui-tool-fg, var(--_accent));
38
+ --_header-bg: var(--ag-ui-header-bg, var(--_accent));
39
+ --_header-fg: var(--ag-ui-header-fg, #ffffff);
40
+ --_border: var(--ag-ui-border, #e2e2ec);
41
+ --_radius: var(--ag-ui-radius, 12px);
42
+
43
+ /* Body text and raised chrome. Both are referenced by the code-block copy
44
+ button; neither had a default before, so the declarations reading them
45
+ were dropped and the button fell back to the inherited colour over a
46
+ transparent box. The defaults below restate exactly that, so this is a
47
+ rename with no repaint — see the note on .code-copy. */
48
+ --_text: var(--ag-ui-text, var(--_fg));
49
+ --_surface: var(--ag-ui-surface, transparent);
22
50
 
23
51
  /* Status accents for tool-call cards. */
24
- --ag-ui-success: #15803d;
25
- --ag-ui-danger: #b91c1c;
26
- --ag-ui-muted: #6b7280;
52
+ --_success: var(--ag-ui-success, #15803d);
53
+ --_danger: var(--ag-ui-danger, #b91c1c);
54
+ --_muted: var(--ag-ui-muted, #6b7280);
27
55
 
28
56
  /* Tool-call status icon glyphs (override to re-theme) + spinner speed.
29
57
  The pending state is the animated ring; the settled states use these. */
30
- --ag-ui-tool-icon-done: "✓";
31
- --ag-ui-tool-icon-error: "✕";
32
- --ag-ui-tool-icon-declined: "⊘";
33
- --ag-ui-tool-spin-duration: 0.7s;
58
+ --_tool-icon-done: var(--ag-ui-tool-icon-done, "✓");
59
+ --_tool-icon-error: var(--ag-ui-tool-icon-error, "✕");
60
+ --_tool-icon-declined: var(--ag-ui-tool-icon-declined, "⊘");
61
+ --_tool-spin-duration: var(--ag-ui-tool-spin-duration, 0.7s);
34
62
 
35
63
  /* Answer well (opt-in via data-answer-well) — boxes a whole assistant turn. */
36
- --ag-ui-well-bg: transparent;
37
- --ag-ui-well-border: var(--ag-ui-border);
64
+ --_well-bg: var(--ag-ui-well-bg, transparent);
65
+ --_well-border: var(--ag-ui-well-border, var(--_border));
38
66
 
39
67
  /* Surface — set --ag-ui-shadow: none for a flush, embedded panel. */
40
- --ag-ui-shadow: 0 12px 32px rgba(20, 20, 50, 0.18);
41
- --ag-ui-font: inherit;
42
- --ag-ui-font-size: 14px;
43
- --ag-ui-code-font: ui-monospace, "SF Mono", Menlo, monospace;
68
+ --_shadow: var(--ag-ui-shadow, 0 12px 32px rgba(20, 20, 50, 0.18));
69
+ --_font: var(--ag-ui-font, inherit);
70
+ --_font-size: var(--ag-ui-font-size, 14px);
71
+ --_code-font: var(--ag-ui-code-font, ui-monospace, "SF Mono", Menlo, monospace);
72
+
73
+ /* Header / launcher icon box. */
74
+ --_icon-size: var(--ag-ui-icon-size, 22px);
75
+ --_icon-radius: var(--ag-ui-icon-radius, 4px);
44
76
 
45
77
  /* Spacing — the density preset overrides these. */
46
- --ag-ui-space: 10px;
47
- --ag-ui-pad: 16px;
48
- --ag-ui-msg-pad: 8px 12px;
49
- --ag-ui-msg-radius: 14px;
78
+ --_space: var(--ag-ui-space, 10px);
79
+ --_pad: var(--ag-ui-pad, 16px);
80
+ --_msg-pad: var(--ag-ui-msg-pad, 8px 12px);
81
+ --_msg-radius: var(--ag-ui-msg-radius, 14px);
50
82
 
51
83
  /* Layout — override from outside to dock the widget anywhere.
52
84
  Set --ag-ui-position: static (and place this element in your own
53
85
  grid/flex layout) to embed it in the page flow instead of floating. */
54
- --ag-ui-position: fixed;
55
- --ag-ui-z-index: 2147483000;
56
- --ag-ui-width: 380px;
57
- --ag-ui-height: 560px;
58
- --ag-ui-inset: auto 24px 24px auto;
59
- --ag-ui-max-width: calc(100vw - 48px);
60
- --ag-ui-max-height: calc(100vh - 48px);
86
+ --_position: var(--ag-ui-position, fixed);
87
+ --_z-index: var(--ag-ui-z-index, 2147483000);
88
+ --_width: var(--ag-ui-width, 380px);
89
+ --_height: var(--ag-ui-height, 560px);
90
+ --_inset: var(--ag-ui-inset, auto 24px 24px auto);
91
+ --_max-width: var(--ag-ui-max-width, calc(100vw - 48px));
92
+ --_max-height: var(--ag-ui-max-height, calc(100vh - 48px));
61
93
  /* Reading-column width for placement="page" (full-bleed, centred content). */
62
- --ag-ui-content-max-width: 820px;
63
-
64
- position: var(--ag-ui-position);
65
- inset: var(--ag-ui-inset);
66
- z-index: var(--ag-ui-z-index);
67
- width: var(--ag-ui-width);
68
- max-width: var(--ag-ui-max-width);
69
- height: var(--ag-ui-height);
70
- max-height: var(--ag-ui-max-height);
94
+ --_content-max-width: var(--ag-ui-content-max-width, 820px);
95
+ /* Slim rail the sidebar placement collapses to. Only that placement reads
96
+ it, but it is declared here so invariant 2 holds for every alias. */
97
+ --_rail-width: var(--ag-ui-rail-width, 52px);
98
+
99
+ position: var(--_position);
100
+ inset: var(--_inset);
101
+ z-index: var(--_z-index);
102
+ width: var(--_width);
103
+ max-width: var(--_max-width);
104
+ height: var(--_height);
105
+ max-height: var(--_max-height);
71
106
  display: flex;
72
- font-family: var(--ag-ui-font);
73
- font-size: var(--ag-ui-font-size);
74
- color: var(--ag-ui-fg);
107
+ font-family: var(--_font);
108
+ font-size: var(--_font-size);
109
+ color: var(--_fg);
75
110
  }
76
111
 
77
112
  /* ── Themes ─────────────────────────────────────────────────────────────
78
113
  Themes only re-set the colour variables; layout/spacing are unaffected.
79
114
  theme="auto" follows the OS via prefers-color-scheme. */
80
115
  :host([theme="dark"]) {
81
- --ag-ui-bg: #15151f;
82
- --ag-ui-fg: #e8e8f2;
83
- --ag-ui-assistant-bg: #25253a;
84
- --ag-ui-hover: #303049;
85
- --ag-ui-header-bg: #1f1f30;
86
- --ag-ui-header-fg: #e8e8f2;
87
- --ag-ui-border: #33334a;
88
- --ag-ui-muted: #9aa0b4;
89
- --ag-ui-shadow: 0 12px 32px rgba(0, 0, 0, 0.5);
116
+ --_bg: var(--ag-ui-bg, #15151f);
117
+ --_fg: var(--ag-ui-fg, #e8e8f2);
118
+ --_assistant-bg: var(--ag-ui-assistant-bg, #25253a);
119
+ --_hover: var(--ag-ui-hover, #303049);
120
+ --_header-bg: var(--ag-ui-header-bg, #1f1f30);
121
+ --_header-fg: var(--ag-ui-header-fg, #e8e8f2);
122
+ --_border: var(--ag-ui-border, #33334a);
123
+ --_muted: var(--ag-ui-muted, #9aa0b4);
124
+ --_shadow: var(--ag-ui-shadow, 0 12px 32px rgba(0, 0, 0, 0.5));
90
125
  }
91
126
 
92
127
  @media (prefers-color-scheme: dark) {
93
128
  :host([theme="auto"]) {
94
- --ag-ui-bg: #15151f;
95
- --ag-ui-fg: #e8e8f2;
96
- --ag-ui-assistant-bg: #25253a;
97
- --ag-ui-hover: #303049;
98
- --ag-ui-header-bg: #1f1f30;
99
- --ag-ui-header-fg: #e8e8f2;
100
- --ag-ui-border: #33334a;
101
- --ag-ui-muted: #9aa0b4;
102
- --ag-ui-shadow: 0 12px 32px rgba(0, 0, 0, 0.5);
129
+ --_bg: var(--ag-ui-bg, #15151f);
130
+ --_fg: var(--ag-ui-fg, #e8e8f2);
131
+ --_assistant-bg: var(--ag-ui-assistant-bg, #25253a);
132
+ --_hover: var(--ag-ui-hover, #303049);
133
+ --_header-bg: var(--ag-ui-header-bg, #1f1f30);
134
+ --_header-fg: var(--ag-ui-header-fg, #e8e8f2);
135
+ --_border: var(--ag-ui-border, #33334a);
136
+ --_muted: var(--ag-ui-muted, #9aa0b4);
137
+ --_shadow: var(--ag-ui-shadow, 0 12px 32px rgba(0, 0, 0, 0.5));
103
138
  }
104
139
  }
105
140
 
106
141
  /* A terminal-flavoured "code" theme: dark, monospace, green accent. */
107
142
  :host([theme="code"]) {
108
- --ag-ui-bg: #0d1117;
109
- --ag-ui-fg: #c9d1d9;
110
- --ag-ui-accent: #3fb950;
111
- --ag-ui-user-bg: #238636;
112
- --ag-ui-assistant-bg: #161b22;
113
- --ag-ui-hover: #21262d;
114
- --ag-ui-header-bg: #010409;
115
- --ag-ui-header-fg: #c9d1d9;
116
- --ag-ui-border: #30363d;
117
- --ag-ui-muted: #8b949e;
118
- --ag-ui-font: var(--ag-ui-code-font);
119
- --ag-ui-shadow: 0 12px 32px rgba(0, 0, 0, 0.6);
143
+ --_bg: var(--ag-ui-bg, #0d1117);
144
+ --_fg: var(--ag-ui-fg, #c9d1d9);
145
+ --_accent: var(--ag-ui-accent, #3fb950);
146
+ --_user-bg: var(--ag-ui-user-bg, #238636);
147
+ --_assistant-bg: var(--ag-ui-assistant-bg, #161b22);
148
+ --_hover: var(--ag-ui-hover, #21262d);
149
+ --_header-bg: var(--ag-ui-header-bg, #010409);
150
+ --_header-fg: var(--ag-ui-header-fg, #c9d1d9);
151
+ --_border: var(--ag-ui-border, #30363d);
152
+ --_muted: var(--ag-ui-muted, #8b949e);
153
+ --_font: var(--ag-ui-font, var(--_code-font));
154
+ --_shadow: var(--ag-ui-shadow, 0 12px 32px rgba(0, 0, 0, 0.6));
120
155
  }
121
156
 
122
157
  /* ── Density ────────────────────────────────────────────────────────────── */
123
158
  :host([density="compact"]) {
124
- --ag-ui-font-size: 13px;
125
- --ag-ui-space: 6px;
126
- --ag-ui-pad: 10px;
127
- --ag-ui-msg-pad: 5px 9px;
128
- --ag-ui-msg-radius: 10px;
159
+ --_font-size: var(--ag-ui-font-size, 13px);
160
+ --_space: var(--ag-ui-space, 6px);
161
+ --_pad: var(--ag-ui-pad, 10px);
162
+ --_msg-pad: var(--ag-ui-msg-pad, 5px 9px);
163
+ --_msg-radius: var(--ag-ui-msg-radius, 10px);
129
164
  }
130
165
 
131
166
  /* ── Placement presets ──────────────────────────────────────────────────── */
132
167
  :host([placement="bottom-left"]) {
133
- --ag-ui-inset: auto auto 24px 24px;
168
+ --_inset: var(--ag-ui-inset, auto auto 24px 24px);
134
169
  }
135
170
 
136
171
  :host([placement="side"]) {
137
- --ag-ui-inset: 0 0 0 auto;
138
- --ag-ui-width: 420px;
139
- --ag-ui-height: 100vh;
140
- --ag-ui-max-height: 100vh;
141
- --ag-ui-radius: 0;
172
+ --_inset: var(--ag-ui-inset, 0 0 0 auto);
173
+ --_width: var(--ag-ui-width, 420px);
174
+ --_height: var(--ag-ui-height, 100vh);
175
+ --_max-height: var(--ag-ui-max-height, 100vh);
176
+ --_radius: var(--ag-ui-radius, 0);
142
177
  }
143
178
 
144
179
  :host([placement="full"]) {
145
- --ag-ui-inset: 0;
146
- --ag-ui-width: 100vw;
147
- --ag-ui-height: 100vh;
148
- --ag-ui-max-width: 100vw;
149
- --ag-ui-max-height: 100vh;
150
- --ag-ui-radius: 0;
180
+ --_inset: var(--ag-ui-inset, 0);
181
+ --_width: var(--ag-ui-width, 100vw);
182
+ --_height: var(--ag-ui-height, 100vh);
183
+ --_max-width: var(--ag-ui-max-width, 100vw);
184
+ --_max-height: var(--ag-ui-max-height, 100vh);
185
+ --_radius: var(--ag-ui-radius, 0);
151
186
  }
152
187
 
153
188
  /* Page: full-bleed background with a centred reading column. Unlike
@@ -156,85 +191,20 @@ export const STYLES = `
156
191
  padding on the scroll area + composer (no per-row wrapper), so user pills
157
192
  still right-align and the assistant well spans the column. */
158
193
  :host([placement="page"]) {
159
- --ag-ui-inset: 0;
160
- --ag-ui-width: 100vw;
161
- --ag-ui-height: 100vh;
162
- --ag-ui-max-width: 100vw;
163
- --ag-ui-max-height: 100vh;
164
- --ag-ui-radius: 0;
194
+ --_inset: var(--ag-ui-inset, 0);
195
+ --_width: var(--ag-ui-width, 100vw);
196
+ --_height: var(--ag-ui-height, 100vh);
197
+ --_max-width: var(--ag-ui-max-width, 100vw);
198
+ --_max-height: var(--ag-ui-max-height, 100vh);
199
+ --_radius: var(--ag-ui-radius, 0);
165
200
  }
166
201
 
167
202
  :host([placement="page"]) .messages {
168
- padding-inline: max(var(--ag-ui-pad), calc((100% - var(--ag-ui-content-max-width)) / 2));
169
- }
170
-
171
- :host([placement="page"]) /* Resize handle: a corner grip on a floating panel, an edge grip on a docked
172
- one. Absent entirely where the placement is full-bleed, since there is
173
- nothing to drag. */
174
- .resize-handle {
175
- position: absolute;
176
- z-index: 2;
177
- background: transparent;
178
- touch-action: none;
179
- }
180
-
181
- .resize-handle:focus-visible {
182
- outline: 2px solid var(--ag-ui-accent);
183
- outline-offset: -2px;
203
+ padding-inline: max(var(--_pad), calc((100% - var(--_content-max-width)) / 2));
184
204
  }
185
205
 
186
- /* The grip sits at the corner the panel grows toward. Which corner that is
187
- depends on the host's layout, not on placement, so the element measures it
188
- and stamps data-resize-anchor with the edges that stay put.
189
-
190
- Default (bottom-right pinned, the floating case) puts the grip top-left. */
191
- .resize-handle {
192
- top: 0;
193
- left: 0;
194
- width: 14px;
195
- height: 14px;
196
- cursor: nwse-resize;
197
- }
198
-
199
- :host([data-resize-anchor~="left"]) .resize-handle {
200
- left: auto;
201
- right: 0;
202
- }
203
-
204
- :host([data-resize-anchor~="top"]) .resize-handle {
205
- top: auto;
206
- bottom: 0;
207
- }
208
-
209
- /* One axis flipped means the drag runs along the other diagonal. */
210
- :host([data-resize-anchor="top-right"]) .resize-handle,
211
- :host([data-resize-anchor="bottom-left"]) .resize-handle {
212
- cursor: nesw-resize;
213
- }
214
-
215
- /* Docked: the placement owns the height, so only the inner edge is the user's. */
216
- :host([placement="sidebar"]) .resize-handle,
217
- :host([placement="side"]) .resize-handle {
218
- top: 0;
219
- bottom: auto;
220
- width: 8px;
221
- height: 100%;
222
- cursor: ew-resize;
223
- }
224
-
225
- /* Full-bleed: nothing to drag. */
226
- :host([placement="full"]) .resize-handle,
227
- :host([placement="page"]) .resize-handle {
228
- display: none;
229
- }
230
-
231
- .resize-handle[data-dragging] {
232
- background: var(--ag-ui-accent);
233
- opacity: 0.35;
234
- }
235
-
236
- .input-row {
237
- padding-inline: max(12px, calc((100% - var(--ag-ui-content-max-width)) / 2));
206
+ :host([placement="page"]) .input-row {
207
+ padding-inline: max(12px, calc((100% - var(--_content-max-width)) / 2));
238
208
  }
239
209
 
240
210
  /* The rows between the message list and the composer (skill chips, the
@@ -243,12 +213,12 @@ export const STYLES = `
243
213
  margin-based, so each gets its own inline axis nudged by the same gutter. */
244
214
  :host([placement="page"]) .skill-chips,
245
215
  :host([placement="page"]) .attachment-tray {
246
- padding-inline: max(12px, calc((100% - var(--ag-ui-content-max-width)) / 2));
216
+ padding-inline: max(12px, calc((100% - var(--_content-max-width)) / 2));
247
217
  }
248
218
 
249
219
  :host([placement="page"]) .skill-palette,
250
220
  :host([placement="page"]) .skill-hint {
251
- margin-inline: max(12px, calc((100% - var(--ag-ui-content-max-width)) / 2));
221
+ margin-inline: max(12px, calc((100% - var(--_content-max-width)) / 2));
252
222
  }
253
223
 
254
224
  /* In the reading column the assistant well uses the full width; the user
@@ -263,17 +233,16 @@ export const STYLES = `
263
233
  --ag-ui-position: static (and place this element in your own layout) for a
264
234
  host-managed push instead. */
265
235
  :host([placement="sidebar"]) {
266
- --ag-ui-inset: 0 0 0 auto;
267
- --ag-ui-width: 420px;
268
- --ag-ui-height: 100vh;
269
- --ag-ui-max-height: 100vh;
270
- --ag-ui-radius: 0;
271
- --ag-ui-rail-width: 52px;
236
+ --_inset: var(--ag-ui-inset, 0 0 0 auto);
237
+ --_width: var(--ag-ui-width, 420px);
238
+ --_height: var(--ag-ui-height, 100vh);
239
+ --_max-height: var(--ag-ui-max-height, 100vh);
240
+ --_radius: var(--ag-ui-radius, 0);
272
241
  transition: width 0.28s ease;
273
242
  }
274
243
 
275
244
  :host([placement="sidebar"][data-side="left"]) {
276
- --ag-ui-inset: 0 auto 0 0;
245
+ --_inset: var(--ag-ui-inset, 0 auto 0 0);
277
246
  }
278
247
 
279
248
  :host([placement="sidebar"]) .chat {
@@ -284,7 +253,7 @@ export const STYLES = `
284
253
  reveal the rail. Higher specificity than the generic collapse rules, so it
285
254
  wins regardless of source order. */
286
255
  :host([placement="sidebar"][collapsed]) {
287
- width: var(--ag-ui-rail-width);
256
+ width: var(--_rail-width);
288
257
  height: 100vh;
289
258
  max-height: 100vh;
290
259
  bottom: 0;
@@ -309,9 +278,9 @@ export const STYLES = `
309
278
  align-items: flex-start;
310
279
  justify-content: center;
311
280
  padding-top: 16px;
312
- border: 1px solid var(--ag-ui-border);
313
- background: var(--ag-ui-header-bg);
314
- color: var(--ag-ui-header-fg);
281
+ border: 1px solid var(--_border);
282
+ background: var(--_header-bg);
283
+ color: var(--_header-fg);
315
284
  cursor: pointer;
316
285
  }
317
286
 
@@ -325,13 +294,13 @@ export const STYLES = `
325
294
  /* Embedded: drop the floating chrome and the high z-index stacking context so
326
295
  the widget lives in the host's own layout (fixes overlay/z-index clashes). */
327
296
  :host([placement="embedded"]) {
328
- --ag-ui-position: static;
329
- --ag-ui-width: 100%;
330
- --ag-ui-height: 100%;
331
- --ag-ui-max-width: 100%;
332
- --ag-ui-max-height: 100%;
333
- --ag-ui-shadow: none;
334
- --ag-ui-z-index: auto;
297
+ --_position: var(--ag-ui-position, static);
298
+ --_width: var(--ag-ui-width, 100%);
299
+ --_height: var(--ag-ui-height, 100%);
300
+ --_max-width: var(--ag-ui-max-width, 100%);
301
+ --_max-height: var(--ag-ui-max-height, 100%);
302
+ --_shadow: var(--ag-ui-shadow, none);
303
+ --_z-index: var(--ag-ui-z-index, auto);
335
304
  }
336
305
 
337
306
  .chat {
@@ -340,10 +309,10 @@ export const STYLES = `
340
309
  flex-direction: column;
341
310
  flex: 1;
342
311
  min-height: 0;
343
- background: var(--ag-ui-bg);
344
- border: 1px solid var(--ag-ui-border);
345
- border-radius: var(--ag-ui-radius);
346
- box-shadow: var(--ag-ui-shadow);
312
+ background: var(--_bg);
313
+ border: 1px solid var(--_border);
314
+ border-radius: var(--_radius);
315
+ box-shadow: var(--_shadow);
347
316
  overflow: hidden;
348
317
  }
349
318
 
@@ -353,9 +322,9 @@ export const STYLES = `
353
322
  justify-content: space-between;
354
323
  gap: 8px;
355
324
  padding: 10px 14px;
356
- border-bottom: 1px solid var(--ag-ui-border);
357
- background: var(--ag-ui-header-bg);
358
- color: var(--ag-ui-header-fg);
325
+ border-bottom: 1px solid var(--_border);
326
+ background: var(--_header-bg);
327
+ color: var(--_header-fg);
359
328
  }
360
329
 
361
330
  .header-title {
@@ -374,8 +343,8 @@ export const STYLES = `
374
343
  align-items: center;
375
344
  justify-content: center;
376
345
  flex: none;
377
- width: var(--ag-ui-icon-size, 22px);
378
- height: var(--ag-ui-icon-size, 22px);
346
+ width: var(--_icon-size);
347
+ height: var(--_icon-size);
379
348
  line-height: 1;
380
349
  }
381
350
 
@@ -383,7 +352,7 @@ export const STYLES = `
383
352
  width: 100%;
384
353
  height: 100%;
385
354
  object-fit: contain;
386
- border-radius: var(--ag-ui-icon-radius, 4px);
355
+ border-radius: var(--_icon-radius);
387
356
  }
388
357
 
389
358
  .header-controls {
@@ -435,10 +404,10 @@ export const STYLES = `
435
404
  .messages {
436
405
  flex: 1;
437
406
  overflow-y: auto;
438
- padding: var(--ag-ui-pad);
407
+ padding: var(--_pad);
439
408
  display: flex;
440
409
  flex-direction: column;
441
- gap: var(--ag-ui-space);
410
+ gap: var(--_space);
442
411
  }
443
412
 
444
413
  /* Empty-state region (slot): centred while it's the only thing in the
@@ -446,7 +415,7 @@ export const STYLES = `
446
415
  .empty {
447
416
  margin: auto;
448
417
  text-align: center;
449
- color: var(--ag-ui-muted);
418
+ color: var(--_muted);
450
419
  }
451
420
 
452
421
  .empty[hidden] {
@@ -462,22 +431,22 @@ export const STYLES = `
462
431
  .answer {
463
432
  display: flex;
464
433
  flex-direction: column;
465
- gap: var(--ag-ui-space);
434
+ gap: var(--_space);
466
435
  align-self: stretch;
467
436
  min-width: 0;
468
437
  }
469
438
 
470
439
  :host([data-answer-well]) .answer {
471
- padding: var(--ag-ui-pad);
472
- background: var(--ag-ui-well-bg);
473
- border: 1px solid var(--ag-ui-well-border);
474
- border-radius: var(--ag-ui-radius);
440
+ padding: var(--_pad);
441
+ background: var(--_well-bg);
442
+ border: 1px solid var(--_well-border);
443
+ border-radius: var(--_radius);
475
444
  }
476
445
 
477
446
  .message {
478
447
  max-width: 80%;
479
- padding: var(--ag-ui-msg-pad);
480
- border-radius: var(--ag-ui-msg-radius);
448
+ padding: var(--_msg-pad);
449
+ border-radius: var(--_msg-radius);
481
450
  line-height: 1.4;
482
451
  white-space: pre-wrap;
483
452
  word-break: break-word;
@@ -515,14 +484,14 @@ export const STYLES = `
515
484
 
516
485
  .message--user {
517
486
  align-self: flex-end;
518
- background: var(--ag-ui-user-bg);
519
- color: var(--ag-ui-user-fg);
487
+ background: var(--_user-bg);
488
+ color: var(--_user-fg);
520
489
  border-bottom-right-radius: 4px;
521
490
  }
522
491
 
523
492
  .message--assistant {
524
493
  align-self: flex-start;
525
- background: var(--ag-ui-assistant-bg);
494
+ background: var(--_assistant-bg);
526
495
  border-bottom-left-radius: 4px;
527
496
  /* Assistant bubbles hold rendered markdown/HTML, so collapse the source
528
497
  whitespace the renderer leaves between block tags. */
@@ -552,7 +521,7 @@ export const STYLES = `
552
521
  }
553
522
 
554
523
  .message--assistant a {
555
- color: var(--ag-ui-accent);
524
+ color: var(--_accent);
556
525
  text-decoration: underline;
557
526
  }
558
527
 
@@ -567,8 +536,8 @@ export const STYLES = `
567
536
  .message--assistant pre {
568
537
  padding: 8px 10px;
569
538
  overflow: auto;
570
- background: var(--ag-ui-bg);
571
- border: 1px solid var(--ag-ui-border);
539
+ background: var(--_bg);
540
+ border: 1px solid var(--_border);
572
541
  border-radius: 6px;
573
542
  }
574
543
 
@@ -584,6 +553,13 @@ export const STYLES = `
584
553
  position: relative;
585
554
  }
586
555
 
556
+ /* This button is the only reader of --ag-ui-surface and --ag-ui-text, and
557
+ neither had a default until the alias layer gave them one. Both references
558
+ used to resolve to nothing, dropping the declaration: the background fell
559
+ back to the initial transparent, and the hover/copied colour to the
560
+ inherited body colour. The defaults chosen upstream (transparent, and the
561
+ body foreground) reproduce that, so the rename repaints nothing. A raised
562
+ surface behind the button is a separate design question. */
587
563
  .code-copy {
588
564
  position: absolute;
589
565
  top: 4px;
@@ -592,9 +568,9 @@ export const STYLES = `
592
568
  font: inherit;
593
569
  font-size: 0.75em;
594
570
  line-height: 1.6;
595
- color: var(--ag-ui-muted);
596
- background: var(--ag-ui-surface);
597
- border: 1px solid var(--ag-ui-border);
571
+ color: var(--_muted);
572
+ background: var(--_surface);
573
+ border: 1px solid var(--_border);
598
574
  border-radius: 4px;
599
575
  cursor: pointer;
600
576
  opacity: 0;
@@ -609,24 +585,24 @@ export const STYLES = `
609
585
  }
610
586
 
611
587
  .code-copy:hover {
612
- color: var(--ag-ui-text);
613
- background: var(--ag-ui-hover);
588
+ color: var(--_text);
589
+ background: var(--_hover);
614
590
  }
615
591
 
616
592
  .code-copy[data-state="copied"] {
617
593
  opacity: 1;
618
- color: var(--ag-ui-text);
594
+ color: var(--_text);
619
595
  }
620
596
 
621
597
  .code-copy[data-state="failed"] {
622
598
  opacity: 1;
623
- color: var(--ag-ui-danger, var(--ag-ui-text));
599
+ color: var(--_danger, var(--_text));
624
600
  }
625
601
 
626
602
  .message--assistant blockquote {
627
603
  padding-left: 10px;
628
- border-left: 3px solid var(--ag-ui-border);
629
- color: var(--ag-ui-muted);
604
+ border-left: 3px solid var(--_border);
605
+ color: var(--_muted);
630
606
  }
631
607
 
632
608
  /* Markdown tables. table/thead/tbody/tr/th/td are all in
@@ -647,13 +623,13 @@ export const STYLES = `
647
623
  .message--assistant th,
648
624
  .message--assistant td {
649
625
  padding: 6px 10px;
650
- border: 1px solid var(--ag-ui-border);
626
+ border: 1px solid var(--_border);
651
627
  text-align: left;
652
628
  vertical-align: top;
653
629
  }
654
630
 
655
631
  .message--assistant th {
656
- background: var(--ag-ui-hover);
632
+ background: var(--_hover);
657
633
  font-weight: 600;
658
634
  }
659
635
 
@@ -663,7 +639,7 @@ export const STYLES = `
663
639
  gap: 4px;
664
640
  align-items: center;
665
641
  padding: 12px 14px;
666
- background: var(--ag-ui-assistant-bg);
642
+ background: var(--_assistant-bg);
667
643
  border-radius: 14px;
668
644
  border-bottom-left-radius: 4px;
669
645
  }
@@ -672,7 +648,7 @@ export const STYLES = `
672
648
  width: 6px;
673
649
  height: 6px;
674
650
  border-radius: 50%;
675
- background: var(--ag-ui-muted);
651
+ background: var(--_muted);
676
652
  animation: ag-ui-pending 1.2s infinite ease-in-out both;
677
653
  }
678
654
 
@@ -705,7 +681,7 @@ export const STYLES = `
705
681
  flex-direction: column;
706
682
  gap: 4px;
707
683
  font-size: 12px;
708
- color: var(--ag-ui-muted);
684
+ color: var(--_muted);
709
685
  }
710
686
 
711
687
  .thoughts-toggle {
@@ -716,7 +692,7 @@ export const STYLES = `
716
692
  font: inherit;
717
693
  font-size: 12px;
718
694
  font-weight: 600;
719
- color: var(--ag-ui-muted);
695
+ color: var(--_muted);
720
696
  cursor: pointer;
721
697
  }
722
698
 
@@ -741,7 +717,7 @@ export const STYLES = `
741
717
  .thoughts-body {
742
718
  margin: 0;
743
719
  padding: 4px 0 4px 10px;
744
- border-left: 2px solid var(--ag-ui-border);
720
+ border-left: 2px solid var(--_border);
745
721
  max-height: 220px;
746
722
  overflow: auto;
747
723
  white-space: pre-wrap;
@@ -770,9 +746,9 @@ export const STYLES = `
770
746
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
771
747
  padding: 8px 10px;
772
748
  border-radius: 8px;
773
- background: var(--ag-ui-tool-bg);
774
- border: 1px solid var(--ag-ui-border);
775
- color: var(--ag-ui-tool-fg);
749
+ background: var(--_tool-bg);
750
+ border: 1px solid var(--_border);
751
+ color: var(--_tool-fg);
776
752
  }
777
753
 
778
754
  .tool-call-head {
@@ -805,10 +781,10 @@ export const STYLES = `
805
781
 
806
782
  /* Pending: a real spinning ring. Speed is tunable; reduced motion stops it. */
807
783
  .tool-call[data-status="pending"] .tool-call-icon {
808
- border: 2px solid var(--ag-ui-muted);
784
+ border: 2px solid var(--_muted);
809
785
  border-top-color: transparent;
810
786
  border-radius: 50%;
811
- animation: ag-ui-tool-spin var(--ag-ui-tool-spin-duration) linear infinite;
787
+ animation: ag-ui-tool-spin var(--_tool-spin-duration) linear infinite;
812
788
  }
813
789
 
814
790
  @keyframes ag-ui-tool-spin {
@@ -817,18 +793,18 @@ export const STYLES = `
817
793
 
818
794
  /* Settled: a themeable glyph coloured by outcome. */
819
795
  .tool-call[data-status="done"] .tool-call-icon::before {
820
- content: var(--ag-ui-tool-icon-done);
821
- color: var(--ag-ui-success);
796
+ content: var(--_tool-icon-done);
797
+ color: var(--_success);
822
798
  }
823
799
 
824
800
  .tool-call[data-status="error"] .tool-call-icon::before {
825
- content: var(--ag-ui-tool-icon-error);
826
- color: var(--ag-ui-danger);
801
+ content: var(--_tool-icon-error);
802
+ color: var(--_danger);
827
803
  }
828
804
 
829
805
  .tool-call[data-status="declined"] .tool-call-icon::before {
830
- content: var(--ag-ui-tool-icon-declined);
831
- color: var(--ag-ui-muted);
806
+ content: var(--_tool-icon-declined);
807
+ color: var(--_muted);
832
808
  }
833
809
 
834
810
  @media (prefers-reduced-motion: reduce) {
@@ -854,19 +830,19 @@ export const STYLES = `
854
830
  font-size: 11px;
855
831
  font-weight: 600;
856
832
  background: rgba(127, 127, 127, 0.16);
857
- color: var(--ag-ui-muted);
833
+ color: var(--_muted);
858
834
  }
859
835
 
860
836
  .tool-call[data-status="done"] .tool-call-status {
861
- color: var(--ag-ui-success);
837
+ color: var(--_success);
862
838
  }
863
839
 
864
840
  .tool-call[data-status="error"] .tool-call-status {
865
- color: var(--ag-ui-danger);
841
+ color: var(--_danger);
866
842
  }
867
843
 
868
844
  .tool-call[data-status="declined"] .tool-call-status {
869
- color: var(--ag-ui-muted);
845
+ color: var(--_muted);
870
846
  }
871
847
 
872
848
  .tool-call-body {
@@ -888,7 +864,7 @@ export const STYLES = `
888
864
  font-weight: 700;
889
865
  letter-spacing: 0.06em;
890
866
  text-transform: uppercase;
891
- color: var(--ag-ui-muted);
867
+ color: var(--_muted);
892
868
  }
893
869
 
894
870
  /* The record of a human decision on a gated call. An approved call used to
@@ -896,7 +872,7 @@ export const STYLES = `
896
872
  .skill-item-token {
897
873
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
898
874
  font-size: 0.92em;
899
- color: var(--ag-ui-accent);
875
+ color: var(--_accent);
900
876
  margin-right: 6px;
901
877
  }
902
878
 
@@ -904,7 +880,7 @@ export const STYLES = `
904
880
  flex: none;
905
881
  font-size: 11px;
906
882
  font-style: italic;
907
- color: var(--ag-ui-muted);
883
+ color: var(--_muted);
908
884
  }
909
885
 
910
886
  .tool-call-args,
@@ -913,12 +889,12 @@ export const STYLES = `
913
889
  padding: 6px 8px;
914
890
  max-height: 160px;
915
891
  overflow: auto;
916
- background: var(--ag-ui-bg);
917
- border: 1px solid var(--ag-ui-border);
892
+ background: var(--_bg);
893
+ border: 1px solid var(--_border);
918
894
  border-radius: 6px;
919
895
  white-space: pre-wrap;
920
896
  word-break: break-word;
921
- color: var(--ag-ui-fg);
897
+ color: var(--_fg);
922
898
  }
923
899
 
924
900
  /* Display modes are pure visibility over one DOM shape, selected from the host
@@ -965,7 +941,7 @@ export const STYLES = `
965
941
  background: none;
966
942
  font: inherit;
967
943
  font-weight: 600;
968
- color: var(--ag-ui-accent);
944
+ color: var(--_accent);
969
945
  cursor: pointer;
970
946
  }
971
947
 
@@ -988,13 +964,12 @@ export const STYLES = `
988
964
  }
989
965
 
990
966
  .resize-handle:focus-visible {
991
- outline: 2px solid var(--ag-ui-accent);
967
+ outline: 2px solid var(--_accent);
992
968
  outline-offset: -2px;
993
969
  }
994
970
 
995
971
  /* The grip sits on the corner opposite the panel's anchor, because a resize
996
- measures from whichever edge is not moving. Selected from the host attribute,
997
- so switching placement moves the grip immediately.
972
+ measures from whichever edge is not moving.
998
973
 
999
974
  Default is floating: pinned bottom-right, so the grip is top-left. */
1000
975
  .resize-handle {
@@ -1005,7 +980,9 @@ export const STYLES = `
1005
980
  cursor: nwse-resize;
1006
981
  }
1007
982
 
1008
- /* Embedded sits in normal flow, pinned top-left, so it grows bottom-right. */
983
+ /* Placement is only the opening guess, and these two rules are all it is good
984
+ for. Embedded sits in normal flow, pinned top-left, so it grows bottom-right;
985
+ bottom-left is pinned there, so its free corner is top-right. */
1009
986
  :host([placement="embedded"]) .resize-handle {
1010
987
  top: auto;
1011
988
  left: auto;
@@ -1014,16 +991,64 @@ export const STYLES = `
1014
991
  cursor: nwse-resize;
1015
992
  }
1016
993
 
1017
- /* Pinned bottom-left, so the free corner is top-right. */
1018
994
  :host([placement="bottom-left"]) .resize-handle {
1019
995
  left: auto;
1020
996
  right: 0;
1021
997
  cursor: nesw-resize;
1022
998
  }
1023
999
 
1024
- /* Docked: the placement owns the height, so only the inner edge is the user's. */
1000
+ /* Then the measurement corrects it. Which edges are held still belongs to the
1001
+ host's layout rather than to placement -- a floating panel a host right-aligns
1002
+ is anchored bottom-left, not bottom-right -- so the element measures the edges
1003
+ that stay put and stamps them here as "<y>-<x>". Equal specificity to the
1004
+ rules above, so source order is what lets the measured value win.
1005
+
1006
+ These must not be written as [data-resize-anchor~="left"]: the stamped value
1007
+ is one hyphenated token, and ~= matches whitespace-separated words, so such a
1008
+ selector cannot ever match. It did not, which left the grip drawn at the
1009
+ corner that moves while the cursor pointed along the right diagonal.
1010
+
1011
+ Each rule also sets both sides of its axis rather than only the side it
1012
+ moves. One that flipped a single way could not undo a placement guess that
1013
+ had flipped the other, which put the grip on the anchored corner for an
1014
+ embedded panel its host right-aligns. */
1015
+ :host([data-resize-anchor$="-left"]) .resize-handle {
1016
+ left: auto;
1017
+ right: 0;
1018
+ }
1019
+
1020
+ :host([data-resize-anchor$="-right"]) .resize-handle {
1021
+ left: 0;
1022
+ right: auto;
1023
+ }
1024
+
1025
+ :host([data-resize-anchor^="top-"]) .resize-handle {
1026
+ top: auto;
1027
+ bottom: 0;
1028
+ }
1029
+
1030
+ :host([data-resize-anchor^="bottom-"]) .resize-handle {
1031
+ top: 0;
1032
+ bottom: auto;
1033
+ }
1034
+
1035
+ /* One axis flipped means the drag runs along the other diagonal. */
1036
+ :host([data-resize-anchor="top-left"]) .resize-handle,
1037
+ :host([data-resize-anchor="bottom-right"]) .resize-handle {
1038
+ cursor: nwse-resize;
1039
+ }
1040
+
1041
+ :host([data-resize-anchor="top-right"]) .resize-handle,
1042
+ :host([data-resize-anchor="bottom-left"]) .resize-handle {
1043
+ cursor: nesw-resize;
1044
+ }
1045
+
1046
+ /* Docked: the placement owns the height, so only the inner edge is the user's --
1047
+ an edge, not a corner, so this outranks the measured anchor by coming after. */
1025
1048
  :host([placement="sidebar"]) .resize-handle,
1026
1049
  :host([placement="side"]) .resize-handle {
1050
+ top: 0;
1051
+ bottom: auto;
1027
1052
  width: 8px;
1028
1053
  height: 100%;
1029
1054
  cursor: ew-resize;
@@ -1042,7 +1067,7 @@ export const STYLES = `
1042
1067
  }
1043
1068
 
1044
1069
  .resize-handle[data-dragging] {
1045
- background: var(--ag-ui-accent);
1070
+ background: var(--_accent);
1046
1071
  opacity: 0.35;
1047
1072
  }
1048
1073
 
@@ -1050,14 +1075,14 @@ export const STYLES = `
1050
1075
  display: flex;
1051
1076
  gap: 8px;
1052
1077
  padding: 12px;
1053
- border-top: 1px solid var(--ag-ui-border);
1078
+ border-top: 1px solid var(--_border);
1054
1079
  }
1055
1080
 
1056
1081
  .input {
1057
1082
  flex: 1;
1058
1083
  resize: none;
1059
- background: var(--ag-ui-input-bg);
1060
- border: 1px solid var(--ag-ui-border);
1084
+ background: var(--_input-bg);
1085
+ border: 1px solid var(--_border);
1061
1086
  border-radius: 8px;
1062
1087
  padding: 8px 10px;
1063
1088
  font: inherit;
@@ -1066,14 +1091,14 @@ export const STYLES = `
1066
1091
  }
1067
1092
 
1068
1093
  .input:focus {
1069
- border-color: var(--ag-ui-accent);
1094
+ border-color: var(--_accent);
1070
1095
  }
1071
1096
 
1072
1097
  .send {
1073
1098
  border: none;
1074
1099
  border-radius: 8px;
1075
1100
  padding: 0 16px;
1076
- background: var(--ag-ui-accent);
1101
+ background: var(--_accent);
1077
1102
  color: #ffffff;
1078
1103
  font: inherit;
1079
1104
  font-weight: 600;
@@ -1087,23 +1112,23 @@ export const STYLES = `
1087
1112
 
1088
1113
  /* The composer button doubles as the Stop control while a run is in flight. */
1089
1114
  .send[data-state="running"] {
1090
- background: var(--ag-ui-muted);
1115
+ background: var(--_muted);
1091
1116
  }
1092
1117
 
1093
1118
  /* ── File attachments ───────────────────────────────────────────────────── */
1094
1119
  /* The 📎 picker button sits left of the input; hidden until data-attachments-url. */
1095
1120
  .attach-btn {
1096
- border: 1px solid var(--ag-ui-border);
1121
+ border: 1px solid var(--_border);
1097
1122
  border-radius: 8px;
1098
1123
  padding: 0 10px;
1099
- background: var(--ag-ui-input-bg);
1124
+ background: var(--_input-bg);
1100
1125
  color: inherit;
1101
1126
  font: inherit;
1102
1127
  cursor: pointer;
1103
1128
  }
1104
1129
 
1105
1130
  .attach-btn:hover {
1106
- border-color: var(--ag-ui-accent);
1131
+ border-color: var(--_accent);
1107
1132
  }
1108
1133
 
1109
1134
  .attach-input {
@@ -1116,17 +1141,17 @@ export const STYLES = `
1116
1141
  }
1117
1142
 
1118
1143
  .voice-btn {
1119
- border: 1px solid var(--ag-ui-border);
1144
+ border: 1px solid var(--_border);
1120
1145
  border-radius: 8px;
1121
1146
  padding: 0 10px;
1122
- background: var(--ag-ui-input-bg);
1147
+ background: var(--_input-bg);
1123
1148
  color: inherit;
1124
1149
  font: inherit;
1125
1150
  cursor: pointer;
1126
1151
  }
1127
1152
 
1128
1153
  .voice-btn:hover {
1129
- border-color: var(--ag-ui-accent);
1154
+ border-color: var(--_accent);
1130
1155
  }
1131
1156
 
1132
1157
  .voice-btn:disabled {
@@ -1136,8 +1161,8 @@ export const STYLES = `
1136
1161
 
1137
1162
  /* Recording: a red tint + a gentle pulse so it's clearly "live". */
1138
1163
  .voice-btn[data-state="recording"] {
1139
- border-color: var(--ag-ui-danger);
1140
- background: var(--ag-ui-danger);
1164
+ border-color: var(--_danger);
1165
+ background: var(--_danger);
1141
1166
  color: #ffffff;
1142
1167
  animation: ag-ui-voice-pulse 1.2s ease-in-out infinite;
1143
1168
  }
@@ -1180,10 +1205,10 @@ export const STYLES = `
1180
1205
  max-width: 100%;
1181
1206
  margin: 2px 0;
1182
1207
  padding: 3px 10px;
1183
- border: 1px dashed var(--ag-ui-border);
1208
+ border: 1px dashed var(--_border);
1184
1209
  border-radius: 999px;
1185
1210
  background: transparent;
1186
- color: var(--ag-ui-muted);
1211
+ color: var(--_muted);
1187
1212
  font-size: 0.8em;
1188
1213
  line-height: 1.4;
1189
1214
  }
@@ -1204,16 +1229,16 @@ export const STYLES = `
1204
1229
  gap: 6px;
1205
1230
  max-width: 100%;
1206
1231
  padding: 4px 8px;
1207
- border: 1px solid var(--ag-ui-border);
1232
+ border: 1px solid var(--_border);
1208
1233
  border-radius: 999px;
1209
- background: var(--ag-ui-assistant-bg);
1234
+ background: var(--_assistant-bg);
1210
1235
  font-size: 0.85em;
1211
1236
  position: relative;
1212
1237
  }
1213
1238
 
1214
1239
  .attachment-chip--error {
1215
- border-color: var(--ag-ui-danger);
1216
- color: var(--ag-ui-danger);
1240
+ border-color: var(--_danger);
1241
+ color: var(--_danger);
1217
1242
  }
1218
1243
 
1219
1244
  .attachment-chip-name {
@@ -1224,12 +1249,12 @@ export const STYLES = `
1224
1249
  }
1225
1250
 
1226
1251
  .attachment-chip-size {
1227
- color: var(--ag-ui-muted);
1252
+ color: var(--_muted);
1228
1253
  white-space: nowrap;
1229
1254
  }
1230
1255
 
1231
1256
  .attachment-chip--error .attachment-chip-size {
1232
- color: var(--ag-ui-danger);
1257
+ color: var(--_danger);
1233
1258
  }
1234
1259
 
1235
1260
  /* The progress bar fills as the file uploads. */
@@ -1237,13 +1262,13 @@ export const STYLES = `
1237
1262
  flex-basis: 100%;
1238
1263
  height: 3px;
1239
1264
  border-radius: 2px;
1240
- background: var(--ag-ui-border);
1265
+ background: var(--_border);
1241
1266
  overflow: hidden;
1242
1267
  }
1243
1268
 
1244
1269
  .attachment-chip-bar-fill {
1245
1270
  height: 100%;
1246
- background: var(--ag-ui-accent);
1271
+ background: var(--_accent);
1247
1272
  transition: width 0.15s ease;
1248
1273
  }
1249
1274
 
@@ -1265,14 +1290,14 @@ export const STYLES = `
1265
1290
 
1266
1291
  /* A subtle outline while a file is dragged over the shell. */
1267
1292
  .chat--dragover {
1268
- outline: 2px dashed var(--ag-ui-accent);
1293
+ outline: 2px dashed var(--_accent);
1269
1294
  outline-offset: -4px;
1270
1295
  }
1271
1296
 
1272
1297
  /* Muted "⏹ Stopped" line after a cancelled run — a note, not an error bubble. */
1273
1298
  .stopped-note {
1274
1299
  align-self: flex-start;
1275
- color: var(--ag-ui-muted);
1300
+ color: var(--_muted);
1276
1301
  font-size: 12px;
1277
1302
  padding: 2px 4px;
1278
1303
  }
@@ -1285,14 +1310,14 @@ export const STYLES = `
1285
1310
  flex-direction: column;
1286
1311
  gap: 8px;
1287
1312
  padding: 12px;
1288
- background: var(--ag-ui-bg);
1289
- border: 1px solid var(--ag-ui-accent);
1313
+ background: var(--_bg);
1314
+ border: 1px solid var(--_accent);
1290
1315
  border-radius: 10px;
1291
1316
  }
1292
1317
 
1293
1318
  .confirm[data-resolved] {
1294
1319
  opacity: 0.7;
1295
- border-color: var(--ag-ui-border);
1320
+ border-color: var(--_border);
1296
1321
  }
1297
1322
 
1298
1323
  .confirm-body {
@@ -1306,7 +1331,7 @@ export const STYLES = `
1306
1331
  overflow: auto;
1307
1332
  font-size: 12px;
1308
1333
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
1309
- background: var(--ag-ui-assistant-bg);
1334
+ background: var(--_assistant-bg);
1310
1335
  border-radius: 8px;
1311
1336
  white-space: pre-wrap;
1312
1337
  word-break: break-word;
@@ -1319,14 +1344,14 @@ export const STYLES = `
1319
1344
  }
1320
1345
 
1321
1346
  .confirm-btn {
1322
- border: 1px solid var(--ag-ui-border);
1347
+ border: 1px solid var(--_border);
1323
1348
  border-radius: 8px;
1324
1349
  padding: 8px 14px;
1325
1350
  font: inherit;
1326
1351
  font-weight: 600;
1327
1352
  cursor: pointer;
1328
- background: var(--ag-ui-bg);
1329
- color: var(--ag-ui-fg);
1353
+ background: var(--_bg);
1354
+ color: var(--_fg);
1330
1355
  }
1331
1356
 
1332
1357
  .confirm-btn:disabled {
@@ -1335,8 +1360,8 @@ export const STYLES = `
1335
1360
  }
1336
1361
 
1337
1362
  .confirm-btn--confirm {
1338
- border-color: var(--ag-ui-accent);
1339
- background: var(--ag-ui-accent);
1363
+ border-color: var(--_accent);
1364
+ background: var(--_accent);
1340
1365
  color: #ffffff;
1341
1366
  }
1342
1367
 
@@ -1348,14 +1373,14 @@ export const STYLES = `
1348
1373
  flex-direction: column;
1349
1374
  gap: 8px;
1350
1375
  padding: 12px;
1351
- background: var(--ag-ui-bg);
1352
- border: 1px solid var(--ag-ui-accent);
1376
+ background: var(--_bg);
1377
+ border: 1px solid var(--_accent);
1353
1378
  border-radius: 10px;
1354
1379
  }
1355
1380
 
1356
1381
  .approval[data-resolved] {
1357
1382
  opacity: 0.7;
1358
- border-color: var(--ag-ui-border);
1383
+ border-color: var(--_border);
1359
1384
  }
1360
1385
 
1361
1386
  .approval-body {
@@ -1369,14 +1394,14 @@ export const STYLES = `
1369
1394
  }
1370
1395
 
1371
1396
  .approval-btn {
1372
- border: 1px solid var(--ag-ui-border);
1397
+ border: 1px solid var(--_border);
1373
1398
  border-radius: 8px;
1374
1399
  padding: 8px 14px;
1375
1400
  font: inherit;
1376
1401
  font-weight: 600;
1377
1402
  cursor: pointer;
1378
- background: var(--ag-ui-bg);
1379
- color: var(--ag-ui-fg);
1403
+ background: var(--_bg);
1404
+ color: var(--_fg);
1380
1405
  }
1381
1406
 
1382
1407
  .approval-btn:disabled {
@@ -1385,8 +1410,8 @@ export const STYLES = `
1385
1410
  }
1386
1411
 
1387
1412
  .approval-btn--approve {
1388
- border-color: var(--ag-ui-accent);
1389
- background: var(--ag-ui-accent);
1413
+ border-color: var(--_accent);
1414
+ background: var(--_accent);
1390
1415
  color: #ffffff;
1391
1416
  }
1392
1417
 
@@ -1398,14 +1423,14 @@ export const STYLES = `
1398
1423
  flex-direction: column;
1399
1424
  gap: 8px;
1400
1425
  padding: 12px;
1401
- background: var(--ag-ui-bg);
1402
- border: 1px solid var(--ag-ui-accent);
1426
+ background: var(--_bg);
1427
+ border: 1px solid var(--_accent);
1403
1428
  border-radius: 10px;
1404
1429
  }
1405
1430
 
1406
1431
  .question[data-resolved] {
1407
1432
  opacity: 0.7;
1408
- border-color: var(--ag-ui-border);
1433
+ border-color: var(--_border);
1409
1434
  }
1410
1435
 
1411
1436
  .question-body {
@@ -1430,9 +1455,9 @@ export const STYLES = `
1430
1455
  width: 100%;
1431
1456
  padding: 8px 10px;
1432
1457
  font: inherit;
1433
- color: var(--ag-ui-fg);
1434
- background: var(--ag-ui-bg);
1435
- border: 1px solid var(--ag-ui-border);
1458
+ color: var(--_fg);
1459
+ background: var(--_bg);
1460
+ border: 1px solid var(--_border);
1436
1461
  border-radius: 8px;
1437
1462
  }
1438
1463
 
@@ -1446,13 +1471,13 @@ export const STYLES = `
1446
1471
  }
1447
1472
 
1448
1473
  .question-btn {
1449
- border: 1px solid var(--ag-ui-accent);
1474
+ border: 1px solid var(--_accent);
1450
1475
  border-radius: 8px;
1451
1476
  padding: 8px 14px;
1452
1477
  font: inherit;
1453
1478
  font-weight: 600;
1454
1479
  cursor: pointer;
1455
- background: var(--ag-ui-accent);
1480
+ background: var(--_accent);
1456
1481
  color: #ffffff;
1457
1482
  }
1458
1483
 
@@ -1470,18 +1495,18 @@ export const STYLES = `
1470
1495
  }
1471
1496
 
1472
1497
  .skill-chip {
1473
- border: 1px solid var(--ag-ui-border);
1498
+ border: 1px solid var(--_border);
1474
1499
  border-radius: 999px;
1475
1500
  padding: 4px 12px;
1476
1501
  font: inherit;
1477
1502
  font-size: 0.9em;
1478
1503
  cursor: pointer;
1479
- background: var(--ag-ui-assistant-bg);
1480
- color: var(--ag-ui-fg);
1504
+ background: var(--_assistant-bg);
1505
+ color: var(--_fg);
1481
1506
  }
1482
1507
 
1483
1508
  .skill-chip:hover {
1484
- border-color: var(--ag-ui-accent);
1509
+ border-color: var(--_accent);
1485
1510
  }
1486
1511
 
1487
1512
  .skill-palette {
@@ -1490,8 +1515,8 @@ export const STYLES = `
1490
1515
  flex-direction: column;
1491
1516
  max-height: 220px;
1492
1517
  overflow: auto;
1493
- background: var(--ag-ui-bg);
1494
- border: 1px solid var(--ag-ui-border);
1518
+ background: var(--_bg);
1519
+ border: 1px solid var(--_border);
1495
1520
  border-radius: 8px;
1496
1521
  box-shadow: 0 8px 24px rgba(20, 20, 50, 0.16);
1497
1522
  }
@@ -1507,11 +1532,11 @@ export const STYLES = `
1507
1532
  font: inherit;
1508
1533
  text-align: left;
1509
1534
  cursor: pointer;
1510
- color: var(--ag-ui-fg);
1535
+ color: var(--_fg);
1511
1536
  }
1512
1537
 
1513
1538
  .skill-item[aria-selected="true"] {
1514
- background: var(--ag-ui-assistant-bg);
1539
+ background: var(--_assistant-bg);
1515
1540
  }
1516
1541
 
1517
1542
  .skill-item-title {
@@ -1520,7 +1545,7 @@ export const STYLES = `
1520
1545
 
1521
1546
  .skill-item-desc {
1522
1547
  font-size: 0.85em;
1523
- color: var(--ag-ui-muted);
1548
+ color: var(--_muted);
1524
1549
  }
1525
1550
 
1526
1551
  /* The hint sits directly above the composer's top border, so a zero bottom
@@ -1529,7 +1554,7 @@ export const STYLES = `
1529
1554
  margin: 8px 12px;
1530
1555
  font-size: 0.85em;
1531
1556
  line-height: 1.4;
1532
- color: var(--ag-ui-danger);
1557
+ color: var(--_danger);
1533
1558
  }
1534
1559
 
1535
1560
  /* Chat-history drawer — a slide-over within the chat panel. */
@@ -1553,9 +1578,9 @@ export const STYLES = `
1553
1578
  flex-direction: column;
1554
1579
  gap: 0.25rem;
1555
1580
  padding: 0.5rem;
1556
- border: 1px solid var(--ag-ui-border);
1581
+ border: 1px solid var(--_border);
1557
1582
  border-radius: 0.5rem;
1558
- background: var(--ag-ui-assistant-bg);
1583
+ background: var(--_assistant-bg);
1559
1584
  box-shadow: 0 6px 24px rgb(0 0 0 / 12%);
1560
1585
  max-height: 60%;
1561
1586
  overflow-y: auto;
@@ -1586,7 +1611,7 @@ export const STYLES = `
1586
1611
  }
1587
1612
 
1588
1613
  .checkpoint-row:hover {
1589
- background: var(--ag-ui-hover);
1614
+ background: var(--_hover);
1590
1615
  }
1591
1616
 
1592
1617
  .checkpoint-label {
@@ -1601,7 +1626,7 @@ export const STYLES = `
1601
1626
  font-size: 0.6875rem;
1602
1627
  padding: 0 0.375rem;
1603
1628
  border-radius: 999px;
1604
- background: var(--ag-ui-hover);
1629
+ background: var(--_hover);
1605
1630
  opacity: 0.8;
1606
1631
  }
1607
1632
 
@@ -1610,14 +1635,14 @@ export const STYLES = `
1610
1635
  font-size: 0.75rem;
1611
1636
  cursor: pointer;
1612
1637
  padding: 0.125rem 0.5rem;
1613
- border: 1px solid var(--ag-ui-border);
1638
+ border: 1px solid var(--_border);
1614
1639
  border-radius: 0.375rem;
1615
1640
  background: transparent;
1616
1641
  color: inherit;
1617
1642
  }
1618
1643
 
1619
1644
  .checkpoint-action:hover {
1620
- background: var(--ag-ui-hover);
1645
+ background: var(--_hover);
1621
1646
  }
1622
1647
 
1623
1648
  .drawer-backdrop {
@@ -1632,9 +1657,9 @@ export const STYLES = `
1632
1657
  flex-direction: column;
1633
1658
  width: min(300px, 85%);
1634
1659
  height: 100%;
1635
- background: var(--ag-ui-bg);
1636
- border-right: 1px solid var(--ag-ui-border);
1637
- box-shadow: var(--ag-ui-shadow);
1660
+ background: var(--_bg);
1661
+ border-right: 1px solid var(--_border);
1662
+ box-shadow: var(--_shadow);
1638
1663
  overflow: hidden;
1639
1664
  }
1640
1665
 
@@ -1642,9 +1667,9 @@ export const STYLES = `
1642
1667
  display: flex;
1643
1668
  align-items: center;
1644
1669
  justify-content: space-between;
1645
- gap: var(--ag-ui-space);
1646
- padding: var(--ag-ui-pad);
1647
- border-bottom: 1px solid var(--ag-ui-border);
1670
+ gap: var(--_space);
1671
+ padding: var(--_pad);
1672
+ border-bottom: 1px solid var(--_border);
1648
1673
  }
1649
1674
 
1650
1675
  .drawer-title {
@@ -1652,10 +1677,10 @@ export const STYLES = `
1652
1677
  }
1653
1678
 
1654
1679
  .drawer-new {
1655
- border: 1px solid var(--ag-ui-border);
1656
- border-radius: var(--ag-ui-radius);
1657
- background: var(--ag-ui-bg);
1658
- color: var(--ag-ui-accent);
1680
+ border: 1px solid var(--_border);
1681
+ border-radius: var(--_radius);
1682
+ background: var(--_bg);
1683
+ color: var(--_accent);
1659
1684
  padding: 4px 10px;
1660
1685
  font: inherit;
1661
1686
  font-size: 0.85em;
@@ -1669,19 +1694,19 @@ export const STYLES = `
1669
1694
  }
1670
1695
 
1671
1696
  .drawer-empty {
1672
- padding: var(--ag-ui-pad);
1697
+ padding: var(--_pad);
1673
1698
  font-size: 0.9em;
1674
- color: var(--ag-ui-muted);
1699
+ color: var(--_muted);
1675
1700
  }
1676
1701
 
1677
1702
  .drawer-row {
1678
1703
  display: flex;
1679
1704
  align-items: stretch;
1680
- border-bottom: 1px solid var(--ag-ui-border);
1705
+ border-bottom: 1px solid var(--_border);
1681
1706
  }
1682
1707
 
1683
1708
  .drawer-row--active {
1684
- background: var(--ag-ui-assistant-bg);
1709
+ background: var(--_assistant-bg);
1685
1710
  }
1686
1711
 
1687
1712
  .drawer-row-select {
@@ -1708,12 +1733,12 @@ export const STYLES = `
1708
1733
 
1709
1734
  .drawer-row-time {
1710
1735
  font-size: 0.72em;
1711
- color: var(--ag-ui-muted);
1736
+ color: var(--_muted);
1712
1737
  }
1713
1738
 
1714
1739
  .drawer-row-preview {
1715
1740
  font-size: 0.8em;
1716
- color: var(--ag-ui-muted);
1741
+ color: var(--_muted);
1717
1742
  overflow: hidden;
1718
1743
  white-space: nowrap;
1719
1744
  text-overflow: ellipsis;
@@ -1730,7 +1755,7 @@ export const STYLES = `
1730
1755
  .drawer-row-delete {
1731
1756
  border: none;
1732
1757
  background: none;
1733
- color: var(--ag-ui-muted);
1758
+ color: var(--_muted);
1734
1759
  font-size: 0.9em;
1735
1760
  padding: 4px;
1736
1761
  cursor: pointer;
@@ -1741,10 +1766,10 @@ export const STYLES = `
1741
1766
  min-width: 0;
1742
1767
  margin: 6px 10px;
1743
1768
  padding: 4px 8px;
1744
- border: 1px solid var(--ag-ui-accent);
1769
+ border: 1px solid var(--_accent);
1745
1770
  border-radius: 6px;
1746
- background: var(--ag-ui-input-bg);
1747
- color: var(--ag-ui-fg);
1771
+ background: var(--_input-bg);
1772
+ color: var(--_fg);
1748
1773
  font: inherit;
1749
1774
  }
1750
1775
 
@@ -1757,13 +1782,13 @@ export const STYLES = `
1757
1782
  }
1758
1783
 
1759
1784
  .drawer-confirm-label {
1760
- color: var(--ag-ui-danger);
1785
+ color: var(--_danger);
1761
1786
  }
1762
1787
 
1763
1788
  .drawer-confirm-yes {
1764
1789
  border: none;
1765
1790
  border-radius: 6px;
1766
- background: var(--ag-ui-danger);
1791
+ background: var(--_danger);
1767
1792
  color: #ffffff;
1768
1793
  padding: 3px 10px;
1769
1794
  font: inherit;
@@ -1771,7 +1796,7 @@ export const STYLES = `
1771
1796
  }
1772
1797
 
1773
1798
  .drawer-confirm-no {
1774
- border: 1px solid var(--ag-ui-border);
1799
+ border: 1px solid var(--_border);
1775
1800
  border-radius: 6px;
1776
1801
  background: none;
1777
1802
  color: inherit;