bunnyquery 1.8.5 → 1.8.8

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/src/widget.css CHANGED
@@ -32,6 +32,8 @@
32
32
  --bq-info-bg: #e8f0fb;
33
33
  --bq-info-border: #3c94ff;
34
34
  --bq-placeholder: #aaaaaa;
35
+ /* hard offset shadow for bubbles; swapped for a light edge in dark */
36
+ --bq-shadow: rgba(0, 0, 0, 0.12);
35
37
  --bq-code-bg: #1e1e1e;
36
38
  --bq-code-fg: #f5f5f5;
37
39
  --bq-icon-invert: 0;
@@ -43,7 +45,8 @@
43
45
  --bq-ink: #ebebeb;
44
46
  --bq-paper: #000;
45
47
  --bq-muted: #a0a0a0;
46
- --bq-line: #3d3d3d;
48
+ /* was #3d3d3d — brighter edges, matching the admin's dark tokens */
49
+ --bq-line: #484848;
47
50
  --bq-hover-bg: #252525;
48
51
  --bq-main: #f06292;
49
52
  --bq-light-main: #f48fb1;
@@ -60,6 +63,8 @@
60
63
  --bq-info-bg: #162230;
61
64
  --bq-info-border: #42a5f5;
62
65
  --bq-placeholder: #787878;
66
+ /* light edge — a black hard shadow is invisible on the dark paper */
67
+ --bq-shadow: rgba(255, 255, 255, 0.16);
63
68
  --bq-icon-invert: 1;
64
69
  }
65
70
 
@@ -565,28 +570,25 @@
565
570
  gap: 0.5rem;
566
571
  }
567
572
 
568
- /* read-only agent (platform + model) badge */
569
- .bq-agent-badge {
570
- display: inline-flex;
571
- align-items: center;
572
- gap: 0.45rem;
573
- padding: 0.3rem 0.6rem;
574
- border: 1px solid var(--bq-main);
575
- background: var(--bq-main-bg);
576
- font-size: 0.75rem;
577
- font-family: var(--bq-mono);
578
- color: var(--bq-main);
579
- max-width: 100%;
580
- overflow: hidden;
573
+ /* landing-style brand header on the chat view: [bunny] BunnyQuery · project */
574
+ .bq-brand {
575
+ min-width: 0;
576
+ font-size: 0.8rem;
577
+ color: var(--bq-muted);
581
578
  }
582
- .bq-agent-badge-logo {
579
+ .bq-brand-icon {
583
580
  width: 1.1rem;
584
581
  height: 1.1rem;
585
582
  object-fit: contain;
586
583
  flex: 0 0 auto;
587
584
  }
588
- .bq-agent-badge-model {
589
- color: var(--bq-muted);
585
+ .bq-brand-name,
586
+ .bq-brand-sep {
587
+ flex: 0 0 auto;
588
+ white-space: nowrap;
589
+ }
590
+ .bq-brand-project {
591
+ min-width: 0;
590
592
  overflow: hidden;
591
593
  text-overflow: ellipsis;
592
594
  white-space: nowrap;
@@ -755,7 +757,7 @@
755
757
  cursor: pointer;
756
758
  z-index: 1;
757
759
  }
758
- .bq-attach-btn:hover:not(:disabled) { color: var(--bq-main); }
760
+ .bq-attach-btn:hover:not(:disabled) { color: var(--bq-main);transform: none; }
759
761
  .bq-attach-btn:disabled { opacity: 0.5; cursor: not-allowed; }
760
762
  .bq-attach-input { display: none; }
761
763
  .bq-input {
@@ -819,6 +821,40 @@
819
821
  pointer-events: none;
820
822
  }
821
823
  .bq-attachment.is-uploading > * { position: relative; z-index: 1; }
824
+ /* The two indeterminate phases, both drawn as a barber pole over the full chip
825
+ because neither has a percentage to show (mirror of agent.vue):
826
+ is-preparing: before the first byte-progress event, while get-signed-url
827
+ is in flight. A bar at 0% here reads as a stalled upload.
828
+ is-finalizing: bytes done, post-upload work (signed url, src:: record,
829
+ indexing dispatch) still running. A bar frozen at a solid
830
+ 100% reads as hung.
831
+ Between them the bar is determinate and driven by --att-progress. */
832
+ .bq-attachment.is-preparing::before,
833
+ .bq-attachment.is-finalizing::before {
834
+ width: 100%;
835
+ background: repeating-linear-gradient(
836
+ -45deg,
837
+ color-mix(in srgb, var(--bq-main) 22%, transparent) 0 8px,
838
+ color-mix(in srgb, var(--bq-main) 10%, transparent) 8px 16px
839
+ );
840
+ background-size: 22.6px 100%;
841
+ animation: bq-att-barber 0.8s linear infinite;
842
+ transition: none;
843
+ }
844
+ .bq-attachment.is-preparing .bq-attachment-meta::after,
845
+ .bq-attachment.is-finalizing .bq-attachment-meta::after {
846
+ content: ".";
847
+ display: inline-block;
848
+ width: 1.1em;
849
+ text-align: left;
850
+ animation: bq-att-dots 1.2s steps(1) infinite;
851
+ }
852
+ @keyframes bq-att-barber { to { background-position: 22.6px 0; } }
853
+ @keyframes bq-att-dots {
854
+ 0% { content: "."; }
855
+ 33% { content: ".."; }
856
+ 66% { content: "..."; }
857
+ }
822
858
  .bq-attachment.is-error { border-color: var(--bq-danger); background: var(--bq-danger-bg); }
823
859
  .bq-attachment.is-error .bq-attachment-meta,
824
860
  .bq-attachment.is-error .bq-attachment-name { color: var(--bq-danger); }
package/styles/chat.css CHANGED
@@ -28,19 +28,58 @@
28
28
  .bq-message.is-assistant { justify-content: flex-start; }
29
29
 
30
30
  .bq-bubble {
31
+ max-width: 100%;
31
32
  padding: 0.55rem 0.7rem;
32
33
  border: 1px solid var(--bq-line);
33
34
  white-space: pre-wrap;
34
35
  line-height: 1.45;
35
36
  font-size: 0.83rem;
36
37
  background: var(--bq-paper);
38
+ /* the house hard shadow (same as buttons/cards); themed so the edge
39
+ stays visible on a dark paper (fallback = the light value) */
40
+ box-shadow: 2px 2px var(--bq-shadow, rgba(0, 0, 0, 0.12));
37
41
  }
38
42
  .bq-bubble span { word-break: break-word; }
39
- .bq-message.is-user .bq-bubble { background: var(--bq-paper); }
40
- .bq-message.is-assistant:not(.is-error) .bq-bubble {
41
- background: var(--bq-success-bg);
42
- border-color: var(--bq-success-border);
43
+ /* User asks in the accent tint, the assistant answers on plain paper (the
44
+ base .bq-bubble already carries paper + line, so assistant needs no rule).
45
+ --bq-main-bg is the widget's own token; the admin bridges it to
46
+ --bq-pink-bg. */
47
+ .bq-message.is-user .bq-bubble {
48
+ background: var(--bq-main-bg);
49
+ /* flat: the hard shadow stays on replies only */
50
+ box-shadow: none;
43
51
  }
52
+
53
+ /* Bunny mark opening every ordinary reply: floated so it sits INSIDE the
54
+ bubble on the first text line with the copy wrapping beside it. Deliberately
55
+ absent from everything that is not a plain answer: user bubbles, error and
56
+ cancelled bubbles, indexing passes (the collapsed rows' members), and the
57
+ empty-chat greeting. Inlined data URI so both consumers get it without
58
+ markup or asset-hosting changes. */
59
+ .bq-message.is-assistant:not(.is-error):not(.is-cancelled):not(.bq-index-pass):not(.bq-empty-greeting) .bq-bubble::before {
60
+ content: "";
61
+ /* block, not float: the bunny takes the first line by itself and the
62
+ message starts on the next line below it */
63
+ display: block;
64
+ width: 2.6em;
65
+ height: 2.6em;
66
+ left: -4px;
67
+ top: -4px;
68
+ position: relative;
69
+ background: url("data:image/png;base64,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") center / contain no-repeat;
70
+ }
71
+ /* While the reply is still "Thinking..." the bubble holds only the dot-trail
72
+ loader: put the bunny INLINE with the dots instead of stacking above them.
73
+ Settled replies keep the block bunny with the message on the next line. */
74
+ .bq-message.is-assistant:not(.is-error):not(.is-cancelled):not(.bq-index-pass):not(.bq-empty-greeting) .bq-bubble:has(> .bq-loader)::before {
75
+ display: inline-block;
76
+ vertical-align: middle;
77
+ margin-right: 0.4rem;
78
+ }
79
+ .bq-message.is-assistant:not(.is-error):not(.is-cancelled):not(.bq-index-pass):not(.bq-empty-greeting) .bq-bubble:has(> .bq-loader) > .bq-loader {
80
+ vertical-align: middle;
81
+ }
82
+
44
83
  .bq-message.is-error .bq-bubble {
45
84
  background: var(--bq-danger-bg);
46
85
  border-color: var(--bq-danger);
@@ -184,6 +223,24 @@
184
223
  state does not know. A slow fade says "pending" without claiming progress. */
185
224
  .bq-index-group.is-resolving .bq-index-icon svg { animation: bq-index-fade 1.6s ease-in-out infinite; }
186
225
  @keyframes bq-index-fade { 0%, 100% { opacity: 1; } 50% { opacity: 0.35; } }
226
+ /* Expand-triggered history fetch: spinning arrows in the row head while the
227
+ run's passes are being paged in. A SEPARATE element from the status icon on
228
+ purpose — the row keeps its verdict (green check, grey clock) and this only
229
+ says "fetching more detail about it", whatever that verdict is. */
230
+ .bq-index-fetch {
231
+ width: 0.85rem;
232
+ height: 0.85rem;
233
+ flex: none;
234
+ margin-left: 0.35rem;
235
+ color: var(--bq-muted);
236
+ display: inline-flex;
237
+ }
238
+ .bq-index-fetch svg { width: 100%; height: 100%; display: block; animation: bq-index-spin 1.1s linear infinite; }
239
+ /* The in-row loading note under an OPEN row while its passes stream in. */
240
+ .bq-index-note .bq-loader { margin-left: 0.15rem; }
241
+ @media (prefers-reduced-motion: reduce) {
242
+ .bq-index-fetch svg { animation-duration: 3s; }
243
+ }
187
244
  @media (prefers-reduced-motion: reduce) {
188
245
  .bq-index-group.is-active .bq-index-icon svg { animation-duration: 3s; }
189
246
  /* A fade has no end state to settle on, so it stops rather than slows. */
@@ -221,7 +278,7 @@
221
278
  line-height: 1.3;
222
279
  letter-spacing: 0.02em;
223
280
  cursor: pointer;
224
- box-shadow: none;
281
+ box-shadow: 2px 2px rgba(0, 0, 0, 0.12);
225
282
  opacity: 0.8;
226
283
  }
227
284
  .bq-index-cancel:hover:not(.is-disabled) { background: var(--bq-warning-bg); color: var(--bq-warning); opacity: 1; }
@@ -246,6 +303,18 @@
246
303
  border-left: 2px solid var(--bq-line);
247
304
  }
248
305
  .bq-message.bq-index-pass .bq-bubble { font-size: 0.78rem; }
306
+ /* Passes inside a collapsed indexing row keep the pre-swap, flat look: no
307
+ hard shadow, requests on plain paper, responses in the success tint. The
308
+ state tints stay on top of this — error/cancelled danger and the queued
309
+ warning are excluded here so those rules keep winning. */
310
+ .bq-message.bq-index-pass .bq-bubble { box-shadow: none; }
311
+ .bq-message.bq-index-pass.is-user:not(.is-cancelled):not(.is-pending-older) .bq-bubble {
312
+ background: var(--bq-paper);
313
+ }
314
+ .bq-message.bq-index-pass.is-assistant:not(.is-error):not(.is-cancelled) .bq-bubble {
315
+ background: var(--bq-success-bg);
316
+ border-color: var(--bq-success-border);
317
+ }
249
318
  /* Close the run: the next ordinary message needs its normal breathing room.
250
319
  NOT scoped to .bq-message: the trailing loader below is a run member too, and
251
320
  requiring .bq-message would silently drop the gap whenever it is the last one. */
@@ -263,10 +332,12 @@
263
332
  font-size: 0.78rem;
264
333
  color: var(--bq-muted);
265
334
  }
266
- /* An open row animates for as long as the file is indexing, which can be minutes.
267
- Readers who ask for less motion get the static end state. */
335
+ /* An open row animates for as long as the file is indexing, which can be
336
+ minutes, and the user-side drafting bubble animates for as long as a draft
337
+ sits in the composer. Readers who ask for less motion get the static dots. */
268
338
  @media (prefers-reduced-motion: reduce) {
269
- .bq-index-tail .bq-loader::after { animation: none; content: '...'; }
339
+ .bq-index-tail .bq-loader::after,
340
+ .bq-user-drafting .bq-loader::after { animation: none; content: '...'; }
270
341
  }
271
342
  .bq-index-note {
272
343
  padding: 0 0.6rem 0.45rem;
@@ -432,3 +503,38 @@
432
503
  .bq-md strong { font-weight: 600; }
433
504
  .bq-md em { font-style: italic; }
434
505
  .bq-md del { text-decoration: line-through; }
506
+ /* ---- host-page insulation -------------------------------------------------*/
507
+ /* The markdown above renders into whatever page this chat sits in: the admin
508
+ app with its own global stylesheet, or - for the embedded widget - a HOST
509
+ page with arbitrary CSS. Element-level globals leak straight into it, and
510
+ form controls are the class nothing above styles on purpose: the admin app
511
+ styles every <input> as a 3rem bordered mono text field, which turned a GFM
512
+ task-list checkbox into a giant text box. `revert` rolls each property back
513
+ to the BROWSER default (as if no author CSS existed), which is the honest
514
+ baseline for a control the markdown produced; `initial`/`unset` would
515
+ instead strip even the user-agent's own control styling. */
516
+ .bq-md input,
517
+ .bq-md select,
518
+ .bq-md textarea,
519
+ .bq-md button {
520
+ all: revert;
521
+ }
522
+ /* GFM task list: `- [x] item` renders as a disabled checkbox in the list item.
523
+ Re-state the little we DO want on top of the revert: sit on the text
524
+ baseline with a small gap, brand accent. The geometry (width/height/
525
+ min-height/padding) is pinned explicitly, at higher specificity than the
526
+ revert rule, so a host sheet whose input rules are more specific than
527
+ `.bq-md input` still loses the properties that actually break layout. */
528
+ .bq-md input[type="checkbox"] {
529
+ width: auto;
530
+ height: auto;
531
+ min-height: 0;
532
+ padding: 0;
533
+ margin: 0 0.4em 0.1em 0;
534
+ vertical-align: middle;
535
+ accent-color: var(--bq-main);
536
+ }
537
+ /* GitHub-style: a task-list item shows the checkbox INSTEAD of a bullet, not
538
+ next to one. :has() is safe here - every supported browser ships it, and a
539
+ miss only means a redundant bullet. */
540
+ .bq-md li:has(> input[type="checkbox"]:first-child) { list-style: none; }