style.css

  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}