@eaera-com/eaera-widgets-v2 0.1.85 → 0.1.87

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 (59) hide show
  1. package/dist/components/base/EaeraDescriptions.d.ts +1 -1
  2. package/dist/components/base/EaeraPagination.mjs +1 -1
  3. package/dist/components/base/EaeraSelect.d.ts +8 -0
  4. package/dist/components/base/EaeraSelect.mjs +1 -1
  5. package/dist/components/base/EaeraSelectStatus.mjs +1 -1
  6. package/dist/components/base/EaeraSelectTag.mjs +1 -1
  7. package/dist/components/base/EaeraTooltip.d.ts +12 -12
  8. package/dist/components/chunks/EaeraChatBox-BizsNzpv.mjs +7 -0
  9. package/dist/components/chunks/{EaeraDynamicFieldRow-C-VUPCvg.mjs → EaeraDynamicFieldRow-8-utCowK.mjs} +1 -1
  10. package/dist/components/chunks/{EaeraForm-DRMCdjw4.mjs → EaeraForm-DxThA46e.mjs} +1 -1
  11. package/dist/components/chunks/{EaeraPagination-BKcbraqK.mjs → EaeraPagination-7pSl3EwP.mjs} +1 -1
  12. package/dist/components/chunks/EaeraSelect-C-sln89V.mjs +1 -0
  13. package/dist/components/chunks/{EaeraSelectStatus-DF8-Svsr.mjs → EaeraSelectStatus-BMiT4W5a.mjs} +1 -1
  14. package/dist/components/chunks/{EaeraSelectTag-fwPFHO14.mjs → EaeraSelectTag-4WtAOO7m.mjs} +1 -1
  15. package/dist/components/chunks/{EaeraTableV2-UqRwaevh.mjs → EaeraTableV2-CIeL4xlB.mjs} +1 -1
  16. package/dist/components/chunks/{EaeraWidgetGrowthBalanceProfitChart-nW-rAuUt.mjs → EaeraWidgetGrowthBalanceProfitChart-BK2uhXA1.mjs} +1 -1
  17. package/dist/components/chunks/{EaeraWidgetMarginCalculator-BoV_EWi6.mjs → EaeraWidgetMarginCalculator-Co6Vnjv1.mjs} +1 -1
  18. package/dist/components/chunks/{EaeraWidgetPositionCalculator-DVbflfoJ.mjs → EaeraWidgetPositionCalculator-_DmVt9Os.mjs} +1 -1
  19. package/dist/components/chunks/{index-D4AGYLPy.mjs → index-2xA6k2YN.mjs} +1 -1
  20. package/dist/components/chunks/{index-TVgABsKc.mjs → index-BWt-XZ6U.mjs} +1 -1
  21. package/dist/components/chunks/{index-4sT0yI4F.mjs → index-COzBGvhd.mjs} +1 -1
  22. package/dist/components/chunks/{index-ocf8b0Fd.mjs → index-CcNULtBu.mjs} +1 -1
  23. package/dist/components/chunks/{index-DD9Bx0uF.mjs → index-ClzOcTL5.mjs} +1 -1
  24. package/dist/components/chunks/{index-IeLjCes0.mjs → index-Cq-BW1_s.mjs} +1 -1
  25. package/dist/components/chunks/{index-BznHBQ5H.mjs → index-CqkcXehS.mjs} +1 -1
  26. package/dist/components/chunks/{index-B4lBGypC.mjs → index-u4AYhvi2.mjs} +1 -1
  27. package/dist/components/composite/EaeraDropdownV2.d.ts +6 -6
  28. package/dist/components/composite/EaeraDynamicFieldRow.mjs +1 -1
  29. package/dist/components/composite/EaeraForm.mjs +1 -1
  30. package/dist/components/composite/EaeraTableV2.mjs +1 -1
  31. package/dist/components/custom/{EaeraChatBox/index.d.ts → EaeraChatBox.d.ts} +5 -3
  32. package/dist/components/custom/EaeraChatBox.mjs +1 -0
  33. package/dist/components/custom/EaeraWidgetBasicTradingStatistics.mjs +1 -1
  34. package/dist/components/custom/EaeraWidgetEconomicInsight.mjs +1 -1
  35. package/dist/components/custom/EaeraWidgetGrowthBalanceProfitChart.mjs +1 -1
  36. package/dist/components/custom/EaeraWidgetHeader.mjs +1 -1
  37. package/dist/components/custom/EaeraWidgetIframe.mjs +1 -1
  38. package/dist/components/custom/EaeraWidgetMarginCalculator.mjs +1 -1
  39. package/dist/components/custom/EaeraWidgetPositionCalculator.mjs +1 -1
  40. package/dist/components/custom/EaeraWidgetTechnicalViews.mjs +1 -1
  41. package/dist/components/index.d.ts +1 -1
  42. package/dist/components/index.mjs +1 -7
  43. package/dist/components/webtrade/EaeraCfdOrderPlacement.mjs +1 -1
  44. package/dist/components/webtrade/EaeraCfdWatchlist.mjs +1 -1
  45. package/dist/components/webtrade/EaeraLightweightChart.mjs +1 -1
  46. package/dist/components/webtrade/EaeraMarketDepth.mjs +1 -1
  47. package/dist/components/webtrade/EaeraOrderPlacement.mjs +1 -1
  48. package/dist/components/webtrade/EaeraTimeNSales.mjs +1 -1
  49. package/dist/components/webtrade/EaeraTradingTable.mjs +1 -1
  50. package/dist/components/webtrade/EaeraWatchlist.mjs +1 -1
  51. package/dist/design-system/components/_chatbox.scss +1176 -0
  52. package/dist/design-system/themes/aurora/index.scss +1 -0
  53. package/dist/design-system/themes/core/index.scss +1 -0
  54. package/dist/design-system/themes/netr/index.scss +1 -0
  55. package/dist/eaera-widgets-v2.es.js +4982 -4926
  56. package/dist/eaera-widgets-v2.umd.cjs +20 -20
  57. package/dist/style.css +1 -1
  58. package/package.json +1 -1
  59. package/dist/components/chunks/EaeraSelect-BxZRZofe.mjs +0 -1
@@ -0,0 +1,1176 @@
1
+ // ============================================================================
2
+ // EAERA CHAT BOX — AI assistant widget (floating + embedded)
3
+ // Component: src/components/custom/EaeraChatBox.vue
4
+ //
5
+ // ALL chat-box styles live here (global stylesheet, BEM-ish naming with
6
+ // the `chat-box-` prefix). Sub-components (message list, bubbles, composer,
7
+ // history list, nav, markdown, code block, blocked state, typing indicator)
8
+ // are style-free templates — every rule is below, organized in sections.
9
+ // Uses --er-* custom properties (host app must provide design tokens).
10
+ // ============================================================================
11
+
12
+ // ── Panel shell ──────────────────────────────────────────────────────────────
13
+
14
+ .chat-box-panel {
15
+ display: flex;
16
+ flex-direction: column;
17
+ overflow: hidden;
18
+ border: 1px solid var(--er-border-default);
19
+ border-radius: var(--er-shape-corner-200, 12px);
20
+ background: var(--er-surface-elevated);
21
+ box-shadow:
22
+ 0 20px 25px -5px rgb(0 0 0 / 0.1),
23
+ 0 8px 10px -6px rgb(0 0 0 / 0.1);
24
+ }
25
+
26
+ // Floating mode — fixed bottom-right, resizable via the panel composable.
27
+ .chat-box-panel--floating {
28
+ position: fixed;
29
+ bottom: 96px;
30
+ right: 32px;
31
+ z-index: 90;
32
+ height: min(780px, calc(100vh - 140px));
33
+ width: min(640px, calc(100vw - 64px));
34
+ }
35
+
36
+ // Wide embedded — history becomes a side column instead of a stacked row.
37
+ .chat-box-panel--sidebar {
38
+ flex-direction: row;
39
+ }
40
+
41
+ // ── History sidebar (wide embedded) ─────────────────────────────────────────
42
+
43
+ .chat-box-sidebar {
44
+ // self-stretch (not h-full): the panel's height often comes only from
45
+ // min-height, and `height: 100%` cannot resolve against a min-height —
46
+ // it would collapse to fit-content. Stretch tracks the panel directly.
47
+ // Flex column so the inner history list can flex + scroll.
48
+ display: flex;
49
+ flex-direction: column;
50
+ align-self: stretch;
51
+ flex-shrink: 0;
52
+ overflow: hidden;
53
+ width: 0;
54
+ transition: width 200ms ease-out;
55
+ }
56
+
57
+ .chat-box-sidebar--open {
58
+ width: 240px;
59
+ border-right: 1px solid var(--er-border-default);
60
+ }
61
+
62
+ // (history list styles live in the MESSAGE LIST / HISTORY section below)
63
+
64
+ // ── Header action buttons ────────────────────────────────────────────────────
65
+
66
+ .chat-box-head-btn {
67
+ display: inline-flex;
68
+ align-items: center;
69
+ justify-content: center;
70
+ flex-shrink: 0;
71
+ padding: 6px;
72
+ border-radius: 6px;
73
+ color: var(--er-text-secondary);
74
+ background: transparent;
75
+ border: none;
76
+ cursor: pointer;
77
+ transition:
78
+ background-color 150ms ease,
79
+ color 150ms ease;
80
+
81
+ &:hover {
82
+ background: var(--er-surface-hover);
83
+ color: var(--er-text-primary);
84
+ }
85
+ }
86
+
87
+ .chat-box-icon {
88
+ width: 16px;
89
+ height: 16px;
90
+ }
91
+
92
+ // ── Floating action button ───────────────────────────────────────────────────
93
+
94
+ .chat-box-fab {
95
+ position: fixed;
96
+ bottom: 24px;
97
+ right: 32px;
98
+ z-index: 90;
99
+ display: flex;
100
+ align-items: center;
101
+ justify-content: center;
102
+ width: 48px;
103
+ height: 48px;
104
+ border: none;
105
+ border-radius: 50%;
106
+ background: var(--er-primary-default);
107
+ color: var(--er-text-inverse, #fff);
108
+ cursor: pointer;
109
+ box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
110
+ transition: transform 200ms ease;
111
+
112
+ &:hover {
113
+ transform: scale(1.05);
114
+ }
115
+ }
116
+
117
+ .chat-box-fab--open {
118
+ transform: rotate(90deg);
119
+
120
+ &:hover {
121
+ transform: rotate(90deg) scale(1.05);
122
+ }
123
+ }
124
+
125
+ .chat-box-fab-icon {
126
+ width: 20px;
127
+ height: 20px;
128
+ }
129
+
130
+ // ── Header ───────────────────────────────────────────────────────────────────
131
+
132
+ .chat-box-header {
133
+ display: flex;
134
+ align-items: center;
135
+ gap: 4px;
136
+ padding: 8px 12px;
137
+ border-bottom: 1px solid var(--er-border-default);
138
+ }
139
+
140
+ .chat-box-header__title {
141
+ flex: 1 1 0%;
142
+ min-width: 0;
143
+ overflow: hidden;
144
+ text-overflow: ellipsis;
145
+ white-space: nowrap;
146
+ font-size: 14px;
147
+ line-height: 20px;
148
+ font-weight: 600;
149
+ color: var(--er-text-primary);
150
+ }
151
+
152
+ .chat-box-head-btn--spin svg {
153
+ animation: spin 1s linear infinite;
154
+ }
155
+
156
+ // ── Main column + error line ────────────────────────────────────────────────
157
+
158
+ // Main column — header + body. min-h-0 lets it shrink inside the flex
159
+ // panel so the message list scrolls instead of overflowing.
160
+ .chat-box-main {
161
+ display: flex;
162
+ min-height: 0;
163
+ min-width: 0;
164
+ flex: 1 1 0%;
165
+ flex-direction: column;
166
+ }
167
+
168
+ .chat-box-error {
169
+ margin: 0;
170
+ padding: 0 16px 4px;
171
+ font-size: 12px;
172
+ line-height: 16px;
173
+ color: var(--er-text-danger);
174
+ }
175
+
176
+ // ── Resize handles (floating mode) ──────────────────────────────────────────
177
+
178
+ .chat-box-resize-n {
179
+ position: absolute;
180
+ inset-inline: 0;
181
+ top: 0;
182
+ height: 6px;
183
+ cursor: ns-resize;
184
+ }
185
+
186
+ .chat-box-resize-w {
187
+ position: absolute;
188
+ inset-block: 0;
189
+ left: 0;
190
+ width: 6px;
191
+ cursor: ew-resize;
192
+ }
193
+
194
+ .chat-box-resize-nw {
195
+ position: absolute;
196
+ left: 0;
197
+ top: 0;
198
+ width: 12px;
199
+ height: 12px;
200
+ cursor: nwse-resize;
201
+ }
202
+
203
+ // ── Embedded fluid mode / root ──────────────────────────────────────────────
204
+
205
+ .chat-box-embedded {
206
+ display: block;
207
+ height: 100%;
208
+ width: 100%;
209
+ }
210
+
211
+ .chat-box-panel--embedded {
212
+ height: 100%;
213
+ min-height: 520px;
214
+ width: 100%;
215
+ }
216
+
217
+ // ── FAB streaming ping dot ──────────────────────────────────────────────────
218
+
219
+ .chat-box-fab__ping {
220
+ position: absolute;
221
+ top: -2px;
222
+ right: -2px;
223
+ width: 12px;
224
+ height: 12px;
225
+ border-radius: 50%;
226
+ background: var(--er-success-default);
227
+ animation: chat-box-ping 1s cubic-bezier(0, 0, 0.2, 1) infinite;
228
+ }
229
+
230
+ @keyframes chat-box-ping {
231
+ 75%,
232
+ 100% {
233
+ transform: scale(2);
234
+ opacity: 0;
235
+ }
236
+ }
237
+
238
+ // ── Panel enter/leave transition ────────────────────────────────────────────
239
+
240
+ .chat-box-panel-enter-active {
241
+ transition:
242
+ opacity 150ms ease-out,
243
+ transform 150ms ease-out;
244
+ }
245
+
246
+ .chat-box-panel-enter-from {
247
+ opacity: 0;
248
+ transform: translateY(8px) scale(0.95);
249
+ }
250
+
251
+ .chat-box-panel-leave-active {
252
+ transition:
253
+ opacity 100ms ease-in,
254
+ transform 100ms ease-in;
255
+ }
256
+
257
+ .chat-box-panel-leave-to {
258
+ opacity: 0;
259
+ transform: translateY(8px) scale(0.95);
260
+ }
261
+
262
+ // ═══════════════════════════════════════════════════════════════════════════
263
+ // MESSAGE LIST
264
+ // ═══════════════════════════════════════════════════════════════════════════
265
+
266
+ .chat-box-msglist {
267
+ position: relative;
268
+ min-height: 0;
269
+ flex: 1 1 0%;
270
+ }
271
+
272
+ .chat-box-msglist__scroll {
273
+ height: 100%;
274
+ overflow-y: auto;
275
+ padding: 16px;
276
+ }
277
+
278
+ .chat-box-msglist__inner {
279
+ margin-inline: auto;
280
+ height: 100%;
281
+ max-width: 860px;
282
+ display: flex;
283
+ flex-direction: column;
284
+ gap: 16px;
285
+ }
286
+
287
+ .chat-box-msglist__empty {
288
+ display: flex;
289
+ flex: 1 1 0%;
290
+ align-items: center;
291
+ justify-content: center;
292
+ text-align: center;
293
+ font-size: 13px;
294
+ line-height: 1.4;
295
+ color: var(--er-text-muted);
296
+ }
297
+
298
+ // ═══════════════════════════════════════════════════════════════════════════
299
+ // MESSAGE BUBBLE
300
+ // ═══════════════════════════════════════════════════════════════════════════
301
+
302
+ .chat-box-msg {
303
+ display: flex;
304
+ flex-direction: column;
305
+ }
306
+
307
+ // NOTE: the `eaera-chat-box-message-bubble--user/--assistant` classes MUST
308
+ // stay — EaeraChatBoxMessageNav queries
309
+ // `[data-msg-id].eaera-chat-box-message-bubble--user`.
310
+
311
+ .eaera-chat-box-message-bubble--user {
312
+ align-items: flex-end;
313
+ }
314
+
315
+ .eaera-chat-box-message-bubble--assistant {
316
+ align-items: stretch;
317
+ }
318
+
319
+ .chat-box-msg__files {
320
+ display: flex;
321
+ flex-wrap: wrap;
322
+ justify-content: flex-end;
323
+ gap: 6px;
324
+ margin-bottom: 6px;
325
+ }
326
+
327
+ .chat-box-attachment {
328
+ display: inline-flex;
329
+ max-width: 240px;
330
+ align-items: center;
331
+ gap: 6px;
332
+ border-radius: 8px;
333
+ border: 1px solid var(--er-border-default);
334
+ background: var(--er-surface-elevated);
335
+ padding: 4px 8px;
336
+ font-size: 12px;
337
+ line-height: 16px;
338
+ color: var(--er-text-secondary);
339
+
340
+ &-icon {
341
+ width: 14px;
342
+ height: 14px;
343
+ flex-shrink: 0;
344
+ }
345
+
346
+ &-name {
347
+ overflow: hidden;
348
+ text-overflow: ellipsis;
349
+ white-space: nowrap;
350
+ }
351
+
352
+ &-size {
353
+ flex-shrink: 0;
354
+ font-size: 10px;
355
+ line-height: 1.4;
356
+ color: var(--er-text-muted);
357
+ }
358
+ }
359
+
360
+ .chat-box-user-bubble {
361
+ max-width: 85%;
362
+ white-space: pre-wrap;
363
+ overflow-wrap: break-word;
364
+ border-radius: 16px;
365
+ border-bottom-right-radius: 6px;
366
+ background: var(--er-primary-default);
367
+ padding: 8px 14px;
368
+ font-size: 13.5px;
369
+ line-height: 1.625;
370
+ color: var(--er-text-inverse, #fff);
371
+ }
372
+
373
+ .chat-box-msg__meta {
374
+ display: flex;
375
+ align-items: center;
376
+ gap: 6px;
377
+ margin-top: 4px;
378
+ padding-right: 4px;
379
+ font-size: 11px;
380
+ line-height: 1.4;
381
+ color: var(--er-text-muted);
382
+ }
383
+
384
+ .chat-box-msg__copy-btn {
385
+ border-radius: 4px;
386
+ padding: 2px;
387
+ transition: color 150ms ease;
388
+ background: transparent;
389
+ border: none;
390
+ cursor: pointer;
391
+ color: inherit;
392
+
393
+ &:hover {
394
+ color: var(--er-text-primary);
395
+ }
396
+ }
397
+
398
+ .chat-box-msg__copy-icon {
399
+ width: 12px;
400
+ height: 12px;
401
+ }
402
+
403
+ .chat-box-msg__copy-icon--ok {
404
+ color: var(--er-success-default);
405
+ }
406
+
407
+ // Assistant header: avatar + name
408
+ .chat-box-msg__head {
409
+ display: flex;
410
+ align-items: center;
411
+ gap: 8px;
412
+ margin-bottom: 6px;
413
+ }
414
+
415
+ .chat-box-msg__avatar {
416
+ display: flex;
417
+ width: 24px;
418
+ height: 24px;
419
+ align-items: center;
420
+ justify-content: center;
421
+ border-radius: 50%;
422
+ background: var(--er-primary-default);
423
+ color: var(--er-text-inverse, #fff);
424
+ }
425
+
426
+ .chat-box-msg__avatar-icon {
427
+ width: 14px;
428
+ height: 14px;
429
+ }
430
+
431
+ .chat-box-msg__name {
432
+ font-size: 13px;
433
+ line-height: 1.4;
434
+ font-weight: 600;
435
+ color: var(--er-text-primary);
436
+ }
437
+
438
+ .chat-box-msg__state {
439
+ margin-bottom: 6px;
440
+ width: fit-content;
441
+ }
442
+
443
+ .chat-box-msg__state-icon {
444
+ display: inline-flex;
445
+ align-items: center;
446
+ gap: 4px;
447
+ }
448
+
449
+ .chat-box-msg__state-spinner {
450
+ width: 8px;
451
+ height: 8px;
452
+ border-radius: 50%;
453
+ border: 1px solid currentColor;
454
+ border-top-color: transparent;
455
+ animation: spin 1s linear infinite;
456
+ }
457
+
458
+ .chat-box-msg__state-icon-ok,
459
+ .chat-box-msg__state-icon-alert {
460
+ width: 12px;
461
+ height: 12px;
462
+ }
463
+
464
+ .chat-box-assistant-card {
465
+ min-width: 0;
466
+ border-radius: 12px;
467
+ border: 1px solid var(--er-border-default);
468
+ background: var(--er-surface-default);
469
+ padding: 10px 14px;
470
+ font-size: 13.5px;
471
+ line-height: 1.625;
472
+ color: var(--er-text-primary);
473
+ box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
474
+ }
475
+
476
+ .chat-box-msg__foot {
477
+ display: flex;
478
+ align-items: center;
479
+ gap: 4px;
480
+ margin-top: 4px;
481
+ font-size: 11px;
482
+ line-height: 1.4;
483
+ color: var(--er-text-muted);
484
+ }
485
+
486
+ .chat-box-msg__error {
487
+ margin: 6px 0 0;
488
+ font-size: 12px;
489
+ line-height: 16px;
490
+ color: var(--er-text-danger);
491
+ }
492
+
493
+ // EaeraTag plain content alignment inside the bubble.
494
+ .chat-box-msg .el-tag__content {
495
+ display: inline-flex;
496
+ align-items: center;
497
+ gap: 4px;
498
+ }
499
+
500
+ // User-bubble markdown — white on primary background overrides.
501
+ .chat-box-msg--user .chat-box-md {
502
+ color: var(--er-text-inverse, #fff);
503
+
504
+ a {
505
+ color: inherit;
506
+ }
507
+
508
+ blockquote {
509
+ border-left-color: color-mix(in srgb, white 40%, transparent);
510
+ color: color-mix(in srgb, white 80%, transparent);
511
+ }
512
+
513
+ :not(pre) > code {
514
+ background: color-mix(in srgb, white 20%, transparent);
515
+ }
516
+ }
517
+
518
+ // ═══════════════════════════════════════════════════════════════════════════
519
+ // MESSAGE NAV (floating ↑ ● ↓ cluster)
520
+ // ═══════════════════════════════════════════════════════════════════════════
521
+
522
+ .chat-box-msg-nav {
523
+ position: absolute;
524
+ top: 50%;
525
+ right: 24px;
526
+ z-index: 10;
527
+ display: flex;
528
+ flex-direction: column;
529
+ align-items: center;
530
+ gap: 8px;
531
+ transform: translateY(-50%);
532
+ }
533
+
534
+ // Button look (circle, border, surface) comes from EaeraButton isIconOnly —
535
+ // only the nav-specific states live here.
536
+ .chat-box-nav-btn {
537
+ position: relative;
538
+ flex-shrink: 0;
539
+
540
+ &--dim {
541
+ opacity: 0.4;
542
+ }
543
+
544
+ // dim variants follow the nav INDEX (which user turn is current), not the
545
+ // raw scroll position — edges of the conversation are what matter.
546
+ &--active {
547
+ border-color: var(--er-primary-default);
548
+ color: var(--er-primary-default);
549
+ box-shadow: none;
550
+ }
551
+ }
552
+
553
+ .chat-box-nav-icon {
554
+ width: 14px;
555
+ height: 14px;
556
+ }
557
+
558
+ .chat-box-nav-icon--list {
559
+ width: 18px;
560
+ height: 18px;
561
+ }
562
+
563
+ .chat-box-nav-badge {
564
+ position: absolute;
565
+ top: -4px;
566
+ right: -4px;
567
+ display: flex;
568
+ align-items: center;
569
+ justify-content: center;
570
+ min-width: 18px;
571
+ height: 18px;
572
+ padding: 0 4px;
573
+ border-radius: 50%;
574
+ background: var(--er-primary-default);
575
+ color: var(--er-text-inverse);
576
+ font-size: 11px;
577
+ font-weight: 600;
578
+ line-height: 1;
579
+ font-variant-numeric: tabular-nums;
580
+ }
581
+
582
+ // ═══════════════════════════════════════════════════════════════════════════
583
+ // COMPOSER
584
+ // ═══════════════════════════════════════════════════════════════════════════
585
+
586
+ .chat-box-composer {
587
+ margin-inline: auto;
588
+ width: 100%;
589
+ max-width: 920px;
590
+ padding: 4px 16px 8px;
591
+ }
592
+
593
+ .chat-box-composer__card {
594
+ border-radius: 12px;
595
+ border: 1px solid var(--er-border-default);
596
+ background: var(--er-surface-default);
597
+ box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
598
+ transition: border-color 150ms ease;
599
+
600
+ &:focus-within {
601
+ border-color: var(--er-primary-default);
602
+ }
603
+ }
604
+
605
+ .chat-box-composer__files {
606
+ display: flex;
607
+ flex-wrap: wrap;
608
+ gap: 6px;
609
+ padding: 10px 12px 0;
610
+ }
611
+
612
+ .chat-box-composer__file-remove {
613
+ border-radius: 4px;
614
+ padding: 2px;
615
+ color: var(--er-text-muted);
616
+ transition: color 150ms ease;
617
+ background: transparent;
618
+ border: none;
619
+ cursor: pointer;
620
+
621
+ &:hover {
622
+ color: var(--er-text-danger);
623
+ }
624
+ }
625
+
626
+ .chat-box-composer__remove-icon {
627
+ width: 12px;
628
+ height: 12px;
629
+ }
630
+
631
+ // Input — EaeraInput text field (borderless inside the card).
632
+ // Doubled class = (0,4,0): must out-rank the EaeraInput `.custom-input`
633
+ // skin (0,3,0) REGARDLESS of stylesheet order — in the bundled style.css
634
+ // this rule lands before the wrapper's default skin and a plain tie would
635
+ // lose the cascade.
636
+ .chat-box-composer-input.chat-box-composer-input {
637
+ .el-textarea__inner {
638
+ border: none;
639
+ background: transparent;
640
+ box-shadow: none !important;
641
+ resize: none;
642
+ padding: 10px 12px 4px;
643
+ font-size: 13.5px;
644
+ line-height: 1.625;
645
+ color: var(--er-text-primary);
646
+
647
+ &::placeholder {
648
+ color: var(--er-text-muted);
649
+ }
650
+
651
+ &:focus {
652
+ box-shadow: none !important;
653
+ }
654
+ }
655
+ }
656
+
657
+ .chat-box-composer__toolbar {
658
+ display: flex;
659
+ align-items: center;
660
+ justify-content: space-between;
661
+ gap: 8px;
662
+ padding: 4px 10px 8px;
663
+ }
664
+
665
+ .chat-box-composer__toolbar-left {
666
+ display: flex;
667
+ min-width: 0;
668
+ align-items: center;
669
+ gap: 4px;
670
+ }
671
+
672
+ .chat-box-composer__toolbar-right {
673
+ display: flex;
674
+ flex-shrink: 0;
675
+ align-items: center;
676
+ gap: 8px;
677
+ }
678
+
679
+ .chat-box-tool-btn {
680
+ border-radius: 6px;
681
+ padding: 6px;
682
+ color: var(--er-text-secondary);
683
+ transition:
684
+ color 150ms ease,
685
+ background-color 150ms ease;
686
+ background: transparent;
687
+ border: none;
688
+ cursor: pointer;
689
+
690
+ &:hover:not(:disabled) {
691
+ background: var(--er-surface-hover);
692
+ color: var(--er-text-primary);
693
+ }
694
+
695
+ &:disabled {
696
+ cursor: not-allowed;
697
+ opacity: 0.4;
698
+ }
699
+ }
700
+
701
+ .chat-box-tool-icon {
702
+ width: 16px;
703
+ height: 16px;
704
+ }
705
+
706
+ .chat-box-tool-icon--sm {
707
+ width: 14px;
708
+ height: 14px;
709
+ }
710
+
711
+ .chat-box-composer__agent {
712
+ display: inline-flex;
713
+ min-width: 0;
714
+ align-items: center;
715
+ gap: 4px;
716
+ border-radius: 6px;
717
+ padding: 4px 6px;
718
+ font-size: 12px;
719
+ line-height: 16px;
720
+ color: var(--er-text-secondary);
721
+ }
722
+
723
+ .chat-box-composer__agent-name {
724
+ overflow: hidden;
725
+ text-overflow: ellipsis;
726
+ white-space: nowrap;
727
+ }
728
+
729
+ .chat-box-composer__agent-chevron {
730
+ width: 12px;
731
+ height: 12px;
732
+ flex-shrink: 0;
733
+ color: var(--er-text-muted);
734
+ }
735
+
736
+ .chat-box-composer__counter {
737
+ font-size: 11px;
738
+ line-height: 1.4;
739
+ font-variant-numeric: tabular-nums;
740
+ color: var(--er-text-muted);
741
+
742
+ &--limit {
743
+ color: var(--er-text-danger);
744
+ }
745
+ }
746
+
747
+ .chat-box-composer__mode {
748
+ display: inline-flex;
749
+ align-items: center;
750
+ gap: 4px;
751
+ border-radius: 6px;
752
+ border: 1px solid var(--er-border-default);
753
+ padding: 2px 6px;
754
+ font-size: 11px;
755
+ line-height: 1.4;
756
+ color: var(--er-text-secondary);
757
+ }
758
+
759
+ .chat-box-composer__mode-dot {
760
+ width: 6px;
761
+ height: 6px;
762
+ border-radius: 50%;
763
+ background: var(--er-success-default);
764
+ }
765
+
766
+ .chat-box-composer__mode-chevron {
767
+ width: 12px;
768
+ height: 12px;
769
+ color: var(--er-text-muted);
770
+ }
771
+
772
+ .chat-box-composer__footer {
773
+ margin: 4px 0 0;
774
+ text-align: center;
775
+ font-size: 11px;
776
+ line-height: 1.4;
777
+ color: var(--er-text-muted);
778
+ }
779
+
780
+ // ═══════════════════════════════════════════════════════════════════════════
781
+ // HISTORY LIST
782
+ // ═══════════════════════════════════════════════════════════════════════════
783
+
784
+ .chat-box-history {
785
+ min-height: 0;
786
+ flex: 1 1 0%;
787
+ overflow-y: auto;
788
+ padding: 8px;
789
+ }
790
+
791
+ .chat-box-history__empty {
792
+ display: flex;
793
+ height: 100%;
794
+ min-height: 10rem;
795
+ align-items: center;
796
+ justify-content: center;
797
+ padding: 0 12px;
798
+ text-align: center;
799
+ font-size: 13px;
800
+ line-height: 1.4;
801
+ color: var(--er-text-muted);
802
+ }
803
+
804
+ .chat-box-history__item {
805
+ display: flex;
806
+ cursor: pointer;
807
+ align-items: center;
808
+ gap: 10px;
809
+ border-radius: 8px;
810
+ padding: 10px 12px;
811
+ transition: background-color 150ms ease;
812
+
813
+ &:hover,
814
+ &:focus-visible {
815
+ background: var(--er-surface-hover);
816
+ }
817
+
818
+ &:focus {
819
+ outline: none;
820
+ }
821
+
822
+ &--active,
823
+ &--active:hover {
824
+ background: var(--er-action-primary-subtle);
825
+ }
826
+
827
+ // Delete button is revealed on row hover.
828
+ &:hover &-delete,
829
+ &:focus-visible &-delete {
830
+ opacity: 1;
831
+ }
832
+ }
833
+
834
+ .chat-box-history__dot {
835
+ width: 8px;
836
+ height: 8px;
837
+ flex-shrink: 0;
838
+ border-radius: 50%;
839
+ background: var(--er-success-default);
840
+ }
841
+
842
+ .chat-box-history__name {
843
+ min-width: 0;
844
+ flex: 1 1 0%;
845
+ overflow: hidden;
846
+ text-overflow: ellipsis;
847
+ white-space: nowrap;
848
+ font-size: 13px;
849
+ line-height: 1.4;
850
+ color: var(--er-text-primary);
851
+ }
852
+
853
+ .chat-box-history__delete {
854
+ flex-shrink: 0;
855
+ border-radius: 6px;
856
+ padding: 4px;
857
+ color: var(--er-text-muted);
858
+ opacity: 0;
859
+ transition:
860
+ opacity 150ms ease,
861
+ color 150ms ease,
862
+ background-color 150ms ease;
863
+ background: transparent;
864
+ border: none;
865
+ cursor: pointer;
866
+
867
+ &:hover {
868
+ background: var(--er-surface-hover);
869
+ color: var(--er-text-danger);
870
+ }
871
+ }
872
+
873
+ .chat-box-history__delete-icon {
874
+ width: 14px;
875
+ height: 14px;
876
+ }
877
+
878
+ .chat-box-history__loading {
879
+ padding: 16px 12px;
880
+ text-align: center;
881
+ font-size: 12px;
882
+ line-height: 16px;
883
+ color: var(--er-text-muted);
884
+ }
885
+
886
+ // ═══════════════════════════════════════════════════════════════════════════
887
+ // MARKDOWN (chat-box-md)
888
+ // ═══════════════════════════════════════════════════════════════════════════
889
+
890
+ .chat-box-md {
891
+ min-width: 0;
892
+ overflow-wrap: break-word;
893
+ font-size: 13.5px;
894
+ line-height: 1.625;
895
+ color: var(--er-text-primary);
896
+
897
+ a {
898
+ color: var(--er-primary-default);
899
+ text-decoration: underline;
900
+ }
901
+
902
+ p {
903
+ margin: 6px 0;
904
+ }
905
+
906
+ h1 {
907
+ margin: 12px 0 6px;
908
+ font-size: 16px;
909
+ font-weight: 600;
910
+ }
911
+
912
+ h2 {
913
+ margin: 12px 0 6px;
914
+ font-size: 15px;
915
+ font-weight: 600;
916
+ }
917
+
918
+ h3 {
919
+ margin: 10px 0 4px;
920
+ font-size: 14px;
921
+ font-weight: 600;
922
+ }
923
+
924
+ h4 {
925
+ margin: 8px 0 4px;
926
+ font-size: 13px;
927
+ font-weight: 600;
928
+ }
929
+
930
+ ul {
931
+ margin: 6px 0;
932
+ padding-left: 20px;
933
+ list-style: disc;
934
+ }
935
+
936
+ ol {
937
+ margin: 6px 0;
938
+ padding-left: 20px;
939
+ list-style: decimal;
940
+ }
941
+
942
+ li {
943
+ margin: 2px 0;
944
+ }
945
+
946
+ blockquote {
947
+ margin: 6px 0;
948
+ padding-left: 12px;
949
+ border-left: 2px solid var(--er-border-default);
950
+ color: var(--er-text-muted);
951
+ }
952
+
953
+ hr {
954
+ margin: 12px 0;
955
+ border-color: var(--er-border-default);
956
+ }
957
+
958
+ strong {
959
+ font-weight: 600;
960
+ }
961
+
962
+ :not(pre) > code {
963
+ padding: 1px 4px;
964
+ border-radius: 4px;
965
+ font-size: 12px;
966
+ background: var(--er-surface-hover);
967
+ }
968
+
969
+ pre {
970
+ margin: 8px 0;
971
+ padding: 12px;
972
+ overflow-x: auto;
973
+ border-radius: 8px;
974
+ font-size: 12.5px;
975
+ }
976
+
977
+ table {
978
+ margin: 8px 0;
979
+ width: 100%;
980
+ border-collapse: collapse;
981
+ font-size: 12px;
982
+
983
+ th {
984
+ padding: 4px 8px;
985
+ border: 1px solid var(--er-border-default);
986
+ text-align: left;
987
+ font-weight: 600;
988
+ }
989
+
990
+ td {
991
+ padding: 4px 8px;
992
+ border: 1px solid var(--er-border-default);
993
+ }
994
+ }
995
+
996
+ *:first-child {
997
+ margin-top: 0;
998
+ }
999
+
1000
+ *:last-child {
1001
+ margin-bottom: 0;
1002
+ }
1003
+ }
1004
+
1005
+ // ═══════════════════════════════════════════════════════════════════════════
1006
+ // CODE BLOCK (chat-box-code-*)
1007
+ // ═══════════════════════════════════════════════════════════════════════════
1008
+
1009
+ .chat-box-code-card {
1010
+ margin: 8px 0;
1011
+ overflow: hidden;
1012
+ border-radius: 8px;
1013
+ border: 1px solid var(--er-border-default);
1014
+ background: var(--er-surface-default);
1015
+ }
1016
+
1017
+ .chat-box-code-bar {
1018
+ display: flex;
1019
+ align-items: center;
1020
+ justify-content: space-between;
1021
+ border-bottom: 1px solid var(--er-border-default);
1022
+ padding: 6px 12px;
1023
+ }
1024
+
1025
+ .chat-box-code-lang {
1026
+ font-size: 11px;
1027
+ line-height: 1.4;
1028
+ font-weight: 500;
1029
+ text-transform: uppercase;
1030
+ letter-spacing: 0.025em;
1031
+ color: var(--er-text-muted);
1032
+ }
1033
+
1034
+ .chat-box-code-actions {
1035
+ display: flex;
1036
+ align-items: center;
1037
+ gap: 2px;
1038
+ }
1039
+
1040
+ .chat-box-code-btn {
1041
+ border-radius: 4px;
1042
+ padding: 4px;
1043
+ color: var(--er-text-muted);
1044
+ transition:
1045
+ color 150ms ease,
1046
+ background-color 150ms ease;
1047
+ background: transparent;
1048
+ border: none;
1049
+ cursor: pointer;
1050
+
1051
+ &:hover {
1052
+ background: var(--er-surface-hover);
1053
+ color: var(--er-text-primary);
1054
+ }
1055
+
1056
+ &--ok {
1057
+ color: var(--er-success-default);
1058
+ }
1059
+ }
1060
+
1061
+ .chat-box-code-btn-icon {
1062
+ width: 14px;
1063
+ height: 14px;
1064
+ }
1065
+
1066
+ .chat-box-code-body {
1067
+ overflow-x: auto;
1068
+ padding: 12px;
1069
+ font-size: 12.5px;
1070
+ line-height: 1.625;
1071
+
1072
+ // Shiki emits hard-coded github-light colors INLINE on every token span
1073
+ // (black body, blue strings…). The chat surface can be dark even when the
1074
+ // host page never sets `html.dark`, so always collapse the whole block to
1075
+ // the design-system text token — near-white in dark themes, token-driven,
1076
+ // never hard-coded. `!important` is required to beat Shiki's inline styles.
1077
+ pre.shiki {
1078
+ background: transparent !important;
1079
+ margin: 0;
1080
+
1081
+ code,
1082
+ code span {
1083
+ color: var(--er-text-primary) !important;
1084
+ }
1085
+ }
1086
+ }
1087
+
1088
+ // ═══════════════════════════════════════════════════════════════════════════
1089
+ // BLOCKED STATE
1090
+ // ═══════════════════════════════════════════════════════════════════════════
1091
+
1092
+ .chat-box-blocked {
1093
+ display: flex;
1094
+ min-height: 0;
1095
+ flex: 1 1 0%;
1096
+ flex-direction: column;
1097
+ align-items: center;
1098
+ justify-content: center;
1099
+ gap: 10px;
1100
+ overflow-y: auto;
1101
+ padding: 24px 20px;
1102
+ text-align: center;
1103
+ }
1104
+
1105
+ .chat-box-blocked__title {
1106
+ margin: 0;
1107
+ font-size: 15px;
1108
+ line-height: 1.4;
1109
+ font-weight: 600;
1110
+ color: var(--er-text-primary);
1111
+ }
1112
+
1113
+ .chat-box-blocked__lead {
1114
+ margin: 0;
1115
+ font-size: 12.5px;
1116
+ line-height: 1.625;
1117
+ color: var(--er-text-muted);
1118
+ }
1119
+
1120
+ .chat-box-blocked__retry {
1121
+ margin-top: 4px;
1122
+ align-self: center;
1123
+ }
1124
+
1125
+ // ═══════════════════════════════════════════════════════════════════════════
1126
+ // TYPING INDICATOR
1127
+ // ═══════════════════════════════════════════════════════════════════════════
1128
+
1129
+ .chat-box-typing {
1130
+ display: flex;
1131
+ align-items: center;
1132
+ justify-content: flex-start;
1133
+ gap: 6px;
1134
+ padding: 8px 0;
1135
+ }
1136
+
1137
+ .chat-box-typing__dot {
1138
+ width: 8px;
1139
+ height: 8px;
1140
+ border-radius: 50%;
1141
+ background: var(--er-text-muted);
1142
+ animation: chat-box-bounce 0.9s infinite ease-in-out;
1143
+
1144
+ &:nth-child(1) {
1145
+ animation-delay: 0ms;
1146
+ }
1147
+
1148
+ &:nth-child(2) {
1149
+ animation-delay: 150ms;
1150
+ }
1151
+
1152
+ &:nth-child(3) {
1153
+ animation-delay: 300ms;
1154
+ }
1155
+ }
1156
+
1157
+ @keyframes chat-box-bounce {
1158
+ 0%,
1159
+ 100% {
1160
+ transform: translateY(-25%);
1161
+ animation-timing-function: cubic-bezier(0.8, 0, 1, 1);
1162
+ }
1163
+
1164
+ 50% {
1165
+ transform: none;
1166
+ animation-timing-function: cubic-bezier(0, 0, 0.2, 1);
1167
+ }
1168
+ }
1169
+
1170
+ // ── Shared spin keyframe (header sync button, state pill) ───────────────────
1171
+
1172
+ @keyframes spin {
1173
+ to {
1174
+ transform: rotate(360deg);
1175
+ }
1176
+ }