1/*
2 * SPDX-FileCopyrightText: Amolith <amolith@secluded.site>
3 *
4 * SPDX-License-Identifier: AGPL-3.0-or-later
5 */
6
7:root {
8 color-scheme: light dark;
9}
10
11* {
12 box-sizing: border-box;
13 margin: 0;
14 padding: 0;
15}
16
17body {
18 font-family: "Atkinson Hyperlegible Next", system-ui, -apple-system, Segoe UI, Roboto, Ubuntu, Cantarell, Noto Sans, sans-serif;
19 background: var(--background-1);
20 color: var(--text-1);
21 line-height: 1.6;
22 -webkit-font-smoothing: antialiased;
23 -moz-osx-font-smoothing: grayscale;
24}
25
26#app {
27 max-width: 800px;
28 margin: 0 auto;
29 padding: 2rem 1rem;
30}
31
32.hidden {
33 display: none !important;
34}
35
36/* Noscript message */
37.noscript-message {
38 max-width: 600px;
39 margin: 4rem auto;
40 padding: 2rem;
41 text-align: center;
42 background: var(--surface-2);
43 border: 2px solid var(--brand-color);
44 border-radius: 8px;
45}
46
47.noscript-message h1 {
48 color: var(--avocado-11);
49 margin-bottom: 1.5rem;
50}
51
52.noscript-message p {
53 margin-bottom: 1rem;
54 line-height: 1.7;
55}
56
57.noscript-message p:last-child {
58 margin-bottom: 0;
59 color: var(--text-2);
60 font-size: 0.9rem;
61}
62
63/* Start screen */
64#start-screen {
65 text-align: center;
66 padding: 4rem 2rem;
67}
68
69#start-screen h1 {
70 margin-bottom: 3rem;
71 color: var(--avocado-11);
72}
73
74.buttons {
75 display: flex;
76 flex-direction: column;
77 gap: 1rem;
78 align-items: center;
79}
80
81.join-section {
82 display: flex;
83 gap: 0.5rem;
84}
85
86button {
87 padding: 0.75rem 1.5rem;
88 background: var(--brand-color);
89 color: var(--stone-1);
90 border: none;
91 border-radius: 8px;
92 cursor: pointer;
93 font-size: 1rem;
94 position: relative;
95 --btn-color: var(--brand-color);
96 transform: translateY(0);
97 box-shadow:
98 0 6px 0 color-mix(in oklch, var(--btn-color) 60%, black),
99 0 12px 18px color-mix(in oklch, var(--stone-16) 30%, transparent),
100 inset 0 1px 0 color-mix(in oklch, white 20%, transparent);
101 transition:
102 transform 140ms cubic-bezier(0.2, 0.7, 0.1, 1),
103 box-shadow 140ms cubic-bezier(0.2, 0.7, 0.1, 1),
104 background 140ms ease;
105}
106
107button:hover {
108 box-shadow:
109 0 7px 0 color-mix(in oklch, var(--btn-color) 60%, black),
110 0 14px 20px color-mix(in oklch, var(--stone-16) 35%, transparent),
111 inset 0 1px 0 color-mix(in oklch, white 25%, transparent);
112}
113
114button:active {
115 transform: translateY(4px);
116 box-shadow:
117 0 2px 0 color-mix(in oklch, var(--btn-color) 60%, black),
118 0 6px 12px color-mix(in oklch, var(--stone-16) 25%, transparent),
119 inset 0 -1px 0 color-mix(in oklch, var(--btn-color) 50%, black);
120}
121
122button.press-lock {
123 transform: translateY(4px);
124 box-shadow:
125 0 2px 0 color-mix(in oklch, var(--btn-color) 60%, black),
126 0 6px 12px color-mix(in oklch, var(--stone-16) 25%, transparent),
127 inset 0 -1px 0 color-mix(in oklch, var(--btn-color) 50%, black);
128}
129
130button:focus-visible,
131input:focus-visible,
132textarea:focus-visible {
133 outline: 2px solid var(--avocado-7);
134 outline-offset: 2px;
135}
136
137input,
138textarea {
139 padding: 0.75rem;
140 border: 1px solid var(--stone-5);
141 border-radius: 6px;
142 font-size: 1rem;
143 font-family: inherit;
144 background: var(--stone-1);
145 color: var(--text-1);
146}
147
148input::placeholder,
149textarea::placeholder {
150 color: color-mix(in oklch, var(--text-1) 50%, transparent);
151}
152
153#join-code {
154 width: 200px;
155 text-transform: uppercase;
156 letter-spacing: 0.08em;
157}
158
159#join-code::placeholder {
160 text-transform: none;
161}
162
163.expiry-notice {
164 font-size: 0.85rem;
165 color: color-mix(in oklch, var(--text-1) 60%, transparent);
166 margin-top: 1rem;
167}
168
169#start-screen .expiry-notice {
170 text-align: center;
171}
172
173#list-screen .expiry-notice {
174 margin: 0.5rem 0 0 0;
175 font-size: 0.8rem;
176}
177
178/* List screen */
179#list-screen header {
180 display: flex;
181 justify-content: space-between;
182 align-items: center;
183 margin-bottom: 2rem;
184 padding-bottom: 1rem;
185 border-bottom: 2px solid var(--brand-color);
186}
187
188#list-screen header h2 {
189 margin-bottom: 0.25rem;
190}
191
192.connection-status {
193 display: flex;
194 align-items: center;
195 gap: 0.5rem;
196 font-size: 0.85rem;
197 color: color-mix(in oklch, var(--text-1) 70%, transparent);
198}
199
200.status-dot {
201 width: 8px;
202 height: 8px;
203 border-radius: 50%;
204 background: var(--stone-8);
205}
206
207.status-dot.connected {
208 background: var(--brand-color);
209 box-shadow: 0 0 4px color-mix(in oklch, var(--brand-color) 60%, transparent);
210}
211
212.status-dot.connecting {
213 background: var(--cranberry-7);
214 animation: pulse 1.5s ease-in-out infinite;
215}
216
217.status-dot.disconnected {
218 background: var(--cranberry-12);
219}
220
221@keyframes pulse {
222 0%, 100% {
223 opacity: 1;
224 }
225 50% {
226 opacity: 0.5;
227 }
228}
229
230.header-actions {
231 display: flex;
232 gap: 0.5rem;
233}
234
235#room-code {
236 font-family: monospace;
237 background: var(--background-2);
238 padding: 0.25rem 0.5rem;
239 border-radius: 6px;
240}
241
242#copy-btn,
243#copy-link-btn,
244#set-title-btn,
245#reset-votes-btn {
246 background: var(--stone-1);
247 --btn-color: var(--stone-1);
248 color: var(--text-1);
249 border: none;
250 width: 40px;
251 height: 40px;
252 padding: 0;
253 border-radius: 999px;
254 display: grid;
255 place-items: center;
256}
257
258#copy-btn:hover,
259#copy-link-btn:hover,
260#set-title-btn:hover,
261#reset-votes-btn:hover {
262 filter: brightness(1.03);
263}
264
265.header-actions button svg {
266 width: 20px;
267 height: 20px;
268 display: block;
269}
270
271#leave-btn {
272 background: var(--stone-1);
273 --btn-color: var(--stone-1);
274 color: var(--avocado-12);
275 border: none;
276}
277
278#leave-btn:hover {
279 filter: brightness(1.03);
280}
281
282.add-section {
283 display: flex;
284 gap: 0.5rem;
285 margin-bottom: 1rem;
286}
287
288.add-section input {
289 flex: 1;
290}
291
292.bulk-section {
293 display: flex;
294 flex-direction: column;
295 align-items: flex-end;
296 margin-bottom: 2rem;
297}
298
299.bulk-section textarea {
300 width: 100%;
301 min-height: 100px;
302 margin-bottom: 0.5rem;
303 resize: vertical;
304}
305
306/* Tie breaker */
307#tie-breaker {
308 display: flex;
309 align-items: center;
310 gap: 1rem;
311 margin-bottom: 1.5rem;
312 padding: 1rem;
313 background: var(--stone-2);
314 border-radius: 8px;
315}
316
317#break-tie-btn {
318 flex-shrink: 0;
319}
320
321#tie-break-result {
322 font-weight: 500;
323 color: var(--brand-color);
324}
325
326/* List items */
327#list-container.disabled {
328 pointer-events: none;
329 opacity: 0.6;
330}
331
332.list-item {
333 position: relative;
334 background: var(--stone-1);
335 padding: 1rem;
336 margin-bottom: 0.5rem;
337 border-radius: 8px;
338 box-shadow: 0 1px 3px color-mix(in oklch, var(--shadow-color) 20%, transparent);
339 display: flex;
340 justify-content: space-between;
341 align-items: center;
342 transition: transform 0.3s ease, box-shadow 0.2s ease;
343 border-left: 3px solid transparent;
344}
345
346.list-item:hover {
347 transform: translateY(-1px);
348 box-shadow: 0 4px 12px color-mix(in oklch, var(--shadow-color) 25%, transparent);
349}
350
351.list-item.selected {
352 outline: 2px solid var(--brand-color);
353 outline-offset: 2px;
354 border-radius: 10px;
355}
356
357.list-item.vetoed {
358 opacity: 0.4;
359 max-height: 3rem;
360 overflow: hidden;
361}
362
363.top-check {
364 position: absolute;
365 left: -40px;
366 top: 50%;
367 transform: translateY(-50%);
368 color: var(--avocado-9);
369 flex-shrink: 0;
370}
371
372
373.list-item-text {
374 flex: 1;
375 padding-right: 1rem;
376 cursor: pointer;
377 user-select: none;
378}
379
380.list-item-text:hover {
381 opacity: 0.9;
382}
383
384.edit-input {
385 flex: 1;
386 margin-right: 1rem;
387}
388
389.list-item-actions {
390 display: flex;
391 gap: 0.5rem;
392 flex-shrink: 0;
393}
394
395.vote-btn {
396 padding: 0.5rem;
397 font-size: 0.9rem;
398}
399
400.delete-btn {
401 padding: 0.5rem;
402 font-size: 0.9rem;
403 background: var(--danger-color);
404 --btn-color: var(--danger-color);
405 color: var(--stone-1);
406 opacity: 0.8;
407 transition: opacity 0.2s, background 0.2s;
408}
409
410.delete-btn:hover {
411 opacity: 1;
412 background: var(--cranberry-8);
413}
414
415.vote-btn.active {
416 background: var(--avocado-11);
417 color: var(--stone-1);
418 transform: translateY(4px);
419 box-shadow:
420 0 2px 0 color-mix(in oklch, var(--btn-color) 60%, black),
421 0 6px 12px color-mix(in oklch, var(--stone-16) 25%, transparent),
422 inset 0 -1px 0 color-mix(in oklch, var(--btn-color) 50%, black);
423}
424
425.vote-btn.veto-active {
426 background: var(--avocado-11);
427 color: var(--stone-1);
428 transform: translateY(4px);
429 box-shadow:
430 0 2px 0 color-mix(in oklch, var(--btn-color) 60%, black),
431 0 6px 12px color-mix(in oklch, var(--stone-16) 25%, transparent),
432 inset 0 -1px 0 color-mix(in oklch, var(--btn-color) 50%, black);
433}
434
435.vote-btn svg,
436.delete-btn svg {
437 width: 16px;
438 height: 16px;
439 display: block;
440}
441
442.score {
443 min-width: 40px;
444 text-align: center;
445 font-weight: bold;
446 color: var(--brand-color);
447 background: var(--stone-2);
448 padding: 0.25rem 0.5rem;
449 border-radius: 999px;
450}
451
452/* Modal */
453.modal {
454 position: fixed;
455 top: 0;
456 left: 0;
457 width: 100%;
458 height: 100%;
459 background: color-mix(in oklch, var(--stone-16) 60%, transparent);
460 display: flex;
461 align-items: center;
462 justify-content: center;
463 z-index: 1000;
464}
465
466.modal-content {
467 background: var(--stone-1);
468 padding: 2rem;
469 border-radius: 8px;
470 max-width: 500px;
471 width: 90%;
472 max-height: 80vh;
473 overflow-y: auto;
474 box-shadow: 0 4px 20px color-mix(in oklch, var(--shadow-color) 35%, transparent);
475}
476
477.modal-header {
478 display: flex;
479 justify-content: space-between;
480 align-items: center;
481 margin-bottom: 1.5rem;
482 padding-bottom: 0.5rem;
483 border-bottom: 2px solid var(--stone-5);
484}
485
486.modal-header h3 {
487 margin: 0;
488 color: var(--avocado-12);
489}
490
491.modal-close {
492 background: transparent;
493 color: var(--text-1);
494 border: none;
495 font-size: 2rem;
496 line-height: 1;
497 padding: 0;
498 width: 2rem;
499 height: 2rem;
500 cursor: pointer;
501}
502
503.modal-close:hover {
504 color: var(--cranberry-9);
505}
506
507.modal-body h4 {
508 color: var(--brand-color);
509 margin-top: 1rem;
510 margin-bottom: 0.5rem;
511}
512
513.modal-body h4:first-child {
514 margin-top: 0;
515}
516
517.modal-body ul {
518 margin: 0;
519 padding-left: 1.5rem;
520}
521
522.modal-body li {
523 margin-bottom: 0.5rem;
524}
525
526kbd {
527 display: inline-block;
528 padding: 0.2rem 0.4rem;
529 font-size: 0.85rem;
530 font-family: monospace;
531 background: var(--background-2);
532 border: 1px solid var(--stone-5);
533 border-radius: 4px;
534 box-shadow: 0 1px 2px color-mix(in oklch, var(--shadow-color) 20%, transparent);
535}
536
537/* Screen reader only */
538.sr-only {
539 position: absolute;
540 width: 1px;
541 height: 1px;
542 padding: 0;
543 margin: -1px;
544 overflow: hidden;
545 clip: rect(0, 0, 0, 0);
546 white-space: nowrap;
547 border-width: 0;
548}
549
550/* Source link */
551.source-link {
552 display: block;
553 text-align: center;
554 margin-top: 2rem;
555 font-size: 0.85rem;
556 color: color-mix(in oklch, var(--text-1) 50%, transparent);
557 text-decoration: none;
558 transition: color 0.2s ease;
559}
560
561.source-link:hover {
562 color: var(--brand-color);
563 text-decoration: underline;
564}
565
566@media (prefers-reduced-motion: reduce) {
567 * {
568 transition: none !important;
569 animation: none !important;
570 }
571}
572
573@media (prefers-color-scheme: dark) {
574 body {
575 background: var(--background-dark-1);
576 color: var(--stone-3);
577 }
578
579 button {
580 background: var(--avocado-9);
581 --btn-color: var(--avocado-9);
582 color: var(--stone-1);
583 }
584
585 button:hover {
586 background: var(--avocado-8);
587 }
588
589 input,
590 textarea {
591 background: var(--background-dark-2);
592 border: 1px solid var(--stone-9);
593 color: var(--stone-3);
594 }
595
596 input::placeholder,
597 textarea::placeholder {
598 color: color-mix(in oklch, var(--stone-3) 50%, transparent);
599 }
600
601 .expiry-notice {
602 color: color-mix(in oklch, var(--stone-3) 60%, transparent);
603 }
604
605 #list-screen header {
606 border-bottom: 2px solid var(--avocado-9);
607 }
608
609 .connection-status {
610 color: color-mix(in oklch, var(--stone-3) 60%, transparent);
611 }
612
613 .status-dot {
614 background: var(--stone-10);
615 }
616
617 .status-dot.connected {
618 background: var(--avocado-9);
619 box-shadow: 0 0 4px color-mix(in oklch, var(--avocado-9) 60%, transparent);
620 }
621
622 .status-dot.connecting {
623 background: var(--cranberry-8);
624 }
625
626 .status-dot.disconnected {
627 background: var(--cranberry-13);
628 }
629
630 #room-code {
631 background: var(--background-dark-2);
632 color: var(--stone-3);
633 }
634
635 #copy-btn,
636 #copy-link-btn,
637 #set-title-btn,
638 #reset-votes-btn {
639 background: var(--background-dark-2);
640 --btn-color: var(--background-dark-2);
641 color: var(--stone-3);
642 border: none;
643 }
644
645 #copy-btn:hover,
646 #copy-link-btn:hover,
647 #set-title-btn:hover,
648 #reset-votes-btn:hover {
649 filter: brightness(1.04);
650 }
651
652 #leave-btn {
653 background: var(--background-dark-2);
654 color: var(--stone-3);
655 border: none;
656 --btn-color: var(--background-dark-2);
657 }
658
659 #leave-btn:hover {
660 filter: brightness(1.04);
661 }
662
663 .list-item {
664 background: var(--background-dark-2);
665 box-shadow: 0 1px 3px color-mix(in oklch, var(--shadow-color) 30%, transparent);
666 }
667
668 #tie-breaker {
669 background: var(--background-dark-2);
670 }
671
672 #tie-break-result {
673 color: var(--avocado-8);
674 }
675
676 .list-item:hover {
677 box-shadow: 0 4px 12px color-mix(in oklch, var(--shadow-color) 45%, transparent);
678 }
679
680 .list-item.selected {
681 outline-color: var(--avocado-9);
682 }
683
684
685 .delete-btn {
686 background: var(--cranberry-10);
687 --btn-color: var(--cranberry-10);
688 }
689
690 .delete-btn:hover {
691 background: var(--cranberry-9);
692 }
693
694 .vote-btn.active {
695 background: var(--avocado-11);
696 }
697
698 .vote-btn.veto-active {
699 background: var(--avocado-12);
700 }
701
702 .score {
703 color: var(--avocado-8);
704 background: var(--stone-14);
705 }
706
707 .modal {
708 background: color-mix(in oklch, var(--background-dark-3) 75%, transparent);
709 }
710
711 .modal-content {
712 background: var(--background-dark-2);
713 box-shadow: 0 4px 20px color-mix(in oklch, var(--shadow-color) 70%, transparent);
714 }
715
716 .modal-header {
717 border-bottom: 2px solid var(--stone-11);
718 }
719
720 .modal-header h3 {
721 color: var(--avocado-8);
722 }
723
724 .modal-close {
725 color: var(--stone-3);
726 }
727
728 .modal-close:hover {
729 color: var(--cranberry-8);
730 }
731
732 .modal-body h4 {
733 color: var(--avocado-8);
734 }
735
736 kbd {
737 background: var(--background-dark-2);
738 border: 1px solid var(--stone-11);
739 box-shadow: 0 1px 2px color-mix(in oklch, var(--shadow-color) 50%, transparent);
740 }
741
742 .source-link {
743 color: color-mix(in oklch, var(--stone-3) 50%, transparent);
744 }
745
746 .source-link:hover {
747 color: var(--avocado-9);
748 }
749}