@haikit/client 0.8.0 → 0.9.1
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.
- package/README.md +54 -1
- package/package.json +1 -1
- package/src/app.d.ts +12 -2
- package/src/app.js +298 -34
- package/src/hai.css +498 -127
- package/src/icons.js +90 -0
- package/src/transcript.js +76 -14
package/src/hai.css
CHANGED
|
@@ -6,226 +6,597 @@
|
|
|
6
6
|
*
|
|
7
7
|
* It deliberately does not style the inside of your surfaces. Your components
|
|
8
8
|
* emit their own class names and your own stylesheet owns them — otherwise the
|
|
9
|
-
* framework starts dictating what your UI looks like.
|
|
9
|
+
* framework starts dictating what your UI looks like. They can use the tokens,
|
|
10
|
+
* though: --hai-hover and --hai-selected are there for rows and pickers.
|
|
10
11
|
*
|
|
11
|
-
*
|
|
12
|
+
* Light and dark, following the system. Every colour is a custom property set
|
|
13
|
+
* here at zero specificity, so a plain `:root` rule in your own sheet wins.
|
|
14
|
+
* Give one value per scheme with light-dark(), behind a plain dark value for
|
|
15
|
+
* the browsers that fall back to dark below:
|
|
12
16
|
*
|
|
13
|
-
* :root { --hai-accent: #b07cff;
|
|
17
|
+
* :root { --hai-accent: #b07cff; }
|
|
18
|
+
* @supports (color: light-dark(#000, #fff)) {
|
|
19
|
+
* :root { --hai-accent: light-dark(#6d28d9, #b07cff); }
|
|
20
|
+
* }
|
|
21
|
+
*
|
|
22
|
+
* <html data-hai-theme="dark"> pins the page to one scheme, as does
|
|
23
|
+
* `mountChat({ theme: "dark" })`. The pin is on the root because the tokens
|
|
24
|
+
* are: a minifier that lowers light-dark() resolves them there.
|
|
14
25
|
*/
|
|
15
26
|
|
|
16
|
-
:root {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
--hai-
|
|
20
|
-
--hai-
|
|
21
|
-
--hai-
|
|
22
|
-
--hai-
|
|
23
|
-
--hai-
|
|
24
|
-
--hai-
|
|
25
|
-
--hai-
|
|
26
|
-
--hai-
|
|
27
|
-
--hai-
|
|
28
|
-
--hai-
|
|
29
|
-
--hai-
|
|
27
|
+
:where(:root) {
|
|
28
|
+
color-scheme: light dark;
|
|
29
|
+
|
|
30
|
+
--hai-bg: light-dark(#f6f7f9, #0c0f13);
|
|
31
|
+
--hai-panel: light-dark(#ffffff, #141920);
|
|
32
|
+
--hai-panel-2: light-dark(#f9fafb, #10141a);
|
|
33
|
+
--hai-line: light-dark(#e1e5ea, #252c35);
|
|
34
|
+
--hai-fg: light-dark(#161b22, #e3e8ee);
|
|
35
|
+
--hai-dim: light-dark(#5b6675, #8a95a3);
|
|
36
|
+
--hai-accent: light-dark(#2160e0, #7aa7ff);
|
|
37
|
+
--hai-on-accent: light-dark(#ffffff, #0b1220);
|
|
38
|
+
--hai-good: light-dark(#127a4c, #5ec597);
|
|
39
|
+
--hai-warn: light-dark(#9a5b00, #e7b65c);
|
|
40
|
+
--hai-bad: light-dark(#c23338, #f07b7b);
|
|
41
|
+
--hai-user-bg: light-dark(#e7eefb, #1e2835);
|
|
42
|
+
--hai-code-bg: light-dark(#f3f5f8, #0a0d11);
|
|
43
|
+
--hai-shadow: 0 1px 2px light-dark(rgb(15 23 42 / .06), rgb(0 0 0 / .35));
|
|
44
|
+
--hai-logo-ink: light-dark(#0f1115, #f3f2ee);
|
|
45
|
+
--hai-logo-paper: light-dark(#f3f2ee, #0f1115);
|
|
46
|
+
--hai-logo-hot: #ff5a1f;
|
|
47
|
+
|
|
48
|
+
/* tints, derived — override the colour and these follow */
|
|
49
|
+
--hai-line-soft: color-mix(in srgb, var(--hai-line) 60%, transparent);
|
|
50
|
+
--hai-hover: color-mix(in srgb, var(--hai-fg) 6%, transparent);
|
|
51
|
+
--hai-selected: color-mix(in srgb, var(--hai-good) 15%, transparent);
|
|
52
|
+
--hai-accent-soft: color-mix(in srgb, var(--hai-accent) 14%, transparent);
|
|
53
|
+
--hai-good-soft: color-mix(in srgb, var(--hai-good) 13%, transparent);
|
|
54
|
+
--hai-warn-soft: color-mix(in srgb, var(--hai-warn) 12%, transparent);
|
|
55
|
+
--hai-bad-soft: color-mix(in srgb, var(--hai-bad) 12%, transparent);
|
|
56
|
+
|
|
57
|
+
--hai-radius: 12px;
|
|
58
|
+
--hai-mono: ui-monospace, "SF Mono", "Cascadia Code", Menlo, Consolas, monospace;
|
|
59
|
+
--hai-sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
|
|
60
|
+
--hai-column: 780px;
|
|
30
61
|
--hai-inspector-width: 400px;
|
|
31
62
|
}
|
|
32
63
|
|
|
64
|
+
:where(:root[data-hai-theme="light"]) { color-scheme: light; }
|
|
65
|
+
:where(:root[data-hai-theme="dark"]) { color-scheme: dark; }
|
|
66
|
+
|
|
67
|
+
/* A browser without light-dark() gets the dark scheme, not no colours at all. */
|
|
68
|
+
@supports not (color: light-dark(#000, #fff)) {
|
|
69
|
+
:where(:root) {
|
|
70
|
+
color-scheme: dark;
|
|
71
|
+
--hai-bg: #0c0f13;
|
|
72
|
+
--hai-panel: #141920;
|
|
73
|
+
--hai-panel-2: #10141a;
|
|
74
|
+
--hai-line: #252c35;
|
|
75
|
+
--hai-fg: #e3e8ee;
|
|
76
|
+
--hai-dim: #8a95a3;
|
|
77
|
+
--hai-accent: #7aa7ff;
|
|
78
|
+
--hai-on-accent: #0b1220;
|
|
79
|
+
--hai-good: #5ec597;
|
|
80
|
+
--hai-warn: #e7b65c;
|
|
81
|
+
--hai-bad: #f07b7b;
|
|
82
|
+
--hai-user-bg: #1e2835;
|
|
83
|
+
--hai-code-bg: #0a0d11;
|
|
84
|
+
--hai-shadow: 0 1px 2px rgb(0 0 0 / .35);
|
|
85
|
+
--hai-logo-ink: #f3f2ee;
|
|
86
|
+
--hai-logo-paper: #0f1115;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/* the shell is the page */
|
|
91
|
+
:where(body:has(.hai-shell)) { margin: 0; }
|
|
92
|
+
|
|
33
93
|
/* ── shell ──────────────────────────────────────────────────────────── */
|
|
34
94
|
.hai-shell {
|
|
35
95
|
height: 100vh;
|
|
96
|
+
height: 100dvh;
|
|
36
97
|
display: flex;
|
|
37
98
|
flex-direction: column;
|
|
38
99
|
background: var(--hai-bg);
|
|
39
100
|
color: var(--hai-fg);
|
|
40
|
-
font: 14px/1.
|
|
101
|
+
font: 14px/1.5 var(--hai-sans);
|
|
102
|
+
-webkit-font-smoothing: antialiased;
|
|
41
103
|
}
|
|
104
|
+
|
|
105
|
+
.hai-icon { width: 16px; height: 16px; flex: none; }
|
|
106
|
+
|
|
42
107
|
.hai-top {
|
|
108
|
+
flex: none;
|
|
43
109
|
display: flex;
|
|
44
|
-
align-items:
|
|
110
|
+
align-items: center;
|
|
45
111
|
gap: 12px;
|
|
46
|
-
|
|
112
|
+
height: 52px;
|
|
113
|
+
padding: 0 10px 0 16px;
|
|
47
114
|
border-bottom: 1px solid var(--hai-line);
|
|
48
115
|
background: var(--hai-panel);
|
|
49
116
|
}
|
|
50
|
-
.hai-
|
|
51
|
-
.hai-
|
|
52
|
-
.hai-
|
|
117
|
+
.hai-brand { display: flex; align-items: center; gap: 10px; min-width: 0; }
|
|
118
|
+
.hai-logo { flex: none; }
|
|
119
|
+
.hai-logo-ink { fill: var(--hai-logo-ink); }
|
|
120
|
+
.hai-logo-paper { fill: var(--hai-logo-paper); }
|
|
121
|
+
.hai-logo-paper-dim { fill: var(--hai-logo-paper); opacity: .5; }
|
|
122
|
+
.hai-logo-hot { fill: var(--hai-logo-hot); }
|
|
123
|
+
.hai-mark { width: 20px; height: 20px; }
|
|
124
|
+
.hai-title { font-size: 15px; font-weight: 650; letter-spacing: -.01em; white-space: nowrap; }
|
|
125
|
+
.hai-subtitle {
|
|
126
|
+
color: var(--hai-dim);
|
|
127
|
+
font-size: 13px;
|
|
128
|
+
padding-left: 10px;
|
|
129
|
+
border-left: 1px solid var(--hai-line);
|
|
130
|
+
overflow: hidden;
|
|
131
|
+
text-overflow: ellipsis;
|
|
132
|
+
white-space: nowrap;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
.hai-actions { margin-left: auto; display: flex; align-items: center; gap: 4px; flex: none; }
|
|
136
|
+
.hai-model {
|
|
137
|
+
display: inline-flex;
|
|
138
|
+
align-items: center;
|
|
139
|
+
gap: 6px;
|
|
140
|
+
margin-right: 6px;
|
|
141
|
+
padding: 3px 9px;
|
|
142
|
+
border: 1px solid var(--hai-line);
|
|
143
|
+
border-radius: 999px;
|
|
144
|
+
font: 11.5px var(--hai-mono);
|
|
145
|
+
color: var(--hai-dim);
|
|
146
|
+
}
|
|
147
|
+
.hai-model::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--hai-good); }
|
|
148
|
+
.hai-model[hidden] { display: none; }
|
|
149
|
+
|
|
150
|
+
.hai-btn {
|
|
151
|
+
display: inline-flex;
|
|
152
|
+
align-items: center;
|
|
153
|
+
gap: 7px;
|
|
154
|
+
height: 32px;
|
|
155
|
+
padding: 0 10px;
|
|
156
|
+
border: none;
|
|
157
|
+
border-radius: 8px;
|
|
158
|
+
background: none;
|
|
159
|
+
color: var(--hai-dim);
|
|
160
|
+
font: inherit;
|
|
161
|
+
font-size: 13px;
|
|
162
|
+
font-weight: 500;
|
|
163
|
+
cursor: pointer;
|
|
164
|
+
}
|
|
165
|
+
.hai-btn:hover:not(:disabled) { background: var(--hai-hover); color: var(--hai-fg); }
|
|
166
|
+
.hai-btn:disabled { opacity: .4; cursor: default; }
|
|
167
|
+
.hai-btn[aria-expanded="true"] { color: var(--hai-fg); background: var(--hai-hover); }
|
|
168
|
+
.hai-ctx-count { font: 11.5px var(--hai-mono); color: var(--hai-dim); }
|
|
169
|
+
.hai-ctx-count:empty { display: none; }
|
|
170
|
+
|
|
171
|
+
.hai-icon-btn {
|
|
172
|
+
display: grid;
|
|
173
|
+
place-items: center;
|
|
174
|
+
width: 30px;
|
|
175
|
+
height: 30px;
|
|
176
|
+
border: none;
|
|
177
|
+
border-radius: 8px;
|
|
178
|
+
background: none;
|
|
179
|
+
color: var(--hai-dim);
|
|
180
|
+
cursor: pointer;
|
|
181
|
+
}
|
|
182
|
+
.hai-icon-btn:hover { background: var(--hai-hover); color: var(--hai-fg); }
|
|
183
|
+
|
|
184
|
+
/* clips the drawer while it waits off the right edge */
|
|
185
|
+
.hai-main { flex: 1; display: grid; grid-template-columns: minmax(0, 1fr); min-height: 0; position: relative; overflow: hidden; }
|
|
186
|
+
|
|
187
|
+
/* the conversation is a centred column; the scrollbar stays at the edge */
|
|
188
|
+
.hai-chat {
|
|
189
|
+
--hai-gutter: max(16px, calc((100% - var(--hai-column)) / 2));
|
|
190
|
+
display: flex;
|
|
191
|
+
flex-direction: column;
|
|
192
|
+
min-width: 0;
|
|
193
|
+
min-height: 0;
|
|
194
|
+
transition: margin-right .25s cubic-bezier(.2, .8, .2, 1), opacity .25s;
|
|
195
|
+
}
|
|
196
|
+
/* behind the drawer on a narrow screen, out of reach until it closes */
|
|
197
|
+
.hai-chat[inert] { opacity: .4; }
|
|
198
|
+
/* on a wide screen the chat makes room for the open drawer */
|
|
199
|
+
@media (min-width: 900px) {
|
|
200
|
+
.hai-main.inspector-open > .hai-chat { margin-right: var(--hai-inspector-width); }
|
|
201
|
+
}
|
|
202
|
+
.hai-transcript {
|
|
203
|
+
flex: 1;
|
|
204
|
+
overflow-y: auto;
|
|
205
|
+
padding: 28px var(--hai-gutter) 8px;
|
|
206
|
+
scrollbar-width: thin;
|
|
207
|
+
scrollbar-color: var(--hai-line) transparent;
|
|
208
|
+
}
|
|
53
209
|
|
|
54
|
-
|
|
55
|
-
.hai-
|
|
56
|
-
.hai-
|
|
210
|
+
/* ── empty state ────────────────────────────────────────────────────── */
|
|
211
|
+
.hai-empty { color: var(--hai-dim); }
|
|
212
|
+
.hai-empty p { margin: 0; max-width: 54ch; font-size: 15px; line-height: 1.6; }
|
|
213
|
+
.hai-empty-mark { width: 44px; height: 44px; margin-bottom: 20px; }
|
|
214
|
+
/* alone, it greets; after what init showed, it stays out of the way */
|
|
215
|
+
.hai-empty:first-child {
|
|
216
|
+
display: flex;
|
|
217
|
+
flex-direction: column;
|
|
218
|
+
align-items: center;
|
|
219
|
+
text-align: center;
|
|
220
|
+
padding-top: clamp(24px, 14vh, 140px);
|
|
221
|
+
}
|
|
222
|
+
.hai-empty:not(:first-child) .hai-empty-mark { display: none; }
|
|
57
223
|
|
|
58
|
-
.hai-
|
|
59
|
-
.hai-empty
|
|
60
|
-
.hai-
|
|
224
|
+
.hai-suggestions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 20px; }
|
|
225
|
+
.hai-empty:first-child .hai-suggestions { justify-content: center; }
|
|
226
|
+
.hai-empty:not(:first-child) .hai-suggestions { margin-top: 12px; }
|
|
61
227
|
.hai-suggestion {
|
|
62
|
-
|
|
63
|
-
color: var(--hai-fg);
|
|
228
|
+
padding: 7px 14px;
|
|
64
229
|
border: 1px solid var(--hai-line);
|
|
65
230
|
border-radius: 999px;
|
|
66
|
-
|
|
67
|
-
|
|
231
|
+
background: var(--hai-panel);
|
|
232
|
+
color: var(--hai-fg);
|
|
68
233
|
font: inherit;
|
|
69
|
-
font-size:
|
|
234
|
+
font-size: 13.5px;
|
|
235
|
+
cursor: pointer;
|
|
236
|
+
transition: border-color .15s, background-color .15s;
|
|
70
237
|
}
|
|
71
|
-
.hai-suggestion:hover { border-color: var(--hai-accent); }
|
|
238
|
+
.hai-suggestion:hover { border-color: var(--hai-accent); background: var(--hai-accent-soft); }
|
|
72
239
|
|
|
73
240
|
/* ── transcript blocks ──────────────────────────────────────────────── */
|
|
74
|
-
.hai-block { margin: 0 0
|
|
241
|
+
.hai-block { margin: 0 0 18px; }
|
|
242
|
+
.hai-user .hai-body,
|
|
243
|
+
.hai-assistant .hai-body {
|
|
244
|
+
white-space: pre-wrap;
|
|
245
|
+
overflow-wrap: anywhere;
|
|
246
|
+
/* each paragraph takes its own direction: a reply can mix scripts */
|
|
247
|
+
unicode-bidi: plaintext;
|
|
248
|
+
font-size: 15px;
|
|
249
|
+
}
|
|
250
|
+
.hai-assistant { max-width: 72ch; line-height: 1.65; }
|
|
251
|
+
.hai-user { display: flex; justify-content: flex-end; }
|
|
75
252
|
.hai-user .hai-body {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
border-radius:
|
|
79
|
-
|
|
80
|
-
display: inline-block;
|
|
253
|
+
max-width: min(85%, 62ch);
|
|
254
|
+
padding: 9px 14px;
|
|
255
|
+
border-radius: 18px 18px 6px 18px;
|
|
256
|
+
background: var(--hai-user-bg);
|
|
81
257
|
}
|
|
82
|
-
|
|
83
|
-
|
|
258
|
+
|
|
259
|
+
/* an answer given in a surface — it went back to the model as the tool result */
|
|
260
|
+
.hai-interaction { display: flex; align-items: flex-start; gap: 10px; max-width: 72ch; font-size: 13.5px; color: var(--hai-dim); }
|
|
261
|
+
.hai-arrow {
|
|
262
|
+
flex: none;
|
|
263
|
+
display: grid;
|
|
264
|
+
place-items: center;
|
|
265
|
+
width: 22px;
|
|
266
|
+
height: 22px;
|
|
267
|
+
margin-top: -1px;
|
|
268
|
+
border-radius: 50%;
|
|
269
|
+
background: var(--hai-good-soft);
|
|
84
270
|
color: var(--hai-good);
|
|
85
|
-
|
|
271
|
+
}
|
|
272
|
+
.hai-arrow .hai-icon { width: 13px; height: 13px; }
|
|
273
|
+
|
|
274
|
+
.hai-error,
|
|
275
|
+
.hai-expired {
|
|
86
276
|
display: flex;
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
padding
|
|
277
|
+
align-items: flex-start;
|
|
278
|
+
gap: 10px;
|
|
279
|
+
padding: 11px 14px;
|
|
280
|
+
border: 1px solid;
|
|
281
|
+
border-radius: var(--hai-radius);
|
|
90
282
|
}
|
|
91
|
-
.hai-error
|
|
283
|
+
.hai-error .hai-icon,
|
|
284
|
+
.hai-expired .hai-icon { margin-top: 2px; }
|
|
285
|
+
.hai-error {
|
|
286
|
+
border-color: color-mix(in srgb, var(--hai-bad) 35%, transparent);
|
|
287
|
+
background: var(--hai-bad-soft);
|
|
288
|
+
color: var(--hai-bad);
|
|
289
|
+
font: 12.5px/1.55 var(--hai-mono);
|
|
290
|
+
}
|
|
291
|
+
.hai-error .hai-body { overflow-wrap: anywhere; }
|
|
92
292
|
|
|
93
293
|
/* tool provenance row — chrome for the surface directly beneath it */
|
|
94
294
|
.hai-tool {
|
|
95
295
|
border: 1px solid var(--hai-line);
|
|
96
|
-
border-radius: var(--hai-radius)
|
|
97
|
-
background: var(--hai-panel);
|
|
98
|
-
|
|
99
|
-
margin-bottom: 0;
|
|
296
|
+
border-radius: var(--hai-radius);
|
|
297
|
+
background: var(--hai-panel-2);
|
|
298
|
+
overflow: hidden;
|
|
100
299
|
}
|
|
300
|
+
.hai-tool:has(+ .hai-surface) { margin-bottom: 0; border-bottom-left-radius: 0; border-bottom-right-radius: 0; }
|
|
101
301
|
.hai-tool summary {
|
|
102
302
|
display: flex;
|
|
103
303
|
align-items: center;
|
|
104
|
-
gap:
|
|
304
|
+
gap: 9px;
|
|
305
|
+
min-height: 36px;
|
|
105
306
|
padding: 7px 12px;
|
|
307
|
+
box-sizing: border-box;
|
|
106
308
|
cursor: pointer;
|
|
107
|
-
font: 12px var(--hai-mono);
|
|
108
309
|
list-style: none;
|
|
310
|
+
font-size: 12.5px;
|
|
311
|
+
user-select: none;
|
|
109
312
|
}
|
|
110
313
|
.hai-tool summary::-webkit-details-marker { display: none; }
|
|
111
|
-
.hai-
|
|
112
|
-
.hai-
|
|
113
|
-
.hai-
|
|
114
|
-
.hai-
|
|
115
|
-
.hai-
|
|
314
|
+
.hai-tool summary:hover { background: var(--hai-hover); }
|
|
315
|
+
.hai-ticon { flex: none; display: grid; place-items: center; width: 16px; height: 16px; color: var(--hai-dim); }
|
|
316
|
+
.hai-ticon .hai-icon { width: 14px; height: 14px; }
|
|
317
|
+
.hai-tname { font: 500 12.5px var(--hai-mono); }
|
|
318
|
+
.hai-targs {
|
|
319
|
+
flex: 1;
|
|
320
|
+
min-width: 0;
|
|
321
|
+
overflow: hidden;
|
|
322
|
+
text-overflow: ellipsis;
|
|
323
|
+
white-space: nowrap;
|
|
324
|
+
font: 12px var(--hai-mono);
|
|
325
|
+
color: var(--hai-dim);
|
|
326
|
+
}
|
|
327
|
+
.hai-tstatus { color: var(--hai-dim); white-space: nowrap; font-variant-numeric: tabular-nums; }
|
|
328
|
+
.hai-chevron { width: 14px; height: 14px; color: var(--hai-dim); transition: transform .15s; }
|
|
329
|
+
.hai-tool[open] .hai-chevron { transform: rotate(90deg); }
|
|
330
|
+
|
|
331
|
+
.hai-status-ok .hai-ticon { color: var(--hai-good); }
|
|
116
332
|
.hai-status-running .hai-tstatus { color: var(--hai-accent); }
|
|
117
|
-
.hai-
|
|
118
|
-
.hai-
|
|
333
|
+
.hai-status-awaiting .hai-tstatus { color: var(--hai-warn); }
|
|
334
|
+
.hai-status-error .hai-ticon,
|
|
335
|
+
.hai-status-error .hai-tstatus { color: var(--hai-bad); }
|
|
336
|
+
/* the component is the question: the turn is parked on it */
|
|
337
|
+
.hai-tool.hai-status-awaiting { background: var(--hai-warn-soft); }
|
|
338
|
+
.hai-tool.hai-status-awaiting,
|
|
339
|
+
.hai-tool.hai-status-awaiting + .hai-surface { border-color: color-mix(in srgb, var(--hai-warn) 45%, var(--hai-line)); }
|
|
340
|
+
|
|
341
|
+
.hai-tool-detail { padding: 0 12px 12px; border-top: 1px solid var(--hai-line); }
|
|
342
|
+
.hai-label { margin: 10px 0 5px; font: 11px var(--hai-mono); color: var(--hai-dim); }
|
|
343
|
+
.hai-code,
|
|
119
344
|
.hai-digest {
|
|
120
345
|
margin: 0;
|
|
121
|
-
padding:
|
|
122
|
-
|
|
346
|
+
padding: 9px 11px;
|
|
347
|
+
max-height: 200px;
|
|
348
|
+
overflow: auto;
|
|
123
349
|
border: 1px solid var(--hai-line);
|
|
124
|
-
border-radius:
|
|
125
|
-
|
|
126
|
-
|
|
350
|
+
border-radius: 8px;
|
|
351
|
+
background: var(--hai-code-bg);
|
|
352
|
+
font: 12px/1.55 var(--hai-mono);
|
|
127
353
|
white-space: pre-wrap;
|
|
128
|
-
|
|
129
|
-
|
|
354
|
+
overflow-wrap: anywhere;
|
|
355
|
+
}
|
|
356
|
+
.hai-digest { color: var(--hai-good); }
|
|
357
|
+
|
|
358
|
+
.hai-spinner {
|
|
359
|
+
width: 12px;
|
|
360
|
+
height: 12px;
|
|
361
|
+
box-sizing: border-box;
|
|
362
|
+
border: 2px solid var(--hai-accent-soft);
|
|
363
|
+
border-top-color: var(--hai-accent);
|
|
364
|
+
border-radius: 50%;
|
|
365
|
+
animation: hai-spin .8s linear infinite;
|
|
366
|
+
}
|
|
367
|
+
.hai-pulse {
|
|
368
|
+
flex: none;
|
|
369
|
+
width: 8px;
|
|
370
|
+
height: 8px;
|
|
371
|
+
border-radius: 50%;
|
|
372
|
+
background: var(--hai-warn);
|
|
373
|
+
animation: hai-pulse 1.8s ease-out infinite;
|
|
130
374
|
}
|
|
131
375
|
|
|
132
376
|
/* surface container — your component mounts inside this */
|
|
133
377
|
.hai-surface {
|
|
134
|
-
|
|
135
|
-
border-top: none;
|
|
136
|
-
border-radius: 0 0 var(--hai-radius) var(--hai-radius);
|
|
137
|
-
background: var(--hai-panel-2);
|
|
138
|
-
margin-bottom: 14px;
|
|
378
|
+
margin-bottom: 18px;
|
|
139
379
|
overflow: hidden;
|
|
380
|
+
border: 1px solid var(--hai-line);
|
|
381
|
+
border-radius: var(--hai-radius);
|
|
382
|
+
background: var(--hai-panel);
|
|
383
|
+
box-shadow: var(--hai-shadow);
|
|
384
|
+
}
|
|
385
|
+
.hai-tool + .hai-surface { border-top: none; border-top-left-radius: 0; border-top-right-radius: 0; }
|
|
386
|
+
.hai-skeleton { display: grid; gap: 9px; padding: 14px; }
|
|
387
|
+
.hai-skeleton-label { margin-bottom: 2px; font: 12px var(--hai-mono); color: var(--hai-dim); }
|
|
388
|
+
.hai-shimmer {
|
|
389
|
+
height: 10px;
|
|
390
|
+
border-radius: 5px;
|
|
391
|
+
background: linear-gradient(90deg, var(--hai-hover), var(--hai-line), var(--hai-hover)) 0 0 / 200% 100%;
|
|
392
|
+
animation: hai-shimmer 1.4s ease-in-out infinite;
|
|
393
|
+
}
|
|
394
|
+
.hai-shimmer:nth-child(3) { width: 82%; }
|
|
395
|
+
.hai-shimmer:nth-child(4) { width: 60%; }
|
|
396
|
+
.hai-surface-error {
|
|
397
|
+
margin-bottom: 18px;
|
|
398
|
+
padding: 11px 14px;
|
|
399
|
+
border: 1px solid color-mix(in srgb, var(--hai-bad) 35%, transparent);
|
|
400
|
+
border-radius: var(--hai-radius);
|
|
401
|
+
background: var(--hai-bad-soft);
|
|
402
|
+
color: var(--hai-bad);
|
|
403
|
+
font: 12.5px var(--hai-mono);
|
|
140
404
|
}
|
|
141
|
-
.hai-skeleton, .hai-surface-error { padding: 14px; font: 12px var(--hai-mono); color: var(--hai-dim); }
|
|
142
|
-
.hai-surface-error { color: var(--hai-bad); }
|
|
143
405
|
|
|
144
406
|
/* out of date — the runtime has made the surface inert; this only shows it */
|
|
145
407
|
.hai-surface[data-expired] { opacity: .45; filter: grayscale(.7); }
|
|
146
408
|
.hai-expired {
|
|
147
|
-
display: flex;
|
|
148
409
|
flex-wrap: wrap;
|
|
149
410
|
align-items: center;
|
|
150
|
-
gap: 10px
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
border-radius: var(--hai-radius);
|
|
411
|
+
gap: 10px 12px;
|
|
412
|
+
border-color: color-mix(in srgb, var(--hai-warn) 45%, transparent);
|
|
413
|
+
background: var(--hai-warn-soft);
|
|
154
414
|
color: var(--hai-warn);
|
|
155
415
|
}
|
|
416
|
+
.hai-expired .hai-icon { margin-top: 0; }
|
|
156
417
|
.hai-expired .hai-body { flex: 1 1 30ch; }
|
|
157
418
|
.hai-new {
|
|
158
|
-
|
|
159
|
-
color: var(--hai-bg);
|
|
419
|
+
padding: 7px 14px;
|
|
160
420
|
border: none;
|
|
161
421
|
border-radius: 8px;
|
|
162
|
-
|
|
422
|
+
background: var(--hai-warn);
|
|
423
|
+
color: var(--hai-on-accent);
|
|
163
424
|
font: inherit;
|
|
164
425
|
font-weight: 600;
|
|
165
426
|
cursor: pointer;
|
|
166
427
|
}
|
|
167
428
|
|
|
168
429
|
/* ── status + composer ──────────────────────────────────────────────── */
|
|
169
|
-
.hai-status {
|
|
430
|
+
.hai-status {
|
|
431
|
+
display: flex;
|
|
432
|
+
align-items: center;
|
|
433
|
+
gap: 8px;
|
|
434
|
+
min-height: 22px;
|
|
435
|
+
padding: 0 var(--hai-gutter) 6px;
|
|
436
|
+
font-size: 12.5px;
|
|
437
|
+
color: var(--hai-dim);
|
|
438
|
+
}
|
|
170
439
|
.hai-status[data-status="awaiting"] { color: var(--hai-warn); }
|
|
171
|
-
.hai-
|
|
440
|
+
.hai-dots { display: inline-flex; gap: 3px; }
|
|
441
|
+
.hai-dots i { width: 5px; height: 5px; border-radius: 50%; background: currentColor; animation: hai-blink 1.2s infinite both; }
|
|
442
|
+
.hai-dots i:nth-child(2) { animation-delay: .2s; }
|
|
443
|
+
.hai-dots i:nth-child(3) { animation-delay: .4s; }
|
|
444
|
+
|
|
445
|
+
.hai-composer { flex: none; padding: 0 var(--hai-gutter) 18px; }
|
|
446
|
+
.hai-composer-box {
|
|
447
|
+
display: flex;
|
|
448
|
+
align-items: flex-end;
|
|
449
|
+
gap: 8px;
|
|
450
|
+
padding: 7px 7px 7px 14px;
|
|
451
|
+
border: 1px solid var(--hai-line);
|
|
452
|
+
border-radius: 16px;
|
|
453
|
+
background: var(--hai-panel);
|
|
454
|
+
box-shadow: var(--hai-shadow);
|
|
455
|
+
transition: border-color .15s, box-shadow .15s;
|
|
456
|
+
}
|
|
457
|
+
.hai-composer-box:focus-within { border-color: var(--hai-accent); box-shadow: 0 0 0 3px var(--hai-accent-soft); }
|
|
172
458
|
.hai-input {
|
|
173
459
|
flex: 1;
|
|
460
|
+
box-sizing: border-box;
|
|
461
|
+
min-height: 34px;
|
|
462
|
+
max-height: 200px;
|
|
463
|
+
padding: 6px 0;
|
|
464
|
+
overflow-y: auto;
|
|
174
465
|
resize: none;
|
|
175
|
-
|
|
466
|
+
border: none;
|
|
467
|
+
outline: none;
|
|
468
|
+
background: transparent;
|
|
176
469
|
color: var(--hai-fg);
|
|
177
|
-
border: 1px solid var(--hai-line);
|
|
178
|
-
border-radius: 8px;
|
|
179
|
-
padding: 9px 12px;
|
|
180
470
|
font: inherit;
|
|
181
|
-
|
|
182
|
-
|
|
471
|
+
font-size: 15px;
|
|
472
|
+
line-height: 1.45;
|
|
183
473
|
}
|
|
184
|
-
.hai-input
|
|
185
|
-
.hai-input:disabled { opacity: .
|
|
474
|
+
.hai-input::placeholder { color: var(--hai-dim); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
475
|
+
.hai-input:disabled { cursor: not-allowed; opacity: .6; }
|
|
186
476
|
.hai-send {
|
|
187
|
-
|
|
188
|
-
|
|
477
|
+
flex: none;
|
|
478
|
+
display: grid;
|
|
479
|
+
place-items: center;
|
|
480
|
+
width: 34px;
|
|
481
|
+
height: 34px;
|
|
189
482
|
border: none;
|
|
190
|
-
border-radius:
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
font-weight: 600;
|
|
483
|
+
border-radius: 10px;
|
|
484
|
+
background: var(--hai-accent);
|
|
485
|
+
color: var(--hai-on-accent);
|
|
194
486
|
cursor: pointer;
|
|
487
|
+
transition: opacity .15s;
|
|
195
488
|
}
|
|
196
|
-
.hai-send
|
|
489
|
+
.hai-send .hai-icon { width: 18px; height: 18px; }
|
|
490
|
+
.hai-send:disabled { opacity: .35; cursor: default; }
|
|
197
491
|
|
|
198
|
-
/* ── context
|
|
492
|
+
/* ── model context debug drawer ─────────────────────────────────────── */
|
|
493
|
+
/* Closed, it waits off the right edge, out of the tab order and the
|
|
494
|
+
accessibility tree; open, it slides in, over the chat on a narrow screen. */
|
|
199
495
|
.hai-inspector {
|
|
200
|
-
|
|
201
|
-
|
|
496
|
+
position: absolute;
|
|
497
|
+
inset: 0 0 0 auto;
|
|
498
|
+
z-index: 10;
|
|
202
499
|
display: flex;
|
|
203
500
|
flex-direction: column;
|
|
501
|
+
width: min(100%, var(--hai-inspector-width));
|
|
204
502
|
min-height: 0;
|
|
503
|
+
border-left: 1px solid var(--hai-line);
|
|
504
|
+
background: var(--hai-panel-2);
|
|
505
|
+
box-shadow: -16px 0 32px -12px rgb(0 0 0 / .25);
|
|
506
|
+
transform: translateX(100%);
|
|
507
|
+
visibility: hidden;
|
|
508
|
+
transition: transform .25s cubic-bezier(.2, .8, .2, 1), visibility 0s .25s;
|
|
205
509
|
}
|
|
206
|
-
.hai-inspector-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
.
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
510
|
+
.hai-main.inspector-open > .hai-inspector {
|
|
511
|
+
transform: none;
|
|
512
|
+
visibility: visible;
|
|
513
|
+
transition: transform .25s cubic-bezier(.2, .8, .2, 1), visibility 0s;
|
|
514
|
+
}
|
|
515
|
+
.hai-inspector-head { display: flex; align-items: center; gap: 8px; padding: 10px 10px 10px 16px; border-bottom: 1px solid var(--hai-line); }
|
|
516
|
+
.hai-inspector-title { flex: 1; display: flex; flex-direction: column; font-size: 13px; font-weight: 600; }
|
|
517
|
+
.hai-inspector-title span { color: var(--hai-dim); font-size: 12px; font-weight: 400; }
|
|
518
|
+
.hai-inspector-body {
|
|
519
|
+
flex: 1;
|
|
520
|
+
overflow-y: auto;
|
|
521
|
+
padding: 0 16px 16px;
|
|
522
|
+
scrollbar-width: thin;
|
|
523
|
+
scrollbar-color: var(--hai-line) transparent;
|
|
524
|
+
}
|
|
525
|
+
.hai-inspector-empty { margin: 16px 0; color: var(--hai-dim); font-size: 13px; }
|
|
526
|
+
|
|
527
|
+
/* the numbers stay in view as the context scrolls under them */
|
|
528
|
+
.hai-ctx {
|
|
529
|
+
position: sticky;
|
|
530
|
+
top: 0;
|
|
531
|
+
z-index: 1;
|
|
532
|
+
padding: 14px 0 12px;
|
|
533
|
+
border-bottom: 1px solid var(--hai-line);
|
|
534
|
+
background: var(--hai-panel-2);
|
|
535
|
+
}
|
|
536
|
+
.hai-ctx-headline { display: flex; align-items: baseline; gap: 8px; margin-bottom: 8px; font-size: 12.5px; color: var(--hai-dim); }
|
|
537
|
+
.hai-ctx-pct { font-size: 26px; font-weight: 650; letter-spacing: -.02em; color: var(--hai-good); font-variant-numeric: tabular-nums; }
|
|
538
|
+
.hai-meter { display: flex; height: 6px; margin-bottom: 10px; overflow: hidden; border-radius: 3px; background: var(--hai-good); }
|
|
539
|
+
.hai-meter-model { min-width: 2px; background: var(--hai-accent); }
|
|
540
|
+
.hai-ctx-stat { display: flex; justify-content: space-between; padding: 1px 0; font: 12px var(--hai-mono); }
|
|
541
|
+
.hai-ctx-label { display: inline-flex; align-items: center; gap: 7px; color: var(--hai-dim); }
|
|
542
|
+
.hai-ctx-tok { font-variant-numeric: tabular-nums; }
|
|
543
|
+
.hai-key { width: 8px; height: 8px; border-radius: 2px; }
|
|
544
|
+
.hai-key-model { background: var(--hai-accent); }
|
|
545
|
+
.hai-key-ui { background: var(--hai-good); }
|
|
546
|
+
|
|
547
|
+
.hai-msg { margin-top: 14px; padding-left: 11px; border-left: 2px solid var(--hai-line); }
|
|
548
|
+
.hai-role { margin-bottom: 4px; font: 600 10px var(--hai-mono); text-transform: uppercase; letter-spacing: .08em; color: var(--hai-dim); }
|
|
549
|
+
.hai-mbody { display: grid; gap: 6px; font: 12px/1.55 var(--hai-mono); white-space: pre-wrap; overflow-wrap: anywhere; }
|
|
550
|
+
.hai-tu,
|
|
551
|
+
.hai-tr { padding: 6px 8px; border-radius: 6px; }
|
|
552
|
+
.hai-tu { background: var(--hai-accent-soft); color: var(--hai-accent); }
|
|
553
|
+
.hai-tr { background: var(--hai-good-soft); color: var(--hai-good); }
|
|
554
|
+
.hai-kind { display: block; margin-bottom: 2px; font-size: 10.5px; opacity: .75; }
|
|
555
|
+
|
|
556
|
+
/* ── narrow screens ─────────────────────────────────────────────────── */
|
|
557
|
+
@media (max-width: 899.98px) {
|
|
558
|
+
.hai-subtitle { display: none; }
|
|
559
|
+
.hai-btn { padding: 0 8px; }
|
|
560
|
+
.hai-btn-label {
|
|
561
|
+
position: absolute;
|
|
562
|
+
width: 1px;
|
|
563
|
+
height: 1px;
|
|
564
|
+
overflow: hidden;
|
|
565
|
+
clip-path: inset(50%);
|
|
566
|
+
white-space: nowrap;
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
@media (max-width: 599.98px) {
|
|
570
|
+
.hai-model { display: none; }
|
|
571
|
+
.hai-transcript { padding-top: 18px; }
|
|
572
|
+
.hai-composer { padding-bottom: 12px; }
|
|
219
573
|
}
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
.hai-
|
|
223
|
-
.hai-
|
|
224
|
-
.hai-
|
|
225
|
-
.hai-
|
|
226
|
-
.hai-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
574
|
+
|
|
575
|
+
/* ── focus, motion ──────────────────────────────────────────────────── */
|
|
576
|
+
.hai-btn:focus-visible,
|
|
577
|
+
.hai-icon-btn:focus-visible,
|
|
578
|
+
.hai-send:focus-visible,
|
|
579
|
+
.hai-suggestion:focus-visible,
|
|
580
|
+
.hai-new:focus-visible { outline: 2px solid var(--hai-accent); outline-offset: 2px; }
|
|
581
|
+
.hai-tool summary:focus-visible { outline: 2px solid var(--hai-accent); outline-offset: -2px; }
|
|
582
|
+
|
|
583
|
+
@keyframes hai-spin { to { transform: rotate(360deg); } }
|
|
584
|
+
@keyframes hai-pulse {
|
|
585
|
+
0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--hai-warn) 55%, transparent); }
|
|
586
|
+
100% { box-shadow: 0 0 0 7px transparent; }
|
|
587
|
+
}
|
|
588
|
+
@keyframes hai-blink { 0%, 80%, 100% { opacity: .25; } 40% { opacity: 1; } }
|
|
589
|
+
@keyframes hai-shimmer { from { background-position: 100% 0; } to { background-position: -100% 0; } }
|
|
590
|
+
|
|
591
|
+
@media (prefers-reduced-motion: reduce) {
|
|
592
|
+
.hai-spinner,
|
|
593
|
+
.hai-pulse,
|
|
594
|
+
.hai-dots i,
|
|
595
|
+
.hai-shimmer { animation: none; }
|
|
596
|
+
.hai-chevron,
|
|
597
|
+
.hai-suggestion,
|
|
598
|
+
.hai-composer-box,
|
|
599
|
+
.hai-chat,
|
|
600
|
+
.hai-inspector,
|
|
601
|
+
.hai-main.inspector-open > .hai-inspector { transition: none; }
|
|
231
602
|
}
|