app.css
⎇
Raw
1/* Theme palettes. The base is light; dark is applied either by the OS
2 preference (theme = auto, the default) or forced by the theme toggle,
3 which puts `light`/`dark` on <html> (see web/src/theme.rs). Keep the two
4 dark blocks in sync. */
5:root {
6 color-scheme: light;
7 --bg: #f6f7f9;
8 --panel: #ffffff;
9 --text: #1a1d21;
10 --muted: #6b7280;
11 --accent: #3b82f6;
12 --accent-hover: #2563eb;
13 --accent-border: #1d4ed8;
14 --danger: #ef4444;
15 --danger-border: #dc2626;
16 --border: #e5e7eb;
17 --topbar-h: 48px;
18 --select-arrow: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2.5' stroke-linecap='square'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
19}
20
21:root.dark {
22 color-scheme: dark;
23 --bg: #0f1115;
24 --panel: #171a20;
25 --text: #e5e7eb;
26 --muted: #9ca3af;
27 --accent: #60a5fa;
28 --accent-hover: #3b82f6;
29 --accent-border: #79b5fc;
30 --danger: #f87171;
31 --danger-border: #fa8b8b;
32 --border: #2a2f3a;
33 --select-arrow: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%239ca3af' stroke-width='2.5' stroke-linecap='square'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
34}
35
36@media (prefers-color-scheme: dark) {
37 :root:not(.light) {
38 color-scheme: dark;
39 --bg: #0f1115;
40 --panel: #171a20;
41 --text: #e5e7eb;
42 --muted: #9ca3af;
43 --accent: #60a5fa;
44 --accent-hover: #3b82f6;
45 --accent-border: #79b5fc;
46 --danger: #f87171;
47 --danger-border: #fa8b8b;
48 --border: #2a2f3a;
49 --select-arrow: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%239ca3af' stroke-width='2.5' stroke-linecap='square'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
50 }
51}
52
53* {
54 box-sizing: border-box;
55 /* The design language is sharp: everything stays square. */
56 border-radius: 0;
57}
58
59body {
60 margin: 0;
61 font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
62 background: var(--bg);
63 color: var(--text);
64 font-size: 15px;
65}
66
67.muted {
68 color: var(--muted);
69}
70
71.card {
72 background: var(--panel);
73 border: 1px solid var(--border);
74 padding: 24px;
75}
76
77.center-screen {
78 min-height: 100vh;
79 display: flex;
80 flex-direction: column;
81 align-items: center;
82 justify-content: center;
83 padding: 16px;
84 text-align: center;
85}
86
87.auth-card {
88 width: 100%;
89 max-width: 380px;
90}
91
92.auth-card h1 {
93 margin: 0 0 8px;
94 font-size: 22px;
95}
96
97.auth-logo {
98 width: 44px;
99 height: 44px;
100 margin-bottom: 12px;
101}
102
103.auth-card p {
104 margin: 0 0 20px;
105 font-size: 13px;
106}
107
108.field {
109 display: block;
110 margin-bottom: 14px;
111}
112
113.field span {
114 display: block;
115 font-size: 13px;
116 color: var(--muted);
117 margin-bottom: 4px;
118}
119
120input {
121 width: 100%;
122 padding: 10px 12px;
123 border: 1px solid var(--border);
124 background: var(--bg);
125 color: var(--text);
126 font-size: 14px;
127}
128
129input:focus {
130 outline: 2px solid var(--accent);
131 outline-offset: -1px;
132}
133
134/* Square checkboxes — native controls are rounded, the theme is sharp. */
135input[type="checkbox"] {
136 appearance: none;
137 -webkit-appearance: none;
138 width: 16px;
139 height: 16px;
140 margin: 0;
141 padding: 0;
142 flex: none;
143 border: 1px solid var(--border);
144 background: var(--panel);
145 cursor: pointer;
146 position: relative;
147 vertical-align: -3px;
148}
149
150input[type="checkbox"]:checked {
151 background: var(--accent);
152 border-color: var(--accent-border);
153}
154
155input[type="checkbox"]:checked::after {
156 content: "";
157 position: absolute;
158 left: 4px;
159 top: 1px;
160 width: 4px;
161 height: 8px;
162 border: solid #fff;
163 border-width: 0 2px 2px 0;
164 transform: rotate(45deg);
165}
166
167button {
168 font: inherit;
169 cursor: pointer;
170 display: inline-flex;
171 align-items: center;
172 justify-content: center;
173 gap: 6px;
174 border: 1px solid var(--border);
175 background: var(--panel);
176 color: var(--text);
177 padding: 9px 14px;
178}
179
180button:hover {
181 border-color: var(--muted);
182}
183
184button:disabled {
185 opacity: 0.6;
186 cursor: default;
187}
188
189.btn-primary {
190 width: 100%;
191 background: var(--accent);
192 /* One step away from the fill, per theme (see palette above), so the
193 button's edge reads the same as on neutral buttons. */
194 border-color: var(--accent-border);
195 color: #fff;
196 font-weight: 600;
197}
198
199.btn-primary:hover {
200 background: var(--accent-hover);
201 border-color: var(--accent-border);
202}
203
204.error {
205 color: var(--danger);
206 font-size: 13px;
207 min-height: 18px;
208 margin: 0 0 10px;
209}
210
211/* layout (signed-in): full-width topbar, then sidebar + content below */
212
213.layout {
214 min-height: 100vh;
215 display: flex;
216 flex-direction: column;
217}
218
219.topbar {
220 flex: none;
221 position: sticky;
222 top: 0;
223 z-index: 130;
224 height: var(--topbar-h);
225 display: flex;
226 align-items: center;
227 justify-content: space-between;
228 gap: 12px;
229 padding: 0 16px;
230 background: var(--panel);
231 border-bottom: 1px solid var(--border);
232}
233
234.topbar-left {
235 display: flex;
236 align-items: center;
237 gap: 10px;
238 min-width: 0;
239}
240
241.icon-btn.nav-toggle {
242 display: none;
243}
244
245.body-row {
246 flex: 1;
247 display: flex;
248 align-items: stretch;
249}
250
251/* ---- sidebar ---- */
252
253.sidebar {
254 flex: none;
255 width: 224px;
256 display: flex;
257 flex-direction: column;
258 background: var(--panel);
259 border-right: 1px solid var(--border);
260 position: sticky;
261 top: var(--topbar-h);
262 height: calc(100vh - var(--topbar-h));
263}
264
265.brand {
266 display: flex;
267 align-items: center;
268 gap: 10px;
269 font-weight: 700;
270 white-space: nowrap;
271 color: inherit;
272 text-decoration: none;
273 cursor: pointer;
274}
275
276.brand:hover {
277 opacity: 0.8;
278}
279
280.brand-name {
281 overflow: hidden;
282 text-overflow: ellipsis;
283}
284
285.logo {
286 width: 26px;
287 height: 26px;
288 flex: none;
289 display: block;
290}
291
292.nav {
293 flex: 1;
294 overflow-y: auto;
295 padding: 14px 8px 16px;
296 display: flex;
297 flex-direction: column;
298 gap: 20px;
299}
300
301.sidebar-user {
302 padding: 0 10px 2px;
303 font-size: 14px;
304 font-weight: 600;
305 overflow: hidden;
306 text-overflow: ellipsis;
307 white-space: nowrap;
308}
309
310.nav-section-label {
311 font-size: 11px;
312 font-weight: 700;
313 text-transform: uppercase;
314 letter-spacing: 0.08em;
315 color: var(--muted);
316 padding: 0 10px 6px;
317}
318
319/* Section header with a right-aligned action (the Files refresh). */
320.nav-section-head {
321 display: flex;
322 align-items: center;
323 justify-content: space-between;
324 gap: 6px;
325 margin-bottom: 4px;
326}
327
328.nav-section-head .nav-section-label {
329 flex: 1;
330 padding-bottom: 2px;
331}
332
333.nav-section-refresh {
334 color: var(--muted);
335 background: none;
336 border-color: transparent;
337 padding: 3px 5px;
338}
339
340.nav-section-refresh:hover {
341 color: var(--text);
342 border-color: var(--border);
343}
344
345.nav-tab {
346 display: flex;
347 align-items: center;
348 justify-content: flex-start;
349 gap: 10px;
350 width: 100%;
351 margin-bottom: 2px;
352 padding: 8px 10px;
353 text-align: left;
354 background: none;
355 border: none;
356 color: var(--muted);
357 font-size: 14px;
358}
359
360.nav-tab:hover {
361 background: var(--bg);
362 color: var(--text);
363}
364
365.nav-tab.active {
366 background: var(--accent);
367 border-color: var(--accent);
368 color: #fff;
369}
370
371.ic-tab {
372 width: 18px;
373 height: 18px;
374 flex: none;
375}
376
377.nav-tab.active .icon {
378 color: #fff;
379}
380
381.nav-tab-name {
382 flex: 1;
383 min-width: 0;
384 overflow: hidden;
385 text-overflow: ellipsis;
386 white-space: nowrap;
387}
388
389.nav-tab-note {
390 flex: none;
391 font-size: 10px;
392 font-weight: 700;
393 padding: 1px 5px;
394 background: var(--bg);
395 border: 1px solid var(--border);
396 color: var(--muted);
397}
398
399.nav-tab.active .nav-tab-note {
400 background: rgb(255 255 255 / 18%);
401 border-color: rgb(255 255 255 / 30%);
402 color: #fff;
403}
404
405.nav-backdrop {
406 display: none;
407}
408
409/* Sidebar footer: theme toggle, log out, and the project version.
410 Sits at the bottom of the sidebar, below the manage section. */
411.sidebar-footer {
412 flex: none;
413 border-top: 1px solid var(--border);
414 padding: 8px;
415}
416
417.sidebar-footer .nav-tab {
418 margin-bottom: 0;
419}
420
421.sidebar-action.logout {
422 color: var(--danger);
423}
424
425.sidebar-action.logout:hover {
426 color: var(--danger);
427}
428
429.sidebar-version {
430 margin-top: 8px;
431 padding: 0 10px;
432 font-size: 11.5px;
433 color: var(--muted);
434 white-space: nowrap;
435 overflow: hidden;
436 text-overflow: ellipsis;
437}
438
439.badge {
440 font-size: 11px;
441 padding: 2px 8px;
442 background: var(--bg);
443 border: 1px solid var(--border);
444 color: var(--muted);
445}
446
447.content {
448 flex: 1;
449 min-width: 0;
450 min-height: 0;
451 display: flex;
452 flex-direction: column;
453 padding: 20px;
454}
455
456/* While a file is open the app is a fixed-height frame: the file view
457 * (editor, image, …) scrolls inside, the page itself never grows. */
458.layout.file-mode {
459 height: 100vh;
460 overflow: hidden;
461}
462
463.layout.file-mode .body-row {
464 min-height: 0;
465}
466
467/* Narrow screens: the sidebar becomes an off-canvas drawer that only
468 covers the content, below the (always visible) topbar. */
469@media (max-width: 860px) {
470 .sidebar {
471 position: fixed;
472 top: var(--topbar-h);
473 bottom: 0;
474 left: 0;
475 right: auto;
476 height: auto;
477 z-index: 120;
478 transform: translateX(-100%);
479 transition: transform 0.15s ease;
480 }
481
482 .sidebar.open {
483 transform: translateX(0);
484 box-shadow: 0 0 48px rgb(0 0 0 / 35%);
485 }
486
487 .nav-backdrop {
488 display: block;
489 position: fixed;
490 top: var(--topbar-h);
491 bottom: 0;
492 left: 0;
493 right: 0;
494 z-index: 110;
495 background: rgb(0 0 0 / 40%);
496 }
497
498 .icon-btn.nav-toggle {
499 display: inline-flex;
500 }
501
502 .content {
503 padding: 14px;
504 }
505}
506
507/* ---- file browser ---- */
508
509.browser {
510 width: 100%;
511 max-width: 1200px;
512 margin: 0 auto;
513 flex: 1;
514 display: flex;
515 flex-direction: column;
516 min-height: 0;
517}
518
519.icon {
520 width: 20px;
521 height: 20px;
522 display: inline-block;
523 vertical-align: middle;
524}
525
526.ic-folder {
527 color: var(--accent);
528}
529
530.ic-muted {
531 color: var(--muted);
532}
533
534.crumbs {
535 display: flex;
536 align-items: center;
537 gap: 2px;
538 padding: 6px 0 12px;
539 font-size: 15px;
540 flex-wrap: wrap;
541}
542
543.crumb {
544 cursor: pointer;
545 color: var(--muted);
546 padding: 3px 6px;
547}
548
549.crumb:hover {
550 color: var(--text);
551 background: var(--panel);
552}
553
554.crumb.current {
555 color: var(--text);
556 font-weight: 600;
557 cursor: default;
558 background: none;
559}
560
561.crumb-sep {
562 color: var(--muted);
563 padding: 0 1px;
564}
565
566.toolbar {
567 display: flex;
568 align-items: center;
569 justify-content: space-between;
570 gap: 6px;
571 padding-bottom: 12px;
572}
573
574.toolbar-right {
575 display: flex;
576 gap: 6px;
577}
578
579.icon-btn {
580 padding: 7px 9px;
581 border: 1px solid var(--border);
582 background: var(--panel);
583 color: var(--muted);
584 display: inline-flex;
585 align-items: center;
586}
587
588.icon-btn:hover {
589 border-color: var(--muted);
590}
591
592.icon-btn.active {
593 background: var(--accent);
594 border-color: var(--accent);
595 color: #fff;
596}
597
598.ic-btn {
599 width: 18px;
600 height: 18px;
601 color: inherit;
602}
603
604.entries-area {
605 flex: 1;
606 min-height: 240px;
607}
608
609.center-note {
610 text-align: center;
611 padding: 48px 0;
612}
613
614.error-card {
615 display: flex;
616 align-items: center;
617 justify-content: space-between;
618 gap: 16px;
619 color: var(--danger);
620 font-size: 14px;
621}
622
623/* root tiles were replaced by the sidebar's folder tabs */
624
625/* grid view */
626
627.entries-grid {
628 display: grid;
629 grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
630 gap: 10px;
631}
632
633.tile {
634 background: var(--panel);
635 border: 1px solid var(--border);
636 padding: 16px 10px 12px;
637 text-align: center;
638 cursor: pointer;
639 user-select: none;
640}
641
642.tile:hover {
643 border-color: var(--muted);
644}
645
646.tile-icon {
647 width: 42px;
648 height: 42px;
649 margin: 0 auto 10px;
650 display: block;
651}
652
653.tile-name {
654 font-size: 13px;
655 line-height: 1.3;
656 word-break: break-word;
657}
658
659/* list view */
660
661.entries-list {
662 background: var(--panel);
663 border: 1px solid var(--border);
664 overflow: hidden;
665}
666
667.row {
668 display: grid;
669 grid-template-columns: 28px minmax(0, 1fr) 90px 150px;
670 gap: 12px;
671 align-items: center;
672 padding: 9px 14px;
673 border-bottom: 1px solid var(--border);
674 cursor: pointer;
675 font-size: 14px;
676 user-select: none;
677}
678
679.row:last-child {
680 border-bottom: none;
681}
682
683.row:hover {
684 background: var(--bg);
685}
686
687.row-icon {
688 width: 20px;
689 height: 20px;
690}
691
692.row-name {
693 overflow: hidden;
694 text-overflow: ellipsis;
695 white-space: nowrap;
696}
697
698.row-size,
699.row-date {
700 font-size: 13px;
701 text-align: right;
702}
703
704@media (max-width: 640px) {
705 .row {
706 grid-template-columns: 28px minmax(0, 1fr) 90px;
707 }
708
709 .row-date {
710 display: none;
711 }
712}
713
714/* context menu */
715
716.ctx-menu {
717 position: fixed;
718 z-index: 100;
719 min-width: 190px;
720 background: var(--panel);
721 border: 1px solid var(--border);
722 padding: 5px;
723 box-shadow: 0 8px 24px rgb(0 0 0 / 18%);
724}
725
726.ctx-item {
727 display: flex;
728 align-items: center;
729 gap: 10px;
730 padding: 8px 12px;
731 font-size: 14px;
732 cursor: pointer;
733}
734
735.ic-ctx {
736 width: 18px;
737 height: 18px;
738 flex: none;
739}
740
741.ctx-item:hover {
742 background: var(--bg);
743}
744
745.ctx-item.disabled {
746 opacity: 0.45;
747 cursor: default;
748}
749
750.ctx-item.disabled:hover {
751 background: none;
752}
753
754/* toolbar selection actions (top right) */
755
756.sel-actions {
757 display: flex;
758 align-items: center;
759 gap: 6px;
760 position: relative;
761}
762
763.sel-actions .icon-btn:disabled {
764 opacity: 0.45;
765 cursor: default;
766}
767
768.sel-actions .icon-btn:disabled:hover {
769 border-color: var(--border);
770 color: var(--muted);
771}
772
773.sel-more-wrap {
774 position: relative;
775}
776
777.sel-more-menu {
778 position: absolute;
779 right: 0;
780 top: calc(100% + 6px);
781 z-index: 100;
782 min-width: 190px;
783 background: var(--panel);
784 border: 1px solid var(--border);
785 padding: 5px;
786 box-shadow: 0 8px 24px rgb(0 0 0 / 18%);
787}
788
789.sel-more-menu.hidden {
790 display: none;
791}
792
793/* selection actions in the top bar */
794
795.topbar .sel-actions {
796 min-height: 0;
797}
798
799.topbar .sel-actions .icon-btn {
800 padding: 5px 7px;
801}
802
803/* selection highlight in the grid and list */
804
805.tile.selected {
806 border-color: var(--accent);
807 background: color-mix(in srgb, var(--accent) 12%, var(--panel));
808}
809
810.row.selected {
811 background: color-mix(in srgb, var(--accent) 12%, var(--panel));
812 box-shadow: inset 2px 0 0 var(--accent);
813}
814
815/* settings tabs (profile / server) */
816
817.settings-tabs {
818 display: flex;
819 gap: 8px;
820}
821
822.settings-tab-btn {
823 padding: 7px 14px;
824 border: 1px solid var(--border);
825 background: var(--panel);
826 color: var(--muted);
827 font-size: 13px;
828 font-weight: 600;
829}
830
831.settings-tab-btn:hover {
832 border-color: var(--muted);
833 color: var(--text);
834}
835
836.settings-tab-btn.active {
837 border-color: var(--accent);
838 color: var(--accent);
839 background: color-mix(in srgb, var(--accent) 10%, var(--panel));
840}
841
842/* toast */
843
844.toast {
845 position: fixed;
846 bottom: 20px;
847 right: 20px;
848 z-index: 200;
849 background: var(--panel);
850 color: var(--text);
851 border: 1px solid var(--border);
852 padding: 11px 16px;
853 font-size: 14px;
854 box-shadow: 0 8px 24px rgb(0 0 0 / 18%);
855 max-width: 320px;
856}
857
858.toast-error {
859 background: color-mix(in srgb, var(--danger) 12%, var(--panel));
860 border-color: var(--danger-border);
861 color: var(--danger);
862}
863
864
865/* ---- modals ---- */
866
867.modal-overlay {
868 position: fixed;
869 inset: 0;
870 background: rgb(0 0 0 / 45%);
871 display: flex;
872 align-items: center;
873 justify-content: center;
874 z-index: 100;
875}
876
877.modal {
878 width: 440px;
879 max-width: calc(100vw - 32px);
880 padding: 20px;
881 background: var(--panel);
882 border: 1px solid var(--border);
883 box-shadow: 0 12px 44px rgb(0 0 0 / 35%);
884}
885
886.modal.picker {
887 width: 520px;
888}
889
890.modal-title {
891 margin: 0 0 12px;
892 font-size: 16px;
893}
894
895.modal-label {
896 display: block;
897 font-size: 13px;
898 color: var(--muted);
899 margin-bottom: 6px;
900}
901
902.modal .input {
903 width: 100%;
904 box-sizing: border-box;
905 margin-bottom: 16px;
906}
907
908.modal-label.error,
909.dialog-error {
910 color: var(--danger);
911 font-size: 13px;
912}
913
914.dialog-error {
915 margin-top: 8px;
916}
917
918.modal-message {
919 white-space: pre-line;
920 font-size: 14px;
921 margin: 0 0 8px;
922}
923
924.modal-actions {
925 display: flex;
926 justify-content: flex-end;
927 gap: 8px;
928 margin-top: 16px;
929}
930
931.btn-danger {
932 background: var(--danger);
933 /* A visible border (one step away from the fill, per theme) so the
934 button's edge reads the same as on neutral buttons. */
935 border-color: var(--danger-border);
936 color: #fff;
937}
938
939.btn-danger:hover {
940 background: color-mix(in srgb, var(--danger) 85%, black);
941}
942
943.btn:disabled {
944 opacity: 0.5;
945 cursor: not-allowed;
946}
947
948.conflict-list {
949 max-height: 200px;
950 overflow-y: auto;
951 margin: 8px 0;
952 padding-left: 20px;
953 font-size: 13px;
954}
955
956.picker-roots {
957 display: flex;
958 gap: 6px;
959 flex-wrap: wrap;
960 margin-bottom: 12px;
961}
962
963.root-opt {
964 font-size: 13px;
965}
966
967.root-opt.active {
968 background: var(--accent);
969 border-color: var(--accent);
970 color: #fff;
971}
972
973.picker-current {
974 font-size: 13px;
975 margin: 0 0 8px;
976}
977
978.picker-crumbs {
979 margin-bottom: 8px;
980}
981
982.picker-entries {
983 max-height: 240px;
984 overflow-y: auto;
985 border: 1px solid var(--border);
986}
987
988.picker-row {
989 display: flex;
990 align-items: center;
991 gap: 10px;
992 padding: 8px 12px;
993 cursor: pointer;
994}
995
996.picker-row:hover {
997 background: var(--bg);
998}
999
1000/* ---------------------------------------------------------------------------
1001 * Full-page file view (preview / editor / "no preview"). The top bar carries
1002 * the title + actions; the content area below is edge to edge.
1003 * ------------------------------------------------------------------------- */
1004.content.file-open {
1005 padding: 0;
1006 overflow: hidden;
1007}
1008
1009/* The browser stays mounted (state, fetch callback) but hidden. */
1010.content.file-open .browser {
1011 display: none;
1012}
1013
1014.file-view {
1015 flex: 1;
1016 min-height: 0;
1017 display: flex;
1018 flex-direction: column;
1019}
1020
1021.file-title {
1022 display: flex;
1023 align-items: center;
1024 gap: 8px;
1025 min-width: 0;
1026}
1027
1028.file-title-icon {
1029 width: 18px;
1030 height: 18px;
1031 flex: none;
1032 color: var(--muted);
1033}
1034
1035.file-title-name {
1036 font-weight: 600;
1037 font-size: 14px;
1038 white-space: nowrap;
1039 overflow: hidden;
1040 text-overflow: ellipsis;
1041}
1042
1043.file-actions {
1044 display: flex;
1045 align-items: center;
1046 gap: 10px;
1047 flex: none;
1048}
1049
1050.file-close {
1051 border: none;
1052 background: transparent;
1053 color: var(--muted);
1054 padding: 6px 8px;
1055}
1056
1057.file-close:hover {
1058 color: var(--text);
1059 background: var(--bg);
1060}
1061.preview-body {
1062 flex: 1;
1063 min-height: 0;
1064 overflow: auto;
1065 display: flex;
1066 background: var(--bg);
1067}
1068.preview-img {
1069 max-width: 100%;
1070 max-height: 100%;
1071 display: block;
1072 margin: auto;
1073}
1074.preview-pdf {
1075 width: 100%;
1076 height: 100%;
1077 border: none;
1078 background: #fff;
1079}
1080.preview-video {
1081 width: 100%;
1082 max-height: 100%;
1083 background: #000;
1084}
1085.preview-audio {
1086 display: flex;
1087 align-items: center;
1088 justify-content: center;
1089 width: 100%;
1090 padding: 24px;
1091}
1092.preview-audio audio {
1093 width: 100%;
1094 max-width: 480px;
1095}
1096
1097/* CodeMirror (text editor) */
1098.cm-container {
1099 height: 100%;
1100}
1101.cm-container .cm-editor {
1102 height: 100%;
1103}
1104/* Load/save failure: dims the editor and shows the message in a card
1105 * (the top-bar Save button stays reachable to retry). */
1106.cm-error {
1107 position: absolute;
1108 inset: 0;
1109 z-index: 5;
1110 display: flex;
1111 align-items: center;
1112 justify-content: center;
1113 padding: 24px;
1114 background: rgb(0 0 0 / 45%);
1115}
1116
1117.cm-error-card {
1118 position: relative;
1119 max-width: 440px;
1120 min-width: 200px;
1121 background: var(--panel);
1122 border: 1px solid var(--border);
1123 box-shadow: 0 12px 44px rgb(0 0 0 / 35%);
1124}
1125
1126.cm-error-close {
1127 position: absolute;
1128 top: 7px;
1129 right: 7px;
1130 display: inline-flex;
1131 align-items: center;
1132 justify-content: center;
1133 border: none;
1134 background: transparent;
1135 color: var(--muted);
1136 padding: 3px;
1137}
1138
1139.cm-error-close:hover {
1140 color: var(--text);
1141 background: var(--bg);
1142}
1143
1144.cm-error-close .ic-btn {
1145 width: 16px;
1146 height: 16px;
1147}
1148
1149.cm-error-text {
1150 padding: 16px 40px 16px 20px;
1151 font-size: 14px;
1152 text-align: center;
1153 overflow-wrap: anywhere;
1154}
1155
1156/* ---------------------------------------------------------------------------
1157 * Text editor (full page; title/save/close live in the top bar)
1158 * ------------------------------------------------------------------------- */
1159.file-editor {
1160 flex: 1;
1161 min-height: 0;
1162 display: flex;
1163 position: relative;
1164 background: var(--bg);
1165}
1166.file-editor .cm-container {
1167 width: 100%;
1168 height: 100%;
1169}
1170/* "No preview" fallback (binaries, archives). */
1171.file-nopreview {
1172 flex: 1;
1173 display: flex;
1174 align-items: center;
1175 justify-content: center;
1176}
1177.file-nopreview .btn-primary {
1178 width: auto;
1179 margin-top: 14px;
1180}
1181/* Conflict / discard dialogs render above the file view. */
1182.editor-sub-overlay {
1183 z-index: 101;
1184 background: rgb(0 0 0 / 25%);
1185}
1186
1187/* ---------------------------------------------------------------------------
1188 * Download format dialog
1189 * ------------------------------------------------------------------------- */
1190.dl-formats {
1191 display: flex;
1192 flex-direction: column;
1193 gap: 8px;
1194 margin-bottom: 8px;
1195}
1196.dl-fmt {
1197 justify-content: flex-start;
1198}
1199
1200/* ---------------------------------------------------------------------------
1201 * Item info dialog
1202 * ------------------------------------------------------------------------- */
1203.info-list {
1204 margin: 8px 0 16px;
1205 display: grid;
1206 grid-template-columns: 90px 1fr;
1207 row-gap: 8px;
1208 column-gap: 12px;
1209}
1210.info-list dt {
1211 color: var(--muted);
1212}
1213.info-list dd {
1214 margin: 0;
1215 word-break: break-word;
1216}
1217
1218/* ---------------------------------------------------------------------------
1219 Shares (milestone 6)
1220 --------------------------------------------------------------------------- */
1221
1222.share-modal {
1223 width: 480px;
1224}
1225
1226.share-link-row {
1227 display: flex;
1228 gap: 8px;
1229 margin: 12px 0;
1230}
1231
1232.share-link-input {
1233 flex: 1;
1234 font-family: ui-monospace, monospace;
1235 font-size: 12.5px;
1236 padding: 8px 10px;
1237 border: 1px solid var(--border);
1238 background: var(--bg);
1239 color: var(--text);
1240 min-width: 0;
1241}
1242
1243.share-check {
1244 display: flex;
1245 align-items: center;
1246 gap: 8px;
1247 margin: 4px 0 14px;
1248 font-size: 14px;
1249}
1250
1251.share-check input {
1252 width: 16px;
1253 height: 16px;
1254}
1255
1256.share-expiry-row {
1257 display: flex;
1258 align-items: center;
1259 gap: 10px;
1260 margin: 0 0 10px;
1261}
1262
1263.share-expiry-row label {
1264 font-size: 13px;
1265 color: var(--muted);
1266 min-width: 52px;
1267}
1268
1269.share-expiry-row select,
1270.share-expiry-row input {
1271 flex: 1;
1272 padding: 8px 10px;
1273 border: 1px solid var(--border);
1274 background: var(--panel);
1275 color: var(--text);
1276 font: inherit;
1277}
1278
1279.share-expiry-note {
1280 margin: 4px 0 0;
1281 font-size: 12.5px;
1282}
1283
1284.btn-sm {
1285 padding: 5px 10px;
1286 font-size: 12.5px;
1287}
1288
1289.icon-btn-sm {
1290 padding: 4px 6px;
1291}
1292
1293/* "Your shares" manage view */
1294
1295.shares-view {
1296 width: 100%;
1297 max-width: 960px;
1298 margin: 0 auto;
1299}
1300
1301.view-header {
1302 margin-bottom: 16px;
1303}
1304
1305.view-header .admin-section-title {
1306 margin-bottom: 0;
1307}
1308
1309.view-hint {
1310 margin: 4px 0 0;
1311 font-size: 13px;
1312 max-width: 64ch;
1313}
1314
1315.share-list {
1316 display: flex;
1317 flex-direction: column;
1318 gap: 10px;
1319}
1320
1321.share-item {
1322 display: flex;
1323 align-items: center;
1324 justify-content: space-between;
1325 gap: 12px;
1326 padding: 10px 12px;
1327 border: 1px solid var(--border);
1328 background: var(--panel);
1329}
1330
1331.share-item-main {
1332 min-width: 0;
1333}
1334
1335.share-item-name {
1336 display: flex;
1337 align-items: center;
1338 gap: 8px;
1339 font-weight: 600;
1340 font-size: 14px;
1341 overflow: hidden;
1342 text-overflow: ellipsis;
1343 white-space: nowrap;
1344}
1345
1346.ic-row {
1347 width: 18px;
1348 height: 18px;
1349 flex: none;
1350}
1351
1352.share-item-meta {
1353 font-size: 12px;
1354 margin-top: 2px;
1355 overflow: hidden;
1356 text-overflow: ellipsis;
1357 white-space: nowrap;
1358}
1359
1360.share-item-actions {
1361 display: flex;
1362 gap: 6px;
1363 flex-shrink: 0;
1364}
1365
1366/* ------------------------------------------------------------------ */
1367/* Admin (milestone 7) */
1368/* ------------------------------------------------------------------ */
1369
1370.admin-view {
1371 display: flex;
1372 flex-direction: column;
1373 gap: 16px;
1374 width: 100%;
1375 max-width: 960px;
1376 margin: 0 auto;
1377}
1378
1379.admin-section-title {
1380 margin: 0 0 14px;
1381 font-size: 15px;
1382}
1383
1384.users-header {
1385 display: flex;
1386 align-items: center;
1387 justify-content: space-between;
1388 margin-bottom: 4px;
1389}
1390
1391.users-header .admin-section-title {
1392 margin-bottom: 0;
1393}
1394
1395.users-header .btn-primary {
1396 width: auto;
1397}
1398
1399.user-list {
1400 display: flex;
1401 flex-direction: column;
1402 gap: 10px;
1403}
1404
1405.user-row {
1406 display: flex;
1407 align-items: center;
1408 justify-content: space-between;
1409 gap: 12px;
1410 padding: 12px 14px;
1411 border: 1px solid var(--border);
1412}
1413
1414.user-row-main {
1415 min-width: 0;
1416}
1417
1418.user-row-name {
1419 display: flex;
1420 align-items: center;
1421 gap: 6px;
1422 font-weight: 600;
1423 font-size: 14px;
1424 flex-wrap: wrap;
1425}
1426
1427.ic-admin {
1428 width: 16px;
1429 height: 16px;
1430 flex: none;
1431}
1432
1433.user-row-actions {
1434 display: flex;
1435 gap: 6px;
1436 flex-shrink: 0;
1437}
1438
1439.badge-off {
1440 background: color-mix(in srgb, var(--danger) 15%, var(--panel));
1441 border-color: var(--danger);
1442 color: var(--danger);
1443}
1444
1445.setting-row {
1446 display: flex;
1447 align-items: center;
1448 gap: 10px;
1449 padding: 14px;
1450 border: 1px solid var(--border);
1451 cursor: pointer;
1452}
1453
1454.setting-row input {
1455 margin-left: auto;
1456}
1457
1458.setting-label {
1459 display: block;
1460 font-weight: 600;
1461 font-size: 14px;
1462}
1463
1464.setting-desc {
1465 display: block;
1466 font-size: 12px;
1467 color: var(--muted);
1468 margin-top: 2px;
1469}
1470
1471/* Setting row whose control is a select, pushed to the right. */
1472.setting-row-select {
1473 cursor: default;
1474}
1475
1476.setting-row-select > span {
1477 flex: 1;
1478}
1479
1480.setting-row-select select {
1481 appearance: none;
1482 margin-left: auto;
1483 padding: 10px 42px 10px 12px;
1484 border: 1px solid var(--border);
1485 background-color: var(--panel);
1486 background-image: var(--select-arrow);
1487 background-repeat: no-repeat;
1488 background-position: right 12px center;
1489 background-size: 14px 14px;
1490 color: var(--text);
1491 font: inherit;
1492 max-width: 190px;
1493}
1494
1495/* User create/edit form */
1496
1497.user-form {
1498 width: 520px;
1499}
1500
1501.field-input {
1502 width: 100%;
1503 box-sizing: border-box;
1504}
1505
1506.field-hint {
1507 font-size: 12px;
1508 margin: -2px 0 8px;
1509}
1510
1511.check-row {
1512 display: flex;
1513 align-items: center;
1514 gap: 8px;
1515 font-size: 14px;
1516 margin-bottom: 12px;
1517 cursor: pointer;
1518}
1519
1520.check-row input {
1521 width: auto;
1522}
1523
1524.form-error {
1525 color: var(--danger);
1526 font-size: 13px;
1527 margin: 4px 0 8px;
1528}
1529
1530.roots-editor {
1531 display: flex;
1532 flex-direction: column;
1533 gap: 6px;
1534}
1535
1536.root-draft {
1537 display: flex;
1538 align-items: center;
1539 gap: 8px;
1540}
1541
1542.root-draft-path {
1543 flex: 1;
1544 font-size: 13px;
1545 overflow: hidden;
1546 text-overflow: ellipsis;
1547 white-space: nowrap;
1548}
1549
1550.root-draft-mode {
1551 width: auto;
1552 padding: 6px 8px;
1553}
1554
1555.root-add {
1556 display: flex;
1557 gap: 8px;
1558 margin-top: 4px;
1559}
1560
1561/* ------------------------------------------------------------------ */
1562/* Empty state + keyboard focus (milestone 8) */
1563/* ------------------------------------------------------------------ */
1564
1565.empty-state {
1566 display: flex;
1567 flex-direction: column;
1568 align-items: center;
1569 justify-content: center;
1570 gap: 8px;
1571 padding: 64px 20px;
1572 text-align: center;
1573}
1574
1575.empty-glyph {
1576 width: 52px;
1577 height: 52px;
1578}
1579
1580.empty-state h3 {
1581 margin: 0;
1582 font-size: 16px;
1583}
1584
1585/* Visible keyboard focus on selectable file/folder entries. The ring is
1586 inset (negative offset) so the scroll container never clips it. */
1587.tile:focus-visible,
1588.row:focus-visible {
1589 outline: 2px solid var(--accent);
1590 outline-offset: -2px;
1591}
1592
1593/* ------------------------------------------------------------------ */
1594/* Search view (#/search) */
1595/* ------------------------------------------------------------------ */
1596
1597.search-view {
1598 display: flex;
1599 flex-direction: column;
1600 gap: 14px;
1601}
1602
1603/* Query bar ------------------------------------------------------ */
1604
1605.query-bar {
1606 display: flex;
1607 align-items: stretch;
1608 gap: 8px;
1609}
1610
1611.query-input {
1612 flex: 1;
1613 display: flex;
1614 align-items: center;
1615 gap: 8px;
1616 background: var(--panel);
1617 border: 1px solid var(--border);
1618 padding: 0 10px;
1619 min-width: 0;
1620}
1621
1622.query-input .qi-icon {
1623 width: 18px;
1624 height: 18px;
1625 color: var(--muted);
1626 flex: none;
1627}
1628
1629.query-input input {
1630 flex: 1;
1631 min-width: 0;
1632 border: none;
1633 outline: none;
1634 background: transparent;
1635 color: var(--text);
1636 font: inherit;
1637 font-size: 14px;
1638 height: 38px;
1639 padding: 0;
1640}
1641
1642.query-input input::placeholder {
1643 color: var(--muted);
1644}
1645
1646/* Segmented Name / Content / Both control */
1647
1648.seg {
1649 display: flex;
1650 border: 1px solid var(--border);
1651 background: var(--panel);
1652}
1653
1654.seg button {
1655 appearance: none;
1656 border: none;
1657 border-right: 1px solid var(--border);
1658 background: transparent;
1659 color: var(--muted);
1660 font: inherit;
1661 font-size: 13px;
1662 padding: 0 14px;
1663 cursor: pointer;
1664}
1665
1666.seg button:last-child {
1667 border-right: none;
1668}
1669
1670.seg button:hover {
1671 background: var(--bg);
1672}
1673
1674.seg button.on {
1675 background: var(--accent);
1676 color: #fff;
1677}
1678
1679/* Roots multi-select --------------------------------------------- */
1680
1681/* The root a search covers. A native select, styled like the query bar. */
1682.root-select {
1683 flex: none;
1684 max-width: 220px;
1685 border: 1px solid var(--border);
1686 background: var(--panel);
1687 color: var(--text);
1688 font: inherit;
1689 font-size: 13px;
1690 padding: 0 10px;
1691}
1692
1693.ms {
1694 position: relative;
1695 display: flex;
1696}
1697
1698.ms-btn {
1699 display: flex;
1700 align-items: center;
1701 gap: 6px;
1702 border: 1px solid var(--border);
1703 background: var(--panel);
1704 color: var(--text);
1705 font: inherit;
1706 font-size: 13px;
1707 padding: 0 10px;
1708 cursor: pointer;
1709 max-width: 180px;
1710}
1711
1712.ms-btn:hover {
1713 background: var(--bg);
1714}
1715
1716.ms-btn > span {
1717 overflow: hidden;
1718 text-overflow: ellipsis;
1719 white-space: nowrap;
1720}
1721
1722/* Square caret drawn with borders (the icon set has no chevron). */
1723.ms-caret {
1724 flex: none;
1725 width: 8px;
1726 height: 8px;
1727 border-right: 2px solid var(--muted);
1728 border-bottom: 2px solid var(--muted);
1729 transform: rotate(45deg) translate(-1px, -1px);
1730}
1731
1732.ms-backdrop {
1733 position: fixed;
1734 inset: 0;
1735 z-index: 40;
1736}
1737
1738.ms-drop {
1739 position: absolute;
1740 right: 0;
1741 top: calc(100% + 4px);
1742 z-index: 41;
1743 min-width: 200px;
1744 max-height: 280px;
1745 overflow: auto;
1746 background: var(--panel);
1747 border: 1px solid var(--border);
1748 padding: 4px 0;
1749}
1750
1751.ms-opt {
1752 display: flex;
1753 align-items: center;
1754 gap: 8px;
1755 padding: 7px 12px;
1756 font-size: 14px;
1757 cursor: pointer;
1758 user-select: none;
1759}
1760
1761.ms-opt:hover {
1762 background: var(--bg);
1763}
1764
1765.ms-opt span {
1766 overflow: hidden;
1767 text-overflow: ellipsis;
1768 white-space: nowrap;
1769}
1770
1771/* Run / stop ------------------------------------------------------- */
1772
1773.btn-run {
1774 border: 1px solid var(--accent-border);
1775 background: var(--accent);
1776 color: #fff;
1777 font: inherit;
1778 font-size: 13px;
1779 font-weight: 600;
1780 padding: 0 18px;
1781 cursor: pointer;
1782}
1783
1784.btn-run:hover {
1785 background: var(--accent-hover);
1786}
1787
1788.btn-stop {
1789 display: flex;
1790 align-items: center;
1791 gap: 6px;
1792 border: 1px solid var(--danger-border);
1793 background: var(--danger);
1794 color: #fff;
1795 font: inherit;
1796 font-size: 13px;
1797 font-weight: 600;
1798 padding: 0 14px;
1799 cursor: pointer;
1800}
1801
1802.btn-stop:hover {
1803 opacity: 0.9;
1804}
1805
1806.btn-stop .ic-stop {
1807 width: 14px;
1808 height: 14px;
1809}
1810
1811/* Status line ------------------------------------------------------ */
1812
1813.status-line {
1814 display: flex;
1815 align-items: center;
1816 gap: 8px;
1817 font-size: 13px;
1818 color: var(--muted);
1819}
1820
1821.status-line .dot {
1822 width: 8px;
1823 height: 8px;
1824 background: var(--accent);
1825 animation: search-pulse 1s ease-in-out infinite;
1826}
1827
1828@keyframes search-pulse {
1829 0%,
1830 100% {
1831 opacity: 1;
1832 }
1833 50% {
1834 opacity: 0.3;
1835 }
1836}
1837
1838.status-line .skip {
1839 opacity: 0.75;
1840}
1841
1842/* Group labels ----------------------------------------------------- */
1843
1844.group-label {
1845 display: flex;
1846 align-items: center;
1847 gap: 8px;
1848 font-size: 12px;
1849 font-weight: 600;
1850 letter-spacing: 0.04em;
1851 text-transform: uppercase;
1852 color: var(--muted);
1853}
1854
1855/* Result group: a `display:flex` (or `none`, from the inline style) flex
1856 item of `.search-view` that re-establishes the column layout for its
1857 label/list/more-row children. */
1858.result-group {
1859 flex-direction: column;
1860 gap: 14px;
1861}
1862
1863.group-label .gl-icon {
1864 width: 15px;
1865 height: 15px;
1866}
1867
1868.group-label .n {
1869 font-weight: 400;
1870 text-transform: none;
1871 letter-spacing: 0;
1872}
1873
1874.group-label .grow {
1875 flex: 1;
1876}
1877
1878.collapse-all {
1879 appearance: none;
1880 border: 1px solid var(--border);
1881 background: transparent;
1882 color: var(--muted);
1883 font: inherit;
1884 font-size: 12px;
1885 text-transform: none;
1886 letter-spacing: 0;
1887 padding: 3px 10px;
1888 cursor: pointer;
1889}
1890
1891.collapse-all:hover {
1892 background: var(--bg);
1893 color: var(--text);
1894}
1895
1896/* Name-result rows --------------------------------------------------- */
1897
1898.srow {
1899 display: grid;
1900 /* icon | name+dir | size | goto */
1901 grid-template-columns: 28px minmax(0, 1fr) 90px 30px;
1902 gap: 12px;
1903 align-items: center;
1904 padding: 9px 14px;
1905 border-bottom: 1px solid var(--border);
1906 cursor: pointer;
1907 font-size: 14px;
1908 user-select: none;
1909}
1910
1911.srow:last-child {
1912 border-bottom: none;
1913}
1914
1915.srow:hover {
1916 background: var(--bg);
1917}
1918
1919.srow-icon {
1920 width: 20px;
1921 height: 20px;
1922}
1923
1924.srow-main {
1925 min-width: 0;
1926 display: flex;
1927 flex-direction: column;
1928 line-height: 1.3;
1929}
1930
1931.srow-name {
1932 overflow: hidden;
1933 text-overflow: ellipsis;
1934 white-space: nowrap;
1935}
1936
1937/* Highlighted query hits (plain fragments render as bare spans). */
1938mark.hl-hit {
1939 background: color-mix(in srgb, var(--accent) 25%, transparent);
1940 color: inherit;
1941}
1942
1943/* The directory-path line (the name line lives inside .srow-name). */
1944.srow-dir {
1945 font-size: 12px;
1946 color: var(--muted);
1947 overflow: hidden;
1948 text-overflow: ellipsis;
1949 white-space: nowrap;
1950}
1951
1952.srow-dir mark.hl-hit {
1953 color: inherit;
1954}
1955
1956.ssize {
1957 font-size: 13px;
1958 color: var(--muted);
1959 text-align: right;
1960}
1961
1962/* Paging footer: position in the results on the left, the action on the
1963 right. Separated from the list by its own border so the button never reads
1964 as another result row. */
1965.page-foot {
1966 display: flex;
1967 align-items: center;
1968 justify-content: space-between;
1969 gap: 12px;
1970 padding: 10px 14px;
1971 border-top: 1px solid var(--border);
1972 font-size: 12px;
1973 color: var(--muted);
1974}
1975
1976.page-foot .pf-count {
1977 font-variant-numeric: tabular-nums;
1978}
1979
1980.page-foot .pf-more {
1981 appearance: none;
1982 padding: 5px 12px;
1983 border: 1px solid var(--border);
1984 background: var(--panel);
1985 font: inherit;
1986 font-weight: 500;
1987 color: var(--text);
1988 cursor: pointer;
1989}
1990
1991.page-foot .pf-more:hover {
1992 border-color: var(--accent);
1993 color: var(--accent);
1994}
1995
1996/* Content matches ----------------------------------------------------- */
1997
1998.match-card {
1999 background: var(--panel);
2000 border: 1px solid var(--border);
2001 border-top: none;
2002}
2003
2004/* The first card is the one right after the group label; `:first-of-type`
2005 cannot be used because the label is an earlier `div` sibling. */
2006.group-label + .match-card {
2007 border-top: 1px solid var(--border);
2008}
2009
2010/* The header opens the file; the matched lines below are text to read. */
2011.match-head {
2012 display: flex;
2013 align-items: center;
2014 gap: 10px;
2015 padding: 9px 14px;
2016 font-size: 14px;
2017 cursor: pointer;
2018}
2019
2020.match-head:hover {
2021 background: var(--bg);
2022}
2023
2024.match-head .mi {
2025 width: 18px;
2026 height: 18px;
2027 color: var(--muted);
2028 flex: none;
2029}
2030
2031/* Takes the slack, so the count and the two buttons sit at the right edge. */
2032.mpath {
2033 flex: 1;
2034 min-width: 0;
2035 overflow: hidden;
2036 text-overflow: ellipsis;
2037 white-space: nowrap;
2038}
2039
2040.mpath b {
2041 font-weight: 600;
2042}
2043
2044.mcount {
2045 flex: none;
2046 font-size: 12px;
2047 color: var(--muted);
2048}
2049
2050/* "Show in folder", in both the name rows and the match-card headers. */
2051.goto-btn {
2052 appearance: none;
2053 flex: none;
2054 justify-self: end;
2055 display: flex;
2056 align-items: center;
2057 justify-content: center;
2058 width: 26px;
2059 height: 26px;
2060 padding: 0;
2061 border: 1px solid transparent;
2062 background: transparent;
2063 cursor: pointer;
2064}
2065
2066.goto-btn:hover {
2067 border-color: var(--border);
2068}
2069
2070.goto-btn .goto-ic {
2071 width: 16px;
2072 height: 16px;
2073 color: var(--muted);
2074}
2075
2076.goto-btn:hover .goto-ic {
2077 color: var(--accent);
2078}
2079
2080.chev {
2081 appearance: none;
2082 border: 1px solid var(--border);
2083 background: transparent;
2084 width: 26px;
2085 height: 26px;
2086 display: flex;
2087 align-items: center;
2088 justify-content: center;
2089 cursor: pointer;
2090 flex: none;
2091}
2092
2093.chev:hover {
2094 background: var(--bg);
2095}
2096
2097.chev .chev-down,
2098.chev .chev-up {
2099 display: block;
2100 width: 10px;
2101 height: 10px;
2102 border-right: 2px solid var(--muted);
2103 border-bottom: 2px solid var(--muted);
2104}
2105
2106.chev .chev-down {
2107 transform: rotate(45deg) translate(-1px, -1px);
2108}
2109
2110.chev .chev-up {
2111 transform: rotate(-135deg) translate(-1px, -1px);
2112}
2113
2114.match-lines {
2115 border-top: 1px solid var(--border);
2116 background: var(--bg);
2117 font-family: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
2118 font-size: 12.5px;
2119}
2120
2121/* Matched lines are text to read, not a control: the card header is what
2122 opens the file, so no pointer cursor and no hover here. */
2123.mline {
2124 display: grid;
2125 grid-template-columns: 52px minmax(0, 1fr);
2126 gap: 12px;
2127 padding: 5px 14px;
2128 border-bottom: 1px solid var(--border);
2129 white-space: pre;
2130 user-select: text;
2131}
2132
2133.mline:last-child {
2134 border-bottom: none;
2135}
2136
2137.mline .ln {
2138 color: var(--muted);
2139 text-align: right;
2140 user-select: none;
2141}
2142
2143.mline .tx {
2144 overflow: hidden;
2145 text-overflow: ellipsis;
2146}
2147
2148.search-empty {
2149 padding: 48px 20px;
2150 text-align: center;
2151 color: var(--muted);
2152 font-size: 14px;
2153}
2154