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 display: flex;
407 flex-direction: column;
408 padding: 20px;
409}
410
411/* Narrow screens: the sidebar becomes an off-canvas drawer that only
412 covers the content, below the (always visible) topbar. */
413@media (max-width: 860px) {
414 .sidebar {
415 position: fixed;
416 top: var(--topbar-h);
417 bottom: 0;
418 left: 0;
419 right: auto;
420 height: auto;
421 z-index: 120;
422 transform: translateX(-100%);
423 transition: transform 0.15s ease;
424 }
425
426 .sidebar.open {
427 transform: translateX(0);
428 box-shadow: 0 0 48px rgb(0 0 0 / 35%);
429 }
430
431 .nav-backdrop {
432 display: block;
433 position: fixed;
434 top: var(--topbar-h);
435 bottom: 0;
436 left: 0;
437 right: 0;
438 z-index: 110;
439 background: rgb(0 0 0 / 40%);
440 }
441
442 .icon-btn.nav-toggle {
443 display: inline-flex;
444 }
445
446 .content {
447 padding: 14px;
448 }
449}
450
451/* ---- file browser ---- */
452
453.browser {
454 width: 100%;
455 max-width: 1200px;
456 margin: 0 auto;
457 flex: 1;
458 display: flex;
459 flex-direction: column;
460 min-height: 0;
461}
462
463.icon {
464 width: 20px;
465 height: 20px;
466 display: inline-block;
467 vertical-align: middle;
468}
469
470.ic-folder {
471 color: var(--accent);
472}
473
474.ic-muted {
475 color: var(--muted);
476}
477
478.crumbs {
479 display: flex;
480 align-items: center;
481 gap: 2px;
482 padding: 6px 0 12px;
483 font-size: 15px;
484 flex-wrap: wrap;
485}
486
487.crumb {
488 cursor: pointer;
489 color: var(--muted);
490 padding: 3px 6px;
491}
492
493.crumb:hover {
494 color: var(--text);
495 background: var(--panel);
496}
497
498.crumb.current {
499 color: var(--text);
500 font-weight: 600;
501 cursor: default;
502 background: none;
503}
504
505.crumb-sep {
506 color: var(--muted);
507 padding: 0 1px;
508}
509
510.toolbar {
511 display: flex;
512 align-items: center;
513 justify-content: space-between;
514 gap: 6px;
515 padding-bottom: 12px;
516}
517
518.toolbar-right {
519 display: flex;
520 gap: 6px;
521}
522
523.icon-btn {
524 padding: 7px 9px;
525 border: 1px solid var(--border);
526 background: var(--panel);
527 color: var(--muted);
528 display: inline-flex;
529 align-items: center;
530}
531
532.icon-btn:hover {
533 border-color: var(--muted);
534}
535
536.icon-btn.active {
537 background: var(--accent);
538 border-color: var(--accent);
539 color: #fff;
540}
541
542.ic-btn {
543 width: 18px;
544 height: 18px;
545 color: inherit;
546}
547
548.entries-area {
549 flex: 1;
550 min-height: 240px;
551}
552
553.center-note {
554 text-align: center;
555 padding: 48px 0;
556}
557
558.error-card {
559 display: flex;
560 align-items: center;
561 justify-content: space-between;
562 gap: 16px;
563 color: var(--danger);
564 font-size: 14px;
565}
566
567/* root tiles were replaced by the sidebar's folder tabs */
568
569/* grid view */
570
571.entries-grid {
572 display: grid;
573 grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
574 gap: 10px;
575}
576
577.tile {
578 background: var(--panel);
579 border: 1px solid var(--border);
580 padding: 16px 10px 12px;
581 text-align: center;
582 cursor: pointer;
583}
584
585.tile:hover {
586 border-color: var(--muted);
587}
588
589.tile-icon {
590 width: 42px;
591 height: 42px;
592 margin: 0 auto 10px;
593 display: block;
594}
595
596.tile-name {
597 font-size: 13px;
598 line-height: 1.3;
599 word-break: break-word;
600}
601
602/* list view */
603
604.entries-list {
605 background: var(--panel);
606 border: 1px solid var(--border);
607 overflow: hidden;
608}
609
610.row {
611 display: grid;
612 grid-template-columns: 28px minmax(0, 1fr) 90px 150px;
613 gap: 12px;
614 align-items: center;
615 padding: 9px 14px;
616 border-bottom: 1px solid var(--border);
617 cursor: pointer;
618 font-size: 14px;
619}
620
621.row:last-child {
622 border-bottom: none;
623}
624
625.row:hover {
626 background: var(--bg);
627}
628
629.row-icon {
630 width: 20px;
631 height: 20px;
632}
633
634.row-name {
635 overflow: hidden;
636 text-overflow: ellipsis;
637 white-space: nowrap;
638}
639
640.row-size,
641.row-date {
642 font-size: 13px;
643 text-align: right;
644}
645
646@media (max-width: 640px) {
647 .row {
648 grid-template-columns: 28px minmax(0, 1fr) 90px;
649 }
650
651 .row-date {
652 display: none;
653 }
654}
655
656/* context menu */
657
658.ctx-menu {
659 position: fixed;
660 z-index: 100;
661 min-width: 190px;
662 background: var(--panel);
663 border: 1px solid var(--border);
664 padding: 5px;
665 box-shadow: 0 8px 24px rgb(0 0 0 / 18%);
666}
667
668.ctx-item {
669 display: flex;
670 align-items: center;
671 gap: 10px;
672 padding: 8px 12px;
673 font-size: 14px;
674 cursor: pointer;
675}
676
677.ic-ctx {
678 width: 18px;
679 height: 18px;
680 flex: none;
681}
682
683.ctx-item:hover {
684 background: var(--bg);
685}
686
687.ctx-item.disabled {
688 opacity: 0.45;
689 cursor: default;
690}
691
692.ctx-item.disabled:hover {
693 background: none;
694}
695
696/* toast */
697
698.toast {
699 position: fixed;
700 bottom: 20px;
701 right: 20px;
702 z-index: 200;
703 background: var(--panel);
704 color: var(--text);
705 border: 1px solid var(--border);
706 padding: 11px 16px;
707 font-size: 14px;
708 box-shadow: 0 8px 24px rgb(0 0 0 / 18%);
709 max-width: 320px;
710}
711
712
713/* ---- modals ---- */
714
715.modal-overlay {
716 position: fixed;
717 inset: 0;
718 background: rgb(0 0 0 / 45%);
719 display: flex;
720 align-items: center;
721 justify-content: center;
722 z-index: 100;
723}
724
725.modal {
726 width: 440px;
727 max-width: calc(100vw - 32px);
728 padding: 20px;
729 background: var(--panel);
730 border: 1px solid var(--border);
731 box-shadow: 0 12px 44px rgb(0 0 0 / 35%);
732}
733
734.modal.picker {
735 width: 520px;
736}
737
738.modal-title {
739 margin: 0 0 12px;
740 font-size: 16px;
741}
742
743.modal-label {
744 display: block;
745 font-size: 13px;
746 color: var(--muted);
747 margin-bottom: 6px;
748}
749
750.modal .input {
751 width: 100%;
752 box-sizing: border-box;
753 margin-bottom: 16px;
754}
755
756.modal-message {
757 white-space: pre-line;
758 font-size: 14px;
759 margin: 0 0 8px;
760}
761
762.modal-actions {
763 display: flex;
764 justify-content: flex-end;
765 gap: 8px;
766 margin-top: 16px;
767}
768
769.btn-danger {
770 background: var(--danger);
771 /* A visible border (one step away from the fill, per theme) so the
772 button's edge reads the same as on neutral buttons. */
773 border-color: var(--danger-border);
774 color: #fff;
775}
776
777.btn-danger:hover {
778 background: color-mix(in srgb, var(--danger) 85%, black);
779}
780
781.btn:disabled {
782 opacity: 0.5;
783 cursor: not-allowed;
784}
785
786.conflict-list {
787 max-height: 200px;
788 overflow-y: auto;
789 margin: 8px 0;
790 padding-left: 20px;
791 font-size: 13px;
792}
793
794.picker-roots {
795 display: flex;
796 gap: 6px;
797 flex-wrap: wrap;
798 margin-bottom: 12px;
799}
800
801.root-opt {
802 font-size: 13px;
803}
804
805.root-opt.active {
806 background: var(--accent);
807 border-color: var(--accent);
808 color: #fff;
809}
810
811.picker-current {
812 font-size: 13px;
813 margin: 0 0 8px;
814}
815
816.picker-crumbs {
817 margin-bottom: 8px;
818}
819
820.picker-entries {
821 max-height: 240px;
822 overflow-y: auto;
823 border: 1px solid var(--border);
824}
825
826.picker-row {
827 display: flex;
828 align-items: center;
829 gap: 10px;
830 padding: 8px 12px;
831 cursor: pointer;
832}
833
834.picker-row:hover {
835 background: var(--bg);
836}
837
838/* ---------------------------------------------------------------------------
839 * Preview modal (image / PDF / video / audio / text)
840 * ------------------------------------------------------------------------- */
841.preview-modal {
842 width: min(960px, calc(100vw - 48px));
843 height: min(720px, calc(100vh - 48px));
844 display: flex;
845 flex-direction: column;
846 padding: 0;
847 overflow: hidden;
848}
849.preview-head {
850 display: flex;
851 align-items: center;
852 justify-content: space-between;
853 gap: 12px;
854 padding: 10px 14px;
855 border-bottom: 1px solid var(--border);
856}
857.preview-title {
858 font-weight: 600;
859 font-size: 14px;
860 white-space: nowrap;
861 overflow: hidden;
862 text-overflow: ellipsis;
863}
864.preview-close {
865 flex: none;
866 display: inline-flex;
867 align-items: center;
868 justify-content: center;
869 border: none;
870 background: transparent;
871 color: var(--muted);
872 cursor: pointer;
873 padding: 4px;
874}
875
876.preview-close:hover {
877 background: var(--bg);
878 color: var(--text);
879}
880
881.ic-close {
882 width: 20px;
883 height: 20px;
884}
885.preview-body {
886 flex: 1;
887 min-height: 0;
888 overflow: auto;
889 display: flex;
890 background: var(--bg);
891}
892.preview-img {
893 max-width: 100%;
894 max-height: 100%;
895 display: block;
896 margin: auto;
897}
898.preview-pdf {
899 width: 100%;
900 height: 100%;
901 border: none;
902 background: #fff;
903}
904.preview-video {
905 width: 100%;
906 max-height: 100%;
907 background: #000;
908}
909.preview-audio {
910 display: flex;
911 align-items: center;
912 justify-content: center;
913 width: 100%;
914 padding: 24px;
915}
916.preview-audio audio {
917 width: 100%;
918 max-width: 480px;
919}
920
921/* CodeMirror (text editor) */
922.cm-container {
923 height: 100%;
924}
925.cm-container .cm-editor {
926 height: 100%;
927}
928.cm-error {
929 position: absolute;
930 inset: 0;
931 display: flex;
932 align-items: center;
933 justify-content: center;
934 padding: 24px;
935 text-align: center;
936}
937
938/* ---------------------------------------------------------------------------
939 * Text editor (milestone 5)
940 * ------------------------------------------------------------------------- */
941.editor-modal {
942 width: min(960px, calc(100vw - 48px));
943 height: min(720px, calc(100vh - 48px));
944 display: flex;
945 flex-direction: column;
946 padding: 0;
947 overflow: hidden;
948}
949.editor-head {
950 display: flex;
951 align-items: center;
952 justify-content: space-between;
953 gap: 12px;
954 padding: 10px 14px;
955 border-bottom: 1px solid var(--border);
956}
957.editor-title {
958 font-weight: 600;
959 font-size: 14px;
960 white-space: nowrap;
961 overflow: hidden;
962 text-overflow: ellipsis;
963}
964.editor-actions {
965 display: flex;
966 align-items: center;
967 gap: 10px;
968 flex: none;
969}
970.editor-body {
971 flex: 1;
972 min-height: 0;
973 display: flex;
974 position: relative;
975 background: var(--bg);
976}
977.editor-body .cm-container {
978 width: 100%;
979 height: 100%;
980}
981/* Conflict / discard dialogs render above the editor overlay. */
982.editor-sub-overlay {
983 z-index: 101;
984 background: rgb(0 0 0 / 25%);
985}
986
987/* ---------------------------------------------------------------------------
988 * Download format dialog
989 * ------------------------------------------------------------------------- */
990.dl-formats {
991 display: flex;
992 flex-direction: column;
993 gap: 8px;
994 margin-bottom: 8px;
995}
996.dl-fmt {
997 justify-content: flex-start;
998}
999
1000/* ---------------------------------------------------------------------------
1001 * Item info dialog
1002 * ------------------------------------------------------------------------- */
1003.info-list {
1004 margin: 8px 0 16px;
1005 display: grid;
1006 grid-template-columns: 90px 1fr;
1007 row-gap: 8px;
1008 column-gap: 12px;
1009}
1010.info-list dt {
1011 color: var(--muted);
1012}
1013.info-list dd {
1014 margin: 0;
1015 word-break: break-word;
1016}
1017
1018/* ---------------------------------------------------------------------------
1019 Shares (milestone 6)
1020 --------------------------------------------------------------------------- */
1021
1022.share-modal {
1023 width: 480px;
1024}
1025
1026.share-link-row {
1027 display: flex;
1028 gap: 8px;
1029 margin: 12px 0;
1030}
1031
1032.share-link-input {
1033 flex: 1;
1034 font-family: ui-monospace, monospace;
1035 font-size: 12.5px;
1036 padding: 8px 10px;
1037 border: 1px solid var(--border);
1038 background: var(--bg);
1039 color: var(--text);
1040 min-width: 0;
1041}
1042
1043.share-check {
1044 display: flex;
1045 align-items: center;
1046 gap: 8px;
1047 margin: 4px 0 14px;
1048 font-size: 14px;
1049}
1050
1051.share-check input {
1052 width: 16px;
1053 height: 16px;
1054}
1055
1056.share-expiry-row {
1057 display: flex;
1058 align-items: center;
1059 gap: 10px;
1060 margin: 0 0 10px;
1061}
1062
1063.share-expiry-row label {
1064 font-size: 13px;
1065 color: var(--muted);
1066 min-width: 52px;
1067}
1068
1069.share-expiry-row select,
1070.share-expiry-row input {
1071 flex: 1;
1072 padding: 8px 10px;
1073 border: 1px solid var(--border);
1074 background: var(--panel);
1075 color: var(--text);
1076 font: inherit;
1077}
1078
1079.share-expiry-note {
1080 margin: 4px 0 0;
1081 font-size: 12.5px;
1082}
1083
1084.btn-sm {
1085 padding: 5px 10px;
1086 font-size: 12.5px;
1087}
1088
1089.icon-btn-sm {
1090 padding: 4px 6px;
1091}
1092
1093/* "Your shares" manage view */
1094
1095.shares-view {
1096 width: 100%;
1097 max-width: 960px;
1098 margin: 0 auto;
1099}
1100
1101.view-header {
1102 margin-bottom: 16px;
1103}
1104
1105.view-header .admin-section-title {
1106 margin-bottom: 0;
1107}
1108
1109.view-hint {
1110 margin: 4px 0 0;
1111 font-size: 13px;
1112 max-width: 64ch;
1113}
1114
1115.share-list {
1116 display: flex;
1117 flex-direction: column;
1118 gap: 10px;
1119}
1120
1121.share-item {
1122 display: flex;
1123 align-items: center;
1124 justify-content: space-between;
1125 gap: 12px;
1126 padding: 10px 12px;
1127 border: 1px solid var(--border);
1128 background: var(--panel);
1129}
1130
1131.share-item-main {
1132 min-width: 0;
1133}
1134
1135.share-item-name {
1136 display: flex;
1137 align-items: center;
1138 gap: 8px;
1139 font-weight: 600;
1140 font-size: 14px;
1141 overflow: hidden;
1142 text-overflow: ellipsis;
1143 white-space: nowrap;
1144}
1145
1146.ic-row {
1147 width: 18px;
1148 height: 18px;
1149 flex: none;
1150}
1151
1152.share-item-meta {
1153 font-size: 12px;
1154 margin-top: 2px;
1155 overflow: hidden;
1156 text-overflow: ellipsis;
1157 white-space: nowrap;
1158}
1159
1160.share-item-actions {
1161 display: flex;
1162 gap: 6px;
1163 flex-shrink: 0;
1164}
1165
1166/* Public share page */
1167
1168.share-badge {
1169 display: inline-flex;
1170 align-items: center;
1171 gap: 6px;
1172 font-size: 13px;
1173 color: var(--muted);
1174 background: var(--panel);
1175 border: 1px solid var(--border);
1176 padding: 4px 10px;
1177}
1178
1179.ic-badge {
1180 width: 14px;
1181 height: 14px;
1182 flex: none;
1183}
1184
1185.share-footer {
1186 padding: 16px;
1187 text-align: center;
1188 font-size: 12px;
1189 border-top: 1px solid var(--border);
1190 margin-top: auto;
1191}
1192
1193.share-file-page {
1194 display: flex;
1195 flex-direction: column;
1196 align-items: center;
1197 gap: 12px;
1198 padding: 80px 20px;
1199 text-align: center;
1200}
1201
1202.share-file-glyph {
1203 width: 64px;
1204 height: 64px;
1205}
1206
1207.share-file-page h2 {
1208 margin: 0;
1209 word-break: break-word;
1210}
1211
1212.share-file-actions .btn-primary {
1213 width: auto;
1214 min-width: 140px;
1215}
1216
1217/* ------------------------------------------------------------------ */
1218/* Admin (milestone 7) */
1219/* ------------------------------------------------------------------ */
1220
1221.admin-view {
1222 display: flex;
1223 flex-direction: column;
1224 gap: 16px;
1225 width: 100%;
1226 max-width: 960px;
1227 margin: 0 auto;
1228}
1229
1230.admin-section-title {
1231 margin: 0 0 14px;
1232 font-size: 15px;
1233}
1234
1235.users-header {
1236 display: flex;
1237 align-items: center;
1238 justify-content: space-between;
1239 margin-bottom: 4px;
1240}
1241
1242.users-header .admin-section-title {
1243 margin-bottom: 0;
1244}
1245
1246.users-header .btn-primary {
1247 width: auto;
1248}
1249
1250.user-list {
1251 display: flex;
1252 flex-direction: column;
1253 gap: 10px;
1254}
1255
1256.user-row {
1257 display: flex;
1258 align-items: center;
1259 justify-content: space-between;
1260 gap: 12px;
1261 padding: 12px 14px;
1262 border: 1px solid var(--border);
1263}
1264
1265.user-row-main {
1266 min-width: 0;
1267}
1268
1269.user-row-name {
1270 display: flex;
1271 align-items: center;
1272 gap: 6px;
1273 font-weight: 600;
1274 font-size: 14px;
1275 flex-wrap: wrap;
1276}
1277
1278.ic-admin {
1279 width: 16px;
1280 height: 16px;
1281 flex: none;
1282}
1283
1284.user-row-actions {
1285 display: flex;
1286 gap: 6px;
1287 flex-shrink: 0;
1288}
1289
1290.badge-off {
1291 background: color-mix(in srgb, var(--danger) 15%, var(--panel));
1292 border-color: var(--danger);
1293 color: var(--danger);
1294}
1295
1296.setting-row {
1297 display: flex;
1298 align-items: flex-start;
1299 gap: 10px;
1300 padding: 14px;
1301 border: 1px solid var(--border);
1302 cursor: pointer;
1303}
1304
1305.setting-row input {
1306 width: auto;
1307 margin-top: 2px;
1308}
1309
1310.setting-label {
1311 display: block;
1312 font-weight: 600;
1313 font-size: 14px;
1314}
1315
1316.setting-desc {
1317 display: block;
1318 font-size: 12px;
1319 color: var(--muted);
1320 margin-top: 2px;
1321}
1322
1323/* User create/edit form */
1324
1325.user-form {
1326 width: 520px;
1327}
1328
1329.field-input {
1330 width: 100%;
1331 box-sizing: border-box;
1332}
1333
1334.field-hint {
1335 font-size: 12px;
1336 margin: -2px 0 8px;
1337}
1338
1339.check-row {
1340 display: flex;
1341 align-items: center;
1342 gap: 8px;
1343 font-size: 14px;
1344 margin-bottom: 12px;
1345 cursor: pointer;
1346}
1347
1348.check-row input {
1349 width: auto;
1350}
1351
1352.form-error {
1353 color: var(--danger);
1354 font-size: 13px;
1355 margin: 4px 0 8px;
1356}
1357
1358.roots-editor {
1359 display: flex;
1360 flex-direction: column;
1361 gap: 6px;
1362}
1363
1364.root-draft {
1365 display: flex;
1366 align-items: center;
1367 gap: 8px;
1368}
1369
1370.root-draft-path {
1371 flex: 1;
1372 font-size: 13px;
1373 overflow: hidden;
1374 text-overflow: ellipsis;
1375 white-space: nowrap;
1376}
1377
1378.root-draft-mode {
1379 width: auto;
1380 padding: 6px 8px;
1381}
1382
1383.root-add {
1384 display: flex;
1385 gap: 8px;
1386 margin-top: 4px;
1387}
1388
1389/* ------------------------------------------------------------------ */
1390/* Empty state + keyboard focus (milestone 8) */
1391/* ------------------------------------------------------------------ */
1392
1393.empty-state {
1394 display: flex;
1395 flex-direction: column;
1396 align-items: center;
1397 justify-content: center;
1398 gap: 8px;
1399 padding: 64px 20px;
1400 text-align: center;
1401}
1402
1403.empty-glyph {
1404 width: 52px;
1405 height: 52px;
1406}
1407
1408.empty-state h3 {
1409 margin: 0;
1410 font-size: 16px;
1411}
1412
1413/* Visible keyboard focus on selectable file/folder entries. */
1414.tile:focus-visible,
1415.row:focus-visible {
1416 outline: 2px solid var(--accent);
1417 outline-offset: 2px;
1418}
1419