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