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