Initial Release
@@ -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)
|
||||
}
|
||||
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
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 |
|
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>✕</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 |