@dualityinstitute/blink 0.0.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.
Files changed (31) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +160 -0
  3. package/assets/AppIcon.icns +0 -0
  4. package/assets/tray/iconTemplate-error.png +0 -0
  5. package/assets/tray/iconTemplate-error@2x.png +0 -0
  6. package/assets/tray/iconTemplate-hidden.png +0 -0
  7. package/assets/tray/iconTemplate-hidden@2x.png +0 -0
  8. package/assets/tray/iconTemplate-monitoring.png +0 -0
  9. package/assets/tray/iconTemplate-monitoring@2x.png +0 -0
  10. package/assets/tray/iconTemplate-processing-b.png +0 -0
  11. package/assets/tray/iconTemplate-processing-b@2x.png +0 -0
  12. package/assets/tray/iconTemplate-processing.png +0 -0
  13. package/assets/tray/iconTemplate-processing@2x.png +0 -0
  14. package/assets/tray/iconTemplate.png +0 -0
  15. package/assets/tray/iconTemplate@2x.png +0 -0
  16. package/dist/cli.js +20463 -0
  17. package/dist/electron/fsevents-1bczt1x4.node +0 -0
  18. package/dist/electron/main.js +28529 -0
  19. package/dist/electron/preload.cjs +115 -0
  20. package/dist/electron/renderer/popup.css +815 -0
  21. package/dist/electron/renderer/popup.html +141 -0
  22. package/dist/electron/renderer/popup.js +4087 -0
  23. package/dist/electron/renderer/presenter.css +455 -0
  24. package/dist/electron/renderer/presenter.html +75 -0
  25. package/dist/electron/renderer/presenter.js +3870 -0
  26. package/package.json +76 -0
  27. package/vendor/Blink.app/Contents/Helpers/BlinkAudio +0 -0
  28. package/vendor/Blink.app/Contents/Info.plist +30 -0
  29. package/vendor/Blink.app/Contents/MacOS/Blink +0 -0
  30. package/vendor/Blink.app/Contents/Resources/AppIcon.icns +0 -0
  31. package/vendor/Blink.app/Contents/_CodeSignature/CodeResources +137 -0
@@ -0,0 +1,815 @@
1
+ /*
2
+ * Popup styles — a calm, native macOS utility panel.
3
+ * Single light/dark stylesheet driven by `prefers-color-scheme`.
4
+ * No theme system, no external CSS, no web fonts.
5
+ */
6
+
7
+ :root {
8
+ color-scheme: light dark;
9
+
10
+ --bg: rgba(248, 244, 235, 0.74);
11
+ --bg-strong: #fbf7ee;
12
+ --card-border: rgba(58, 49, 40, 0.13);
13
+ --fg: #26231f;
14
+ --fg-muted: #777068;
15
+ --fg-subtle: #6f675f;
16
+ --accent: #a84d2a;
17
+ --private: #2c715d;
18
+ --private-soft: rgba(44, 113, 93, 0.13);
19
+ --pill-bg: rgba(75, 62, 48, 0.08);
20
+ --pill-fg: #5e574f;
21
+ --pill-reconciled-bg: rgba(44, 113, 93, 0.13);
22
+ --pill-reconciled-fg: #2c715d;
23
+ --pill-stopped-bg: rgba(168, 77, 42, 0.11);
24
+ --pill-stopped-fg: #8f4326;
25
+ --err-bg: rgba(170, 52, 46, 0.08);
26
+ --err-border: rgba(170, 52, 46, 0.26);
27
+ --err-fg: #aa342e;
28
+ --code-bg: rgba(75, 62, 48, 0.08);
29
+ --code-fg: #26231f;
30
+ --shimmer-base: rgba(75, 62, 48, 0.07);
31
+ --shimmer-highlight: rgba(168, 77, 42, 0.17);
32
+ --divider: rgba(58, 49, 40, 0.13);
33
+ --shadow: 0 26px 80px rgba(35, 28, 20, 0.24), 0 4px 14px rgba(35, 28, 20, 0.12);
34
+ --close-hover: rgba(75, 62, 48, 0.08);
35
+ --stop-hover: rgba(170, 52, 46, 0.14);
36
+
37
+ --font-ui: "Avenir Next", "Helvetica Neue", sans-serif;
38
+ --font-mono: "SF Mono", "IBM Plex Mono", Menlo, monospace;
39
+ }
40
+
41
+ @media (prefers-color-scheme: dark) {
42
+ :root {
43
+ --bg: rgba(28, 27, 25, 0.76);
44
+ --bg-strong: #22211f;
45
+ --card-border: rgba(255, 245, 229, 0.12);
46
+ --fg: #f2ede4;
47
+ --fg-muted: #aca59b;
48
+ --fg-subtle: #aaa297;
49
+ --accent: #dc815c;
50
+ --private: #76c8ad;
51
+ --private-soft: rgba(118, 200, 173, 0.14);
52
+ --pill-bg: rgba(255, 244, 226, 0.09);
53
+ --pill-fg: #d7d0c5;
54
+ --pill-reconciled-bg: rgba(118, 200, 173, 0.14);
55
+ --pill-reconciled-fg: #76c8ad;
56
+ --pill-stopped-bg: rgba(220, 129, 92, 0.14);
57
+ --pill-stopped-fg: #e69a7b;
58
+ --err-bg: rgba(255, 138, 130, 0.12);
59
+ --err-border: rgba(255, 138, 130, 0.34);
60
+ --err-fg: #ff8a82;
61
+ --code-bg: rgba(255, 244, 226, 0.09);
62
+ --code-fg: #f2ede4;
63
+ --shimmer-base: rgba(255, 244, 226, 0.07);
64
+ --shimmer-highlight: rgba(220, 129, 92, 0.24);
65
+ --divider: rgba(255, 245, 229, 0.12);
66
+ --shadow: 0 28px 90px rgba(0, 0, 0, 0.55), 0 4px 14px rgba(0, 0, 0, 0.34);
67
+ --close-hover: rgba(255, 244, 226, 0.09);
68
+ --stop-hover: rgba(255, 138, 130, 0.2);
69
+ }
70
+ }
71
+
72
+ * {
73
+ box-sizing: border-box;
74
+ }
75
+
76
+ html,
77
+ body {
78
+ margin: 0;
79
+ padding: 0;
80
+ height: 100%;
81
+ background: transparent;
82
+ font-family: var(--font-ui);
83
+ font-size: 13px;
84
+ line-height: 1.45;
85
+ color: var(--fg);
86
+ -webkit-font-smoothing: antialiased;
87
+ overflow: hidden;
88
+ user-select: none;
89
+ cursor: default;
90
+ }
91
+
92
+ .card {
93
+ display: flex;
94
+ flex-direction: column;
95
+ height: 100vh;
96
+ background: var(--bg);
97
+ border-radius: 18px;
98
+ border: 1px solid var(--card-border);
99
+ box-shadow: var(--shadow);
100
+ overflow: hidden;
101
+ backdrop-filter: blur(28px) saturate(130%);
102
+ -webkit-backdrop-filter: blur(28px) saturate(130%);
103
+ }
104
+
105
+ .card-header {
106
+ -webkit-app-region: drag;
107
+ display: flex;
108
+ align-items: center;
109
+ justify-content: space-between;
110
+ gap: 8px;
111
+ min-height: 62px;
112
+ padding: 11px 12px 10px 16px;
113
+ border-bottom: 1px solid var(--divider);
114
+ flex-shrink: 0;
115
+ }
116
+
117
+ .identity {
118
+ flex: 1 1 auto;
119
+ min-width: 0;
120
+ overflow: hidden;
121
+ display: flex;
122
+ flex-direction: column;
123
+ gap: 4px;
124
+ }
125
+
126
+ .window-title {
127
+ color: var(--fg);
128
+ font-size: 13px;
129
+ font-weight: 700;
130
+ letter-spacing: 0.035em;
131
+ }
132
+
133
+ .product-context {
134
+ display: flex;
135
+ align-items: center;
136
+ min-width: 0;
137
+ color: var(--fg-muted);
138
+ font-size: 10.5px;
139
+ line-height: 1.2;
140
+ overflow: hidden;
141
+ text-overflow: ellipsis;
142
+ white-space: nowrap;
143
+ }
144
+
145
+ .header-actions {
146
+ display: flex;
147
+ align-items: center;
148
+ gap: 4px;
149
+ flex-shrink: 0;
150
+ -webkit-app-region: no-drag;
151
+ }
152
+
153
+ @media (max-width: 380px) {
154
+ .card-header {
155
+ gap: 0;
156
+ }
157
+
158
+ .header-actions {
159
+ gap: 2px;
160
+ }
161
+
162
+ .identity {
163
+ display: none;
164
+ }
165
+ }
166
+
167
+ .monitoring-control,
168
+ .meeting-control,
169
+ .privacy-control {
170
+ display: inline-flex;
171
+ align-items: center;
172
+ gap: 5px;
173
+ height: 30px;
174
+ padding: 0 8px 0 7px;
175
+ border: 1px solid var(--divider);
176
+ border-radius: 999px;
177
+ color: var(--fg-muted);
178
+ background: rgba(255, 255, 255, 0.08);
179
+ font-size: 12px;
180
+ font-weight: 600;
181
+ cursor: default;
182
+ transition: color 140ms ease, background 140ms ease, border-color 140ms ease;
183
+ }
184
+
185
+ .monitoring-control input,
186
+ .meeting-control input,
187
+ .privacy-control input {
188
+ position: absolute;
189
+ opacity: 0;
190
+ pointer-events: none;
191
+ }
192
+
193
+ .monitoring-indicator,
194
+ .meeting-indicator,
195
+ .privacy-indicator {
196
+ width: 8px;
197
+ height: 8px;
198
+ border: 1.5px solid currentColor;
199
+ border-radius: 50%;
200
+ }
201
+
202
+ .monitoring-control.is-monitoring {
203
+ color: var(--fg);
204
+ background: var(--pill-bg);
205
+ border-color: color-mix(in srgb, var(--fg) 24%, transparent);
206
+ }
207
+
208
+ .monitoring-control.is-monitoring .monitoring-indicator {
209
+ background: currentColor;
210
+ }
211
+
212
+ .meeting-control.is-meeting {
213
+ color: var(--fg);
214
+ background: var(--pill-bg);
215
+ border-color: color-mix(in srgb, var(--fg) 24%, transparent);
216
+ }
217
+
218
+ .meeting-control.is-meeting .meeting-indicator {
219
+ background: currentColor;
220
+ }
221
+
222
+ .monitoring-control.is-starting,
223
+ .meeting-control.is-starting {
224
+ opacity: 0.68;
225
+ }
226
+
227
+ .privacy-control.is-private {
228
+ color: var(--private);
229
+ background: var(--private-soft);
230
+ border-color: color-mix(in srgb, var(--private) 35%, transparent);
231
+ }
232
+
233
+ .privacy-control.is-private .privacy-indicator {
234
+ background: currentColor;
235
+ box-shadow: inset 0 0 0 2px var(--bg-strong);
236
+ }
237
+
238
+ .monitoring-control:focus-within,
239
+ .meeting-control:focus-within,
240
+ .privacy-control:focus-within {
241
+ outline: 2px solid color-mix(in srgb, var(--accent) 45%, transparent);
242
+ outline-offset: 2px;
243
+ }
244
+
245
+ .response-context {
246
+ display: flex;
247
+ align-items: center;
248
+ justify-content: space-between;
249
+ gap: 10px;
250
+ min-height: 30px;
251
+ padding: 5px 12px 6px 16px;
252
+ border-bottom: 1px solid var(--divider);
253
+ background: color-mix(in srgb, var(--bg-strong) 18%, transparent);
254
+ flex: 0 0 auto;
255
+ }
256
+
257
+ .source {
258
+ display: flex;
259
+ align-items: center;
260
+ gap: 8px;
261
+ min-width: 0;
262
+ }
263
+
264
+ .source-label {
265
+ min-width: 0;
266
+ overflow: hidden;
267
+ color: var(--fg-muted);
268
+ font-size: 11px;
269
+ font-weight: 600;
270
+ text-overflow: ellipsis;
271
+ white-space: nowrap;
272
+ }
273
+
274
+ .source-time {
275
+ flex: 0 0 auto;
276
+ color: var(--fg-subtle);
277
+ font-size: 10px;
278
+ font-variant-numeric: tabular-nums;
279
+ }
280
+
281
+ .source[data-source="meeting"] .source-label {
282
+ color: var(--accent);
283
+ }
284
+
285
+ .status-group {
286
+ display: flex;
287
+ align-items: center;
288
+ gap: 5px;
289
+ flex: 0 0 auto;
290
+ }
291
+
292
+ .meeting-context {
293
+ display: flex;
294
+ align-items: center;
295
+ justify-content: space-between;
296
+ gap: 8px;
297
+ min-height: 38px;
298
+ padding: 4px 12px 4px 16px;
299
+ border-bottom: 1px solid var(--divider);
300
+ background: color-mix(in srgb, var(--private-soft) 68%, transparent);
301
+ flex: 0 0 auto;
302
+ }
303
+
304
+ .meeting-context-summary {
305
+ display: flex;
306
+ align-items: center;
307
+ gap: 8px;
308
+ min-width: 0;
309
+ }
310
+
311
+ .context-copy {
312
+ min-width: 0;
313
+ overflow: hidden;
314
+ color: var(--fg-subtle);
315
+ font-size: 10.5px;
316
+ font-weight: 600;
317
+ line-height: 1.2;
318
+ text-overflow: ellipsis;
319
+ white-space: nowrap;
320
+ }
321
+
322
+ .context-copy.has-context {
323
+ color: var(--private);
324
+ }
325
+
326
+ .pill {
327
+ display: inline-flex;
328
+ align-items: center;
329
+ height: 18px;
330
+ padding: 0 8px;
331
+ border-radius: 9px;
332
+ font-size: 10.5px;
333
+ font-weight: 600;
334
+ letter-spacing: 0.02em;
335
+ color: var(--pill-fg);
336
+ background: var(--pill-bg);
337
+ white-space: nowrap;
338
+ }
339
+
340
+ .transcript-toggle {
341
+ -webkit-app-region: no-drag;
342
+ border: 1px solid transparent;
343
+ font-family: var(--font-ui);
344
+ cursor: default;
345
+ transition: opacity 120ms ease, border-color 120ms ease;
346
+ }
347
+
348
+ .transcript-toggle::before {
349
+ content: "";
350
+ width: 5px;
351
+ height: 5px;
352
+ margin-right: 5px;
353
+ border-radius: 50%;
354
+ background: currentColor;
355
+ }
356
+
357
+ .transcript-toggle[aria-expanded="false"] {
358
+ opacity: 0.55;
359
+ }
360
+
361
+ .transcript-toggle:hover,
362
+ .transcript-toggle:focus-visible {
363
+ border-color: color-mix(in srgb, var(--fg) 22%, transparent);
364
+ outline: none;
365
+ }
366
+
367
+ .ask-btn {
368
+ -webkit-app-region: no-drag;
369
+ display: inline-flex;
370
+ align-items: center;
371
+ justify-content: center;
372
+ flex: 0 0 auto;
373
+ min-width: 52px;
374
+ height: 30px;
375
+ padding: 0 10px;
376
+ border: 1px solid color-mix(in srgb, var(--accent) 72%, var(--divider));
377
+ border-radius: 9px;
378
+ background: var(--accent);
379
+ color: var(--bg-strong);
380
+ font: 600 12px/1 var(--font-ui);
381
+ cursor: default;
382
+ transition: filter 120ms ease, opacity 120ms ease;
383
+ }
384
+
385
+ .ask-btn:hover:not(:disabled) {
386
+ filter: brightness(1.08);
387
+ }
388
+
389
+ .ask-btn:focus-visible {
390
+ outline: 2px solid color-mix(in srgb, var(--accent) 45%, transparent);
391
+ outline-offset: 2px;
392
+ }
393
+
394
+ .ask-btn:disabled {
395
+ opacity: 0.45;
396
+ }
397
+
398
+ .transcript-panel {
399
+ flex: 0 0 auto;
400
+ max-height: 74px;
401
+ overflow-y: auto;
402
+ padding: 6px 14px 7px 16px;
403
+ border-bottom: 1px solid var(--divider);
404
+ background: color-mix(in srgb, var(--bg-strong) 12%, transparent);
405
+ font-size: 11.5px;
406
+ line-height: 1.35;
407
+ user-select: text;
408
+ -webkit-user-select: text;
409
+ scrollbar-width: thin;
410
+ scrollbar-color: var(--fg-subtle) transparent;
411
+ }
412
+
413
+ .transcript-panel::-webkit-scrollbar {
414
+ width: 5px;
415
+ }
416
+
417
+ .transcript-panel::-webkit-scrollbar-thumb {
418
+ background: var(--fg-subtle);
419
+ border-radius: 3px;
420
+ opacity: 0.4;
421
+ }
422
+
423
+ .transcript-line {
424
+ display: flex;
425
+ gap: 6px;
426
+ margin: 1px 0;
427
+ }
428
+
429
+ .transcript-speaker {
430
+ flex: 0 0 auto;
431
+ padding-top: 1px;
432
+ font-size: 9.5px;
433
+ font-weight: 700;
434
+ letter-spacing: 0.05em;
435
+ text-transform: uppercase;
436
+ color: var(--fg-subtle);
437
+ }
438
+
439
+ .transcript-speaker.is-them {
440
+ color: var(--accent);
441
+ }
442
+
443
+ .transcript-speaker.is-you {
444
+ color: var(--private);
445
+ }
446
+
447
+ .transcript-text {
448
+ min-width: 0;
449
+ color: var(--fg-muted);
450
+ word-break: keep-all;
451
+ overflow-wrap: break-word;
452
+ }
453
+
454
+ .transcript-empty {
455
+ color: var(--fg-subtle);
456
+ font-style: italic;
457
+ }
458
+
459
+ .pill.reconciled-pill {
460
+ background: var(--pill-reconciled-bg);
461
+ color: var(--pill-reconciled-fg);
462
+ }
463
+
464
+ .pill.stopped-pill {
465
+ background: var(--pill-stopped-bg);
466
+ color: var(--pill-stopped-fg);
467
+ }
468
+
469
+ .pill.usage-pill {
470
+ font-variant-numeric: tabular-nums;
471
+ }
472
+
473
+ .pill.usage-pill.is-near-limit {
474
+ background: var(--pill-reconciled-bg);
475
+ color: var(--pill-reconciled-fg);
476
+ }
477
+
478
+ .pill.usage-pill.is-exhausted {
479
+ background: var(--pill-stopped-bg);
480
+ color: var(--pill-stopped-fg);
481
+ }
482
+
483
+ .stop-btn {
484
+ -webkit-app-region: no-drag;
485
+ display: inline-flex;
486
+ align-items: center;
487
+ gap: 5px;
488
+ height: 30px;
489
+ padding: 0 10px;
490
+ border: 1px solid var(--err-border);
491
+ border-radius: 9px;
492
+ background: var(--err-bg);
493
+ color: var(--err-fg);
494
+ font: 600 11px/1 var(--font-ui);
495
+ letter-spacing: 0.01em;
496
+ cursor: default;
497
+ transition: background 120ms ease, opacity 120ms ease;
498
+ }
499
+
500
+ .stop-btn::before {
501
+ content: "";
502
+ width: 6px;
503
+ height: 6px;
504
+ border-radius: 1.5px;
505
+ background: currentColor;
506
+ flex: 0 0 auto;
507
+ }
508
+
509
+ .stop-btn:hover,
510
+ .stop-btn:focus-visible {
511
+ background: var(--stop-hover);
512
+ outline: none;
513
+ }
514
+
515
+ .stop-btn:disabled {
516
+ opacity: 0.65;
517
+ }
518
+
519
+ .close-btn {
520
+ -webkit-app-region: no-drag;
521
+ border: 0;
522
+ background: transparent;
523
+ color: var(--fg-muted);
524
+ font-size: 20px;
525
+ line-height: 1;
526
+ width: 30px;
527
+ height: 30px;
528
+ border-radius: 9px;
529
+ display: inline-flex;
530
+ align-items: center;
531
+ justify-content: center;
532
+ padding: 0;
533
+ cursor: default;
534
+ transition: background 120ms ease, color 120ms ease;
535
+ }
536
+
537
+ .close-btn:hover,
538
+ .close-btn:focus-visible {
539
+ background: var(--close-hover);
540
+ color: var(--fg);
541
+ outline: none;
542
+ }
543
+
544
+ .card-body {
545
+ position: relative;
546
+ flex: 1 1 auto;
547
+ min-height: 0;
548
+ overflow-y: auto;
549
+ padding: 12px 14px 14px 14px;
550
+ scrollbar-width: thin;
551
+ scrollbar-color: var(--fg-subtle) transparent;
552
+ user-select: text;
553
+ -webkit-user-select: text;
554
+ }
555
+
556
+ .bridge-error {
557
+ position: fixed;
558
+ inset: 0 0 auto;
559
+ z-index: 9999;
560
+ padding: 8px;
561
+ border-bottom: 1px solid var(--err-border);
562
+ background: var(--bg-strong);
563
+ color: var(--err-fg);
564
+ font: 600 12px/1.35 var(--font-ui);
565
+ text-align: center;
566
+ }
567
+
568
+ .card-body::-webkit-scrollbar {
569
+ width: 6px;
570
+ }
571
+
572
+ .card-body::-webkit-scrollbar-thumb {
573
+ background: var(--fg-subtle);
574
+ border-radius: 3px;
575
+ opacity: 0.4;
576
+ }
577
+
578
+ .card-body::-webkit-scrollbar-thumb:hover {
579
+ opacity: 0.8;
580
+ }
581
+
582
+ .answering {
583
+ display: flex;
584
+ flex-direction: column;
585
+ gap: 8px;
586
+ padding: 4px 2px 6px;
587
+ }
588
+
589
+ .shimmer-line {
590
+ display: block;
591
+ height: 10px;
592
+ border-radius: 5px;
593
+ background: linear-gradient(
594
+ 90deg,
595
+ var(--shimmer-base) 0%,
596
+ var(--shimmer-highlight) 40%,
597
+ var(--shimmer-base) 80%
598
+ );
599
+ background-size: 220% 100%;
600
+ animation: shimmer 1.4s cubic-bezier(0.4, 0, 0.2, 1) infinite;
601
+ }
602
+
603
+ .shimmer-line-1 {
604
+ width: 92%;
605
+ animation-delay: 0s;
606
+ }
607
+
608
+ .shimmer-line-2 {
609
+ width: 78%;
610
+ animation-delay: 0.14s;
611
+ }
612
+
613
+ .shimmer-line-3 {
614
+ width: 45%;
615
+ animation-delay: 0.28s;
616
+ }
617
+
618
+ .answering-label {
619
+ margin-top: 4px;
620
+ font-size: 11px;
621
+ color: var(--fg-subtle);
622
+ letter-spacing: 0.06em;
623
+ text-transform: lowercase;
624
+ animation: pulse 1.6s ease-in-out infinite;
625
+ }
626
+
627
+ @keyframes shimmer {
628
+ 0% { background-position: 220% 0; }
629
+ 100% { background-position: -120% 0; }
630
+ }
631
+
632
+ @keyframes pulse {
633
+ 0%, 100% { opacity: 0.95; }
634
+ 50% { opacity: 1; }
635
+ }
636
+
637
+ @media (prefers-reduced-motion: reduce) {
638
+ .shimmer-line,
639
+ .answering-label {
640
+ animation: none;
641
+ opacity: 1;
642
+ }
643
+
644
+ .ask-btn {
645
+ transition: none;
646
+ }
647
+ }
648
+
649
+ /* ---- Answer body (markdown) ---- */
650
+
651
+ .answer {
652
+ font-size: 13px;
653
+ color: var(--fg);
654
+ word-wrap: break-word;
655
+ overflow-wrap: anywhere;
656
+ }
657
+
658
+ .answer:empty {
659
+ display: none;
660
+ }
661
+
662
+ .answer p {
663
+ margin: 0 0 8px 0;
664
+ }
665
+
666
+ .answer p:last-child {
667
+ margin-bottom: 0;
668
+ }
669
+
670
+ .answer h1,
671
+ .answer h2,
672
+ .answer h3,
673
+ .answer h4 {
674
+ margin: 12px 0 6px 0;
675
+ font-weight: 600;
676
+ line-height: 1.3;
677
+ }
678
+
679
+ .answer h1 { font-size: 17px; }
680
+ .answer h2 { font-size: 15px; }
681
+ .answer h3 { font-size: 14px; }
682
+ .answer h4 { font-size: 13px; color: var(--fg-muted); }
683
+
684
+ .answer ul,
685
+ .answer ol {
686
+ margin: 4px 0 8px 0;
687
+ padding-left: 22px;
688
+ }
689
+
690
+ .answer li {
691
+ margin: 2px 0;
692
+ }
693
+
694
+ .answer a {
695
+ color: var(--accent);
696
+ text-decoration: none;
697
+ }
698
+
699
+ .answer a:hover {
700
+ text-decoration: underline;
701
+ }
702
+
703
+ .answer code {
704
+ font-family: var(--font-mono);
705
+ font-size: 12px;
706
+ padding: 1px 5px;
707
+ border-radius: 4px;
708
+ background: var(--code-bg);
709
+ color: var(--code-fg);
710
+ }
711
+
712
+ .answer pre {
713
+ font-family: var(--font-mono);
714
+ font-size: 12px;
715
+ line-height: 1.5;
716
+ padding: 10px 12px;
717
+ border-radius: 8px;
718
+ background: var(--code-bg);
719
+ color: var(--code-fg);
720
+ overflow-x: auto;
721
+ margin: 8px 0;
722
+ }
723
+
724
+ .answer pre code {
725
+ padding: 0;
726
+ background: transparent;
727
+ border-radius: 0;
728
+ font-size: 12px;
729
+ }
730
+
731
+ .answer blockquote {
732
+ margin: 8px 0;
733
+ padding: 2px 10px;
734
+ border-left: 3px solid var(--divider);
735
+ color: var(--fg-muted);
736
+ }
737
+
738
+ .answer strong {
739
+ font-weight: 600;
740
+ }
741
+
742
+ .answer em {
743
+ font-style: italic;
744
+ }
745
+
746
+ .answer hr {
747
+ border: 0;
748
+ border-top: 1px solid var(--divider);
749
+ margin: 10px 0;
750
+ }
751
+
752
+ .answer table {
753
+ border-collapse: collapse;
754
+ margin: 8px 0;
755
+ font-size: 12px;
756
+ }
757
+
758
+ .answer th,
759
+ .answer td {
760
+ border: 1px solid var(--divider);
761
+ padding: 4px 8px;
762
+ text-align: left;
763
+ }
764
+
765
+ /* ---- Error card ---- */
766
+
767
+ .error {
768
+ padding: 10px 12px;
769
+ background: var(--err-bg);
770
+ border: 1px solid var(--err-border);
771
+ border-radius: 8px;
772
+ color: var(--err-fg);
773
+ font-size: 12.5px;
774
+ line-height: 1.4;
775
+ }
776
+
777
+ .error-title {
778
+ font-weight: 600;
779
+ margin-bottom: 4px;
780
+ }
781
+
782
+ .error-message {
783
+ color: var(--err-fg);
784
+ opacity: 0.9;
785
+ word-wrap: break-word;
786
+ overflow-wrap: anywhere;
787
+ font-family: var(--font-mono);
788
+ font-size: 11.5px;
789
+ }
790
+
791
+ /* ---- State machine ---- */
792
+
793
+ .card.state-idle .answering,
794
+ .card.state-idle .answer,
795
+ .card.state-idle .error {
796
+ display: none !important;
797
+ }
798
+
799
+ .card.state-answering .answering { display: flex; }
800
+ .card.state-answering .error { display: none; }
801
+
802
+ .card.state-streaming .answering { display: none; }
803
+ .card.state-streaming .error { display: none; }
804
+
805
+ .card.state-done .answering { display: none; }
806
+ .card.state-done .error { display: none; }
807
+
808
+ .card.state-error .answering { display: none; }
809
+ .card.state-error .answer { display: none; }
810
+ .card.state-error .error { display: block; }
811
+
812
+ /* Hide-attribute fallback */
813
+ [hidden] {
814
+ display: none !important;
815
+ }