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  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}