onlylogs 0.10.0 → 0.12.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 (38) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +270 -69
  3. data/app/assets/images/onlylogs/favicon/apple-touch-icon.png +0 -0
  4. data/app/assets/images/onlylogs/favicon/favicon-96x96.png +0 -0
  5. data/app/assets/images/onlylogs/favicon/favicon.ico +0 -0
  6. data/app/assets/images/onlylogs/favicon/favicon.svg +1 -3
  7. data/app/assets/images/onlylogs/favicon/web-app-manifest-192x192.png +0 -0
  8. data/app/assets/images/onlylogs/favicon/web-app-manifest-512x512.png +0 -0
  9. data/app/assets/images/onlylogs/logo.png +0 -0
  10. data/app/assets/javascripts/onlylogs/clusterize.js +26 -1
  11. data/app/channels/onlylogs/logs_channel.rb +22 -9
  12. data/app/controllers/concerns/onlylogs/authentication.rb +26 -0
  13. data/app/controllers/onlylogs/application_controller.rb +1 -18
  14. data/app/controllers/onlylogs/queries_controller.rb +70 -0
  15. data/app/controllers/onlylogs/viewer_controller.rb +7 -0
  16. data/app/javascript/onlylogs/controllers/keyboard_shortcuts_controller.js +131 -21
  17. data/app/javascript/onlylogs/controllers/log_cursor_controller.js +286 -0
  18. data/app/javascript/onlylogs/controllers/log_streamer_controller.js +52 -6
  19. data/app/javascript/onlylogs/controllers/match_highlight_controller.js +82 -0
  20. data/app/javascript/onlylogs/controllers/queries_controller.js +470 -0
  21. data/app/javascript/onlylogs/controllers/range_slider_controller.js +5 -4
  22. data/app/javascript/onlylogs/controllers/text_selection_controller.js +136 -15
  23. data/app/models/onlylogs/file.rb +27 -7
  24. data/app/models/onlylogs/grep.rb +13 -6
  25. data/app/models/onlylogs/queries_record.rb +28 -0
  26. data/app/models/onlylogs/query.rb +29 -0
  27. data/app/views/onlylogs/logs/index.html.erb +1 -1
  28. data/app/views/onlylogs/shared/_log_container.html.erb +179 -30
  29. data/app/views/onlylogs/shared/_log_container_styles.html.erb +731 -45
  30. data/app/views/onlylogs/shared/_shortcuts_dialog.html.erb +62 -0
  31. data/bin/super_grep +7 -0
  32. data/bin/super_ripgrep +5 -0
  33. data/config/routes.rb +1 -0
  34. data/lib/onlylogs/configuration.rb +14 -1
  35. data/lib/onlylogs/http_device.rb +28 -13
  36. data/lib/onlylogs/version.rb +1 -1
  37. data/lib/onlylogs.rb +4 -0
  38. metadata +38 -1
@@ -14,10 +14,18 @@
14
14
  --ol-accent-soft: #e8f0fe;
15
15
  --ol-accent-border: #9dbcf7;
16
16
  --ol-accent-ink: #1a4fc4;
17
+ --ol-accent-ring: rgba(37, 99, 235, 0.2);
18
+ --ol-star: #d97706;
19
+ --ol-star-fill: #f59e0b;
17
20
  --ol-live: #16a34a;
18
21
  --ol-alert: #dc2626;
22
+ --ol-alert-soft: #fef2f2;
19
23
  --ol-amber: #b7791f;
24
+ --ol-amber-soft: #fffbeb;
25
+ --ol-amber-border: #fde68a;
20
26
  --ol-radius: 3px;
27
+ --ol-mono: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
28
+ --ol-sans: ui-sans-serif, -apple-system, "Segoe UI", Helvetica, Arial, sans-serif;
21
29
 
22
30
  background-color: var(--onlylogs-bg-color, none);
23
31
  width: var(--onlylogs-width, 100%);
@@ -28,7 +36,7 @@
28
36
  takes whatever is left. Hosts can still pin a height with the variable. */
29
37
  grid-template-rows: 1fr var(--onlylogs-toolbar-height, auto);
30
38
 
31
- font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
39
+ font-family: var(--ol-mono);
32
40
  font-size: var(--onlylogs-font-size, 0.8rem);
33
41
  margin: 0;
34
42
  border: none;
@@ -203,7 +211,6 @@
203
211
  display: inline-flex;
204
212
  border: 1px solid var(--ol-control-border);
205
213
  border-radius: 4px;
206
- overflow: hidden;
207
214
  background-color: var(--ol-surface);
208
215
  flex-shrink: 0;
209
216
  }
@@ -221,6 +228,14 @@
221
228
  gap: 0.3rem;
222
229
  transition: background-color 0.15s, color 0.15s;
223
230
 
231
+ &:first-child {
232
+ border-radius: 3px 0 0 3px;
233
+ }
234
+
235
+ &:last-child {
236
+ border-radius: 0 3px 3px 0;
237
+ }
238
+
224
239
  & + & {
225
240
  border-left: 1px solid var(--ol-border);
226
241
  }
@@ -242,7 +257,8 @@
242
257
  background-color: var(--ol-accent);
243
258
  }
244
259
 
245
- .search-whole-file-button {
260
+ .search-whole-file-button,
261
+ .reload-button {
246
262
  font: inherit;
247
263
  border: 1px solid var(--ol-accent-border);
248
264
  background-color: var(--ol-accent-soft);
@@ -256,23 +272,6 @@
256
272
  background-color: #d7e5fd;
257
273
  }
258
274
  }
259
- .clear-filter-button {
260
- position: absolute;
261
- right: 0.2rem;
262
- background: none;
263
- border: none;
264
- color: var(--ol-muted);
265
- cursor: pointer;
266
- font-size: 0.8rem;
267
- padding: 0;
268
- width: 1rem;
269
- height: 1rem;
270
- display: flex;
271
- align-items: center;
272
- justify-content: center;
273
- padding: 0.25rem;
274
- }
275
-
276
275
  .onlylogs-spin-animation {
277
276
  display: inline-block;
278
277
  animation: spin 1s linear infinite;
@@ -345,6 +344,546 @@
345
344
  display: inline-block;
346
345
  }
347
346
 
347
+ .success-message {
348
+ color: var(--ol-live);
349
+ font-weight: 600;
350
+ }
351
+
352
+ .onlylogs-query {
353
+ display: flex;
354
+ align-items: center;
355
+ gap: 0.4rem;
356
+ flex: 1 1 14rem;
357
+ min-width: 14rem;
358
+ max-width: 26rem;
359
+ }
360
+
361
+ .saved-searches {
362
+ position: relative;
363
+ flex: 1;
364
+ min-width: 0;
365
+ }
366
+
367
+ /* The field is the box: the query, its clear button and the saved-search
368
+ buttons all live inside one border. */
369
+ .filter-input-wrapper {
370
+ display: flex;
371
+ align-items: center;
372
+ gap: 0.1rem;
373
+ height: 1.9rem;
374
+ padding: 0 0.2rem 0 0.5rem;
375
+ border: 1px solid var(--ol-control-border);
376
+ border-radius: 6px;
377
+ background-color: var(--ol-surface);
378
+
379
+ &:has(input:focus-visible),
380
+ .saved-searches:has(.saved-searches__panel:not([hidden])) & {
381
+ border-color: var(--ol-accent);
382
+ box-shadow: 0 0 0 3px var(--ol-accent-ring);
383
+ }
384
+
385
+ &:has(input:placeholder-shown) .clear-filter-button {
386
+ display: none;
387
+ }
388
+
389
+ input {
390
+ flex: 1;
391
+ min-width: 3.5rem;
392
+ height: 100%;
393
+ padding: 0;
394
+ border: 0;
395
+ outline: none;
396
+ background: transparent;
397
+ font: inherit;
398
+ color: var(--ol-ink);
399
+
400
+ &::placeholder {
401
+ color: var(--ol-muted);
402
+ }
403
+ }
404
+ }
405
+
406
+ .filter-input-button {
407
+ flex-shrink: 0;
408
+ display: flex;
409
+ align-items: center;
410
+ justify-content: center;
411
+ width: 1.6rem;
412
+ height: 1.6rem;
413
+ padding: 0;
414
+ border: 0;
415
+ border-radius: 4px;
416
+ background: transparent;
417
+ color: var(--ol-ink-3);
418
+ cursor: pointer;
419
+
420
+ &:hover:not(:disabled),
421
+ &[aria-expanded="true"] {
422
+ background-color: var(--ol-hover);
423
+ color: var(--ol-ink);
424
+ }
425
+
426
+ &:focus-visible {
427
+ outline: 2px solid var(--ol-accent);
428
+ outline-offset: -2px;
429
+ }
430
+
431
+ &:disabled {
432
+ color: var(--ol-control-border);
433
+ cursor: default;
434
+ }
435
+ }
436
+
437
+ .clear-filter-button {
438
+ width: 1.4rem;
439
+ height: 1.4rem;
440
+ color: var(--ol-faint);
441
+ }
442
+
443
+ .saved-searches__toggle {
444
+ position: relative;
445
+ }
446
+
447
+ .saved-searches__count:not(:empty) {
448
+ position: absolute;
449
+ top: 0;
450
+ right: -0.1rem;
451
+ min-width: 0.8rem;
452
+ height: 0.8rem;
453
+ padding: 0 0.2rem;
454
+ box-sizing: border-box;
455
+ border-radius: 999px;
456
+ background-color: var(--ol-ink);
457
+ color: #fff;
458
+ font-size: 0.55rem;
459
+ line-height: 0.8rem;
460
+ text-align: center;
461
+ }
462
+
463
+ .saved-searches__star--saved {
464
+ color: var(--ol-star);
465
+
466
+ svg {
467
+ fill: var(--ol-star-fill);
468
+ }
469
+ }
470
+
471
+ .saved-searches__panel {
472
+ position: absolute;
473
+ bottom: calc(100% + 0.6rem);
474
+ left: 0;
475
+ z-index: 1000;
476
+ display: flex;
477
+ flex-direction: column;
478
+ width: min(25rem, calc(100vw - 2rem));
479
+ overflow: hidden;
480
+ background-color: var(--ol-surface);
481
+ color: var(--ol-ink-2);
482
+ border: 1px solid var(--ol-border);
483
+ border-radius: 10px;
484
+ box-shadow: 0 12px 32px rgba(18, 23, 31, 0.14);
485
+ font-family: var(--ol-sans);
486
+
487
+ code {
488
+ font-family: var(--ol-mono);
489
+ }
490
+ animation: onlylogs-pop 130ms cubic-bezier(0.2, 0.8, 0.3, 1);
491
+
492
+ &[hidden] {
493
+ display: none;
494
+ }
495
+ }
496
+
497
+ .saved-searches__panel--save {
498
+ width: min(22rem, calc(100vw - 2rem));
499
+ padding: 0.85rem;
500
+ gap: 0.75rem;
501
+ }
502
+
503
+ .saved-searches__header {
504
+ display: flex;
505
+ justify-content: space-between;
506
+ align-items: center;
507
+ gap: 1rem;
508
+ padding: 0.6rem 0.85rem 0.35rem;
509
+ white-space: nowrap;
510
+ font-size: 0.85em;
511
+ color: var(--ol-muted);
512
+ }
513
+
514
+ .saved-searches__title {
515
+ font-weight: 600;
516
+ letter-spacing: 0.06em;
517
+ text-transform: uppercase;
518
+ }
519
+
520
+ .saved-searches__list {
521
+ list-style: none;
522
+ margin: 0;
523
+ padding: 0 0.35rem 0.35rem;
524
+ max-height: 20rem;
525
+ overflow-y: auto;
526
+
527
+ &:empty {
528
+ display: none;
529
+ }
530
+ }
531
+
532
+ .saved-searches__empty {
533
+ display: flex;
534
+ flex-direction: column;
535
+ gap: 0.25rem;
536
+ margin: 0.25rem 0.85rem 0.75rem;
537
+ padding: 0.9rem;
538
+ border: 1px dashed var(--ol-control-border);
539
+ border-radius: 8px;
540
+
541
+ strong {
542
+ color: var(--ol-ink);
543
+ font-weight: 600;
544
+ }
545
+
546
+ &[hidden] {
547
+ display: none;
548
+ }
549
+ }
550
+
551
+ .saved-searches__footer {
552
+ padding: 0.35rem;
553
+ border-top: 1px solid var(--ol-border);
554
+
555
+ &[hidden] {
556
+ display: none;
557
+ }
558
+ }
559
+
560
+ .saved-searches__footer-button {
561
+ display: flex;
562
+ align-items: center;
563
+ gap: 0.5rem;
564
+ width: 100%;
565
+ padding: 0.5rem;
566
+ border: 0;
567
+ border-radius: 6px;
568
+ background: transparent;
569
+ font: inherit;
570
+ color: var(--ol-ink);
571
+ text-align: left;
572
+ cursor: pointer;
573
+
574
+ span {
575
+ flex: 1;
576
+ min-width: 0;
577
+ overflow: hidden;
578
+ text-overflow: ellipsis;
579
+ white-space: nowrap;
580
+ }
581
+
582
+ &:hover,
583
+ &:focus-visible {
584
+ outline: none;
585
+ background-color: var(--ol-hover);
586
+ }
587
+ }
588
+
589
+ .saved-search {
590
+ display: flex;
591
+ align-items: center;
592
+ gap: 0.35rem;
593
+ padding: 0.4rem 0.5rem;
594
+ border-radius: 6px;
595
+
596
+ &:hover,
597
+ &:focus-within {
598
+ background-color: var(--ol-hover);
599
+ }
600
+
601
+ &[aria-current] {
602
+ background-color: var(--ol-accent-soft);
603
+
604
+ .saved-search__name {
605
+ font-weight: 600;
606
+ }
607
+ }
608
+ }
609
+
610
+ .saved-search__apply {
611
+ flex: 1;
612
+ min-width: 0;
613
+ display: flex;
614
+ flex-direction: column;
615
+ gap: 0.15rem;
616
+ padding: 0;
617
+ border: 0;
618
+ background: transparent;
619
+ font: inherit;
620
+ color: var(--ol-ink);
621
+ text-align: left;
622
+ cursor: pointer;
623
+
624
+ &:focus-visible {
625
+ outline: none;
626
+ }
627
+
628
+ &[hidden] {
629
+ display: none;
630
+ }
631
+ }
632
+
633
+ .saved-search__line {
634
+ display: flex;
635
+ align-items: center;
636
+ gap: 0.4rem;
637
+ min-width: 0;
638
+ }
639
+
640
+ .saved-search__name,
641
+ .saved-search__filter {
642
+ flex: 1 1 0;
643
+ min-width: 0;
644
+ overflow: hidden;
645
+ text-overflow: ellipsis;
646
+ white-space: nowrap;
647
+ }
648
+
649
+ .saved-search__name {
650
+ font-weight: 500;
651
+ }
652
+
653
+ .saved-search__check {
654
+ flex-shrink: 0;
655
+ color: var(--ol-accent);
656
+
657
+ &[hidden] {
658
+ display: none;
659
+ }
660
+ }
661
+
662
+ .saved-search__edited {
663
+ flex-shrink: 0;
664
+ padding: 0 0.4rem;
665
+ border: 1px solid var(--ol-amber-border);
666
+ border-radius: 999px;
667
+ background-color: var(--ol-amber-soft);
668
+ color: var(--ol-amber);
669
+ font-size: 0.85em;
670
+
671
+ &[hidden] {
672
+ display: none;
673
+ }
674
+ }
675
+
676
+ .saved-search__filter {
677
+ font: inherit;
678
+ color: var(--ol-ink-3);
679
+ }
680
+
681
+ .saved-search__flags {
682
+ display: flex;
683
+ gap: 0.25rem;
684
+ }
685
+
686
+ .saved-search__flag {
687
+ flex-shrink: 0;
688
+ padding: 0 0.35rem;
689
+ border: 1px solid var(--ol-border);
690
+ border-radius: 999px;
691
+ color: var(--ol-ink-3);
692
+ font-size: 0.8em;
693
+ }
694
+
695
+ .saved-search__rename-input {
696
+ flex: 1;
697
+ min-width: 0;
698
+ height: 1.9rem;
699
+ padding: 0 0.5rem;
700
+ border: 1px solid var(--ol-accent);
701
+ border-radius: 4px;
702
+ box-shadow: 0 0 0 3px var(--ol-accent-ring);
703
+ font: inherit;
704
+ outline: none;
705
+
706
+ &[hidden] {
707
+ display: none;
708
+ }
709
+ }
710
+
711
+ .saved-search__action {
712
+ flex-shrink: 0;
713
+ display: flex;
714
+ align-items: center;
715
+ justify-content: center;
716
+ gap: 0.25rem;
717
+ min-width: 1.75rem;
718
+ height: 1.75rem;
719
+ padding: 0 0.3rem;
720
+ border: 0;
721
+ border-radius: 4px;
722
+ background: transparent;
723
+ font: inherit;
724
+ color: var(--ol-faint);
725
+ cursor: pointer;
726
+
727
+ &:hover,
728
+ &:focus-visible {
729
+ outline: none;
730
+ background-color: var(--ol-border);
731
+ color: var(--ol-ink-2);
732
+ }
733
+
734
+ &[hidden] {
735
+ display: none;
736
+ }
737
+ }
738
+
739
+ .saved-search__delete {
740
+ &:hover,
741
+ &:focus-visible {
742
+ background-color: var(--ol-alert-soft);
743
+ color: var(--ol-alert);
744
+ }
745
+
746
+ .saved-search__delete-label {
747
+ display: none;
748
+ }
749
+
750
+ &.saved-search__delete--confirm {
751
+ background-color: var(--ol-alert);
752
+ color: #fff;
753
+
754
+ .saved-search__delete-label {
755
+ display: inline;
756
+ }
757
+ }
758
+ }
759
+
760
+ .save-search__summary {
761
+ display: flex;
762
+ flex-direction: column;
763
+ gap: 0.3rem;
764
+ }
765
+
766
+ .save-search__title {
767
+ font-weight: 600;
768
+ color: var(--ol-ink);
769
+ }
770
+
771
+ .save-search__current {
772
+ display: flex;
773
+ flex-wrap: wrap;
774
+ align-items: center;
775
+ gap: 0.35rem;
776
+
777
+ code {
778
+ max-width: 100%;
779
+ padding: 0.05rem 0.4rem;
780
+ border-radius: 4px;
781
+ background-color: var(--ol-hover);
782
+ color: var(--ol-ink);
783
+ font: inherit;
784
+ overflow-wrap: anywhere;
785
+ }
786
+
787
+ > span {
788
+ display: contents;
789
+ }
790
+ }
791
+
792
+ .save-search__form {
793
+ display: flex;
794
+ flex-direction: column;
795
+ gap: 0.35rem;
796
+
797
+ label {
798
+ font-weight: 500;
799
+ color: var(--ol-ink-2);
800
+ }
801
+ }
802
+
803
+ .save-search__row {
804
+ display: flex;
805
+ gap: 0.5rem;
806
+
807
+ input {
808
+ flex: 1;
809
+ min-width: 0;
810
+ height: 2rem;
811
+ padding: 0 0.6rem;
812
+ border: 1px solid var(--ol-control-border);
813
+ border-radius: 6px;
814
+ background-color: var(--ol-surface);
815
+ font: inherit;
816
+ color: var(--ol-ink);
817
+ outline: none;
818
+
819
+ &:focus {
820
+ border-color: var(--ol-accent);
821
+ box-shadow: 0 0 0 3px var(--ol-accent-ring);
822
+ }
823
+ }
824
+
825
+ button {
826
+ height: 2rem;
827
+ padding: 0 0.85rem;
828
+ border: 1px solid var(--ol-ink);
829
+ border-radius: 6px;
830
+ background-color: var(--ol-ink);
831
+ color: #fff;
832
+ font: inherit;
833
+ font-weight: 500;
834
+ cursor: pointer;
835
+
836
+ &:hover:not(:disabled) {
837
+ background-color: var(--ol-ink-2);
838
+ }
839
+
840
+ &:disabled {
841
+ opacity: 0.4;
842
+ cursor: default;
843
+ }
844
+ }
845
+ }
846
+
847
+ .save-search__hint {
848
+ margin: 0;
849
+ font-size: 0.9em;
850
+ color: var(--ol-muted);
851
+
852
+ &.save-search__hint--warning {
853
+ color: var(--ol-amber);
854
+ }
855
+ }
856
+
857
+ .save-search__saved {
858
+ display: flex;
859
+ justify-content: space-between;
860
+ align-items: center;
861
+ padding-top: 0.6rem;
862
+ border-top: 1px solid var(--ol-border);
863
+ font-size: 0.9em;
864
+ color: var(--ol-muted);
865
+
866
+ button {
867
+ padding: 0.25rem 0.6rem;
868
+ border: 0;
869
+ border-radius: 4px;
870
+ background: transparent;
871
+ font: inherit;
872
+ color: var(--ol-alert);
873
+ cursor: pointer;
874
+
875
+ &:hover,
876
+ &:focus-visible {
877
+ outline: none;
878
+ background-color: var(--ol-alert-soft);
879
+ }
880
+ }
881
+
882
+ &[hidden] {
883
+ display: none;
884
+ }
885
+ }
886
+
348
887
  .range-slider {
349
888
  --range-track-height: 0.25rem;
350
889
  --range-thumb-size: 0.6rem;
@@ -365,31 +904,6 @@
365
904
  color: var(--ol-ink-3);
366
905
  }
367
906
 
368
- .filter-input-wrapper {
369
- display: inline-flex;
370
- align-items: center;
371
- position: relative;
372
- }
373
-
374
- .filter-input-wrapper input {
375
- font: inherit;
376
- padding: 0.22rem 1.4rem 0.22rem 0.4rem;
377
- border: 1px solid var(--ol-control-border);
378
- border-radius: var(--ol-radius);
379
- background-color: var(--ol-surface);
380
- color: var(--ol-ink);
381
- width: 11rem;
382
-
383
- &::placeholder {
384
- color: var(--ol-muted);
385
- }
386
-
387
- &:focus-visible {
388
- outline: 2px solid var(--ol-accent);
389
- outline-offset: 1px;
390
- }
391
- }
392
-
393
907
  .results-text {
394
908
  color: var(--ol-ink-3);
395
909
  white-space: nowrap;
@@ -596,4 +1110,176 @@
596
1110
  }
597
1111
  }
598
1112
  }
1113
+
1114
+ .onlylogs-log-container {
1115
+ .clusterize-content > .onlylogs-cursor-line {
1116
+ transition: background-color 0.1s;
1117
+ }
1118
+
1119
+ .onlylogs-log-lines:focus-within .clusterize-content > .onlylogs-cursor-line {
1120
+ background-color: var(--ol-accent-soft);
1121
+ box-shadow: inset 3px 0 0 var(--ol-accent);
1122
+ }
1123
+
1124
+ mark.onlylogs-match {
1125
+ background-color: #fde68a;
1126
+ color: inherit;
1127
+ border-radius: 2px;
1128
+ box-shadow: 0 0 0 1px #f5c542;
1129
+ }
1130
+
1131
+ .clusterize-content > .onlylogs-line-copied {
1132
+ animation: onlylogs-copied 0.6s ease-out;
1133
+ }
1134
+
1135
+ .onlylogs-context-menu kbd {
1136
+ font: inherit;
1137
+ font-size: 0.85em;
1138
+ padding: 0 0.3em;
1139
+ border: 1px solid #90caf9;
1140
+ border-radius: 3px;
1141
+ background-color: #fff;
1142
+ }
1143
+
1144
+ .shortcuts-button {
1145
+ font: inherit;
1146
+ line-height: 1;
1147
+ background: none;
1148
+ border: 0;
1149
+ color: var(--ol-ink-3);
1150
+ padding: 0.15rem 0.3rem;
1151
+ border-radius: var(--ol-radius);
1152
+ cursor: pointer;
1153
+
1154
+ &:hover {
1155
+ background-color: var(--ol-hover);
1156
+ }
1157
+ }
1158
+
1159
+ .onlylogs-shortcuts-dialog {
1160
+ max-width: min(46rem, calc(100vw - 2rem));
1161
+ max-height: calc(100vh - 3rem);
1162
+ padding: 1rem 1.25rem 1.25rem;
1163
+ border: 1px solid var(--ol-border);
1164
+ border-radius: 6px;
1165
+ box-shadow: 0 12px 40px rgba(18, 23, 31, 0.25);
1166
+ color: var(--ol-ink-2);
1167
+ background-color: var(--ol-surface);
1168
+ font: inherit;
1169
+
1170
+ &::backdrop {
1171
+ background-color: rgba(18, 23, 31, 0.35);
1172
+ }
1173
+
1174
+ h2 {
1175
+ margin: 0;
1176
+ font-size: 1rem;
1177
+ color: var(--ol-ink);
1178
+ }
1179
+
1180
+ h3 {
1181
+ margin: 0 0 0.4rem;
1182
+ font-size: 0.8rem;
1183
+ font-weight: 600;
1184
+ color: var(--ol-ink-3);
1185
+ }
1186
+
1187
+ dl {
1188
+ margin: 0;
1189
+ display: grid;
1190
+ gap: 0.25rem;
1191
+ }
1192
+
1193
+ dl > div {
1194
+ display: grid;
1195
+ grid-template-columns: 8.5rem 1fr;
1196
+ gap: 0.75rem;
1197
+ align-items: baseline;
1198
+ }
1199
+
1200
+ dt {
1201
+ display: flex;
1202
+ flex-wrap: wrap;
1203
+ gap: 0.2rem;
1204
+ }
1205
+
1206
+ dd {
1207
+ margin: 0;
1208
+ }
1209
+
1210
+ kbd {
1211
+ font: inherit;
1212
+ font-size: 0.85em;
1213
+ min-width: 1.1em;
1214
+ text-align: center;
1215
+ padding: 0.05em 0.35em;
1216
+ border: 1px solid var(--ol-control-border);
1217
+ border-bottom-width: 2px;
1218
+ border-radius: 3px;
1219
+ background-color: var(--ol-toolbar-bg);
1220
+ color: var(--ol-ink);
1221
+ }
1222
+ }
1223
+
1224
+ .onlylogs-shortcuts-dialog__header {
1225
+ display: flex;
1226
+ align-items: center;
1227
+ justify-content: space-between;
1228
+ margin-bottom: 0.9rem;
1229
+
1230
+ button {
1231
+ font: inherit;
1232
+ font-size: 1.2rem;
1233
+ line-height: 1;
1234
+ background: none;
1235
+ border: 0;
1236
+ color: var(--ol-muted);
1237
+ cursor: pointer;
1238
+ }
1239
+ }
1240
+
1241
+ .onlylogs-shortcuts-dialog__sections {
1242
+ display: grid;
1243
+ grid-template-columns: repeat(auto-fit, minmax(19rem, 1fr));
1244
+ gap: 1.1rem 1.75rem;
1245
+ }
1246
+ }
1247
+
1248
+ @keyframes onlylogs-pop {
1249
+ from { opacity: 0; transform: translateY(4px); }
1250
+ to { opacity: 1; transform: none; }
1251
+ }
1252
+
1253
+ @keyframes onlylogs-copied {
1254
+ from { background-color: rgba(22, 163, 74, 0.35); }
1255
+ }
1256
+
1257
+ /* Not scoped to the viewer: host apps can put the attribute on their own controls. */
1258
+ :where([data-onlylogs-shortcut]) {
1259
+ position: relative;
1260
+ }
1261
+
1262
+ .onlylogs-shortcuts-visible [data-onlylogs-shortcut]::after {
1263
+ content: attr(data-onlylogs-shortcut);
1264
+ position: absolute;
1265
+ top: -0.6rem;
1266
+ left: -0.45rem;
1267
+ z-index: 1001;
1268
+ min-width: 0.8rem;
1269
+ padding: 0.1rem 0.28rem;
1270
+ border-radius: 3px;
1271
+ background-color: #12171f;
1272
+ color: #fff;
1273
+ box-shadow: 0 1px 4px rgba(0, 0, 0, 0.35);
1274
+ font: 600 0.68rem/1 "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
1275
+ text-align: center;
1276
+ text-transform: uppercase;
1277
+ text-decoration: none;
1278
+ pointer-events: none;
1279
+ animation: onlylogs-hint-in 0.12s ease-out;
1280
+ }
1281
+
1282
+ @keyframes onlylogs-hint-in {
1283
+ from { opacity: 0; transform: scale(0.7); }
1284
+ }
599
1285
  </style>