forked from
nekomimi.pet/wisp.place-monorepo
Monorepo for wisp.place. A static site hosting service built on top of the AT Protocol.
1/**
2 * wisp.css - A minimal, monospace-first CSS framework
3 *
4 * Usage:
5 * <link rel="stylesheet" href="https://sites.wisp.place/wisp.place/wisp.css/wisp.css">
6 *
7 * Requires JetBrains Mono font:
8 * <link rel="preconnect" href="https://fonts.googleapis.com">
9 * <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
10 * <link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600;700&display=swap" rel="stylesheet">
11 *
12 * Features:
13 * - Light/dark mode via prefers-color-scheme
14 * - CSS custom properties for easy theming
15 * - Monospace typography with JetBrains Mono
16 * - Minimal component styles (cards, buttons, alerts)
17 * - Utility classes for spacing and layout
18 *
19 * License: MIT
20 */
21
22/* ==========================================================================
23 CSS Custom Properties (Theme)
24 ========================================================================== */
25
26:root {
27 /* Background colors */
28 --wisp-bg: oklch(0.92 0.012 35);
29 --wisp-bg-alt: oklch(0.88 0.01 35);
30
31 /* Text colors */
32 --wisp-text: oklch(0.15 0.015 30);
33 --wisp-text-muted: oklch(0.35 0.02 30);
34 --wisp-text-subtle: oklch(0.50 0.02 30);
35
36 /* Border colors */
37 --wisp-border: oklch(0.30 0.025 35);
38 --wisp-border-light: oklch(0.65 0.02 30);
39
40 /* Accent colors */
41 --wisp-accent: oklch(0.65 0.18 345);
42 --wisp-accent-muted: oklch(0.75 0.14 345);
43
44 /* CTA/Button colors */
45 --wisp-cta-bg: oklch(0.30 0.025 35);
46 --wisp-cta-text: oklch(0.96 0.008 35);
47
48 /* Semantic colors */
49 --wisp-code-bg: oklch(0.95 0.008 35);
50 --wisp-success: oklch(0.65 0.20 145);
51 --wisp-danger: oklch(0.60 0.20 25);
52 --wisp-warning: oklch(0.70 0.15 85);
53 --wisp-info: oklch(0.60 0.15 240);
54
55 /* Layout */
56 --wisp-max-width: 900px;
57 --wisp-header-max-width: 1100px;
58
59 /* Typography */
60 --wisp-font-family: "JetBrains Mono", ui-monospace, monospace;
61 --wisp-line-height: 1.6;
62
63 /* Spacing scale */
64 --wisp-space-1: 0.25rem;
65 --wisp-space-2: 0.5rem;
66 --wisp-space-3: 1rem;
67 --wisp-space-4: 1.5rem;
68 --wisp-space-5: 2rem;
69 --wisp-space-6: 3rem;
70
71 /* Border radius */
72 --wisp-radius-sm: 0.25rem;
73 --wisp-radius: 0.375rem;
74 --wisp-radius-lg: 0.5rem;
75
76 /* Backward-compatible aliases (unprefixed) */
77 --bg: var(--wisp-bg);
78 --bg-alt: var(--wisp-bg-alt);
79 --text: var(--wisp-text);
80 --text-muted: var(--wisp-text-muted);
81 --text-subtle: var(--wisp-text-subtle);
82 --border: var(--wisp-border);
83 --border-light: var(--wisp-border-light);
84 --accent: var(--wisp-accent);
85 --accent-muted: var(--wisp-accent-muted);
86 --cta-bg: var(--wisp-cta-bg);
87 --cta-text: var(--wisp-cta-text);
88 --code-bg: var(--wisp-code-bg);
89 --success: var(--wisp-success);
90 --red: var(--wisp-danger);
91 --yellow: var(--wisp-warning);
92 --blue: var(--wisp-info);
93}
94
95@media (prefers-color-scheme: dark) {
96 :root:not([data-theme="light"]) {
97 --wisp-bg: oklch(0.23 0.015 285);
98 --wisp-bg-alt: oklch(0.20 0.015 285);
99 --wisp-text: oklch(0.90 0.005 285);
100 --wisp-text-muted: oklch(0.72 0.01 285);
101 --wisp-text-subtle: oklch(0.55 0.01 285);
102 --wisp-border: oklch(0.90 0.005 285);
103 --wisp-border-light: oklch(0.38 0.02 285);
104 --wisp-accent: oklch(0.85 0.08 5);
105 --wisp-accent-muted: oklch(0.70 0.10 295);
106 --wisp-cta-bg: oklch(0.70 0.10 295);
107 --wisp-cta-text: oklch(0.23 0.015 285);
108 --wisp-code-bg: oklch(0.28 0.015 285);
109 --wisp-success: oklch(0.65 0.20 145);
110 --wisp-danger: oklch(0.65 0.20 25);
111 --wisp-warning: oklch(0.75 0.15 85);
112 --wisp-info: oklch(0.65 0.18 240);
113
114 /* Backward-compatible aliases */
115 --bg: var(--wisp-bg);
116 --bg-alt: var(--wisp-bg-alt);
117 --text: var(--wisp-text);
118 --text-muted: var(--wisp-text-muted);
119 --text-subtle: var(--wisp-text-subtle);
120 --border: var(--wisp-border);
121 --border-light: var(--wisp-border-light);
122 --accent: var(--wisp-accent);
123 --accent-muted: var(--wisp-accent-muted);
124 --cta-bg: var(--wisp-cta-bg);
125 --cta-text: var(--wisp-cta-text);
126 --code-bg: var(--wisp-code-bg);
127 --success: var(--wisp-success);
128 --red: var(--wisp-danger);
129 --yellow: var(--wisp-warning);
130 --blue: var(--wisp-info);
131 }
132}
133
134/* Manual dark theme override */
135:root[data-theme="dark"] {
136 --wisp-bg: oklch(0.23 0.015 285);
137 --wisp-bg-alt: oklch(0.20 0.015 285);
138 --wisp-text: oklch(0.90 0.005 285);
139 --wisp-text-muted: oklch(0.72 0.01 285);
140 --wisp-text-subtle: oklch(0.55 0.01 285);
141 --wisp-border: oklch(0.90 0.005 285);
142 --wisp-border-light: oklch(0.38 0.02 285);
143 --wisp-accent: oklch(0.85 0.08 5);
144 --wisp-accent-muted: oklch(0.70 0.10 295);
145 --wisp-cta-bg: oklch(0.70 0.10 295);
146 --wisp-cta-text: oklch(0.23 0.015 285);
147 --wisp-code-bg: oklch(0.28 0.015 285);
148 --wisp-success: oklch(0.65 0.20 145);
149 --wisp-danger: oklch(0.65 0.20 25);
150 --wisp-warning: oklch(0.75 0.15 85);
151 --wisp-info: oklch(0.65 0.18 240);
152
153 /* Backward-compatible aliases */
154 --bg: var(--wisp-bg);
155 --bg-alt: var(--wisp-bg-alt);
156 --text: var(--wisp-text);
157 --text-muted: var(--wisp-text-muted);
158 --text-subtle: var(--wisp-text-subtle);
159 --border: var(--wisp-border);
160 --border-light: var(--wisp-border-light);
161 --accent: var(--wisp-accent);
162 --accent-muted: var(--wisp-accent-muted);
163 --cta-bg: var(--wisp-cta-bg);
164 --cta-text: var(--wisp-cta-text);
165 --code-bg: var(--wisp-code-bg);
166 --success: var(--wisp-success);
167 --red: var(--wisp-danger);
168 --yellow: var(--wisp-warning);
169 --blue: var(--wisp-info);
170}
171
172/* ==========================================================================
173 Base / Reset
174 ========================================================================== */
175
176*, *::before, *::after {
177 margin: 0;
178 padding: 0;
179 box-sizing: border-box;
180}
181
182html {
183 scroll-behavior: smooth;
184 -webkit-text-size-adjust: 100%;
185}
186
187body {
188 font-family: var(--wisp-font-family);
189 background: var(--wisp-bg);
190 color: var(--wisp-text);
191 min-height: 100vh;
192 display: flex;
193 flex-direction: column;
194 line-height: var(--wisp-line-height);
195}
196
197/* ==========================================================================
198 Typography
199 ========================================================================== */
200
201h1, h2, h3, h4, h5, h6 {
202 color: var(--wisp-text);
203 font-weight: 700;
204 line-height: 1.2;
205}
206
207h1 {
208 font-size: clamp(2rem, 5vw, 2.5rem);
209 margin-bottom: var(--wisp-space-4);
210 letter-spacing: -0.03em;
211}
212
213h2 {
214 font-size: 1.875rem;
215 margin-bottom: var(--wisp-space-4);
216 letter-spacing: -0.02em;
217}
218
219h3 {
220 font-size: 1.5rem;
221 font-weight: 600;
222 margin-bottom: var(--wisp-space-3);
223}
224
225h4 {
226 font-size: 1.25rem;
227 font-weight: 600;
228 margin-bottom: var(--wisp-space-2);
229}
230
231p {
232 color: var(--wisp-text-muted);
233 margin-bottom: var(--wisp-space-3);
234 line-height: 1.7;
235}
236
237strong, b {
238 color: var(--wisp-text);
239 font-weight: 600;
240}
241
242small {
243 font-size: 0.875rem;
244 color: var(--wisp-text-muted);
245}
246
247a {
248 color: var(--wisp-accent);
249 text-decoration: none;
250 transition: opacity 0.15s;
251}
252
253a:hover {
254 opacity: 0.8;
255}
256
257code {
258 font-family: var(--wisp-font-family);
259 background: var(--wisp-code-bg);
260 padding: 0.125rem 0.375rem;
261 border-radius: var(--wisp-radius-sm);
262 font-size: 0.875em;
263}
264
265pre {
266 background: var(--wisp-code-bg);
267 padding: var(--wisp-space-3);
268 border-radius: var(--wisp-radius);
269 overflow-x: auto;
270 margin-bottom: var(--wisp-space-3);
271}
272
273pre code {
274 background: none;
275 padding: 0;
276}
277
278/* ==========================================================================
279 Layout
280 ========================================================================== */
281
282.container {
283 max-width: var(--wisp-max-width);
284 margin: 0 auto;
285 padding: var(--wisp-space-6) var(--wisp-space-3);
286}
287
288.container-wide {
289 max-width: var(--wisp-header-max-width);
290 margin: 0 auto;
291 padding: var(--wisp-space-6) var(--wisp-space-3);
292}
293
294/* ==========================================================================
295 Header
296 ========================================================================== */
297
298header {
299 position: sticky;
300 top: 0;
301 background: var(--wisp-bg);
302 border-bottom: 1px solid var(--wisp-border-light);
303 padding: var(--wisp-space-3) var(--wisp-space-5);
304 z-index: 100;
305}
306
307.header-inner {
308 max-width: var(--wisp-header-max-width);
309 margin: 0 auto;
310 display: flex;
311 justify-content: space-between;
312 align-items: center;
313}
314
315.logo {
316 font-weight: 700;
317 font-size: 1.125rem;
318 text-decoration: none;
319 color: var(--wisp-text);
320 letter-spacing: -0.02em;
321 display: flex;
322 align-items: center;
323 gap: var(--wisp-space-2);
324}
325
326.logo:hover {
327 opacity: 1;
328}
329
330.logo img {
331 width: 2rem;
332 height: 2rem;
333}
334
335nav {
336 display: flex;
337 gap: var(--wisp-space-5);
338 align-items: center;
339}
340
341nav a {
342 color: var(--wisp-text-muted);
343 font-size: 1rem;
344 transition: color 0.15s;
345}
346
347nav a:hover {
348 color: var(--wisp-text);
349 opacity: 1;
350}
351
352/* ==========================================================================
353 Buttons
354 ========================================================================== */
355
356button, .btn {
357 display: inline-flex;
358 align-items: center;
359 justify-content: center;
360 gap: var(--wisp-space-2);
361 padding: var(--wisp-space-2) var(--wisp-space-3);
362 background: var(--wisp-cta-bg);
363 color: var(--wisp-cta-text);
364 border: none;
365 border-radius: var(--wisp-radius);
366 font-weight: 600;
367 font-size: 0.875rem;
368 font-family: var(--wisp-font-family);
369 cursor: pointer;
370 transition: opacity 0.15s;
371 text-decoration: none;
372}
373
374button:hover, .btn:hover {
375 opacity: 0.9;
376}
377
378button:disabled, .btn:disabled {
379 opacity: 0.5;
380 cursor: not-allowed;
381}
382
383button.outline, .btn.outline {
384 background: transparent;
385 color: var(--wisp-text);
386 border: 1px solid var(--wisp-border-light);
387}
388
389button.outline:hover, .btn.outline:hover {
390 background: var(--wisp-bg-alt);
391 opacity: 1;
392}
393
394.btn-lg {
395 padding: var(--wisp-space-3) var(--wisp-space-5);
396 font-size: 1rem;
397}
398
399.cta-primary {
400 background: var(--wisp-cta-bg);
401 color: var(--wisp-cta-text);
402 padding: var(--wisp-space-3) var(--wisp-space-5);
403 border: 2px solid var(--wisp-border);
404 font-weight: 600;
405 font-size: 1rem;
406 text-decoration: none;
407 text-transform: uppercase;
408 letter-spacing: 0.05em;
409 transition: all 0.15s;
410}
411
412.cta-primary:hover {
413 background: var(--wisp-bg);
414 color: var(--wisp-text);
415 opacity: 1;
416}
417
418.cta-secondary {
419 background: transparent;
420 color: var(--wisp-text);
421 padding: var(--wisp-space-3) var(--wisp-space-5);
422 border: 2px solid var(--wisp-border);
423 font-weight: 600;
424 font-size: 1rem;
425 text-decoration: none;
426 text-transform: uppercase;
427 letter-spacing: 0.05em;
428 transition: all 0.15s;
429}
430
431.cta-secondary:hover {
432 background: var(--wisp-cta-bg);
433 color: var(--wisp-cta-text);
434 opacity: 1;
435}
436
437.nav-cta {
438 background: var(--wisp-cta-bg);
439 color: var(--wisp-cta-text);
440 padding: var(--wisp-space-2) var(--wisp-space-3);
441 border: 1px solid var(--wisp-border);
442 font-weight: 600;
443 font-size: 0.875rem;
444 text-transform: uppercase;
445 letter-spacing: 0.05em;
446 transition: all 0.15s;
447}
448
449.nav-cta:hover {
450 background: var(--wisp-bg);
451 color: var(--wisp-text);
452 opacity: 1;
453}
454
455/* ==========================================================================
456 Forms
457 ========================================================================== */
458
459label {
460 display: block;
461 margin-bottom: var(--wisp-space-2);
462 font-size: 0.875rem;
463 font-weight: 500;
464 color: var(--wisp-text);
465}
466
467input, textarea, select {
468 width: 100%;
469 padding: var(--wisp-space-2) 0.75rem;
470 background: var(--wisp-bg);
471 border: 1px solid var(--wisp-border-light);
472 border-radius: var(--wisp-radius);
473 color: var(--wisp-text);
474 font-size: 0.875rem;
475 font-family: var(--wisp-font-family);
476}
477
478input:focus, textarea:focus, select:focus {
479 outline: 2px solid var(--wisp-accent);
480 outline-offset: 2px;
481}
482
483input::placeholder, textarea::placeholder {
484 color: var(--wisp-text-subtle);
485}
486
487/* ==========================================================================
488 Cards
489 ========================================================================== */
490
491.card {
492 background: var(--wisp-bg-alt);
493 border: 1px solid var(--wisp-border-light);
494 border-radius: var(--wisp-radius-lg);
495 padding: var(--wisp-space-4);
496 margin-bottom: var(--wisp-space-3);
497}
498
499.card.success {
500 background: color-mix(in oklch, var(--wisp-success) 5%, var(--wisp-bg-alt));
501 border-color: color-mix(in oklch, var(--wisp-success) 20%, transparent);
502}
503
504.card.danger {
505 background: color-mix(in oklch, var(--wisp-danger) 5%, var(--wisp-bg-alt));
506 border-color: color-mix(in oklch, var(--wisp-danger) 30%, transparent);
507 border-width: 2px;
508}
509
510.card.warning {
511 background: color-mix(in oklch, var(--wisp-warning) 5%, var(--wisp-bg-alt));
512 border-color: color-mix(in oklch, var(--wisp-warning) 20%, transparent);
513}
514
515.card.info {
516 background: color-mix(in oklch, var(--wisp-info) 5%, var(--wisp-bg-alt));
517 border-color: color-mix(in oklch, var(--wisp-info) 20%, transparent);
518}
519
520.card.thick {
521 border-width: 2px;
522}
523
524.card-flex {
525 display: flex;
526 gap: var(--wisp-space-3);
527 align-items: start;
528}
529
530.card-icon {
531 flex-shrink: 0;
532 width: 2rem;
533 height: 2rem;
534}
535
536/* ==========================================================================
537 Alerts
538 ========================================================================== */
539
540.alert {
541 padding: var(--wisp-space-3);
542 border-radius: var(--wisp-radius-lg);
543 margin-bottom: var(--wisp-space-3);
544}
545
546.alert-success {
547 background: var(--wisp-code-bg);
548 border: 1px solid var(--wisp-border-light);
549 color: var(--wisp-success);
550}
551
552.alert-info {
553 background: var(--wisp-code-bg);
554 color: var(--wisp-text-muted);
555}
556
557.alert-warning {
558 background: var(--wisp-code-bg);
559 border-left: 4px solid var(--wisp-warning);
560}
561
562.alert-danger {
563 background: var(--wisp-code-bg);
564 border-left: 4px solid var(--wisp-danger);
565}
566
567/* ==========================================================================
568 Lists
569 ========================================================================== */
570
571ul, ol {
572 list-style: none;
573 margin: var(--wisp-space-3) 0;
574}
575
576ol {
577 counter-reset: item;
578}
579
580ol li {
581 counter-increment: item;
582}
583
584ol li::before {
585 content: counter(item) ".";
586 font-weight: 700;
587 color: var(--wisp-accent);
588 margin-right: 0.75rem;
589}
590
591.bullet {
592 flex-shrink: 0;
593 margin-top: 0.25rem;
594}
595
596.bullet.red, .bullet.danger { color: var(--wisp-danger); }
597.bullet.green, .bullet.success { color: var(--wisp-success); }
598.bullet.yellow, .bullet.warning { color: var(--wisp-warning); }
599.bullet.accent { color: var(--wisp-accent); }
600
601/* ==========================================================================
602 Footer
603 ========================================================================== */
604
605footer {
606 padding: var(--wisp-space-6) var(--wisp-space-5) var(--wisp-space-5);
607 border-top: 1px solid var(--wisp-border-light);
608 margin-top: auto;
609}
610
611.footer-inner {
612 max-width: var(--wisp-header-max-width);
613 margin: 0 auto;
614 display: grid;
615 grid-template-columns: 2fr repeat(3, 1fr);
616 gap: var(--wisp-space-6);
617}
618
619.footer-brand p:first-child {
620 font-weight: 700;
621 margin-bottom: 0.75rem;
622}
623
624.footer-brand p:last-child {
625 color: var(--wisp-text-muted);
626 line-height: 1.6;
627}
628
629.footer-col h4 {
630 font-size: 0.875rem;
631 color: var(--wisp-text-subtle);
632 text-transform: uppercase;
633 letter-spacing: 0.05em;
634 margin-bottom: var(--wisp-space-3);
635}
636
637.footer-col ul {
638 margin: 0;
639}
640
641.footer-col li {
642 margin-bottom: var(--wisp-space-2);
643}
644
645.footer-col a {
646 color: var(--wisp-text-muted);
647 transition: color 0.15s;
648}
649
650.footer-col a:hover {
651 color: var(--wisp-text);
652 opacity: 1;
653}
654
655.footer-bottom {
656 max-width: var(--wisp-header-max-width);
657 margin: var(--wisp-space-6) auto 0;
658 padding-top: var(--wisp-space-5);
659 border-top: 1px solid var(--wisp-border-light);
660 display: flex;
661 justify-content: space-between;
662 align-items: center;
663}
664
665.footer-bottom p {
666 color: var(--wisp-text-subtle);
667 font-size: 0.875rem;
668}
669
670.footer-bottom nav {
671 gap: var(--wisp-space-4);
672}
673
674.footer-bottom a {
675 color: var(--wisp-text-subtle);
676 font-size: 0.875rem;
677}
678
679.footer-bottom a:hover {
680 color: var(--wisp-text);
681 opacity: 1;
682}
683
684footer.simple {
685 background: var(--wisp-bg-alt);
686 padding: var(--wisp-space-5) var(--wisp-space-3);
687 text-align: center;
688 font-size: 0.875rem;
689 color: var(--wisp-text-muted);
690}
691
692footer.simple p {
693 margin-bottom: var(--wisp-space-2);
694}
695
696/* ==========================================================================
697 Spinner
698 ========================================================================== */
699
700.spinner {
701 display: inline-block;
702 width: 1rem;
703 height: 1rem;
704 border: 2px solid var(--wisp-border-light);
705 border-top-color: var(--wisp-accent);
706 border-radius: 50%;
707 animation: wisp-spin 0.6s linear infinite;
708}
709
710.spinner-lg {
711 width: 2rem;
712 height: 2rem;
713 border-width: 3px;
714}
715
716@keyframes wisp-spin {
717 to { transform: rotate(360deg); }
718}
719
720/* ==========================================================================
721 Utility Classes
722 ========================================================================== */
723
724/* Display */
725.hidden { display: none; }
726.block { display: block; }
727.inline { display: inline; }
728.inline-block { display: inline-block; }
729.flex { display: flex; }
730.inline-flex { display: inline-flex; }
731.grid { display: grid; }
732
733/* Flexbox */
734.flex-col { flex-direction: column; }
735.flex-wrap { flex-wrap: wrap; }
736.items-start { align-items: flex-start; }
737.items-center { align-items: center; }
738.items-end { align-items: flex-end; }
739.justify-start { justify-content: flex-start; }
740.justify-center { justify-content: center; }
741.justify-end { justify-content: flex-end; }
742.justify-between { justify-content: space-between; }
743
744/* Gap */
745.gap-1 { gap: var(--wisp-space-1); }
746.gap-2 { gap: var(--wisp-space-2); }
747.gap-3 { gap: var(--wisp-space-3); }
748.gap-4 { gap: var(--wisp-space-4); }
749.gap-5 { gap: var(--wisp-space-5); }
750.gap-6 { gap: var(--wisp-space-6); }
751
752/* Margin */
753.m-0 { margin: 0; }
754.m-1 { margin: var(--wisp-space-1); }
755.m-2 { margin: var(--wisp-space-2); }
756.m-3 { margin: var(--wisp-space-3); }
757.m-4 { margin: var(--wisp-space-4); }
758
759.mt-0 { margin-top: 0; }
760.mt-1 { margin-top: var(--wisp-space-1); }
761.mt-2 { margin-top: var(--wisp-space-2); }
762.mt-3 { margin-top: var(--wisp-space-3); }
763.mt-4 { margin-top: var(--wisp-space-4); }
764.mt-5 { margin-top: var(--wisp-space-5); }
765.mt-6 { margin-top: var(--wisp-space-6); }
766
767.mb-0 { margin-bottom: 0; }
768.mb-1 { margin-bottom: var(--wisp-space-1); }
769.mb-2 { margin-bottom: var(--wisp-space-2); }
770.mb-3 { margin-bottom: var(--wisp-space-3); }
771.mb-4 { margin-bottom: var(--wisp-space-4); }
772.mb-5 { margin-bottom: var(--wisp-space-5); }
773.mb-6 { margin-bottom: var(--wisp-space-6); }
774
775.ml-0 { margin-left: 0; }
776.ml-1 { margin-left: var(--wisp-space-1); }
777.ml-2 { margin-left: var(--wisp-space-2); }
778.ml-3 { margin-left: var(--wisp-space-3); }
779.ml-4 { margin-left: var(--wisp-space-4); }
780
781.mr-0 { margin-right: 0; }
782.mr-1 { margin-right: var(--wisp-space-1); }
783.mr-2 { margin-right: var(--wisp-space-2); }
784.mr-3 { margin-right: var(--wisp-space-3); }
785.mr-4 { margin-right: var(--wisp-space-4); }
786
787/* Padding */
788.p-0 { padding: 0; }
789.p-1 { padding: var(--wisp-space-1); }
790.p-2 { padding: var(--wisp-space-2); }
791.p-3 { padding: var(--wisp-space-3); }
792.p-4 { padding: var(--wisp-space-4); }
793.p-5 { padding: var(--wisp-space-5); }
794.p-6 { padding: var(--wisp-space-6); }
795
796.px-1 { padding-left: var(--wisp-space-1); padding-right: var(--wisp-space-1); }
797.px-2 { padding-left: var(--wisp-space-2); padding-right: var(--wisp-space-2); }
798.px-3 { padding-left: var(--wisp-space-3); padding-right: var(--wisp-space-3); }
799.px-4 { padding-left: var(--wisp-space-4); padding-right: var(--wisp-space-4); }
800
801.py-1 { padding-top: var(--wisp-space-1); padding-bottom: var(--wisp-space-1); }
802.py-2 { padding-top: var(--wisp-space-2); padding-bottom: var(--wisp-space-2); }
803.py-3 { padding-top: var(--wisp-space-3); padding-bottom: var(--wisp-space-3); }
804.py-4 { padding-top: var(--wisp-space-4); padding-bottom: var(--wisp-space-4); }
805
806/* Width */
807.w-full { width: 100%; }
808.w-auto { width: auto; }
809.max-w-sm { max-width: 24rem; }
810.max-w-md { max-width: 28rem; }
811.max-w-lg { max-width: 32rem; }
812.max-w-xl { max-width: 36rem; }
813
814/* Text */
815.text-left { text-align: left; }
816.text-center { text-align: center; }
817.text-right { text-align: right; }
818
819.text-sm { font-size: 0.875rem; }
820.text-base { font-size: 1rem; }
821.text-lg { font-size: 1.125rem; }
822.text-xl { font-size: 1.25rem; }
823
824.font-normal { font-weight: 400; }
825.font-medium { font-weight: 500; }
826.font-semibold { font-weight: 600; }
827.font-bold { font-weight: 700; }
828
829.text-muted { color: var(--wisp-text-muted); }
830.text-subtle { color: var(--wisp-text-subtle); }
831.text-accent { color: var(--wisp-accent); }
832.text-success { color: var(--wisp-success); }
833.text-danger { color: var(--wisp-danger); }
834.text-warning { color: var(--wisp-warning); }
835.text-info { color: var(--wisp-info); }
836
837/* Background */
838.bg-alt { background: var(--wisp-bg-alt); }
839.bg-code { background: var(--wisp-code-bg); }
840
841/* Border */
842.border { border: 1px solid var(--wisp-border-light); }
843.border-2 { border: 2px solid var(--wisp-border-light); }
844.rounded { border-radius: var(--wisp-radius); }
845.rounded-lg { border-radius: var(--wisp-radius-lg); }
846
847/* Other */
848.cursor-pointer { cursor: pointer; }
849.select-none { user-select: none; }
850.truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
851
852/* ==========================================================================
853 Responsive
854 ========================================================================== */
855
856@media (max-width: 768px) {
857 nav a:not(.nav-cta) {
858 display: none;
859 }
860
861 .footer-inner {
862 grid-template-columns: 1fr 1fr;
863 }
864
865 .footer-brand {
866 grid-column: span 2;
867 }
868
869 .footer-bottom {
870 flex-direction: column;
871 gap: var(--wisp-space-3);
872 text-align: center;
873 }
874
875 h1 { font-size: 2rem; }
876 h2 { font-size: 1.5rem; }
877 h3 { font-size: 1.25rem; }
878
879 .hide-mobile { display: none; }
880}
881
882@media (max-width: 480px) {
883 .footer-inner {
884 grid-template-columns: 1fr;
885 }
886
887 .footer-brand {
888 grid-column: span 1;
889 }
890
891 .hide-sm { display: none; }
892}
893
894@media (min-width: 769px) {
895 .hide-desktop { display: none; }
896}