summaryrefslogtreecommitdiff
path: root/assets
diff options
context:
space:
mode:
authordelta <darkussdelta@gmail.com>2025-02-03 22:58:46 +0100
committerdelta <darkussdelta@gmail.com>2025-02-03 22:58:46 +0100
commit41a6d16ef6a356bc286b0eafe267d04aeed174f3 (patch)
tree86fe71416dc5f802bacec930f9afadd453824423 /assets
initial commit
Diffstat (limited to 'assets')
-rw-r--r--assets/css/404.css13
-rw-r--r--assets/css/index.css198
-rw-r--r--assets/css/posts.css7
-rw-r--r--assets/css/reset.css48
-rw-r--r--assets/icons/apple-touch-icon.pngbin0 -> 4938 bytes
-rw-r--r--assets/icons/favicon-16x16.pngbin0 -> 347 bytes
-rw-r--r--assets/icons/favicon-32x32.pngbin0 -> 675 bytes
-rw-r--r--assets/js/live.js225
-rw-r--r--assets/js/main.js41
9 files changed, 532 insertions, 0 deletions
diff --git a/assets/css/404.css b/assets/css/404.css
new file mode 100644
index 0000000..b75ef00
--- /dev/null
+++ b/assets/css/404.css
@@ -0,0 +1,13 @@
+main {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+main > div {
+ text-align: center;
+}
+
+main > div > div {
+ color: var(--fg-low);
+}
diff --git a/assets/css/index.css b/assets/css/index.css
new file mode 100644
index 0000000..9f9ce62
--- /dev/null
+++ b/assets/css/index.css
@@ -0,0 +1,198 @@
+:root {
+ --font: "Iosevka Comfy Duo";
+
+ --fg-low: oklch(70% 0.01368 253.09);
+ --fg: oklch(80% 0.01368 253.09);
+ --fg-high: oklch(90% 0.01368 253.09);
+
+ --bg-lowest: oklch(15% 0.01368 253.09);
+ --bg-low: oklch(17.5% 0.01368 253.09);
+ --bg: oklch(20% 0.01368 253.09);
+ --bg-high: oklch(22.5% 0.01368 253.09);
+ --bg-highest: oklch(25% 0.01368 253.09);
+
+ --border: oklch(35% 0.023 253.09);
+ --border-variant: oklch(30% 0.023 253.09);
+
+ --red: oklch(80% 0.15765 24.728);
+ --red-bright: oklch(90% 0.15765 24.728);
+ --orange: oklch(80% 0.139 45.216);
+ --orange-bright: oklch(90% 0.139 45.216);
+ --yellow: oklch(80% 0.12758 76.402);
+ --yellow-bright: oklch(90% 0.12758 76.402);
+ --green: oklch(80% 0.11211 147.63);
+ --green-bright: oklch(90% 0.11211 147.63);
+ --cyan: oklch(80% 0.09919 181.49);
+ --cyan-bright: oklch(90% 0.09919 181.49);
+ --blue: oklch(80% 0.09994 249.58);
+ --blue-bright: oklch(90% 0.09994 249.58);
+ --purple: oklch(80% 0.09923 296.61);
+ --purple-bright: oklch(90% 0.09923 296.61);
+ --pink: oklch(80% 0.06662 9.2146);
+ --pink-bright: oklch(90% 0.06662 9.2146);
+
+ --border-radius: 5px;
+ --border-width: 2px;
+ --padding: 5px;
+ --padding-big: 10px;
+}
+
+body {
+ font-family: "Iosevka Comfy Duo";
+ background-color: var(--bg);
+ color: var(--fg);
+ display: flex;
+ gap: var(--padding-big);
+ min-height: 100vh;
+ padding: var(--padding-big);
+ box-sizing: border-box;
+ position: relative;
+}
+
+#lower {
+ --bar-size: 0.3em;
+ position: absolute;
+ z-index: -1;
+ bottom: 0;
+ right: 0;
+ aspect-ratio: 1 / 1;
+ height: calc(var(--bar-size) * 14); /* magic number */
+ background-image: linear-gradient(
+ -45deg,
+ transparent,
+ transparent var(--bar-size),
+ var(--blue) var(--bar-size),
+ var(--blue) calc(var(--bar-size) * 2),
+ transparent calc(var(--bar-size) * 2),
+ transparent calc(var(--bar-size) * 3),
+ var(--green) calc(var(--bar-size) * 3),
+ var(--green) calc(var(--bar-size) * 4),
+ transparent calc(var(--bar-size) * 4),
+ transparent calc(var(--bar-size) * 5),
+ var(--yellow) calc(var(--bar-size) * 5),
+ var(--yellow) calc(var(--bar-size) * 6),
+ transparent calc(var(--bar-size) * 6),
+ transparent calc(var(--bar-size) * 7),
+ var(--orange) calc(var(--bar-size) * 7),
+ var(--orange) calc(var(--bar-size) * 8),
+ transparent calc(var(--bar-size) * 8),
+ transparent calc(var(--bar-size) * 9),
+ var(--red) calc(var(--bar-size) * 9),
+ var(--red) calc(var(--bar-size) * 10),
+ transparent calc(var(--bar-size) * 10)
+ );
+}
+
+/*
+ * failsafe for when the viewport is too small and the rainbow overlaps the text
+ */
+main > div,
+footer > span {
+ background-color: var(--bg);
+}
+
+#upper {
+ display: flex;
+ flex-direction: column;
+ flex-grow: 1;
+}
+
+#upper > div {
+ flex-grow: 1;
+ display: flex;
+ flex-direction: column;
+ gap: var(--padding-big);
+ align-items: center;
+}
+
+.subtle {
+ color: var(--fg-low);
+}
+
+main {
+ flex-grow: 1;
+ width: 80vw;
+ line-height: 1.5;
+}
+
+nav > ul {
+ display: flex;
+}
+
+main,
+nav {
+ padding: var(--padding-big);
+}
+
+nav li:not(:last-of-type)::after,
+footer > span:not(:last-of-type)::after {
+ content: "|";
+ margin-left: var(--padding);
+ margin-right: var(--padding);
+ color: var(--border);
+}
+
+footer {
+ text-align: center;
+ padding: var(--padding);
+ font-size: 0.8em;
+}
+
+a,
+a:link {
+ color: var(--yellow);
+}
+
+a:visited {
+ color: var(--pink);
+}
+
+a:focus,
+a:hover {
+ color: var(--yellow-bright);
+}
+
+a:active {
+ color: var(--yellow);
+}
+
+h1 {
+ font-size: 1.5em;
+ margin-bottom: calc(var(--padding-big) * 2);
+}
+
+h2 {
+ font-size: 1.25em;
+ margin-bottom: calc(var(--padding-big) * 1.5);
+}
+
+p:not(:last-of-type) {
+ margin-bottom: var(--padding-big);
+}
+
+main li {
+ margin-left: var(--padding-big);
+ list-style-type: "- ";
+ list-style-position: inside;
+}
+
+main li::marker {
+ color: var(--border);
+}
+
+main ol,
+main ul {
+ padding-top: var(--padding);
+ gap: var(--padding);
+ display: flex;
+ flex-direction: column;
+}
+
+main ol:not(:last-child),
+main ul:not(:last-child) {
+ margin-bottom: var(--padding-big);
+}
+
+strong {
+ font-weight: bold;
+}
diff --git a/assets/css/posts.css b/assets/css/posts.css
new file mode 100644
index 0000000..50ca347
--- /dev/null
+++ b/assets/css/posts.css
@@ -0,0 +1,7 @@
+.list > li {
+ margin-left: 0;
+}
+
+.list > li > span {
+ float: right;
+}
diff --git a/assets/css/reset.css b/assets/css/reset.css
new file mode 100644
index 0000000..e29c0f5
--- /dev/null
+++ b/assets/css/reset.css
@@ -0,0 +1,48 @@
+/* http://meyerweb.com/eric/tools/css/reset/
+ v2.0 | 20110126
+ License: none (public domain)
+*/
+
+html, body, div, span, applet, object, iframe,
+h1, h2, h3, h4, h5, h6, p, blockquote, pre,
+a, abbr, acronym, address, big, cite, code,
+del, dfn, em, img, ins, kbd, q, s, samp,
+small, strike, strong, sub, sup, tt, var,
+b, u, i, center,
+dl, dt, dd, ol, ul, li,
+fieldset, form, label, legend,
+table, caption, tbody, tfoot, thead, tr, th, td,
+article, aside, canvas, details, embed,
+figure, figcaption, footer, header, hgroup,
+menu, nav, output, ruby, section, summary,
+time, mark, audio, video {
+ margin: 0;
+ padding: 0;
+ border: 0;
+ font-size: 100%;
+ font: inherit;
+ vertical-align: baseline;
+}
+/* HTML5 display-role reset for older browsers */
+article, aside, details, figcaption, figure,
+footer, header, hgroup, menu, nav, section {
+ display: block;
+}
+body {
+ line-height: 1;
+}
+ol, ul {
+ list-style: none;
+}
+blockquote, q {
+ quotes: none;
+}
+blockquote:before, blockquote:after,
+q:before, q:after {
+ content: '';
+ content: none;
+}
+table {
+ border-collapse: collapse;
+ border-spacing: 0;
+}
diff --git a/assets/icons/apple-touch-icon.png b/assets/icons/apple-touch-icon.png
new file mode 100644
index 0000000..bfdf6cc
--- /dev/null
+++ b/assets/icons/apple-touch-icon.png
Binary files differ
diff --git a/assets/icons/favicon-16x16.png b/assets/icons/favicon-16x16.png
new file mode 100644
index 0000000..adba0ac
--- /dev/null
+++ b/assets/icons/favicon-16x16.png
Binary files differ
diff --git a/assets/icons/favicon-32x32.png b/assets/icons/favicon-32x32.png
new file mode 100644
index 0000000..af10188
--- /dev/null
+++ b/assets/icons/favicon-32x32.png
Binary files differ
diff --git a/assets/js/live.js b/assets/js/live.js
new file mode 100644
index 0000000..a015d05
--- /dev/null
+++ b/assets/js/live.js
@@ -0,0 +1,225 @@
+/*
+ Live.js - One script closer to Designing in the Browser
+ Written for Handcraft.com by Martin Kool (@mrtnkl).
+
+ Version 4.
+ Recent change: Made stylesheet and mimetype checks case insensitive.
+
+ http://livejs.com
+ http://livejs.com/license (MIT)
+ @livejs
+
+ Include live.js#css to monitor css changes only.
+ Include live.js#js to monitor js changes only.
+ Include live.js#html to monitor html changes only.
+ Mix and match to monitor a preferred combination such as live.js#html,css
+
+ By default, just include live.js to monitor all css, js and html changes.
+
+ Live.js can also be loaded as a bookmarklet. It is best to only use it for CSS then,
+ as a page reload due to a change in html or css would not re-include the bookmarklet.
+ To monitor CSS and be notified that it has loaded, include it as: live.js#css,notify
+*/
+(function () {
+ var headers = { Etag: 1, "Last-Modified": 1, "Content-Length": 1, "Content-Type": 1 },
+ resources = {},
+ pendingRequests = {},
+ currentLinkElements = {},
+ oldLinkElements = {},
+ interval = 1000,
+ loaded = false,
+ active = { html: 1, css: 1, js: 1 };
+
+ var Live = {
+ // performs a cycle per interval
+ heartbeat: function () {
+ if (document.body) {
+ // make sure all resources are loaded on first activation
+ if (!loaded) Live.loadresources();
+ Live.checkForChanges();
+ }
+ setTimeout(Live.heartbeat, interval);
+ },
+
+ // loads all local css and js resources upon first activation
+ loadresources: function () {
+ // helper method to assert if a given url is local
+ function isLocal(url) {
+ var loc = document.location,
+ reg = new RegExp("^\\.|^\/(?!\/)|^[\\w]((?!://).)*$|" + loc.protocol + "//" + loc.host);
+ return url.match(reg);
+ }
+
+ // gather all resources
+ var scripts = document.getElementsByTagName("script"),
+ links = document.getElementsByTagName("link"),
+ uris = [];
+
+ // track local js urls
+ for (var i = 0; i < scripts.length; i++) {
+ var script = scripts[i],
+ src = script.getAttribute("src");
+ if (src && isLocal(src)) uris.push(src);
+ if (src && src.match(/\blive.js#/)) {
+ for (var type in active) active[type] = src.match("[#,|]" + type) != null;
+ if (src.match("notify")) alert("Live.js is loaded.");
+ }
+ }
+ if (!active.js) uris = [];
+ if (active.html) uris.push(document.location.href);
+
+ // track local css urls
+ for (var i = 0; i < links.length && active.css; i++) {
+ var link = links[i],
+ rel = link.getAttribute("rel"),
+ href = link.getAttribute("href", 2);
+ if (href && rel && rel.match(new RegExp("stylesheet", "i")) && isLocal(href)) {
+ uris.push(href);
+ currentLinkElements[href] = link;
+ }
+ }
+
+ // initialize the resources info
+ for (var i = 0; i < uris.length; i++) {
+ var url = uris[i];
+ Live.getHead(url, function (url, info) {
+ resources[url] = info;
+ });
+ }
+
+ // add rule for morphing between old and new css files
+ var head = document.getElementsByTagName("head")[0],
+ style = document.createElement("style"),
+ rule = "transition: all .3s ease-out;";
+ css = [".livejs-loading * { ", rule, " -webkit-", rule, "-moz-", rule, "-o-", rule, "}"].join("");
+ style.setAttribute("type", "text/css");
+ head.appendChild(style);
+ style.styleSheet ? (style.styleSheet.cssText = css) : style.appendChild(document.createTextNode(css));
+
+ // yep
+ loaded = true;
+ },
+
+ // check all tracking resources for changes
+ checkForChanges: function () {
+ for (var url in resources) {
+ if (pendingRequests[url]) continue;
+
+ Live.getHead(url, function (url, newInfo) {
+ var oldInfo = resources[url],
+ hasChanged = false;
+ resources[url] = newInfo;
+ for (var header in oldInfo) {
+ // do verification based on the header type
+ var oldValue = oldInfo[header],
+ newValue = newInfo[header],
+ contentType = newInfo["Content-Type"];
+ switch (header.toLowerCase()) {
+ case "etag":
+ if (!newValue) break;
+ // fall through to default
+ default:
+ hasChanged = oldValue != newValue;
+ break;
+ }
+ // if changed, act
+ if (hasChanged) {
+ Live.refreshResource(url, contentType);
+ break;
+ }
+ }
+ });
+ }
+ },
+
+ // act upon a changed url of certain content type
+ refreshResource: function (url, type) {
+ switch (type.toLowerCase()) {
+ // css files can be reloaded dynamically by replacing the link element
+ case "text/css":
+ var link = currentLinkElements[url],
+ html = document.body.parentNode,
+ head = link.parentNode,
+ next = link.nextSibling,
+ newLink = document.createElement("link");
+
+ html.className = html.className.replace(/\s*livejs\-loading/gi, "") + " livejs-loading";
+ newLink.setAttribute("type", "text/css");
+ newLink.setAttribute("rel", "stylesheet");
+ newLink.setAttribute("href", url + "?now=" + new Date() * 1);
+ next ? head.insertBefore(newLink, next) : head.appendChild(newLink);
+ currentLinkElements[url] = newLink;
+ oldLinkElements[url] = link;
+
+ // schedule removal of the old link
+ Live.removeoldLinkElements();
+ break;
+
+ // check if an html resource is our current url, then reload
+ case "text/html":
+ if (url != document.location.href) return;
+
+ // local javascript changes cause a reload as well
+ case "text/javascript":
+ case "application/javascript":
+ case "application/x-javascript":
+ document.location.reload();
+ }
+ },
+
+ // removes the old stylesheet rules only once the new one has finished loading
+ removeoldLinkElements: function () {
+ var pending = 0;
+ for (var url in oldLinkElements) {
+ // if this sheet has any cssRules, delete the old link
+ try {
+ var link = currentLinkElements[url],
+ oldLink = oldLinkElements[url],
+ html = document.body.parentNode,
+ sheet = link.sheet || link.styleSheet,
+ rules = sheet.rules || sheet.cssRules;
+ if (rules.length >= 0) {
+ oldLink.parentNode.removeChild(oldLink);
+ delete oldLinkElements[url];
+ setTimeout(function () {
+ html.className = html.className.replace(/\s*livejs\-loading/gi, "");
+ }, 100);
+ }
+ } catch (e) {
+ pending++;
+ }
+ if (pending) setTimeout(Live.removeoldLinkElements, 50);
+ }
+ },
+
+ // performs a HEAD request and passes the header info to the given callback
+ getHead: function (url, callback) {
+ pendingRequests[url] = true;
+ var xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XmlHttp");
+ xhr.open("HEAD", url, true);
+ xhr.onreadystatechange = function () {
+ delete pendingRequests[url];
+ if (xhr.readyState == 4 && xhr.status != 304) {
+ xhr.getAllResponseHeaders();
+ var info = {};
+ for (var h in headers) {
+ var value = xhr.getResponseHeader(h);
+ // adjust the simple Etag variant to match on its significant part
+ if (h.toLowerCase() == "etag" && value) value = value.replace(/^W\//, "");
+ if (h.toLowerCase() == "content-type" && value) value = value.replace(/^(.*?);.*?$/i, "$1");
+ info[h] = value;
+ }
+ callback(url, info);
+ }
+ };
+ xhr.send();
+ },
+ };
+
+ // start listening
+ if (document.location.protocol != "file:") {
+ if (!window.liveJsLoaded) Live.heartbeat();
+
+ window.liveJsLoaded = true;
+ } else if (window.console) console.log("Live.js doesn't support the file protocol. It needs http.");
+})();
diff --git a/assets/js/main.js b/assets/js/main.js
new file mode 100644
index 0000000..5bc2d41
--- /dev/null
+++ b/assets/js/main.js
@@ -0,0 +1,41 @@
+// Toggle the navigation menu and theme
+document.addEventListener("DOMContentLoaded", function () {
+ var menuToggle = document.getElementById("menu-toggle");
+ var mainNav = document.getElementById("main-nav");
+ var themeToggle = document.getElementById("theme-toggle");
+ var body = document.body;
+
+ // Menu toggle functionality
+ menuToggle.addEventListener("click", function () {
+ mainNav.classList.toggle("open");
+ });
+
+ // Theme toggle functionality
+ themeToggle.addEventListener("click", function () {
+ // Toggle between 'light' and 'dark' themes
+ var currentTheme = body.getAttribute("data-theme") || "light";
+ var newTheme = currentTheme === "dark" ? "light" : "dark";
+ body.setAttribute("data-theme", newTheme);
+ localStorage.setItem("theme", newTheme);
+ });
+
+ // On page load, set the theme from localStorage or system preference
+ var storedTheme = localStorage.getItem("theme");
+ if (storedTheme) {
+ body.setAttribute("data-theme", storedTheme);
+ } else {
+ // Detect system preference
+ var prefersDarkScheme = window.matchMedia("(prefers-color-scheme: dark)").matches;
+ var defaultTheme = prefersDarkScheme ? "dark" : "light";
+ body.setAttribute("data-theme", defaultTheme);
+ }
+
+ // Listen for changes in the system color scheme
+ window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", function (e) {
+ var storedTheme = localStorage.getItem("theme");
+ if (!storedTheme) {
+ var newColorScheme = e.matches ? "dark" : "light";
+ body.setAttribute("data-theme", newColorScheme);
+ }
+ });
+});