Initial Release

This commit is contained in:
2026-05-24 19:52:45 -07:00
commit 8242fdbbb3
181 changed files with 10119 additions and 0 deletions
+59
View File
@@ -0,0 +1,59 @@
package include
import (
"embed"
"io"
"io/fs"
"log"
"os"
"path"
"strings"
)
var (
//go:embed public/*
embedPublic embed.FS
//go:embed templates/*
embedTemplates embed.FS
Embedded = true
Templates fs.FS
Public fs.FS
)
func init() {
if strings.Contains(os.Args[0], "go-build") {
Embedded = false
}
if Embedded {
Templates = embedTemplates
Public = embedPublic
} else {
log.Println("[include] In Debug Mode, using local filesystem!")
Templates = os.DirFS("include/templates")
Public = os.DirFS("include/public")
}
}
func PreparePath(fsys fs.FS, filepath string) string {
filepath = path.Clean(filepath)
if Embedded {
// If using embed, prepend the folder name automatically if missing
switch {
case fsys == Public && !strings.HasPrefix(filepath, "public/"):
filepath = path.Join("public", filepath)
case fsys == Templates && !strings.HasPrefix(filepath, "templates/"):
filepath = path.Join("templates", filepath)
}
}
return filepath
}
func ReadFile(fsys fs.FS, filepath string) ([]byte, error) {
f, err := fsys.Open(PreparePath(fsys, filepath))
if err != nil {
return nil, err
}
defer f.Close()
return io.ReadAll(f)
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 99.11 94.5" fill="#f0f0f0">
<path d="M99.01,35.85c-.24-.72-.86-1.25-1.62-1.36l-31.83-4.57L51.29,1.11c-.34-.68-1.03-1.11-1.79-1.11h0c-.76,0-1.46.43-1.79,1.12l-14.18,28.85L1.71,34.65c-.75.11-1.38.64-1.61,1.36-.23.72-.04,1.52.51,2.05l23.06,22.41-5.38,31.7c-.13.75.18,1.51.8,1.96.35.25.76.38,1.17.38.32,0,.64-.08.93-.23l28.43-15.01,28.48,14.92c.67.35,1.49.29,2.11-.16.62-.45.92-1.21.79-1.96l-5.49-31.68,22.99-22.48c.54-.53.74-1.33.5-2.05Z" />
</svg>

After

Width:  |  Height:  |  Size: 502 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

@@ -0,0 +1,5 @@
# \_/
# ()o_o) <( beep boop )
User-agent: *
Disallow:
@@ -0,0 +1,115 @@
// @ts-check
(() => { // Table of Content Highlights
/** @type {HTMLDivElement | null} */
const parentChapter = document.querySelector("div.article-chapters")
/** @type {HTMLDivElement | null} */
const parentArticle = document.querySelector("div.article-content")
if (!parentChapter || !parentArticle) return
/** @type {Array<{ o: number; e: Array<Element | null> }>} */
let scrollSections = []
let scrollHeader = null
let scrollOffset = 0
// Generate Table of Contents
for (const child of parentArticle.children) {
const offset = (child.getBoundingClientRect().top + window.scrollY + scrollOffset) | 0
const normal = child.textContent.toString().toLocaleLowerCase().replaceAll(" ", "-")
if (child.classList.contains("element-header")) {
const anchor = document.createElement("a")
anchor.classList.add("chapter")
anchor.textContent = child.textContent
anchor.href = "#" + normal
child.id = normal
parentChapter.appendChild(anchor)
scrollSections.push({ o: offset, e: [anchor] })
scrollHeader = anchor
scrollOffset += 36 // bandaid fix for desync
}
if (child.classList.contains("element-subheader")) {
const anchor = document.createElement("a")
anchor.classList.add("section")
anchor.textContent = child.textContent
anchor.href = "#" + normal
child.id = normal
parentChapter.appendChild(anchor)
scrollSections.push({ o: offset, e: [scrollHeader, anchor] })
}
}
// Update Highlight when Page Scrolls
function pageScroll() {
const winoffset = window.innerHeight / 5
const position = window.scrollY + winoffset
let closest = null
let closestDist = Infinity
// Find Closest Header
for (const section of scrollSections) {
const dist = Math.abs(position - section.o)
if (dist < closestDist) {
closestDist = dist
closest = section
}
for (const elem of section.e) {
// Reset Styling
elem && elem.removeAttribute("selected")
}
}
// Apply Header Styling
if (closest) {
for (const elem of closest.e) {
elem && elem.setAttribute("selected", "")
}
}
}
window.addEventListener("scroll", pageScroll)
pageScroll()
})();
(() => { // Share Button
/** @type {HTMLButtonElement | null} */
const shareButton = document.querySelector("a#button-share")
/** @type {HTMLDialogElement | null} */
const shareModal = document.querySelector("dialog.layout-dialog")
// UX: Close Modal if Background is clicked or pressed
shareModal && shareModal.addEventListener("click", ev => {
if (ev.target === shareModal) {
shareModal.close()
}
})
// UX: Open Native Modal on Mobile, Custom Modal on Desktop
shareButton && shareButton.addEventListener("click", ev => {
ev.preventDefault()
// Use Native Modal
const isMobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent)
if (isMobile) {
const metaTitle = document.querySelector(`meta[property="og:title"]`)?.getAttribute("content")
const metaURL = document.querySelector(`meta[property="og:url"]`)?.getAttribute("content")
if (typeof (metaURL) !== "string" || typeof (metaTitle) !== "string") {
alert("Missing Required Metadata")
return
}
navigator.share({ title: metaTitle, url: metaURL })
return
}
// Use Desktop Modal
if (shareModal) {
shareModal.showModal()
}
})
})();
@@ -0,0 +1,240 @@
div.layout-content {
margin-bottom: 50vw;
}
/* Modal */
dialog.layout-dialog {
position: fixed;
z-index: 999;
width: 100%;
height: 100%;
background-color: rgba(var(--rgb-background), .5);
}
div.layout-modal {
width: 480px;
height: fit-content;
position: relative;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
padding: 16px;
box-sizing: border-box;
}
div.modal-header {
display: flex;
justify-content: space-between;
align-items: start;
margin-bottom: 16px;
}
div.modal-header>p {
color: rgba(var(--rgb-accent), 1);
font-size: x-large;
font-weight: 600;
}
div.modal-header>form>button {
background: transparent;
color: rgba(var(--rgb-text), 1);
font-size: x-large;
border: none;
}
div.modal-header>form>button:hover,
div.modal-header>form>button:focus-visible {
color: rgba(var(--rgb-accent), 1);
cursor: pointer;
}
div.modal-content {
display: flex;
gap: 8px;
justify-content: center;
}
div.modal-content>input {
height: 40px;
padding: 0 8px;
box-sizing: border-box;
border: 1px solid rgba(var(--rgb-accent), 1);
background: transparent;
flex-basis: 100%;
font-family: monospace;
color: rgba(var(--rgb-text), 1);
}
div.modal-content>a {
fill: rgba(var(--rgb-text), 1);
border: 1px solid rgba(var(--rgb-accent), 1);
box-sizing: border-box;
padding: 8px 0;
flex-basis: 100%;
max-width: 40px;
height: 40px;
line-height: 24px;
}
div.modal-content>a:hover,
div.modal-content>a:focus-visible {
background: rgba(var(--rgb-accent), 1);
}
div.modal-content>a>svg {
fill: rgba(var(--rgb-accent), 1);
display: block;
margin: auto;
height: 24px;
}
div.modal-content>a:hover>svg,
div.modal-content>a:focus-visible>svg {
fill: rgba(var(--rgb-text), 1);
}
/* Navigation */
div.article-actions {
display: flex;
justify-content: center;
gap: 8px;
margin-bottom: 8px;
}
div.article-actions>a {
border: 2px solid rgba(var(--rgb-accent), 1);
box-sizing: border-box;
flex-basis: 100%;
padding: 8px 0;
}
div.article-actions>a>svg {
fill: rgba(var(--rgb-accent), 1);
display: block;
margin: auto;
height: 16px;
}
div.article-actions>a:hover,
div.article-actions>a:focus-visible {
background: rgba(var(--rgb-accent), 1);
}
div.article-actions>a:hover>svg,
div.article-actions>a:focus-visible>svg {
fill: rgba(var(--rgb-text), 1);
}
div.article-chapters {
display: grid;
}
div.article-chapters>a.chapter,
div.article-chapters>a.section {
transition: var(--transition-time) ease-in-out all;
text-decoration: none;
}
div.article-chapters>a.chapter {
margin-left: 16px;
transform: skew(0deg);
}
div.article-chapters>a.chapter:hover,
div.article-chapters>a.chapter:focus-visible {
text-decoration: underline;
}
div.article-chapters>a.chapter[selected] {
position: relative;
letter-spacing: 1px;
}
div.article-chapters>a.chapter[selected]::before {
content: '>';
color: rgba(var(--rgb-accent), 1);
font-size: 24px;
font-weight: bold;
position: absolute;
left: -16px;
}
div.article-chapters>a.section {
margin-left: 32px;
font-size: small;
}
div.article-chapters>a.section:hover,
div.article-chapters>a.section:focus-visible {
text-decoration: underline;
}
div.article-chapters>a.section[selected] {
color: rgba(var(--rgb-accent), 1);
letter-spacing: 1px;
}
/* Article */
div.article-header {
width: 100%;
height: fit-content;
display: grid;
justify-items: center;
}
img.header-banner {
width: 100%;
object-fit: cover;
aspect-ratio: 3/1;
border-bottom: 4px solid rgba(var(--rgb-accent), 1);
}
p.header-title {
word-wrap: break-word;
overflow: hidden;
margin: 16px 0 24px 0;
}
div.header-chevrons {
display: flex;
justify-content: space-between;
width: 100%;
}
div.article-content {
padding: 16px;
display: grid;
gap: 8px;
}
/* Elements */
div.element-divider {
position: relative;
background-color: rgba(var(--rgb-accent), 1);
height: 2px;
margin: 16px 0;
}
div.element-divider::before {
content: '';
transform: translate(-50%, -50%);
position: absolute;
height: 16px;
width: 24px;
left: 50%;
top: 50%;
background: url('/public/divider.svg') rgba(var(--rgb-background), 1) no-repeat center;
padding: 0 4px;
}
p.element-header {
font-size: x-large;
font-weight: 500;
color: rgb(var(--rgb-accent));
}
p.element-subheader {
text-decoration: underline;
font-weight: 500;
color: rgb(var(--rgb-accent));
}
@@ -0,0 +1,82 @@
/* Section: Introduction */
div.browser-introduction {
display: grid;
padding: 16px;
box-sizing: border-box;
gap: 8px;
}
p.intro-header {
font-size: large;
text-align: center;
}
img.intro-banner {
margin: auto;
image-rendering: pixelated;
}
p.intro-disclaimer {
font-size: small;
text-align: center;
color: rgba(var(--rgb-text), 0.8);
}
div.intro-dots {
display: flex;
justify-content: center;
font-size: small;
}
/* Section: Items */
/* div.browser-content {} */
a.browser-item {
display: grid;
text-decoration: none;
}
a.browser-item:not(:hover) .effect-rhombus-animated {
animation: none;
}
div.item-background,
div.item-foreground,
a.item-redirect {
grid-row: 1;
grid-column: 1;
}
div.item-background {
width: 100%;
height: 48px;
background-image: var(--background);
background-size: cover;
background-position: center;
filter: grayscale(1) brightness(0.5);
}
div.item-foreground {
display: flex;
align-items: center;
justify-content: space-between;
padding-left: 8px;
}
p.item-description {
font-size: small;
font-style: italic;
}
/* Section: Footer */
div.browser-footer {
padding: 16px;
box-sizing: border-box;
}
div.browser-footer>p {
width: 100%;
text-align: center;
font-family: monospace;
color: rgba(var(--rgb-text), 0.8);
}
@@ -0,0 +1,270 @@
:root {
--transition-time: 200ms;
--rgb-background: 0, 0, 0;
--rgb-text: 240, 240, 240;
--rgb-accent: 70, 70, 70;
}
body {
background-color: rgba(var(--rgb-background), 1);
margin: 0;
padding: 0;
}
::-webkit-scrollbar {
display: none;
}
a,
p,
span {
display: inline-block;
font-family: "Poppins", sans-serif;
line-height: 1.5em;
font-weight: 400;
color: rgba(var(--rgb-text), 1);
padding: 0;
margin: 0;
}
/* Global Effects */
.effect-caution {
position: relative;
border: 4px solid rgba(var(--rgb-accent), 1);
background-color: rgba(var(--rgb-background), 1);
margin-bottom: 12px;
margin-right: 12px;
}
.effect-caution::before {
content: '';
position: absolute;
left: 0;
top: 0;
right: -16px;
bottom: -16px;
box-sizing: border-box;
filter: brightness(0.5);
background: repeating-linear-gradient(45deg, rgba(var(--rgb-accent), 1) 0, rgba(var(--rgb-accent), 1) 8px, rgba(var(--rgb-background), 1) 8px, rgba(var(--rgb-background), 1) 16px);
clip-path: polygon(calc(100% - 11px) 0, 100% 0, 100% 100%, 0 100%, 0 calc(100% - 11px), calc(100% - 11px) calc(100% - 11px));
}
.effect-docked {
font-size: 2em;
font-weight: 700;
text-align: center;
position: relative;
padding: 0 16px;
z-index: 1;
}
.effect-docked::before {
position: absolute;
content: '';
height: 100%;
width: 100%;
top: 0;
left: 0;
box-sizing: border-box;
background: rgba(var(--rgb-accent), 0.7);
clip-path: polygon(12px 60%, calc(100% - 12px) 60%, 100% 100%, 0 100%);
z-index: -1;
}
.effect-rhombus-animated,
.effect-rhombus-left,
.effect-rhombus-right {
position: relative;
font-weight: 500;
padding: 0 16px;
z-index: 1;
}
.effect-rhombus-animated::before,
.effect-rhombus-left::before,
.effect-rhombus-right::before {
position: absolute;
content: '';
height: 100%;
width: 100%;
top: 0;
left: 0;
box-sizing: border-box;
background: rgba(var(--rgb-accent), .8);
z-index: -1;
}
.effect-rhombus-left {
clip-path: polygon(0 0, calc(100% - 8px) 0, 100% 100%, 8px 100%);
}
.effect-rhombus-right {
clip-path: polygon(8px 0, 100% 0, calc(100% - 8px) 100%, 0 100%);
}
.effect-rhombus-animated {
animation: kf-rhombus 1s ease-in-out infinite alternate;
}
@keyframes kf-rhombus {
0% {
clip-path: polygon(0 0, calc(100% - 8px) 0, 100% 100%, 8px 100%);
}
100% {
clip-path: polygon(8px 0, 100% 0, calc(100% - 8px) 100%, 0 100%);
}
}
div.effect-chevron-container {
align-items: end;
}
.effect-chevron-point-left,
.effect-chevron-point-right {
display: inline-block;
background-color: rgba(var(--rgb-accent), 1);
text-decoration: none;
font-weight: 500;
height: 24px;
width: fit-content;
padding: 0 16px;
}
.effect-chevron-point-right {
margin-right: -4px;
clip-path: polygon(0 0, calc(100% - 8px) 0, 100% 50%, calc(100% - 8px) 100%, 0 100%, 8px 50%);
}
div.effect-chevron-container>.effect-chevron-point-right:first-child {
padding-left: 8px;
clip-path: polygon(0 0, calc(100% - 8px) 0, 100% 50%, calc(100% - 8px) 100%, 0 100%);
}
.effect-chevron-point-left {
margin-left: -4px;
clip-path: polygon(8px 0, 100% 0, calc(100% - 8px) 50%, 100% 100%, 8px 100%, 0 50%);
}
div.effect-chevron-container>.effect-chevron-point-left:last-child {
padding-right: 8px;
clip-path: polygon(8px 0, 100% 0, 100% 100%, 8px 100%, 0 50%);
}
span.effect-dot {
height: 16px;
width: 16px;
position: relative;
align-self: center;
border-radius: 100%;
background-color: rgba(var(--color), 0.8);
margin: 0 8px;
}
span.effect-dot::before {
content: '';
height: 10px;
width: 10px;
border-radius: 100%;
position: absolute;
background-color: rgba(var(--color), 1);
transform: translate(-50%, -50%);
left: 50%;
top: 50%;
}
/* Page Layout */
div.layout-wrapper {
display: flex;
gap: 16px;
min-width: 1024px;
max-width: 1024px;
width: 1024px;
margin: 16px auto;
}
div.layout-navigation {
min-width: 286px;
max-width: 286px;
width: 100%;
height: fit-content;
position: sticky;
top: 16px;
}
div.layout-content {
width: 100%;
height: fit-content;
}
/* Layout: Navigation */
div.navigation-header {
padding: 16px;
}
a.navigation-title {
width: 100%;
box-sizing: border-box;
}
p.navigation-description {
width: 100%;
padding: 8px 0;
text-align: center;
box-sizing: border-box;
font-size: small;
}
/* div.navigation-links {} */
a.navigation-item {
width: 100%;
padding: 8px 16px;
box-sizing: border-box;
border-bottom: 4px solid rgba(var(--rgb-accent), 1);
text-decoration: none;
font-size: 20px;
font-weight: 500;
background-size: 100% 300%;
background-repeat: no-repeat;
background-image: var(--background);
}
a.navigation-item:first-child {
border-top: 4px solid rgba(var(--rgb-accent), 1);
}
div.navigation-content {
padding: 16px;
padding-bottom: 0;
}
div.navigation-footer {
display: flex;
padding: 16px;
justify-content: center;
align-items: center;
gap: 4px;
}
a.footer-item {
color: rgba(var(--rgb-accent), 1);
text-decoration: none;
}
a.footer-item:hover,
a.footer-item:focus-visible {
text-decoration: underline;
}
div.footer-views {
width: 100%;
display: flex;
justify-content: center;
gap: 4px;
}
div.footer-views img {
height: 24px;
image-rendering: pixelated;
}
@@ -0,0 +1,122 @@
/* Local Version of following stylesheet to save on bandwidth while developing locally :3 */
/* https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap */
/* devanagari */
@font-face {
font-family: 'Poppins';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url(/public/fonts/pxiEyp8kv8JHgFVrJJbecmNE.woff2) format('woff2');
unicode-range: U+0900-097F, U+1CD0-1CF9, U+200C-200D, U+20A8, U+20B9, U+20F0, U+25CC, U+A830-A839, U+A8E0-A8FF, U+11B00-11B09;
}
/* latin-ext */
@font-face {
font-family: 'Poppins';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url(/public/fonts/pxiEyp8kv8JHgFVrJJnecmNE.woff2) format('woff2');
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Poppins';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url(/public/fonts/pxiEyp8kv8JHgFVrJJfecg.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* devanagari */
@font-face {
font-family: 'Poppins';
font-style: normal;
font-weight: 500;
font-display: swap;
src: url(/public/fonts/pxiByp8kv8JHgFVrLGT9Z11lFc-K.woff2) format('woff2');
unicode-range: U+0900-097F, U+1CD0-1CF9, U+200C-200D, U+20A8, U+20B9, U+20F0, U+25CC, U+A830-A839, U+A8E0-A8FF, U+11B00-11B09;
}
/* latin-ext */
@font-face {
font-family: 'Poppins';
font-style: normal;
font-weight: 500;
font-display: swap;
src: url(/public/fonts/pxiByp8kv8JHgFVrLGT9Z1JlFc-K.woff2) format('woff2');
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Poppins';
font-style: normal;
font-weight: 500;
font-display: swap;
src: url(/public/fonts/pxiByp8kv8JHgFVrLGT9Z1xlFQ.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* devanagari */
@font-face {
font-family: 'Poppins';
font-style: normal;
font-weight: 600;
font-display: swap;
src: url(/public/fonts/pxiByp8kv8JHgFVrLEj6Z11lFc-K.woff2) format('woff2');
unicode-range: U+0900-097F, U+1CD0-1CF9, U+200C-200D, U+20A8, U+20B9, U+20F0, U+25CC, U+A830-A839, U+A8E0-A8FF, U+11B00-11B09;
}
/* latin-ext */
@font-face {
font-family: 'Poppins';
font-style: normal;
font-weight: 600;
font-display: swap;
src: url(/public/fonts/pxiByp8kv8JHgFVrLEj6Z1JlFc-K.woff2) format('woff2');
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Poppins';
font-style: normal;
font-weight: 600;
font-display: swap;
src: url(/public/fonts/pxiByp8kv8JHgFVrLEj6Z1xlFQ.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* devanagari */
@font-face {
font-family: 'Poppins';
font-style: normal;
font-weight: 700;
font-display: swap;
src: url(/public/fonts/pxiByp8kv8JHgFVrLCz7Z11lFc-K.woff2) format('woff2');
unicode-range: U+0900-097F, U+1CD0-1CF9, U+200C-200D, U+20A8, U+20B9, U+20F0, U+25CC, U+A830-A839, U+A8E0-A8FF, U+11B00-11B09;
}
/* latin-ext */
@font-face {
font-family: 'Poppins';
font-style: normal;
font-weight: 700;
font-display: swap;
src: url(/public/fonts/pxiByp8kv8JHgFVrLCz7Z1JlFc-K.woff2) format('woff2');
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Poppins';
font-style: normal;
font-weight: 700;
font-display: swap;
src: url(/public/fonts/pxiByp8kv8JHgFVrLCz7Z1xlFQ.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@@ -0,0 +1,84 @@
{{ define "ArticleContent" }}
<p class="element-header">Introduction</p>
<p class="element-paragraph">
If you're reading this... I haven't written the article yet :P
</p>
<p class="element-paragraph">
Luctus montes donec mauris. Vehicula suspendisse condimentum massa fringilla at conubia.
Senectus laoreet praesent in, porttitor sollicitudin luctus orci scelerisque egestas malesuada faucibus a.
Arcu imperdiet libero imperdiet nulla libero natoque eu fusce ultricies vehicula nisi.
Torquent lacus sodales inceptos dignissim sed, mauris feugiat erat.
Phasellus at tincidunt sociosqu potenti risus aliquam non litora.
Commodo mi fermentum, id arcu dictum convallis.
Vehicula convallis, proin fames molestie potenti congue penatibus feugiat porttitor.
Habitant justo lacinia, curabitur nascetur!
Dolor nunc accumsan imperdiet penatibus?
Amet cursus faucibus dui vestibulum nascetur quam.
</p>
<div class="element-divider"></div>
<p class="element-header">Prerequisites</p>
<p class="element-paragraph">
Praesent augue ligula amet nisl. Litora lectus consectetur aliquet.
Sociis iaculis dolor nostra pulvinar felis condimentum netus.
Suscipit enim habitant sed eros etiam, ut odio sed.
Fringilla quam tempus nisl natoque parturient dolor curabitur tellus.
Lacus conubia quis inceptos tristique ultricies cum consequat.
Consequat phasellus proin dolor molestie nec quam cursus mollis vel?
Eros tempor sollicitudin tortor litora nunc.
Sem scelerisque semper id ac auctor fusce quis erat imperdiet convallis donec eget!
Pellentesque tempor nunc ipsum imperdiet quam ipsum habitant feugiat.
</p>
<p class="element-subheader">Hosting</p>
<p class="element-paragraph">
Odio nibh penatibus erat sociosqu eget iaculis. Ante curabitur bibendum ligula?
Netus aliquet cursus interdum pharetra. Magnis elementum nunc luctus eu nam sit habitant etiam vestibulum in.
Lacus nisl ullamcorper molestie! Dignissim, vulputate porta pulvinar duis posuere.
</p>
<p class="element-subheader">Domains</p>
<p class="element-paragraph">
Curae; laoreet cum duis turpis, feugiat per integer.
Sit in blandit himenaeos. Penatibus fringilla imperdiet, luctus dapibus elementum.
Felis senectus pulvinar a natoque risus.
</p>
<p class="element-subheader">Credentials</p>
<p class="element-paragraph">
Mauris habitasse nulla accumsan fermentum fermentum.
Magnis amet amet risus senectus in curae;.
Elementum ac montes sagittis vivamus malesuada elementum senectus ultrices scelerisque fusce.
In nulla platea.
</p>
<div class="element-divider"></div>
<p class="element-header">Setup DNS</p>
<p class="element-paragraph">
Nisi vitae vehicula etiam nam auctor, accumsan purus ridiculus molestie.
Ante malesuada condimentum aliquam etiam auctor arcu porttitor parturient nullam accumsan bibendum?
Vitae arcu at mattis. Volutpat himenaeos class vitae elit, luctus sociosqu semper?
Praesent taciti lobortis tortor laoreet magnis tortor sagittis porta facilisi vivamus dictum scelerisque.
Consectetur elit enim malesuada commodo proin facilisi sagittis!
Malesuada quam duis non elit himenaeos sem.
Luctus suspendisse senectus mollis aliquet aliquam pellentesque conubia condimentum suspendisse aptent litora potenti.
Curabitur sociis lacus turpis, laoreet ligula consequat luctus eu auctor auctor sagittis.
Turpis nibh feugiat lorem donec quis bibendum.
Himenaeos sapien interdum aptent.
</p>
<p class="element-header">Setup Linux</p>
<p class="element-paragraph">
Convallis pharetra vitae tincidunt phasellus bibendum porta, praesent dictum aliquet volutpat.
Lobortis semper eget consectetur elementum elit hendrerit natoque mauris taciti ante ac augue.
Ullamcorper viverra vestibulum vehicula nisi metus vestibulum curabitur vehicula et.
Phasellus ligula vitae posuere penatibus ullamcorper lorem phasellus metus.
Scelerisque ac lobortis gravida primis?
Lacus porttitor ullamcorper quisque viverra molestie.
Lacinia bibendum facilisi tempor cubilia felis eros!
Etiam blandit lacinia leo urna.
</p>
{{ end }}
@@ -0,0 +1,48 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="theme-color" content="{{ .Site.Color }}">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="A small corner of the web for odd tech experiments and the occasional questionable idea. Enjoy in moderation!">
<link rel="stylesheet" href="/public/styles/default.css?v={{ .Version }}">
<link rel="stylesheet" href="/public/styles/font_poppins.css?v={{ .Version }}">
{{ block "PageStyles" . }}{{ end }}
<title>{{ .Title }} - {{ .Site.Name }}</title>
<meta property="og:locale" content="{{ .Site.Locale }}">
{{ block "PageHead" . }}{{ end }}
</head>
<body style="--rgb-accent: {{ if .Article }}{{ .Article.Color }}{{ else }}{{ .Site.Color }}{{ end }}">
<div class="layout-wrapper">
<!-- Navigation -->
<div class="layout-navigation effect-caution">
<div class="navigation-header">
<a class="navigation-title effect-docked" href="/">{{ .Site.Name }}</a>
<p class="navigation-description">{{ .Site.Description }}</p>
</div>
<div class="navigation-links" style="--background: url('/public/anchors.gif?v={{ .Version}}');">
<a style="background-position-y: 0%;" class="navigation-item" href="/blog">Blog</a>
<a style="background-position-y: 50%;" class="navigation-item" href="http://git.panca.kz/">Codebase</a>
<a style="background-position-y: 100%;" class="navigation-item" href="http://stickers.panca.kz/">Stickerboard</a>
</div>
<div class="navigation-content">
{{ block "NavContent" . }}{{ end }}
</div>
<div class="navigation-footer">
<a class="footer-item" href="/rss.xml">RSS</a>
</div>
</div>
<!-- Content -->
<div class="layout-content effect-caution">
{{ block "PageContent" . }}{{ end }}
</div>
</div>
{{ block "PageBody" . }}{{ end }}
</body>
</html>
@@ -0,0 +1,82 @@
{{ define "PageStyles" }}
<link rel="stylesheet" href="/public/styles/blog_article.css?v={{ .Version }}">
{{ end }}
{{ define "PageHead" }}
<meta property="og:type" content="article">
<meta property="og:title" content="{{ .Article.Title }}">
<meta property="og:image" content="{{ .Site.Host }}{{ .Article.BaseBanner }}">
<meta property="og:url" content="{{ .Site.Host }}/blog/{{ .Article.Slug }}">
<meta property="og:description" content="{{ .Article.Description }}">
{{ end }}
{{ define "PageBody" }}
<dialog class="layout-dialog">
<div class="layout-modal effect-caution">
<div class="modal-header">
<p>Share</p>
<form method="dialog" autofocus>
<button>&#10005;</button>
</form>
</div>
<div class="modal-content">
<input type="text" value="{{ .Site.Host }}/blog/{{ .Article.Slug }}" onclick="this.select()" readonly>
<a title="Share on X" target="_blank" href="https://twitter.com/intent/tweet?url={{ .Site.Host }}/blog/{{ .Article.Slug }}&text={{ .Article.Title }}&via={{ .Site.Owner }}">
{{ template "logo_x.svg" . }}
</a>
<a title="Share on Facebook" target="_blank" href="https://www.facebook.com/sharer/sharer.php?u={{ .Site.Host }}/blog/{{ .Article.Slug }}">
{{ template "logo_facebook.svg" . }}
</a>
<a title="Share on LinkedIn" target="_blank" href="https://www.linkedin.com/shareArticle?url={{ .Site.Host }}/blog/{{ .Article.Slug }}">
{{ template "logo_linkedin.svg" . }}
</a>
</div>
</div>
</dialog>
<script src="/public/scripts/blog_article.js?v={{ .Version }}"></script>
{{ end }}
{{ define "NavContent" }}
<div class="article-actions">
<a title="Visit Homepage" href="/blog">
{{ template "icon_home.svg" . }}
</a>
<a title="Return To Top" href="#" class="mobile-hide">
{{ template "icon_top.svg" . }}
</a>
<a title="Share Article" href="{{ .Site.Host }}/blog/{{ .Article.Slug }}" id="button-share">
{{ template "icon_share.svg" . }}
</a>
</div>
<div class="article-chapters">
<!-- To Be Generated by Article Script -->
</div>
{{ end }}
{{ define "PageContent" }}
<h1 id="#" hidden><!-- Top Anchor --></h1>
<div class="article-header">
<img class="header-banner" alt="Article Banner" src="/public/articles/{{ .Article.BaseResources }}/{{ .Article.BaseBanner }}?v={{ $.Version }}">
<p class="header-title effect-docked">{{ .Article.Title }}</p>
<div class="header-chevrons">
<div class="effect-chevron-container header-about">
<span class="effect-chevron-point-right">{{ .Article.Author }}</span>
<span class="effect-chevron-point-right">{{ .Article.Date.Format "Jan 02 2006" }}</span>
</div>
<div class="effect-chevron-container header-tags">
{{ range .Article.Tags }}
<span class="effect-chevron-point-left">{{ . }}</span>
{{ end }}
</div>
</div>
</div>
<div class="article-content">
{{ block "ArticleContent" . }}{{ end }}
</div>
{{ end }}
@@ -0,0 +1,71 @@
{{ template "base.html" . }}
{{ define "PageStyles" }}
<link rel="stylesheet" href="/public/styles/blog_browser.css?v={{ .Version }}">
<link rel="stylesheet" href="/public/styles/blog_article.css?v={{ .Version }}">
{{ end }}
{{ define "PageContent" }}
<!-- Introduction & Disclaimer -->
<div class="browser-introduction">
<p class="intro-header effect-rhombus-right">Welcome to my blog!</p>
<img class="intro-banner" src="/public/banner_blog.gif?v={{ .Version }}" alt="Blog Banner" width="520" height="292">
<p class="intro-paragraph">
This corner of the internet contains ramblings about random experiments
that more than likely occured on a bright sunday afternoon. Nothing here
is meant to be perfect, but I do hope to provide the odd spark of insight.
<br><br>
I assume no responsibility for bodily harm, wasted time, or raised eyebrows
that may result from consuming these articles. Enjoy in Moderation! Have fun!
</p>
<div class="element-divider"></div>
<div class="intro-dots">
<span class="effect-dot" style="--color: 94, 167, 1;"></span>
<p>Personal</p>
<span class="effect-dot" style="--color: 0, 167, 170;"></span>
<p>Update</p>
<span class="effect-dot" style="--color: 255, 0, 91;"></span>
<p>Guide</p>
</div>
</div>
<!-- Article List -->
<div class="browser-content">
{{ range $.Articles }}
<a class="browser-item" href="/blog/{{ .Slug }}" style="--rgb-accent: {{ .Color }};">
<div class="item-background" style="--background: url('/public/articles/{{ .BaseResources }}/{{ .BaseBanner }}?v={{ $.Version }}');"></div>
<div class="item-foreground">
<p class="effect-rhombus-left effect-rhombus-animated">{{ .Title }}</p>
<div class="item-tags effect-chevron-container">
{{ range .Tags }}
<span class="effect-chevron-point-left">{{ . }}</span>
{{ end }}
<span class="effect-chevron-point-left">{{ .Date.Format "Jan 02 2006" }}</span>
</div>
</div>
</a>
{{ end }}
</div>
<!-- Fortune Cookie -->
<div class="browser-footer">
<p id="browser-message">If you're reading this, you have JavaScript disabled. Paranoid much? :P</p>
<script>
const monitor = document.querySelector("p#browser-message")
const messages = [
"Did you eat something sweet today? Everybody deserves a sweet treat, especially you. :)",
"Make sure you clean your keyboard, it's amazingly disgusting what you can find in there.",
"Religion aside even God rested on the 7th day, are you treating yourself well?",
"If bored try learning about how your favorite Game Console OS works, or is that weird?",
"Your projects miss you... maybe poke around? You might rediscover something!",
"If somebody has done it before, you can too! And if they got close, you can get closer!",
"Bad Idea Counter -> {{ len .Articles }}",
]
monitor.textContent = messages[Math.floor(Math.random() * messages.length)]
</script>
</div>
{{ end }}
@@ -0,0 +1,76 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="robots" content="noindex">
<title>Page Not Found</title>
<style>
:root{
--color: {{ .Site.Color }};
}
body {
background-color: black;
margin: 0;
}
a,
p {
font-family: "MS Gothic", monospace;
line-height: 16px;
}
p {
color: #f0f0f0;
margin: 4px 0;
}
a,
a:visited {
color: rgba(var(--color), 1);
display: inline-block;
text-align: center;
width: 50%;
text-decoration: none;
}
a:hover,
a:focus-visible {
text-decoration: underline;
outline: none;
}
div {
width: 200px;
text-align: center;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
</style>
</head>
<body>
<div>
<p>404: Page Not Found </p>
<br>
<p>.-.</p>
<br>
<a href="javascript:window.history.back()">Go Back</a><a href="/">Homepage</a>
</div>
<script>
// Note: In MS Gothic, backslash shows as ¥ on Windows
const catalog = [
".(^Д^)/", "(・.・)", "(°Δ°)b", "(・_・)", "(^_^)", "(>_<)",
"(o^^)o", "(;-;)", ".(≧o≦)/", "(o_o)", "(^-^*)", "(='X'=)",
"( ̄へ ̄)", "(★ω★)", "ᓚᘏᗢ", "✿◠‿◠", "(●'◡'●)", "◑﹏◐"
];
const kaomoji = catalog[Math.floor(Math.random() * catalog.length)];
document.querySelectorAll("p")[1].textContent = kaomoji;
</script>
</body>
</html>
@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<atom:link href="{{ .Site.Host}}/rss.xml" rel="self" type="application/rss+xml"></atom:link>
<link>{{ .Site.Host }}</link>
<title><![CDATA[{{ .Site.Name }}]]></title>
<description><![CDATA[{{ .Site.Description }}]]></description>
<category>{{ .Site.Category }}</category>
<language>{{ .Site.Locale }} </language>
<generator>teto</generator>
<copyright>Copyright 2025 {{ .Site.Owner }}</copyright>
<lastBuildDate>{{ .BuildDate.UTC.Format .RFC1123 }}</lastBuildDate>
</channel>
{{ range $index, $elem := .Articles }}
<item>
<link>{{ $.Site.Host }}/{{ $elem.Slug }}</link>
<guid isPermaLink="true">{{ $.Site.Host }}/{{ $elem.Slug }}</guid>
<title><![CDATA[{{ $elem.Title }}]]></title>
<description><![CDATA[{{ $elem.Description }}]]></description>
<pubDate>{{ $elem.Date.UTC.Format $.RFC1123 }}</pubDate>
{{ range $i, $tag := $elem.Tags }}
<category>{{ $tag }}</category>
{{ end }}
</item>
{{ end }}
</rss>
@@ -0,0 +1,21 @@
{{ template "base.html" . }}
{{ define "PageContent" }}
<style>
div.placeholder {
width: 100%;
height: 100%;
min-height: 480px;
display: grid;
justify-content: center;
justify-items: center;
align-content: center;
gap: 32px;
}
</style>
<div class="placeholder" style="text-align: center;">
<img style="image-rendering: pixelated;" src="/public/banner_home.gif?v={{ .Version }}" alt="Lost Sprite">
<p>I intended to put something here, but I couldn't come up with anything....</p>
<p>So check out my <a href="/blog">blog</a>, <a href="https://git.panca.kz/">code</a> or <a href="https://stickers.panca.kz/">stickerboard</a>!</p>
</div>
{{ end }}
@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 32">
<!-- @bakonpancakz -->
<polygon points="20 0 0 14 6 14 6 32 16 32 16 21 24 21 24 32 34 32 34 14 40 14 20 0" />
</svg>

After

Width:  |  Height:  |  Size: 186 B

@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30.99 30.99">
<!-- @bakonpancakz -->
<polygon points="26.22 14.92 26.22 27.25 3.73 27.25 3.73 4.75 16.05 4.75 12.31 1.01 0 1.01 0 1.03 0 3.82 0 28.18 0 30.97 0 30.99 29.95 30.99 29.95 30.97 29.98 30.97 29.98 18.68 26.22 14.92" />
<polygon points="14.99 0 21.57 6.59 13.57 14.59 16.4 17.41 24.4 9.41 30.99 16 30.99 0 14.99 0" />
</svg>

After

Width:  |  Height:  |  Size: 399 B

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 17.51">
<!-- @bakonpancakz -->
<polygon points="15 17.51 3 17.51 0 8.01 18 8.01 15 17.51" />
<rect y="4" width="18" height="3" />
<rect width="18" height="3" />
</svg>

After

Width:  |  Height:  |  Size: 239 B

@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
<!-- @bakonpancakz -->
<polygon points="4.69 20.68 13 20.69 13 32 18.99 31.99 18.99 20.68 27.31 20.68 16 6.74 4.69 20.68" />
<rect width="32" height="3.74" />
</svg>

After

Width:  |  Height:  |  Size: 238 B

@@ -0,0 +1,7 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500">
<mask id="icon">
<path fill="white" d="M500,250C500,111.93,388.07,0,250,0S0,111.93,0,250c0,117.24,80.72,215.62,189.61,242.64v-166.24h-51.55v-76.4h51.55v-32.92c0-85.09,38.51-124.53,122.05-124.53,15.84,0,43.17,3.11,54.35,6.21v69.25c-5.9-.62-16.15-.93-28.88-.93-40.99,0-56.83,15.53-56.83,55.9v27.02h81.66l-14.03,76.4h-67.63v171.77c123.79-14.95,219.71-120.35,219.71-248.17Z" />
<path fill="black" d="M347.92,326.4l14.03-76.4h-81.66v-27.02c0-40.37,15.84-55.9,56.83-55.9,12.73,0,22.98.31,28.88.93v-69.25c-11.18-3.11-38.51-6.21-54.35-6.21-83.54,0-122.05,39.44-122.05,124.53v32.92h-51.55v76.4h51.55v166.24c19.34,4.8,39.57,7.36,60.39,7.36,10.25,0,20.36-.63,30.29-1.83v-171.77h67.63Z" />
</mask>
<rect mask="url(#icon)" width="500" height="500" />
</svg>

After

Width:  |  Height:  |  Size: 835 B

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 382 382">
<path d="M347.445,0H34.555C15.471,0,0,15.471,0,34.555v312.889C0,366.529,15.471,382,34.555,382h312.889 C366.529,382,382,366.529,382,347.444V34.555C382,15.471,366.529,0,347.445,0z M118.207,329.844c0,5.554-4.502,10.056-10.056,10.056 H65.345c-5.554,0-10.056-4.502-10.056-10.056V150.403c0-5.554,4.502-10.056,10.056-10.056h42.806 c5.554,0,10.056,4.502,10.056,10.056V329.844z M86.748,123.432c-22.459,0-40.666-18.207-40.666-40.666S64.289,42.1,86.748,42.1 s40.666,18.207,40.666,40.666S109.208,123.432,86.748,123.432z M341.91,330.654c0,5.106-4.14,9.246-9.246,9.246H286.73 c-5.106,0-9.246-4.14-9.246-9.246v-84.168c0-12.556,3.683-55.021-32.813-55.021c-28.309,0-34.051,29.066-35.204,42.11v97.079 c0,5.106-4.139,9.246-9.246,9.246h-44.426c-5.106,0-9.246-4.14-9.246-9.246V149.593c0-5.106,4.14-9.246,9.246-9.246h44.426 c5.106,0,9.246,4.14,9.246,9.246v15.655c10.497-15.753,26.097-27.912,59.312-27.912c73.552,0,73.131,68.716,73.131,106.472 L341.91,330.654L341.91,330.654z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 300.251">
<path d="M178.57 127.15 290.27 0h-26.46l-97.03 110.38L89.34 0H0l117.13 166.93L0 300.25h26.46l102.4-116.59 81.8 116.59h89.34M36.01 19.54H76.66l187.13 262.13h-40.66"/>
</svg>

After

Width:  |  Height:  |  Size: 243 B