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}
19
20:root.dark {
21 color-scheme: dark;
22 --bg: #0f1115;
23 --panel: #171a20;
24 --text: #e5e7eb;
25 --muted: #9ca3af;
26 --accent: #60a5fa;
27 --accent-hover: #3b82f6;
28 --accent-border: #79b5fc;
29 --danger: #f87171;
30 --danger-border: #fa8b8b;
31 --border: #2a2f3a;
32}
33
34@media (prefers-color-scheme: dark) {
35 :root:not(.light) {
36 color-scheme: dark;
37 --bg: #0f1115;
38 --panel: #171a20;
39 --text: #e5e7eb;
40 --muted: #9ca3af;
41 --accent: #60a5fa;
42 --accent-hover: #3b82f6;
43 --accent-border: #79b5fc;
44 --danger: #f87171;
45 --danger-border: #fa8b8b;
46 --border: #2a2f3a;
47 }
48}
49
50* {
51 box-sizing: border-box;
52 /* The design language is sharp: everything stays square. */
53 border-radius: 0;
54}
55
56body {
57 margin: 0;
58 font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
59 background: var(--bg);
60 color: var(--text);
61 font-size: 15px;
62}
63
64.muted {
65 color: var(--muted);
66}
67
68.card {
69 background: var(--panel);
70 border: 1px solid var(--border);
71 padding: 24px;
72}
73
74.center-screen {
75 min-height: 100vh;
76 display: flex;
77 flex-direction: column;
78 align-items: center;
79 justify-content: center;
80 padding: 16px;
81 text-align: center;
82}
83
84.auth-card {
85 width: 100%;
86 max-width: 380px;
87}
88
89.auth-card h1 {
90 margin: 0 0 8px;
91 font-size: 22px;
92}
93
94.auth-logo {
95 width: 44px;
96 height: 44px;
97 margin-bottom: 12px;
98}
99
100.auth-card p {
101 margin: 0 0 20px;
102 font-size: 13px;
103}
104
105.field {
106 display: block;
107 margin-bottom: 14px;
108}
109
110.field span {
111 display: block;
112 font-size: 13px;
113 color: var(--muted);
114 margin-bottom: 4px;
115}
116
117input {
118 width: 100%;
119 padding: 10px 12px;
120 border: 1px solid var(--border);
121 background: var(--bg);
122 color: var(--text);
123 font-size: 14px;
124}
125
126input:focus {
127 outline: 2px solid var(--accent);
128 outline-offset: -1px;
129}
130
131button {
132 font: inherit;
133 cursor: pointer;
134 display: inline-flex;
135 align-items: center;
136 justify-content: center;
137 gap: 6px;
138 border: 1px solid var(--border);
139 background: var(--panel);
140 color: var(--text);
141 padding: 9px 14px;
142}
143
144button:hover {
145 border-color: var(--muted);
146}
147
148button:disabled {
149 opacity: 0.6;
150 cursor: default;
151}
152
153.btn-primary {
154 width: 100%;
155 background: var(--accent);
156 /* One step away from the fill, per theme (see palette above), so the
157 button's edge reads the same as on neutral buttons. */
158 border-color: var(--accent-border);
159 color: #fff;
160 font-weight: 600;
161}
162
163.btn-primary:hover {
164 background: var(--accent-hover);
165 border-color: var(--accent-border);
166}
167
168.error {
169 color: var(--danger);
170 font-size: 13px;
171 min-height: 18px;
172 margin: 0 0 10px;
173}
174
175/* layout (signed-in): full-width topbar, then sidebar + content below */
176
177.layout {
178 min-height: 100vh;
179 display: flex;
180 flex-direction: column;
181}
182
183.topbar {
184 flex: none;
185 position: sticky;
186 top: 0;
187 z-index: 130;
188 height: var(--topbar-h);
189 display: flex;
190 align-items: center;
191 justify-content: space-between;
192 gap: 12px;
193 padding: 0 16px;
194 background: var(--panel);
195 border-bottom: 1px solid var(--border);
196}
197
198.topbar-left {
199 display: flex;
200 align-items: center;
201 gap: 10px;
202 min-width: 0;
203}
204
205.icon-btn.nav-toggle {
206 display: none;
207}
208
209.body-row {
210 flex: 1;
211 display: flex;
212 align-items: stretch;
213}
214
215/* ---- sidebar ---- */
216
217.sidebar {
218 flex: none;
219 width: 224px;
220 display: flex;
221 flex-direction: column;
222 background: var(--panel);
223 border-right: 1px solid var(--border);
224 position: sticky;
225 top: var(--topbar-h);
226 height: calc(100vh - var(--topbar-h));
227}
228
229.brand {
230 display: flex;
231 align-items: center;
232 gap: 10px;
233 font-weight: 700;
234 white-space: nowrap;
235}
236
237.brand-name {
238 overflow: hidden;
239 text-overflow: ellipsis;
240}
241
242.logo {
243 width: 26px;
244 height: 26px;
245 flex: none;
246 display: block;
247}
248
249.nav {
250 flex: 1;
251 overflow-y: auto;
252 padding: 14px 8px 16px;
253 display: flex;
254 flex-direction: column;
255 gap: 20px;
256}
257
258.sidebar-user {
259 padding: 0 10px 2px;
260 font-size: 14px;
261 font-weight: 600;
262 overflow: hidden;
263 text-overflow: ellipsis;
264 white-space: nowrap;
265}
266
267.nav-section-label {
268 font-size: 11px;
269 font-weight: 700;
270 text-transform: uppercase;
271 letter-spacing: 0.08em;
272 color: var(--muted);
273 padding: 0 10px 6px;
274}
275
276/* Section header with a right-aligned action (the Files refresh). */
277.nav-section-head {
278 display: flex;
279 align-items: center;
280 justify-content: space-between;
281 gap: 6px;
282}
283
284.nav-section-head .nav-section-label {
285 flex: 1;
286 padding-bottom: 2px;
287}
288
289.nav-section-refresh {
290 color: var(--muted);
291 background: none;
292 border-color: transparent;
293 padding: 3px 5px;
294}
295
296.nav-section-refresh:hover {
297 color: var(--text);
298 border-color: var(--border);
299}
300
301.nav-tab {
302 display: flex;
303 align-items: center;
304 justify-content: flex-start;
305 gap: 10px;
306 width: 100%;
307 margin-bottom: 2px;
308 padding: 8px 10px;
309 text-align: left;
310 background: none;
311 border: none;
312 color: var(--muted);
313 font-size: 14px;
314}
315
316.nav-tab:hover {
317 background: var(--bg);
318 color: var(--text);
319}
320
321.nav-tab.active {
322 background: var(--accent);
323 border-color: var(--accent);
324 color: #fff;
325}
326
327.ic-tab {
328 width: 18px;
329 height: 18px;
330 flex: none;
331}
332
333.nav-tab.active .icon {
334 color: #fff;
335}
336
337.nav-tab-name {
338 flex: 1;
339 min-width: 0;
340 overflow: hidden;
341 text-overflow: ellipsis;
342 white-space: nowrap;
343}
344
345.nav-tab-note {
346 flex: none;
347 font-size: 10px;
348 font-weight: 700;
349 padding: 1px 5px;
350 background: var(--bg);
351 border: 1px solid var(--border);
352 color: var(--muted);
353}
354
355.nav-tab.active .nav-tab-note {
356 background: rgb(255 255 255 / 18%);
357 border-color: rgb(255 255 255 / 30%);
358 color: #fff;
359}
360
361.nav-backdrop {
362 display: none;
363}
364
365/* Sidebar footer: theme toggle, log out, and the project version.
366 Sits at the bottom of the sidebar, below the manage section. */
367.sidebar-footer {
368 flex: none;
369 border-top: 1px solid var(--border);
370 padding: 8px;
371}
372
373.sidebar-footer .nav-tab {
374 margin-bottom: 0;
375}
376
377.sidebar-action.logout {
378 color: var(--danger);
379}
380
381.sidebar-action.logout:hover {
382 color: var(--danger);
383}
384
385.sidebar-version {
386 margin-top: 8px;
387 padding: 0 10px;
388 font-size: 11.5px;
389 color: var(--muted);
390 white-space: nowrap;
391 overflow: hidden;
392 text-overflow: ellipsis;
393}
394
395.badge {
396 font-size: 11px;
397 padding: 2px 8px;
398 background: var(--bg);
399 border: 1px solid var(--border);
400 color: var(--muted);
401}
402
403.content {
404 flex: 1;
405 min-width: 0;
406 min-height: 0;
407 display: flex;
408 flex-direction: column;
409 padding: 20px;
410}
411
412/* While a file is open the app is a fixed-height frame: the file view
413 * (editor, image, …) scrolls inside, the page itself never grows. */
414.layout.file-mode {
415 height: 100vh;
416 overflow: hidden;
417}
418
419.layout.file-mode .body-row {
420 min-height: 0;
421}
422
423/* Narrow screens: the sidebar becomes an off-canvas drawer that only
424 covers the content, below the (always visible) topbar. */
425@media (max-width: 860px) {
426 .sidebar {
427 position: fixed;
428 top: var(--topbar-h);
429 bottom: 0;
430 left: 0;
431 right: auto;
432 height: auto;
433 z-index: 120;
434 transform: translateX(-100%);
435 transition: transform 0.15s ease;
436 }
437
438 .sidebar.open {
439 transform: translateX(0);
440 box-shadow: 0 0 48px rgb(0 0 0 / 35%);
441 }
442
443 .nav-backdrop {
444 display: block;
445 position: fixed;
446 top: var(--topbar-h);
447 bottom: 0;
448 left: 0;
449 right: 0;
450 z-index: 110;
451 background: rgb(0 0 0 / 40%);
452 }
453
454 .icon-btn.nav-toggle {
455 display: inline-flex;
456 }
457
458 .content {
459 padding: 14px;
460 }
461}
462
463/* ---- file browser ---- */
464
465.browser {
466 width: 100%;
467 max-width: 1200px;
468 margin: 0 auto;
469 flex: 1;
470 display: flex;
471 flex-direction: column;
472 min-height: 0;
473}
474
475.icon {
476 width: 20px;
477 height: 20px;
478 display: inline-block;
479 vertical-align: middle;
480}
481
482.ic-folder {
483 color: var(--accent);
484}
485
486.ic-muted {
487 color: var(--muted);
488}
489
490.crumbs {
491 display: flex;
492 align-items: center;
493 gap: 2px;
494 padding: 6px 0 12px;
495 font-size: 15px;
496 flex-wrap: wrap;
497}
498
499.crumb {
500 cursor: pointer;
501 color: var(--muted);
502 padding: 3px 6px;
503}
504
505.crumb:hover {
506 color: var(--text);
507 background: var(--panel);
508}
509
510.crumb.current {
511 color: var(--text);
512 font-weight: 600;
513 cursor: default;
514 background: none;
515}
516
517.crumb-sep {
518 color: var(--muted);
519 padding: 0 1px;
520}
521
522.toolbar {
523 display: flex;
524 align-items: center;
525 justify-content: space-between;
526 gap: 6px;
527 padding-bottom: 12px;
528}
529
530.toolbar-right {
531 display: flex;
532 gap: 6px;
533}
534
535.icon-btn {
536 padding: 7px 9px;
537 border: 1px solid var(--border);
538 background: var(--panel);
539 color: var(--muted);
540 display: inline-flex;
541 align-items: center;
542}
543
544.icon-btn:hover {
545 border-color: var(--muted);
546}
547
548.icon-btn.active {
549 background: var(--accent);
550 border-color: var(--accent);
551 color: #fff;
552}
553
554.ic-btn {
555 width: 18px;
556 height: 18px;
557 color: inherit;
558}
559
560.entries-area {
561 flex: 1;
562 min-height: 240px;
563}
564
565.center-note {
566 text-align: center;
567 padding: 48px 0;
568}
569
570.error-card {
571 display: flex;
572 align-items: center;
573 justify-content: space-between;
574 gap: 16px;
575 color: var(--danger);
576 font-size: 14px;
577}
578
579/* root tiles were replaced by the sidebar's folder tabs */
580
581/* grid view */
582
583.entries-grid {
584 display: grid;
585 grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
586 gap: 10px;
587}
588
589.tile {
590 background: var(--panel);
591 border: 1px solid var(--border);
592 padding: 16px 10px 12px;
593 text-align: center;
594 cursor: pointer;
595}
596
597.tile:hover {
598 border-color: var(--muted);
599}
600
601.tile-icon {
602 width: 42px;
603 height: 42px;
604 margin: 0 auto 10px;
605 display: block;
606}
607
608.tile-name {
609 font-size: 13px;
610 line-height: 1.3;
611 word-break: break-word;
612}
613
614/* list view */
615
616.entries-list {
617 background: var(--panel);
618 border: 1px solid var(--border);
619 overflow: hidden;
620}
621
622.row {
623 display: grid;
624 grid-template-columns: 28px minmax(0, 1fr) 90px 150px;
625 gap: 12px;
626 align-items: center;
627 padding: 9px 14px;
628 border-bottom: 1px solid var(--border);
629 cursor: pointer;
630 font-size: 14px;
631}
632
633.row:last-child {
634 border-bottom: none;
635}
636
637.row:hover {
638 background: var(--bg);
639}
640
641.row-icon {
642 width: 20px;
643 height: 20px;
644}
645
646.row-name {
647 overflow: hidden;
648 text-overflow: ellipsis;
649 white-space: nowrap;
650}
651
652.row-size,
653.row-date {
654 font-size: 13px;
655 text-align: right;
656}
657
658@media (max-width: 640px) {
659 .row {
660 grid-template-columns: 28px minmax(0, 1fr) 90px;
661 }
662
663 .row-date {
664 display: none;
665 }
666}
667
668/* context menu */
669
670.ctx-menu {
671 position: fixed;
672 z-index: 100;
673 min-width: 190px;
674 background: var(--panel);
675 border: 1px solid var(--border);
676 padding: 5px;
677 box-shadow: 0 8px 24px rgb(0 0 0 / 18%);
678}
679
680.ctx-item {
681 display: flex;
682 align-items: center;
683 gap: 10px;
684 padding: 8px 12px;
685 font-size: 14px;
686 cursor: pointer;
687}
688
689.ic-ctx {
690 width: 18px;
691 height: 18px;
692 flex: none;
693}
694
695.ctx-item:hover {
696 background: var(--bg);
697}
698
699.ctx-item.disabled {
700 opacity: 0.45;
701 cursor: default;
702}
703
704.ctx-item.disabled:hover {
705 background: none;
706}
707
708/* toast */
709
710.toast {
711 position: fixed;
712 bottom: 20px;
713 right: 20px;
714 z-index: 200;
715 background: var(--panel);
716 color: var(--text);
717 border: 1px solid var(--border);
718 padding: 11px 16px;
719 font-size: 14px;
720 box-shadow: 0 8px 24px rgb(0 0 0 / 18%);
721 max-width: 320px;
722}
723
724
725/* ---- modals ---- */
726
727.modal-overlay {
728 position: fixed;
729 inset: 0;
730 background: rgb(0 0 0 / 45%);
731 display: flex;
732 align-items: center;
733 justify-content: center;
734 z-index: 100;
735}
736
737.modal {
738 width: 440px;
739 max-width: calc(100vw - 32px);
740 padding: 20px;
741 background: var(--panel);
742 border: 1px solid var(--border);
743 box-shadow: 0 12px 44px rgb(0 0 0 / 35%);
744}
745
746.modal.picker {
747 width: 520px;
748}
749
750.modal-title {
751 margin: 0 0 12px;
752 font-size: 16px;
753}
754
755.modal-label {
756 display: block;
757 font-size: 13px;
758 color: var(--muted);
759 margin-bottom: 6px;
760}
761
762.modal .input {
763 width: 100%;
764 box-sizing: border-box;
765 margin-bottom: 16px;
766}
767
768.modal-message {
769 white-space: pre-line;
770 font-size: 14px;
771 margin: 0 0 8px;
772}
773
774.modal-actions {
775 display: flex;
776 justify-content: flex-end;
777 gap: 8px;
778 margin-top: 16px;
779}
780
781.btn-danger {
782 background: var(--danger);
783 /* A visible border (one step away from the fill, per theme) so the
784 button's edge reads the same as on neutral buttons. */
785 border-color: var(--danger-border);
786 color: #fff;
787}
788
789.btn-danger:hover {
790 background: color-mix(in srgb, var(--danger) 85%, black);
791}
792
793.btn:disabled {
794 opacity: 0.5;
795 cursor: not-allowed;
796}
797
798.conflict-list {
799 max-height: 200px;
800 overflow-y: auto;
801 margin: 8px 0;
802 padding-left: 20px;
803 font-size: 13px;
804}
805
806.picker-roots {
807 display: flex;
808 gap: 6px;
809 flex-wrap: wrap;
810 margin-bottom: 12px;
811}
812
813.root-opt {
814 font-size: 13px;
815}
816
817.root-opt.active {
818 background: var(--accent);
819 border-color: var(--accent);
820 color: #fff;
821}
822
823.picker-current {
824 font-size: 13px;
825 margin: 0 0 8px;
826}
827
828.picker-crumbs {
829 margin-bottom: 8px;
830}
831
832.picker-entries {
833 max-height: 240px;
834 overflow-y: auto;
835 border: 1px solid var(--border);
836}
837
838.picker-row {
839 display: flex;
840 align-items: center;
841 gap: 10px;
842 padding: 8px 12px;
843 cursor: pointer;
844}
845
846.picker-row:hover {
847 background: var(--bg);
848}
849
850/* ---------------------------------------------------------------------------
851 * Full-page file view (preview / editor / "no preview"). The top bar carries
852 * the title + actions; the content area below is edge to edge.
853 * ------------------------------------------------------------------------- */
854.content.file-open {
855 padding: 0;
856 overflow: hidden;
857}
858
859/* The browser stays mounted (state, fetch callback) but hidden. */
860.content.file-open .browser {
861 display: none;
862}
863
864.file-view {
865 flex: 1;
866 min-height: 0;
867 display: flex;
868 flex-direction: column;
869}
870
871.file-title {
872 display: flex;
873 align-items: center;
874 gap: 8px;
875 min-width: 0;
876}
877
878.file-title-icon {
879 width: 18px;
880 height: 18px;
881 flex: none;
882 color: var(--muted);
883}
884
885.file-title-name {
886 font-weight: 600;
887 font-size: 14px;
888 white-space: nowrap;
889 overflow: hidden;
890 text-overflow: ellipsis;
891}
892
893.file-actions {
894 display: flex;
895 align-items: center;
896 gap: 10px;
897 flex: none;
898}
899
900.file-close {
901 border: none;
902 background: transparent;
903 color: var(--muted);
904 padding: 6px 8px;
905}
906
907.file-close:hover {
908 color: var(--text);
909 background: var(--bg);
910}
911.preview-body {
912 flex: 1;
913 min-height: 0;
914 overflow: auto;
915 display: flex;
916 background: var(--bg);
917}
918.preview-img {
919 max-width: 100%;
920 max-height: 100%;
921 display: block;
922 margin: auto;
923}
924.preview-pdf {
925 width: 100%;
926 height: 100%;
927 border: none;
928 background: #fff;
929}
930.preview-video {
931 width: 100%;
932 max-height: 100%;
933 background: #000;
934}
935.preview-audio {
936 display: flex;
937 align-items: center;
938 justify-content: center;
939 width: 100%;
940 padding: 24px;
941}
942.preview-audio audio {
943 width: 100%;
944 max-width: 480px;
945}
946
947/* CodeMirror (text editor) */
948.cm-container {
949 height: 100%;
950}
951.cm-container .cm-editor {
952 height: 100%;
953}
954.cm-error {
955 position: absolute;
956 inset: 0;
957 display: flex;
958 align-items: center;
959 justify-content: center;
960 padding: 24px;
961 text-align: center;
962}
963
964/* ---------------------------------------------------------------------------
965 * Text editor (full page; title/save/close live in the top bar)
966 * ------------------------------------------------------------------------- */
967.file-editor {
968 flex: 1;
969 min-height: 0;
970 display: flex;
971 position: relative;
972 background: var(--bg);
973}
974.file-editor .cm-container {
975 width: 100%;
976 height: 100%;
977}
978/* "No preview" fallback (binaries, archives). */
979.file-nopreview {
980 flex: 1;
981 display: flex;
982 align-items: center;
983 justify-content: center;
984}
985.file-nopreview .btn-primary {
986 width: auto;
987 margin-top: 14px;
988}
989/* Conflict / discard dialogs render above the file view. */
990.editor-sub-overlay {
991 z-index: 101;
992 background: rgb(0 0 0 / 25%);
993}
994
995/* ---------------------------------------------------------------------------
996 * Download format dialog
997 * ------------------------------------------------------------------------- */
998.dl-formats {
999 display: flex;
1000 flex-direction: column;
1001 gap: 8px;
1002 margin-bottom: 8px;
1003}
1004.dl-fmt {
1005 justify-content: flex-start;
1006}
1007
1008/* ---------------------------------------------------------------------------
1009 * Item info dialog
1010 * ------------------------------------------------------------------------- */
1011.info-list {
1012 margin: 8px 0 16px;
1013 display: grid;
1014 grid-template-columns: 90px 1fr;
1015 row-gap: 8px;
1016 column-gap: 12px;
1017}
1018.info-list dt {
1019 color: var(--muted);
1020}
1021.info-list dd {
1022 margin: 0;
1023 word-break: break-word;
1024}
1025
1026/* ---------------------------------------------------------------------------
1027 Shares (milestone 6)
1028 --------------------------------------------------------------------------- */
1029
1030.share-modal {
1031 width: 480px;
1032}
1033
1034.share-link-row {
1035 display: flex;
1036 gap: 8px;
1037 margin: 12px 0;
1038}
1039
1040.share-link-input {
1041 flex: 1;
1042 font-family: ui-monospace, monospace;
1043 font-size: 12.5px;
1044 padding: 8px 10px;
1045 border: 1px solid var(--border);
1046 background: var(--bg);
1047 color: var(--text);
1048 min-width: 0;
1049}
1050
1051.share-check {
1052 display: flex;
1053 align-items: center;
1054 gap: 8px;
1055 margin: 4px 0 14px;
1056 font-size: 14px;
1057}
1058
1059.share-check input {
1060 width: 16px;
1061 height: 16px;
1062}
1063
1064.share-expiry-row {
1065 display: flex;
1066 align-items: center;
1067 gap: 10px;
1068 margin: 0 0 10px;
1069}
1070
1071.share-expiry-row label {
1072 font-size: 13px;
1073 color: var(--muted);
1074 min-width: 52px;
1075}
1076
1077.share-expiry-row select,
1078.share-expiry-row input {
1079 flex: 1;
1080 padding: 8px 10px;
1081 border: 1px solid var(--border);
1082 background: var(--panel);
1083 color: var(--text);
1084 font: inherit;
1085}
1086
1087.share-expiry-note {
1088 margin: 4px 0 0;
1089 font-size: 12.5px;
1090}
1091
1092.btn-sm {
1093 padding: 5px 10px;
1094 font-size: 12.5px;
1095}
1096
1097.icon-btn-sm {
1098 padding: 4px 6px;
1099}
1100
1101/* "Your shares" manage view */
1102
1103.shares-view {
1104 width: 100%;
1105 max-width: 960px;
1106 margin: 0 auto;
1107}
1108
1109.view-header {
1110 margin-bottom: 16px;
1111}
1112
1113.view-header .admin-section-title {
1114 margin-bottom: 0;
1115}
1116
1117.view-hint {
1118 margin: 4px 0 0;
1119 font-size: 13px;
1120 max-width: 64ch;
1121}
1122
1123.share-list {
1124 display: flex;
1125 flex-direction: column;
1126 gap: 10px;
1127}
1128
1129.share-item {
1130 display: flex;
1131 align-items: center;
1132 justify-content: space-between;
1133 gap: 12px;
1134 padding: 10px 12px;
1135 border: 1px solid var(--border);
1136 background: var(--panel);
1137}
1138
1139.share-item-main {
1140 min-width: 0;
1141}
1142
1143.share-item-name {
1144 display: flex;
1145 align-items: center;
1146 gap: 8px;
1147 font-weight: 600;
1148 font-size: 14px;
1149 overflow: hidden;
1150 text-overflow: ellipsis;
1151 white-space: nowrap;
1152}
1153
1154.ic-row {
1155 width: 18px;
1156 height: 18px;
1157 flex: none;
1158}
1159
1160.share-item-meta {
1161 font-size: 12px;
1162 margin-top: 2px;
1163 overflow: hidden;
1164 text-overflow: ellipsis;
1165 white-space: nowrap;
1166}
1167
1168.share-item-actions {
1169 display: flex;
1170 gap: 6px;
1171 flex-shrink: 0;
1172}
1173
1174/* Public share page */
1175
1176.share-badge {
1177 display: inline-flex;
1178 align-items: center;
1179 gap: 6px;
1180 font-size: 13px;
1181 color: var(--muted);
1182 background: var(--panel);
1183 border: 1px solid var(--border);
1184 padding: 4px 10px;
1185}
1186
1187.ic-badge {
1188 width: 14px;
1189 height: 14px;
1190 flex: none;
1191}
1192
1193.share-footer {
1194 padding: 16px;
1195 text-align: center;
1196 font-size: 12px;
1197 border-top: 1px solid var(--border);
1198 margin-top: auto;
1199}
1200
1201.share-file-page {
1202 display: flex;
1203 flex-direction: column;
1204 align-items: center;
1205 gap: 12px;
1206 padding: 80px 20px;
1207 text-align: center;
1208}
1209
1210.share-file-glyph {
1211 width: 64px;
1212 height: 64px;
1213}
1214
1215.share-file-page h2 {
1216 margin: 0;
1217 word-break: break-word;
1218}
1219
1220.share-file-actions .btn-primary {
1221 width: auto;
1222 min-width: 140px;
1223}
1224
1225/* ------------------------------------------------------------------ */
1226/* Admin (milestone 7) */
1227/* ------------------------------------------------------------------ */
1228
1229.admin-view {
1230 display: flex;
1231 flex-direction: column;
1232 gap: 16px;
1233 width: 100%;
1234 max-width: 960px;
1235 margin: 0 auto;
1236}
1237
1238.admin-section-title {
1239 margin: 0 0 14px;
1240 font-size: 15px;
1241}
1242
1243.users-header {
1244 display: flex;
1245 align-items: center;
1246 justify-content: space-between;
1247 margin-bottom: 4px;
1248}
1249
1250.users-header .admin-section-title {
1251 margin-bottom: 0;
1252}
1253
1254.users-header .btn-primary {
1255 width: auto;
1256}
1257
1258.user-list {
1259 display: flex;
1260 flex-direction: column;
1261 gap: 10px;
1262}
1263
1264.user-row {
1265 display: flex;
1266 align-items: center;
1267 justify-content: space-between;
1268 gap: 12px;
1269 padding: 12px 14px;
1270 border: 1px solid var(--border);
1271}
1272
1273.user-row-main {
1274 min-width: 0;
1275}
1276
1277.user-row-name {
1278 display: flex;
1279 align-items: center;
1280 gap: 6px;
1281 font-weight: 600;
1282 font-size: 14px;
1283 flex-wrap: wrap;
1284}
1285
1286.ic-admin {
1287 width: 16px;
1288 height: 16px;
1289 flex: none;
1290}
1291
1292.user-row-actions {
1293 display: flex;
1294 gap: 6px;
1295 flex-shrink: 0;
1296}
1297
1298.badge-off {
1299 background: color-mix(in srgb, var(--danger) 15%, var(--panel));
1300 border-color: var(--danger);
1301 color: var(--danger);
1302}
1303
1304.setting-row {
1305 display: flex;
1306 align-items: flex-start;
1307 gap: 10px;
1308 padding: 14px;
1309 border: 1px solid var(--border);
1310 cursor: pointer;
1311}
1312
1313.setting-row input {
1314 width: auto;
1315 margin-top: 2px;
1316}
1317
1318.setting-label {
1319 display: block;
1320 font-weight: 600;
1321 font-size: 14px;
1322}
1323
1324.setting-desc {
1325 display: block;
1326 font-size: 12px;
1327 color: var(--muted);
1328 margin-top: 2px;
1329}
1330
1331/* User create/edit form */
1332
1333.user-form {
1334 width: 520px;
1335}
1336
1337.field-input {
1338 width: 100%;
1339 box-sizing: border-box;
1340}
1341
1342.field-hint {
1343 font-size: 12px;
1344 margin: -2px 0 8px;
1345}
1346
1347.check-row {
1348 display: flex;
1349 align-items: center;
1350 gap: 8px;
1351 font-size: 14px;
1352 margin-bottom: 12px;
1353 cursor: pointer;
1354}
1355
1356.check-row input {
1357 width: auto;
1358}
1359
1360.form-error {
1361 color: var(--danger);
1362 font-size: 13px;
1363 margin: 4px 0 8px;
1364}
1365
1366.roots-editor {
1367 display: flex;
1368 flex-direction: column;
1369 gap: 6px;
1370}
1371
1372.root-draft {
1373 display: flex;
1374 align-items: center;
1375 gap: 8px;
1376}
1377
1378.root-draft-path {
1379 flex: 1;
1380 font-size: 13px;
1381 overflow: hidden;
1382 text-overflow: ellipsis;
1383 white-space: nowrap;
1384}
1385
1386.root-draft-mode {
1387 width: auto;
1388 padding: 6px 8px;
1389}
1390
1391.root-add {
1392 display: flex;
1393 gap: 8px;
1394 margin-top: 4px;
1395}
1396
1397/* ------------------------------------------------------------------ */
1398/* Empty state + keyboard focus (milestone 8) */
1399/* ------------------------------------------------------------------ */
1400
1401.empty-state {
1402 display: flex;
1403 flex-direction: column;
1404 align-items: center;
1405 justify-content: center;
1406 gap: 8px;
1407 padding: 64px 20px;
1408 text-align: center;
1409}
1410
1411.empty-glyph {
1412 width: 52px;
1413 height: 52px;
1414}
1415
1416.empty-state h3 {
1417 margin: 0;
1418 font-size: 16px;
1419}
1420
1421/* Visible keyboard focus on selectable file/folder entries. */
1422.tile:focus-visible,
1423.row:focus-visible {
1424 outline: 2px solid var(--accent);
1425 outline-offset: 2px;
1426}
1427