style.css
⎇
Raw
1/* Custom layout and components on top of Pico.css */
2
3/* Scale down Pico's default sizing */
4html {
5 font-size: 16px;
6}
7
8/* Remove Pico's default bottom margin on button types */
9[type="button"],
10[type="reset"],
11[type="submit"] {
12 margin-bottom: 0;
13}
14
15/* Layout */
16body {
17 min-height: 100vh;
18 display: flex;
19 flex-direction: column;
20}
21
22body > header {
23 padding: 1rem 2rem;
24 position: sticky;
25 top: 0;
26 z-index: 100;
27 background-color: var(--pico-card-background-color);
28 border-bottom: 1px solid var(--pico-muted-border-color);
29 display: flex;
30 align-items: center;
31 gap: 2rem;
32}
33
34body > header h1 {
35 margin: 0;
36 flex-shrink: 0;
37 font-size: 1.5rem;
38}
39
40/* Brand: logo + wordmark, no longer a link */
41.brand {
42 display: flex;
43 align-items: center;
44 gap: 0.55rem;
45}
46
47.brand-logo {
48 display: block;
49 flex-shrink: 0;
50}
51
52nav {
53 display: flex;
54 align-items: center;
55 gap: 1rem;
56 /* Take the rest of the header row, so the sign-out button can sit at its far
57 right while the links stay next to the brand. */
58 flex: 1;
59}
60
61.nav-signout {
62 margin-left: auto;
63}
64
65nav a {
66 color: var(--pico-muted-color);
67 text-decoration: none;
68 padding: 0.5rem 1rem;
69 border-radius: var(--pico-border-radius);
70 transition: all 0.2s;
71}
72
73nav a:hover {
74 color: var(--pico-primary);
75 background-color: var(--pico-card-sectioning-background-color);
76}
77
78nav a.active {
79 background-color: var(--pico-primary);
80 color: var(--pico-primary-inverse);
81 font-weight: 600;
82}
83
84main {
85 flex: 1;
86 padding: 2rem 1rem;
87}
88
89main > * {
90 max-width: 1400px;
91 margin-left: auto;
92 margin-right: auto;
93}
94
95footer {
96 padding: 1rem 2rem;
97 text-align: center;
98 color: var(--pico-muted-color);
99 font-size: 0.9rem;
100 background-color: var(--pico-card-background-color);
101 border-top: 1px solid var(--pico-muted-border-color);
102}
103
104/* Page headers */
105.page-header {
106 display: flex;
107 justify-content: space-between;
108 align-items: center;
109 margin-bottom: 1.5rem;
110 flex-wrap: wrap;
111 gap: 1rem;
112}
113
114.page-header h2 {
115 font-size: 1.5rem;
116 margin: 0;
117}
118
119.actions {
120 display: flex;
121 gap: 1rem;
122 align-items: center;
123 flex-wrap: wrap;
124}
125
126/* Forms */
127.form-group {
128 margin-bottom: 1rem;
129}
130
131.form-row {
132 display: grid;
133 grid-template-columns: 1fr 1fr;
134 gap: 1rem;
135}
136
137.radio-group {
138 display: flex;
139 flex-wrap: wrap;
140 gap: 1rem;
141}
142
143.radio-group label {
144 display: flex;
145 align-items: center;
146 gap: 0.3rem;
147 cursor: pointer;
148 font-weight: normal;
149 margin-bottom: 0;
150}
151
152.form-actions {
153 display: flex;
154 gap: 1rem;
155 margin-top: 1.5rem;
156}
157
158.file-selector {
159 display: flex;
160 align-items: center;
161 gap: 0.75rem;
162 flex-wrap: wrap;
163 margin-bottom: 1rem;
164}
165
166.file-selector label {
167 margin: 0;
168}
169
170.file-selector select {
171 flex: 1;
172 min-width: 0;
173 margin: 0;
174}
175
176.file-selector button {
177 margin: 0;
178 width: auto;
179 flex: none;
180}
181
182/* Buttons */
183button.small,
184[role="button"].small {
185 padding: 0.3rem 0.6rem;
186 font-size: 0.85rem;
187}
188
189button.danger,
190button.danger:hover,
191button.danger:focus,
192[role="button"].danger,
193[role="button"].danger:hover,
194[role="button"].danger:focus {
195 --pico-background-color: #c62828;
196 --pico-border-color: #c62828;
197 --pico-color: white;
198}
199
200button.danger:hover,
201button.danger:focus,
202[role="button"].danger:hover,
203[role="button"].danger:focus {
204 --pico-background-color: #b71c1c;
205 --pico-border-color: #b71c1c;
206}
207
208/* One-shot feedback banner shown after a form action (see PageData.Flash). */
209.flash {
210 padding: 0.75rem 1rem;
211 margin-bottom: 1.5rem;
212 border-radius: var(--pico-border-radius);
213 border: 1px solid transparent;
214 border-left-width: 4px;
215}
216
217.flash-success {
218 background-color: rgba(46, 125, 50, 0.12);
219 border-color: #2e7d32;
220 color: var(--pico-color);
221}
222
223.flash-error {
224 background-color: rgba(198, 40, 40, 0.12);
225 border-color: #c62828;
226 color: var(--pico-color);
227}
228
229button:disabled {
230 opacity: 0.5;
231 cursor: not-allowed;
232}
233
234/* Library */
235.breadcrumbs {
236 margin-bottom: 1rem;
237 display: flex;
238 align-items: center;
239 justify-content: flex-start;
240 gap: 0.35rem;
241 flex-wrap: wrap;
242 text-align: left;
243 width: 100%;
244}
245
246.breadcrumbs a,
247.breadcrumbs span {
248 flex-shrink: 0;
249}
250
251.breadcrumbs .current {
252 cursor: default;
253 pointer-events: none;
254}
255
256.library-grid {
257 display: grid;
258 grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
259 gap: 1rem;
260}
261
262.folder-item,
263.media-item {
264 background: var(--pico-card-background-color);
265 border: 1px solid var(--pico-card-border-color);
266 border-radius: var(--pico-border-radius);
267 overflow: hidden;
268 text-decoration: none;
269 color: var(--pico-color);
270 box-shadow: var(--pico-card-box-shadow);
271}
272
273.folder-item:hover,
274.media-item:hover {
275 background-color: var(--pico-primary-background);
276 border-color: var(--pico-primary-border);
277 box-shadow: var(--pico-card-box-shadow), 0 4px 12px rgba(0, 0, 0, 0.15);
278}
279
280.folder-item:hover .folder-name,
281.media-item:hover .media-info,
282.media-item:hover .media-title {
283 color: var(--pico-primary-inverse);
284}
285
286.media-info {
287 transition: color 0.2s;
288}
289
290.media-thumbnail {
291 aspect-ratio: 16/9;
292 background: var(--pico-card-sectioning-background-color);
293 display: flex;
294 align-items: center;
295 justify-content: center;
296 font-size: 3rem;
297 position: relative;
298}
299
300/* Each thumbnail sits in a tile so it can carry its own per-file duration
301 badge; the tile fills the container (single file) or a grid cell (multi). */
302.thumb-tile {
303 position: relative;
304 display: flex;
305 align-items: center;
306 justify-content: center;
307 overflow: hidden;
308 width: 100%;
309 height: 100%;
310 min-width: 0;
311 min-height: 0;
312}
313
314.thumb-tile .media-duration {
315 position: absolute;
316 bottom: 0.4rem;
317 right: 0.4rem;
318 background: rgba(0, 0, 0, 0.75);
319 color: #fff;
320 padding: 0.15rem 0.4rem;
321 border-radius: var(--pico-border-radius);
322 font-size: 0.7rem;
323 font-weight: 500;
324 line-height: 1;
325}
326
327.folder-icon {
328 aspect-ratio: 16/9;
329 background: var(--pico-card-sectioning-background-color);
330 display: flex;
331 align-items: center;
332 justify-content: center;
333 font-size: 3rem;
334}
335
336.thumb-tile img {
337 width: 100%;
338 height: 100%;
339 /* contain: show the whole thumbnail (letterboxed) and never overflow the
340 16/9 box, including portrait/vertical sources. */
341 object-fit: contain;
342}
343
344.thumb-tile img[src$=".svg"] {
345 width: 48px;
346 height: 48px;
347 opacity: 0.5;
348 object-fit: contain;
349}
350
351/* Multi-file items: tile each media file's thumbnail in a grid. */
352.media-thumbnail.count-2,
353.media-thumbnail.count-3,
354.media-thumbnail.count-many {
355 display: grid;
356 gap: 2px;
357}
358
359.media-thumbnail.count-2 {
360 grid-template-columns: 1fr 1fr;
361}
362
363.media-thumbnail.count-3,
364.media-thumbnail.count-many {
365 grid-template-columns: 1fr 1fr;
366 grid-template-rows: 1fr 1fr;
367}
368
369/* For 3 files, let the first thumbnail span the full top row. */
370.media-thumbnail.count-3 .thumb-tile:first-of-type {
371 grid-column: 1 / -1;
372}
373
374/* "+N" overlay on the last tile when there are more than 4 files. */
375.media-thumbnail .thumb-more {
376 position: absolute;
377 right: 0;
378 bottom: 0;
379 width: 50%;
380 height: 50%;
381 display: flex;
382 align-items: center;
383 justify-content: center;
384 background: rgba(0, 0, 0, 0.6);
385 color: #fff;
386 font-size: 1.1rem;
387 font-weight: 600;
388 pointer-events: none;
389}
390
391/* File-count badge in the top-left for multi-file items. */
392.media-thumbnail .thumb-count {
393 position: absolute;
394 top: 0.4rem;
395 left: 0.4rem;
396 background: rgba(0, 0, 0, 0.75);
397 color: #fff;
398 padding: 0.15rem 0.4rem;
399 border-radius: var(--pico-border-radius);
400 font-size: 0.7rem;
401 font-weight: 500;
402 line-height: 1;
403}
404
405.folder-name,
406.media-info {
407 padding: 0.75rem;
408}
409
410.media-title {
411 font-weight: 500;
412 margin-bottom: 0.3rem;
413 overflow: hidden;
414 text-overflow: ellipsis;
415 white-space: nowrap;
416}
417
418.media-info .media-duration {
419 display: none;
420}
421
422/* Detail view */
423.detail-view {
424 max-width: 900px;
425}
426
427.detail-header {
428 display: flex;
429 justify-content: space-between;
430 align-items: center;
431 margin-bottom: 1.5rem;
432 flex-wrap: wrap;
433 gap: 1rem;
434}
435
436.player-container {
437 background: #000;
438 border-radius: var(--pico-border-radius);
439 overflow: hidden;
440 margin-bottom: 1.5rem;
441 max-height: 80vh;
442 display: flex;
443 align-items: center;
444 justify-content: center;
445}
446
447.player-container video,
448.player-container audio {
449 max-width: 100%;
450 max-height: 80vh;
451 width: auto;
452 height: auto;
453 display: block;
454}
455
456.detail-meta dl {
457 display: grid;
458 grid-template-columns: 150px 1fr;
459 gap: 0.5rem 1rem;
460 align-items: baseline;
461}
462
463/* Render keys as understated labels so they read as keys — not just another
464 line of value text — in both the two-column and the stacked (narrow) layout. */
465.detail-meta dt {
466 font-size: 0.75rem;
467 font-weight: 600;
468 text-transform: uppercase;
469 letter-spacing: 0.04em;
470 color: var(--pico-muted-color);
471}
472
473.detail-meta dd {
474 word-break: break-all;
475 margin: 0;
476}
477
478/* Description: preserve the source line breaks; collapse long ones to ~2 lines
479 with a pure-CSS (no-JS, CSP-safe) Show more/less toggle. */
480.detail-meta dd.description {
481 margin: 0;
482}
483
484.description .desc-text {
485 white-space: pre-wrap;
486 word-break: normal;
487 overflow-wrap: anywhere;
488 line-height: 1.5;
489}
490
491/* The checkbox is the toggle state; it's driven by the label, never shown. */
492.description.collapsible .desc-toggle {
493 display: none;
494}
495
496/* Collapsed: clamp to ~2 lines (max-height works with pre-wrap; line-clamp
497 does not), with a fade so the cut reads as intentional. */
498.description.collapsible .desc-text {
499 position: relative;
500 max-height: 3em;
501 overflow: hidden;
502}
503
504.description.collapsible .desc-text::after {
505 content: "";
506 position: absolute;
507 left: 0;
508 right: 0;
509 bottom: 0;
510 height: 1.5em;
511 background: linear-gradient(to bottom, transparent, var(--pico-background-color));
512 pointer-events: none;
513}
514
515.description.collapsible .desc-toggle:checked ~ .desc-text {
516 max-height: none;
517}
518
519.description.collapsible .desc-toggle:checked ~ .desc-text::after {
520 display: none;
521}
522
523.description.collapsible .desc-toggle-label {
524 display: inline-block;
525 margin-top: 0.4rem;
526 color: var(--pico-primary);
527 font-size: 0.85rem;
528 font-weight: 600;
529 cursor: pointer;
530 user-select: none;
531}
532
533.description.collapsible .desc-toggle-label::after {
534 content: "Show more \25be";
535}
536
537.description.collapsible .desc-toggle:checked ~ .desc-toggle-label::after {
538 content: "Show less \25b4";
539}
540
541/* Engagement metadata */
542.engagement-section {
543 margin-top: 2rem;
544}
545
546.engagement-section > summary .badge {
547 margin-left: 0.35rem;
548}
549
550.comments-actions {
551 margin: 0.75rem 0;
552 text-align: right;
553}
554
555.comment-settings-group:has(input[name="write_info_json"]:not(:checked)) .comment-options {
556 display: none;
557}
558
559.comment-options:has(input[name="write_comments"]:not(:checked)) .comment-settings-fields {
560 display: none;
561}
562
563.comment-options {
564 margin-top: 1rem;
565 padding: 0.75rem 1rem 1rem;
566}
567
568.comment-options legend {
569 padding: 0 0.35rem;
570 font-weight: 600;
571}
572
573.comment-settings-fields {
574 margin: 0.75rem 0 0 1.5rem;
575 padding-left: 1rem;
576 border-left: 2px solid var(--pico-muted-border-color);
577}
578
579.comment-settings-fields small {
580 display: block;
581 margin: -0.5rem 0 0.75rem;
582 color: var(--pico-muted-color);
583}
584
585.heatmap-figure {
586 margin: 0;
587}
588
589.heatmap {
590 height: 7rem;
591 display: flex;
592 align-items: flex-end;
593 gap: 0;
594 padding: 0.5rem 0;
595 border-bottom: 1px solid var(--pico-muted-border-color);
596}
597
598.heatmap-bar {
599 flex: 0 0 auto;
600 min-width: 0;
601 background: var(--pico-primary);
602 opacity: 0.8;
603 border-radius: 2px 2px 0 0;
604}
605
606.heatmap-figure figcaption {
607 display: flex;
608 justify-content: space-between;
609 color: var(--pico-muted-color);
610 font-size: 0.8rem;
611}
612
613.comment-list {
614 display: flex;
615 flex-direction: column;
616 gap: 0.75rem;
617}
618
619.comment {
620 margin: 0;
621 padding: 0.85rem 1rem;
622 border: 1px solid var(--pico-card-border-color);
623 border-radius: var(--pico-border-radius);
624 background: var(--pico-card-background-color);
625}
626
627.comment-depth-1 {
628 margin-left: 1.25rem;
629}
630
631.comment-depth-2 {
632 margin-left: 2.5rem;
633}
634
635.comment-depth-3 {
636 margin-left: 3.75rem;
637}
638
639.comment-depth-4 {
640 margin-left: 5rem;
641}
642
643.comment header {
644 display: flex;
645 align-items: center;
646 gap: 0.5rem;
647 flex-wrap: wrap;
648}
649
650.comment time {
651 color: var(--pico-muted-color);
652 font-size: 0.85rem;
653 margin-left: auto;
654}
655
656.comment-reply-to {
657 display: block;
658 margin-top: 0.35rem;
659 color: var(--pico-muted-color);
660}
661
662.comment p {
663 white-space: pre-wrap;
664 overflow-wrap: anywhere;
665 margin: 0.5rem 0 0.25rem;
666}
667
668.comment small,
669.muted {
670 color: var(--pico-muted-color);
671}
672
673/* Queue */
674.queue-list {
675 display: flex;
676 flex-direction: column;
677 gap: 1rem;
678}
679
680.queue-item {
681 padding: 1rem;
682 margin-bottom: 0;
683 position: relative;
684 transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
685}
686
687/* Stretched link: the whole row navigates to the detail page, matching the
688 library card hover. Interactive children (Remove) sit above it via z-index. */
689.queue-link {
690 position: absolute;
691 inset: 0;
692 z-index: 1;
693}
694
695.queue-item:hover {
696 background-color: var(--pico-primary-background);
697 border-color: var(--pico-primary-border);
698 box-shadow: var(--pico-card-box-shadow), 0 4px 12px rgba(0, 0, 0, 0.15);
699 cursor: pointer;
700}
701
702/* Keep text legible on the solid primary hover background (status badges and
703 the error message keep their own colors). */
704.queue-item:hover .queue-url,
705.queue-item:hover .queue-meta {
706 color: var(--pico-primary-inverse);
707}
708
709.queue-header {
710 display: flex;
711 justify-content: space-between;
712 align-items: flex-start;
713 gap: 1rem;
714 flex-wrap: wrap;
715 margin-bottom: 0.5rem;
716}
717
718.queue-url {
719 flex: 1;
720 min-width: 0;
721 word-break: break-all;
722}
723
724.queue-status {
725 display: flex;
726 gap: 0.5rem;
727 align-items: center;
728 flex-wrap: wrap;
729}
730
731/* Keep the Remove action clickable above the stretched link overlay. */
732.queue-action {
733 position: relative;
734 z-index: 2;
735}
736
737.status-badge {
738 padding: 0.2rem 0.6rem;
739 border-radius: 12px;
740 font-size: 0.85rem;
741 font-weight: 500;
742}
743
744.status-badge.queued {
745 background: var(--pico-card-sectioning-background-color);
746 color: var(--pico-muted-color);
747}
748
749.status-badge.downloading {
750 background: var(--pico-primary);
751 color: var(--pico-primary-inverse);
752}
753
754.status-badge.completed {
755 background: var(--pico-ins-color);
756 color: white;
757}
758
759.status-badge.error {
760 background: var(--pico-del-color);
761 color: white;
762}
763
764.status-badge.cancelled {
765 background: var(--pico-muted-color);
766 color: var(--pico-background-color);
767}
768
769.error-message {
770 color: var(--pico-del-color);
771 font-size: 0.9rem;
772 margin-top: 0.5rem;
773}
774
775.error-text {
776 color: var(--pico-del-color);
777}
778
779.queue-meta {
780 margin-top: 0.5rem;
781 font-size: 0.85rem;
782 display: flex;
783 gap: 1rem;
784}
785
786/* Logs */
787.logs {
788 max-height: 500px;
789 overflow-y: auto;
790 white-space: pre-wrap;
791 word-break: break-all;
792}
793
794pre {
795 padding: 1.5rem;
796}
797
798/* Settings */
799.settings-layout {
800 display: flex;
801 flex-direction: column;
802 gap: 2rem;
803}
804
805.presets-list {
806 display: flex;
807 flex-direction: column;
808 gap: 1rem;
809 margin-bottom: 1.5rem;
810}
811
812.preset-header {
813 display: flex;
814 justify-content: space-between;
815 align-items: center;
816 margin-bottom: 0.5rem;
817}
818
819.preset-header h4 {
820 display: flex;
821 align-items: center;
822 gap: 0.5rem;
823 margin: 0;
824}
825
826.badge {
827 background: var(--pico-primary);
828 color: var(--pico-primary-inverse);
829 padding: 0.1rem 0.4rem;
830 border-radius: 10px;
831 font-size: 0.75rem;
832}
833
834.preset-actions {
835 display: flex;
836 gap: 0.5rem;
837 flex-wrap: wrap;
838 margin-top: 1rem;
839}
840
841.preset-actions > details {
842 flex: 1 1 100%;
843 min-width: 0;
844}
845
846.preset-description {
847 margin-bottom: 0.5rem;
848}
849
850.preset-flags {
851 margin-top: 0.5rem;
852}
853
854.preset-flags pre {
855 overflow-x: auto;
856 margin-top: 0.3rem;
857 margin-bottom: 0;
858}
859
860/* Nested articles need visible borders */
861.presets-list article {
862 border: 1px solid var(--pico-muted-border-color);
863}
864
865/* Suppress Pico details marker for button-like summaries */
866details:has(summary[role="button"]) summary::after {
867 display: none !important;
868}
869
870details summary[role="button"] {
871 display: inline-flex;
872 width: auto;
873}
874
875/* Toggle text: Edit vs Cancel */
876details .cancel-text {
877 display: none;
878}
879
880details[open] .edit-text {
881 display: none;
882}
883
884details[open] .cancel-text {
885 display: inline;
886}
887
888/* Delete overlay popover */
889.delete-overlay {
890 position: relative;
891}
892
893.delete-overlay summary {
894 list-style: none;
895 cursor: pointer;
896}
897
898.delete-overlay summary::-webkit-details-marker {
899 display: none;
900}
901
902.delete-overlay summary::after {
903 display: none !important;
904}
905
906.delete-overlay .overlay-panel {
907 position: absolute;
908 top: calc(100% + 0.5rem);
909 right: 0;
910 z-index: 1000;
911 width: 260px;
912 background: var(--pico-background-color);
913 border: 1px solid var(--pico-muted-border-color);
914 border-radius: var(--pico-border-radius);
915 padding: 1rem;
916 box-shadow: var(--pico-dropdown-box-shadow);
917}
918
919/* Popover arrow */
920.delete-overlay .overlay-panel::before {
921 content: '';
922 position: absolute;
923 top: -6px;
924 right: 1rem;
925 width: 10px;
926 height: 10px;
927 background: var(--pico-background-color);
928 border-left: 1px solid var(--pico-muted-border-color);
929 border-top: 1px solid var(--pico-muted-border-color);
930 transform: rotate(45deg);
931}
932
933.delete-overlay .overlay-panel p {
934 margin-bottom: 1rem;
935 font-size: 0.9rem;
936}
937
938.delete-overlay .overlay-panel .form-actions {
939 margin-top: 0;
940 justify-content: flex-end;
941}
942
943/* Inline edit form */
944.edit-form {
945 width: 100%;
946 box-sizing: border-box;
947 padding: 1rem;
948}
949
950/* Conditional sections (no-JS show/hide) */
951.conditional-section {
952 margin-bottom: 1rem;
953}
954
955.conditional-section .conditional-content {
956 display: none;
957 margin-top: 1rem;
958}
959
960/* Checkbox triggers */
961.conditional-section:has(input[type="checkbox"].conditional-trigger:checked) .conditional-content {
962 display: block;
963}
964
965/* Radio triggers for format mode */
966.conditional-section:has(.radio-group input[value="preset"]:checked) .conditional-content.format-preset,
967.conditional-section:has(.radio-group input[value="custom"]:checked) .conditional-content.format-custom {
968 display: block;
969}
970
971/* Subscriptions: lock the cron field unless the schedule is "Custom (cron)".
972 Pure CSS — the :has() reacts live as the <select> changes, no JS needed. */
973input[name="cron_expr"] {
974 opacity: 0.5;
975 pointer-events: none;
976}
977.form-row:has(select[name="schedule_kind"] option[value="cron"]:checked) input[name="cron_expr"] {
978 opacity: 1;
979 pointer-events: auto;
980}
981
982/* Format mode selector - hidden radio inputs with button-like labels */
983.radio-group.format-mode {
984 display: flex;
985 gap: 0.5rem;
986 margin-top: 0.5rem;
987 flex-wrap: wrap;
988}
989
990.radio-group.format-mode input[type="radio"] {
991 position: absolute;
992 opacity: 0;
993 width: 0;
994 height: 0;
995}
996
997.radio-group.format-mode label {
998 padding: 0.4rem 0.8rem;
999 border: 1px solid var(--pico-muted-border-color);
1000 border-radius: var(--pico-border-radius);
1001 cursor: pointer;
1002 background: var(--pico-background-color);
1003 transition: all 0.2s;
1004 font-weight: normal;
1005}
1006
1007.radio-group.format-mode label:hover {
1008 background: var(--pico-card-sectioning-background-color);
1009}
1010
1011.radio-group.format-mode label:has(input:checked) {
1012 background: var(--pico-primary);
1013 color: var(--pico-primary-inverse);
1014 border-color: var(--pico-primary);
1015}
1016
1017/* Inline informational note paragraph */
1018.note {
1019 font-size: 0.85rem;
1020 color: var(--pico-muted-color);
1021}
1022
1023/* Collapsible "managed yt-dlp options" notes component */
1024.ytdlp-notes {
1025 margin: 0 0 1rem;
1026 border: 1px solid var(--pico-muted-border-color);
1027 border-radius: var(--pico-border-radius);
1028 background: var(--pico-card-sectioning-background-color);
1029 overflow: hidden;
1030}
1031
1032.ytdlp-notes > summary {
1033 cursor: pointer;
1034 padding: 0.6rem 0.9rem;
1035 font-size: 0.9rem;
1036 font-weight: 600;
1037 color: var(--pico-color);
1038 user-select: none;
1039 transition: background 0.15s ease-in-out;
1040}
1041
1042.ytdlp-notes > summary:hover {
1043 background: var(--pico-card-background-color);
1044}
1045
1046.ytdlp-notes-icon {
1047 color: var(--pico-primary);
1048 font-style: normal;
1049 font-size: 1rem;
1050 margin-right: 0.4rem;
1051}
1052
1053.ytdlp-notes-body {
1054 padding: 0 0.9rem 0.6rem;
1055 border-top: 1px solid var(--pico-muted-border-color);
1056}
1057
1058.ytdlp-notes-body > p {
1059 font-size: 0.85rem;
1060 color: var(--pico-muted-color);
1061 margin: 0.7rem 0;
1062}
1063
1064.ytdlp-notes-table-wrap {
1065 overflow-x: auto;
1066}
1067
1068.ytdlp-notes-body table {
1069 margin: 0;
1070 font-size: 0.85rem;
1071}
1072
1073.ytdlp-notes-body th,
1074.ytdlp-notes-body td {
1075 padding: 0.4rem 0.6rem;
1076 vertical-align: top;
1077}
1078
1079.ytdlp-notes-body td:first-child {
1080 white-space: nowrap;
1081}
1082
1083.ytdlp-notes-body code {
1084 font-size: 0.8rem;
1085}
1086
1087/* Theme selector */
1088.theme-selector {
1089 display: flex;
1090 gap: 0.5rem;
1091}
1092
1093.theme-selector button {
1094 min-width: 80px;
1095}
1096
1097.theme-selector button.active {
1098 background: var(--pico-primary);
1099 color: var(--pico-primary-inverse);
1100 border-color: var(--pico-primary);
1101}
1102
1103/* Download form */
1104.download-form {
1105 max-width: 900px;
1106}
1107
1108.download-form form {
1109 max-width: 800px;
1110}
1111
1112/* Filter form inline */
1113.filter-form {
1114 display: flex;
1115 gap: 0.5rem;
1116 align-items: center;
1117}
1118
1119.filter-form input,
1120.filter-form select,
1121.filter-form button {
1122 margin-bottom: 0;
1123 width: auto;
1124 display: inline-block;
1125 flex-shrink: 0;
1126}
1127
1128.filter-form input[type="text"] {
1129 min-width: 200px;
1130}
1131
1132/* Empty state */
1133.empty-state {
1134 text-align: center;
1135 padding: 3rem;
1136}
1137
1138/* Login */
1139.login-page {
1140 max-width: 24rem;
1141 margin: 0 auto;
1142}
1143
1144/* The login page is one narrow column, so the flash above the form is kept to
1145 the same width instead of spanning the whole page. */
1146.login-main {
1147 display: flex;
1148 flex-direction: column;
1149 justify-content: center;
1150}
1151
1152.login-main > * {
1153 max-width: 24rem;
1154 width: 100%;
1155}
1156
1157/* Pagination */
1158.pagination {
1159 display: flex;
1160 align-items: center;
1161 justify-content: space-between;
1162 gap: 1rem;
1163 margin: 1.5rem 0;
1164}
1165
1166/* Utility */
1167.inline {
1168 display: inline;
1169}
1170
1171/* Responsive */
1172@media (max-width: 768px) {
1173 main {
1174 padding: 1rem;
1175 }
1176
1177 .page-header {
1178 flex-direction: column;
1179 align-items: flex-start;
1180 }
1181
1182 .library-grid {
1183 grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
1184 }
1185
1186 .form-row {
1187 grid-template-columns: 1fr;
1188 }
1189
1190 .detail-meta dl {
1191 grid-template-columns: 1fr;
1192 gap: 0;
1193 }
1194
1195 /* Stacked layout: tighten key→value and space out each pair so the grouping
1196 is obvious without the column alignment to lean on. */
1197 .detail-meta dt {
1198 margin-top: 0.85rem;
1199 }
1200
1201 .detail-meta dt:first-child {
1202 margin-top: 0;
1203 }
1204
1205 .detail-meta dd {
1206 margin-top: 0.15rem;
1207 }
1208
1209 .queue-header {
1210 flex-direction: column;
1211 }
1212
1213 body > header {
1214 flex-direction: column;
1215 gap: 1rem;
1216 padding: 1rem;
1217 }
1218
1219 nav {
1220 width: 100%;
1221 justify-content: center;
1222 }
1223}
1224