style.css
⎇
Raw
1:root {
2 --bg-primary: #ffffff;
3 --bg-secondary: #f5f5f5;
4 --bg-tertiary: #e0e0e0;
5 --text-primary: #212121;
6 --text-secondary: #666666;
7 --accent: #1976d2;
8 --accent-hover: #1565c0;
9 --danger: #d32f2f;
10 --danger-hover: #b71c1c;
11 --success: #388e3c;
12 --warning: #f57c00;
13 --border: #e0e0e0;
14 --shadow: rgba(0, 0, 0, 0.1);
15 --player-bg: #000000;
16}
17
18[data-theme="dark"] {
19 --bg-primary: #121212;
20 --bg-secondary: #1e1e1e;
21 --bg-tertiary: #2d2d2d;
22 --text-primary: #ffffff;
23 --text-secondary: #b0b0b0;
24 --accent: #90caf9;
25 --accent-hover: #64b5f6;
26 --danger: #ef5350;
27 --danger-hover: #e53935;
28 --success: #66bb6a;
29 --warning: #ffa726;
30 --border: #424242;
31 --shadow: rgba(0, 0, 0, 0.3);
32 --player-bg: #000000;
33}
34
35@media (prefers-color-scheme: dark) {
36 [data-theme="auto"] {
37 --bg-primary: #121212;
38 --bg-secondary: #1e1e1e;
39 --bg-tertiary: #2d2d2d;
40 --text-primary: #ffffff;
41 --text-secondary: #b0b0b0;
42 --accent: #90caf9;
43 --accent-hover: #64b5f6;
44 --danger: #ef5350;
45 --danger-hover: #e53935;
46 --success: #66bb6a;
47 --warning: #ffa726;
48 --border: #424242;
49 --shadow: rgba(0, 0, 0, 0.3);
50 --player-bg: #000000;
51 }
52}
53
54* {
55 box-sizing: border-box;
56 margin: 0;
57 padding: 0;
58}
59
60body {
61 font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
62 background-color: var(--bg-primary);
63 color: var(--text-primary);
64 line-height: 1.6;
65 min-height: 100vh;
66 display: flex;
67 flex-direction: column;
68}
69
70header {
71 background-color: var(--bg-secondary);
72 border-bottom: 1px solid var(--border);
73 padding: 1rem 2rem;
74 position: sticky;
75 top: 0;
76 z-index: 100;
77 display: flex;
78 align-items: center;
79 gap: 2rem;
80}
81
82header h1 {
83 margin: 0;
84 flex-shrink: 0;
85}
86
87header h1 a {
88 color: var(--accent);
89 text-decoration: none;
90 font-size: 1.5rem;
91}
92
93.theme-toggle {
94 display: flex;
95 gap: 0.5rem;
96}
97
98.theme-toggle button {
99 background: var(--bg-tertiary);
100 border: 1px solid var(--border);
101 color: var(--text-primary);
102 padding: 0.4rem 0.6rem;
103 border-radius: 4px;
104 cursor: pointer;
105 transition: background-color 0.2s;
106}
107
108.theme-toggle button:hover {
109 background: var(--accent);
110 color: white;
111}
112
113.theme-toggle button.active {
114 background: var(--accent);
115 color: white;
116 border-color: var(--accent);
117}
118
119nav {
120 display: flex;
121 gap: 1rem;
122}
123
124nav a {
125 color: var(--text-secondary);
126 text-decoration: none;
127 padding: 0.5rem 1rem;
128 border-radius: 4px;
129 transition: all 0.2s;
130}
131
132nav a:hover,
133nav a.active {
134 color: var(--accent);
135 background-color: var(--bg-tertiary);
136}
137
138main {
139 flex: 1;
140 padding: 2rem;
141 max-width: 1400px;
142 margin: 0 auto;
143 width: 100%;
144}
145
146footer {
147 background-color: var(--bg-secondary);
148 border-top: 1px solid var(--border);
149 padding: 1rem 2rem;
150 text-align: center;
151 color: var(--text-secondary);
152 font-size: 0.9rem;
153}
154
155/* Page headers */
156.page-header {
157 display: flex;
158 justify-content: space-between;
159 align-items: center;
160 margin-bottom: 1.5rem;
161 flex-wrap: wrap;
162 gap: 1rem;
163}
164
165.page-header h2 {
166 font-size: 1.5rem;
167}
168
169.actions {
170 display: flex;
171 gap: 1rem;
172 align-items: center;
173 flex-wrap: wrap;
174}
175
176/* Forms */
177.form-card {
178 background: var(--bg-secondary);
179 border: 1px solid var(--border);
180 border-radius: 8px;
181 padding: 1.5rem;
182 max-width: 800px;
183}
184
185.form-group {
186 margin-bottom: 1rem;
187}
188
189.form-group label {
190 display: block;
191 margin-bottom: 0.5rem;
192 font-weight: 500;
193}
194
195.form-group input[type="text"],
196.form-group input[type="url"],
197.form-group input[type="number"],
198.form-group select,
199.form-group textarea {
200 width: 100%;
201 padding: 0.6rem;
202 border: 1px solid var(--border);
203 border-radius: 4px;
204 background: var(--bg-primary);
205 color: var(--text-primary);
206 font-family: inherit;
207}
208
209.form-group input:focus,
210.form-group select:focus,
211.form-group textarea:focus {
212 outline: none;
213 border-color: var(--accent);
214}
215
216.form-group.checkbox label {
217 display: flex;
218 align-items: center;
219 gap: 0.5rem;
220 cursor: pointer;
221}
222
223.form-group.checkbox input[type="checkbox"] {
224 width: auto;
225}
226
227.form-row {
228 display: grid;
229 grid-template-columns: 1fr 1fr;
230 gap: 1rem;
231}
232
233.radio-group {
234 display: flex;
235 flex-wrap: wrap;
236 gap: 1rem;
237}
238
239.radio-group label {
240 display: flex;
241 align-items: center;
242 gap: 0.3rem;
243 cursor: pointer;
244 font-weight: normal;
245}
246
247.form-actions {
248 display: flex;
249 gap: 1rem;
250 margin-top: 1.5rem;
251}
252
253.form-group small {
254 display: block;
255 margin-top: 0.3rem;
256 color: var(--text-secondary);
257 font-size: 0.85rem;
258}
259
260/* Buttons */
261button,
262.button {
263 padding: 0.6rem 1.2rem;
264 border: none;
265 border-radius: 4px;
266 cursor: pointer;
267 font-family: inherit;
268 font-size: 0.95rem;
269 text-decoration: none;
270 display: inline-flex;
271 align-items: center;
272 justify-content: center;
273 transition: background-color 0.2s;
274}
275
276button.primary,
277.button.primary {
278 background: var(--accent);
279 color: white;
280}
281
282button.primary:hover,
283.button.primary:hover {
284 background: var(--accent-hover);
285}
286
287button.secondary,
288.button.secondary {
289 background: var(--bg-tertiary);
290 color: var(--text-primary);
291 border: 1px solid var(--border);
292}
293
294button.secondary:hover,
295.button.secondary:hover {
296 background: var(--border);
297}
298
299button.danger,
300.button.danger {
301 background: var(--danger);
302 color: white;
303}
304
305button.danger:hover,
306.button.danger:hover {
307 background: var(--danger-hover);
308}
309
310button.small {
311 padding: 0.3rem 0.6rem;
312 font-size: 0.85rem;
313}
314
315button:disabled {
316 opacity: 0.5;
317 cursor: not-allowed;
318}
319
320/* Library grid */
321.breadcrumbs {
322 margin-bottom: 1rem;
323 padding: 0.5rem;
324 background: var(--bg-secondary);
325 border-radius: 4px;
326}
327
328.breadcrumbs a {
329 color: var(--accent);
330 text-decoration: none;
331}
332
333.breadcrumbs a:hover {
334 text-decoration: underline;
335}
336
337.breadcrumbs span {
338 margin: 0 0.3rem;
339 color: var(--text-secondary);
340}
341
342.library-grid {
343 display: grid;
344 grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
345 gap: 1rem;
346}
347
348.folder-item,
349.media-item {
350 background: var(--bg-secondary);
351 border: 1px solid var(--border);
352 border-radius: 8px;
353 overflow: hidden;
354 text-decoration: none;
355 color: var(--text-primary);
356 transition: transform 0.2s, box-shadow 0.2s;
357}
358
359.folder-item:hover,
360.media-item:hover {
361 transform: translateY(-2px);
362 box-shadow: 0 4px 12px var(--shadow);
363}
364
365.folder-icon,
366.media-thumbnail {
367 aspect-ratio: 16/9;
368 background: var(--bg-tertiary);
369 display: flex;
370 align-items: center;
371 justify-content: center;
372 font-size: 3rem;
373}
374
375.media-thumbnail img {
376 width: 100%;
377 height: 100%;
378 object-fit: cover;
379}
380
381.audio-icon,
382.video-icon {
383 font-size: 3rem;
384 opacity: 0.5;
385}
386
387.folder-name,
388.media-info {
389 padding: 0.75rem;
390}
391
392.media-title {
393 font-weight: 500;
394 margin-bottom: 0.3rem;
395 overflow: hidden;
396 text-overflow: ellipsis;
397 white-space: nowrap;
398}
399
400.media-duration,
401.media-path {
402 font-size: 0.85rem;
403 color: var(--text-secondary);
404}
405
406/* Detail view */
407.detail-view {
408 max-width: 900px;
409}
410
411.detail-header {
412 display: flex;
413 justify-content: space-between;
414 align-items: center;
415 margin-bottom: 1.5rem;
416 flex-wrap: wrap;
417 gap: 1rem;
418}
419
420.back-link {
421 color: var(--accent);
422 text-decoration: none;
423}
424
425.player-container {
426 background: var(--player-bg);
427 border-radius: 8px;
428 overflow: hidden;
429 margin-bottom: 1.5rem;
430}
431
432.player-container video,
433.player-container audio {
434 width: 100%;
435 display: block;
436}
437
438.detail-meta dl {
439 display: grid;
440 grid-template-columns: 150px 1fr;
441 gap: 0.5rem 1rem;
442}
443
444.detail-meta dt {
445 color: var(--text-secondary);
446 font-weight: 500;
447}
448
449.detail-meta dd {
450 word-break: break-all;
451}
452
453.detail-meta a {
454 color: var(--accent);
455}
456
457/* Queue */
458.queue-list {
459 display: flex;
460 flex-direction: column;
461 gap: 1rem;
462}
463
464.queue-item {
465 background: var(--bg-secondary);
466 border: 1px solid var(--border);
467 border-radius: 8px;
468 padding: 1rem;
469}
470
471.queue-header {
472 display: flex;
473 justify-content: space-between;
474 align-items: flex-start;
475 gap: 1rem;
476 flex-wrap: wrap;
477 margin-bottom: 0.5rem;
478}
479
480.queue-url {
481 flex: 1;
482 min-width: 0;
483}
484
485.queue-url a {
486 color: var(--accent);
487 text-decoration: none;
488 word-break: break-all;
489}
490
491.queue-status {
492 display: flex;
493 gap: 0.5rem;
494 align-items: center;
495 flex-wrap: wrap;
496}
497
498.status-badge {
499 padding: 0.2rem 0.6rem;
500 border-radius: 12px;
501 font-size: 0.85rem;
502 font-weight: 500;
503}
504
505.status-badge.queued {
506 background: var(--bg-tertiary);
507 color: var(--text-secondary);
508}
509
510.status-badge.downloading {
511 background: var(--accent);
512 color: white;
513}
514
515.status-badge.completed {
516 background: var(--success);
517 color: white;
518}
519
520.status-badge.error {
521 background: var(--danger);
522 color: white;
523}
524
525.progress-bar {
526 height: 6px;
527 background: var(--bg-tertiary);
528 border-radius: 3px;
529 overflow: hidden;
530 margin: 0.5rem 0;
531}
532
533.progress-bar.large {
534 height: 12px;
535 border-radius: 6px;
536}
537
538.progress-fill {
539 height: 100%;
540 background: var(--accent);
541 transition: width 0.3s;
542}
543
544.error-message {
545 color: var(--danger);
546 font-size: 0.9rem;
547 margin-top: 0.5rem;
548}
549
550.queue-meta {
551 margin-top: 0.5rem;
552 font-size: 0.85rem;
553 color: var(--text-secondary);
554 display: flex;
555 gap: 1rem;
556}
557
558/* Logs */
559.logs-container {
560 background: var(--bg-secondary);
561 border: 1px solid var(--border);
562 border-radius: 8px;
563 padding: 1rem;
564 margin-top: 1rem;
565}
566
567.logs-container h3 {
568 margin-bottom: 0.5rem;
569}
570
571.logs {
572 background: var(--bg-primary);
573 border: 1px solid var(--border);
574 border-radius: 4px;
575 padding: 1rem;
576 max-height: 500px;
577 overflow-y: auto;
578 font-family: "Courier New", monospace;
579 font-size: 0.85rem;
580 line-height: 1.4;
581 white-space: pre-wrap;
582 word-break: break-all;
583}
584
585/* Settings */
586.settings-layout {
587 display: flex;
588 flex-direction: column;
589 gap: 2rem;
590}
591
592.settings-section {
593 background: var(--bg-secondary);
594 border: 1px solid var(--border);
595 border-radius: 8px;
596 padding: 1.5rem;
597}
598
599.settings-section h3 {
600 margin-bottom: 1rem;
601}
602
603.presets-list {
604 display: flex;
605 flex-direction: column;
606 gap: 1rem;
607 margin-bottom: 1.5rem;
608}
609
610.preset-card {
611 background: var(--bg-primary);
612 border: 1px solid var(--border);
613 border-radius: 6px;
614 padding: 1rem;
615}
616
617.preset-header {
618 display: flex;
619 justify-content: space-between;
620 align-items: center;
621 margin-bottom: 0.5rem;
622}
623
624.preset-header h4 {
625 display: flex;
626 align-items: center;
627 gap: 0.5rem;
628}
629
630.badge {
631 background: var(--accent);
632 color: white;
633 padding: 0.1rem 0.4rem;
634 border-radius: 10px;
635 font-size: 0.75rem;
636}
637
638.preset-actions {
639 display: flex;
640 gap: 0.5rem;
641 flex-wrap: wrap;
642 margin-top: 1rem;
643}
644
645.preset-description {
646 color: var(--text-secondary);
647 margin-bottom: 0.5rem;
648}
649
650.preset-flags {
651 margin-top: 0.5rem;
652}
653
654.preset-flags pre {
655 background: var(--bg-tertiary);
656 padding: 0.5rem;
657 border-radius: 4px;
658 font-size: 0.85rem;
659 overflow-x: auto;
660 margin-top: 0.3rem;
661}
662
663/* Toggle text: Edit vs Cancel */
664details .cancel-text {
665 display: none;
666}
667
668details[open] .edit-text {
669 display: none;
670}
671
672details[open] .cancel-text {
673 display: inline;
674}
675
676/* Delete overlay popover */
677.delete-overlay {
678 position: relative;
679}
680
681.delete-overlay summary {
682 list-style: none;
683 cursor: pointer;
684}
685
686.delete-overlay summary::-webkit-details-marker {
687 display: none;
688}
689
690.delete-overlay .overlay-panel {
691 position: absolute;
692 top: calc(100% + 0.5rem);
693 right: 0;
694 z-index: 1000;
695 width: 260px;
696 background: var(--bg-primary);
697 border: 1px solid var(--border);
698 border-radius: 8px;
699 padding: 1rem;
700 box-shadow: 0 4px 12px var(--shadow);
701}
702
703/* Popover arrow */
704.delete-overlay .overlay-panel::before {
705 content: '';
706 position: absolute;
707 top: -6px;
708 right: 1rem;
709 width: 10px;
710 height: 10px;
711 background: var(--bg-primary);
712 border-left: 1px solid var(--border);
713 border-top: 1px solid var(--border);
714 transform: rotate(45deg);
715}
716
717.delete-overlay .overlay-panel p {
718 margin-bottom: 1rem;
719 font-size: 0.9rem;
720}
721
722.delete-overlay .overlay-panel .form-actions {
723 margin-top: 0;
724 justify-content: flex-end;
725}
726
727/* Inline edit form */
728.edit-form {
729 padding: 1rem;
730}
731
732/* Conditional sections (no-JS show/hide) */
733.conditional-section {
734 margin-bottom: 1rem;
735}
736
737.conditional-section .conditional-content {
738 display: none;
739 margin-top: 1rem;
740}
741
742/* Checkbox triggers */
743.conditional-section:has(input[type="checkbox"].conditional-trigger:checked) .conditional-content {
744 display: block;
745}
746
747/* Radio triggers for format mode */
748.conditional-section:has(.radio-group input[value="preset"]:checked) .conditional-content.format-preset,
749.conditional-section:has(.radio-group input[value="custom"]:checked) .conditional-content.format-custom {
750 display: block;
751}
752
753/* Format mode selector - hidden radio inputs with button-like labels */
754.radio-group.format-mode {
755 display: flex;
756 gap: 0.5rem;
757 margin-top: 0.5rem;
758 flex-wrap: wrap;
759}
760
761.radio-group.format-mode input[type="radio"] {
762 position: absolute;
763 opacity: 0;
764 width: 0;
765 height: 0;
766}
767
768.radio-group.format-mode label {
769 padding: 0.4rem 0.8rem;
770 border: 1px solid var(--border);
771 border-radius: 4px;
772 cursor: pointer;
773 background: var(--bg-primary);
774 transition: all 0.2s;
775 font-weight: normal;
776}
777
778.radio-group.format-mode label:hover {
779 background: var(--bg-tertiary);
780}
781
782.radio-group.format-mode label:has(input:checked) {
783 background: var(--accent);
784 color: white;
785 border-color: var(--accent);
786}
787
788/* Theme selector */
789.theme-selector {
790 display: flex;
791 gap: 0.5rem;
792}
793
794.theme-selector button {
795 min-width: 80px;
796}
797
798.theme-selector button.active {
799 background: var(--accent);
800 color: white;
801 border-color: var(--accent);
802}
803
804/* Download form */
805.download-form {
806 max-width: 900px;
807}
808
809.formats-table-container {
810 margin: 1rem 0;
811 background: var(--bg-secondary);
812 border: 1px solid var(--border);
813 border-radius: 8px;
814 padding: 1rem;
815}
816
817.formats-table {
818 width: 100%;
819 border-collapse: collapse;
820 font-size: 0.9rem;
821}
822
823.formats-table th,
824.formats-table td {
825 padding: 0.5rem;
826 text-align: left;
827 border-bottom: 1px solid var(--border);
828}
829
830.formats-table th {
831 background: var(--bg-tertiary);
832 font-weight: 500;
833}
834
835.formats-table tr:hover {
836 background: var(--bg-primary);
837}
838
839/* Filter form inline */
840.filter-form {
841 display: flex;
842 gap: 0.5rem;
843 align-items: center;
844}
845
846.filter-form input,
847.filter-form select {
848 padding: 0.4rem;
849}
850
851/* Empty state */
852.empty-state {
853 text-align: center;
854 padding: 3rem;
855 color: var(--text-secondary);
856}
857
858.empty-state a {
859 color: var(--accent);
860}
861
862/* Utility */
863.inline {
864 display: inline;
865}
866
867/* Responsive */
868@media (max-width: 768px) {
869 main {
870 padding: 1rem;
871 }
872
873 .page-header {
874 flex-direction: column;
875 align-items: flex-start;
876 }
877
878 .library-grid {
879 grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
880 }
881
882 .form-row {
883 grid-template-columns: 1fr;
884 }
885
886 .detail-meta dl {
887 grid-template-columns: 1fr;
888 }
889
890 .queue-header {
891 flex-direction: column;
892 }
893}
894