@frockbot/plugin-shell 0.0.0 → 0.1.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/frockbot.json +68 -0
- package/package.json +87 -6
- package/src/agent.test.ts +372 -0
- package/src/agent.ts +335 -0
- package/src/approvals.test.ts +224 -0
- package/src/approvals.ts +530 -0
- package/src/backend-assignment.test.ts +161 -0
- package/src/backend-assignment.ts +274 -0
- package/src/backend-authoring.test.ts +518 -0
- package/src/backend-authoring.ts +531 -0
- package/src/backend-bot-identity.test.ts +215 -0
- package/src/backend-completion.test.ts +289 -0
- package/src/backend-completion.ts +95 -0
- package/src/backend-composition.ts +242 -0
- package/src/backend-computer.ts +76 -0
- package/src/backend-configuration.test.ts +1757 -0
- package/src/backend-contracts.test.ts +189 -0
- package/src/backend-contracts.ts +44 -0
- package/src/backend-debug.test.ts +202 -0
- package/src/backend-execution.ts +55 -0
- package/src/backend-flock.ts +96 -0
- package/src/backend-image.test.ts +115 -0
- package/src/backend-image.ts +180 -0
- package/src/backend-isolate.test.ts +238 -0
- package/src/backend-isolate.ts +409 -0
- package/src/backend-machine.ts +144 -0
- package/src/backend-memory.ts +89 -0
- package/src/backend-recovery-integration.test.ts +1575 -0
- package/src/backend-recovery.ts +106 -0
- package/src/backend-routines.ts +375 -0
- package/src/backend-runner.ts +251 -0
- package/src/backend-skills.test.ts +126 -0
- package/src/backend-skills.ts +198 -0
- package/src/backend-stop.test.ts +356 -0
- package/src/backend-subagents.ts +459 -0
- package/src/backend.ts +6035 -0
- package/src/client/FrockBotApp.vue +1026 -0
- package/src/client/SendPayloadView.vue +337 -0
- package/src/client/composer-draft.test.ts +31 -0
- package/src/client/composer-draft.ts +35 -0
- package/src/client/cordis-client-shim.d.ts +15 -0
- package/src/client/index.test.ts +2548 -0
- package/src/client/index.ts +2346 -0
- package/src/client/model-presentation.test.ts +35 -0
- package/src/client/model-presentation.ts +19 -0
- package/src/client/notify.test.ts +89 -0
- package/src/client/notify.ts +101 -0
- package/src/client/skill-invocation.test.ts +143 -0
- package/src/client/skill-invocation.ts +175 -0
- package/src/client/styles.css +1043 -0
- package/src/composition-views.ts +118 -0
- package/src/debug-protocol.test.ts +80 -0
- package/src/debug-protocol.ts +165 -0
- package/src/env.d.ts +10 -0
- package/src/history.test.ts +163 -0
- package/src/history.ts +108 -0
- package/src/host.ts +20 -0
- package/src/index.ts +2 -0
- package/src/manifest.ts +3 -0
- package/src/run-cursor.ts +28 -0
- package/src/run-protocol.test.ts +1281 -0
- package/src/run-protocol.ts +1417 -0
- package/src/settings-links.test.ts +106 -0
- package/src/settings-links.ts +289 -0
- package/src/shared.ts +338 -0
- package/src/skill-protocol.ts +117 -0
- package/src/terminal-records.test.ts +217 -0
- package/src/terminal-records.ts +150 -0
- package/src/unread.test.ts +362 -0
- package/src/unread.ts +675 -0
- package/tsconfig.json +18 -0
- package/vite.config.ts +32 -0
- package/README.md +0 -3
|
@@ -0,0 +1,1043 @@
|
|
|
1
|
+
.frockbot-root {
|
|
2
|
+
position: fixed;
|
|
3
|
+
z-index: 1000;
|
|
4
|
+
inset: 0;
|
|
5
|
+
width: 100%;
|
|
6
|
+
height: 100%;
|
|
7
|
+
|
|
8
|
+
/*
|
|
9
|
+
* `clip`, not `hidden`. A closed drawer is parked outside the window, and
|
|
10
|
+
* `hidden` makes this element a scroll container that can still be scrolled
|
|
11
|
+
* programmatically: focusing a field inside the composer scrolls the parked
|
|
12
|
+
* drawer into view and takes the whole layout sideways with it. `clip` has
|
|
13
|
+
* the clipping without the scroll port, so there is nothing to scroll. The
|
|
14
|
+
* `hidden` above it is the fallback for a renderer without `clip`.
|
|
15
|
+
*/
|
|
16
|
+
overflow: hidden;
|
|
17
|
+
overflow: clip;
|
|
18
|
+
font-size: var(--frock-text-base);
|
|
19
|
+
line-height: var(--frock-leading-normal);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/*
|
|
23
|
+
* Three columns: flock sidebar, workspace, right panel. The panel column is
|
|
24
|
+
* always present and animates between its width and zero so the toggle feels
|
|
25
|
+
* like a drawer rather than a relayout, and so panel plugins keep their state.
|
|
26
|
+
*/
|
|
27
|
+
.app-shell {
|
|
28
|
+
--panel-current: 0px;
|
|
29
|
+
|
|
30
|
+
/* A hosted surface needs more room than a panel plugin's summary column. */
|
|
31
|
+
--panel-surface-width: 360px;
|
|
32
|
+
position: relative;
|
|
33
|
+
display: grid;
|
|
34
|
+
grid-template-columns:
|
|
35
|
+
var(--frock-sidebar-width) minmax(0, 1fr)
|
|
36
|
+
var(--panel-current);
|
|
37
|
+
width: 100%;
|
|
38
|
+
height: 100%;
|
|
39
|
+
min-height: 0;
|
|
40
|
+
background: var(--frock-surface-window);
|
|
41
|
+
transition: grid-template-columns var(--frock-motion-panel);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.app-shell.panel-open {
|
|
45
|
+
--panel-current: var(--frock-panel-width);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.app-shell.panel-open.panel-surface {
|
|
49
|
+
--panel-current: var(--panel-surface-width);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/* Sidebar */
|
|
53
|
+
|
|
54
|
+
.sidebar {
|
|
55
|
+
position: relative;
|
|
56
|
+
display: flex;
|
|
57
|
+
min-height: 0;
|
|
58
|
+
flex-direction: column;
|
|
59
|
+
padding: 0 10px 10px;
|
|
60
|
+
border-right: 1px solid var(--frock-border);
|
|
61
|
+
background: var(--frock-surface-sidebar);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.brand {
|
|
65
|
+
display: flex;
|
|
66
|
+
height: var(--frock-titlebar-height);
|
|
67
|
+
flex: 0 0 auto;
|
|
68
|
+
align-items: center;
|
|
69
|
+
padding: 0 8px;
|
|
70
|
+
-webkit-app-region: drag;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.mac-desktop .brand {
|
|
74
|
+
padding-left: 72px;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.brand-mark {
|
|
78
|
+
color: var(--frock-text);
|
|
79
|
+
font-family: var(--frock-font-display);
|
|
80
|
+
font-size: var(--frock-text-xl);
|
|
81
|
+
letter-spacing: var(--frock-tracking-display);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
.sidebar-top {
|
|
85
|
+
display: flex;
|
|
86
|
+
flex: 0 0 auto;
|
|
87
|
+
align-items: center;
|
|
88
|
+
gap: 6px;
|
|
89
|
+
margin: 0 2px 6px;
|
|
90
|
+
-webkit-app-region: no-drag;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
.sidebar-top > *:first-child {
|
|
94
|
+
min-width: 0;
|
|
95
|
+
flex: 1 1 auto;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.bot-list {
|
|
99
|
+
min-height: 0;
|
|
100
|
+
flex: 1 1 auto;
|
|
101
|
+
overflow: auto;
|
|
102
|
+
padding-top: 4px;
|
|
103
|
+
scrollbar-color: var(--frock-scrollbar) transparent;
|
|
104
|
+
scrollbar-width: thin;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.sidebar-computer {
|
|
108
|
+
flex: 0 0 auto;
|
|
109
|
+
padding: 8px 2px 10px;
|
|
110
|
+
border-top: 1px solid var(--frock-border);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
.sidebar-bottom {
|
|
114
|
+
display: grid;
|
|
115
|
+
gap: 2px;
|
|
116
|
+
margin-top: 0;
|
|
117
|
+
padding-top: 10px;
|
|
118
|
+
border-top: 1px solid var(--frock-border);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/* Workspace */
|
|
122
|
+
|
|
123
|
+
.workspace {
|
|
124
|
+
position: relative;
|
|
125
|
+
min-width: 0;
|
|
126
|
+
min-height: 0;
|
|
127
|
+
background: var(--frock-surface);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
.topbar {
|
|
131
|
+
display: flex;
|
|
132
|
+
height: var(--frock-titlebar-height);
|
|
133
|
+
align-items: center;
|
|
134
|
+
gap: 12px;
|
|
135
|
+
padding: 0 64px 0 18px;
|
|
136
|
+
border-bottom: 1px solid var(--frock-border);
|
|
137
|
+
-webkit-app-region: drag;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
.topbar > :last-child:not(.workspace-title) {
|
|
141
|
+
flex: 0 0 auto;
|
|
142
|
+
-webkit-app-region: no-drag;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
.bot-identity {
|
|
146
|
+
display: grid;
|
|
147
|
+
flex: 0 0 auto;
|
|
148
|
+
place-items: center;
|
|
149
|
+
-webkit-app-region: no-drag;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
.workspace-title {
|
|
153
|
+
display: flex;
|
|
154
|
+
min-width: 0;
|
|
155
|
+
flex: 1;
|
|
156
|
+
flex-direction: column;
|
|
157
|
+
line-height: var(--frock-leading-tight);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
.workspace-title strong {
|
|
161
|
+
overflow: hidden;
|
|
162
|
+
color: var(--frock-text);
|
|
163
|
+
font-size: var(--frock-text-lg);
|
|
164
|
+
font-weight: 600;
|
|
165
|
+
white-space: nowrap;
|
|
166
|
+
text-overflow: ellipsis;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
.workspace-title small {
|
|
170
|
+
overflow: hidden;
|
|
171
|
+
margin-top: 3px;
|
|
172
|
+
color: var(--frock-text-muted);
|
|
173
|
+
font-size: var(--frock-text-sm);
|
|
174
|
+
white-space: nowrap;
|
|
175
|
+
text-overflow: ellipsis;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
.model-setup-link {
|
|
179
|
+
width: max-content;
|
|
180
|
+
max-width: 100%;
|
|
181
|
+
margin-top: 3px;
|
|
182
|
+
overflow: hidden;
|
|
183
|
+
border: 0;
|
|
184
|
+
padding: 0;
|
|
185
|
+
color: var(--frock-action-primary);
|
|
186
|
+
background: transparent;
|
|
187
|
+
font: inherit;
|
|
188
|
+
font-size: var(--frock-text-sm);
|
|
189
|
+
text-align: left;
|
|
190
|
+
text-overflow: ellipsis;
|
|
191
|
+
white-space: nowrap;
|
|
192
|
+
cursor: pointer;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
.model-setup-link:hover {
|
|
196
|
+
color: var(--frock-action-primary-hover);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/*
|
|
200
|
+
* The panel collapse control is pinned to the window's trailing edge. Feature
|
|
201
|
+
* actions live in the panel's own header.
|
|
202
|
+
*/
|
|
203
|
+
.window-actions {
|
|
204
|
+
position: absolute;
|
|
205
|
+
z-index: 20;
|
|
206
|
+
top: 0;
|
|
207
|
+
right: 0;
|
|
208
|
+
display: flex;
|
|
209
|
+
height: var(--frock-titlebar-height);
|
|
210
|
+
align-items: center;
|
|
211
|
+
gap: 2px;
|
|
212
|
+
padding: 0 12px;
|
|
213
|
+
-webkit-app-region: no-drag;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/* Thread */
|
|
217
|
+
|
|
218
|
+
.thread {
|
|
219
|
+
position: absolute;
|
|
220
|
+
top: var(--frock-titlebar-height);
|
|
221
|
+
right: 0;
|
|
222
|
+
bottom: 84px;
|
|
223
|
+
left: 0;
|
|
224
|
+
overflow-y: auto;
|
|
225
|
+
padding: 16px 20px 24px;
|
|
226
|
+
background-color: var(--frock-surface);
|
|
227
|
+
background-image: var(--frock-thread-gradient);
|
|
228
|
+
scrollbar-color: var(--frock-scrollbar) transparent;
|
|
229
|
+
scrollbar-width: thin;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
.empty-thread {
|
|
233
|
+
display: grid;
|
|
234
|
+
min-height: 100%;
|
|
235
|
+
place-content: center;
|
|
236
|
+
justify-items: center;
|
|
237
|
+
padding: 30px;
|
|
238
|
+
color: var(--frock-text-muted);
|
|
239
|
+
text-align: center;
|
|
240
|
+
animation: frock-fade-in var(--frock-motion-enter) both;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
.empty-mark {
|
|
244
|
+
display: grid;
|
|
245
|
+
width: 44px;
|
|
246
|
+
height: 44px;
|
|
247
|
+
place-items: center;
|
|
248
|
+
margin-bottom: 14px;
|
|
249
|
+
border-radius: 14px;
|
|
250
|
+
color: var(--frock-action-primary-hover);
|
|
251
|
+
background: var(--frock-surface-accent);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
.empty-thread h1 {
|
|
255
|
+
margin: 0;
|
|
256
|
+
color: var(--frock-text);
|
|
257
|
+
font-family: var(--frock-font-display);
|
|
258
|
+
font-size: var(--frock-text-2xl);
|
|
259
|
+
font-weight: 400;
|
|
260
|
+
letter-spacing: var(--frock-tracking-display);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
.empty-thread p {
|
|
264
|
+
max-width: 340px;
|
|
265
|
+
margin: 6px 0 0;
|
|
266
|
+
color: var(--frock-text-muted);
|
|
267
|
+
font-size: var(--frock-text-md);
|
|
268
|
+
line-height: var(--frock-leading-normal);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
.message {
|
|
272
|
+
display: flex;
|
|
273
|
+
width: 100%;
|
|
274
|
+
flex-direction: column;
|
|
275
|
+
margin-top: 6px;
|
|
276
|
+
animation: frock-rise-in var(--frock-motion-enter) both;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
.message-user {
|
|
280
|
+
align-items: flex-end;
|
|
281
|
+
margin-top: 18px;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/* A Session announcement: the conversation narrating itself, not a party. */
|
|
285
|
+
.message-system {
|
|
286
|
+
align-items: center;
|
|
287
|
+
margin-top: 14px;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
.message-system-line {
|
|
291
|
+
margin: 0;
|
|
292
|
+
padding: 4px 10px;
|
|
293
|
+
border-radius: var(--frock-radius-control);
|
|
294
|
+
background: var(--frock-surface-subtle);
|
|
295
|
+
color: var(--frock-text-muted);
|
|
296
|
+
font-size: var(--frock-text-xs);
|
|
297
|
+
text-align: center;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/* An assistant Turn is its avatar and, once there is text, its bubble. */
|
|
301
|
+
.message-assistant {
|
|
302
|
+
flex-direction: row;
|
|
303
|
+
align-items: flex-start;
|
|
304
|
+
gap: 8px;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
.bot-avatar {
|
|
308
|
+
position: relative;
|
|
309
|
+
display: grid;
|
|
310
|
+
width: var(--frock-avatar-sm);
|
|
311
|
+
height: var(--frock-avatar-sm);
|
|
312
|
+
flex: 0 0 auto;
|
|
313
|
+
place-items: center;
|
|
314
|
+
margin-top: 2px;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
.bot-avatar-fallback {
|
|
318
|
+
display: grid;
|
|
319
|
+
width: var(--frock-avatar-sm);
|
|
320
|
+
height: var(--frock-avatar-sm);
|
|
321
|
+
place-items: center;
|
|
322
|
+
border-radius: 9px;
|
|
323
|
+
color: var(--frock-action-primary-hover);
|
|
324
|
+
background: var(--frock-surface-accent);
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
/*
|
|
328
|
+
* A Package that fills `frockbot.bot-avatar` renders beside this tile, which
|
|
329
|
+
* then stops being the only child and steps aside.
|
|
330
|
+
*/
|
|
331
|
+
.bot-avatar-fallback:not(:only-child) {
|
|
332
|
+
display: none;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
/*
|
|
336
|
+
* The avatar carries the running state: a fast breath with a halo while the
|
|
337
|
+
* Turn has produced nothing yet, a slower one once text is arriving. The
|
|
338
|
+
* reduced-motion block at the end of this file stops both.
|
|
339
|
+
*/
|
|
340
|
+
.bot-avatar-live {
|
|
341
|
+
animation: frock-breathe 2600ms ease-in-out infinite;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
.bot-avatar-live::after {
|
|
345
|
+
position: absolute;
|
|
346
|
+
border-radius: 12px;
|
|
347
|
+
animation: frock-halo 2600ms ease-in-out infinite;
|
|
348
|
+
box-shadow: 0 0 0 2px var(--frock-surface-accent);
|
|
349
|
+
content: "";
|
|
350
|
+
inset: -4px;
|
|
351
|
+
opacity: 0;
|
|
352
|
+
pointer-events: none;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
.bot-avatar-waiting,
|
|
356
|
+
.bot-avatar-waiting::after {
|
|
357
|
+
animation-duration: 1600ms;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
@keyframes frock-breathe {
|
|
361
|
+
0%,
|
|
362
|
+
100% {
|
|
363
|
+
transform: scale(1);
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
50% {
|
|
367
|
+
transform: scale(1.07);
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
@keyframes frock-halo {
|
|
372
|
+
0%,
|
|
373
|
+
100% {
|
|
374
|
+
opacity: 0;
|
|
375
|
+
transform: scale(0.94);
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
50% {
|
|
379
|
+
opacity: 1;
|
|
380
|
+
transform: scale(1.06);
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
.message-bubble {
|
|
385
|
+
width: max-content;
|
|
386
|
+
max-width: min(640px, 84%);
|
|
387
|
+
padding: 10px 14px;
|
|
388
|
+
border: 1px solid var(--frock-border);
|
|
389
|
+
border-radius: 18px 18px 18px 6px;
|
|
390
|
+
color: var(--frock-text);
|
|
391
|
+
background: var(--frock-surface-raised);
|
|
392
|
+
box-shadow: var(--frock-shadow-card);
|
|
393
|
+
font-size: var(--frock-text-md);
|
|
394
|
+
line-height: var(--frock-leading-normal);
|
|
395
|
+
white-space: pre-wrap;
|
|
396
|
+
overflow-wrap: anywhere;
|
|
397
|
+
animation: frock-rise-in var(--frock-motion-enter) both;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
.message-user .message-bubble {
|
|
401
|
+
max-width: min(640px, 84%);
|
|
402
|
+
border-color: var(--frock-action-primary);
|
|
403
|
+
border-radius: 18px 18px 6px 18px;
|
|
404
|
+
color: var(--frock-on-accent);
|
|
405
|
+
background: var(--frock-action-primary);
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
/*
|
|
409
|
+
* User-facing sends. They stack under the Bot's avatar in the same column the
|
|
410
|
+
* text bubble occupies, so a Turn that only sent a widget still reads as the
|
|
411
|
+
* Bot speaking.
|
|
412
|
+
*/
|
|
413
|
+
|
|
414
|
+
.message-sends {
|
|
415
|
+
display: flex;
|
|
416
|
+
flex-direction: column;
|
|
417
|
+
gap: 8px;
|
|
418
|
+
width: min(640px, 84%);
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
/*
|
|
422
|
+
* Dispatched subagents. A chip is deliberately quiet — a subagent is work the
|
|
423
|
+
* Bot delegated, not something it said — and opens in place to the summary the
|
|
424
|
+
* child handed back. The child's own transcript is never here.
|
|
425
|
+
*/
|
|
426
|
+
|
|
427
|
+
.message-tasks {
|
|
428
|
+
display: flex;
|
|
429
|
+
flex-direction: column;
|
|
430
|
+
gap: 6px;
|
|
431
|
+
width: min(640px, 84%);
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
.task-chip {
|
|
435
|
+
display: flex;
|
|
436
|
+
flex-wrap: wrap;
|
|
437
|
+
gap: 8px;
|
|
438
|
+
align-items: baseline;
|
|
439
|
+
padding: 8px 10px;
|
|
440
|
+
font: inherit;
|
|
441
|
+
color: var(--frock-text);
|
|
442
|
+
text-align: left;
|
|
443
|
+
cursor: pointer;
|
|
444
|
+
background: var(--frock-surface);
|
|
445
|
+
border: 1px solid var(--frock-border);
|
|
446
|
+
border-radius: 10px;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
.task-chip-type {
|
|
450
|
+
font-weight: 600;
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
.task-chip-description {
|
|
454
|
+
flex: 1 1 auto;
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
.task-chip-status,
|
|
458
|
+
.task-chip-model {
|
|
459
|
+
color: var(--frock-text-muted);
|
|
460
|
+
font-size: var(--frock-text-xs);
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
.task-chip-completed .task-chip-status {
|
|
464
|
+
color: var(--frock-text);
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
.task-chip-failed .task-chip-status,
|
|
468
|
+
.task-chip-stopped .task-chip-status {
|
|
469
|
+
color: var(--frock-danger-text);
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
.task-chip-summary {
|
|
473
|
+
flex: 1 0 100%;
|
|
474
|
+
color: var(--frock-text-muted);
|
|
475
|
+
white-space: pre-wrap;
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
.task-chip-stop {
|
|
479
|
+
flex: 0 0 auto;
|
|
480
|
+
padding: 2px 8px;
|
|
481
|
+
color: var(--frock-danger-text);
|
|
482
|
+
font-size: var(--frock-text-xs);
|
|
483
|
+
cursor: pointer;
|
|
484
|
+
border: 1px solid var(--frock-danger-border);
|
|
485
|
+
border-radius: 8px;
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
/* Jump to latest */
|
|
489
|
+
|
|
490
|
+
.jump-latest {
|
|
491
|
+
position: absolute;
|
|
492
|
+
z-index: 6;
|
|
493
|
+
right: 24px;
|
|
494
|
+
bottom: 92px;
|
|
495
|
+
color: var(--frock-text);
|
|
496
|
+
background: var(--frock-surface-raised);
|
|
497
|
+
box-shadow: var(--frock-shadow-card);
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
/* Status banner */
|
|
501
|
+
|
|
502
|
+
.error-banner {
|
|
503
|
+
position: absolute;
|
|
504
|
+
right: 20px;
|
|
505
|
+
bottom: 84px;
|
|
506
|
+
left: 20px;
|
|
507
|
+
z-index: 5;
|
|
508
|
+
display: flex;
|
|
509
|
+
min-height: 38px;
|
|
510
|
+
align-items: center;
|
|
511
|
+
justify-content: space-between;
|
|
512
|
+
gap: 12px;
|
|
513
|
+
padding: 7px 12px;
|
|
514
|
+
border: 1px solid var(--frock-danger-border);
|
|
515
|
+
border-radius: 12px;
|
|
516
|
+
color: var(--frock-danger-text);
|
|
517
|
+
background: var(--frock-danger-surface);
|
|
518
|
+
box-shadow: var(--frock-shadow-card);
|
|
519
|
+
font-size: var(--frock-text-sm);
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
.error-banner button {
|
|
523
|
+
flex: 0 0 auto;
|
|
524
|
+
padding: 5px 10px;
|
|
525
|
+
border-radius: 999px;
|
|
526
|
+
color: var(--frock-on-accent);
|
|
527
|
+
background: var(--frock-danger-text);
|
|
528
|
+
font-weight: 600;
|
|
529
|
+
cursor: pointer;
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
.banner-enter-active,
|
|
533
|
+
.banner-leave-active {
|
|
534
|
+
transition:
|
|
535
|
+
opacity var(--frock-motion-fast),
|
|
536
|
+
transform var(--frock-motion-fast);
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
.banner-enter-from,
|
|
540
|
+
.banner-leave-to {
|
|
541
|
+
opacity: 0;
|
|
542
|
+
transform: translateY(6px);
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
/* Composer */
|
|
546
|
+
|
|
547
|
+
.composer {
|
|
548
|
+
position: absolute;
|
|
549
|
+
right: 20px;
|
|
550
|
+
bottom: 18px;
|
|
551
|
+
left: 20px;
|
|
552
|
+
display: flex;
|
|
553
|
+
min-height: 52px;
|
|
554
|
+
align-items: flex-end;
|
|
555
|
+
gap: 8px;
|
|
556
|
+
padding: 8px 8px 8px 18px;
|
|
557
|
+
border: 1px solid var(--frock-border-strong);
|
|
558
|
+
border-radius: 26px;
|
|
559
|
+
background: var(--frock-surface-raised);
|
|
560
|
+
box-shadow: var(--frock-shadow-composer);
|
|
561
|
+
transition:
|
|
562
|
+
border-color var(--frock-motion-fast),
|
|
563
|
+
box-shadow var(--frock-motion-fast);
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
.composer:focus-within {
|
|
567
|
+
border-color: var(--frock-border-strong);
|
|
568
|
+
box-shadow:
|
|
569
|
+
var(--frock-shadow-composer),
|
|
570
|
+
0 0 0 3px var(--frock-focus-ring);
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
.composer-model-setup {
|
|
574
|
+
min-width: 0;
|
|
575
|
+
flex: 1;
|
|
576
|
+
align-self: center;
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
.composer textarea {
|
|
580
|
+
box-sizing: border-box;
|
|
581
|
+
width: 100%;
|
|
582
|
+
min-width: 0;
|
|
583
|
+
min-height: 36px;
|
|
584
|
+
max-height: 120px;
|
|
585
|
+
flex: 1;
|
|
586
|
+
align-self: stretch;
|
|
587
|
+
resize: none;
|
|
588
|
+
border: 0;
|
|
589
|
+
outline: 0;
|
|
590
|
+
padding: 8px 0;
|
|
591
|
+
color: var(--frock-text);
|
|
592
|
+
background: transparent;
|
|
593
|
+
font-size: var(--frock-text-md);
|
|
594
|
+
line-height: var(--frock-leading-normal);
|
|
595
|
+
text-align: left;
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
.composer textarea::placeholder {
|
|
599
|
+
color: var(--frock-text-subtle);
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
.composer textarea:disabled {
|
|
603
|
+
color: var(--frock-text-muted);
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
/*
|
|
607
|
+
* Skill invocation. The popover floats above the composer rather than pushing
|
|
608
|
+
* it, so the message the User is writing never moves under their caret; the
|
|
609
|
+
* chips sit inside the composer with the textarea because they are part of the
|
|
610
|
+
* message being composed, not a separate control.
|
|
611
|
+
*/
|
|
612
|
+
|
|
613
|
+
.composer-body {
|
|
614
|
+
display: flex;
|
|
615
|
+
width: 100%;
|
|
616
|
+
min-width: 0;
|
|
617
|
+
flex: 1;
|
|
618
|
+
flex-direction: column;
|
|
619
|
+
align-self: stretch;
|
|
620
|
+
gap: 6px;
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
.skill-chips {
|
|
624
|
+
display: flex;
|
|
625
|
+
margin: 0;
|
|
626
|
+
padding: 0;
|
|
627
|
+
flex-wrap: wrap;
|
|
628
|
+
gap: 6px;
|
|
629
|
+
list-style: none;
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
.skill-chip {
|
|
633
|
+
display: inline-flex;
|
|
634
|
+
align-items: center;
|
|
635
|
+
gap: 4px;
|
|
636
|
+
padding: 2px 6px 2px 8px;
|
|
637
|
+
border: 1px solid var(--frock-accent-border);
|
|
638
|
+
border-radius: var(--frock-radius-control);
|
|
639
|
+
color: var(--frock-accent-text);
|
|
640
|
+
background: var(--frock-accent-surface);
|
|
641
|
+
cursor: pointer;
|
|
642
|
+
font-size: var(--frock-text-xs);
|
|
643
|
+
line-height: var(--frock-leading-tight);
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
.skill-chip:hover {
|
|
647
|
+
border-color: var(--frock-border-strong);
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
.skill-chip-name {
|
|
651
|
+
max-width: 160px;
|
|
652
|
+
overflow: hidden;
|
|
653
|
+
text-overflow: ellipsis;
|
|
654
|
+
white-space: nowrap;
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
.skill-popover {
|
|
658
|
+
position: absolute;
|
|
659
|
+
right: 0;
|
|
660
|
+
bottom: calc(100% + 8px);
|
|
661
|
+
left: 0;
|
|
662
|
+
z-index: var(--frock-layer-menu);
|
|
663
|
+
max-height: 240px;
|
|
664
|
+
margin: 0;
|
|
665
|
+
padding: 4px;
|
|
666
|
+
overflow-y: auto;
|
|
667
|
+
border: 1px solid var(--frock-border);
|
|
668
|
+
border-radius: var(--frock-radius-card);
|
|
669
|
+
background: var(--frock-surface-raised);
|
|
670
|
+
box-shadow: var(--frock-shadow-floating);
|
|
671
|
+
list-style: none;
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
.skill-option {
|
|
675
|
+
display: grid;
|
|
676
|
+
padding: 6px 8px;
|
|
677
|
+
border-radius: var(--frock-radius-control);
|
|
678
|
+
cursor: pointer;
|
|
679
|
+
grid-template-columns: auto 1fr;
|
|
680
|
+
gap: 2px 8px;
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
.skill-option-active {
|
|
684
|
+
background: var(--frock-fill-hover);
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
.skill-option-name {
|
|
688
|
+
color: var(--frock-text);
|
|
689
|
+
font-size: var(--frock-text-base);
|
|
690
|
+
line-height: var(--frock-leading-tight);
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
.skill-option-ref {
|
|
694
|
+
color: var(--frock-text-subtle);
|
|
695
|
+
font-family: var(--frock-font-mono);
|
|
696
|
+
font-size: var(--frock-text-xs);
|
|
697
|
+
line-height: var(--frock-leading-tight);
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
.skill-option-description {
|
|
701
|
+
overflow: hidden;
|
|
702
|
+
color: var(--frock-text-muted);
|
|
703
|
+
font-size: var(--frock-text-xs);
|
|
704
|
+
grid-column: 1 / -1;
|
|
705
|
+
line-height: var(--frock-leading-snug);
|
|
706
|
+
text-overflow: ellipsis;
|
|
707
|
+
white-space: nowrap;
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
.composer-busy .stop-button {
|
|
711
|
+
background: var(--frock-danger-text);
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
/* Right panel */
|
|
715
|
+
|
|
716
|
+
.right-panel {
|
|
717
|
+
min-width: 0;
|
|
718
|
+
overflow: hidden;
|
|
719
|
+
border-left: 1px solid var(--frock-border);
|
|
720
|
+
background: var(--frock-surface-sidebar);
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
.right-panel-stack {
|
|
724
|
+
position: relative;
|
|
725
|
+
width: 100%;
|
|
726
|
+
height: 100%;
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
.right-panel-content {
|
|
730
|
+
position: absolute;
|
|
731
|
+
inset: 0;
|
|
732
|
+
display: flex;
|
|
733
|
+
width: var(--frock-panel-width);
|
|
734
|
+
min-height: 0;
|
|
735
|
+
flex-direction: column;
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
.right-panel-header {
|
|
739
|
+
display: flex;
|
|
740
|
+
height: var(--frock-titlebar-height);
|
|
741
|
+
flex: 0 0 auto;
|
|
742
|
+
align-items: center;
|
|
743
|
+
justify-content: flex-end;
|
|
744
|
+
padding: 0 52px 0 12px;
|
|
745
|
+
border-bottom: 1px solid var(--frock-border);
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
.right-panel-body {
|
|
749
|
+
min-height: 0;
|
|
750
|
+
flex: 1;
|
|
751
|
+
overflow-y: auto;
|
|
752
|
+
padding: 16px;
|
|
753
|
+
scrollbar-color: var(--frock-scrollbar) transparent;
|
|
754
|
+
scrollbar-width: thin;
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
.panel-surface-view {
|
|
758
|
+
position: absolute;
|
|
759
|
+
inset: 0;
|
|
760
|
+
display: flex;
|
|
761
|
+
width: var(--panel-surface-width);
|
|
762
|
+
min-height: 0;
|
|
763
|
+
flex-direction: column;
|
|
764
|
+
background: var(--frock-surface);
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
/*
|
|
768
|
+
* The title and back control belong to the surface header; only the generic
|
|
769
|
+
* collapse control floats over its trailing edge.
|
|
770
|
+
*/
|
|
771
|
+
.panel-surface-header {
|
|
772
|
+
display: flex;
|
|
773
|
+
height: var(--frock-titlebar-height);
|
|
774
|
+
flex: 0 0 auto;
|
|
775
|
+
align-items: center;
|
|
776
|
+
gap: 8px;
|
|
777
|
+
padding: 0 52px 0 10px;
|
|
778
|
+
border-bottom: 1px solid var(--frock-border);
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
.panel-surface-header h2 {
|
|
782
|
+
overflow: hidden;
|
|
783
|
+
margin: 0;
|
|
784
|
+
color: var(--frock-text);
|
|
785
|
+
font-size: var(--frock-text-md);
|
|
786
|
+
font-weight: 600;
|
|
787
|
+
white-space: nowrap;
|
|
788
|
+
text-overflow: ellipsis;
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
.panel-surface-content {
|
|
792
|
+
min-height: 0;
|
|
793
|
+
flex: 1;
|
|
794
|
+
overflow-y: auto;
|
|
795
|
+
padding: 16px;
|
|
796
|
+
scrollbar-color: var(--frock-scrollbar) transparent;
|
|
797
|
+
scrollbar-width: thin;
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
.panel-swap-enter-active,
|
|
801
|
+
.panel-swap-leave-active {
|
|
802
|
+
transition:
|
|
803
|
+
opacity var(--frock-motion-panel),
|
|
804
|
+
transform var(--frock-motion-panel);
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
.panel-swap-enter-from,
|
|
808
|
+
.panel-swap-leave-to {
|
|
809
|
+
opacity: 0;
|
|
810
|
+
transform: translateX(12px);
|
|
811
|
+
}
|
|
812
|
+
|
|
813
|
+
/* Responsive */
|
|
814
|
+
|
|
815
|
+
@media (max-width: 980px) {
|
|
816
|
+
.app-shell.panel-open {
|
|
817
|
+
--panel-current: 0px;
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
.app-shell.panel-surface .right-panel {
|
|
821
|
+
width: var(--panel-surface-width);
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
/*
|
|
825
|
+
* A parked panel is hidden as well as off-canvas: it is not something to
|
|
826
|
+
* tab into, read out, or hit-test, and `visibility` is the one property that
|
|
827
|
+
* says all three and still animates.
|
|
828
|
+
*/
|
|
829
|
+
.right-panel {
|
|
830
|
+
position: absolute;
|
|
831
|
+
z-index: 15;
|
|
832
|
+
top: 0;
|
|
833
|
+
right: 0;
|
|
834
|
+
bottom: 0;
|
|
835
|
+
width: var(--frock-panel-width);
|
|
836
|
+
box-shadow: var(--frock-shadow-right-panel);
|
|
837
|
+
transform: translateX(100%);
|
|
838
|
+
visibility: hidden;
|
|
839
|
+
transition:
|
|
840
|
+
transform var(--frock-motion-panel),
|
|
841
|
+
visibility var(--frock-motion-panel);
|
|
842
|
+
}
|
|
843
|
+
|
|
844
|
+
.app-shell.panel-open .right-panel {
|
|
845
|
+
transform: translateX(0);
|
|
846
|
+
visibility: visible;
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
|
|
850
|
+
/*
|
|
851
|
+
* Phone.
|
|
852
|
+
*
|
|
853
|
+
* A hand-held viewport has room for exactly one column, so the shell stops
|
|
854
|
+
* being three columns and becomes the conversation with two drawers over it:
|
|
855
|
+
* the Bot list from the leading edge, the right panel from the trailing one.
|
|
856
|
+
* Squeezing all three instead is what the 190px sidebar above used to do, and
|
|
857
|
+
* at 390px it left the conversation about a hundred points wide with every
|
|
858
|
+
* label clipped mid-word.
|
|
859
|
+
*
|
|
860
|
+
* Only one drawer is ever open: opening either closes the other, in the
|
|
861
|
+
* component, so this layer never has to reason about them overlapping.
|
|
862
|
+
*/
|
|
863
|
+
@media (max-width: 640px) {
|
|
864
|
+
.frockbot-root {
|
|
865
|
+
height: var(--frock-viewport-height);
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
.app-shell,
|
|
869
|
+
.app-shell.panel-open,
|
|
870
|
+
.app-shell.panel-open.panel-surface {
|
|
871
|
+
--panel-surface-width: 100%;
|
|
872
|
+
grid-template-columns: minmax(0, 1fr);
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
/*
|
|
876
|
+
* Off canvas and inert. `visibility` rather than transform alone so a closed
|
|
877
|
+
* drawer is hidden to assistive technology and to a hit test, and so it
|
|
878
|
+
* still animates: the property is transitioned, not switched.
|
|
879
|
+
*/
|
|
880
|
+
.sidebar {
|
|
881
|
+
position: absolute;
|
|
882
|
+
z-index: 25;
|
|
883
|
+
top: 0;
|
|
884
|
+
bottom: 0;
|
|
885
|
+
left: 0;
|
|
886
|
+
width: var(--frock-drawer-width);
|
|
887
|
+
/* `calc` so the declaration is a length the checker can type; `env` alone
|
|
888
|
+
is not one it knows. */
|
|
889
|
+
padding-top: calc(var(--frock-safe-top) + 0px);
|
|
890
|
+
box-shadow: var(--frock-shadow-panel);
|
|
891
|
+
transform: translateX(-100%);
|
|
892
|
+
visibility: hidden;
|
|
893
|
+
transition:
|
|
894
|
+
transform var(--frock-motion-panel),
|
|
895
|
+
visibility var(--frock-motion-panel);
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
.app-shell.nav-open .sidebar {
|
|
899
|
+
transform: translateX(0);
|
|
900
|
+
visibility: visible;
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
/* The drawers dim the conversation they cover, and the dimmed area closes them. */
|
|
904
|
+
/*
|
|
905
|
+
* Under both drawers and over the workspace: the sidebar sits at 25 and the
|
|
906
|
+
* right panel at 15, so one scrim serves whichever is open.
|
|
907
|
+
*/
|
|
908
|
+
.nav-scrim {
|
|
909
|
+
position: absolute;
|
|
910
|
+
z-index: 14;
|
|
911
|
+
inset: 0;
|
|
912
|
+
border: 0;
|
|
913
|
+
padding: 0;
|
|
914
|
+
background: var(--frock-overlay-tint);
|
|
915
|
+
cursor: pointer;
|
|
916
|
+
}
|
|
917
|
+
|
|
918
|
+
.scrim-enter-active,
|
|
919
|
+
.scrim-leave-active {
|
|
920
|
+
transition: opacity var(--frock-motion-panel);
|
|
921
|
+
}
|
|
922
|
+
|
|
923
|
+
.scrim-enter-from,
|
|
924
|
+
.scrim-leave-to {
|
|
925
|
+
opacity: 0;
|
|
926
|
+
}
|
|
927
|
+
|
|
928
|
+
/* The right panel is a drawer too, and on a phone it takes the whole width. */
|
|
929
|
+
.right-panel,
|
|
930
|
+
.app-shell.panel-surface .right-panel {
|
|
931
|
+
width: 100%;
|
|
932
|
+
}
|
|
933
|
+
|
|
934
|
+
.right-panel-content,
|
|
935
|
+
.panel-surface-view {
|
|
936
|
+
width: 100%;
|
|
937
|
+
}
|
|
938
|
+
|
|
939
|
+
/* There is no window chrome to drag and no traffic lights to clear. */
|
|
940
|
+
.brand {
|
|
941
|
+
padding-left: 0;
|
|
942
|
+
}
|
|
943
|
+
|
|
944
|
+
.mac-desktop .brand {
|
|
945
|
+
padding-left: 0;
|
|
946
|
+
}
|
|
947
|
+
|
|
948
|
+
.topbar {
|
|
949
|
+
gap: 8px;
|
|
950
|
+
padding: 0 100px 0 4px;
|
|
951
|
+
}
|
|
952
|
+
|
|
953
|
+
.brand-mark {
|
|
954
|
+
font-size: var(--frock-text-lg);
|
|
955
|
+
}
|
|
956
|
+
|
|
957
|
+
.window-actions {
|
|
958
|
+
padding: 0 8px;
|
|
959
|
+
}
|
|
960
|
+
|
|
961
|
+
.nav-toggle {
|
|
962
|
+
flex: 0 0 auto;
|
|
963
|
+
}
|
|
964
|
+
|
|
965
|
+
/*
|
|
966
|
+
* The conversation. Its horizontal room is the whole window now, so the
|
|
967
|
+
* gutters shrink and a bubble may use nearly all of what is left; the
|
|
968
|
+
* vertical anchors all clear the home indicator.
|
|
969
|
+
*/
|
|
970
|
+
.thread {
|
|
971
|
+
bottom: calc(76px + var(--frock-safe-bottom));
|
|
972
|
+
padding: 12px 12px 20px;
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
.empty-thread {
|
|
976
|
+
padding: 20px;
|
|
977
|
+
}
|
|
978
|
+
|
|
979
|
+
.message-bubble,
|
|
980
|
+
.message-user .message-bubble {
|
|
981
|
+
max-width: 92%;
|
|
982
|
+
}
|
|
983
|
+
|
|
984
|
+
.message-sends,
|
|
985
|
+
.message-tasks {
|
|
986
|
+
width: 92%;
|
|
987
|
+
}
|
|
988
|
+
|
|
989
|
+
.message-attachments img {
|
|
990
|
+
max-width: 100%;
|
|
991
|
+
}
|
|
992
|
+
|
|
993
|
+
.error-banner {
|
|
994
|
+
right: 10px;
|
|
995
|
+
bottom: calc(76px + var(--frock-safe-bottom));
|
|
996
|
+
left: 10px;
|
|
997
|
+
}
|
|
998
|
+
|
|
999
|
+
.jump-latest {
|
|
1000
|
+
right: 14px;
|
|
1001
|
+
bottom: calc(84px + var(--frock-safe-bottom));
|
|
1002
|
+
}
|
|
1003
|
+
|
|
1004
|
+
.composer {
|
|
1005
|
+
right: 10px;
|
|
1006
|
+
bottom: calc(10px + var(--frock-safe-bottom));
|
|
1007
|
+
left: 10px;
|
|
1008
|
+
padding: 6px 6px 6px 14px;
|
|
1009
|
+
}
|
|
1010
|
+
|
|
1011
|
+
.composer textarea {
|
|
1012
|
+
max-height: 96px;
|
|
1013
|
+
font-size: var(--frock-text-input);
|
|
1014
|
+
}
|
|
1015
|
+
|
|
1016
|
+
.skill-chip-name {
|
|
1017
|
+
max-width: 120px;
|
|
1018
|
+
}
|
|
1019
|
+
}
|
|
1020
|
+
|
|
1021
|
+
@media (prefers-reduced-motion: reduce) {
|
|
1022
|
+
*,
|
|
1023
|
+
*::before,
|
|
1024
|
+
*::after {
|
|
1025
|
+
animation-duration: 0.01ms !important;
|
|
1026
|
+
animation-iteration-count: 1 !important;
|
|
1027
|
+
scroll-behavior: auto !important;
|
|
1028
|
+
}
|
|
1029
|
+
}
|
|
1030
|
+
|
|
1031
|
+
.message-attachments {
|
|
1032
|
+
display: flex;
|
|
1033
|
+
flex-wrap: wrap;
|
|
1034
|
+
gap: var(--frockbot-space-2, 0.5rem);
|
|
1035
|
+
margin-top: var(--frockbot-space-2, 0.5rem);
|
|
1036
|
+
}
|
|
1037
|
+
|
|
1038
|
+
.message-attachments img {
|
|
1039
|
+
border: 1px solid var(--frock-border);
|
|
1040
|
+
border-radius: var(--frockbot-radius-small, 4px);
|
|
1041
|
+
display: block;
|
|
1042
|
+
max-width: 20rem;
|
|
1043
|
+
}
|