solid_log-ui 0.1.0

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 (63) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +295 -0
  4. data/Rakefile +12 -0
  5. data/app/assets/javascripts/application.js +6 -0
  6. data/app/assets/javascripts/solid_log/checkbox_dropdown.js +171 -0
  7. data/app/assets/javascripts/solid_log/filter_state.js +138 -0
  8. data/app/assets/javascripts/solid_log/jump_to_live.js +119 -0
  9. data/app/assets/javascripts/solid_log/live_tail.js +476 -0
  10. data/app/assets/javascripts/solid_log/live_tail.js.bak +270 -0
  11. data/app/assets/javascripts/solid_log/log_filters.js +37 -0
  12. data/app/assets/javascripts/solid_log/stream_scroll.js +195 -0
  13. data/app/assets/javascripts/solid_log/timeline_histogram.js +162 -0
  14. data/app/assets/javascripts/solid_log/toast.js +50 -0
  15. data/app/assets/stylesheets/solid_log/application.css +1329 -0
  16. data/app/assets/stylesheets/solid_log/components.css +1506 -0
  17. data/app/assets/stylesheets/solid_log/mission_control.css +398 -0
  18. data/app/channels/solid_log/ui/application_cable/channel.rb +8 -0
  19. data/app/channels/solid_log/ui/application_cable/connection.rb +10 -0
  20. data/app/channels/solid_log/ui/log_stream_channel.rb +132 -0
  21. data/app/controllers/solid_log/ui/base_controller.rb +122 -0
  22. data/app/controllers/solid_log/ui/dashboard_controller.rb +32 -0
  23. data/app/controllers/solid_log/ui/entries_controller.rb +34 -0
  24. data/app/controllers/solid_log/ui/fields_controller.rb +57 -0
  25. data/app/controllers/solid_log/ui/streams_controller.rb +204 -0
  26. data/app/controllers/solid_log/ui/timelines_controller.rb +29 -0
  27. data/app/controllers/solid_log/ui/tokens_controller.rb +46 -0
  28. data/app/helpers/solid_log/ui/application_helper.rb +99 -0
  29. data/app/helpers/solid_log/ui/dashboard_helper.rb +46 -0
  30. data/app/helpers/solid_log/ui/entries_helper.rb +16 -0
  31. data/app/helpers/solid_log/ui/timeline_helper.rb +39 -0
  32. data/app/services/solid_log/ui/live_tail_broadcaster.rb +81 -0
  33. data/app/views/layouts/solid_log/ui/application.html.erb +53 -0
  34. data/app/views/solid_log/ui/dashboard/index.html.erb +178 -0
  35. data/app/views/solid_log/ui/entries/show.html.erb +132 -0
  36. data/app/views/solid_log/ui/fields/index.html.erb +133 -0
  37. data/app/views/solid_log/ui/shared/_checkbox_dropdown.html.erb +64 -0
  38. data/app/views/solid_log/ui/shared/_multiselect_filter.html.erb +37 -0
  39. data/app/views/solid_log/ui/shared/_toast.html.erb +7 -0
  40. data/app/views/solid_log/ui/shared/_toast_message.html.erb +30 -0
  41. data/app/views/solid_log/ui/streams/_filter_form.html.erb +207 -0
  42. data/app/views/solid_log/ui/streams/_footer.html.erb +37 -0
  43. data/app/views/solid_log/ui/streams/_log_entries.html.erb +5 -0
  44. data/app/views/solid_log/ui/streams/_log_row.html.erb +5 -0
  45. data/app/views/solid_log/ui/streams/_log_row_compact.html.erb +37 -0
  46. data/app/views/solid_log/ui/streams/_log_row_expanded.html.erb +67 -0
  47. data/app/views/solid_log/ui/streams/_log_stream_content.html.erb +8 -0
  48. data/app/views/solid_log/ui/streams/_timeline.html.erb +68 -0
  49. data/app/views/solid_log/ui/streams/index.html.erb +22 -0
  50. data/app/views/solid_log/ui/timelines/show_job.html.erb +78 -0
  51. data/app/views/solid_log/ui/timelines/show_request.html.erb +88 -0
  52. data/app/views/solid_log/ui/tokens/index.html.erb +95 -0
  53. data/app/views/solid_log/ui/tokens/new.html.erb +47 -0
  54. data/config/importmap.rb +15 -0
  55. data/config/routes.rb +27 -0
  56. data/lib/solid_log/ui/api_client.rb +117 -0
  57. data/lib/solid_log/ui/configuration.rb +99 -0
  58. data/lib/solid_log/ui/data_source.rb +146 -0
  59. data/lib/solid_log/ui/engine.rb +76 -0
  60. data/lib/solid_log/ui/version.rb +5 -0
  61. data/lib/solid_log/ui.rb +27 -0
  62. data/lib/solid_log-ui.rb +2 -0
  63. metadata +290 -0
@@ -0,0 +1,1506 @@
1
+ /* Component Styles */
2
+
3
+ /* Badges */
4
+ .badge {
5
+ display: inline-block;
6
+ padding: 0.25rem 0.5rem;
7
+ font-size: 0.75rem;
8
+ font-weight: 600;
9
+ line-height: 1;
10
+ border-radius: 0.25rem;
11
+ text-transform: uppercase;
12
+ }
13
+
14
+ .badge-blue {
15
+ background: #dbeafe;
16
+ color: #1e40af;
17
+ }
18
+
19
+ .badge-gray {
20
+ background: #f3f4f6;
21
+ color: #4b5563;
22
+ }
23
+
24
+ .badge-yellow {
25
+ background: #fef3c7;
26
+ color: #92400e;
27
+ }
28
+
29
+ .badge-red {
30
+ background: #fee2e2;
31
+ color: #991b1b;
32
+ }
33
+
34
+ .badge-dark-red {
35
+ background: #7f1d1d;
36
+ color: #fecaca;
37
+ }
38
+
39
+ .badge-success {
40
+ background: #d1fae5;
41
+ color: #065f46;
42
+ }
43
+
44
+ .badge-info {
45
+ background: #dbeafe;
46
+ color: #1e40af;
47
+ }
48
+
49
+ .badge-warning {
50
+ background: #fef3c7;
51
+ color: #92400e;
52
+ }
53
+
54
+ .badge-danger {
55
+ background: #fee2e2;
56
+ color: #991b1b;
57
+ }
58
+
59
+ .badge-secondary {
60
+ background: #f3f4f6;
61
+ color: #6b7280;
62
+ }
63
+
64
+ /* Log level badges */
65
+ .badge-debug {
66
+ background: #f3f4f6;
67
+ color: #4b5563;
68
+ }
69
+
70
+ .badge-error {
71
+ background: #fee2e2;
72
+ color: #991b1b;
73
+ }
74
+
75
+ .badge-fatal {
76
+ background: #7f1d1d;
77
+ color: #fecaca;
78
+ }
79
+
80
+ .badge-default {
81
+ background: #f3f4f6;
82
+ color: #6b7280;
83
+ }
84
+
85
+ /* Buttons */
86
+ .btn {
87
+ display: inline-block;
88
+ padding: 0.5rem 1rem;
89
+ font-size: 0.875rem;
90
+ font-weight: 500;
91
+ line-height: 1.5;
92
+ text-align: center;
93
+ text-decoration: none;
94
+ border: 1px solid transparent;
95
+ border-radius: var(--border-radius);
96
+ cursor: pointer;
97
+ transition: all 0.15s ease;
98
+ }
99
+
100
+ .btn-primary {
101
+ background: var(--color-primary);
102
+ color: white;
103
+ border-color: var(--color-primary);
104
+ }
105
+
106
+ .btn-primary:hover {
107
+ background: #1d4ed8;
108
+ border-color: #1d4ed8;
109
+ }
110
+
111
+ .btn-secondary {
112
+ background: white;
113
+ color: var(--color-gray-700);
114
+ border-color: var(--color-gray-300);
115
+ }
116
+
117
+ .btn-secondary:hover {
118
+ background: var(--color-gray-50);
119
+ }
120
+
121
+ .btn-disabled,
122
+ .btn:disabled,
123
+ button:disabled {
124
+ opacity: 0.5;
125
+ cursor: not-allowed;
126
+ pointer-events: none;
127
+ }
128
+
129
+ .btn-block {
130
+ display: block;
131
+ width: 100%;
132
+ box-sizing: border-box;
133
+ }
134
+
135
+ .btn-link {
136
+ color: var(--color-primary);
137
+ text-decoration: none;
138
+ font-size: 0.875rem;
139
+ }
140
+
141
+ .btn-link:hover {
142
+ text-decoration: underline;
143
+ }
144
+
145
+ /* Forms */
146
+ .form-input,
147
+ .form-select {
148
+ width: 100%;
149
+ padding: 0.5rem 0.75rem;
150
+ font-size: 0.875rem;
151
+ line-height: 1.5;
152
+ color: var(--color-gray-900);
153
+ background: white;
154
+ border: 1px solid var(--color-gray-300);
155
+ border-radius: var(--border-radius);
156
+ box-sizing: border-box;
157
+ }
158
+
159
+ .form-input:focus,
160
+ .form-select:focus {
161
+ outline: none;
162
+ border-color: var(--color-primary);
163
+ box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1);
164
+ }
165
+
166
+ .form-input-small {
167
+ font-size: 0.8125rem;
168
+ padding: 0.375rem 0.625rem;
169
+ }
170
+
171
+ /* Checkbox */
172
+ .checkbox-item {
173
+ display: flex;
174
+ align-items: center;
175
+ gap: 0.5rem;
176
+ padding: 0.25rem 0;
177
+ }
178
+
179
+ .checkbox-item input[type="checkbox"] {
180
+ width: 1rem;
181
+ height: 1rem;
182
+ cursor: pointer;
183
+ }
184
+
185
+ .checkbox-item label {
186
+ cursor: pointer;
187
+ margin: 0;
188
+ display: flex;
189
+ align-items: center;
190
+ }
191
+
192
+ /* Checkbox Dropdown - Portal/Popover Style */
193
+ .checkbox-dropdown-portal {
194
+ position: relative;
195
+ width: 100%;
196
+ }
197
+
198
+ .checkbox-dropdown-toggle {
199
+ width: 100%;
200
+ display: flex;
201
+ align-items: center;
202
+ justify-content: space-between;
203
+ padding: 0.5rem 0.75rem;
204
+ font-size: 0.875rem;
205
+ line-height: 1.5;
206
+ color: var(--color-gray-900);
207
+ background: white;
208
+ border: 1px solid var(--color-gray-300);
209
+ border-radius: var(--border-radius);
210
+ cursor: pointer;
211
+ text-align: left;
212
+ transition: border-color 0.15s ease;
213
+ }
214
+
215
+ .dropdown-toggle-content {
216
+ display: flex;
217
+ align-items: center;
218
+ gap: 0.5rem;
219
+ flex: 1;
220
+ min-width: 0;
221
+ }
222
+
223
+ .dropdown-label {
224
+ flex: 1;
225
+ min-width: 0;
226
+ overflow: hidden;
227
+ text-overflow: ellipsis;
228
+ white-space: nowrap;
229
+ }
230
+
231
+ .dropdown-label-placeholder {
232
+ color: var(--color-gray-500);
233
+ font-style: italic;
234
+ }
235
+
236
+ .checkbox-dropdown-toggle:hover {
237
+ border-color: var(--color-gray-400);
238
+ }
239
+
240
+ .checkbox-dropdown-toggle[aria-expanded="true"] {
241
+ border-color: var(--color-primary);
242
+ box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1);
243
+ }
244
+
245
+ .checkbox-dropdown-toggle .badge-small {
246
+ display: inline-block;
247
+ min-width: 1.25rem;
248
+ padding: 0.125rem 0.375rem;
249
+ font-size: 0.75rem;
250
+ font-weight: 600;
251
+ margin-right: 4px;
252
+ line-height: 1;
253
+ text-align: center;
254
+ background: var(--color-primary);
255
+ color: white;
256
+ border-radius: 0.75rem;
257
+ flex-shrink: 0;
258
+ }
259
+
260
+ .dropdown-arrow {
261
+ color: var(--color-gray-600);
262
+ font-size: 0.75rem;
263
+ flex-shrink: 0;
264
+ transition: transform 0.2s ease;
265
+ }
266
+
267
+ .checkbox-dropdown-toggle[aria-expanded="true"] .dropdown-arrow {
268
+ transform: rotate(180deg);
269
+ }
270
+
271
+ /* Popover - Spans Full Sidebar Width */
272
+ .checkbox-dropdown-popover {
273
+ position: absolute;
274
+ left: 0;
275
+ right: 0;
276
+ top: 100%; /* Below the toggle button */
277
+ background: white;
278
+ border: 1px solid var(--color-gray-300);
279
+ border-radius: var(--border-radius);
280
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
281
+ z-index: 9999;
282
+ display: flex;
283
+ flex-direction: column;
284
+ max-height: 400px;
285
+ margin-top: 4px;
286
+ }
287
+
288
+ .popover-header {
289
+ display: flex;
290
+ align-items: center;
291
+ justify-content: space-between;
292
+ padding: var(--spacing-md) var(--spacing-lg);
293
+ border-bottom: 1px solid var(--color-gray-200);
294
+ background: var(--color-gray-50);
295
+ }
296
+
297
+ .popover-header h4 {
298
+ margin: 0;
299
+ font-size: 1rem;
300
+ font-weight: 600;
301
+ color: var(--color-gray-900);
302
+ }
303
+
304
+ .popover-close {
305
+ background: none;
306
+ border: none;
307
+ font-size: 1.5rem;
308
+ line-height: 1;
309
+ color: var(--color-gray-600);
310
+ cursor: pointer;
311
+ padding: 0;
312
+ width: 1.5rem;
313
+ height: 1.5rem;
314
+ display: flex;
315
+ align-items: center;
316
+ justify-content: center;
317
+ transition: color 0.15s ease;
318
+ }
319
+
320
+ .popover-close:hover {
321
+ color: var(--color-gray-900);
322
+ }
323
+
324
+ .popover-search {
325
+ padding: var(--spacing-md) var(--spacing-lg);
326
+ border-bottom: 1px solid var(--color-gray-200);
327
+ }
328
+
329
+ .popover-search .form-input {
330
+ margin: 0;
331
+ }
332
+
333
+ .popover-options {
334
+ overflow-y: auto;
335
+ padding: var(--spacing-md) var(--spacing-lg);
336
+ flex: 1;
337
+ max-height: 300px;
338
+ }
339
+
340
+ .popover-options .checkbox-item {
341
+ padding: 0.375rem 0.5rem;
342
+ border-radius: var(--border-radius);
343
+ transition: background 0.1s ease;
344
+ }
345
+
346
+ .popover-options .checkbox-item:hover {
347
+ background: var(--color-gray-50);
348
+ }
349
+
350
+ .popover-footer {
351
+ padding: var(--spacing-md) var(--spacing-lg);
352
+ border-top: 1px solid var(--color-gray-200);
353
+ background: white;
354
+ }
355
+
356
+ /* Streams Page */
357
+ .streams-page {
358
+ height: calc(100vh - 120px); /* Full height minus nav (60px), footer (~50px), and stream footer margin (10px) */
359
+ display: flex;
360
+ flex-direction: column;
361
+ }
362
+
363
+ .streams-container {
364
+ display: grid;
365
+ grid-template-columns: 420px 1fr;
366
+ height: 100%;
367
+ overflow: hidden;
368
+ position: relative;
369
+ gap: 10px;
370
+ padding: 10px;
371
+ padding-bottom: 0;
372
+ }
373
+
374
+ .streams-sidebar {
375
+ background: white;
376
+ border: 1px solid var(--color-gray-200);
377
+ border-radius: 8px;
378
+ display: flex;
379
+ flex-direction: column;
380
+ min-height: 0;
381
+ }
382
+
383
+ .streams-main {
384
+ padding: 0;
385
+ display: flex;
386
+ flex-direction: column;
387
+ gap: var(--spacing-md);
388
+ min-height: 0;
389
+ }
390
+
391
+ /* Stream Footer - Inline in Terminal View */
392
+ .stream-footer-inline {
393
+ display: flex;
394
+ align-items: center;
395
+ gap: var(--spacing-lg);
396
+ padding: var(--spacing-md);
397
+ background: white;
398
+ border: 1px solid var(--color-gray-200);
399
+ border-radius: 8px;
400
+ flex-shrink: 0;
401
+ }
402
+
403
+ #timeline-container {
404
+ flex: 1;
405
+ min-width: 0;
406
+ }
407
+
408
+ .stream-footer-controls {
409
+ display: flex;
410
+ flex-direction: column;
411
+ align-items: stretch;
412
+ gap: var(--spacing-sm);
413
+ margin-left: auto;
414
+ min-width: 120px;
415
+ }
416
+
417
+ /* Filter Form */
418
+ .filter-form {
419
+ display: flex;
420
+ flex-direction: column;
421
+ flex: 1;
422
+ min-height: 0;
423
+ }
424
+
425
+ .filter-form form {
426
+ display: flex;
427
+ flex-direction: column;
428
+ flex: 1;
429
+ min-height: 0;
430
+ }
431
+
432
+ .filter-form-content {
433
+ flex: 1;
434
+ overflow-y: auto;
435
+ padding: var(--spacing-lg);
436
+ display: flex;
437
+ flex-direction: column;
438
+ gap: var(--spacing-lg);
439
+ }
440
+
441
+ .filter-form h3 {
442
+ margin: 0;
443
+ padding: var(--spacing-lg);
444
+ padding-bottom: var(--spacing-md);
445
+ font-size: 1.125rem;
446
+ font-weight: 600;
447
+ flex-shrink: 0;
448
+ }
449
+
450
+ .filter-group {
451
+ display: flex;
452
+ flex-direction: column;
453
+ gap: var(--spacing-sm);
454
+ }
455
+
456
+ .filter-group label {
457
+ font-size: 0.875rem;
458
+ font-weight: 500;
459
+ color: var(--color-gray-700);
460
+ }
461
+
462
+ .time-inputs {
463
+ display: flex;
464
+ flex-direction: column;
465
+ gap: var(--spacing-sm);
466
+ }
467
+
468
+ .filter-actions {
469
+ display: flex;
470
+ flex-direction: column;
471
+ gap: var(--spacing-sm);
472
+ padding: var(--spacing-lg);
473
+ padding-bottom: 0;
474
+ background: white;
475
+ flex-shrink: 0;
476
+ }
477
+
478
+ /* Timeline Histogram */
479
+ .timeline-histogram {
480
+ background: transparent;
481
+ border: none;
482
+ border-radius: 0;
483
+ padding: var(--spacing-sm) 0;
484
+ margin-bottom: 0;
485
+ flex: 1;
486
+ min-width: 0; /* Allow shrinking */
487
+ }
488
+
489
+ .timeline-header-row {
490
+ display: flex;
491
+ justify-content: space-between;
492
+ align-items: center;
493
+ margin-bottom: var(--spacing-sm);
494
+ }
495
+
496
+ .timeline-header-row h3 {
497
+ margin: 0;
498
+ font-size: 0.8125rem;
499
+ font-weight: 500;
500
+ color: #888;
501
+ }
502
+
503
+ .timeline-info {
504
+ display: flex;
505
+ align-items: center;
506
+ gap: var(--spacing-md);
507
+ }
508
+
509
+ .timeline-range {
510
+ font-size: 0.75rem;
511
+ color: #666;
512
+ font-family: "SF Mono", Monaco, "Cascadia Code", "Roboto Mono", Consolas, monospace;
513
+ }
514
+
515
+ .timeline-chart {
516
+ position: relative;
517
+ height: 60px;
518
+ max-height: 80px;
519
+ background: rgba(255, 255, 255, 0.03);
520
+ border-radius: var(--border-radius);
521
+ overflow: hidden;
522
+ }
523
+
524
+ .timeline-bars {
525
+ display: flex;
526
+ align-items: flex-end;
527
+ height: 100%;
528
+ gap: 1px;
529
+ padding: 0.5rem;
530
+ }
531
+
532
+ .timeline-bar-wrapper {
533
+ flex: 1;
534
+ height: 100%;
535
+ display: flex;
536
+ align-items: flex-end;
537
+ cursor: pointer;
538
+ position: relative;
539
+ }
540
+
541
+ .timeline-bar {
542
+ width: 100%;
543
+ background: var(--color-primary);
544
+ opacity: 0.6;
545
+ transition: opacity 0.1s ease;
546
+ min-height: 2px;
547
+ border-radius: 2px 2px 0 0;
548
+ }
549
+
550
+ .timeline-bar-wrapper:hover .timeline-bar {
551
+ opacity: 0.9;
552
+ }
553
+
554
+ .timeline-bar-wrapper.selected .timeline-bar {
555
+ background: #10b981;
556
+ opacity: 1;
557
+ }
558
+
559
+ .timeline-selection {
560
+ position: absolute;
561
+ top: 0;
562
+ bottom: 0;
563
+ background: rgba(16, 185, 129, 0.2);
564
+ border: 2px solid #10b981;
565
+ pointer-events: none;
566
+ z-index: 10;
567
+ }
568
+
569
+ .timeline-tooltip {
570
+ position: absolute;
571
+ transform: translate(-50%, -100%);
572
+ background: var(--color-gray-900);
573
+ color: white;
574
+ padding: 0.375rem 0.5rem;
575
+ border-radius: var(--border-radius);
576
+ font-size: 0.75rem;
577
+ white-space: nowrap;
578
+ pointer-events: none;
579
+ z-index: 1000;
580
+ box-shadow: var(--shadow-lg);
581
+ }
582
+
583
+ .timeline-tooltip::after {
584
+ content: '';
585
+ position: absolute;
586
+ top: 100%;
587
+ left: 50%;
588
+ transform: translateX(-50%);
589
+ border: 4px solid transparent;
590
+ border-top-color: var(--color-gray-900);
591
+ }
592
+
593
+ .tooltip-time {
594
+ font-family: "SF Mono", Monaco, "Cascadia Code", "Roboto Mono", Consolas, monospace;
595
+ margin-bottom: 0.125rem;
596
+ }
597
+
598
+ .tooltip-count {
599
+ font-weight: 600;
600
+ }
601
+
602
+ /* Streams Toolbar */
603
+ .streams-toolbar {
604
+ display: flex;
605
+ justify-content: space-between;
606
+ align-items: center;
607
+ padding: var(--spacing-md);
608
+ background: white;
609
+ border: 1px solid var(--color-gray-200);
610
+ border-radius: var(--border-radius);
611
+ margin-bottom: var(--spacing-lg);
612
+ }
613
+
614
+ .streams-count {
615
+ font-size: 0.875rem;
616
+ color: var(--color-gray-700);
617
+ }
618
+
619
+ .streams-actions {
620
+ display: flex;
621
+ gap: var(--spacing-sm);
622
+ }
623
+
624
+ #live-tail-toggle.active {
625
+ background: var(--color-success);
626
+ border-color: var(--color-success);
627
+ color: white;
628
+ }
629
+
630
+ #live-tail-toggle.active:hover {
631
+ background: #059669;
632
+ border-color: #059669;
633
+ }
634
+
635
+ /* Log Stream */
636
+ .log-stream {
637
+ flex: 1;
638
+ min-height: 0;
639
+ overflow-y: auto;
640
+ display: flex;
641
+ flex-direction: column;
642
+ gap: 0;
643
+ background: #1a1a1a; /* Terminal dark background */
644
+ border: 1px solid #333;
645
+ border-radius: var(--border-radius);
646
+ overflow-y: auto;
647
+ overflow-x: hidden;
648
+ font-family: "SF Mono", Monaco, "Cascadia Code", "Roboto Mono", Consolas, "Courier New", monospace;
649
+ font-size: 0.8125rem;
650
+ line-height: 1.5;
651
+ padding: 0.5rem;
652
+ flex: 1;
653
+ min-height: 0;
654
+ }
655
+
656
+ /* Compact Log Row - Terminal Style */
657
+ .log-row-compact-wrapper {
658
+ display: flex;
659
+ align-items: flex-start;
660
+ gap: 0.25rem;
661
+ padding: 0.125rem 0.5rem;
662
+ background: transparent;
663
+ transition: background 0.1s ease;
664
+ line-height: 1.5;
665
+ flex-wrap: wrap;
666
+ min-height: calc(1.5em + 0.25rem); /* At least 1 line + padding */
667
+ max-height: calc((1.5em * 3) + 0.25rem); /* 3 lines max + padding */
668
+ overflow: hidden;
669
+ }
670
+
671
+ .log-row-compact-wrapper:hover {
672
+ background: rgba(255, 255, 255, 0.05);
673
+ }
674
+
675
+ .log-filter-btn {
676
+ background: none;
677
+ border: none;
678
+ padding: 0;
679
+ margin: 0;
680
+ font-family: inherit;
681
+ font-size: inherit;
682
+ color: #888;
683
+ cursor: pointer;
684
+ transition: color 0.1s ease;
685
+ white-space: nowrap;
686
+ flex-shrink: 0;
687
+ }
688
+
689
+ .log-filter-btn:hover {
690
+ color: #60a5fa;
691
+ }
692
+
693
+ .log-row-compact-message {
694
+ color: #e4e4e4;
695
+ text-decoration: none;
696
+ cursor: pointer;
697
+ transition: color 0.1s ease;
698
+ display: inline;
699
+ }
700
+
701
+ .log-row-compact-message:hover {
702
+ color: #fff;
703
+ }
704
+
705
+ .log-row-timestamp {
706
+ color: #666;
707
+ flex-shrink: 0;
708
+ margin-right: 0.5rem;
709
+ }
710
+
711
+ /* Loading Indicator */
712
+ .loading-indicator {
713
+ text-align: center;
714
+ padding: var(--spacing-md);
715
+ background: rgba(255, 255, 255, 0.05);
716
+ color: #888;
717
+ font-size: 0.875rem;
718
+ font-family: "SF Mono", Monaco, "Cascadia Code", "Roboto Mono", Consolas, monospace;
719
+ animation: pulse 1.5s ease-in-out infinite;
720
+ }
721
+
722
+ @keyframes pulse {
723
+ 0%, 100% { opacity: 0.5; }
724
+ 50% { opacity: 1; }
725
+ }
726
+
727
+ /* Legacy log row styles (for details page if needed) */
728
+ .log-row {
729
+ background: white;
730
+ border: 1px solid var(--color-gray-200);
731
+ border-radius: var(--border-radius);
732
+ padding: var(--spacing-md);
733
+ transition: box-shadow 0.15s ease;
734
+ }
735
+
736
+ .log-row:hover {
737
+ box-shadow: var(--shadow-md);
738
+ }
739
+
740
+ .log-row-header {
741
+ display: flex;
742
+ justify-content: space-between;
743
+ align-items: center;
744
+ margin-bottom: var(--spacing-sm);
745
+ }
746
+
747
+ .log-row-meta {
748
+ display: flex;
749
+ align-items: center;
750
+ gap: var(--spacing-sm);
751
+ flex-wrap: wrap;
752
+ }
753
+
754
+ .log-timestamp {
755
+ font-size: 0.8125rem;
756
+ color: var(--color-gray-700);
757
+ font-family: "SF Mono", Monaco, "Cascadia Code", "Roboto Mono", Consolas, monospace;
758
+ }
759
+
760
+ .log-app,
761
+ .log-env {
762
+ font-size: 0.75rem;
763
+ padding: 0.125rem 0.375rem;
764
+ background: var(--color-gray-100);
765
+ border-radius: 0.25rem;
766
+ color: var(--color-gray-700);
767
+ }
768
+
769
+ .log-row-content {
770
+ display: flex;
771
+ flex-direction: column;
772
+ gap: var(--spacing-sm);
773
+ }
774
+
775
+ .log-message {
776
+ font-size: 0.875rem;
777
+ line-height: 1.6;
778
+ color: var(--color-gray-900);
779
+ word-break: break-word;
780
+ }
781
+
782
+ .log-message mark {
783
+ background: #fef08a;
784
+ padding: 0.125rem 0.25rem;
785
+ border-radius: 0.125rem;
786
+ }
787
+
788
+ .log-details {
789
+ display: flex;
790
+ flex-wrap: wrap;
791
+ gap: var(--spacing-md);
792
+ font-size: 0.8125rem;
793
+ color: var(--color-gray-700);
794
+ }
795
+
796
+ .log-detail-item {
797
+ display: flex;
798
+ gap: 0.25rem;
799
+ }
800
+
801
+ .log-detail-link {
802
+ color: var(--color-primary);
803
+ text-decoration: none;
804
+ }
805
+
806
+ .log-detail-link:hover {
807
+ text-decoration: underline;
808
+ }
809
+
810
+ .log-correlation {
811
+ display: flex;
812
+ gap: var(--spacing-sm);
813
+ font-size: 0.75rem;
814
+ }
815
+
816
+ .correlation-link {
817
+ color: var(--color-primary);
818
+ text-decoration: none;
819
+ padding: 0.25rem 0.5rem;
820
+ background: var(--color-gray-100);
821
+ border-radius: 0.25rem;
822
+ }
823
+
824
+ .correlation-link:hover {
825
+ background: var(--color-gray-200);
826
+ }
827
+
828
+ /* Entry Detail */
829
+ .entry-detail {
830
+ max-width: 1200px;
831
+ margin: 0 auto;
832
+ padding: var(--spacing-xl);
833
+ }
834
+
835
+ .entry-detail-content {
836
+ display: flex;
837
+ flex-direction: column;
838
+ gap: var(--spacing-lg);
839
+ }
840
+
841
+ .metadata-list {
842
+ display: grid;
843
+ grid-template-columns: 150px 1fr;
844
+ gap: var(--spacing-md);
845
+ }
846
+
847
+ .metadata-list dt {
848
+ font-weight: 600;
849
+ color: var(--color-gray-700);
850
+ }
851
+
852
+ .metadata-list dd {
853
+ margin: 0;
854
+ color: var(--color-gray-900);
855
+ }
856
+
857
+ .metadata-link {
858
+ color: var(--color-primary);
859
+ text-decoration: none;
860
+ font-size: 0.875rem;
861
+ margin-left: var(--spacing-sm);
862
+ }
863
+
864
+ .metadata-link:hover {
865
+ text-decoration: underline;
866
+ }
867
+
868
+ .log-message-full {
869
+ white-space: pre-wrap;
870
+ word-break: break-word;
871
+ margin: 0;
872
+ padding: var(--spacing-md);
873
+ background: var(--color-gray-50);
874
+ border-radius: var(--border-radius);
875
+ font-family: "SF Mono", Monaco, "Cascadia Code", "Roboto Mono", Consolas, monospace;
876
+ font-size: 0.875rem;
877
+ line-height: 1.6;
878
+ }
879
+
880
+ .json-display {
881
+ white-space: pre;
882
+ margin: 0;
883
+ padding: var(--spacing-md);
884
+ background: var(--color-gray-900);
885
+ color: #d4d4d4;
886
+ border-radius: var(--border-radius);
887
+ font-family: "SF Mono", Monaco, "Cascadia Code", "Roboto Mono", Consolas, monospace;
888
+ font-size: 0.8125rem;
889
+ line-height: 1.6;
890
+ overflow-x: auto;
891
+ }
892
+
893
+ /* Empty State */
894
+ .empty-state-large {
895
+ text-align: center;
896
+ padding: var(--spacing-xl) * 2;
897
+ }
898
+
899
+ .empty-state-large h2 {
900
+ font-size: 1.5rem;
901
+ margin: 0 0 var(--spacing-md) 0;
902
+ color: var(--color-gray-900);
903
+ }
904
+
905
+ .empty-state-large p {
906
+ color: var(--color-gray-700);
907
+ margin-bottom: var(--spacing-lg);
908
+ }
909
+
910
+ /* Timeline Styles */
911
+ .timeline-page {
912
+ max-width: 1200px;
913
+ margin: 0 auto;
914
+ padding: var(--spacing-xl);
915
+ }
916
+
917
+ .timeline-container {
918
+ display: flex;
919
+ flex-direction: column;
920
+ gap: var(--spacing-lg);
921
+ }
922
+
923
+ .timeline-stats {
924
+ display: flex;
925
+ gap: var(--spacing-lg);
926
+ flex-wrap: wrap;
927
+ padding: var(--spacing-md);
928
+ background: white;
929
+ border: 1px solid var(--color-gray-200);
930
+ border-radius: var(--border-radius);
931
+ }
932
+
933
+ .stat-inline {
934
+ display: flex;
935
+ align-items: center;
936
+ gap: var(--spacing-sm);
937
+ }
938
+
939
+ .stat-inline-label {
940
+ font-size: 0.875rem;
941
+ color: var(--color-gray-700);
942
+ }
943
+
944
+ .stat-inline-value {
945
+ font-size: 0.875rem;
946
+ font-weight: 600;
947
+ color: var(--color-gray-900);
948
+ }
949
+
950
+ .timeline-entries {
951
+ display: flex;
952
+ flex-direction: column;
953
+ }
954
+
955
+ .timeline-entry {
956
+ display: flex;
957
+ gap: var(--spacing-md);
958
+ }
959
+
960
+ .timeline-marker {
961
+ display: flex;
962
+ flex-direction: column;
963
+ align-items: center;
964
+ padding-top: 0.375rem;
965
+ }
966
+
967
+ .timeline-dot {
968
+ width: 12px;
969
+ height: 12px;
970
+ border-radius: 50%;
971
+ border: 2px solid white;
972
+ box-shadow: 0 0 0 2px var(--color-gray-300);
973
+ }
974
+
975
+ .timeline-dot.debug { box-shadow: 0 0 0 2px var(--color-gray-300); background: var(--color-gray-300); }
976
+ .timeline-dot.info { box-shadow: 0 0 0 2px var(--color-info); background: var(--color-info); }
977
+ .timeline-dot.warn { box-shadow: 0 0 0 2px var(--color-warning); background: var(--color-warning); }
978
+ .timeline-dot.error { box-shadow: 0 0 0 2px var(--color-danger); background: var(--color-danger); }
979
+ .timeline-dot.fatal { box-shadow: 0 0 0 2px #7f1d1d; background: #7f1d1d; }
980
+
981
+ .timeline-line {
982
+ width: 2px;
983
+ flex: 1;
984
+ background: var(--color-gray-200);
985
+ min-height: 40px;
986
+ }
987
+
988
+ .timeline-content {
989
+ flex: 1;
990
+ padding-bottom: var(--spacing-lg);
991
+ }
992
+
993
+ .timeline-header {
994
+ display: flex;
995
+ align-items: center;
996
+ gap: var(--spacing-sm);
997
+ margin-bottom: var(--spacing-sm);
998
+ }
999
+
1000
+ .timeline-time {
1001
+ font-family: "SF Mono", Monaco, "Cascadia Code", "Roboto Mono", Consolas, monospace;
1002
+ font-size: 0.8125rem;
1003
+ color: var(--color-gray-700);
1004
+ font-weight: 500;
1005
+ }
1006
+
1007
+ .timeline-delta {
1008
+ color: var(--color-gray-600);
1009
+ font-size: 0.75rem;
1010
+ margin-left: 0.5rem;
1011
+ }
1012
+
1013
+ .timeline-message {
1014
+ font-size: 0.875rem;
1015
+ line-height: 1.6;
1016
+ color: var(--color-gray-900);
1017
+ margin-bottom: var(--spacing-sm);
1018
+ word-break: break-word;
1019
+ }
1020
+
1021
+ .timeline-meta {
1022
+ display: flex;
1023
+ flex-wrap: wrap;
1024
+ gap: var(--spacing-md);
1025
+ font-size: 0.8125rem;
1026
+ color: var(--color-gray-700);
1027
+ margin-bottom: var(--spacing-sm);
1028
+ }
1029
+
1030
+ .timeline-actions {
1031
+ font-size: 0.875rem;
1032
+ }
1033
+
1034
+ .timeline-details summary {
1035
+ cursor: pointer;
1036
+ font-size: 0.875rem;
1037
+ color: var(--color-primary);
1038
+ margin: var(--spacing-sm) 0;
1039
+ }
1040
+
1041
+ .json-display-small {
1042
+ font-size: 0.75rem;
1043
+ padding: var(--spacing-sm);
1044
+ margin: var(--spacing-sm) 0;
1045
+ }
1046
+
1047
+ /* Fields Page */
1048
+ .fields-page,
1049
+ .tokens-page {
1050
+ max-width: 1400px;
1051
+ margin: 0 auto;
1052
+ padding: var(--spacing-xl);
1053
+ }
1054
+
1055
+ .fields-container,
1056
+ .tokens-container {
1057
+ display: flex;
1058
+ flex-direction: column;
1059
+ gap: var(--spacing-lg);
1060
+ }
1061
+
1062
+ .fields-stats {
1063
+ display: flex;
1064
+ gap: var(--spacing-lg);
1065
+ flex-wrap: wrap;
1066
+ }
1067
+
1068
+ .stat-card-inline {
1069
+ background: white;
1070
+ border: 1px solid var(--color-gray-200);
1071
+ border-radius: var(--border-radius);
1072
+ padding: var(--spacing-md);
1073
+ min-width: 200px;
1074
+ }
1075
+
1076
+ .stat-card-inline .stat-label {
1077
+ font-size: 0.875rem;
1078
+ color: var(--color-gray-700);
1079
+ margin-bottom: 0.25rem;
1080
+ }
1081
+
1082
+ .stat-card-inline .stat-value {
1083
+ font-size: 1.5rem;
1084
+ font-weight: 700;
1085
+ color: var(--color-gray-900);
1086
+ }
1087
+
1088
+ .data-table {
1089
+ width: 100%;
1090
+ border-collapse: collapse;
1091
+ }
1092
+
1093
+ .data-table thead {
1094
+ background: var(--color-gray-50);
1095
+ border-bottom: 2px solid var(--color-gray-200);
1096
+ }
1097
+
1098
+ .data-table th {
1099
+ padding: 0.75rem 1rem;
1100
+ text-align: left;
1101
+ font-size: 0.875rem;
1102
+ font-weight: 600;
1103
+ color: var(--color-gray-700);
1104
+ }
1105
+
1106
+ .data-table td {
1107
+ padding: 0.75rem 1rem;
1108
+ font-size: 0.875rem;
1109
+ border-bottom: 1px solid var(--color-gray-200);
1110
+ }
1111
+
1112
+ .data-table tbody tr:hover {
1113
+ background: var(--color-gray-50);
1114
+ }
1115
+
1116
+ .field-promoted {
1117
+ background: #f0fdf4;
1118
+ }
1119
+
1120
+ .field-name code {
1121
+ font-family: "SF Mono", Monaco, "Cascadia Code", "Roboto Mono", Consolas, monospace;
1122
+ font-size: 0.8125rem;
1123
+ color: var(--color-gray-900);
1124
+ background: var(--color-gray-100);
1125
+ padding: 0.125rem 0.375rem;
1126
+ border-radius: 0.25rem;
1127
+ }
1128
+
1129
+ .text-right {
1130
+ text-align: right;
1131
+ }
1132
+
1133
+ .text-danger {
1134
+ color: var(--color-danger) !important;
1135
+ }
1136
+
1137
+ .text-muted {
1138
+ color: var(--color-gray-600);
1139
+ }
1140
+
1141
+ .table-actions {
1142
+ display: flex;
1143
+ gap: var(--spacing-sm);
1144
+ }
1145
+
1146
+ .btn-link-small {
1147
+ font-size: 0.8125rem;
1148
+ color: var(--color-primary);
1149
+ text-decoration: none;
1150
+ background: none;
1151
+ border: none;
1152
+ cursor: pointer;
1153
+ padding: 0.25rem 0.5rem;
1154
+ }
1155
+
1156
+ .btn-link-small:hover {
1157
+ text-decoration: underline;
1158
+ }
1159
+
1160
+ .field-help,
1161
+ .token-help,
1162
+ .info-card {
1163
+ background: var(--color-gray-50);
1164
+ border: 1px solid var(--color-gray-200);
1165
+ border-radius: var(--border-radius);
1166
+ padding: var(--spacing-lg);
1167
+ }
1168
+
1169
+ .field-help h3,
1170
+ .token-help h3,
1171
+ .info-card h3 {
1172
+ margin: 0 0 var(--spacing-md) 0;
1173
+ font-size: 1.125rem;
1174
+ font-weight: 600;
1175
+ }
1176
+
1177
+ .field-help p,
1178
+ .token-help p {
1179
+ margin-bottom: var(--spacing-sm);
1180
+ font-size: 0.875rem;
1181
+ line-height: 1.6;
1182
+ }
1183
+
1184
+ .code-example {
1185
+ background: var(--color-gray-900);
1186
+ color: #d4d4d4;
1187
+ padding: var(--spacing-md);
1188
+ border-radius: var(--border-radius);
1189
+ font-family: "SF Mono", Monaco, "Cascadia Code", "Roboto Mono", Consolas, monospace;
1190
+ font-size: 0.8125rem;
1191
+ overflow-x: auto;
1192
+ margin: var(--spacing-md) 0;
1193
+ }
1194
+
1195
+ /* Token Display */
1196
+ .alert {
1197
+ padding: var(--spacing-lg);
1198
+ border-radius: var(--border-radius);
1199
+ margin-bottom: var(--spacing-lg);
1200
+ }
1201
+
1202
+ .alert-success {
1203
+ background: #d1fae5;
1204
+ border: 1px solid #10b981;
1205
+ color: #065f46;
1206
+ }
1207
+
1208
+ .alert h3 {
1209
+ margin: 0 0 var(--spacing-sm) 0;
1210
+ font-size: 1.125rem;
1211
+ }
1212
+
1213
+ .alert p {
1214
+ margin: var(--spacing-sm) 0;
1215
+ font-size: 0.875rem;
1216
+ }
1217
+
1218
+ .token-display {
1219
+ display: flex;
1220
+ align-items: center;
1221
+ gap: var(--spacing-sm);
1222
+ padding: var(--spacing-md);
1223
+ background: white;
1224
+ border: 1px solid #10b981;
1225
+ border-radius: var(--border-radius);
1226
+ margin: var(--spacing-md) 0;
1227
+ }
1228
+
1229
+ .token-display code {
1230
+ flex: 1;
1231
+ font-family: "SF Mono", Monaco, "Cascadia Code", "Roboto Mono", Consolas, monospace;
1232
+ font-size: 0.875rem;
1233
+ word-break: break-all;
1234
+ }
1235
+
1236
+ .token-usage {
1237
+ font-size: 0.8125rem;
1238
+ font-family: "SF Mono", Monaco, "Cascadia Code", "Roboto Mono", Consolas, monospace;
1239
+ }
1240
+
1241
+ .btn-small {
1242
+ padding: 0.375rem 0.75rem;
1243
+ font-size: 0.8125rem;
1244
+ }
1245
+
1246
+ /* Form Styles */
1247
+ .form-container {
1248
+ max-width: 600px;
1249
+ margin: 0 auto;
1250
+ display: flex;
1251
+ flex-direction: column;
1252
+ gap: var(--spacing-lg);
1253
+ }
1254
+
1255
+ .form-group {
1256
+ margin-bottom: var(--spacing-md);
1257
+ }
1258
+
1259
+ .form-group label {
1260
+ display: block;
1261
+ font-size: 0.875rem;
1262
+ font-weight: 500;
1263
+ color: var(--color-gray-700);
1264
+ margin-bottom: var(--spacing-sm);
1265
+ }
1266
+
1267
+ .form-help {
1268
+ font-size: 0.8125rem;
1269
+ color: var(--color-gray-600);
1270
+ margin-top: 0.25rem;
1271
+ }
1272
+
1273
+ .form-actions {
1274
+ display: flex;
1275
+ gap: var(--spacing-sm);
1276
+ padding-top: var(--spacing-md);
1277
+ }
1278
+
1279
+ .info-card ul {
1280
+ margin: 0;
1281
+ padding-left: 1.5rem;
1282
+ }
1283
+
1284
+ .info-card li {
1285
+ font-size: 0.875rem;
1286
+ line-height: 1.6;
1287
+ margin-bottom: 0.5rem;
1288
+ }
1289
+
1290
+ .no-padding {
1291
+ padding: 0 !important;
1292
+ }
1293
+
1294
+ .table-responsive {
1295
+ overflow-x: auto;
1296
+ }
1297
+
1298
+ /* Responsive */
1299
+ @media (max-width: 768px) {
1300
+ .streams-container {
1301
+ grid-template-columns: 1fr;
1302
+ }
1303
+
1304
+ .streams-sidebar {
1305
+ border-right: none;
1306
+ border-bottom: 1px solid var(--color-gray-200);
1307
+ }
1308
+
1309
+ .metadata-list {
1310
+ grid-template-columns: 1fr;
1311
+ gap: var(--spacing-sm);
1312
+ }
1313
+
1314
+ .timeline-stats {
1315
+ flex-direction: column;
1316
+ }
1317
+
1318
+ .fields-stats {
1319
+ flex-direction: column;
1320
+ }
1321
+ }
1322
+
1323
+ /* Toast Notifications */
1324
+ .toast-container {
1325
+ position: fixed;
1326
+ top: 1rem;
1327
+ right: 1rem;
1328
+ z-index: 10000;
1329
+ display: flex;
1330
+ flex-direction: column;
1331
+ gap: 0.5rem;
1332
+ pointer-events: none;
1333
+ }
1334
+
1335
+ .toast {
1336
+ background: var(--color-gray-900);
1337
+ color: white;
1338
+ padding: 0.75rem 1rem;
1339
+ border-radius: 0.5rem;
1340
+ box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
1341
+ display: flex;
1342
+ align-items: center;
1343
+ gap: 0.75rem;
1344
+ min-width: 300px;
1345
+ max-width: 500px;
1346
+ pointer-events: auto;
1347
+ animation: toast-slide-in 0.2s ease-out;
1348
+ }
1349
+
1350
+ .toast.toast-success {
1351
+ background: #059669;
1352
+ color: white;
1353
+ }
1354
+
1355
+ .toast.toast-info {
1356
+ background: #2563eb;
1357
+ color: white;
1358
+ }
1359
+
1360
+ .toast.toast-warning {
1361
+ background: #f59e0b;
1362
+ color: var(--color-gray-900);
1363
+ }
1364
+
1365
+ .toast.toast-error {
1366
+ background: #dc2626;
1367
+ color: white;
1368
+ }
1369
+
1370
+ .toast-icon {
1371
+ font-size: 1.25rem;
1372
+ flex-shrink: 0;
1373
+ }
1374
+
1375
+ .toast-message {
1376
+ flex: 1;
1377
+ font-size: 0.875rem;
1378
+ line-height: 1.25rem;
1379
+ }
1380
+
1381
+ .toast-close {
1382
+ background: none;
1383
+ border: none;
1384
+ color: inherit;
1385
+ opacity: 0.7;
1386
+ cursor: pointer;
1387
+ padding: 0;
1388
+ font-size: 1.25rem;
1389
+ line-height: 1;
1390
+ flex-shrink: 0;
1391
+ }
1392
+
1393
+ .toast-close:hover {
1394
+ opacity: 1;
1395
+ }
1396
+
1397
+ @keyframes toast-slide-in {
1398
+ from {
1399
+ transform: translateX(100%);
1400
+ opacity: 0;
1401
+ }
1402
+ to {
1403
+ transform: translateX(0);
1404
+ opacity: 1;
1405
+ }
1406
+ }
1407
+
1408
+ .toast.toast-dismissing {
1409
+ animation: toast-slide-out 0.2s ease-in forwards;
1410
+ }
1411
+
1412
+ @keyframes toast-slide-out {
1413
+ from {
1414
+ transform: translateX(0);
1415
+ opacity: 1;
1416
+ }
1417
+ to {
1418
+ transform: translateX(100%);
1419
+ opacity: 0;
1420
+ }
1421
+ }
1422
+
1423
+ /* Live Tail Status Indicator */
1424
+ .live-tail-status {
1425
+ display: inline-flex;
1426
+ align-items: center;
1427
+ gap: 0.5rem;
1428
+ padding: 0.25rem 0.75rem;
1429
+ background-color: rgba(34, 197, 94, 0.1);
1430
+ border: 1px solid rgba(34, 197, 94, 0.3);
1431
+ border-radius: 9999px;
1432
+ font-size: 0.75rem;
1433
+ font-weight: 500;
1434
+ color: rgb(22, 163, 74);
1435
+ margin-left: 0.5rem;
1436
+ }
1437
+
1438
+ .live-tail-status .status-dot {
1439
+ width: 0.5rem;
1440
+ height: 0.5rem;
1441
+ background-color: rgb(34, 197, 94);
1442
+ border-radius: 50%;
1443
+ animation: pulse-dot 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
1444
+ }
1445
+
1446
+ .live-tail-status .status-text {
1447
+ white-space: nowrap;
1448
+ }
1449
+
1450
+ @keyframes pulse-dot {
1451
+ 0%, 100% {
1452
+ opacity: 1;
1453
+ }
1454
+ 50% {
1455
+ opacity: 0.5;
1456
+ }
1457
+ }
1458
+
1459
+ /* Jump to Live button with new entries indicator */
1460
+ #jump-to-live.has-new-entries {
1461
+ background-color: rgb(59, 130, 246);
1462
+ color: white;
1463
+ border-color: rgb(37, 99, 235);
1464
+ animation: pulse-button 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
1465
+ position: relative;
1466
+ }
1467
+
1468
+ #jump-to-live.has-new-entries::after {
1469
+ content: '';
1470
+ position: absolute;
1471
+ top: -4px;
1472
+ right: -4px;
1473
+ width: 8px;
1474
+ height: 8px;
1475
+ background-color: rgb(239, 68, 68);
1476
+ border-radius: 50%;
1477
+ animation: pulse-dot 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
1478
+ }
1479
+
1480
+ @keyframes pulse-button {
1481
+ 0%, 100% {
1482
+ box-shadow: 0 0 0 0 rgba(59, 130, 246, 0.7);
1483
+ }
1484
+ 50% {
1485
+ box-shadow: 0 0 0 6px rgba(59, 130, 246, 0);
1486
+ }
1487
+ }
1488
+
1489
+ /* Dark theme support */
1490
+ @media (prefers-color-scheme: dark) {
1491
+ .live-tail-status {
1492
+ background-color: rgba(34, 197, 94, 0.15);
1493
+ border-color: rgba(34, 197, 94, 0.4);
1494
+ color: rgb(134, 239, 172);
1495
+ }
1496
+
1497
+ .live-tail-status .status-dot {
1498
+ background-color: rgb(134, 239, 172);
1499
+ }
1500
+
1501
+ #jump-to-live.has-new-entries {
1502
+ background-color: rgb(59, 130, 246);
1503
+ color: white;
1504
+ border-color: rgb(96, 165, 250);
1505
+ }
1506
+ }