forked from
tranquil.farm/tranquil-pds
Our Personal Data Server from scratch!
1@import "./tokens.css";
2
3@property --accent {
4 syntax: "<color>";
5 inherits: true;
6 initial-value: #1a1d1d;
7}
8
9@property --secondary {
10 syntax: "<color>";
11 inherits: true;
12 initial-value: #1a1d1d;
13}
14
15*,
16*::before,
17*::after {
18 box-sizing: border-box;
19}
20
21body {
22 margin: 0;
23 font-family:
24 "Space Grotesk", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
25 font-size: var(--text-base);
26 line-height: var(--leading-normal);
27 color: var(--text-primary);
28 background: var(--bg-primary);
29 -webkit-font-smoothing: antialiased;
30 -moz-osx-font-smoothing: grayscale;
31 transition: background-color 0.3s ease;
32 overflow-wrap: anywhere;
33 word-break: break-word;
34}
35
36h1, h2, h3, h4, h5, h6 {
37 margin: 0;
38 line-height: var(--leading-tight);
39}
40
41h1 {
42 font-size: var(--text-2xl);
43}
44h2 {
45 font-size: var(--text-xl);
46}
47h3 {
48 font-size: var(--text-lg);
49}
50h4 {
51 font-size: var(--text-base);
52}
53
54p {
55 margin: 0;
56}
57
58a {
59 color: var(--accent);
60 text-decoration: underline;
61 text-underline-offset: 2px;
62}
63
64a:hover {
65 color: var(--accent-hover);
66}
67
68::selection {
69 background: var(--secondary-muted);
70}
71
72input,
73select,
74textarea {
75 font-family: inherit;
76 font-size: var(--text-base);
77 line-height: var(--leading-normal);
78 padding: var(--space-4);
79 border: 1px solid var(--border-dark);
80 border-radius: var(--radius-md);
81 background: var(--bg-input);
82 color: var(--text-primary);
83 transition:
84 border-color var(--transition-normal),
85 box-shadow var(--transition-normal);
86 width: 100%;
87}
88
89input:focus,
90select:focus,
91textarea:focus {
92 outline: none;
93 border-color: var(--accent);
94 box-shadow: var(--shadow-focus);
95}
96
97input:disabled,
98select:disabled,
99textarea:disabled {
100 background: var(--bg-input-disabled);
101 color: var(--text-muted);
102 cursor: not-allowed;
103}
104
105input::placeholder,
106textarea::placeholder {
107 color: var(--text-muted);
108}
109
110select {
111 cursor: pointer;
112 appearance: none;
113 background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%23666' d='M6 8L1 3h10z'/%3E%3C/svg%3E");
114 background-repeat: no-repeat;
115 background-position: right var(--space-4) center;
116 padding-right: var(--space-7);
117}
118
119button {
120 font-family: inherit;
121 font-size: var(--text-base);
122 font-weight: var(--font-medium);
123 line-height: var(--leading-normal);
124 padding: var(--space-4) var(--space-6);
125 border: none;
126 border-radius: var(--radius-md);
127 cursor: pointer;
128 transition:
129 background var(--transition-normal),
130 border-color var(--transition-normal),
131 opacity var(--transition-normal);
132 background: var(--accent);
133 color: var(--text-inverse);
134}
135
136button:hover:not(:disabled) {
137 background: var(--accent-hover);
138}
139
140button:disabled {
141 opacity: 0.6;
142 cursor: not-allowed;
143}
144
145button.secondary {
146 background: transparent;
147 color: var(--accent);
148 border: 1px solid var(--accent);
149}
150
151button.secondary:hover:not(:disabled) {
152 background: var(--accent);
153 color: var(--text-inverse);
154}
155
156button.tertiary {
157 background: transparent;
158 color: var(--text-secondary);
159 padding: var(--space-3) var(--space-4);
160}
161
162button.tertiary:hover:not(:disabled) {
163 color: var(--text-primary);
164 background: var(--bg-tertiary);
165}
166
167button.danger {
168 background: var(--error-text);
169}
170
171button.danger:hover:not(:disabled) {
172 background: #900;
173}
174
175button.danger-outline {
176 background: transparent;
177 border: 1px solid var(--error-border);
178 color: var(--error-text);
179}
180
181button.danger-outline:hover:not(:disabled) {
182 background: var(--error-bg);
183 border-color: var(--error-text);
184}
185
186button.ghost {
187 background: transparent;
188 color: var(--text-secondary);
189 border: 1px solid var(--border-dark);
190}
191
192button.ghost:hover:not(:disabled) {
193 background: var(--bg-secondary);
194 color: var(--text-primary);
195}
196
197button.link {
198 background: none;
199 border: none;
200 color: var(--accent);
201 padding: var(--space-2);
202 font-size: var(--text-sm);
203 font-weight: var(--font-normal);
204}
205
206button.link:hover:not(:disabled) {
207 background: none;
208 text-decoration: underline;
209}
210
211button.sm {
212 padding: var(--space-2) var(--space-3);
213 font-size: var(--text-xs);
214}
215
216button.icon {
217 background: none;
218 border: none;
219 color: var(--text-secondary);
220 padding: var(--space-1);
221 font-size: var(--text-base);
222}
223
224button.icon:hover:not(:disabled) {
225 background: none;
226 color: var(--text-primary);
227}
228
229label {
230 display: block;
231 font-size: var(--text-sm);
232 font-weight: var(--font-medium);
233 color: var(--text-primary);
234 margin-bottom: var(--space-2);
235}
236
237fieldset {
238 border: none;
239 border-left: 3px solid var(--accent);
240 border-radius: var(--radius-lg);
241 padding: var(--space-5);
242 padding-left: var(--space-6);
243 margin: 0;
244 background: var(--bg-secondary);
245}
246
247fieldset legend {
248 font-size: var(--text-xs);
249 font-weight: var(--font-semibold);
250 text-transform: uppercase;
251 letter-spacing: 0.05em;
252 padding: 0;
253 margin-left: calc(-1 * var(--space-1));
254 margin-bottom: var(--space-3);
255 color: var(--text-secondary);
256 float: left;
257 width: 100%;
258}
259
260fieldset legend + * {
261 clear: both;
262}
263
264code {
265 font-family: var(--font-mono);
266 font-size: 0.9em;
267 background: var(--bg-tertiary);
268 padding: var(--space-1) var(--space-2);
269 border-radius: var(--radius-sm);
270}
271
272pre {
273 font-family: var(--font-mono);
274 font-size: var(--text-sm);
275 background: var(--bg-tertiary);
276 padding: var(--space-4);
277 border-radius: var(--radius-md);
278 overflow-x: auto;
279 margin: 0;
280}
281
282hr {
283 border: none;
284 border-top: 1px solid var(--border-color);
285 margin: var(--space-6) 0;
286}
287
288.field {
289 display: flex;
290 flex-direction: column;
291 gap: var(--space-2);
292}
293
294.field + .field {
295 margin-top: var(--space-5);
296}
297
298.form-row .field + .field {
299 margin-top: 0;
300}
301
302.hint {
303 font-size: var(--text-xs);
304 color: var(--text-secondary);
305 margin-top: var(--space-1);
306}
307
308.hint.warning {
309 color: var(--warning-text);
310}
311
312.hint.error {
313 color: var(--error-text);
314}
315
316.hint.success {
317 color: var(--success-text);
318}
319
320.message {
321 padding: var(--space-4);
322 border-radius: var(--radius-md);
323 font-size: var(--text-sm);
324}
325
326.message.success {
327 background: var(--success-bg);
328 border: 1px solid var(--success-border);
329 color: var(--success-text);
330}
331
332.message.error {
333 background: var(--error-bg);
334 border: 1px solid var(--error-border);
335 color: var(--error-text);
336}
337
338.message.warning {
339 background: var(--warning-bg);
340 border: 1px solid var(--warning-border);
341 color: var(--warning-text);
342}
343
344.badge {
345 display: inline-block;
346 padding: var(--space-1) var(--space-3);
347 border-radius: var(--radius-md);
348 font-size: var(--text-xs);
349 font-weight: var(--font-medium);
350}
351
352.badge.success {
353 background: var(--success-bg);
354 color: var(--success-text);
355}
356
357.badge.warning {
358 background: var(--warning-bg);
359 color: var(--warning-text);
360}
361
362.badge.error {
363 background: var(--error-bg);
364 color: var(--error-text);
365}
366
367.badge.accent {
368 background: var(--accent);
369 color: var(--text-inverse);
370}
371
372.card {
373 background: var(--bg-card);
374 border: 1px solid var(--border-color);
375 border-radius: var(--radius-xl);
376 padding: var(--space-6);
377 overflow: hidden;
378 min-width: 0;
379}
380
381.section {
382 background: var(--bg-secondary);
383 border-radius: var(--radius-xl);
384 padding: var(--space-6);
385 overflow: hidden;
386 min-width: 0;
387}
388
389.section + .section {
390 margin-top: var(--space-6);
391}
392
393.page {
394 max-width: var(--width-lg);
395 margin: 0 auto;
396 padding: var(--space-7);
397}
398
399.page-sm {
400 max-width: var(--width-md);
401 margin: 0 auto;
402 padding: var(--space-7);
403}
404
405.page-lg {
406 max-width: var(--width-xl);
407 margin: 0 auto;
408 padding: var(--space-7);
409}
410
411.page-header {
412 margin-bottom: var(--space-6);
413}
414
415.page-header h1 {
416 margin: 0 0 var(--space-3) 0;
417}
418
419.page-header .subtitle {
420 color: var(--text-secondary);
421 margin: 0;
422}
423
424.loading {
425 display: flex;
426 flex-direction: column;
427 align-items: center;
428 gap: var(--space-4);
429 padding: var(--space-8);
430}
431
432.loading p {
433 color: var(--text-secondary);
434 margin: 0;
435}
436
437.back-link {
438 display: inline-block;
439 color: var(--text-secondary);
440 font-size: var(--text-sm);
441 margin-bottom: var(--space-3);
442 text-decoration: none;
443}
444
445.back-link:hover {
446 color: var(--accent);
447 text-decoration: none;
448}
449
450.text-muted {
451 color: var(--text-muted);
452}
453
454.text-secondary {
455 color: var(--text-secondary);
456}
457
458.text-sm {
459 font-size: var(--text-sm);
460}
461
462.text-xs {
463 font-size: var(--text-xs);
464}
465
466.text-center {
467 text-align: center;
468}
469
470.mono {
471 font-family: var(--font-mono);
472}
473
474.mt-4 {
475 margin-top: var(--space-4);
476}
477.mt-5 {
478 margin-top: var(--space-5);
479}
480.mt-6 {
481 margin-top: var(--space-6);
482}
483.mb-4 {
484 margin-bottom: var(--space-4);
485}
486.mb-5 {
487 margin-bottom: var(--space-5);
488}
489.mb-6 {
490 margin-bottom: var(--space-6);
491}
492
493.split-layout {
494 display: grid;
495 grid-template-columns: 1fr;
496 gap: var(--space-6);
497}
498
499@media (min-width: 800px) {
500 .split-layout {
501 grid-template-columns: 1fr 1fr;
502 align-items: start;
503 }
504 .split-layout.sidebar-right {
505 grid-template-columns: 1.5fr 1fr;
506 }
507 .split-layout.sidebar-left {
508 grid-template-columns: 1fr 1.5fr;
509 }
510}
511
512.split-layout > * {
513 min-width: 0;
514}
515
516.form-row {
517 display: grid;
518 grid-template-columns: 1fr;
519 gap: var(--space-4);
520}
521
522@media (min-width: 600px) {
523 .form-row {
524 grid-template-columns: repeat(2, 1fr);
525 }
526 .form-row.thirds {
527 grid-template-columns: repeat(3, 1fr);
528 }
529}
530
531.full-width {
532 grid-column: 1 / -1;
533}
534
535.info-panel {
536 background: var(--bg-secondary);
537 border-radius: var(--radius-xl);
538 padding: var(--space-6);
539 height: fit-content;
540 overflow: hidden;
541 min-width: 0;
542}
543
544.info-panel h3 {
545 margin: 0 0 var(--space-3) 0;
546 font-size: var(--text-base);
547 font-weight: var(--font-semibold);
548}
549
550.info-panel p {
551 margin: 0 0 var(--space-4) 0;
552 font-size: var(--text-sm);
553 color: var(--text-secondary);
554}
555
556.info-panel p:last-child {
557 margin-bottom: 0;
558}
559
560.spinner {
561 width: 40px;
562 height: 40px;
563 border: 3px solid var(--border-color);
564 border-top-color: var(--accent);
565 border-radius: 50%;
566 animation: spin 1s linear infinite;
567}
568
569.spinner.sm {
570 width: 20px;
571 height: 20px;
572 border-width: 2px;
573}
574
575.spinner.md {
576 width: 32px;
577 height: 32px;
578}
579
580.spinner.lg {
581 width: 60px;
582 height: 60px;
583 border-width: 4px;
584}
585
586@keyframes spin {
587 to {
588 transform: rotate(360deg);
589 }
590}
591
592.skeleton {
593 background: var(--bg-secondary);
594 border-radius: var(--radius-md);
595 animation: skeleton-pulse 1.5s ease-in-out infinite;
596}
597
598.skeleton-card {
599 height: 100px;
600 background: var(--bg-secondary);
601 border: 1px solid var(--border-color);
602 border-radius: var(--radius-xl);
603 animation: skeleton-pulse 1.5s ease-in-out infinite;
604}
605
606.skeleton-line {
607 height: var(--space-4);
608 background: var(--bg-secondary);
609 border-radius: var(--radius-sm);
610 animation: skeleton-pulse 1.5s ease-in-out infinite;
611}
612
613@keyframes skeleton-pulse {
614 0%, 100% {
615 opacity: 1;
616 }
617 50% {
618 opacity: 0.5;
619 }
620}
621
622.section-hint {
623 font-size: var(--text-sm);
624 color: var(--text-secondary);
625 margin: 0 0 var(--space-5) 0;
626}
627
628.radio-group {
629 display: flex;
630 flex-direction: column;
631 gap: var(--space-4);
632}
633
634.radio-label {
635 display: flex;
636 align-items: flex-start;
637 gap: var(--space-3);
638 cursor: pointer;
639 font-size: var(--text-base);
640 font-weight: var(--font-normal);
641 margin-bottom: 0;
642}
643
644.radio-label input[type="radio"] {
645 margin-top: var(--space-1);
646 width: auto;
647}
648
649.radio-content {
650 display: flex;
651 flex-direction: column;
652 gap: var(--space-1);
653}
654
655.radio-hint {
656 font-size: var(--text-xs);
657 color: var(--text-secondary);
658}
659
660.radio-label.disabled {
661 opacity: 0.5;
662 cursor: not-allowed;
663}
664
665.radio-hint.disabled-hint {
666 color: var(--warning-text);
667}
668
669.warning-box {
670 margin-top: var(--space-5);
671 padding: var(--space-5);
672 background: var(--warning-bg);
673 border: 1px solid var(--warning-border);
674 border-radius: var(--radius-lg);
675 font-size: var(--text-sm);
676}
677
678.warning-box strong {
679 display: block;
680 margin-bottom: var(--space-3);
681 color: var(--warning-text);
682}
683
684.warning-box ul {
685 margin: var(--space-4) 0 0 0;
686 padding-left: var(--space-5);
687}
688
689.warning-box li {
690 margin-bottom: var(--space-3);
691 line-height: var(--leading-normal);
692}
693
694.warning-box li:last-child {
695 margin-bottom: 0;
696}
697
698.migrate-callout {
699 display: flex;
700 gap: var(--space-4);
701 padding: var(--space-5);
702 background: var(--accent-muted);
703 border: 1px solid var(--accent);
704 border-radius: var(--radius-xl);
705 margin-bottom: var(--space-6);
706}
707
708.migrate-icon {
709 font-size: var(--text-2xl);
710 line-height: 1;
711 color: var(--accent);
712}
713
714.migrate-content {
715 flex: 1;
716}
717
718.migrate-content strong {
719 display: block;
720 color: var(--text-primary);
721 margin-bottom: var(--space-2);
722}
723
724.migrate-content p {
725 margin: 0 0 var(--space-3) 0;
726 font-size: var(--text-sm);
727 color: var(--text-secondary);
728 line-height: var(--leading-relaxed);
729}
730
731.migrate-link {
732 font-size: var(--text-sm);
733 font-weight: var(--font-medium);
734 color: var(--accent);
735 text-decoration: none;
736}
737
738.migrate-link:hover {
739 text-decoration: underline;
740}
741
742.app-password-step {
743 display: flex;
744 flex-direction: column;
745 gap: var(--space-5);
746 max-width: var(--width-md);
747 margin: 0 auto;
748}
749
750.app-password-step .warning-box {
751 margin-top: 0;
752}
753
754.app-password-step .warning-box p {
755 margin: 0;
756 color: var(--warning-text);
757}
758
759.app-password-display {
760 background: var(--bg-card);
761 border: 2px solid var(--accent);
762 border-radius: var(--radius-xl);
763 padding: var(--space-6);
764 text-align: center;
765}
766
767.app-password-label {
768 font-size: var(--text-sm);
769 color: var(--text-secondary);
770 margin-bottom: var(--space-4);
771}
772
773.app-password-code {
774 display: block;
775 font-size: var(--text-xl);
776 font-family: var(--font-mono);
777 letter-spacing: 0.1em;
778 padding: var(--space-5);
779 background: var(--bg-input);
780 border-radius: var(--radius-md);
781 margin-bottom: var(--space-4);
782 user-select: all;
783}
784
785.copy-btn {
786 padding: var(--space-3) var(--space-5);
787 font-size: var(--text-sm);
788}
789
790.checkbox-label {
791 display: flex;
792 align-items: center;
793 gap: var(--space-3);
794 cursor: pointer;
795 font-weight: var(--font-normal);
796}
797
798.checkbox-label input[type="checkbox"] {
799 width: auto;
800 padding: 0;
801}
802
803.form-section {
804 min-width: 0;
805}
806
807.form-links {
808 margin-top: var(--space-6);
809}
810
811.form-links .link-text {
812 text-align: center;
813 color: var(--text-secondary);
814}
815
816.form-links .link-text a {
817 color: var(--accent);
818}
819
820.contact-fields {
821 display: flex;
822 flex-direction: column;
823 gap: var(--space-4);
824}
825
826.contact-fields .field {
827 margin-bottom: 0;
828}
829
830.provider-badge {
831 display: flex;
832 align-items: center;
833 gap: var(--space-3);
834 padding: var(--space-4);
835 background: var(--bg-secondary);
836 border-radius: var(--radius-md);
837}
838
839.provider-details {
840 display: flex;
841 flex-direction: column;
842}
843
844.provider-name {
845 font-weight: var(--font-semibold);
846}
847
848.provider-username {
849 font-size: var(--text-sm);
850 color: var(--text-secondary);
851}
852
853.error-container {
854 text-align: center;
855 padding: var(--space-8);
856}
857
858.error-icon {
859 width: 48px;
860 height: 48px;
861 border-radius: 50%;
862 background: var(--error-text);
863 color: var(--text-inverse);
864 display: flex;
865 align-items: center;
866 justify-content: center;
867 font-size: var(--text-xl);
868 font-weight: var(--font-bold);
869 margin: 0 auto var(--space-4);
870}
871
872.error-container h2 {
873 margin-bottom: var(--space-2);
874}
875
876.error-container p {
877 color: var(--text-secondary);
878 margin-bottom: var(--space-6);
879}
880
881.info-list {
882 margin: 0;
883 padding-left: var(--space-5);
884}
885
886.info-list li {
887 margin-bottom: var(--space-2);
888 font-size: var(--text-sm);
889 color: var(--text-secondary);
890 line-height: var(--leading-relaxed);
891}
892
893.info-list li:last-child {
894 margin-bottom: 0;
895}
896
897.required {
898 color: var(--error-text);
899}