WebUI: Use event delegation to handle common table events
[qBittorrent.git] / src / webui / www / private / css / style.css
blob116f4948acdc703e560548c13496d5e07bbec8e9
1 /* Adaptive color palette */
3 /* Default rules */
4 :root {
5 --color-accent-blue: hsl(210deg 65% 55%);
6 --color-text-blue: hsl(210deg 100% 55%);
7 --color-text-orange: hsl(26deg 100% 45%);
8 --color-text-red: hsl(0deg 100% 65%);
9 --color-text-green: hsl(110deg 94% 27%);
10 --color-text-white: hsl(0deg 0% 100%);
11 --color-text-disabled: hsl(0deg 0% 60%);
12 --color-text-default: hsl(0deg 0% 33%);
13 --color-background-blue: hsl(210deg 65% 55%);
14 --color-background-popup: hsl(0deg 0% 100%);
15 --color-background-default: hsl(0deg 0% 94%);
16 --color-background-hover: hsl(26deg 80% 60%);
17 --color-border-blue: hsl(210deg 42% 48%);
18 --color-border-default: hsl(0deg 0% 85%);
19 --color-icon-hover: brightness(0) invert(100%) sepia(100%) saturate(0%)
20 hue-rotate(108deg) brightness(104%) contrast(104%);
22 &:not(.dark) {
23 color-scheme: light;
26 &.dark {
27 --color-accent-blue: hsl(210deg 42% 48%);
28 --color-text-blue: hsl(210deg 88.1% 73.5%);
29 --color-text-orange: hsl(26deg 65% 70%);
30 --color-text-default: hsl(0deg 0% 90%);
31 --color-background-blue: hsl(210deg 42% 48%);
32 --color-background-popup: hsl(0deg 0% 20%);
33 --color-background-default: hsl(0deg 0% 25%);
34 --color-background-hover: hsl(26deg 50% 55%);
35 --color-border-default: hsl(0deg 0% 33%);
37 color-scheme: dark;
39 #rssButtonBar img,
40 #startSearchButton img,
41 #manageSearchPlugins img {
42 filter: brightness(0) saturate(100%) invert(100%) sepia(0%)
43 saturate(1%) hue-rotate(156deg) brightness(106%) contrast(101%);
48 /* Reset */
51 *::before,
52 *::after {
53 box-sizing: border-box;
56 * {
57 margin: 0;
60 input,
61 button,
62 textarea,
63 select {
64 font: inherit;
67 a img,
68 :link img,
69 :visited img {
70 border: none;
73 ul,
74 ol {
75 list-style: none;
78 /* Scrollbars */
80 @supports (scrollbar-width: auto) and (selector(::-webkit-scrollbar)) {
81 :root[slick-uniqueid], /* targets iframe mocha dialogs */
82 .dynamicTableDiv,
83 .mochaContentWrapper,
84 .panel,
85 #rssDetailsView {
86 scrollbar-width: thin;
90 /* Forms */
92 input[type="text"],
93 input[type="number"],
94 input[type="password"],
95 input[type="button"],
96 button,
97 select {
98 border: 1px solid var(--color-border-default);
99 border-radius: 3px;
100 color: var(--color-text-default);
101 padding: 3px;
104 select {
105 padding: 4px;
108 input[type="checkbox"],
109 input[type="radio"] {
110 accent-color: var(--color-accent-blue);
111 margin: 3px 3px 3px 4px;
114 input[type="button"],
115 input[type="submit"],
116 button {
117 cursor: pointer;
118 padding-left: 10px;
119 padding-right: 10px;
122 button:disabled {
123 cursor: initial;
126 :focus {
127 outline: none;
130 /* Structure */
132 body {
133 color: var(--color-text-default);
134 font-family: Arial, Helvetica, sans-serif;
135 font-size: 12px;
136 line-height: 1.5;
137 text-align: left;
140 .aside {
141 width: 300px;
144 .invisible {
145 display: none;
148 /* Typography */
152 h4 {
153 font-size: 12px;
154 font-weight: bold;
155 padding: 0 0 5px;
158 h2 {
159 color: var(--color-text-default);
160 font-size: 14px;
161 font-weight: bold;
164 #mochaPage h3 {
165 border-bottom: 1px solid var(--color-border-default);
166 display: block;
167 font-size: 12px;
168 margin: 0 0 8px;
169 padding: 6px 0;
172 #error_div,
173 #rename_error {
174 color: var(--color-text-red);
175 float: left;
176 font-size: 14px;
177 font-weight: bold;
180 h4 {
181 font-size: 11px;
185 color: var(--color-text-orange);
186 cursor: pointer;
187 text-decoration: none;
190 a:hover {
191 text-decoration: none;
195 padding: 0 0 9px;
198 /* List Elements */
200 dt {
201 font-weight: bold;
204 dd {
205 padding: 0 0 9px;
208 /* Forms */
210 fieldset {
211 border: 1px solid var(--color-border-default);
212 border-radius: 1px;
213 margin: 0 2px;
216 /* Code */
218 pre {
219 background-color: var(--color-background-default);
220 border: 1px solid var(--color-border-default);
221 color: var(--color-text-green);
222 display: block;
223 font-family: "Courier New", Courier, monospace;
224 font-size: 11px;
225 margin: 0 0 10px;
226 max-height: 250px;
227 overflow: auto;
228 padding: 10px;
231 /* Dividers */
233 hr {
234 background-color: var(--color-background-default);
235 border: 0px;
236 color: var(--color-text-default);
237 height: 1px;
238 margin-bottom: 6px;
241 .vcenter {
242 vertical-align: middle;
245 #urls {
246 height: 100%;
247 width: 90%;
250 #trackersUrls {
251 display: block;
252 height: 100%;
253 margin: 0 auto 10px;
254 width: 90%;
257 #Filters {
258 overflow-x: hidden !important; /* override for default mocha inline style */
261 #Filters ul img {
262 height: 16px;
263 width: 16px;
266 #properties {
267 background-color: var(--color-background-default);
270 a.propButton {
271 border: 1px solid rgb(85 81 91);
272 margin-left: 3px;
273 margin-right: 3px;
274 padding: 2px;
277 a.propButton img {
278 margin-bottom: -4px;
281 .scrollableMenu {
282 overflow: hidden auto;
285 .propertiesTabContent {
286 height: 100%;
288 > div {
289 height: 100%;
293 /* context menu specific */
295 .contextMenu {
296 background-color: var(--color-background-default);
297 border: 1px solid var(--color-border-default);
298 display: none;
299 padding: 0;
302 .contextMenu .separator {
303 border-top: 1px solid var(--color-border-default);
306 .contextMenu .separatorBottom {
307 border-bottom: 1px solid var(--color-border-default);
310 .contextMenu li {
311 padding: 0;
312 user-select: none;
315 .contextMenu li.disabled {
316 background-color: transparent;
317 cursor: default;
318 opacity: 0.5;
321 .contextMenu li.disabled a {
322 pointer-events: none;
325 .contextMenu li a {
326 align-items: center;
327 color: var(--color-text-default);
328 display: flex;
329 gap: 2px;
330 padding: 5px 20px 5px 5px;
331 text-decoration: none;
332 white-space: nowrap;
335 .contextMenu li a:hover {
336 background-color: var(--color-background-hover);
337 color: var(--color-text-white);
340 .contextMenu li a:hover img:not(.highlightedCategoryIcon) {
341 filter: var(--color-icon-hover);
344 .contextMenu li ul {
345 background: var(--color-background-default);
346 border: 1px solid var(--color-border-default);
347 left: -999em;
348 margin: -29px 0 0 100%;
349 padding: 0;
350 position: absolute;
351 width: max-content;
352 z-index: 8000;
355 .contextMenu li ul li a {
356 position: relative;
359 .contextMenu li:not(.disabled) .arrow-right {
360 background-image: url("../images/arrow-right.gif");
361 background-position: right center;
362 background-repeat: no-repeat;
365 .contextMenu li:not(.disabled):hover > ul {
366 /* lists nested under hovered list items */
367 left: auto;
370 .contextMenu li img {
371 height: 16px;
372 margin-right: 0.5em;
373 width: 16px;
376 .contextMenu li input[type="checkbox"] {
377 margin: 0 0.5em 0 0;
378 width: 16px;
381 #contextCategoryList img {
382 border: 1px solid transparent;
383 box-sizing: content-box;
384 padding: 1px;
387 #contextCategoryList img.highlightedCategoryIcon {
388 background-color: hsl(213deg 94% 86%);
391 /* Sliders */
393 .slider {
394 clear: both;
395 font-size: 12px;
396 font-weight: bold;
397 margin-bottom: 15px;
398 position: relative;
399 width: 400px;
402 .sliderWrapper {
403 font-size: 1px;
404 height: 9px;
405 line-height: 1px;
406 position: relative;
407 width: 422px;
410 .sliderarea {
411 background: #f2f2f2 url("../images/slider-area.gif") repeat-x;
412 border: 1px solid #a3a3a3;
413 border-bottom: 1px solid #ccc;
414 border-left: 1px solid #ccc;
415 font-size: 1px;
416 height: 7px;
417 left: 0;
418 line-height: 1px;
419 overflow: hidden;
420 padding: 0;
421 position: absolute;
422 top: 0;
423 width: 420px;
426 .sliderknob {
427 background: url("../images/knob.gif") no-repeat;
428 cursor: pointer;
429 font-size: 1px;
430 height: 9px;
431 left: 0;
432 line-height: 1px;
433 overflow: hidden;
434 position: absolute;
435 top: 0;
436 width: 19px;
437 z-index: 2;
440 .update {
441 padding-bottom: 5px;
444 .mochaToolButton {
445 margin-right: 10px;
448 /* Mocha Customization */
450 #mochaToolbar {
451 height: auto !important;
452 margin-top: 5px;
453 overflow-y: hidden;
454 position: relative;
457 #mochaToolbar .divider {
458 background-image: url("../images/toolbox-divider.gif");
459 background-position: left center;
460 background-repeat: no-repeat;
461 padding-left: 14px;
462 padding-top: 15px;
465 .MyMenuIcon {
466 margin: 0 6px -3px -18px;
469 #mainWindowTabs {
470 float: right;
471 margin: 4px 5px 0 0;
474 #torrentsFilterToolbar {
475 display: inline-block;
476 vertical-align: top;
479 #torrentsFilterInput {
480 background-color: var(--color-background-default);
481 background-image: url("../images/edit-find.svg");
482 background-position: left;
483 background-repeat: no-repeat;
484 background-size: 1.5em;
485 border: 1px solid var(--color-border-default);
486 border-radius: 3px;
487 min-width: 160px;
488 padding: 2px 12px 2px 25px;
491 #torrentsFilterRegexBox {
492 display: none;
495 #torrentsFilterRegexBox + label {
496 background-image: url("../images/regex.svg");
497 background-position: center;
498 background-repeat: no-repeat;
499 background-size: 1.5em;
500 border: 1px solid var(--color-border-default);
501 border-radius: 4px;
502 cursor: pointer;
503 display: inline-block;
504 height: 26px;
505 margin-bottom: -9px;
506 width: 26px;
509 #torrentsFilterRegexBox:checked + label {
510 background-color: var(--color-background-default);
511 background-image: url("../images/regex.svg");
512 background-position: center;
513 background-repeat: no-repeat;
514 background-size: 1.5em;
515 border: 1px solid var(--color-accent-blue);
516 border-radius: 4px;
517 display: inline-block;
518 height: 26px;
519 margin-bottom: -9px;
520 width: 26px;
523 #torrentsFilterSelect {
524 padding: 2px 4px;
527 #torrentFilesFilterToolbar {
528 float: right;
529 margin-right: 5px;
532 #torrentFilesFilterInput {
533 background-image: url("../images/edit-find.svg");
534 background-position: left;
535 background-repeat: no-repeat;
536 background-size: 1.5em;
537 margin-top: -1px;
538 padding-bottom: 1px;
539 padding-left: 2em;
540 padding-top: 1px;
541 width: 190px;
544 /* Tri-state checkbox */
546 label.tristate {
547 background: url("../images/3-state-checkbox.gif") 0 0 no-repeat;
548 display: block;
549 float: left;
550 height: 13px;
551 margin: 0.15em 8px 5px 0px;
552 overflow: hidden;
553 text-indent: -999em;
554 width: 13px;
557 label.checked {
558 background-position: 0 -13px;
561 label.partial {
562 background-position: 0 -26px;
565 fieldset.settings {
566 border: 1px solid var(--color-border-default);
567 padding: 4px 4px 6px 6px;
570 fieldset.settings legend {
571 font-weight: bold;
572 margin-left: 8px;
573 padding: 4px;
576 fieldset.settings label {
577 padding: 2px;
580 fieldset.settings + div.formRow {
581 margin-top: 10px;
584 div.formRow {
585 clear: left;
586 display: block;
589 .filterTitle {
590 cursor: pointer;
591 display: flex;
592 font-weight: bold;
593 gap: 4px;
594 overflow: hidden;
595 padding: 4px 0 4px 6px;
596 text-overflow: ellipsis;
597 text-transform: uppercase;
598 user-select: none;
599 white-space: nowrap;
602 .filterTitle img {
603 height: 16px;
604 padding: 2px;
605 width: 16px;
608 .collapsedCategory > ul {
609 display: none;
612 .collapsedCategory .categoryToggle,
613 .filterTitle img.rotate {
614 transform: rotate(-90deg);
617 ul.filterList {
618 margin: 0;
619 padding-left: 0;
622 ul.filterList span.link:hover :is(img, button),
623 ul.filterList .selectedFilter > .link :is(img, button) {
624 filter: var(--color-icon-hover);
627 ul.filterList span.link {
628 align-items: center;
629 cursor: pointer;
630 display: flex;
631 gap: 5px;
632 overflow: hidden;
633 padding: 4px 6px;
634 white-space: nowrap;
637 ul.filterList span.link:hover {
638 background-color: var(--color-background-hover);
639 color: var(--color-text-white);
642 span.link :last-child {
643 min-width: 0;
644 overflow: hidden;
645 text-overflow: ellipsis;
646 white-space: nowrap;
649 span.link :is(img, button) {
650 flex-shrink: 0;
653 .selectedFilter > span.link {
654 background-color: var(--color-background-blue);
655 color: var(--color-text-white);
658 .subcategories,
659 .subcategories ul {
660 margin: 0;
661 padding: 0;
664 .subcategories .categoryToggle {
665 display: inline-block;
666 visibility: hidden;
669 .categoryToggle {
670 background: url("../images/go-down.svg") center center / 10px no-repeat
671 transparent;
672 border: none;
673 display: none;
674 height: 16px;
675 margin-right: -2px;
676 padding: 2px;
677 transition: transform 0.3s;
678 width: 16px;
681 td.generalLabel {
682 text-align: right;
683 vertical-align: top;
684 white-space: nowrap;
685 width: 1px;
688 #tristate_cb {
689 margin-bottom: 0;
690 margin-top: 0;
693 .filesTableCollapseIcon {
694 cursor: pointer;
695 height: 15px;
696 margin-bottom: -3px;
697 padding-right: 5px;
698 width: 15px;
701 .filesTableCollapseIcon.rotate {
702 margin-bottom: -1px;
703 transform: rotate(270deg);
706 .unselectable {
707 -webkit-touch-callout: none;
708 user-select: none;
711 #propGeneral {
712 padding: 2px;
715 #propProgressWrapper {
716 align-items: center;
717 display: flex;
718 height: auto;
719 margin: 5px 2px;
721 & > span:not(:first-child, :empty) {
722 margin-left: 6px;
723 min-width: 3.5em;
726 & #progress {
727 flex: 1;
731 .piecesbarWrapper {
732 position: relative;
733 width: 100%;
736 .piecesbarCanvas {
737 height: 100%;
738 image-rendering: pixelated;
739 inset: 0;
740 position: absolute;
741 width: 100%;
744 #watched_folders_tab {
745 border-collapse: collapse;
748 #watched_folders_tab td,
749 #watched_folders_tab th {
750 border: 1px solid black;
751 padding: 2px 4px;
754 .select-watched-folder-editable {
755 border: 1px solid var(--color-border-default);
756 height: 22px;
757 position: relative;
758 width: 160px;
761 .select-watched-folder-editable select {
762 border: none;
763 bottom: 0px;
764 left: 0px;
765 padding: 0;
766 position: absolute;
767 top: 0px;
768 width: 158px;
771 .select-watched-folder-editable input {
772 border: none;
773 left: 0px;
774 padding: 0;
775 position: absolute;
776 top: 0px;
777 width: 140px;
780 .select-watched-folder-editable select:focus,
781 .select-editable input:focus {
782 outline: none;
786 * Workaround to prevent the transfer list from
787 * disappearing when zooming in the browser.
789 #filtersColumn_handle {
790 margin-left: -1px;
793 .combo_priority {
794 font-size: 1em;
795 padding: 2px 6px;
798 td.statusBarSeparator {
799 background-image: url("../images/toolbox-divider.gif");
800 background-position: center 1px;
801 background-repeat: no-repeat;
802 background-size: 2px 18px;
803 width: 24px;
806 /* Statistics window */
807 #statisticsContent {
808 & table {
809 background-color: var(--color-background-default);
810 border-radius: 6px;
811 margin-bottom: 6px;
812 padding: 6px 10px;
814 & .statisticsValue {
815 text-align: right;
819 & h3 {
820 color: var(--color-text-default);
821 margin-bottom: 1px;
822 padding: 2px;
826 /* Search tab */
828 #SearchPanel,
829 #SearchPanel_wrapper,
830 #SearchPanel_pad {
831 height: inherit;
834 #searchResults {
835 height: 100%;
836 padding: 0 20px;
839 #searchResultsTableContainer {
840 height: calc(100% - 177px);
841 overflow: auto;
844 #searchResultsTableDiv {
845 height: calc(100% - 26px) !important;
848 #searchResults .dynamicTable {
849 width: 100%;
852 #searchResults .numSearchResults {
853 font-style: italic;
856 .red {
857 color: var(--color-text-red);
860 .green {
861 color: var(--color-text-green);
864 #torrentFilesTableDiv .dynamicTable tr.nonAlt:hover {
865 background-color: var(--color-background-hover);
866 color: var(--color-text-white);
869 /* Modals */
870 .modalDialog .mochaContent.pad {
871 display: flex !important; /* override for default mocha inline style */
872 flex-direction: column;
873 height: 100%;
876 .modalDialog .mochaContent.pad > :last-child {
877 align-self: flex-end;
880 .modalDialog .mochaContent.pad > :first-child {
881 margin: auto 0;
884 #rememberBtn {
885 background: url("../images/object-locked.svg") center center / 24px
886 no-repeat var(--color-background-popup);
887 height: 38px;
888 padding: 4px 6px;
889 width: 38px;
892 #rememberBtn.disabled {
893 filter: grayscale(100%);
896 #deleteFromDiskCB {
897 margin: 0 2px 0 0;
898 vertical-align: -1px;
901 .dialogMessage {
902 overflow-wrap: anywhere;
905 .genericConfirmGrid,
906 .confirmDeletionGrid {
907 align-items: center;
908 display: grid;
909 gap: 3px 4px;
910 grid-template-columns: max-content 1fr;
911 margin-bottom: 10px;
914 .confirmGridItem,
915 .deletionGridItem {
916 padding: 3px;
919 .deletionGridItem:first-child {
920 justify-self: center;
923 .confirmWarning,
924 .confirmDialogWarning {
925 background: url("../images/dialog-warning.svg") center center no-repeat;
926 height: 38px;
927 width: 38px;
930 .confirmWarning {
931 background-image: url("../images/help-about.svg");