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 margin-bottom: 2rem;
294}
295
296.bulk-section textarea {
297 width: 100%;
298 min-height: 100px;
299 margin-bottom: 0.5rem;
300 resize: vertical;
301}
302
303/* Tie breaker */
304#tie-breaker {
305 display: flex;
306 align-items: center;
307 gap: 1rem;
308 margin-bottom: 1.5rem;
309 padding: 1rem;
310 background: var(--stone-2);
311 border-radius: 8px;
312}
313
314#break-tie-btn {
315 flex-shrink: 0;
316}
317
318#tie-break-result {
319 font-weight: 500;
320 color: var(--brand-color);
321}
322
323/* List items */
324#list-container.disabled {
325 pointer-events: none;
326 opacity: 0.6;
327}
328
329.list-item {
330 position: relative;
331 background: var(--stone-1);
332 padding: 1rem;
333 margin-bottom: 0.5rem;
334 border-radius: 8px;
335 box-shadow: 0 1px 3px color-mix(in oklch, var(--shadow-color) 20%, transparent);
336 display: flex;
337 justify-content: space-between;
338 align-items: center;
339 transition: transform 0.3s ease, box-shadow 0.2s ease;
340 border-left: 3px solid transparent;
341}
342
343.list-item:hover {
344 transform: translateY(-1px);
345 box-shadow: 0 4px 12px color-mix(in oklch, var(--shadow-color) 25%, transparent);
346}
347
348.list-item.selected {
349 outline: 2px solid var(--brand-color);
350 outline-offset: 2px;
351 border-radius: 10px;
352}
353
354.list-item.vetoed {
355 opacity: 0.4;
356 max-height: 3rem;
357 overflow: hidden;
358}
359
360.top-check {
361 position: absolute;
362 left: -40px;
363 top: 50%;
364 transform: translateY(-50%);
365 color: var(--avocado-9);
366 flex-shrink: 0;
367}
368
369
370.list-item-text {
371 flex: 1;
372 padding-right: 1rem;
373 cursor: pointer;
374 user-select: none;
375}
376
377.list-item-text:hover {
378 opacity: 0.9;
379}
380
381.edit-input {
382 flex: 1;
383 margin-right: 1rem;
384}
385
386.list-item-actions {
387 display: flex;
388 gap: 0.5rem;
389 flex-shrink: 0;
390}
391
392.vote-btn {
393 padding: 0.5rem;
394 font-size: 0.9rem;
395}
396
397.delete-btn {
398 padding: 0.5rem;
399 font-size: 0.9rem;
400 background: var(--danger-color);
401 --btn-color: var(--danger-color);
402 color: var(--stone-1);
403 opacity: 0.8;
404 transition: opacity 0.2s, background 0.2s;
405}
406
407.delete-btn:hover {
408 opacity: 1;
409 background: var(--cranberry-8);
410}
411
412.vote-btn.active {
413 background: var(--avocado-11);
414 color: var(--stone-1);
415 transform: translateY(4px);
416 box-shadow:
417 0 2px 0 color-mix(in oklch, var(--btn-color) 60%, black),
418 0 6px 12px color-mix(in oklch, var(--stone-16) 25%, transparent),
419 inset 0 -1px 0 color-mix(in oklch, var(--btn-color) 50%, black);
420}
421
422.vote-btn.veto-active {
423 background: var(--avocado-11);
424 color: var(--stone-1);
425 transform: translateY(4px);
426 box-shadow:
427 0 2px 0 color-mix(in oklch, var(--btn-color) 60%, black),
428 0 6px 12px color-mix(in oklch, var(--stone-16) 25%, transparent),
429 inset 0 -1px 0 color-mix(in oklch, var(--btn-color) 50%, black);
430}
431
432.vote-btn svg,
433.delete-btn svg {
434 width: 16px;
435 height: 16px;
436 display: block;
437}
438
439.score {
440 min-width: 40px;
441 text-align: center;
442 font-weight: bold;
443 color: var(--brand-color);
444 background: var(--stone-2);
445 padding: 0.25rem 0.5rem;
446 border-radius: 999px;
447}
448
449/* Modal */
450.modal {
451 position: fixed;
452 top: 0;
453 left: 0;
454 width: 100%;
455 height: 100%;
456 background: color-mix(in oklch, var(--stone-16) 60%, transparent);
457 display: flex;
458 align-items: center;
459 justify-content: center;
460 z-index: 1000;
461}
462
463.modal-content {
464 background: var(--stone-1);
465 padding: 2rem;
466 border-radius: 8px;
467 max-width: 500px;
468 width: 90%;
469 max-height: 80vh;
470 overflow-y: auto;
471 box-shadow: 0 4px 20px color-mix(in oklch, var(--shadow-color) 35%, transparent);
472}
473
474.modal-header {
475 display: flex;
476 justify-content: space-between;
477 align-items: center;
478 margin-bottom: 1.5rem;
479 padding-bottom: 0.5rem;
480 border-bottom: 2px solid var(--stone-5);
481}
482
483.modal-header h3 {
484 margin: 0;
485 color: var(--avocado-12);
486}
487
488.modal-close {
489 background: transparent;
490 color: var(--text-1);
491 border: none;
492 font-size: 2rem;
493 line-height: 1;
494 padding: 0;
495 width: 2rem;
496 height: 2rem;
497 cursor: pointer;
498}
499
500.modal-close:hover {
501 color: var(--cranberry-9);
502}
503
504.modal-body h4 {
505 color: var(--brand-color);
506 margin-top: 1rem;
507 margin-bottom: 0.5rem;
508}
509
510.modal-body h4:first-child {
511 margin-top: 0;
512}
513
514.modal-body ul {
515 margin: 0;
516 padding-left: 1.5rem;
517}
518
519.modal-body li {
520 margin-bottom: 0.5rem;
521}
522
523kbd {
524 display: inline-block;
525 padding: 0.2rem 0.4rem;
526 font-size: 0.85rem;
527 font-family: monospace;
528 background: var(--background-2);
529 border: 1px solid var(--stone-5);
530 border-radius: 4px;
531 box-shadow: 0 1px 2px color-mix(in oklch, var(--shadow-color) 20%, transparent);
532}
533
534/* Screen reader only */
535.sr-only {
536 position: absolute;
537 width: 1px;
538 height: 1px;
539 padding: 0;
540 margin: -1px;
541 overflow: hidden;
542 clip: rect(0, 0, 0, 0);
543 white-space: nowrap;
544 border-width: 0;
545}
546
547/* Source link */
548.source-link {
549 display: block;
550 text-align: center;
551 margin-top: 2rem;
552 font-size: 0.85rem;
553 color: color-mix(in oklch, var(--text-1) 50%, transparent);
554 text-decoration: none;
555 transition: color 0.2s ease;
556}
557
558.source-link:hover {
559 color: var(--brand-color);
560 text-decoration: underline;
561}
562
563@media (prefers-reduced-motion: reduce) {
564 * {
565 transition: none !important;
566 animation: none !important;
567 }
568}
569
570@media (prefers-color-scheme: dark) {
571 body {
572 background: var(--background-dark-1);
573 color: var(--stone-3);
574 }
575
576 button {
577 background: var(--avocado-9);
578 --btn-color: var(--avocado-9);
579 color: var(--stone-1);
580 }
581
582 button:hover {
583 background: var(--avocado-8);
584 }
585
586 input,
587 textarea {
588 background: var(--background-dark-2);
589 border: 1px solid var(--stone-9);
590 color: var(--stone-3);
591 }
592
593 input::placeholder,
594 textarea::placeholder {
595 color: color-mix(in oklch, var(--stone-3) 50%, transparent);
596 }
597
598 .expiry-notice {
599 color: color-mix(in oklch, var(--stone-3) 60%, transparent);
600 }
601
602 #list-screen header {
603 border-bottom: 2px solid var(--avocado-9);
604 }
605
606 .connection-status {
607 color: color-mix(in oklch, var(--stone-3) 60%, transparent);
608 }
609
610 .status-dot {
611 background: var(--stone-10);
612 }
613
614 .status-dot.connected {
615 background: var(--avocado-9);
616 box-shadow: 0 0 4px color-mix(in oklch, var(--avocado-9) 60%, transparent);
617 }
618
619 .status-dot.connecting {
620 background: var(--cranberry-8);
621 }
622
623 .status-dot.disconnected {
624 background: var(--cranberry-13);
625 }
626
627 #room-code {
628 background: var(--background-dark-2);
629 color: var(--stone-3);
630 }
631
632 #copy-btn,
633 #copy-link-btn,
634 #set-title-btn,
635 #reset-votes-btn {
636 background: var(--background-dark-2);
637 --btn-color: var(--background-dark-2);
638 color: var(--stone-3);
639 border: none;
640 }
641
642 #copy-btn:hover,
643 #copy-link-btn:hover,
644 #set-title-btn:hover,
645 #reset-votes-btn:hover {
646 filter: brightness(1.04);
647 }
648
649 #leave-btn {
650 background: var(--background-dark-2);
651 color: var(--stone-3);
652 border: none;
653 --btn-color: var(--background-dark-2);
654 }
655
656 #leave-btn:hover {
657 filter: brightness(1.04);
658 }
659
660 .list-item {
661 background: var(--background-dark-2);
662 box-shadow: 0 1px 3px color-mix(in oklch, var(--shadow-color) 30%, transparent);
663 }
664
665 #tie-breaker {
666 background: var(--background-dark-2);
667 }
668
669 #tie-break-result {
670 color: var(--avocado-8);
671 }
672
673 .list-item:hover {
674 box-shadow: 0 4px 12px color-mix(in oklch, var(--shadow-color) 45%, transparent);
675 }
676
677 .list-item.selected {
678 outline-color: var(--avocado-9);
679 }
680
681
682 .delete-btn {
683 background: var(--cranberry-10);
684 --btn-color: var(--cranberry-10);
685 }
686
687 .delete-btn:hover {
688 background: var(--cranberry-9);
689 }
690
691 .vote-btn.active {
692 background: var(--avocado-11);
693 }
694
695 .vote-btn.veto-active {
696 background: var(--avocado-12);
697 }
698
699 .score {
700 color: var(--avocado-8);
701 background: var(--stone-14);
702 }
703
704 .modal {
705 background: color-mix(in oklch, var(--background-dark-3) 75%, transparent);
706 }
707
708 .modal-content {
709 background: var(--background-dark-2);
710 box-shadow: 0 4px 20px color-mix(in oklch, var(--shadow-color) 70%, transparent);
711 }
712
713 .modal-header {
714 border-bottom: 2px solid var(--stone-11);
715 }
716
717 .modal-header h3 {
718 color: var(--avocado-8);
719 }
720
721 .modal-close {
722 color: var(--stone-3);
723 }
724
725 .modal-close:hover {
726 color: var(--cranberry-8);
727 }
728
729 .modal-body h4 {
730 color: var(--avocado-8);
731 }
732
733 kbd {
734 background: var(--background-dark-2);
735 border: 1px solid var(--stone-11);
736 box-shadow: 0 1px 2px color-mix(in oklch, var(--shadow-color) 50%, transparent);
737 }
738
739 .source-link {
740 color: color-mix(in oklch, var(--stone-3) 50%, transparent);
741 }
742
743 .source-link:hover {
744 color: var(--avocado-9);
745 }
746}