1@import "./catppuccin.css";
2@import "./base.css";
3
4/* styles */
5.navigation-bar {
6 position: sticky;
7 top: 0;
8 left: 0;
9 width: 100%;
10 z-index: 1000;
11
12 background-color: hsla(var(--mantle) / 0.8);
13 backdrop-filter: blur(1rem);
14 border-bottom: 2px solid hsla(var(--surface0) / 0.5);
15
16 .navigation-bar__inner {
17 display: flex;
18 align-items: flex-end;
19 justify-content: space-between;
20 gap: 0.5rem;
21 padding: 0.5rem 1rem;
22
23 max-width: 768px;
24 margin: 0 auto;
25 width: 100%;
26 }
27
28 .navigation-bar__brand {
29 display: flex;
30 align-items: flex-end;
31 gap: 0.5rem;
32 color: inherit;
33 text-decoration: none;
34 border-radius: 0.5rem; /* for the outline */
35
36 .navigation-bar__icon {
37 width: 2.25rem;
38 height: 2.25rem;
39 background-color: hsla(var(--surface0) / 1);
40 border-radius: 0.5rem;
41 overflow: hidden;
42
43 img {
44 width: 100%;
45 height: 100%;
46 object-fit: cover;
47 }
48 }
49
50 .navigation-bar__title {
51 font-size: 1.25rem;
52 font-weight: 600;
53 color: hsl(var(--text));
54 }
55 }
56
57 .navigation-bar__nav {
58 display: flex;
59 gap: 0.75rem;
60
61 a {
62 position: relative;
63 border-bottom: 2px solid transparent;
64 text-decoration: none;
65 color: hsl(var(--subtext0));
66 border-radius: 0.2rem;
67 padding: 0 0.25rem;
68
69 &::before {
70 content: "";
71 position: absolute;
72 bottom: -2px;
73 left: 0;
74 width: 100%;
75 height: 2px;
76 opacity: 0;
77 background-color: hsl(var(--blue));
78 transform: scaleX(0);
79 border-radius: 0.25rem;
80 transition:
81 background-color var(--transition),
82 opacity var(--transition),
83 transform var(--transition);
84 }
85
86 &.active {
87 color: hsl(var(--text));
88 &::before {
89 transform: scaleX(1);
90 opacity: 1;
91 background-color: hsl(var(--flamingo));
92 }
93 }
94
95 &:hover,
96 &:focus {
97 color: hsl(var(--text));
98 &::before {
99 transform: scaleX(1);
100 opacity: 1;
101 background-color: hsl(var(--blue));
102 }
103 }
104 }
105 }
106}
107
108/* */
109.layout {
110 min-height: 100vh;
111 display: flex;
112 flex-direction: column;
113}
114
115.main-content {
116 flex: 1;
117 max-width: 768px;
118 margin: 0 auto;
119 width: 100%;
120 padding: 2rem 1rem;
121
122 .page {
123 width: 100%;
124
125 .page-header {
126 position: relative;
127 display: flex;
128 flex-direction: column;
129 margin-bottom: 2rem;
130 padding: 0.75rem;
131
132 border-radius: 0.5rem;
133 border: 2px solid hsla(var(--surface0) / 1);
134 overflow: hidden;
135
136 /*
137 stupid hack.
138 if i had the background on the page-header directly, on some zoom levels
139 there'd be a small gap at the bottom, showing the page background.
140 */
141 &::before {
142 content: "";
143 position: absolute;
144 top: 0;
145 left: 0;
146 width: 100%;
147 height: 100%;
148 background: linear-gradient(
149 to top,
150 hsla(var(--surface0) / 1) 0%,
151 hsla(var(--surface0) / 0) 100%
152 );
153 z-index: -1;
154 transition: background-color var(--transition);
155 }
156
157 .page-title {
158 font-size: 2rem;
159 font-weight: 700;
160 color: hsl(var(--text));
161 margin-bottom: 0.5rem;
162 }
163
164 .page-subtitle {
165 font-size: 1rem;
166 color: hsl(var(--subtext0));
167 margin: 0;
168 }
169
170 .page-cta {
171 margin-top: 1rem;
172 display: flex;
173 gap: 0.5rem;
174
175 .button__pill:hover,
176 .button__pill:focus {
177 background-color: hsla(var(--blue) / 1);
178 color: hsl(var(--crust));
179 }
180
181 .button__pill:active {
182 background-color: hsla(var(--blue) / 0.8);
183 }
184 }
185 }
186
187 section {
188 margin-bottom: 2rem;
189 padding: 1rem;
190 border-radius: 0.5rem;
191 background-color: hsla(var(--surface0) / 0.25);
192
193 h2 {
194 font-size: 1.5rem;
195 font-weight: 700;
196 color: hsl(var(--text));
197 margin-bottom: 0.5rem;
198 }
199 }
200
201 p {
202 line-height: 1.6;
203 color: hsl(var(--subtext0));
204 &:not(:last-child) {
205 margin-bottom: 1rem;
206 }
207 }
208
209 nav {
210 display: flex;
211 gap: 1rem;
212 margin-top: 2rem;
213 }
214
215 nav a {
216 padding: 0.5rem 1rem;
217 background-color: hsl(var(--surface0));
218 border-radius: 0.375rem;
219 text-decoration: none;
220 color: hsl(var(--text));
221 transition: background-color var(--transition);
222 }
223
224 nav a:hover {
225 background-color: hsl(var(--surface1));
226 }
227 }
228}
229/* */
230
231.error {
232 h1 {
233 color: hsl(var(--red));
234 font-size: 2rem;
235 margin-bottom: 1rem;
236 }
237
238 p {
239 color: hsl(var(--subtext0));
240 margin-bottom: 2rem;
241 }
242
243 .error__actions {
244 display: flex;
245 gap: 0.25rem;
246 }
247}
248
249.button__pill {
250 display: inline-block;
251 border-radius: 5rem;
252 border: 1px solid transparent;
253 color: hsl(var(--subtext0));
254 text-decoration: none;
255 background-color: hsl(var(--surface0));
256 padding: 0.5rem 1rem;
257
258 &:hover,
259 &:focus {
260 color: hsl(var(--text));
261 background-color: hsl(var(--surface1));
262 }
263 &:active {
264 border-color: hsl(var(--surface2));
265 background-color: hsla(var(--surface1) / 0.8);
266 }
267}
268
269footer {
270 background-color: hsl(var(--crust));
271 padding: 1rem;
272 max-width: 768px;
273 border-radius: 1rem;
274 margin: 1rem auto;
275 width: calc(100% - 2rem);
276
277 display: grid;
278 grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
279
280 gap: 1rem;
281 grid-gap: 1rem;
282
283 .footer__column {
284 display: flex;
285 flex-direction: column;
286 gap: 0.5rem;
287
288 h2 {
289 font-size: 1.75rem;
290 font-weight: 900;
291 color: hsl(var(--pink));
292 }
293 h3 {
294 font-size: 1.25rem;
295 font-weight: 600;
296 color: hsl(var(--subtext1));
297 }
298 p,
299 a {
300 font-size: 0.75rem;
301 font-weight: 400;
302 color: hsl(var(--subtext0));
303 }
304 a {
305 color: hsl(var(--blue));
306 text-decoration: none;
307 }
308 }
309
310 .footer__column-links {
311 display: flex;
312 flex-direction: column;
313
314 ul {
315 list-style: none;
316 padding: 0;
317 margin: 0;
318 display: flex;
319 flex-direction: column;
320
321 border: 2px solid hsl(var(--surface0));
322 border-radius: 0.5rem;
323 overflow: hidden;
324
325 li {
326 font-size: 1rem;
327 font-weight: 400;
328 padding: 0;
329 width: 100%;
330
331 &:not(:last-child) {
332 border-bottom: 2px solid hsl(var(--surface0));
333 }
334
335 .footer__link {
336 width: 100%;
337 display: flex;
338 flex-direction: column;
339 padding: 0.5rem 0.5rem;
340 outline-offset: -2px;
341
342 &:hover,
343 &:focus {
344 background-color: hsla(var(--blue) / 0.05);
345 }
346
347 .footer__link-container {
348 display: flex;
349 align-items: center;
350 }
351
352 .hint {
353 color: hsl(var(--subtext0));
354 font-size: 0.7rem;
355 }
356 }
357
358 &:last-child .footer__link {
359 border-radius: 0 0 0.5rem 0.5rem;
360 }
361 &:first-child .footer__link {
362 border-radius: 0.5rem 0.5rem 0 0;
363 }
364 }
365
366 &:focus-within,
367 &:hover {
368 a:not(:focus-visible):not(:hover) {
369 filter: brightness(0.85);
370 }
371 }
372 }
373 }
374}
375
376.projects-page {
377 --card-radius: 1rem;
378
379 .projects-header {
380 margin-bottom: 1.5rem;
381
382 h1 {
383 margin-bottom: 0.25rem;
384 }
385 .projects-subtitle {
386 font-size: 0.9rem;
387 color: hsl(var(--subtext0));
388 margin: 0;
389 }
390 }
391
392 .projects {
393 display: grid;
394 gap: 0.5rem;
395 grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
396 }
397
398 .project {
399 position: relative;
400 display: flex;
401 flex-direction: column;
402 gap: 0.5rem;
403 border: 1px solid hsla(var(--accent) / 0.1);
404 background: hsla(var(--surface0) / 1);
405 border-radius: var(--card-radius);
406 padding: 0.5rem;
407 overflow: hidden;
408
409 --accent: var(--blue);
410 &[data-accent-lang="typescript"] {
411 --accent: var(--blue);
412 }
413 &[data-accent-lang="rust"] {
414 --accent: var(--peach);
415 }
416 &[data-accent-lang="nix"] {
417 --accent: var(--sapphire);
418 }
419 &[data-accent-lang="bash"] {
420 --accent: var(--green);
421 }
422 &[data-accent-lang="css"] {
423 --accent: var(--pink);
424 }
425
426 &:hover,
427 &:focus-within {
428 background: hsla(var(--surface0) / 0.75);
429 border-color: hsla(var(--accent) / 0.2);
430 }
431
432 .project__header {
433 display: flex;
434 gap: 0.5rem;
435 align-items: center;
436
437 .project__avatar {
438 height: 100%;
439 aspect-ratio: 1;
440 border-radius: 0.5rem;
441 background: hsla(var(--accent) / 1);
442
443 display: flex;
444 align-items: center;
445 justify-content: center;
446
447 font-weight: 700;
448 font-size: 1rem;
449 color: hsl(var(--crust));
450 user-select: none;
451 }
452
453 .project__title-block {
454 display: flex;
455 flex-direction: column;
456 gap: 0.15rem;
457
458 h2 {
459 font-size: 1.05rem;
460 font-weight: 700;
461 margin: 0;
462 line-height: 1.2;
463 color: hsl(var(--text));
464 }
465 .project__meta {
466 display: flex;
467 gap: 0.4rem;
468 flex-wrap: wrap;
469
470 .meta-item {
471 background: hsl(var(--surface0));
472 color: hsl(var(--subtext1));
473 }
474
475 .status {
476 &.status--active {
477 background: hsla(var(--green) / 0.2);
478 color: hsl(var(--green));
479 }
480 &.status--wip {
481 background: hsla(var(--yellow) / 0.25);
482 color: hsl(var(--yellow));
483 }
484 &.status--archived {
485 background: hsla(var(--overlay0) / 0.3);
486 color: hsl(var(--overlay1));
487 }
488 }
489 }
490 }
491 }
492
493 .project__description {
494 color: hsl(var(--subtext0));
495 font-size: 0.75rem;
496 margin: 0;
497 overflow: hidden;
498 }
499
500 .project__languages {
501 list-style: none;
502 display: flex;
503 flex-wrap: wrap;
504 gap: 0.35rem;
505 padding: 0;
506
507 .language-tag {
508 --lang-bg: var(--surface1);
509 --lang-colour: var(--subtext1);
510
511 background: hsl(var(--lang-colour));
512 color: hsla(var(--crust));
513
514 &[data-lang="typescript"] {
515 --lang-colour: var(--blue);
516 }
517 &[data-lang="rust"] {
518 --lang-colour: var(--peach);
519 }
520 &[data-lang="nix"] {
521 --lang-colour: var(--sapphire);
522 }
523 &[data-lang="bash"] {
524 --lang-colour: var(--green);
525 }
526 &[data-lang="css"] {
527 --lang-colour: var(--pink);
528 }
529 }
530 }
531
532 .project__meta .meta-item,
533 .project__languages .language-tag {
534 padding: 0.15rem 0.45rem;
535 letter-spacing: 0.05em;
536 font-size: 0.5rem;
537 font-weight: 600;
538 border-radius: 1rem;
539
540 user-select: none;
541 }
542
543 .project__links {
544 margin-top: auto;
545 display: flex;
546 flex-wrap: wrap;
547 gap: 0.5rem;
548
549 .project-link {
550 display: flex;
551
552 align-items: center;
553 text-decoration: none;
554 font-size: 0.75rem;
555 font-weight: 600;
556 gap: 0.25rem;
557
558 padding: 0.25rem 0.75rem;
559 border-radius: 0.25rem;
560
561 background: hsla(var(--accent) / 0.05);
562 color: hsl(var(--text));
563 border: 1px solid hsla(var(--accent) / 0.25);
564
565 &:hover,
566 &:focus-visible {
567 background: hsla(var(--accent) / 0.2);
568 border-color: hsla(var(--accent) / 0.1);
569 }
570 &:active {
571 background: hsla(var(--accent) / 0.1);
572 border-color: hsla(var(--accent) / 0.2);
573 }
574 }
575 }
576 }
577}
578
579.theme-picker {
580 display: flex;
581 flex-direction: column;
582 gap: 0.5rem;
583}
584
585.dropdown {
586 display: flex;
587 flex-direction: column;
588 gap: 0.15rem;
589
590 .dropdown__label {
591 font-size: 0.75rem;
592 font-weight: 600;
593 }
594
595 .dropdown__select {
596 color: hsl(var(--subtext0));
597 border: 2px solid hsl(var(--surface0));
598 background-color: transparent;
599
600 border-radius: 0.5rem;
601 padding: 0.5rem;
602 font-size: 0.75rem;
603 }
604}
605
606.checkbox-container {
607 display: flex;
608 flex-direction: row;
609
610 color: hsl(var(--subtext0));
611 border: 2px solid hsl(var(--surface0));
612 background-color: transparent;
613
614 border-radius: 0.5rem;
615 font-size: 0.75rem;
616 justify-content: space-apart;
617 overflow: hidden;
618
619 .checkbox-label {
620 padding: 0.5rem 0.25rem 0.5rem 0.5rem;
621 flex: 1;
622 }
623
624 .checkbox {
625 position: relative;
626 height: calc(100% - 0.4rem);
627 aspect-ratio: 1;
628 appearance: none;
629
630 background-color: hsl(var(--surface0));
631 border-radius: 0.25rem;
632 margin: 0.2rem;
633 cursor: pointer;
634 outline-offset: 2px;
635
636 &::after {
637 content: "✓";
638 position: absolute;
639 top: 50%;
640 left: 50%;
641 color: hsl(var(--crust));
642 opacity: 0;
643 font-size: 1.25rem;
644 font-weight: 700;
645 transform: translate(-50%, -50%) scale(0.8);
646 }
647
648 &:hover,
649 &:focus-visible {
650 background-color: hsl(var(--surface1));
651 border-color: hsl(var(--surface1));
652 }
653 &:active {
654 background-color: hsl(var(--surface2));
655 border-color: hsl(var(--surface2));
656 }
657 &:checked {
658 background-color: hsl(var(--blue));
659 border-color: hsl(var(--blue));
660 &::after {
661 opacity: 1;
662 transform: translate(-50%, -50%) scale(1);
663 }
664 &:hover,
665 &:focus-visible {
666 background-color: hsla(var(--blue) / 0.8);
667 border-color: hsl(var(--blue));
668 }
669 &:active {
670 background-color: hsla(var(--blue) / 0.6);
671 border-color: hsl(var(--blue));
672 }
673 }
674 }
675}
676
677.input-container {
678 /* display: flex; */
679 /* flex-direction: row; */
680
681 color: hsl(var(--subtext0));
682 /* border: 2px solid hsl(var(--surface0)); */
683 background-color: transparent;
684
685 border-radius: 0.5rem;
686 font-size: 0.75rem;
687 justify-content: space-apart;
688 overflow: hidden;
689
690 * {
691 outline: none;
692 }
693
694 &:hover,
695 &:focus-visible,
696 &:has(:focus-visible) {
697 background-color: hsla(var(--blue) / 0.05);
698 border-color: hsl(var(--surface1));
699 color: hsl(var(--text));
700 }
701
702 &:focus-visible,
703 &:has(:focus-visible) {
704 outline-color: hsl(var(--blue));
705 }
706}
707
708html.boxy * {
709 border-radius: 0 !important;
710}
711
712.sr-only {
713 position: absolute;
714 width: 1px;
715 height: 1px;
716 padding: 0;
717 margin: -1px;
718 overflow: hidden;
719 clip: rect(0, 0, 0, 0);
720 border: 0;
721}