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