summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authoraxtloss <axtlos@disroot.org>2024-08-20 01:20:30 +0200
committeraxtloss <axtlos@disroot.org>2024-08-20 01:20:30 +0200
commite235aa6cf4914cbff6c72f19e0fcf6888da349f7 (patch)
tree0d488cadc02706aa2c7652b42e4f21342125c5f7 /src
parent479414a93ae03a4463c16d54b39cd155b1e04683 (diff)
downloadwebsite-e235aa6cf4914cbff6c72f19e0fcf6888da349f7.tar.gz
website-e235aa6cf4914cbff6c72f19e0fcf6888da349f7.tar.bz2
yayyy new website!!
Diffstat (limited to 'src')
-rw-r--r--src/app.d.ts13
-rw-r--r--src/app.html18
-rw-r--r--src/lib/#decoder.ts#17
-rw-r--r--src/lib/assets/close.svg4
-rw-r--r--src/lib/assets/xmpp.svg31
-rw-r--r--src/lib/decoder.ts16
-rw-r--r--src/lib/images/github.svg16
-rw-r--r--src/lib/images/svelte-logo.svg1
-rw-r--r--src/lib/images/svelte-welcome.pngbin0 -> 360807 bytes
-rw-r--r--src/lib/images/svelte-welcome.webpbin0 -> 115470 bytes
-rw-r--r--src/lib/mobile.js4
-rw-r--r--src/lib/styles/contact.scss38
-rw-r--r--src/lib/styles/index.scss2
-rw-r--r--src/lib/styles/shadow.scss9
-rw-r--r--src/routes/+error.svelte41
-rw-r--r--src/routes/+layout.svelte31
-rw-r--r--src/routes/+page.svelte205
-rw-r--r--src/routes/+page.ts3
-rw-r--r--src/routes/ContactCard.svelte40
-rw-r--r--src/routes/Header.svelte299
-rw-r--r--src/routes/projects/+page.svelte53
-rw-r--r--src/routes/projects/+page.ts9
-rw-r--r--src/routes/projects/ProjectEntry.svelte36
-rw-r--r--src/routes/styles.scss48
24 files changed, 934 insertions, 0 deletions
diff --git a/src/app.d.ts b/src/app.d.ts
new file mode 100644
index 0000000..743f07b
--- /dev/null
+++ b/src/app.d.ts
@@ -0,0 +1,13 @@
+// See https://kit.svelte.dev/docs/types#app
+// for information about these interfaces
+declare global {
+ namespace App {
+ // interface Error {}
+ // interface Locals {}
+ // interface PageData {}
+ // interface PageState {}
+ // interface Platform {}
+ }
+}
+
+export {};
diff --git a/src/app.html b/src/app.html
new file mode 100644
index 0000000..3f56455
--- /dev/null
+++ b/src/app.html
@@ -0,0 +1,18 @@
+<!doctype html>
+<html lang="en">
+ <script>
+ var isBrave = (navigator.brave && await navigator.brave.isBrave()) || false;
+ if (isBrave) {
+ window.location.href = '/not-very-brave.html';
+ }
+ </script>
+ <head>
+ <meta charset="utf-8" />
+ <link rel="icon" href="%sveltekit.assets%/favicon.gif" />
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
+ %sveltekit.head%
+ </head>
+ <body data-sveltekit-preload-data="hover">
+ <div style="display: contents">%sveltekit.body%</div>
+ </body>
+</html>
diff --git a/src/lib/#decoder.ts# b/src/lib/#decoder.ts#
new file mode 100644
index 0000000..3e5613f
--- /dev/null
+++ b/src/lib/#decoder.ts#
@@ -0,0 +1,17 @@
+export function decode(value: string): string {
+ var offset: number = parseInt(value.substring(0,2), 16);
+ var n: number = 2;
+ var final: string = "";
+ for (inti ; n < value.length; n=n+3) {
+ var num: string = value.substring(n, n+3);
+ var charAscii: number = parseInt(num, 16)-offset;
+ final = final + String.fromCharCode(charAscii)
+ }
+ return final;
+}
+
+
+export function isDecoded(value: string): boolean {
+ var offset: number = Number(value.substring(0,2));
+ return isNaN(offset);
+}
diff --git a/src/lib/assets/close.svg b/src/lib/assets/close.svg
new file mode 100644
index 0000000..cbb7654
--- /dev/null
+++ b/src/lib/assets/close.svg
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg">
+ <path d="m 4 4 h 1 h 0.03125 c 0.253906 0.011719 0.511719 0.128906 0.6875 0.3125 l 2.28125 2.28125 l 2.3125 -2.28125 c 0.265625 -0.230469 0.445312 -0.304688 0.6875 -0.3125 h 1 v 1 c 0 0.285156 -0.035156 0.550781 -0.25 0.75 l -2.28125 2.28125 l 2.25 2.25 c 0.1875 0.1875 0.28125 0.453125 0.28125 0.71875 v 1 h -1 c -0.265625 0 -0.53125 -0.09375 -0.71875 -0.28125 l -2.28125 -2.28125 l -2.28125 2.28125 c -0.1875 0.1875 -0.453125 0.28125 -0.71875 0.28125 h -1 v -1 c 0 -0.265625 0.09375 -0.53125 0.28125 -0.71875 l 2.28125 -2.25 l -2.28125 -2.28125 c -0.210938 -0.195312 -0.304688 -0.46875 -0.28125 -0.75 z m 0 0"/>
+</svg>
diff --git a/src/lib/assets/xmpp.svg b/src/lib/assets/xmpp.svg
new file mode 100644
index 0000000..f660926
--- /dev/null
+++ b/src/lib/assets/xmpp.svg
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ viewBox="0 0 1750 1273"
+ height="1273"
+ width="1750"
+ version="1.1"
+ id="svg2">
+ <metadata
+ id="metadata8">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs6" />
+ <path
+ id="path3342"
+ d="m 445.5368,1260.3774 0.2798,-12.6227 12.5,-3.3998 c 86.3329,-23.4818 169.6413,-62.291 250.3046,-116.6045 21.6348,-14.5674 54.9023,-39.6297 54.4411,-41.0135 -0.219,-0.6568 -4.8638,-3.8543 -10.3219,-7.1055 C 643.2778,1014.4283 545.02,941.13549 450.3396,854.06369 429.6559,835.04199 380.3414,785.90449 358.9481,762.99999 180.5946,572.04763 62.054497,360.05908 18.4066,153.99998 8.7628,108.47213 2.3059,58.553447 0.6664,16.850277 L 0,-0.10203342 6.4083,2.3337566 c 3.5246,1.33968 58.833297,22.7793104 122.9083,47.6436104 166.6481,64.667773 168.944,65.464203 304.4367,105.604623 62.1152,18.40194 113.1902,33.71169 113.5,34.02166 0.3099,0.30997 0.4154,15.03845 0.2346,32.72995 -0.7292,71.3433 7.8053,140.72171 26.8373,218.16638 39.0143,158.75637 118.1187,319.92841 223.5627,455.50001 28.91491,37.1765 73.62151,88 77.40871,88 2.7547,0 26.96638,-26.2437 52.834,-57.2683 132.54379,-158.9674 227.42059,-358.08969 261.64909,-549.13496 10.0437,-56.05859 13.7745,-98.67828 13.4235,-153.34671 -0.121,-18.83748 -0.032,-34.43372 0.1968,-34.6583 0.2292,-0.22459 50.1417,-15.11502 110.9167,-33.08986 134.5925,-39.80714 140.484,-41.85315 312,-108.352043 l 123.5,-47.88249042 0.3207,7.61633002 c 0.3596,8.5370104 -1.1628,33.2485804 -3.3954,55.1163204 -3.8106,37.324233 -12.1421,84.466813 -21.8263,123.500003 -60.4804,243.77385 -227.0666,496.24088 -463.599,702.59971 -78.2752,68.2899 -161.6555,129.12491 -251.25,183.31441 -12.5125,7.5679 -22.75,14.1335 -22.75,14.5903 0,1.0394 22.9632,18.4731 41.5,31.5068 84.3957,59.3407 173.6883,101.5869 269,127.2694 l 7,1.8862 0.2799,12.6666 0.2799,12.6666 -3.2799,-6e-4 c -5.2353,-10e-4 -37.4406,-3.7921 -60.2799,-7.0959 -85.6385,-12.3881 -177.8337,-38.246 -257.5,-72.2208 -39.76812,-16.9597 -71.45999,-30.8513 -87.00005,-38.1349 -9.075,-4.2535 -17.85004,-8.1823 -19.50004,-8.7307 -2.6877,-0.8934 -5.0814,-0.039 -23,8.2132 -20.2043,9.3045 -59.60201,26.5462 -89.00001,38.9493 -95.6207,40.3427 -198.208,66.8187 -300.3568,77.5168 -7.8962,0.827 -15.6722,1.5036 -17.2799,1.5036 l -2.923,0 0.2799,-12.6226 z"
+ style="fill:#000000" />
+</svg>
diff --git a/src/lib/decoder.ts b/src/lib/decoder.ts
new file mode 100644
index 0000000..f28bbbc
--- /dev/null
+++ b/src/lib/decoder.ts
@@ -0,0 +1,16 @@
+export function decode(value: string): string {
+ var offset: number = parseInt(value.substring(0,2), 16);
+ var final: string = "";
+ for (let i = 2; i < value.length; i=i+3) {
+ var num: string = value.substring(i, i+3);
+ var charAscii: number = parseInt(num, 16)-offset;
+ final = final + String.fromCharCode(charAscii)
+ }
+ return final;
+}
+
+
+export function isDecoded(value: string): boolean {
+ var offset: number = Number(value.substring(0,2));
+ return isNaN(offset);
+}
diff --git a/src/lib/images/github.svg b/src/lib/images/github.svg
new file mode 100644
index 0000000..bc5d249
--- /dev/null
+++ b/src/lib/images/github.svg
@@ -0,0 +1,16 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="-3 -3 30 30">
+ <path
+ fill-rule="evenodd"
+ clip-rule="evenodd"
+ d="M12 2C6.47715 2 2 6.47715 2 12C2 17.5229 6.47715 22 12 22C17.5229 22 22 17.5229 22 12C22 6.47715 17.5229 2 12 2ZM0 12C0 5.3726 5.3726 0 12 0C18.6274 0 24 5.3726 24 12C24 18.6274 18.6274 24 12 24C5.3726 24 0 18.6274 0 12Z"
+ fill="rgba(0,0,0,0.7)"
+ stroke="none"
+ />
+ <path
+ fill-rule="evenodd"
+ clip-rule="evenodd"
+ d="M9.59162 22.7357C9.49492 22.6109 9.49492 21.4986 9.59162 19.399C8.55572 19.4347 7.90122 19.3628 7.62812 19.1833C7.21852 18.9139 6.80842 18.0833 6.44457 17.4979C6.08072 16.9125 5.27312 16.8199 4.94702 16.6891C4.62091 16.5582 4.53905 16.0247 5.84562 16.4282C7.15222 16.8316 7.21592 17.9303 7.62812 18.1872C8.04032 18.4441 9.02572 18.3317 9.47242 18.1259C9.91907 17.9201 9.88622 17.1538 9.96587 16.8503C10.0666 16.5669 9.71162 16.5041 9.70382 16.5018C9.26777 16.5018 6.97697 16.0036 6.34772 13.7852C5.71852 11.5669 6.52907 10.117 6.96147 9.49369C7.24972 9.07814 7.22422 8.19254 6.88497 6.83679C8.11677 6.67939 9.06732 7.06709 9.73672 7.99999C9.73737 8.00534 10.6143 7.47854 12.0001 7.47854C13.386 7.47854 13.8777 7.90764 14.2571 7.99999C14.6365 8.09234 14.94 6.36699 17.2834 6.83679C16.7942 7.79839 16.3844 8.99999 16.6972 9.49369C17.0099 9.98739 18.2372 11.5573 17.4833 13.7852C16.9807 15.2706 15.9927 16.1761 14.5192 16.5018C14.3502 16.5557 14.2658 16.6427 14.2658 16.7627C14.2658 16.9427 14.4942 16.9624 14.8233 17.8058C15.0426 18.368 15.0585 19.9739 14.8708 22.6234C14.3953 22.7445 14.0254 22.8257 13.7611 22.8673C13.2924 22.9409 12.7835 22.9822 12.2834 22.9982C11.7834 23.0141 11.6098 23.0123 10.9185 22.948C10.4577 22.9051 10.0154 22.8343 9.59162 22.7357Z"
+ fill="rgba(0,0,0,0.7)"
+ stroke="none"
+ />
+</svg> \ No newline at end of file
diff --git a/src/lib/images/svelte-logo.svg b/src/lib/images/svelte-logo.svg
new file mode 100644
index 0000000..49492a8
--- /dev/null
+++ b/src/lib/images/svelte-logo.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="107" height="128" viewBox="0 0 107 128"><title>svelte-logo</title><path d="M94.1566,22.8189c-10.4-14.8851-30.94-19.2971-45.7914-9.8348L22.2825,29.6078A29.9234,29.9234,0,0,0,8.7639,49.6506a31.5136,31.5136,0,0,0,3.1076,20.2318A30.0061,30.0061,0,0,0,7.3953,81.0653a31.8886,31.8886,0,0,0,5.4473,24.1157c10.4022,14.8865,30.9423,19.2966,45.7914,9.8348L84.7167,98.3921A29.9177,29.9177,0,0,0,98.2353,78.3493,31.5263,31.5263,0,0,0,95.13,58.117a30,30,0,0,0,4.4743-11.1824,31.88,31.88,0,0,0-5.4473-24.1157" style="fill:#ff3e00"/><path d="M45.8171,106.5815A20.7182,20.7182,0,0,1,23.58,98.3389a19.1739,19.1739,0,0,1-3.2766-14.5025,18.1886,18.1886,0,0,1,.6233-2.4357l.4912-1.4978,1.3363.9815a33.6443,33.6443,0,0,0,10.203,5.0978l.9694.2941-.0893.9675a5.8474,5.8474,0,0,0,1.052,3.8781,6.2389,6.2389,0,0,0,6.6952,2.485,5.7449,5.7449,0,0,0,1.6021-.7041L69.27,76.281a5.4306,5.4306,0,0,0,2.4506-3.631,5.7948,5.7948,0,0,0-.9875-4.3712,6.2436,6.2436,0,0,0-6.6978-2.4864,5.7427,5.7427,0,0,0-1.6.7036l-9.9532,6.3449a19.0329,19.0329,0,0,1-5.2965,2.3259,20.7181,20.7181,0,0,1-22.2368-8.2427,19.1725,19.1725,0,0,1-3.2766-14.5024,17.9885,17.9885,0,0,1,8.13-12.0513L55.8833,23.7472a19.0038,19.0038,0,0,1,5.3-2.3287A20.7182,20.7182,0,0,1,83.42,29.6611a19.1739,19.1739,0,0,1,3.2766,14.5025,18.4,18.4,0,0,1-.6233,2.4357l-.4912,1.4978-1.3356-.98a33.6175,33.6175,0,0,0-10.2037-5.1l-.9694-.2942.0893-.9675a5.8588,5.8588,0,0,0-1.052-3.878,6.2389,6.2389,0,0,0-6.6952-2.485,5.7449,5.7449,0,0,0-1.6021.7041L37.73,51.719a5.4218,5.4218,0,0,0-2.4487,3.63,5.7862,5.7862,0,0,0,.9856,4.3717,6.2437,6.2437,0,0,0,6.6978,2.4864,5.7652,5.7652,0,0,0,1.602-.7041l9.9519-6.3425a18.978,18.978,0,0,1,5.2959-2.3278,20.7181,20.7181,0,0,1,22.2368,8.2427,19.1725,19.1725,0,0,1,3.2766,14.5024,17.9977,17.9977,0,0,1-8.13,12.0532L51.1167,104.2528a19.0038,19.0038,0,0,1-5.3,2.3287" style="fill:#fff"/></svg> \ No newline at end of file
diff --git a/src/lib/images/svelte-welcome.png b/src/lib/images/svelte-welcome.png
new file mode 100644
index 0000000..fe7d2d6
--- /dev/null
+++ b/src/lib/images/svelte-welcome.png
Binary files differ
diff --git a/src/lib/images/svelte-welcome.webp b/src/lib/images/svelte-welcome.webp
new file mode 100644
index 0000000..6ec1a28
--- /dev/null
+++ b/src/lib/images/svelte-welcome.webp
Binary files differ
diff --git a/src/lib/mobile.js b/src/lib/mobile.js
new file mode 100644
index 0000000..1f2416c
--- /dev/null
+++ b/src/lib/mobile.js
@@ -0,0 +1,4 @@
+export function isMobile() {
+ a = navigator.userAgent||navigator.vendor||window.opera;
+ return (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4)))
+}
diff --git a/src/lib/styles/contact.scss b/src/lib/styles/contact.scss
new file mode 100644
index 0000000..910cac6
--- /dev/null
+++ b/src/lib/styles/contact.scss
@@ -0,0 +1,38 @@
+@use "sass:color";
+@use "sass:meta";
+
+@mixin contact($color, $text-color: $color) {
+ cursor: pointer;
+ color: $text-color;
+ background-color: color.adjust($color, $alpha: -0.1);
+ padding: 7px 25px;
+ min-width: 70px;
+ max-width: 70vw;
+ overflow-wrap: break-word;
+ border-radius: 10px;
+ align-items: center;
+ justify-content: center;
+ box-shadow: 0 1px 4px 1px color.change(black, $alpha: 0.10),
+ 0 1px 10px 5px color.change(black, $alpha: 0.09),
+ 0 3px 16px 8px color.change(black, $alpha: 0.04),
+ 0 0 0 1px color.change(black, $alpha: 0.05);
+ transition: box-shadow 0.3s ease-in-out;
+
+ &:hover {
+ box-shadow: 0 1px 4px 1px color.change($color, $alpha: 0.10),
+ 0 1px 10px 5px color.change($color, $alpha: 0.09),
+ 0 3px 16px 8px color.change($color, $alpha: 0.04),
+ 0 0 0 1px color.change($color, $alpha: 0.05);
+ }
+ & h3 {
+ text-align: center;
+ }
+
+ & p {
+ user-select: none;
+ }
+
+ & noscript {
+ text-overflow: ellipsis;
+ }
+}
diff --git a/src/lib/styles/index.scss b/src/lib/styles/index.scss
new file mode 100644
index 0000000..f8b00dd
--- /dev/null
+++ b/src/lib/styles/index.scss
@@ -0,0 +1,2 @@
+@forward "$lib/styles/shadow.scss";
+@forward "$lib/styles/contact.scss";
diff --git a/src/lib/styles/shadow.scss b/src/lib/styles/shadow.scss
new file mode 100644
index 0000000..382c337
--- /dev/null
+++ b/src/lib/styles/shadow.scss
@@ -0,0 +1,9 @@
+@use "sass:color";
+@use "sass:meta";
+
+@mixin shadow($color: black) {
+ box-shadow: 0 1px 4px 1px color.change($color, $alpha: 0.13),
+ 0 1px 10px 5px color.change($color, $alpha: 0.09),
+ 0 3px 16px 8px color.change($color, $alpha: 0.04),
+ 0 0 0 1px color.change($color, $alpha: 0.05);
+}
diff --git a/src/routes/+error.svelte b/src/routes/+error.svelte
new file mode 100644
index 0000000..2ced366
--- /dev/null
+++ b/src/routes/+error.svelte
@@ -0,0 +1,41 @@
+<script lang="ts">
+ import { page } from "$app/stores";
+
+ let displayDog = ($page.status === 404) || false;
+</script>
+
+<div class="error-container">
+ <div class="error">
+ <h1>{$page.status ?? "oopsie daisies!"}</h1>
+ <p>{$page.error?.message ?? "website broke &gt;w&lt; "}</p>
+ </div>
+ {#if displayDog}
+ <div class="huh">
+ <img src="/huh.jpg" alt="dog looking at the camera with a question mark edited next to it"/>
+ </div>
+ {/if}
+</div>
+
+<style lang="scss">
+ .error-container {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ width: 100%;
+ height: 100%;
+
+ & .error {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ margin: 36px 12px;
+ border-spacing: 36px;
+
+ & :not(:last-child) {
+ margin-bottom: 1rem;
+ }
+ }
+ }
+</style>
+
diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte
new file mode 100644
index 0000000..7772574
--- /dev/null
+++ b/src/routes/+layout.svelte
@@ -0,0 +1,31 @@
+<script lang="ts">
+ import Header from './Header.svelte';
+ import './styles.scss';
+</script>
+
+<div class="app">
+ <Header>
+ <main>
+ <slot />
+ </main>
+ </Header>
+</div>
+
+<style>
+ .app {
+ display: flex;
+ flex-direction: column;
+ }
+
+ main {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ padding: 1rem;
+ padding-top: 4em;
+ width: 100%;
+ max-width: 64rem;
+ margin: 0 auto;
+ box-sizing: border-box;
+ }
+</style>
diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte
new file mode 100644
index 0000000..c046cd7
--- /dev/null
+++ b/src/routes/+page.svelte
@@ -0,0 +1,205 @@
+<script lang="ts">
+ import { fade } from "svelte/transition";
+ import github from "$lib/images/github.svg?raw";
+ import xmppSvg from "$lib/assets/xmpp.svg?raw";
+ import { decode, isDecoded } from "$lib/decoder";
+ import { getContext, onMount } from "svelte";
+ import { isMobile } from "$lib/mobile";
+ import { browser } from "$app/environment";
+
+
+ const header = getContext<Header>("Header");
+
+ var description = [
+ "Hiiiii im Rose!! I've been coding and abusing computers for like 8 years now (as of 2024)!",
+ "My main focus is in OSdev and Containers, but my experience ranges all accross the spectrum, ",
+ "frontend, backend, weird amalgamations inbetween, I can make everything work! ",
+ ].join("");
+
+
+ var xmpp:string = "e714815f15b15315615a12714b15015a15915615615b11515615914e";
+ var matrix: string = "c210213a12713012b1230fc13612a1270ef12313213113612a12712512313413b0f012512e137124"
+ onMount(() => {
+ if (navigator.webdriver) {
+ document.body.toggleAttribute("data-noscript");
+ return;
+ }
+
+ xmpp = decode(xmpp);
+ matrix = decode(matrix);
+ });
+
+ onMount(async () => {
+ var chrome: boolean = /Chrome/.test(navigator.userAgent) && /Google Inc/.test(navigator.vendor);
+ if (chrome && !isMobile()) { // I can forgive people for using chrome on mobile tbh
+ header.addMessage("Chrome browsers enforce Googles monopolistic position while harming user privacy. See https://contrachrome.com/", {
+ dismissable: false
+ })
+ }
+ });
+
+ function copyText(text: string): (event: MouseEvent|KeyboardEvent) => void {
+ return (event) => {
+ if (event instanceof KeyboardEvent && event.code != "Enter")
+ return;
+
+ if (navigator.clipboard == null) {
+ return;
+ }
+
+ navigator.clipboard.writeText(text)
+ .then(() => header.addMessage("Copied to clipboard"))
+ .catch(() => header.addMessage("Failed to copy to clipboard"));
+ };
+ }
+</script>
+
+<svelte:head>
+ <title>rose</title>
+ <meta name="description" content="Coder of C. Abuser of Containers. Hater of golang." />
+ <meta property="og:title" content="axtlos"/>
+ <meta property="og:type" content="website"/>
+ <meta property="og:description" content={description}/>
+ <meta property="og:image" content="/me.png"/>
+ <meta property="og:url" content="https://xenia.blahaj.land"/>
+ <meta property="og:locale" content="en_US"/>
+ <link rel="me" href="https://eepy.moe/@rose"/>
+</svelte:head>
+
+<page>
+ <section id="welcome">
+ <h1>Hi! I'm Rose</h1>
+ </section>
+ <section id="about">
+ <h2>About me!</h2>
+ <p>
+ I'm a software engineer with an interest in Containers and OSdev.
+ I currently live in germany and study Computer Science.
+ </p>
+ <p>
+ Apart from Coding and tinkering with Hardware, I enjoy listening to music, reading books and going on walks!
+ </p>
+ </section>
+ <section id="projects">
+ <h2>My work</h2>
+ <p>
+ Currently most of my time is spent working on
+ <a href="https://github.com/Vanilla-OS/vib">vib</a>,
+ as the maintainer of vib I handle any project management,
+ while actively expanding it with more features.
+ </p>
+ <p>
+ In connection to vib. I am currently reviving an older
+ project called Project Shards, an arch based immutable
+ distribution, that went through many different designs,
+ but has settled on using systemd-sysupdate in the same vein as
+ <a href="https://os.gnome.org">GNOME OS</a>.
+ </p>
+ <p>
+ A more thorough list of Projects can be found in the
+ <a href="/projects">Projects</a> page.
+ </p>
+ </section>
+ <section id="contact">
+ <h2>Contact</h2>
+ <p class="subheader">Click on an element to copy its address</p>
+ <p>
+ You can contact me on these platforms!
+ </p>
+ {#if !browser}
+ <p id="noscript">
+ You seem to have disable javascript! But this website uses js to deobfuscate the contacts &gt;w&lt;
+ The obfuscated codes are displayed in the boxes below, you can use <a href="/deobfuscate.sh">this shell script</a> to debofuscate them locally!
+ </p>
+ {/if}
+ <ul>
+ <li id="xmpp">
+ <div
+ role="button"
+ tabindex="0"
+ on:click={isDecoded(matrix) ? undefined : copyText(xmpp)}
+ on:keydown={isDecoded(matrix) ? undefined : copyText(xmpp)}>
+ <h3>XMPP</h3>
+ {#if !browser}
+ <noscript>{xmpp}</noscript>
+ {:else}
+ <p>{xmpp}</p>
+ {/if}
+ </div>
+ </li>
+ <li id="matrix">
+ <div
+ role="button"
+ tabindex="0"
+ on:click={isDecoded(matrix) ? undefined : copyText(matrix)}
+ on:keydown={isDecoded(matrix) ? undefined : copyText(matrix)}>
+ <h3>matrix</h3>
+ {#if !browser}
+ <noscript>{matrix}</noscript>
+ {:else}
+ <p>{matrix}</p>
+ {/if}
+ </div>
+ </li>
+ <li id="email">
+ <div>
+ <a class="permalink"
+ href={isDecoded(matrix) ? `javascript:void` : `mailto:${xmpp}`}>
+ <h3>email</h3>
+ {#if !browser}
+ <noscript>{xmpp}</noscript>
+ {:else}
+ <p>{xmpp}</p>
+ {/if}
+ </a>
+ </div>
+ </li>
+ </ul>
+ </section>
+</page>
+
+<style lang="scss">
+ @use "$lib/styles";
+ page {
+ & section {
+ width: 100%;
+
+ &#contact {
+ & .subheader {
+ font-size: 0.8em;
+ margin-top: -25px;
+ }
+ & ul {
+ list-style: none;
+ display: flex;
+ gap: 10px;
+ flex-wrap: wrap;
+ flex-direction: row;
+ padding: unset;
+ margin: unset;
+ margin-top: 1em;
+ margin-bottom: 1em;
+ justify-content: space-around;
+
+ & li#xmpp > div { @include styles.contact($color: #FFC067, $text-color: #000000); }
+ & li#matrix > div { @include styles.contact($color: #7D7, $text-color: #000000); }
+ & li#email {
+ & a {
+ text-decoration: none;
+ }
+ & > div {
+ @include styles.contact($color: #B19CD9, $text-color: #000000);
+ }
+ }
+
+ & li > * {
+ & p {
+ text-align: center;
+ }
+ }
+ }
+ }
+ }
+ }
+
+</style>
diff --git a/src/routes/+page.ts b/src/routes/+page.ts
new file mode 100644
index 0000000..a72419a
--- /dev/null
+++ b/src/routes/+page.ts
@@ -0,0 +1,3 @@
+// since there's no dynamic data here, we can prerender
+// it so that it gets served as a static asset in production
+export const prerender = true;
diff --git a/src/routes/ContactCard.svelte b/src/routes/ContactCard.svelte
new file mode 100644
index 0000000..d347deb
--- /dev/null
+++ b/src/routes/ContactCard.svelte
@@ -0,0 +1,40 @@
+<script lang="ts">
+ export let inline: boolean = false;
+ export let svg: string;
+ export let onclick;
+</script>
+
+<div
+ role="button"
+ tabindex="0"
+ on:click={onclick}
+ on:keydown={onclick}>
+ <span class:inline={inline}>
+ {@html svg}
+ </span>
+</div>
+
+<span class:inline={inline}>
+ {@html svg}
+</span>
+
+<style lang="scss">
+ span {
+ & :global(svg) {
+ width: 1em;
+ height: 1em;
+ fill: currentColor;
+ }
+ &.inline :global(svg) { transform: translate(0, 0.125em); }
+ }
+
+ div {
+ background-color: green;
+ user-select: none;
+ padding: 1px 18px;
+ border-radius: 9999px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ }
+</style>
diff --git a/src/routes/Header.svelte b/src/routes/Header.svelte
new file mode 100644
index 0000000..0366e6d
--- /dev/null
+++ b/src/routes/Header.svelte
@@ -0,0 +1,299 @@
+<script context="module" lang="ts">
+ import { type ComponentType, SvelteComponent} from "svelte";
+ var showmsg: boolean = false;
+
+ export type Header = {
+ addMessage (message: string, options?: Partial<MessageOptions>): void
+ };
+
+ type HeaderMessage = {
+ message: string,
+ options: MessageOptions,
+ dismiss: () => void,
+ }
+
+ type MessageOptions = {
+ time: number,
+ dismissable: boolean,
+ };
+
+ var chrome: boolean = /Chrome/.test(navigator.userAgent) && /Google Inc/.test(navigator.vendor);
+</script>
+
+<script lang="ts">
+ import { page } from '$app/stores';
+ import logo from '/rose.gif';
+ import boowomp from '/wilted-flower.gif';
+ import close from '$lib/assets/close.svg?raw';
+ import { setContext } from "svelte";
+ import { fly } from "svelte/transition";
+ import { readable, writable } from "svelte/store";
+
+ const newestMessage = writable<HeaderMessage|null>(null);
+
+ const rose = chrome ? boowomp : logo;
+
+ const currentMessage = writable<HeaderMessage|null>(null, (set) => {
+ let $currentMessage: HeaderMessage|null = null;
+ let currentTimeout: number|null = null;
+
+ const dismiss = () => {
+ if (currentTimeout == null) clearTimeout(currentTimeout);
+ $currentMessage = null;
+ set(null);
+ };
+
+ const unsubscribe = newestMessage.subscribe(($newestMessage) => {
+ if ($newestMessage == null) return;
+
+ if ($currentMessage != null) dismiss();
+
+ $currentMessage = $newestMessage;
+ $currentMessage.dismiss = dismiss;
+ if ($currentMessage.options.dismissable)
+ currentTimeout = setTimeout(dismiss, $currentMessage.options.duration);
+ set($currentMessage);
+ });
+
+ return () => {
+ unsubscribe();
+ dismiss();
+ };
+ });
+
+ setContext<Header>("Header", {
+ addMessage(...args: any[]) {
+
+ let [ message, options ] = args as [string, Partial<MessageOptions>|undefined];
+ options ??= { dismissable: true, duration: 5000 };
+ options.dismissable ??= true;
+ options.duration ??= 5000;
+ newestMessage.set({
+ type: "message",
+ message,
+ options: options as MessageOptions,
+ dismiss: void {},
+ });
+
+ },
+ });
+
+</script>
+
+<div class="main">
+ <header>
+ <div class="corner">
+ <a href="/" class="name">
+ <img id="logo" src={rose} alt="rose"/>
+ <p>rose</p>
+ </a>
+ </div>
+
+ {#if $currentMessage != null}
+ <div class="center" transition:fly>
+ <p>
+ {$currentMessage.message}
+ </p>
+ {#if $currentMessage.options.dismissable}
+ <button
+ class="dismiss"
+ on:click={$currentMessage.dismiss}>
+ <span class="icon">{@html close}</span>
+ </button>
+ {/if}
+ </div>
+ {/if}
+
+ <nav>
+ <ul>
+ <li aria-current={$page.url.pathname === '/' ? 'page' : undefined}>
+ <a href="/">Home</a>
+ </li>
+ <li aria-current={$page.url.pathname === '/projects' ? 'page' : undefined}>
+ <a href="/projects">Projects</a>
+ </li>
+ </ul>
+ </nav>
+ </header>
+ <slot />
+</div>
+
+<style lang="scss">
+ @use "sass:color";
+
+ @import "@fontsource-variable/playwrite-hr";
+
+ header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ width: 100%;
+ position: fixed;
+ position: -webkit-sticky;
+ top: 0;
+ z-index: 99;
+ background-color: color.change(white, $alpha: 0.9);
+ height: 3em;
+ }
+
+ .name {
+ font-family: 'Playwrite HR Variable', cursive;
+ font-size: 1.3em;
+ color: #150129;
+ padding-bottom: 6px;
+ }
+
+ .corner {
+ height: 3em;
+ margin-bottom: 0px;
+
+ & a {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 100%;
+ height: 100%;
+ text-decoration: none;
+
+ &:visited {
+ color: black;
+ }
+ &:hover &:active {
+ color: black;
+ }
+
+ & p {
+ padding-left: 4px;
+ }
+ }
+
+ & img {
+ width: 1.5em;
+ height: 1.5em;
+ object-fit: contain;
+ }
+
+ & img {
+ width: 1.5em;
+ height: 1.5em;
+ object-fit: contain;
+
+ }
+
+ }
+
+ .center {
+ display: flex;
+ flex-direction: row;
+ background-color: #000000ac;
+ border-radius: 100px;
+ align-items: center;
+ height: 2.5em;
+
+ & > .dismiss {
+ min-height: 2.3em;
+ min-width: 2.3em;
+ background: transparent;
+ border: none;
+ border-radius: 9999px;
+ margin-right: 10px;
+
+ &:hover { background: #ffffff30; }
+ &:active { background: #ffffff60; }
+
+ & > :global(span) {
+ justify-content: center;
+ align-content: center;
+ width: 100%;
+ height: 100%;
+ fill: #ffffff;
+ transform: translate(0, 0.125em);
+ & > :global(svg) {
+ width: 16px;
+ height: 16px;
+ object-fit: contain;
+ text-align: center;
+ fill: #ffffff;
+ }
+ }
+ }
+
+ & p {
+ color: #fff;
+ margin-left: 10px;
+ margin-right: 10px;
+ }
+
+ }
+
+ nav {
+ display: flex;
+ justify-content: right;
+ font-size: 1.2em;
+ padding-right: 10px;
+ object-fit: contain;
+ }
+
+ ul {
+ position: relative;
+ padding: 0;
+ margin: 0;
+ height: 3em;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ list-style: none;
+ background-size: contain;
+ }
+
+ li {
+ position: relative;
+ height: 100%;
+ }
+
+ li[aria-current='page']::before {
+ --size: 6px;
+ content: '';
+ width: 0;
+ height: 0;
+ position: absolute;
+ top: 0;
+ left: calc(50% - var(--size));
+ border: var(--size) solid transparent;
+ border-top: var(--size) solid var(--color-theme-1);
+ }
+
+ nav a {
+ display: flex;
+ height: 100%;
+ align-items: center;
+ padding: 0 0.5rem;
+ color: #150129;
+ font-weight: 700;
+ font-size-adjust: 0.3;
+ text-transform: uppercase;
+ letter-spacing: 0.1em;
+ text-decoration: none;
+ transition: color 0.2s linear;
+ }
+
+ a:hover {
+ color: var(--color-theme-1);
+ }
+
+ @media (prefers-color-scheme: dark) {
+ /* If the operating system is using dark mode, then apply this CSS */
+ header {
+ background-color: color.change(#292b33, $alpha: 0.9);
+ }
+
+ a:link:not(.permalink),a:visited:not(.permalink) {
+ color: #b9cffb;
+ }
+
+ .name {
+ color: #f5f5f5;
+ }
+ }
+
+</style>
diff --git a/src/routes/projects/+page.svelte b/src/routes/projects/+page.svelte
new file mode 100644
index 0000000..dbe5516
--- /dev/null
+++ b/src/routes/projects/+page.svelte
@@ -0,0 +1,53 @@
+<script lang="ts">
+ import ProjectEntry from "./ProjectEntry.svelte";
+</script>
+
+<page>
+ <section id="title">
+ <h1>Projects</h1>
+ </section>
+ <section id="brief">
+ <p>
+ A list of most projects I have worked on or am a part of, note that not all of them are still maintained.
+ </p>
+ </section>
+ <ProjectEntry name={'FsVerify'} description={'Block Based filesystem verification for immutable Linux Distributions written in golang and C'}
+ projType={'Personal Project'} link={'https://github.com/axtloss/fsverify'}/>
+
+ <ProjectEntry name={'BVG - Basic Vector Graphics'} description={'Custom made vector graphic format for use with FsVerify, the parser (fbwarn) is written in C using raylib'}
+ projType={'Personal Project'} link={'https://github.com/axtloss/fsverify/tree/main/fbwarn'}>
+ <img src="/bvg.png" alt="The FsVerify logo drawn with BVG"/>
+ </ProjectEntry>
+
+ <ProjectEntry name={'vib'} description={'Building docker images using yaml recipes, written in golang'}
+ projType={'Maintainer, Collaboration'} link={'https://vib.vanillaos.org'}/>
+
+ <ProjectEntry name={'Vanilla System Operator'} description={'Tool to manage Vanilla OS installations, including Waydroid app management'}
+ projType={'Collaboration'} link={'https://github.com/vanilla-os/vanilla-system-operator'}/>
+
+ <ProjectEntry name={'FsGuard'} description={'File tree based Filesystem integrity verification, fully written in go and used by Vanilla OS through fswarn'}
+ projType={'Maintainer, Personal Project'} link={'https://github.com/linux-immutability-tools/fsguard'}/>
+
+ <ProjectEntry name={'jade'} description={'Installer backend for Crystal Linux, written in rust'}
+ projType={'Collaboration / Personal Project'} link={'https://gitlab.com/crystal-linux/software/jade'}/>
+
+ <ProjectEntry name={'jade-gui'} description={'Graphical frontend for Jade, written in python using gtk4 and libadwaita'}
+ projType={'Collaboration / Personal Project'} link={'https://gitlab.com/crystal-linux/software/jade-gui'}/>
+
+ <ProjectEntry name={'JshipIT'} description={'OCI client written in Java similiar to podman/docker with a focus on using containers as a form of isolated environments, similiar to Distrobox and Toolbx'}
+ projType={'Personal Project'} link={'https://github.com/axtloss/JshipIT'}/>
+</page>
+
+<style lang="scss">
+ @use 'sass:color';
+ img {
+ display: block;
+ margin-left: auto;
+ margin-right: auto;
+ border-radius: 10px 10px 10px 10px;
+ box-shadow: 0 1px 4px 1px color.change(black, $alpha: 0.13),
+ 0 1px 10px 5px color.change(black, $alpha: 0.09),
+ 0 3px 16px 8px color.change(black, $alpha: 0.04),
+ 0 0 0 1px color.change(black, $alpha: 0.05);
+ }
+</style>
diff --git a/src/routes/projects/+page.ts b/src/routes/projects/+page.ts
new file mode 100644
index 0000000..e739ef4
--- /dev/null
+++ b/src/routes/projects/+page.ts
@@ -0,0 +1,9 @@
+import { dev } from '$app/environment';
+
+// we don't need any JS on this page, though we'll load
+// it in dev so that we get hot module replacement
+export const csr = dev;
+
+// since there's no dynamic data here, we can prerender
+// it so that it gets served as a static asset in production
+export const prerender = true;
diff --git a/src/routes/projects/ProjectEntry.svelte b/src/routes/projects/ProjectEntry.svelte
new file mode 100644
index 0000000..53c69b5
--- /dev/null
+++ b/src/routes/projects/ProjectEntry.svelte
@@ -0,0 +1,36 @@
+<script lang="ts">
+ export let name: string;
+ export let description: string;
+ export let projType: string;
+ export let link: string;
+ export let id: string = name.toLowerCase().replaceAll(" ", "_");
+</script>
+
+<section id="{id}" class="box">
+ <h2>{name}</h2>
+ <section id="fsverify-link">
+ <p class="subheader">
+ {projType} - <a href="{link}">{link}</a>
+ </p>
+ </section>
+ <slot />
+ <p class="description">
+ {description}
+ </p>
+</section>
+
+
+<style lang="scss">
+ @use 'sass:color';
+ section {
+ max-width: 790px;
+ width: 100%;
+ & h2 {
+ margin-bottom: 0px;
+ }
+ & .description {
+ text-align: center;
+ }
+ }
+
+</style>
diff --git a/src/routes/styles.scss b/src/routes/styles.scss
new file mode 100644
index 0000000..0fe7ab6
--- /dev/null
+++ b/src/routes/styles.scss
@@ -0,0 +1,48 @@
+@import "@fontsource-variable/inter";
+
+body {
+ font-family:
+ 'Inter Variable', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu,
+ Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
+ font-size: 1.2em;
+ color: #150129;
+}
+
+h1 {
+ width: 100%;
+ font-size-adjust: 0.7;
+ margin-bottom: 2px;
+}
+
+page {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+
+ width: 100%;
+ height: 0;
+ padding: 0 0 calc(100% * 495 / 2048) 0;
+}
+
+.permalink {
+ color: #150129;
+}
+
+.subheader {
+ font-size: 0.9em;
+ margin-top: 0px;
+}
+
+
+@media (prefers-color-scheme: dark) {
+ /* If the operating system is using dark mode, then apply this CSS */
+ body {
+ background: #292b33;
+ color: #f5f5f5
+ }
+ a:link:not(.permalink),a:visited:not(.permalink) {
+ color: #b9cffb;
+ }
+}
+
+a:link:not(.permalink),a:visited:not(.permalink) { color: #2160ad; }