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