diff --git a/new/Caddyfile b/new/Caddyfile
new file mode 100644
index 0000000..ae6906e
--- /dev/null
+++ b/new/Caddyfile
@@ -0,0 +1,6 @@
+localhost
+
+file_server
+templates
+
+try_files {path}.html {path}
diff --git a/new/includes/head.html b/new/includes/head.html
new file mode 100644
index 0000000..9152ca8
--- /dev/null
+++ b/new/includes/head.html
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/new/index.html b/new/index.html
new file mode 100644
index 0000000..10a529f
--- /dev/null
+++ b/new/index.html
@@ -0,0 +1,195 @@
+
+
+
+ Caddy - The Ultimate Server with Automatic HTTPS
+ {{include "/includes/head.html"}}
+
+
+
+
+
+
+
+
+

+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/new/resources/css/common.css b/new/resources/css/common.css
new file mode 100644
index 0000000..0ee7eb5
--- /dev/null
+++ b/new/resources/css/common.css
@@ -0,0 +1,305 @@
+* {
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
+}
+
+body {
+ font-family: Inter, system-ui;
+ font-size: 16px;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ tab-size: 4;
+ -moz-tab-size: 4;
+}
+
+.wrapper {
+ max-width: 1400px;
+ margin-left: auto;
+ margin-right: auto;
+}
+
+header {
+ background: rgb(255 255 255 / .1);
+ box-shadow: 0 0 50px rgb(0 0 0 / .2);
+ backdrop-filter: blur(10px);
+}
+
+header a {
+ text-decoration: none;
+}
+
+header .topbar,
+header nav > ul {
+ background: linear-gradient(to right, rgb(100 190 121), rgb(54 206 255));
+ background-clip: text;
+ -webkit-background-clip: text;
+}
+
+.topbar {
+ font-size: 14px;
+ border-bottom: 1px solid hsl(203deg 100% 79% / 20%);
+}
+
+.topbar .wrapper {
+ display: flex;
+ justify-content: flex-end;
+ align-items: center;
+ gap: 1em;
+ color: rgba(255, 255, 255, 0.75);
+}
+
+.topbar a {
+ display: inline-block;
+ padding: 8px;
+ color: inherit;
+ display: flex;
+ align-items: center;
+}
+
+.topbar a:hover {
+ background: rgb(0 0 0 / .5);
+}
+
+.navbar {
+ display: flex;
+ align-items: center;
+ gap: 2em;
+}
+
+nav ul {
+ list-style: none;
+ margin: 0;
+ padding-left: 0;
+ display: flex;
+ align-items: center;
+ gap: 2em;
+ flex: 1;
+}
+
+.topbar,
+.navbar nav > ul > li > a {
+ -webkit-text-fill-color: rgba(0 0 0 / .1);
+}
+
+.topbar a:hover,
+.navbar nav > ul > li > a:hover {
+ -webkit-text-fill-color: rgba(255 255 255 / .4);
+}
+
+.navbar nav > ul > li > a,
+.navbar .button {
+ text-decoration: none;
+ transition: all 250ms;
+ color: inherit;
+ font-weight: 500;
+}
+
+.navbar nav > ul > li > a {
+ padding: 20px 5px;
+ display: block;
+}
+
+.icon {
+ height: 1.4em;
+ vertical-align: middle;
+}
+
+#logo {
+ height: 2.25em;
+}
+
+.navbar .actions {
+ margin-left: auto;
+ display: flex;
+ gap: 1em;
+}
+
+.button {
+ padding: .6em 1.5em;
+ border-radius: 6px;
+ text-decoration: none;
+}
+
+.button.secondary {
+ color: rgb(54 206 255);
+ border: 1px solid rgb(54 206 255);
+}
+
+.button.secondary:hover {
+ color: white;
+}
+
+.button.primary {
+ background: linear-gradient(135deg, white 25%, rgba(167,183,193) 80%);
+ color: #222;
+ box-shadow: 0 2px 8px rgb(0 0 0 / .3);
+}
+
+.button.primary:hover {
+ color: #1a71cb;
+ transform: scale(1.08);
+ box-shadow: 0 4px 15px rgb(0 0 0 / .2);
+}
+
+.button.primary:active {
+ transition: all 100ms;
+ transform: scale(.95);
+ box-shadow: 0 -1px 4px rgb(0 0 0 / .5);
+}
+
+
+
+
+
+#docs-link:hover .dropdown {
+ visibility: visible;
+ opacity: 1;
+ transform-origin: top center;
+ animation: rotateMenu 300ms ease;
+}
+
+@keyframes rotateMenu {
+ 0% { transform: rotateX(-90deg) }
+ 100% { transform: rotateX(0deg) }
+}
+
+
+.dropdown {
+ position: absolute;
+ display: inline-block;
+ background: #e8ecef;
+ border-radius: 15px;
+ line-height: 1.5;
+ overflow: hidden;
+ box-shadow: 0 20px 50px black;
+ transition-duration: .2s;
+ transition-property: opacity, transform;
+ visibility: hidden;
+ opacity: 0;
+ top: calc(100% - 5px);
+ left: 0;
+}
+
+.dropdown .row {
+ display: flex;
+ gap: 1px;
+ margin-bottom: 1px;
+}
+
+.dropdown .plainbox,
+.dropdown .linkbox {
+ display: flex;
+ gap: 4em;
+ padding: 1.5em;
+}
+
+.dropdown .plainbox {
+ padding-top: .5em;
+ width: 100%;
+ justify-content: space-around;
+}
+
+.dropdown .plainbox a {
+ color: #647687;
+}
+
+.dropdown .plainbox a:hover {
+ color: #142633;
+}
+
+.dropdown .linkbox {
+ background: white;
+ gap: 4em;
+}
+
+.dropdown h2 {
+ font-family: Poppins, ui-rounded;
+ font-weight: 500;
+ color: #444;
+ font-size: 22px;
+ margin-bottom: 15px;
+}
+
+.dropdown .col {
+ min-width: 150px;
+}
+
+.dropdown .col a {
+ display: block;
+ color: #647687;
+ text-decoration: none;
+ padding: 5px 0;
+}
+
+
+.dropdown .col a:hover {
+ color: #142633;
+}
+
+.dropdown .flatlinks a {
+ background: white;
+ padding: 1em 2em;
+ color: #647687;
+ font-size: 14px;
+}
+
+.dropdown .flatlinks a b,
+.dropdown .featured a b {
+ display: block;
+ font-size: 16px;
+ font-weight: 600;
+}
+
+.dropdown .flatlinks a b {
+ color: #142633;
+ margin-bottom: .25em;
+}
+
+.dropdown .flatlinks a:hover {
+ background: rgb(239, 244, 248);
+}
+
+.dropdown .featured a b {
+ color: #384f61;
+ margin-bottom: .5em;
+}
+
+.dropdown .featured a:hover b {
+ color: #1e3141;
+}
+
+
+.dropdown .featured {
+ gap: 1em;
+ padding: 1em;
+ /* background: white; */
+}
+
+.dropdown .featured a {
+ display: block;
+ padding: 1em;
+ font-size: 14px;
+ line-height: 1.4;
+ border-radius: 10px;
+ color: #647687;
+ font-size: 14px;
+ background-color: white;
+ background-image: linear-gradient(to bottom, rgb(239 244 247), rgba(252,252,252,0));
+ /* background: linear-gradient(137deg, rgb(241 251 247) 0%, rgb(242 248 255) 100%); */
+ flex: 1;
+ transition: background-color 150ms;
+ box-shadow: 0 1px 2px rgb(0 0 0 / .2);
+}
+
+.dropdown .featured a:hover {
+ background-color: rgb(223, 233, 238); /* rgb(232, 255, 254); */
+}
+
+.dropdown .featured a b {
+ display: block;
+ color: #384f61;
+ font-size: 16px;
+ margin-bottom: .5em;
+ font-weight: 600;
+}
\ No newline at end of file
diff --git a/new/resources/css/home.css b/new/resources/css/home.css
new file mode 100644
index 0000000..09fcca2
--- /dev/null
+++ b/new/resources/css/home.css
@@ -0,0 +1,10 @@
+.hero {
+ background-color: hsla(201,63%,15%,1);
+ background-image:
+ radial-gradient(at 50% 96%, hsla(0,100%,20%,0.35) 0px, transparent 50%),
+ radial-gradient(at 5% 30%, hsla(136,95%,15%,1) 0px, transparent 50%),
+ radial-gradient(at 91% 0%, hsla(214,83%,25%,1) 0px, transparent 50%),
+ radial-gradient(at 82% 73%, hsla(265,72%,20%,1) 0px, transparent 50%);
+
+ min-height: 800px;
+}
\ No newline at end of file
diff --git a/new/resources/images/logo.svg b/new/resources/images/logo.svg
new file mode 100644
index 0000000..40d96f3
--- /dev/null
+++ b/new/resources/images/logo.svg
@@ -0,0 +1,73 @@
+
+
+
diff --git a/new/resources/js/common.js b/new/resources/js/common.js
new file mode 100644
index 0000000..e69de29
diff --git a/new/resources/js/lib.js b/new/resources/js/lib.js
new file mode 100644
index 0000000..03a04ed
--- /dev/null
+++ b/new/resources/js/lib.js
@@ -0,0 +1,82 @@
+// AJQuery: https://github.com/coolaj86/ajquery.js (modified slightly by me)
+function $(sel, el) { return ((typeof el === 'string' ? $(el) : el) || document).querySelector(sel); }
+function $$(sel, el) { return (el || document).querySelectorAll(sel); }
+
+
+function ready(fn) {
+ if (document.readyState !== 'loading') {
+ fn();
+ } else {
+ document.addEventListener('DOMContentLoaded', fn);
+ }
+}
+
+function on(eventName, elemSelector, handler, capture) {
+ let events = [eventName];
+ if (eventName.indexOf(',') >= 0) {
+ events = eventName.split(',');
+ }
+
+ events.forEach(eventName => {
+ // from youmightnotneedjquery.com
+ document.addEventListener(eventName.trim(), function (e) {
+ // loop parent nodes from the target to the delegation node
+ for (let target = e.target; target && target != this; target = target.parentNode) {
+ if (NodeList.prototype.isPrototypeOf(elemSelector)) {
+ for (el of elemSelector) {
+ if (el == target) {
+ handler.call(target, e);
+ return;
+ }
+ }
+ } else if (!elemSelector || target.matches(elemSelector)) {
+ handler.call(target, e);
+ return;
+ }
+ }
+ }, capture); // I find capture=true helpful when using :not() selectors to exclude one elem of the node tree
+ });
+}
+
+function trigger(el, eventType) {
+ if (typeof el === 'string') {
+ el = $(el); // assume it was a selector, for convenience
+ }
+
+ // from youmightnotneedjquery.com
+ if (typeof eventType === 'string' && typeof el[eventType] === 'function') {
+ el[eventType]();
+ } else {
+ const event =
+ typeof eventType === 'string'
+ ? new Event(eventType, { bubbles: true, cancelable: true })
+ : eventType;
+ el.dispatchEvent(event);
+ }
+}
+
+// cloneTemplate does a deep clone of the tag selected by tplSelector.
+function cloneTemplate(tplSelector) {
+ // Ohhhhhh wow, we need to use firstElementChild when cloning the content of a template tag (!!!!):
+ // https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template#avoiding_documentfragment_pitfall
+ // I spent way too long on this.
+ const elem = $(tplSelector);
+ if (!elem) return;
+ return elem.content.firstElementChild.cloneNode(true);
+ // return document.importNode(elem.content, true);
+}
+
+// isVisible returns true if elem (an element or selector) is visible.
+function isVisible(elem) {
+ if (typeof elem === 'string') {
+ elem = $(elem);
+ }
+ return elem.offsetParent !== null;
+}
+
+// queryParam returns the named query string parameter's value(s).
+function queryParam(name) {
+ const urlSearchParams = new URLSearchParams(window.location.search);
+ const params = Object.fromEntries(urlSearchParams.entries());
+ return params[name];
+}
\ No newline at end of file