Create a central webpage for projects and likewise

Change-Id: If5b218fcb7cd223029bccdfac5ee9ea4e86ddf38
Reviewed-on: https://git.clicks.codes/c/Coded/thecoded.prof/+/673
Reviewed-by: Samuel Shuert <coded@clicks.codes>
Tested-by: Samuel Shuert <coded@clicks.codes>
diff --git a/sites/main/.gitignore b/sites/main/.gitignore
new file mode 100644
index 0000000..016b59e
--- /dev/null
+++ b/sites/main/.gitignore
@@ -0,0 +1,24 @@
+# build output
+dist/
+
+# generated types
+.astro/
+
+# dependencies
+node_modules/
+
+# logs
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+
+# environment variables
+.env
+.env.production
+
+# macOS-specific files
+.DS_Store
+
+# jetbrains setting folder
+.idea/
diff --git a/sites/main/.vscode/extensions.json b/sites/main/.vscode/extensions.json
new file mode 100644
index 0000000..22a1505
--- /dev/null
+++ b/sites/main/.vscode/extensions.json
@@ -0,0 +1,4 @@
+{
+  "recommendations": ["astro-build.astro-vscode"],
+  "unwantedRecommendations": []
+}
diff --git a/sites/main/.vscode/launch.json b/sites/main/.vscode/launch.json
new file mode 100644
index 0000000..d642209
--- /dev/null
+++ b/sites/main/.vscode/launch.json
@@ -0,0 +1,11 @@
+{
+  "version": "0.2.0",
+  "configurations": [
+    {
+      "command": "./node_modules/.bin/astro dev",
+      "name": "Development server",
+      "request": "launch",
+      "type": "node-terminal"
+    }
+  ]
+}
diff --git a/sites/main/README.md b/sites/main/README.md
new file mode 100644
index 0000000..1db3fb3
--- /dev/null
+++ b/sites/main/README.md
@@ -0,0 +1,54 @@
+# Astro Starter Kit: Basics
+
+```sh
+npm create astro@latest -- --template basics
+```
+
+[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/withastro/astro/tree/latest/examples/basics)
+[![Open with CodeSandbox](https://assets.codesandbox.io/github/button-edit-lime.svg)](https://codesandbox.io/p/sandbox/github/withastro/astro/tree/latest/examples/basics)
+[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/withastro/astro?devcontainer_path=.devcontainer/basics/devcontainer.json)
+
+> 🧑‍🚀 **Seasoned astronaut?** Delete this file. Have fun!
+
+![just-the-basics](https://github.com/withastro/astro/assets/2244813/a0a5533c-a856-4198-8470-2d67b1d7c554)
+
+## 🚀 Project Structure
+
+Inside of your Astro project, you'll see the following folders and files:
+
+```text
+/
+├── public/
+│   └── favicon.svg
+├── src/
+│   ├── components/
+│   │   └── Card.astro
+│   ├── layouts/
+│   │   └── Layout.astro
+│   └── pages/
+│       └── index.astro
+└── package.json
+```
+
+Astro looks for `.astro` or `.md` files in the `src/pages/` directory. Each page is exposed as a route based on its file name.
+
+There's nothing special about `src/components/`, but that's where we like to put any Astro/React/Vue/Svelte/Preact components.
+
+Any static assets, like images, can be placed in the `public/` directory.
+
+## 🧞 Commands
+
+All commands are run from the root of the project, from a terminal:
+
+| Command                   | Action                                           |
+| :------------------------ | :----------------------------------------------- |
+| `npm install`             | Installs dependencies                            |
+| `npm run dev`             | Starts local dev server at `localhost:4321`      |
+| `npm run build`           | Build your production site to `./dist/`          |
+| `npm run preview`         | Preview your build locally, before deploying     |
+| `npm run astro ...`       | Run CLI commands like `astro add`, `astro check` |
+| `npm run astro -- --help` | Get help using the Astro CLI                     |
+
+## 👀 Want to learn more?
+
+Feel free to check [our documentation](https://docs.astro.build) or jump into our [Discord server](https://astro.build/chat).
diff --git a/sites/main/astro.config.mjs b/sites/main/astro.config.mjs
new file mode 100644
index 0000000..89dedbd
--- /dev/null
+++ b/sites/main/astro.config.mjs
@@ -0,0 +1,7 @@
+import { defineConfig } from 'astro/config';
+import tailwind from '@astrojs/tailwind';
+
+// https://astro.build/config
+export default defineConfig({
+    integrations: [tailwind()],
+});
diff --git a/sites/main/bun.lockb b/sites/main/bun.lockb
new file mode 100755
index 0000000..85e6d66
--- /dev/null
+++ b/sites/main/bun.lockb
Binary files differ
diff --git a/sites/main/package.json b/sites/main/package.json
new file mode 100644
index 0000000..31e4a02
--- /dev/null
+++ b/sites/main/package.json
@@ -0,0 +1,12 @@
+{
+  "name": "thecoded.prof-main",
+  "type": "module",
+  "version": "1.0.0",
+  "scripts": {
+    "dev": "astro dev",
+    "start": "astro dev",
+    "build": "astro check && astro build",
+    "preview": "astro preview",
+    "astro": "astro"
+  }
+}
\ No newline at end of file
diff --git a/sites/main/public/favicon.svg b/sites/main/public/favicon.svg
new file mode 100644
index 0000000..86a5632
--- /dev/null
+++ b/sites/main/public/favicon.svg
@@ -0,0 +1,114 @@
+<svg xmlns:xlink="http://www.w3.org/1999/xlink" width="2048" xmlns="http://www.w3.org/2000/svg" height="2048"
+    id="screenshot-575c1a2e-27e8-80c7-8003-2584dd2a8ab9" viewBox="0 0 2048 2048"
+    style="-webkit-print-color-adjust: exact;" fill="none" version="1.1">
+    <g id="shape-575c1a2e-27e8-80c7-8003-2584dd2a8ab9">
+        <defs>
+            <clipPath class="frame-clip-def frame-clip"
+                id="frame-clip-575c1a2e-27e8-80c7-8003-2584dd2a8ab9-rumext-id-1">
+                <rect rx="0" ry="0" x="0" y="0" width="2048" height="2048"
+                    transform="matrix(1.000000, 0.000000, -0.000000, 1.000000, 0.000022, -0.000022)" />
+            </clipPath>
+        </defs>
+        <g clip-path="url(#frame-clip-575c1a2e-27e8-80c7-8003-2584dd2a8ab9-rumext-id-1)" fill="none">
+            <clipPath class="frame-clip-def frame-clip"
+                id="frame-clip-575c1a2e-27e8-80c7-8003-2584dd2a8ab9-rumext-id-1">
+                <rect rx="0" ry="0" x="0" y="0" width="2048" height="2048"
+                    transform="matrix(1.000000, 0.000000, -0.000000, 1.000000, 0.000022, -0.000022)" />
+            </clipPath>
+            <g class="fills" id="fills-575c1a2e-27e8-80c7-8003-2584dd2a8ab9">
+                <rect rx="0" ry="0" x="0" y="0"
+                    transform="matrix(1.000000, 0.000000, -0.000000, 1.000000, 0.000022, -0.000022)" width="2048"
+                    height="2048" class="frame-background" />
+            </g>
+            <g class="frame-children">
+                <g id="shape-575c1a2e-27e8-80c7-8003-2584dd2a8aba" rx="0" ry="0">
+                    <g id="shape-575c1a2e-27e8-80c7-8003-2584dd2a8abb">
+                        <g class="fills" id="fills-575c1a2e-27e8-80c7-8003-2584dd2a8abb">
+                            <path rx="0" ry="0"
+                                d="M1024.000,714.000C1195.094,714.000,1334.000,852.906,1334.000,1024.000C1334.000,1195.094,1195.094,1334.000,1024.000,1334.000C852.906,1334.000,714.000,1195.094,714.000,1024.000C714.000,852.906,852.906,714.000,1024.000,714.000Z" />
+                        </g>
+                        <g id="strokes-575c1a2e-27e8-80c7-8003-2584dd2a8abb" class="strokes">
+                            <g class="inner-stroke-shape">
+                                <defs>
+                                    <clipPath id="inner-stroke-rumext-id-3-575c1a2e-27e8-80c7-8003-2584dd2a8abb-0">
+                                        <use href="#stroke-shape-rumext-id-3-575c1a2e-27e8-80c7-8003-2584dd2a8abb-0" />
+                                    </clipPath>
+                                    <path rx="0" ry="0"
+                                        d="M1024.000,714.000C1195.094,714.000,1334.000,852.906,1334.000,1024.000C1334.000,1195.094,1195.094,1334.000,1024.000,1334.000C852.906,1334.000,714.000,1195.094,714.000,1024.000C714.000,852.906,852.906,714.000,1024.000,714.000Z"
+                                        id="stroke-shape-rumext-id-3-575c1a2e-27e8-80c7-8003-2584dd2a8abb-0"
+                                        style="fill: none; stroke-width: 125; stroke: rgb(237, 197, 117); stroke-opacity: 1;" />
+                                </defs>
+                                <use href="#stroke-shape-rumext-id-3-575c1a2e-27e8-80c7-8003-2584dd2a8abb-0"
+                                    clip-path="url('#inner-stroke-rumext-id-3-575c1a2e-27e8-80c7-8003-2584dd2a8abb-0')" />
+                            </g>
+                        </g>
+                    </g>
+                    <g id="shape-575c1a2e-27e8-80c7-8003-2584dd2a8abc" rx="0" ry="0">
+                        <g id="shape-575c1a2e-27e8-80c7-8003-2584dd2a8abf">
+                            <g class="fills" id="fills-575c1a2e-27e8-80c7-8003-2584dd2a8abf">
+                                <ellipse rx="504.99999999999955" ry="505.00110958512687" cx="1024.0000248384572"
+                                    cy="1024.001124635316"
+                                    transform="matrix(1.000000, 0.000000, 0.000000, 1.000000, -0.000000, 0.000000)" />
+                            </g>
+                        </g>
+                        <g id="shape-575c1a2e-27e8-80c7-8003-2584dd2a8ac0">
+                            <g class="fills" id="fills-575c1a2e-27e8-80c7-8003-2584dd2a8ac0">
+                                <path rx="0" ry="0"
+                                    d="M1389.486,675.650C1475.910,766.293,1529.000,888.994,1529.000,1023.998C1529.000,1302.715,1302.717,1528.998,1024.000,1528.998C745.283,1528.998,519.000,1302.715,519.000,1023.998C519.000,888.994,572.090,766.293,658.514,675.650" />
+                            </g>
+                            <g id="strokes-575c1a2e-27e8-80c7-8003-2584dd2a8ac0" class="strokes">
+                                <g class="stroke-shape">
+                                    <path rx="0" ry="0"
+                                        d="M1389.486,675.650C1475.910,766.293,1529.000,888.994,1529.000,1023.998C1529.000,1302.715,1302.717,1528.998,1024.000,1528.998C745.283,1528.998,519.000,1302.715,519.000,1023.998C519.000,888.994,572.090,766.293,658.514,675.650"
+                                        style="fill: none; stroke-width: 75; stroke: rgb(237, 197, 117); stroke-opacity: 1;" />
+                                </g>
+                            </g>
+                        </g>
+                    </g>
+                    <g id="shape-575c1a2e-27e8-80c7-8003-2584dd2a8abd" rx="0" ry="0">
+                        <g id="shape-575c1a2e-27e8-80c7-8003-2584dd2a8ac1">
+                            <g class="fills" id="fills-575c1a2e-27e8-80c7-8003-2584dd2a8ac1">
+                                <ellipse rx="700" ry="700" cx="1024" cy="1024"
+                                    transform="matrix(1.000000, 0.000000, -0.000000, 1.000000, 0.000015, -0.000015)" />
+                            </g>
+                        </g>
+                        <g id="shape-575c1a2e-27e8-80c7-8003-2584dd2a8ac2">
+                            <g class="fills" id="fills-575c1a2e-27e8-80c7-8003-2584dd2a8ac2">
+                                <path rx="0" ry="0"
+                                    d="M517.386,1506.376C397.591,1380.784,324.000,1210.772,324.000,1023.715C324.000,637.532,637.659,324.000,1024.000,324.000C1410.341,324.000,1724.000,637.532,1724.000,1023.715C1724.000,1210.772,1650.409,1380.784,1530.614,1506.376" />
+                            </g>
+                            <g id="strokes-575c1a2e-27e8-80c7-8003-2584dd2a8ac2" class="strokes">
+                                <g class="stroke-shape">
+                                    <path rx="0" ry="0"
+                                        d="M517.386,1506.376C397.591,1380.784,324.000,1210.772,324.000,1023.715C324.000,637.532,637.659,324.000,1024.000,324.000C1410.341,324.000,1724.000,637.532,1724.000,1023.715C1724.000,1210.772,1650.409,1380.784,1530.614,1506.376"
+                                        style="fill: none; stroke-width: 87.5; stroke: rgb(237, 197, 117); stroke-opacity: 1;" />
+                                </g>
+                            </g>
+                        </g>
+                    </g>
+                    <g id="shape-575c1a2e-27e8-80c7-8003-2584dd2a8abe" rx="0" ry="0">
+                        <g id="shape-575c1a2e-27e8-80c7-8003-2584dd2a8ac3">
+                            <g class="fills" id="fills-575c1a2e-27e8-80c7-8003-2584dd2a8ac3">
+                                <ellipse rx="895" ry="895" cx="1024" cy="1024"
+                                    transform="matrix(1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000)" />
+                            </g>
+                        </g>
+                        <g id="shape-575c1a2e-27e8-80c7-8003-2584dd2a8ac4">
+                            <g class="fills" id="fills-575c1a2e-27e8-80c7-8003-2584dd2a8ac4">
+                                <path rx="0" ry="0"
+                                    d="M1671.742,407.240C1824.909,567.819,1919.000,785.192,1919.000,1024.359C1919.000,1518.123,1517.964,1918.997,1024.000,1918.997C530.036,1918.997,129.000,1518.123,129.000,1024.359C129.000,785.192,223.091,567.819,376.258,407.240" />
+                            </g>
+                            <g id="strokes-575c1a2e-27e8-80c7-8003-2584dd2a8ac4" class="strokes">
+                                <g class="stroke-shape">
+                                    <path rx="0" ry="0"
+                                        d="M1671.742,407.240C1824.909,567.819,1919.000,785.192,1919.000,1024.359C1919.000,1518.123,1517.964,1918.997,1024.000,1918.997C530.036,1918.997,129.000,1518.123,129.000,1024.359C129.000,785.192,223.091,567.819,376.258,407.240"
+                                        style="fill: none; stroke-width: 100; stroke: rgb(237, 197, 117); stroke-opacity: 1;" />
+                                </g>
+                            </g>
+                        </g>
+                    </g>
+                </g>
+            </g>
+        </g>
+    </g>
+</svg>
\ No newline at end of file
diff --git a/sites/main/src/components/Project.astro b/sites/main/src/components/Project.astro
new file mode 100644
index 0000000..56249dd
--- /dev/null
+++ b/sites/main/src/components/Project.astro
@@ -0,0 +1,52 @@
+---
+
+import active from '../images/active.svg';
+import wip from '../images/wip.svg';
+import inactive from '../images/inactive.svg';
+
+export enum Status {
+    Active,
+    Inactive,
+    WIP
+}
+
+interface Props {
+    name: string,
+    url: string,
+    children: string;
+    status: Status;
+}
+
+const { name, url, status } = Astro.props;
+
+let color: string;
+let icon: string;
+
+switch (status) {
+    case Status.Active: {
+        color = "bg-green";
+        icon = active.src;
+        break;
+    }
+    case Status.WIP: {
+        color = "bg-yellow";
+        icon = wip.src;
+        break;
+    }
+    default:
+    case Status.Inactive: {
+        color = "bg-red";
+        icon = inactive.src;
+        break;
+    }
+}
+---
+
+<a href={url} class="w-72 h-36 flex flex-col rounded-lg p-2 m-2 bg-surface0 shadow-md shadow-crust transition-transform hover:bg-surface1 hover:drop-shadow-md hover:-translate-y-1">
+    <div class="flex justify-between mr-1 mb-1 items-end">
+        <p class="text-text text-lg">{name}</p>
+        <img src={icon} alt="cross" class="h-8"/>
+    </div>
+    <div class={`h-[2px] w-full mb-1 ${color}`}/>
+    <p class="text-text text-sm text-ellipsis overflow-hidden"><slot /></p>
+</a>
\ No newline at end of file
diff --git a/sites/main/src/env.d.ts b/sites/main/src/env.d.ts
new file mode 100644
index 0000000..acef35f
--- /dev/null
+++ b/sites/main/src/env.d.ts
@@ -0,0 +1,2 @@
+/// <reference path="../.astro/types.d.ts" />
+/// <reference types="astro/client" />
diff --git a/sites/main/src/images/active.svg b/sites/main/src/images/active.svg
new file mode 100644
index 0000000..752ec79
--- /dev/null
+++ b/sites/main/src/images/active.svg
@@ -0,0 +1,25 @@
+<svg width="1263" height="1263" viewBox="0 0 1263 1263" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g clip-path="url(#clip0_6690_17)">
+<rect x="605" y="325" width="53" height="242" fill="#A6DA95"/>
+<rect x="605" width="53" height="280" fill="#A6DA95"/>
+<rect x="605" y="983" width="53" height="280" fill="#A6DA95"/>
+<rect x="605" y="695" width="53" height="243" fill="#A6DA95"/>
+<rect x="1059.3" y="166.224" width="53" height="280" transform="rotate(45 1059.3 166.224)" fill="black"/>
+<rect x="567" y="605" width="53" height="242" transform="rotate(90 567 605)" fill="#A6DA95"/>
+<rect x="364.215" y="861.31" width="53" height="280" transform="rotate(45 364.215 861.31)" fill="black"/>
+<rect x="938" y="605" width="53" height="242" transform="rotate(90 938 605)" fill="#A6DA95"/>
+<rect x="567.652" y="657.873" width="53" height="242.704" transform="rotate(45 567.652 657.873)" fill="black"/>
+<rect x="829.492" y="396.033" width="53" height="241.898" transform="rotate(45 829.492 396.033)" fill="black"/>
+<rect x="865.465" y="828.99" width="53" height="240.82" transform="rotate(135 865.465 828.99)" fill="black"/>
+<rect x="1096.78" y="1059.3" width="53" height="280" transform="rotate(135 1096.78 1059.3)" fill="black"/>
+<rect x="401.691" y="364.215" width="53" height="280" transform="rotate(135 401.691 364.215)" fill="black"/>
+<rect x="604.754" y="567.277" width="53" height="242.176" transform="rotate(135 604.754 567.277)" fill="black"/>
+<rect x="1263" y="605" width="53" height="280" transform="rotate(90 1263 605)" fill="#A6DA95"/>
+<rect x="280" y="605" width="53" height="280" transform="rotate(90 280 605)" fill="#A6DA95"/>
+</g>
+<defs>
+<clipPath id="clip0_6690_17">
+<rect width="1263" height="1263" fill="white"/>
+</clipPath>
+</defs>
+</svg>
diff --git a/sites/main/src/images/inactive.svg b/sites/main/src/images/inactive.svg
new file mode 100644
index 0000000..245e89d
--- /dev/null
+++ b/sites/main/src/images/inactive.svg
@@ -0,0 +1,25 @@
+<svg width="1263" height="1263" viewBox="0 0 1263 1263" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g clip-path="url(#clip0_6690_17)">
+<rect x="605" y="325" width="53" height="242" fill="black"/>
+<rect x="605" width="53" height="280" fill="black"/>
+<rect x="605" y="983" width="53" height="280" fill="black"/>
+<rect x="605" y="695" width="53" height="243" fill="black"/>
+<rect x="1059.3" y="166.224" width="53" height="280" transform="rotate(45 1059.3 166.224)" fill="#ED8796"/>
+<rect x="567" y="605" width="53" height="242" transform="rotate(90 567 605)" fill="black"/>
+<rect x="364.215" y="861.31" width="53" height="280" transform="rotate(45 364.215 861.31)" fill="#ED8796"/>
+<rect x="938" y="605" width="53" height="242" transform="rotate(90 938 605)" fill="black"/>
+<rect x="567.652" y="657.873" width="53" height="242.704" transform="rotate(45 567.652 657.873)" fill="#ED8796"/>
+<rect x="829.492" y="396.033" width="53" height="241.898" transform="rotate(45 829.492 396.033)" fill="#ED8796"/>
+<rect x="865.465" y="828.99" width="53" height="240.82" transform="rotate(135 865.465 828.99)" fill="#ED8796"/>
+<rect x="1096.78" y="1059.3" width="53" height="280" transform="rotate(135 1096.78 1059.3)" fill="#ED8796"/>
+<rect x="401.691" y="364.215" width="53" height="280" transform="rotate(135 401.691 364.215)" fill="#ED8796"/>
+<rect x="604.754" y="567.277" width="53" height="242.176" transform="rotate(135 604.754 567.277)" fill="#ED8796"/>
+<rect x="1263" y="605" width="53" height="280" transform="rotate(90 1263 605)" fill="black"/>
+<rect x="280" y="605" width="53" height="280" transform="rotate(90 280 605)" fill="black"/>
+</g>
+<defs>
+<clipPath id="clip0_6690_17">
+<rect width="1263" height="1263" fill="white"/>
+</clipPath>
+</defs>
+</svg>
diff --git a/sites/main/src/images/wip.svg b/sites/main/src/images/wip.svg
new file mode 100644
index 0000000..4316f66
--- /dev/null
+++ b/sites/main/src/images/wip.svg
@@ -0,0 +1,25 @@
+<svg width="1263" height="1263" viewBox="0 0 1263 1263" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g clip-path="url(#clip0_6690_17)">
+<rect x="605" y="325" width="53" height="242" fill="black"/>
+<rect x="605" width="53" height="280" fill="black"/>
+<rect x="605" y="983" width="53" height="280" fill="black"/>
+<rect x="605" y="695" width="53" height="243" fill="black"/>
+<rect x="1059.3" y="166.224" width="53" height="280" transform="rotate(45 1059.3 166.224)" fill="#EED49F"/>
+<rect x="567" y="605" width="53" height="242" transform="rotate(90 567 605)" fill="black"/>
+<rect x="364.215" y="861.31" width="53" height="280" transform="rotate(45 364.215 861.31)" fill="#EED49F"/>
+<rect x="938" y="605" width="53" height="242" transform="rotate(90 938 605)" fill="black"/>
+<rect x="567.652" y="657.873" width="53" height="242.704" transform="rotate(45 567.652 657.873)" fill="#EED49F"/>
+<rect x="829.492" y="396.033" width="53" height="241.898" transform="rotate(45 829.492 396.033)" fill="#EED49F"/>
+<rect x="865.465" y="828.99" width="53" height="240.82" transform="rotate(135 865.465 828.99)" fill="black"/>
+<rect x="1096.78" y="1059.3" width="53" height="280" transform="rotate(135 1096.78 1059.3)" fill="black"/>
+<rect x="401.691" y="364.215" width="53" height="280" transform="rotate(135 401.691 364.215)" fill="black"/>
+<rect x="604.754" y="567.277" width="53" height="242.176" transform="rotate(135 604.754 567.277)" fill="black"/>
+<rect x="1263" y="605" width="53" height="280" transform="rotate(90 1263 605)" fill="black"/>
+<rect x="280" y="605" width="53" height="280" transform="rotate(90 280 605)" fill="black"/>
+</g>
+<defs>
+<clipPath id="clip0_6690_17">
+<rect width="1263" height="1263" fill="white"/>
+</clipPath>
+</defs>
+</svg>
diff --git a/sites/main/src/layouts/Layout.astro b/sites/main/src/layouts/Layout.astro
new file mode 100644
index 0000000..9ac61b0
--- /dev/null
+++ b/sites/main/src/layouts/Layout.astro
@@ -0,0 +1,30 @@
+---
+interface Props {
+	title: string;
+}
+
+const { title } = Astro.props;
+---
+
+<!doctype html>
+<html lang="en">
+	<head>
+		<meta charset="UTF-8" />
+		<meta name="description" content="Samuel Shuert's main site" />
+		<meta name="viewport" content="width=device-width" />
+		<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
+		<meta name="generator" content={Astro.generator} />
+		<title>{title}</title>
+	</head>
+	<body class="bg-mantle flex justify-center">
+		<main class="flex justify-center my-4 mx-4 w-full flex-col gap-2 lg:w-[1024px]">
+			<slot />
+		</main>
+	</body>
+</html>
+<style is:global>
+	@import url('https://fonts.googleapis.com/css2?family=Fira+Code:wght@300..700&display=swap');
+	:root {
+		font-family: 'Fira Code', sans-serif;
+	}
+</style>
diff --git a/sites/main/src/pages/index.astro b/sites/main/src/pages/index.astro
new file mode 100644
index 0000000..1075435
--- /dev/null
+++ b/sites/main/src/pages/index.astro
@@ -0,0 +1,68 @@
+---
+import Layout from '../layouts/Layout.astro';
+import Project, { Status } from '../components/Project.astro';
+import active from '../images/active.svg'
+import inactive from '../images/inactive.svg'
+import wip from '../images/wip.svg'
+
+---
+
+<Layout title='TheCodedProf'>
+	<!--ABOUT ME-->
+	<h1 id="About" class="text-text text-2xl">About Me:</h1>
+	<div class="h-[3px] bg-surface2" />
+	<p class="text-text text-sm m-1">
+		Hi, my name's Samuel and I'm a full stack dev (and more) based in Delaware. I collect makeship
+		plushies, metal mugs, card decks, and some other trinkets. I also enjoy playing video games
+		from time to time.
+		<br />
+		<br />
+		I'm always looking for work so feel free to hit me up at any of my socials down below!
+	</p>
+
+	<!--PROJECTS-->
+	<h1 id="Projects" class="text-text text-2xl mt-6">Projects:</h1>
+	<div class="h-[3px] bg-surface2" />
+	<div id="key" class="w-full flex gap-6 justify-center items-center">
+		<p class="text-xs text-text -mr-4">Key:</p>
+		<div class="flex text-xs text-text h-fit w-fit items-center space-x-1"><img src={active.src} alt="cross" class="h-6"/><p>Active</p></div>
+		<div class="flex text-xs text-text h-fit w-fit items-center space-x-1"><img src={wip.src} alt="cross" class="h-6"/><p>Inactive</p></div>
+		<div class="flex text-xs text-text h-fit w-fit items-center space-x-1"><img src={inactive.src} alt="cross" class="h-6"/><p>WIP</p></div>
+	</div>
+	<div class="flex flex-wrap justify-center h-fit">
+		<Project name='Chimera' url='https://git.clicks.codes/plugins/gitiles/Chimera/NixFiles' status={Status.Active}>
+			Personal Nix configuration for me and my friends systems using Snowfall lib.
+		</Project>
+		<Project name="thecoded.prof suite" url="https://git.clicks.codes/plugins/gitiles/Coded/thecoded.prof/" status={Status.Active}>
+			My series of websites, including this one and my blog.
+		</Project>
+		<Project name="Clicks.Codes" url="https://git.clicks.codes/plugins/gitiles/Clicks/clicks.codes/" status={Status.Active}>
+			The main page for ClicksCodes, a programming group run by me and some of my friends.
+		</Project>
+		<Project name="Clicks Nix" url="https://git.clicks.codes/plugins/gitiles/Infra/NixFiles/" status={Status.Active}>
+			Nix configuration for Clicks Server.
+		</Project>
+		<Project name="NixFiles" url="https://git.clicks.codes/plugins/gitiles/Coded/nixConfig/" status={Status.Inactive}>
+			My old Nix configuration, deprecated since move to Chimera.
+		</Project>
+		<Project name="Nucleus" url="https://git.clicks.codes/plugins/gitiles/Clicks/Nucleus/" status={Status.Inactive}>
+			Moderation bot for Discord. Written with the Clicks group.
+		</Project>
+		<Project name="Innuendo" url="https://github.com/ClicksCodes/gone-pear-shaped" status={Status.Inactive}>
+			CAH bot for Discord.
+		</Project>
+		<Project name="Neat" url="https://git.clicks.codes/q/project:Chimera/Neat" status={Status.WIP}>
+			A set of windows for use as top bars, app runners, etc in Chimera.
+		</Project>
+	</div>
+
+	<!--Contacts/Socials-->
+	<h1 id="Projects" class="text-text text-2xl mt-6">Contact Me:</h1>
+	<div class="h-[3px] bg-surface2" />
+	<div class="flex flex-col gap-1">
+		<p class="text-text text-sm">Discord: @thecodedprof</p>
+		<p class="text-text text-sm">Matrix: <a href="https://matrix.to/#/@coded:clicks.codes" class="text-blue">@coded:clicks.codes</a></p>
+		<p class="text-text text-sm">Email: <a href="mailto:me@thecoded.prof" class="text-blue">me@thecoded.prof</a></p>
+		<p class="text-text text-sm">Text: <a href="sms:+12673426954" class="text-blue">+1(267)342-6954</a></p>
+	</div>
+</Layout>
\ No newline at end of file
diff --git a/sites/main/tailwind.config.mjs b/sites/main/tailwind.config.mjs
new file mode 100644
index 0000000..6c4b859
--- /dev/null
+++ b/sites/main/tailwind.config.mjs
@@ -0,0 +1,10 @@
+/** @type {import('tailwindcss').Config} */
+export default {
+	content: ['./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}'],
+	theme: {
+		extend: {},
+	},
+	plugins: [require("@catppuccin/tailwindcss")({
+		defaultFlavour: "macchiato",
+	})],
+}
diff --git a/sites/main/tsconfig.json b/sites/main/tsconfig.json
new file mode 100644
index 0000000..3fd7ae6
--- /dev/null
+++ b/sites/main/tsconfig.json
@@ -0,0 +1,3 @@
+{
+  "extends": "astro/tsconfigs/strictest"
+}
\ No newline at end of file