From a08229a866ad02bf1e76a847f6ae7f608c71b135 Mon Sep 17 00:00:00 2001 From: voidarc Date: Sat, 28 Mar 2026 17:35:17 +0000 Subject: [PATCH] initial --- assets/css/prism-sweetie.min.css | 1 + assets/css/styles.min.css | 1372 ++++++++++++++++++++++++++++++ assets/css/tailwind.css | 343 ++++++++ assets/norgolith.svg | 181 ++++ assets/style.css | 110 +++ categories/blog/index.html | 271 ++++++ categories/homelab/index.html | 253 ++++++ categories/index.html | 332 ++++++++ categories/linux/index.html | 262 ++++++ categories/neorg/index.html | 253 ++++++ categories/nix/index.html | 253 ++++++ categories/nvim/index.html | 253 ++++++ categories/voidarc/index.html | 262 ++++++ categories/webdev/index.html | 262 ++++++ index.html | 304 +++++++ posts/homelab/index.html | 330 +++++++ posts/index.html | 295 +++++++ posts/nix/index.html | 319 +++++++ posts/site/index.html | 346 ++++++++ rss.xml | 53 ++ 20 files changed, 6055 insertions(+) create mode 100644 assets/css/prism-sweetie.min.css create mode 100644 assets/css/styles.min.css create mode 100644 assets/css/tailwind.css create mode 100644 assets/norgolith.svg create mode 100644 assets/style.css create mode 100644 categories/blog/index.html create mode 100644 categories/homelab/index.html create mode 100644 categories/index.html create mode 100644 categories/linux/index.html create mode 100644 categories/neorg/index.html create mode 100644 categories/nix/index.html create mode 100644 categories/nvim/index.html create mode 100644 categories/voidarc/index.html create mode 100644 categories/webdev/index.html create mode 100644 index.html create mode 100644 posts/homelab/index.html create mode 100644 posts/index.html create mode 100644 posts/nix/index.html create mode 100644 posts/site/index.html create mode 100644 rss.xml diff --git a/assets/css/prism-sweetie.min.css b/assets/css/prism-sweetie.min.css new file mode 100644 index 0000000..294dc34 --- /dev/null +++ b/assets/css/prism-sweetie.min.css @@ -0,0 +1 @@ +pre[class*=language-]{--padding-y:var(--am-prism-padding-y, 1rem);--padding-x:var(--am-prism-padding-x, 1rem);padding:var(--padding-y) var(--padding-x);overflow:auto;font-size:var(--am-prism-font-size,.85em);border-radius:var(--am-prism-border-radius,.4em)}pre>code[class*=language-]{padding:initial;font-size:1em;font-weight:400;font-family:var(--am-prism-font-family,ui-monospace),monospace;line-height:var(--am-prism-line-height,1.5);background-color:initial}code[class*=language-],pre[class*=language-]{text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}pre[class*=language-] .line-numbers-rows{box-sizing:content-box;margin:calc(var(--padding-y) * -1) 0;padding:var(--padding-y) 0}.line-numbers.line-numbers .line-numbers-rows{border-right-width:var(--am-prism-border-width,1px);border-right-color:var(--am-prism-border-color)}.line-numbers .line-numbers-rows>span:before{color:var(--am-prism-line-numbers-color)}div.code-toolbar>.toolbar{top:.3rem!important;right:.3rem!important}div.code-toolbar>.toolbar>.toolbar-item>button.copy-to-clipboard-button{display:inline-flex;padding:0 .75em;font-size:var(--am-prism-font-size,.8em);font-family:var(--am-prism-font-family,ui-monospace),monospace;font-weight:600!important;line-height:2.25em;color:var(--am-prism-copy-color);background-color:var(--am-prism-copy-bg);border-radius:calc(var(--am-prism-border-radius, .4em) - .1em);cursor:pointer;box-shadow:none;opacity:1;transition:opacity .2s}div.code-toolbar>.toolbar>.toolbar-item>button.copy-to-clipboard-button:hover{opacity:.8}div.code-toolbar>.toolbar>.toolbar-item>button.copy-to-clipboard-button:focus{opacity:1}code[class*=language-],pre[class*=language-]{color:#202023}pre[class*=language-]{background:#bbbbce}:not(pre)>code[class*=language-]{padding:.1em .3em;border-radius:.3em;color:#202023;background:#bbbbce}pre[data-line]{position:relative}pre[class*=language-]>code[class*=language-]{position:relative;z-index:1}.line-highlight{position:absolute;left:0;right:0;padding:inherit 0;margin-top:1em;background:#fff8c5;box-shadow:inset 5px 0 0 #eed888;z-index:0;pointer-events:none;line-height:inherit;white-space:pre}.namespace{opacity:.7}.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#8989a9}.token.operator,.token.punctuation{color:#0c5090}.token.boolean,.token.constant,.token.deleted,.token.number,.token.property,.token.class-name,.token.symbol,.token.tag{color:#ae580e}.token.attr-name,.token.builtin,.token.char,.token.inserted,.token.selector,.token.string{color:#287f0d}.language-css .token.string,.style .token.string,.token.entity,.token.url{color:#287f0d}.token.atrule,.token.attr-value,.token.keyword{color:#0c5090}.token.function{color:#a00c79}.token.macro,.token.important,.token.regex,.token.variable{color:#9437ff}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}:root{--am-prism-line-numbers-color:#18181a77;--am-prism-border-color:#18181a22;--am-prism-copy-color:#202023aa;--am-prism-copy-bg:#78789d22}html[class*="-dark"],html[class*="dark-"],.dark{& code[class*=language-],& pre[class*=language-]{color:#d3d7de}& pre[class*=language-]{background:#303040}& :not(pre)>code[class*=language-]{padding:.1em .3em;border-radius:.3em;color:#bdbdbd;background:#303040}& pre[data-line]{position:relative}& pre[class*=language-]>code[class*=language-]{position:relative;z-index:1}& .line-highlight{position:absolute;left:0;right:0;padding:inherit 0;margin-top:1em;background:#2f2a1e;box-shadow:inset 5px 0 0 #674c16;z-index:0;pointer-events:none;line-height:inherit;white-space:pre}& .namespace{opacity:.7}& .token.cdata,& .token.comment,& .token.doctype,& .token.prolog{color:#798399}& .token.punctuation,& .token.operator,& .token.variable{color:#73a3f3}& .token.boolean,& .token.constant,& .token.deleted,& .token.number,& .token.property,& .token.symbol,& .token.class-name,& .token.tag{color:#e7a06a}& .token.attr-name,& .token.builtin,& .token.char,& .token.inserted,& .token.selector,& .token.string{color:#89c252}& .language-css .token.string,& .style .token.string,& .token.entity,& .token.url{color:#89c252;background:#161b22}& .token.atrule,& .token.keyword{color:#73a3f3}& .token.attr-value,& .token.function{color:#d087e8}& .token.macro,& .token.important,& .token.regex{color:#b094e2}& .token.bold,& .token.important{font-weight:700}& .token.italic{font-style:italic}& .token.entity{cursor:help}&{--am-prism-line-numbers-color:#bdbdbd55;--am-prism-border-color:#bdbdbd22;--am-prism-copy-color:#d3d7de;--am-prism-copy-bg:#707b8722}} diff --git a/assets/css/styles.min.css b/assets/css/styles.min.css new file mode 100644 index 0000000..2d8e720 --- /dev/null +++ b/assets/css/styles.min.css @@ -0,0 +1,1372 @@ +/*! tailwindcss v4.1.18 | MIT License | https://tailwindcss.com */ +@import url("https://fonts.googleapis.com/css2?family=Fira+Mono:wght@400;500;700&display=swap"); +@import url("https://unpkg.com/@catppuccin/palette/css/catppuccin.css"); +@layer properties; +@layer theme, base, components, utilities; +@layer theme { + :root, :host { + --font-sans: "Fira Mono", ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", + "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; + --font-mono: "Fira Mono", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, + "Liberation Mono", "Courier New", monospace; + --color-blue-400: oklch(70.7% 0.165 254.624); + --spacing: 0.25rem; + --text-xs: 0.75rem; + --text-xs--line-height: calc(1 / 0.75); + --text-sm: 0.875rem; + --text-sm--line-height: calc(1.25 / 0.875); + --text-lg: 1.125rem; + --text-lg--line-height: calc(1.75 / 1.125); + --text-xl: 1.25rem; + --text-xl--line-height: calc(1.75 / 1.25); + --text-2xl: 1.5rem; + --text-2xl--line-height: calc(2 / 1.5); + --text-3xl: 1.875rem; + --text-3xl--line-height: calc(2.25 / 1.875); + --font-weight-medium: 500; + --font-weight-semibold: 600; + --font-weight-bold: 700; + --leading-relaxed: 1.625; + --radius-sm: 0.25rem; + --radius-md: 0.375rem; + --radius-lg: 0.5rem; + --radius-xl: 0.75rem; + --ease-in: cubic-bezier(0.4, 0, 1, 1); + --ease-out: cubic-bezier(0, 0, 0.2, 1); + --ease-in-out: cubic-bezier(0.4, 0, 0.2, 1); + --default-transition-duration: 150ms; + --default-transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + --default-font-family: var(--font-sans); + --default-mono-font-family: var(--font-mono); + --color-base: var(--base); + --color-base-alt: var(--base-alt); + --color-surface: var(--surface); + --color-text: var(--text); + --color-text-alt: var(--text-alt); + --color-grey: var(--grey); + --color-dark-grey: var(--dark-grey); + --color-red: var(--red); + --color-orange: var(--orange); + --color-green: var(--green); + --color-teal: var(--teal); + --color-yellow: var(--yellow); + --color-blue: var(--blue); + --color-magenta: var(--magenta); + --color-violet: var(--violet); + --color-cyan: var(--cyan); + } +} +@layer base { + *, ::after, ::before, ::backdrop, ::file-selector-button { + box-sizing: border-box; + margin: 0; + padding: 0; + border: 0 solid; + } + html, :host { + line-height: 1.5; + -webkit-text-size-adjust: 100%; + tab-size: 4; + font-family: var(--default-font-family, ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'); + font-feature-settings: var(--default-font-feature-settings, normal); + font-variation-settings: var(--default-font-variation-settings, normal); + -webkit-tap-highlight-color: transparent; + } + hr { + height: 0; + color: inherit; + border-top-width: 1px; + } + abbr:where([title]) { + -webkit-text-decoration: underline dotted; + text-decoration: underline dotted; + } + h1, h2, h3, h4, h5, h6 { + font-size: inherit; + font-weight: inherit; + } + a { + color: inherit; + -webkit-text-decoration: inherit; + text-decoration: inherit; + } + b, strong { + font-weight: bolder; + } + code, kbd, samp, pre { + font-family: var(--default-mono-font-family, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace); + font-feature-settings: var(--default-mono-font-feature-settings, normal); + font-variation-settings: var(--default-mono-font-variation-settings, normal); + font-size: 1em; + } + small { + font-size: 80%; + } + sub, sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; + } + sub { + bottom: -0.25em; + } + sup { + top: -0.5em; + } + table { + text-indent: 0; + border-color: inherit; + border-collapse: collapse; + } + :-moz-focusring { + outline: auto; + } + progress { + vertical-align: baseline; + } + summary { + display: list-item; + } + ol, ul, menu { + list-style: none; + } + img, svg, video, canvas, audio, iframe, embed, object { + display: block; + vertical-align: middle; + } + img, video { + max-width: 100%; + height: auto; + } + button, input, select, optgroup, textarea, ::file-selector-button { + font: inherit; + font-feature-settings: inherit; + font-variation-settings: inherit; + letter-spacing: inherit; + color: inherit; + border-radius: 0; + background-color: transparent; + opacity: 1; + } + :where(select:is([multiple], [size])) optgroup { + font-weight: bolder; + } + :where(select:is([multiple], [size])) optgroup option { + padding-inline-start: 20px; + } + ::file-selector-button { + margin-inline-end: 4px; + } + ::placeholder { + opacity: 1; + } + @supports (not (-webkit-appearance: -apple-pay-button)) or (contain-intrinsic-size: 1px) { + ::placeholder { + color: currentcolor; + @supports (color: color-mix(in lab, red, red)) { + color: color-mix(in oklab, currentcolor 50%, transparent); + } + } + } + textarea { + resize: vertical; + } + ::-webkit-search-decoration { + -webkit-appearance: none; + } + ::-webkit-date-and-time-value { + min-height: 1lh; + text-align: inherit; + } + ::-webkit-datetime-edit { + display: inline-flex; + } + ::-webkit-datetime-edit-fields-wrapper { + padding: 0; + } + ::-webkit-datetime-edit, ::-webkit-datetime-edit-year-field, ::-webkit-datetime-edit-month-field, ::-webkit-datetime-edit-day-field, ::-webkit-datetime-edit-hour-field, ::-webkit-datetime-edit-minute-field, ::-webkit-datetime-edit-second-field, ::-webkit-datetime-edit-millisecond-field, ::-webkit-datetime-edit-meridiem-field { + padding-block: 0; + } + ::-webkit-calendar-picker-indicator { + line-height: 1; + } + :-moz-ui-invalid { + box-shadow: none; + } + button, input:where([type='button'], [type='reset'], [type='submit']), ::file-selector-button { + appearance: button; + } + ::-webkit-inner-spin-button, ::-webkit-outer-spin-button { + height: auto; + } + [hidden]:where(:not([hidden='until-found'])) { + display: none !important; + } +} +@layer utilities { + .sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip-path: inset(50%); + white-space: nowrap; + border-width: 0; + } + .relative { + position: relative; + } + .static { + position: static; + } + .container { + width: 100%; + @media (width >= 40rem) { + max-width: 40rem; + } + @media (width >= 48rem) { + max-width: 48rem; + } + @media (width >= 64rem) { + max-width: 64rem; + } + @media (width >= 80rem) { + max-width: 80rem; + } + @media (width >= 96rem) { + max-width: 96rem; + } + } + .mx-auto { + margin-inline: auto; + } + .mt-0\! { + margin-top: calc(var(--spacing) * 0) !important; + } + .mt-4 { + margin-top: calc(var(--spacing) * 4); + } + .mt-6 { + margin-top: calc(var(--spacing) * 6); + } + .mt-8 { + margin-top: calc(var(--spacing) * 8); + } + .mt-12 { + margin-top: calc(var(--spacing) * 12); + } + .mr-1 { + margin-right: calc(var(--spacing) * 1); + } + .mr-2 { + margin-right: calc(var(--spacing) * 2); + } + .mr-4 { + margin-right: calc(var(--spacing) * 4); + } + .mr-px { + margin-right: 1px; + } + .block { + display: block; + } + .flex { + display: flex; + } + .hidden { + display: none; + } + .inline-flex { + display: inline-flex; + } + .h-5 { + height: calc(var(--spacing) * 5); + } + .h-8 { + height: calc(var(--spacing) * 8); + } + .h-16 { + height: calc(var(--spacing) * 16); + } + .min-h-screen { + min-height: 100vh; + } + .w-5 { + width: calc(var(--spacing) * 5); + } + .w-8 { + width: calc(var(--spacing) * 8); + } + .w-fit { + width: fit-content; + } + .w-full { + width: 100%; + } + .max-w-\[50\%\] { + max-width: 50%; + } + .flex-1 { + flex: 1; + } + .shrink-0 { + flex-shrink: 0; + } + .rotate-90 { + rotate: 90deg; + } + .flex-col { + flex-direction: column; + } + .flex-row { + flex-direction: row; + } + .flex-wrap { + flex-wrap: wrap; + } + .items-center { + align-items: center; + } + .justify-between { + justify-content: space-between; + } + .justify-center { + justify-content: center; + } + .space-y-2 { + :where(& > :not(:last-child)) { + --tw-space-y-reverse: 0; + margin-block-start: calc(calc(var(--spacing) * 2) * var(--tw-space-y-reverse)); + margin-block-end: calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-y-reverse))); + } + } + .space-y-4 { + :where(& > :not(:last-child)) { + --tw-space-y-reverse: 0; + margin-block-start: calc(calc(var(--spacing) * 4) * var(--tw-space-y-reverse)); + margin-block-end: calc(calc(var(--spacing) * 4) * calc(1 - var(--tw-space-y-reverse))); + } + } + .space-x-1 { + :where(& > :not(:last-child)) { + --tw-space-x-reverse: 0; + margin-inline-start: calc(calc(var(--spacing) * 1) * var(--tw-space-x-reverse)); + margin-inline-end: calc(calc(var(--spacing) * 1) * calc(1 - var(--tw-space-x-reverse))); + } + } + .space-x-2 { + :where(& > :not(:last-child)) { + --tw-space-x-reverse: 0; + margin-inline-start: calc(calc(var(--spacing) * 2) * var(--tw-space-x-reverse)); + margin-inline-end: calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-x-reverse))); + } + } + .space-x-4 { + :where(& > :not(:last-child)) { + --tw-space-x-reverse: 0; + margin-inline-start: calc(calc(var(--spacing) * 4) * var(--tw-space-x-reverse)); + margin-inline-end: calc(calc(var(--spacing) * 4) * calc(1 - var(--tw-space-x-reverse))); + } + } + .truncate { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + .rounded-lg { + border-radius: var(--radius-lg); + } + .rounded-md { + border-radius: var(--radius-md); + } + .rounded-sm { + border-radius: var(--radius-sm); + } + .rounded-xl { + border-radius: var(--radius-xl); + } + .border-2 { + border-style: var(--tw-border-style); + border-width: 2px; + } + .border-t { + border-top-style: var(--tw-border-style); + border-top-width: 1px; + } + .border-base-alt { + border-color: var(--color-base-alt); + } + .border-t-base-alt { + border-top-color: var(--color-base-alt); + } + .bg-\[\#303040\] { + background-color: #303040; + } + .bg-grey { + background-color: var(--color-grey); + } + .bg-surface { + background-color: var(--color-surface); + } + .p-2 { + padding: calc(var(--spacing) * 2); + } + .p-4 { + padding: calc(var(--spacing) * 4); + } + .px-1 { + padding-inline: calc(var(--spacing) * 1); + } + .px-3 { + padding-inline: calc(var(--spacing) * 3); + } + .px-4 { + padding-inline: calc(var(--spacing) * 4); + } + .px-6 { + padding-inline: calc(var(--spacing) * 6); + } + .py-2 { + padding-block: calc(var(--spacing) * 2); + } + .py-4 { + padding-block: calc(var(--spacing) * 4); + } + .pt-2 { + padding-top: calc(var(--spacing) * 2); + } + .pt-6 { + padding-top: calc(var(--spacing) * 6); + } + .pt-8 { + padding-top: calc(var(--spacing) * 8); + } + .pt-10 { + padding-top: calc(var(--spacing) * 10); + } + .pb-4 { + padding-bottom: calc(var(--spacing) * 4); + } + .text-center { + text-align: center; + } + .font-mono { + font-family: var(--font-mono); + } + .text-2xl { + font-size: var(--text-2xl); + line-height: var(--tw-leading, var(--text-2xl--line-height)); + } + .text-lg { + font-size: var(--text-lg); + line-height: var(--tw-leading, var(--text-lg--line-height)); + } + .text-sm { + font-size: var(--text-sm); + line-height: var(--tw-leading, var(--text-sm--line-height)); + } + .text-xl { + font-size: var(--text-xl); + line-height: var(--tw-leading, var(--text-xl--line-height)); + } + .text-xs { + font-size: var(--text-xs); + line-height: var(--tw-leading, var(--text-xs--line-height)); + } + .font-bold { + --tw-font-weight: var(--font-weight-bold); + font-weight: var(--font-weight-bold); + } + .font-medium { + --tw-font-weight: var(--font-weight-medium); + font-weight: var(--font-weight-medium); + } + .font-semibold { + --tw-font-weight: var(--font-weight-semibold); + font-weight: var(--font-weight-semibold); + } + .break-keep { + word-break: keep-all; + } + .text-base { + color: var(--color-base); + } + .text-blue { + color: var(--color-blue); + } + .text-blue\! { + color: var(--color-blue) !important; + } + .text-blue-400 { + color: var(--color-blue-400); + } + .text-dark-grey { + color: var(--color-dark-grey); + } + .text-grey { + color: var(--color-grey); + } + .text-magenta { + color: var(--color-magenta); + } + .text-magenta\! { + color: var(--color-magenta) !important; + } + .text-red { + color: var(--color-red); + } + .text-text { + color: var(--color-text); + } + .text-text-alt { + color: var(--color-text-alt); + } + .text-text\/70 { + color: var(--color-text); + @supports (color: color-mix(in lab, red, red)) { + color: color-mix(in oklab, var(--color-text) 70%, transparent); + } + } + .capitalize { + text-transform: capitalize; + } + .italic { + font-style: italic; + } + .tabular-nums { + --tw-numeric-spacing: tabular-nums; + font-variant-numeric: var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,); + } + .no-underline\! { + text-decoration-line: none !important; + } + .opacity-0 { + opacity: 0%; + } + .opacity-100 { + opacity: 100%; + } + .shadow-lg { + --tw-shadow: 0 10px 15px -3px var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 4px 6px -4px var(--tw-shadow-color, rgb(0 0 0 / 0.1)); + box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); + } + .shadow-sm { + --tw-shadow: 0 1px 3px 0 var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 1px 2px -1px var(--tw-shadow-color, rgb(0 0 0 / 0.1)); + box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); + } + .transition { + transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to, opacity, box-shadow, transform, translate, scale, rotate, filter, -webkit-backdrop-filter, backdrop-filter, display, content-visibility, overlay, pointer-events; + transition-timing-function: var(--tw-ease, var(--default-transition-timing-function)); + transition-duration: var(--tw-duration, var(--default-transition-duration)); + } + .transition-all { + transition-property: all; + transition-timing-function: var(--tw-ease, var(--default-transition-timing-function)); + transition-duration: var(--tw-duration, var(--default-transition-duration)); + } + .transition-colors { + transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to; + transition-timing-function: var(--tw-ease, var(--default-transition-timing-function)); + transition-duration: var(--tw-duration, var(--default-transition-duration)); + } + .duration-150 { + --tw-duration: 150ms; + transition-duration: 150ms; + } + .duration-200 { + --tw-duration: 200ms; + transition-duration: 200ms; + } + .duration-300 { + --tw-duration: 300ms; + transition-duration: 300ms; + } + .ease-in { + --tw-ease: var(--ease-in); + transition-timing-function: var(--ease-in); + } + .ease-in-out { + --tw-ease: var(--ease-in-out); + transition-timing-function: var(--ease-in-out); + } + .ease-linear { + --tw-ease: linear; + transition-timing-function: linear; + } + .ease-out { + --tw-ease: var(--ease-out); + transition-timing-function: var(--ease-out); + } + .last\:mr-0 { + &:last-child { + margin-right: calc(var(--spacing) * 0); + } + } + .hover\:bg-magenta { + &:hover { + @media (hover: hover) { + background-color: var(--color-magenta); + } + } + } + .hover\:text-base\! { + &:hover { + @media (hover: hover) { + color: var(--color-base) !important; + } + } + } + .hover\:text-blue { + &:hover { + @media (hover: hover) { + color: var(--color-blue); + } + } + } + .hover\:text-blue-400 { + &:hover { + @media (hover: hover) { + color: var(--color-blue-400); + } + } + } + .hover\:text-text-alt { + &:hover { + @media (hover: hover) { + color: var(--color-text-alt); + } + } + } + .hover\:text-yellow { + &:hover { + @media (hover: hover) { + color: var(--color-yellow); + } + } + } + .hover\:no-underline\! { + &:hover { + @media (hover: hover) { + text-decoration-line: none !important; + } + } + } + .hover\:underline { + &:hover { + @media (hover: hover) { + text-decoration-line: underline; + } + } + } + .hover\:underline\! { + &:hover { + @media (hover: hover) { + text-decoration-line: underline !important; + } + } + } + .hover\:decoration-dashed { + &:hover { + @media (hover: hover) { + text-decoration-style: dashed; + } + } + } + .focus\:outline-none { + &:focus { + --tw-outline-style: none; + outline-style: none; + } + } + .md\:mr-6 { + @media (width >= 48rem) { + margin-right: calc(var(--spacing) * 6); + } + } + .md\:flex { + @media (width >= 48rem) { + display: flex; + } + } + .md\:hidden { + @media (width >= 48rem) { + display: none; + } + } + .md\:flex-row { + @media (width >= 48rem) { + flex-direction: row; + } + } + .md\:items-center { + @media (width >= 48rem) { + align-items: center; + } + } + .md\:space-y-0 { + @media (width >= 48rem) { + :where(& > :not(:last-child)) { + --tw-space-y-reverse: 0; + margin-block-start: calc(calc(var(--spacing) * 0) * var(--tw-space-y-reverse)); + margin-block-end: calc(calc(var(--spacing) * 0) * calc(1 - var(--tw-space-y-reverse))); + } + } + } + .md\:space-x-8 { + @media (width >= 48rem) { + :where(& > :not(:last-child)) { + --tw-space-x-reverse: 0; + margin-inline-start: calc(calc(var(--spacing) * 8) * var(--tw-space-x-reverse)); + margin-inline-end: calc(calc(var(--spacing) * 8) * calc(1 - var(--tw-space-x-reverse))); + } + } + } + .md\:px-0 { + @media (width >= 48rem) { + padding-inline: calc(var(--spacing) * 0); + } + } + .md\:text-2xl { + @media (width >= 48rem) { + font-size: var(--text-2xl); + line-height: var(--tw-leading, var(--text-2xl--line-height)); + } + } + .md\:text-sm { + @media (width >= 48rem) { + font-size: var(--text-sm); + line-height: var(--tw-leading, var(--text-sm--line-height)); + } + } + .md\:text-xl { + @media (width >= 48rem) { + font-size: var(--text-xl); + line-height: var(--tw-leading, var(--text-xl--line-height)); + } + } + .lg\:mr-8 { + @media (width >= 64rem) { + margin-right: calc(var(--spacing) * 8); + } + } + .dark\:border-t-\[\#39394b\] { + &:where(.dark, .dark *) { + border-top-color: #39394b; + } + } + .dark\:text-grey { + &:where(.dark, .dark *) { + color: var(--color-grey); + } + } +} +@layer base { + button:not(:disabled), [role="button"]:not(:disabled) { + cursor: pointer; + } +} +@layer utilities { + .table { + display: initial; + } +} +:root { + --base: var(--ctp-latte-base); + --base-alt: var(--ctp-latte-mantle); + --surface: var(--ctp-latte-surface0); + --text: var(--ctp-latte-text); + --text-alt: var(--ctp-latte-subtext1); + --grey: var(--ctp-latte-overlay1); + --dark-grey: var(--ctp-latte-overlay0); + --magenta: var(--ctp-latte-mauve); + --red: var(--ctp-latte-red); + --orange: var(--ctp-latte-peach); + --yellow: var(--ctp-latte-yellow); + --green: var(--ctp-latte-green); + --teal: var(--ctp-latte-teal); + --cyan: var(--ctp-latte-sky); + --blue: var(--ctp-latte-blue); + --violet: var(--ctp-latte-lavender); +} +:root.dark { + --base: var(--ctp-mocha-base); + --base-alt: var(--ctp-mocha-mantle); + --surface: var(--ctp-mocha-surface0); + --text: var(--ctp-mocha-text); + --text-alt: var(--ctp-mocha-subtext1); + --grey: var(--ctp-mocha-overlay1); + --dark-grey: var(--ctp-mocha-overlay0); + --magenta: var(--ctp-mocha-mauve); + --red: var(--ctp-mocha-red); + --orange: var(--ctp-mocha-peach); + --yellow: var(--ctp-mocha-yellow); + --green: var(--ctp-mocha-green); + --teal: var(--ctp-mocha-teal); + --cyan: var(--ctp-mocha-sky); + --blue: var(--ctp-mocha-blue); + --violet: var(--ctp-mocha-lavender); +} +html { + scrollbar-color: var(--blue) var(--surface); + scroll-behavior: smooth; + font-family: var(--font-sans); + --tw-numeric-spacing: tabular-nums; + font-variant-numeric: var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,); +} +body { + background-color: var(--color-base); + --tw-font-weight: var(--font-weight-medium); + font-weight: var(--font-weight-medium); + color: var(--color-text); + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} +main a { + text-decoration-line: underline; + &:hover { + @media (hover: hover) { + color: var(--color-blue); + } + } +} +a.icon { + text-decoration-line: none; +} +a { + transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to; + transition-timing-function: var(--tw-ease, var(--default-transition-timing-function)); + transition-duration: var(--tw-duration, var(--default-transition-duration)); + --tw-duration: 200ms; + transition-duration: 200ms; + --tw-ease: var(--ease-in-out); + transition-timing-function: var(--ease-in-out); +} +hr { + color: var(--color-base-alt); + &:where(.dark, .dark *) { + --tw-brightness: brightness(120%); + filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,); + } +} +header, footer { + background-color: var(--color-surface); + color: var(--color-text-alt); +} +h1, h2, h3, h4, h5, h6 { + --tw-font-weight: var(--font-weight-bold); + font-weight: var(--font-weight-bold); +} +h1 { + font-size: var(--text-3xl); + line-height: var(--tw-leading, var(--text-3xl--line-height)); +} +h2 { + font-size: var(--text-2xl); + line-height: var(--tw-leading, var(--text-2xl--line-height)); + counter-increment: h2; + counter-reset: h3; +} +h3 { + font-size: var(--text-xl); + line-height: var(--tw-leading, var(--text-xl--line-height)); + counter-increment: h3; + counter-reset: h4; +} +h4 { + font-size: var(--text-lg); + line-height: var(--tw-leading, var(--text-lg--line-height)); + counter-increment: h4; +} +h5 { + counter-increment: h5; +} +h6 { + --tw-font-weight: var(--font-weight-semibold); + font-weight: var(--font-weight-semibold); + counter-increment: h6; +} +p { + padding-block: calc(var(--spacing) * 2); + --tw-leading: var(--leading-relaxed); + line-height: var(--leading-relaxed); +} +strong { + --tw-font-weight: var(--font-weight-semibold); + font-weight: var(--font-weight-semibold); +} +ul { + list-style-type: disc; +} +ol { + list-style-type: decimal; +} +ul, ol { + --tw-leading: var(--leading-relaxed); + line-height: var(--leading-relaxed); +} +nav ul, nav ol { + margin-inline: calc(var(--spacing) * 2); + list-style-type: none; + :where(& > :not(:last-child)) { + --tw-space-y-reverse: 0; + margin-block-start: calc(calc(var(--spacing) * 0) * var(--tw-space-y-reverse)); + margin-block-end: calc(calc(var(--spacing) * 0) * calc(1 - var(--tw-space-y-reverse))); + } +} +main ul { + padding-left: calc(var(--spacing) * 4); +} +main h2, article h2, section h2 { + margin-top: calc(var(--spacing) * 10); +} +main h3, article h3, section h3 { + margin-top: calc(var(--spacing) * 8); +} +main h4, article h4, section h4 { + margin-top: calc(var(--spacing) * 6); +} +main h5, article h5, section h5 { + margin-top: calc(var(--spacing) * 4); +} +main h6, article h6, section h6 { + margin-top: calc(var(--spacing) * 2); +} +main div#content h2:not(:first-child) { + border-top-style: var(--tw-border-style); + border-top-width: 1px; + border-top-color: var(--color-base-alt); + padding-top: calc(var(--spacing) * 5); + &:where(.dark, .dark *) { + border-top-color: #39394b; + } +} +main div#content h3:not(:first-child) { + border-top-style: var(--tw-border-style); + border-top-width: 1px; + border-top-color: var(--color-base-alt); + padding-top: calc(var(--spacing) * 4); + &:where(.dark, .dark *) { + border-top-color: #39394b; + } +} +main div#content h4:not(:first-child) { + border-top-style: var(--tw-border-style); + border-top-width: 1px; + border-top-color: var(--color-base-alt); + padding-top: calc(var(--spacing) * 3); + &:where(.dark, .dark *) { + border-top-color: #39394b; + } +} +main div#content h5:not(:first-child) { + border-top-style: var(--tw-border-style); + border-top-width: 1px; + border-top-color: var(--color-base-alt); + padding-top: calc(var(--spacing) * 2); + &:where(.dark, .dark *) { + border-top-color: #39394b; + } +} +main div#content h6:not(:first-child) { + border-top-style: var(--tw-border-style); + border-top-width: 1px; + border-top-color: var(--color-base-alt); + padding-top: calc(var(--spacing) * 1); + &:where(.dark, .dark *) { + border-top-color: #39394b; + } +} +blockquote { + margin-block: calc(var(--spacing) * 4); + border-top-right-radius: var(--radius-sm); + border-bottom-right-radius: var(--radius-sm); + border-inline-start-style: var(--tw-border-style); + border-inline-start-width: 4px; + border-color: var(--color-base-alt); + background-color: var(--color-surface); + padding: calc(var(--spacing) * 4); + &:where(.dark, .dark *) { + border-color: var(--color-surface); + } + &:where(.dark, .dark *) { + background-color: var(--color-base-alt); + } +} +blockquote.tip { + border-color: var(--color-green); + background-color: var(--color-green); + @supports (color: color-mix(in lab, red, red)) { + background-color: color-mix(in oklab, var(--color-green) 30%, transparent); + } +} +blockquote.note { + border-color: var(--color-blue); + background-color: var(--color-blue); + @supports (color: color-mix(in lab, red, red)) { + background-color: color-mix(in oklab, var(--color-blue) 30%, transparent); + } +} +blockquote.important { + border-color: var(--color-violet); + background-color: var(--color-violet); + @supports (color: color-mix(in lab, red, red)) { + background-color: color-mix(in oklab, var(--color-violet) 30%, transparent); + } +} +blockquote.warning { + border-color: var(--color-yellow); + background-color: var(--color-yellow); + @supports (color: color-mix(in lab, red, red)) { + background-color: color-mix(in oklab, var(--color-yellow) 30%, transparent); + } +} +blockquote.error { + border-color: var(--color-red); + background-color: var(--color-red); + @supports (color: color-mix(in lab, red, red)) { + background-color: color-mix(in oklab, var(--color-red) 30%, transparent); + } +} +blockquote > p { + --tw-leading: var(--leading-relaxed); + line-height: var(--leading-relaxed); +} +code:not([class*="language-"]) { + border-radius: var(--radius-md); + background-color: var(--color-base-alt); + padding-inline: calc(var(--spacing) * 1); + padding-block: 1px; + font-family: var(--font-mono); + font-size: var(--text-sm); + line-height: var(--tw-leading, var(--text-sm--line-height)); + &:where(.dark, .dark *) { + background-color: var(--color-surface); + } + &:where(.dark, .dark *) { + --tw-brightness: brightness(80%); + filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,); + } +} +nav.toc { + height: calc(3/4 * 100%); + border-radius: var(--radius-md); + border-style: var(--tw-border-style); + border-width: 2px; + border-color: var(--color-base-alt); + background-color: var(--color-surface); + padding-top: calc(var(--spacing) * 4); + padding-bottom: calc(var(--spacing) * 4); + font-family: var(--font-mono); +} +nav.toc ol { + list-style-position: inside; + list-style-type: decimal; + padding-left: calc(var(--spacing) * 4); +} +nav.toc ul { + list-style-position: inside; + list-style-type: disc; + padding-left: calc(var(--spacing) * 4); +} +nav.toc ol li, nav.toc ul li { + margin-top: calc(var(--spacing) * 0); + padding-bottom: calc(var(--spacing) * 0); +} +nav.toc ol li a, nav.toc ul li a { + text-decoration-line: none; + &:hover { + @media (hover: hover) { + color: var(--color-blue); + } + } +} +nav.toc ol li::marker, nav.toc ul li::marker { + &:hover { + @media (hover: hover) { + color: var(--color-blue); + } + } +} +nav.toc ol li ol, nav.toc ul li ul { + padding-bottom: calc(var(--spacing) * 2); +} +pre[class*="language-"], code[class*="language-"] { + font-variant-ligatures: common-ligatures !important; + background-color: var(--color-surface) !important; + font-family: var(--font-mono) !important; + text-shadow: none !important; + &:where(.dark, .dark *) { + background-color: var(--color-base-alt); + } +} +pre[class*="language-"].line-numbers { + counter-reset: linenumber; + position: relative; + padding-left: calc(var(--spacing) * 13); +} +pre[class*="language-"].line-numbers > code { + white-space: inherit; + position: relative; +} +.line-numbers .line-numbers-rows { + pointer-events: none; + position: absolute; + top: -1.5px; + left: calc(var(--spacing) * -12); + display: flex; + width: calc(var(--spacing) * 10); + flex-direction: column; + border-right-style: var(--tw-border-style) !important; + border-right-width: 1px !important; + border-right-color: var(--color-grey) !important; + -webkit-user-select: none; + user-select: none; +} +.line-numbers-rows > span { + counter-increment: linenumber; + display: block; + --tw-leading: 1.5; + line-height: 1.5; +} +.line-numbers-rows > span:before { + content: counter(linenumber); + display: block; + padding-right: calc(var(--spacing) * 2); + text-align: right; + color: var(--color-grey) !important; +} +pre.mermaid { + display: flex; + justify-content: center; +} +.dark .mermaid { + filter: invert(0.9) hue-rotate(180deg); +} +@property --tw-space-y-reverse { + syntax: "*"; + inherits: false; + initial-value: 0; +} +@property --tw-space-x-reverse { + syntax: "*"; + inherits: false; + initial-value: 0; +} +@property --tw-border-style { + syntax: "*"; + inherits: false; + initial-value: solid; +} +@property --tw-font-weight { + syntax: "*"; + inherits: false; +} +@property --tw-ordinal { + syntax: "*"; + inherits: false; +} +@property --tw-slashed-zero { + syntax: "*"; + inherits: false; +} +@property --tw-numeric-figure { + syntax: "*"; + inherits: false; +} +@property --tw-numeric-spacing { + syntax: "*"; + inherits: false; +} +@property --tw-numeric-fraction { + syntax: "*"; + inherits: false; +} +@property --tw-shadow { + syntax: "*"; + inherits: false; + initial-value: 0 0 #0000; +} +@property --tw-shadow-color { + syntax: "*"; + inherits: false; +} +@property --tw-shadow-alpha { + syntax: ""; + inherits: false; + initial-value: 100%; +} +@property --tw-inset-shadow { + syntax: "*"; + inherits: false; + initial-value: 0 0 #0000; +} +@property --tw-inset-shadow-color { + syntax: "*"; + inherits: false; +} +@property --tw-inset-shadow-alpha { + syntax: ""; + inherits: false; + initial-value: 100%; +} +@property --tw-ring-color { + syntax: "*"; + inherits: false; +} +@property --tw-ring-shadow { + syntax: "*"; + inherits: false; + initial-value: 0 0 #0000; +} +@property --tw-inset-ring-color { + syntax: "*"; + inherits: false; +} +@property --tw-inset-ring-shadow { + syntax: "*"; + inherits: false; + initial-value: 0 0 #0000; +} +@property --tw-ring-inset { + syntax: "*"; + inherits: false; +} +@property --tw-ring-offset-width { + syntax: ""; + inherits: false; + initial-value: 0px; +} +@property --tw-ring-offset-color { + syntax: "*"; + inherits: false; + initial-value: #fff; +} +@property --tw-ring-offset-shadow { + syntax: "*"; + inherits: false; + initial-value: 0 0 #0000; +} +@property --tw-duration { + syntax: "*"; + inherits: false; +} +@property --tw-ease { + syntax: "*"; + inherits: false; +} +@property --tw-blur { + syntax: "*"; + inherits: false; +} +@property --tw-brightness { + syntax: "*"; + inherits: false; +} +@property --tw-contrast { + syntax: "*"; + inherits: false; +} +@property --tw-grayscale { + syntax: "*"; + inherits: false; +} +@property --tw-hue-rotate { + syntax: "*"; + inherits: false; +} +@property --tw-invert { + syntax: "*"; + inherits: false; +} +@property --tw-opacity { + syntax: "*"; + inherits: false; +} +@property --tw-saturate { + syntax: "*"; + inherits: false; +} +@property --tw-sepia { + syntax: "*"; + inherits: false; +} +@property --tw-drop-shadow { + syntax: "*"; + inherits: false; +} +@property --tw-drop-shadow-color { + syntax: "*"; + inherits: false; +} +@property --tw-drop-shadow-alpha { + syntax: ""; + inherits: false; + initial-value: 100%; +} +@property --tw-drop-shadow-size { + syntax: "*"; + inherits: false; +} +@property --tw-leading { + syntax: "*"; + inherits: false; +} +@property --tw-text-shadow-color { + syntax: "*"; + inherits: false; +} +@property --tw-text-shadow-alpha { + syntax: ""; + inherits: false; + initial-value: 100%; +} +@layer properties { + @supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))) { + *, ::before, ::after, ::backdrop { + --tw-space-y-reverse: 0; + --tw-space-x-reverse: 0; + --tw-border-style: solid; + --tw-font-weight: initial; + --tw-ordinal: initial; + --tw-slashed-zero: initial; + --tw-numeric-figure: initial; + --tw-numeric-spacing: initial; + --tw-numeric-fraction: initial; + --tw-shadow: 0 0 #0000; + --tw-shadow-color: initial; + --tw-shadow-alpha: 100%; + --tw-inset-shadow: 0 0 #0000; + --tw-inset-shadow-color: initial; + --tw-inset-shadow-alpha: 100%; + --tw-ring-color: initial; + --tw-ring-shadow: 0 0 #0000; + --tw-inset-ring-color: initial; + --tw-inset-ring-shadow: 0 0 #0000; + --tw-ring-inset: initial; + --tw-ring-offset-width: 0px; + --tw-ring-offset-color: #fff; + --tw-ring-offset-shadow: 0 0 #0000; + --tw-duration: initial; + --tw-ease: initial; + --tw-blur: initial; + --tw-brightness: initial; + --tw-contrast: initial; + --tw-grayscale: initial; + --tw-hue-rotate: initial; + --tw-invert: initial; + --tw-opacity: initial; + --tw-saturate: initial; + --tw-sepia: initial; + --tw-drop-shadow: initial; + --tw-drop-shadow-color: initial; + --tw-drop-shadow-alpha: 100%; + --tw-drop-shadow-size: initial; + --tw-leading: initial; + --tw-text-shadow-color: initial; + --tw-text-shadow-alpha: 100%; + } + } +} diff --git a/assets/css/tailwind.css b/assets/css/tailwind.css new file mode 100644 index 0000000..4064b9a --- /dev/null +++ b/assets/css/tailwind.css @@ -0,0 +1,343 @@ +@import url("https://fonts.googleapis.com/css2?family=Fira+Mono:wght@400;500;700&display=swap"); +@import url("https://unpkg.com/@catppuccin/palette/css/catppuccin.css"); +@import "tailwindcss"; +/* User content */ +@source "../../../content"; +/* User templates */ +@source "../../../templates"; +/* Theme templates */ +@source "../../templates"; + +/* Use dark class for dark theme */ +@custom-variant dark (&:where(.dark, .dark *)); + +@layer base { + /* Buttons use pointer cursor */ + button:not(:disabled), + [role="button"]:not(:disabled) { + cursor: pointer; + } +} + +/* + * Fix some code rendering bugs with PrismJS + * See https://github.com/PrismJS/prism/issues/2443 + */ +@layer utilities { + .table { + display: initial; + } +} + +/* Colorscheme, using sweetie palette */ +:root { + --base: var(--ctp-latte-base); + --base-alt: var(--ctp-latte-mantle); + --surface: var(--ctp-latte-surface0); + --text: var(--ctp-latte-text); + --text-alt: var(--ctp-latte-subtext1); + --grey: var(--ctp-latte-overlay1); + --dark-grey: var(--ctp-latte-overlay0); + --magenta: var(--ctp-latte-mauve); + --red: var(--ctp-latte-red); + --orange: var(--ctp-latte-peach); + --yellow: var(--ctp-latte-yellow); + --green: var(--ctp-latte-green); + --teal: var(--ctp-latte-teal); + --cyan: var(--ctp-latte-sky); + --blue: var(--ctp-latte-blue); + --violet: var(--ctp-latte-lavender); +} +:root.dark { + --base: var(--ctp-mocha-base); + --base-alt: var(--ctp-mocha-mantle); + --surface: var(--ctp-mocha-surface0); + --text: var(--ctp-mocha-text); + --text-alt: var(--ctp-mocha-subtext1); + --grey: var(--ctp-mocha-overlay1); + --dark-grey: var(--ctp-mocha-overlay0); + --magenta: var(--ctp-mocha-mauve); + --red: var(--ctp-mocha-red); + --orange: var(--ctp-mocha-peach); + --yellow: var(--ctp-mocha-yellow); + --green: var(--ctp-mocha-green); + --teal: var(--ctp-mocha-teal); + --cyan: var(--ctp-mocha-sky); + --blue: var(--ctp-mocha-blue); + --violet: var(--ctp-mocha-lavender); +} + +@theme static { + --font-sans: + "Fira Mono", ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", + "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; + --font-mono: + "Fira Mono", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, + "Liberation Mono", "Courier New", monospace; + + --color-base: var(--base); + --color-base-alt: var(--base-alt); + --color-surface: var(--surface); + --color-text: var(--text); + --color-text-alt: var(--text-alt); + --color-grey: var(--grey); + --color-dark-grey: var(--dark-grey); + --color-red: var(--red); + --color-orange: var(--orange); + --color-green: var(--green); + --color-teal: var(--teal); + --color-yellow: var(--yellow); + --color-blue: var(--blue); + --color-magenta: var(--magenta); + --color-violet: var(--violet); + --color-cyan: var(--cyan); +} + +/* Overall design */ +html { + scrollbar-color: var(--blue) var(--surface); + @apply scroll-smooth tabular-nums font-sans; +} + +body { + @apply bg-base text-text antialiased font-medium; +} + +main a { + @apply underline hover:text-blue; +} + +a.icon { + @apply no-underline; +} + +a { + @apply transition-colors duration-200 ease-in-out; +} + +hr { + /* brightness-120 = #39394b */ + @apply text-base-alt dark:brightness-120; +} + +header, +footer { + @apply bg-surface text-text-alt; +} + +h1, +h2, +h3, +h4, +h5, +h6 { + @apply font-bold; +} + +h1 { + @apply text-3xl; +} + +h2 { + @apply text-2xl; + counter-increment: h2; + counter-reset: h3; +} + +h3 { + @apply text-xl; + counter-increment: h3; + counter-reset: h4; +} + +h4 { + @apply text-lg; + counter-increment: h4; +} + +h5 { + counter-increment: h5; +} + +h6 { + @apply font-semibold; + counter-increment: h6; +} + +p { + @apply leading-relaxed py-2; +} + +strong { + @apply font-semibold; +} + +ul { + @apply list-disc; +} + +ol { + @apply list-decimal; +} + +ul, +ol { + @apply leading-relaxed; +} + +nav ul, +nav ol { + @apply mx-2 space-y-0 list-none; +} + +main ul { + @apply pl-4; +} + +/* Margins */ +main h2, +article h2, +section h2 { + @apply mt-10; +} +main h3, +article h3, +section h3 { + @apply mt-8; +} +main h4, +article h4, +section h4 { + @apply mt-6; +} +main h5, +article h5, +section h5 { + @apply mt-4; +} +main h6, +article h6, +section h6 { + @apply mt-2; +} + +/* Visual flair */ +main div#content h2:not(:first-child) { + @apply border-t border-t-base-alt dark:border-t-[#39394b] pt-5; +} +main div#content h3:not(:first-child) { + @apply border-t border-t-base-alt dark:border-t-[#39394b] pt-4; +} +main div#content h4:not(:first-child) { + @apply border-t border-t-base-alt dark:border-t-[#39394b] pt-3; +} +main div#content h5:not(:first-child) { + @apply border-t border-t-base-alt dark:border-t-[#39394b] pt-2; +} +main div#content h6:not(:first-child) { + @apply border-t border-t-base-alt dark:border-t-[#39394b] pt-1; +} + +blockquote { + @apply p-4 my-4 border-s-4 rounded-r-sm border-base-alt bg-surface dark:border-surface dark:bg-base-alt; +} + +blockquote.tip { + @apply border-green bg-green/30; +} +blockquote.note { + @apply border-blue bg-blue/30; +} +blockquote.important { + @apply border-violet bg-violet/30; +} +blockquote.warning { + @apply border-yellow bg-yellow/30; +} +blockquote.error { + @apply border-red bg-red/30; +} + +blockquote > p { + @apply leading-relaxed; +} + +/* Inline verbatim `` */ +code:not([class*="language-"]) { + @apply px-1 py-px font-mono text-sm rounded-md bg-base-alt dark:bg-surface dark:brightness-80; +} + +/* Table of Contents */ +nav.toc { + @apply h-3/4 pt-4 pb-4 font-mono bg-surface border-2 border-base-alt rounded-md; +} + +nav.toc ol { + @apply pl-4 list-decimal list-inside; +} + +nav.toc ul { + @apply pl-4 list-disc list-inside; +} + +nav.toc ol li, +nav.toc ul li { + @apply mt-0 pb-0; +} + +nav.toc ol li a, +nav.toc ul li a { + @apply no-underline hover:text-blue; +} + +nav.toc ol li::marker, +nav.toc ul li::marker { + @apply hover:text-blue; +} + +nav.toc ol li ol, +nav.toc ul li ul { + @apply pb-2; +} + +/* PrismJS specific css */ +pre[class*="language-"], +code[class*="language-"] { + font-variant-ligatures: common-ligatures !important; + @apply bg-surface! dark:bg-base-alt font-mono! text-shadow-none!; +} + +/* PrismJS line-numbers plugin */ +pre[class*="language-"].line-numbers { + counter-reset: linenumber; + @apply relative pl-13; +} + +pre[class*="language-"].line-numbers > code { + white-space: inherit; + @apply relative; +} + +.line-numbers .line-numbers-rows { + @apply absolute flex flex-col top-[-1.5px] -left-12 w-10 pointer-events-none select-none border-r! border-r-grey!; +} + +.line-numbers-rows > span { + counter-increment: linenumber; + @apply block leading-[1.5]; +} + +.line-numbers-rows > span:before { + content: counter(linenumber); + @apply text-grey! text-right pr-2 block; +} + +/* Center MermaidJS charts and diagrams */ +pre.mermaid { + @apply flex justify-center; +} + +/* Automatic dark theme for MermaidJS */ +.dark .mermaid { + filter: invert(0.9) hue-rotate(180deg); +} diff --git a/assets/norgolith.svg b/assets/norgolith.svg new file mode 100644 index 0000000..6da6bf3 --- /dev/null +++ b/assets/norgolith.svg @@ -0,0 +1,181 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/style.css b/assets/style.css new file mode 100644 index 0000000..3417daf --- /dev/null +++ b/assets/style.css @@ -0,0 +1,110 @@ +/* Default fonts */ +@font-face { + font-family: "Inter"; + font-style: normal; + font-display: swap; + font-weight: 100 900; + src: url(https://cdn.jsdelivr.net/fontsource/fonts/inter:vf@latest/latin-wght-normal.woff2) format('woff2-variations'); + 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; +} + +@font-face { + font-family: "JetBrains Mono"; + font-style: normal; + font-display: swap; + font-weight: 100 800; + src: url(https://cdn.jsdelivr.net/fontsource/fonts/jetbrains-mono:vf@latest/latin-wght-normal.woff2) format('woff2-variations'); + 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; +} + +@font-face { + font-family: "JetBrains Mono Italic"; + font-style: italic; + font-display: swap; + font-weight: 100 800; + src: url(https://cdn.jsdelivr.net/fontsource/fonts/jetbrains-mono:vf@latest/latin-wght-italic.woff2) format('woff2-variations'); + 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; +} + +/* Styling */ +*, *:before, *:after { + box-sizing: border-box; +} + +body { + color: white; + background-color: #202030; + width: auto; + height: 100%; + font-family: "Inter", ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; +} + +/* Inline verbatim `` */ +code { + font-family: "JetBrains Mono", monospace; + background-color: #303040; + border-radius: 6px; + padding: 0px 4px; +} + +/* PrismJS specific css */ +pre[class*="language-"], +code[class*="language-"] { + text-shadow: unset !important; + font-family: "JetBrains Mono", monospace !important; +} + +/* PrismJS line-numbers plugin */ +pre[class*="language-"].line-numbers { + position: relative; + padding-left: 3.4em; + counter-reset: linenumber; +} + +pre[class*="language-"].line-numbers > code { + position: relative; + white-space: inherit; +} + +.line-numbers .line-numbers-rows { + position: absolute; + pointer-events: none; + top: 0; + font-size: 100%; + left: -3.8em; + width: 3em; /* works for line-numbers below 1000 lines */ + /* letter-spacing: -1px; */ + border-right: 1px solid #999; + + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.line-numbers-rows > span { + display: block; + counter-increment: linenumber; +} + +.line-numbers-rows > span:before { + content: counter(linenumber); + color: #999; + display: block; + padding-right: 0.8em; + text-align: right; +} + +/* Norgolith landing page styling */ +#desc > a, +#discord-link > a, +#github-pages > a, +#github-issues > a { + color: var(--color-blue-400); +} +#desc > a:hover, +#discord-link > a:hover, +#github-pages > a:hover, +#github-issues > a:hover { + text-decoration: underline; +} diff --git a/categories/blog/index.html b/categories/blog/index.html new file mode 100644 index 0000000..924e404 --- /dev/null +++ b/categories/blog/index.html @@ -0,0 +1,271 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Category: blog - Voidarc + + + +
+
+ + +
+ +
+ +
+

Posts in blog

+

All the posts with the category "blog"

+ +
+ +
+ +
+
+ Copyright © 2026 + + Adumh00man. + + +
Licensed under MIT. + +
+
+ + + +
+
+ +
+
+ + diff --git a/categories/homelab/index.html b/categories/homelab/index.html new file mode 100644 index 0000000..580f750 --- /dev/null +++ b/categories/homelab/index.html @@ -0,0 +1,253 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Category: homelab - Voidarc + + + +
+
+ + +
+ +
+ +
+

Posts in homelab

+

All the posts with the category "homelab"

+ +
+ +
+ +
+
+ Copyright © 2026 + + Adumh00man. + + +
Licensed under MIT. + +
+
+ + + +
+
+ +
+
+ + diff --git a/categories/index.html b/categories/index.html new file mode 100644 index 0000000..66b499c --- /dev/null +++ b/categories/index.html @@ -0,0 +1,332 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Categories - Voidarc + + + +
+
+ + +
+ +
+ +
+

Categories

+

All the categories used in posts.

+
    + + + + + + + +
  • + blog + (3 posts) +
  • + + + + + + + +
  • + homelab + (1 post) +
  • + + + + + + + +
  • + linux + (2 posts) +
  • + + + + + + + +
  • + neorg + (1 post) +
  • + + + + + + + +
  • + nix + (1 post) +
  • + + + + + + + +
  • + nvim + (1 post) +
  • + + + + + + + +
  • + voidarc + (2 posts) +
  • + + + + + + + +
  • + webdev + (2 posts) +
  • + +
+
+ +
+ +
+
+ Copyright © 2026 + + Adumh00man. + + +
Licensed under MIT. + +
+
+ + + +
+
+ +
+
+ + diff --git a/categories/linux/index.html b/categories/linux/index.html new file mode 100644 index 0000000..26ecb02 --- /dev/null +++ b/categories/linux/index.html @@ -0,0 +1,262 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Category: linux - Voidarc + + + +
+
+ + +
+ +
+ +
+

Posts in linux

+

All the posts with the category "linux"

+ +
+ +
+ +
+
+ Copyright © 2026 + + Adumh00man. + + +
Licensed under MIT. + +
+
+ + + +
+
+ +
+
+ + diff --git a/categories/neorg/index.html b/categories/neorg/index.html new file mode 100644 index 0000000..9c178fb --- /dev/null +++ b/categories/neorg/index.html @@ -0,0 +1,253 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Category: neorg - Voidarc + + + +
+
+ + +
+ +
+ +
+

Posts in neorg

+

All the posts with the category "neorg"

+ +
+ +
+ +
+
+ Copyright © 2026 + + Adumh00man. + + +
Licensed under MIT. + +
+
+ + + +
+
+ +
+
+ + diff --git a/categories/nix/index.html b/categories/nix/index.html new file mode 100644 index 0000000..3f73d8b --- /dev/null +++ b/categories/nix/index.html @@ -0,0 +1,253 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Category: nix - Voidarc + + + +
+
+ + +
+ +
+ +
+

Posts in nix

+

All the posts with the category "nix"

+ +
+ +
+ +
+
+ Copyright © 2026 + + Adumh00man. + + +
Licensed under MIT. + +
+
+ + + +
+
+ +
+
+ + diff --git a/categories/nvim/index.html b/categories/nvim/index.html new file mode 100644 index 0000000..5dae44f --- /dev/null +++ b/categories/nvim/index.html @@ -0,0 +1,253 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Category: nvim - Voidarc + + + +
+
+ + +
+ +
+ +
+

Posts in nvim

+

All the posts with the category "nvim"

+ +
+ +
+ +
+
+ Copyright © 2026 + + Adumh00man. + + +
Licensed under MIT. + +
+
+ + + +
+
+ +
+
+ + diff --git a/categories/voidarc/index.html b/categories/voidarc/index.html new file mode 100644 index 0000000..1458faa --- /dev/null +++ b/categories/voidarc/index.html @@ -0,0 +1,262 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Category: voidarc - Voidarc + + + +
+
+ + +
+ +
+ +
+

Posts in voidarc

+

All the posts with the category "voidarc"

+ +
+ +
+ +
+
+ Copyright © 2026 + + Adumh00man. + + +
Licensed under MIT. + +
+
+ + + +
+
+ +
+
+ + diff --git a/categories/webdev/index.html b/categories/webdev/index.html new file mode 100644 index 0000000..8902007 --- /dev/null +++ b/categories/webdev/index.html @@ -0,0 +1,262 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Category: webdev - Voidarc + + + +
+
+ + +
+ +
+ +
+

Posts in webdev

+

All the posts with the category "webdev"

+ +
+ +
+ +
+
+ Copyright © 2026 + + Adumh00man. + + +
Licensed under MIT. + +
+
+ + + +
+
+ +
+
+ + diff --git a/index.html b/index.html new file mode 100644 index 0000000..3b679e7 --- /dev/null +++ b/index.html @@ -0,0 +1,304 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Home - Voidarc + + + +
+
+ + +
+ +
+ +

Voidarc

Home page for Voidarc Documentation (or whatever excuse for a blog this is). I just wanted to do this for fun idk. Seems interesting for A-level.

If you can read this, server02 hasn't crashed (yet) :)

Email always open: admin@voidarc.co.uk (if my mailserver is up, which is sometimes)

+ + + +
+

Recent posts

+ +
+
+

Why Nixos is the Coolest Operating System

+ I really like Nix + +
+
+

+ + + + The Nixos Philosophy Nix is the all in one solution to every problem you could have with Linux. It p… +

+ Read more … +
+
+ +
+
+

How I fell in with Linux

+ Haha war of the worlds reference + +
+
+

+ + + + Some Backstory Linux is not hard to learn. Some say it is, but they're wrong. If one can be afraid o… +

+ Read more … +
+
+ +
+
+

Making a Blog Using a Niche Markdown Language

+ How to make a blog using Norg and some random project from github + +
+
+

+ + + + Nonsense Preamble Neorg is a markdown Language that is Org mode but with some different shit in it. … +

+ Read more … +
+
+ +
+ + + +
+ +
+
+ Copyright © 2026 + + Adumh00man. + + +
Licensed under MIT. + +
+
+ + + +
+
+ +
+
+ + diff --git a/posts/homelab/index.html b/posts/homelab/index.html new file mode 100644 index 0000000..cc6dbae --- /dev/null +++ b/posts/homelab/index.html @@ -0,0 +1,330 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + How I Fell In With Linux - Voidarc + + + +
+
+ + +
+ +
+ +
+

How I fell in with Linux

+
+
+
+
+ + + + + + + +
+ + + +
+
+ + + +
+

Some Backstory

Linux is not hard to learn. Some say it is, but they're wrong. If one can be afraid of a terminal, then I must be the bravest man alive. But, I digress. I began many moons ago, when I was still young, innocent, and didn't know what nix was (what precious days). I began tinkering with some ubuntu virtual machines, but, since I didn't have much of a use for them, I stuck to the desolate landscape of windows, which was still pretty good at the time, to be fair. This was in the dark days before windows 11 struck, and before RAM was £3000. Skip forward, to when I decided that building a PC was a good use of money. I will admit, it was a steal, even for the time. I was doing LTT challenges before they were even popular, managing to build a fully functional machine for the low low price of about £700. In what was to be the first issue I had ever faced, I decided to install windows. Foolish.

That is not the point of this story, though. Fast forward again, to when I aqquired, through some sheer luck, a relative's old desktop. It was, of course, a piece of shit. 4gb of ram, something something pentium. It was hardly anything to write home about. The only thing it had going was that it had a whole terabyte of storage hidden within, a drive I am still using 4 years on, as of writing this, to store all of my legally aqquired media (I'll get to it later). I had the brilliant idea of turning it into a server. Of course, instead of doing anything moderately intelligent, I installed ubuntu on it, and accessed it over rdp for about 6 months. I know, revolutionary. This was the legendary Server01, or, at least, the first iteration.

The first iteration

As far as I can remember, I never really hosted anything interesting for the first stretch of time. But, after seeing my success in hosting a whole docker container (thanks networkchuck), the linux addiction began to take hold of me. I scoured facebook marketplace for anything that could satiate my urge to fuck about with json more efficiently, until I came across a diamond in the rough. For a measly £20, an old workstation. A HP Optiplex. Server02.

8 whole gigs of ram, a (moderately) more powerful processor, and even more storage. It was a dream come true. It was around this time, too, that I installed either Arch or fedora on my laptop (All I can remember is that it had kde and was a laggy piece of shit), which let me get used to how linux actually functioned. After another banger video from networkchuck, detailing the installation of a load balancer, the Kemp Loadmaster (I would come to hate that name), I finally had the inspiration to reinstall everything. The second iteration had begun.

The one with Alpine

I couldn't tell you why, but I got it in my head that Alpine was the lightest distro. Knowing that my "servers" (if you could call them that) were basically E waste, I figured that alpine was the obvious choice, because of how fast it was, or something. It probably had something to do with all the docker images that were based on it, but now I know that they're only based on alpine for the sake of it. Alpine is a small distro, sure, but for that storage space, you sacrifice basically everything you need to live. I.e. packages.

Even so, I transfered the kemp install over to a usb and began the installation. Both servers kitted out with only the finest alpine images money could buy. I was quick to install docker and get up basically the only service that I had at the time, plex.

Plex

Plex is shit. I can see that now. Before I knew it was propriotary nonsense, I thought it was amazing. Fast, efficient, something something. Who am I kidding, I saw it on an LTT video and installed it immediately. I can't remember what I even hosted on there, since it was way before I installed the arr stack or anything like that, but I switched over to my love jellyfin a few months later.

Alpine lasted a good while. I was still on windows at this point, and only really used the servers for silly little services. Before that, though, I need to explain a key part of the plan

Humble beginnings

In the same video explaining the load balancer, Chuck showed me how to get a free domain. I needed a name, and voidarc was something I had recently cooked up for some story or another, so I went with that. As you can see, it stuck. Hence, voidarc.tk was born.

Voidarc.tk was to become a core part of my life. Using the newfound power that came with a commercial load balancer, I began adding services left right and center, services that would follow me, if not uselessly, all the way through until the co.uk days. Some notable services included: kasm, a remote app gateway, which was fun while it lasted, but alltogether useless; portainer, that I never once used to start a container; code-server, where I ended up doing most of my development and management, just to name a few. The domain also allowed me to host public minecraft servers, the domains for which had remained unchanged until a few months ago. A few attempts at making an ssh server over https were made, but none were sucessful, because I was doing it wrong.

The linux era

By this time, it was the summer of 2023. My laptop had Arch on it by now, after going through a phase of being a windows machine because I couldn't figure out intel drivers, and I was on holiday. This was the turning point. This was the holiday that turned me into a loser. For the first week, nothing interesting happened, the same for the next week. I was using the code server I had set up to program one thing or another, but the fact I was using linux at all was completely lost on me. It wasn't until that fateful day when someone I knew on the campsite offered to show me her laptop that it clicked. She brought out a thinkpad, and displayed on the screen was a linux desktop the likes of which I had never seen before. The linux desktop that would end me.

Hyprland

The transition to Linux

I didn't know at the time what hyprland was, or how it worked, but after seeing such a beautiful system with my own mortal eyes, I knew I wanted in. I researched, coming across sway and some other nonsense I ended up not using. After a trip onto r/unixporn, I realised that almost everyone was using hyprland. So, I did the same. I decided, still on holiday, to reinstall arch with hyprland and configure it, so that when I got back home, I could install it on my main machine.

Needless to say, it was a success. In the beginning, there was a lot of stealing configs, as is normal, because I had no idea what I was doing. The day came, and I erased windows for the final time. Of course, I used archinstall, but it hardly made a difference. The first day was spent trying to figure out modesetting so that my gpu, a GTX 1070, would work with wayland. I hate kernel options.

A time came when I decided that there needed to be a change, so I installed a complete solution, called hyprdots. This is when I realised that I hated that idea of bloat. I understood the minimalists! But anyway, this is an article on servers, not other random shit. I digress.

The penultimate era: the plateu

I realised eventually that Alpine was also shit. So, in a frantic evening of usb installers, I switched server02 over to arch. And so it remains to this day. I wouldn't be surprised if there were still remnants of zammad lurking in the /etc folder. Zammad was a ticketing system that was a royal pain in my ass to install, and broke at every possible convenience. Don't even know why I needed it in the first place, if I'm honest. Server01 remained on alpine, and still does for some reason, but only because I can't be bothered to wait for my home assistant image to copy over to a usb. Not happening with usb2 speeds. There was a period where I tried to use proxmox on server01, since I only wanted vms on there, but it was too slow to bother, so I gave in to the alpine gods and removed that kvm entry. This is where development began to slow to a halt. I had bought a .co.uk domain by now, and the services I used were now set in stone. I wasn't using jellyfin daily yet, or really anything. The most I used my servers was to watch some manually downloaded show that I could've just found online. I believe that that was how I first watched JJK.

I had a download manager in some docker container that I had to manually add torrents to so that they would download. What trying times. I definately didn't know what the arr stack was even for back then, but I trudged on. Some other notable services included:

  • Portainer (still didn't use it)
  • homepage, for a time
  • code-server, obviously
  • shellinabox, probably the best thing ever made.

And that's where it stayed for a while. I made no changes, and no efforts to remove the invasive nonsense from my life. How sad :(.

De-corporatifying

There came a time when I got fed up of the overpriced nonsense shit that the companies of the world believe that we should put up with. I wanted freedom. I wanted a better life. And more importantly, I didn't want a gruvbox themed system anymore. So, everything changed I reinstalled arch on my main pc. I re-themed everything. But, most importantly, I purged a load of shit that I didn't use anymore. Of course, this made me install a load of other random shit that I used for all of 10 minutes, but that's the price you pay when you self-host. I stripped down, finally removed portainer, and focused on making my servers as useful as possible. I even automated replacing the ip on cloudflare when fucking vodafone decided it was funny to change it, and not give an option to have a static ip in the first place. This system is, of course, still in use to this day, and is using node.js and a cron job instead of anything more logical. What works, works, but I should probably put it on n8n someday.

I started to use Jellyfin more frequently, and get away from shit social media. I uninstalled snapchat, leaving me with only whatsapp and reddit, which is all the modern man really needs. No more youtube shorts, either. I got into deadmau5, too, but that's unrelated. It was around this time, too, when I decided hosting a mailserver would be a fun thing to do. It was not, and still barely functions to this day.

Then, the final evolution occured.

The last straw

I was interested in nix when i first heard of it. Imagine, a whole system, version controlled and reproducible on any machine. I know now that that was a stupid way to think about it, but it began as it always did, with an install on my laptop. It seemed simple enough, and I got a hyprland system working fairly quickly. Of course, the evolution of my nix config is a whole other story article, so I'll save it for now. I believe once I installed nix, things began to accelerate. I began to wonder what else could be replaced. Could endless reddit feeds be replaced by something more interesting? Could manual downloads be automated? Could I be free of the mortal coil that is Microslop and Github? I began to experiment, on the old trusty server02.

Current era: before proxy manager

It all started when I finally realised what the Arr stack actually was. I had it set up within the day, importing all of my shows. More importantly, I realised that I could automate downloading the albums that were so hard to source on mobile. It began with deadmau5, then some other artists, and before long I had a library of 800 songs that I could listen to without the permission of some old man in a suit (I was using auxio before then, which was open source, but shush). That was the first service that I replaced.

Then came the second. After finishing JJK for the second time, I wanted to see the rest of the story. So, I downloaded the manga. To my server of course. I fired up komga, and then changed my mind when the other options were worse. I finished the manga in about 2 months, before moving onto one punch man, and now one piece (which is peak btw). There was another purge somewhere in the middle of all of this, but I was hardly using any of the other services anyway.

Finally, there was git. Gitea I mean. My github had become bloated with a load of shit that I didn't want anymore, like old dockerfiles and non-functional web games. So, I left it all behind. Gitea was a breeze to set up, and I only had to change over a few links on my local repos in order for it to work. At long last, my config was owned by me. Not microslop

The final realisation

Kemp loadmaster had seen me through over 4 years of trials and tribulations. It was tried and true, and worked even better when you added a * entry in cloudflare. However, it was on one fateful night that I sight of a reddit thread complaining about speed on the Free tier. I clicked, aprehensively, and what I saw next truly rocked me to my core.

Free tier bandwidth cap.

I immediately googled it, and to my utter shock, The free tier had always been limeted to a measly 20mbps. For reference, I was paying for 900. No wonder my sites were slow, I thought, no wonder it took 2 minutes to load a word document. I had always attributed responsiveness to the shit cpu in server02. I would never have thought that my oldest ally would betray me so. So, with a heavy heart, and a somber funeral, I pulled the plug on the kemp loadmaster for the final time.

Modern day Homelabbing

Nginx proxy manager was something I had tried to use before, but not understood in the slightest. Turns out, before, I was putting the urls in the wrong boxes. Once I had switched it over, and given my home assistant vm the ram it deserved, I was finally free. Cryptpad actually loaded! Git pulls were as fast as they were on github! I was free! Thank God, I was free.

Nowadays, I host only what I need on my servers, the latest of which being this Blog site. The only thing I don't use is syncthing, but you never know when that might come in handy. And yes, I did figure out how to use ssh over cloudflare, and do on a regular basis. The Arr stack and jellyfin save me from having to crawl through the pirate bay every time I want to watch a movie, and Cryptpad saves me from the affront to humanity that is onedrive. The last thing I still have to do is switch to grapheneos, but that would be a whole article within itself too.

The moral of the story

If I were a youtuber, I would give some do's and dont's on how to set up your own homelab. But, I'm not a youtuber, or knowledgeable. So, If I had to give some advice, I would say 2 things:

If you're going to start, then do it. If you wait until you're ready, you'll be waiting for the rest of your life.

And, whatever you do...

Stay the fuck away from Zammad.

+
+ +
+ +
+
+ Copyright © 2026 + + Adumh00man. + + +
Licensed under MIT. + +
+
+ + + +
+
+ +
+
+ + diff --git a/posts/index.html b/posts/index.html new file mode 100644 index 0000000..19e1701 --- /dev/null +++ b/posts/index.html @@ -0,0 +1,295 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Posts - Voidarc + + + +
+
+ + +
+ +
+ +

Posts

+
+ +
+
+

Why Nixos is the Coolest Operating System

+ + I really like Nix +
+
+

+ + + + The Nixos Philosophy Nix is the all in one solution to every problem you could have with Linux. It prides itself on being a fully declarative way to install and manage system packages, and It (mostly) achieves those goals. Before trying to involve oneself in such matters, though, an important distin… +

+ Read more … +
+
+ +
+
+

How I fell in with Linux

+ + Haha war of the worlds reference +
+
+

+ + + + Some Backstory Linux is not hard to learn. Some say it is, but they're wrong. If one can be afraid of a terminal, then I must be the bravest man alive. But, I digress. I began many moons ago, when I was still young, innocent, and didn't know what nix was (what precious days). I began tinkering with … +

+ Read more … +
+
+ +
+
+

Making a Blog Using a Niche Markdown Language

+ + How to make a blog using Norg and some random project from github +
+
+

+ + + + Nonsense Preamble Neorg is a markdown Language that is Org mode but with some different shit in it. It is supposed to be a replacement, but since I never really used Org mode in the first place, that doesn't really apply. However, after using it for a whole 10 seconds, I decided I could never go bac… +

+ Read more … +
+
+ +
+ +
+ +
+
+ Copyright © 2026 + + Adumh00man. + + +
Licensed under MIT. + +
+
+ + + +
+
+ +
+
+ + diff --git a/posts/nix/index.html b/posts/nix/index.html new file mode 100644 index 0000000..75b5bb4 --- /dev/null +++ b/posts/nix/index.html @@ -0,0 +1,319 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Why Nixos Is The Coolest Operating System - Voidarc + + + +
+
+ + +
+ +
+ +
+

Why Nixos is the Coolest Operating System

+
+
+
+
+ + + + + + + +
+ +
+ Tags:  + + + Linux + + + + Blog + + + + Nix + + +
+ +
+
+ + + +
+

The Nixos Philosophy

Nix is the all in one solution to every problem you could have with Linux. It prides itself on being a fully declarative way to install and manage system packages, and It (mostly) achieves those goals. Before trying to involve oneself in such matters, though, an important distinction to make is that Nix as a concept, and a package manager, is seperate from Nixos as a system. Nix can, and should, in some cases, exist outside of Nixos. But, let's get onto that later.

Origins

If you wanted a full rundown on how nix came about, then you're in the wrong place. Go read wikipedia or something. The main thing that you need to know is that the nix language, and therefore the packaging system, was made on a whim for a university dissertation. First of all, that's pretty insane. Making an entire programming language for the sake of it, and I wouldn't even be surprised if he didn't get full credit. It quickly caught the attention of all the linux nerds out there, and before long it had evolved into the nix project that we know and love today.

Reasoning and Methodology

The main draw of nix as a concept is it's reproducability. It works similarly, and often in tandem with, Git. The git working tree is a simple concept. A long ledger of changes (more commonly called diffs), that when put together results in a full codebase. Nix uses this principle to its advantage, and I will demonstrate this by comparing nixpkgs with another common package repo, the AUR.

The AUR

The AUR is the Arch User Repository, a gigantic collection of packages uploaded by anyone that can be asked to figure out how PKGBUILDS work. PKGBUILDS are a form of makefile, that is used as a standard way of declaring dependancies, versions wherein, and how to build a given app. These PKGBUILDS are stored within the repos they are associated with, and are therefore versioned alongside the app. When you upload an app to the AUR, and it is approved, a static version of your app, ie one commit, is hosted on the aur domain. This url is read only, and cannot be viewed like something hosted on github. To install the app, you clone the repo and use makepkg -si to compile.

The key part of all of that is that only one commit is hosted at a time. Because arch is a "rolling release" distro, they see no need to waste storage on older versions of apps. This is an issue, when there is a breaking change and you cannot roll back to an older version of a package, because it no longer exists. This is remedied slightly by the pacman cache, but that only goes for your local machine. If you need a specific version of an app, then either compile from source or give up.

But, I hear you ask, what happened to git versioning? Can't you just roll back to an older commit and use the PKGBUILD from there? This, my friend, is where Nix comes in.

Nixpkgs

Nixpkgs is, without exxageration, a git repository. Every time you install a package, the entire repo is pulled to your local machine. Despite the fact that, at the time of writing, it has over 200,000 packages, it is still small enough, because of how diffs work, to be downloaded every time you need to update an app. The reason for this is that it leverages git histories to their maximum potential.

Git, as I said, is just a long ledger of changes. All diffs are stored in the .git folder, along with some other stuff that might be important to someone someday. Every time you make a commit, a new hash is generated. It isn't important how the hash is generated, just that every commit has a unique hash associated with it. This gives rise to revisions. With this hash, you can address a specific state of the ecode at that commit, and this is what nix uses to stay so small.

Every package has a .nix file, that details its build process. This can be as simple as compiling one file to a binary, all the way up to compiling the whole linux kernel. Nix in of itself is a wrapper for every other build system, which means that any app that can be built can be run on nix. Hence, when enough apps are compiled, nixpkgs becomes completely self sufficient. For an app to be built with nix, all of its dependancies, and the builder itself, must also be built with nix. This means that, instead of using a manner of different build systems, and rolling release nonsense, that means that you can never be sure if you're getting the same version of a dependancy an app was developed with, you simply call another nix file, at a specific rev, or commit.

This leads to what is known as a dependancy chain. Because you call every dependancy with a specific rev, you can make sure that you are getting the right version. When you get down to the actual source code, that isn't nix, you download the specified rev of the third party repo, and compile that. If an app compiles once, it will always compile, because the git ledger should never be changed manually.

In practice

Due to the existence of flakes, something that I'll get to later, this is made much easier. No more "it works on my machine", because, for all intents and purposes, all machines are identical when running nix. There are no outside dependancies, so there is no way for an app to fail to compile. Nix as a package manager can be used on other systems, being monolithically configured with one file, that can be shared and rebuilt on any other machine with (almost) exactly the same functionality.

Hang on, this sounds awfully familiar. Like a problem that system integrators have been trying to solve for years, but could only come so close. And so, the quest for a system built with Nix began.

Nixos, the coolest operating system

Nixos is what came of that endeavour. A system fully defined by code. A system that could be rebuilt over and over, with exactly the same result, on multiple machines. This had the added benefit of the same git methodology that nixpkgs was based on. No more updates that rendered your computer unusable! You could simply revert back to a previous revision of your system, using the same diff structure that git uses, but with boot entries and packages instead of just code.

Nixos is the pinnacle of stability. By definition, there can't be a more stable system. By virtue of the fact that It can be rolled back, it cannot be defeated in that regard. It is impossible to have conflicting packages, because, in theory, all packages can be installed alongside eachother. If you want to install 50 different versions of the linux kernel at once, then go ahead! If you want to run 10 different versions of firefox on the same machine, there's nothing stopping you! You get all of the benefits of rolling release, while also having the option of installing a 5 year old version of onlyoffice in the same breath.

And the best part? Your system config, in of itself, can be controlled by git! It's git all the way down! I can instantly have the same system I did 6 months ago if I wanted to, the only difference being the user files, of course. Ah, the user files.

Home Manager: An attempt was made

Home manager is the logical extension of Nixos. A way to control dotfiles, or really any file, through nix. Revisions, versioning, etc. It seems like a good idea on paper, until you try to use it.

First of all, the way that home manager works is exactly the same as the nix store. It creates a load of read only folders, and then generates the immutable config files within. Seems reasonable, why would you want to change them in the first place? Two words: Lock File. Nvim is the main culprit when it comes to issues like this. The Lazy.lock file can't update, because presumably the entire .config/nvim folder was created by home-manager, meaning that updating packages is nearly impossible. All home manager leads to is a massive headache at the end of the day. Especially when you come across some unsupported app, where you have to paste in the non-nix config so that home-manager can copy and paste it into a read only file somewhere else in your home directory.

Because of these issues, I have taken a different approach, which I will now go on a tangent about.

The Better way to manage dotfiles

Stow is an old GNU utility. It calls itself a "symlink farm", which is fancy speak for "it takes files in a directory and links them to another place". The idea is that you have a folder with all of your dotfiles in, the ones that you actually care about, and stow links them to your actual .config directory. I used this for a while, in order to manage my hyprland and nvim configs more nicely.

Due to the fact it's a GNU utility, however, it's really old. And doesn't have nice features. It was never intended to be a dotfiles manager, so didn't have the killer feature that I would need to make a proper nix config. Multiple host support.

I have 2 machines that I have nix on. My laptop and my desktop. I want a similar experience between the two, but some things I want to be different. Nixos thought of this, and made it so that you could have different outputs in a flake, that represented different systems. But what about all my other nonsense? My monitor names are different between the two machines, and I had different keyboard styles, so wanted different modifiers too! This could be remedied by loads of scripts, but that was boring. I needed something new. Something... Intuitive.

Doot: The Fast, Intuitive dotfiles manager

Doot is my choice for a dotfiles manager. It's fast(ish), configurable, and, most importantly, was built with multiple hosts in mind. If you want to see how it works more closeley, click the link at the start of this paragraph, or have a look at my Dotfiles, which I think are pretty cool. For those of you that can't be asked to have a look, though, I'll explain the concept as simply as I can be bothered.

Your doot repo is located in the .dotfiles directory, next to .config. When you run doot install, the folders in your repo are mapped to your home directory in the same structure as they were in the repo. Eg, if you put a .zshrc in the root of the repo, it will end up in the right place. So far, this is exactly the same as stow, the only difference being where stow would link a whole folder, doot creates the structure in place and only symlinks files.

Doot can be configured in the doot folder, in the root of the repo, that will not be mapped to the home directory. The doot config contains things like exclude files (like .gitignores and licences), the diff viewer you want to use to see file changes, and your different hosts. Doot manages hosts intelligently, using the hostname of the machine as an indicator. Here is my host config:

[hosts]
+"HACKSTATION" = "pc-files"
+"mobile02" = "laptop-files"
+

The keys on the right correspond to the different hostnames, and the keys on the right correspond to the folders that contain the dotfiles specific to that machine. These folders are located in the root of the repo, and within them, contain another structure that is relative to your home directory. Eg, in the pc-files directory, there is also a .config directory, with some specific hyprland configs that only work on my PC.

What was I talking about again?

You could, of course, version every single file on your disk using this method, but that sounds like a waste of time. There will never be a world where 100% of a system is always generated by nix, because there will always be some random app that only compiles to an appimage and uses proprietary config locations or something. Nevermind how you would manage something like a download folder.

I believe that Nix, and Nixpkgs, is the gold standard when it comes to software development. There are genuine, real world uses for stuff like this. Sites like replit are fully managed and distributed using nix, because of how stupidly stable it is. You can define whole Kubernetes clusters on nix, and then update them in place with 0 downtime. Pretty impressive. However, as tends to happen with nerds on the internet (me included), the concept and utility that comes along with something like nix is buried under who can make the lightest or best looking config.

Moral of the story (or something)

Nix isn't for everyone. If you don't care about versioning everything in your entire life, then you're probably better off sticking with something like arch. If you don't mind that you have slightly different configs across different machines, then there's no need for you to learn how to use flakes so that you can make sure that you have identical packages on all of your systems.

But, It sure is fun to mess around with. If you're on the fence about trying nix, then this is your indicator to switch. It will make you feel a great deal of things, but regret will not be one of those feelings.

+
+ +
+ +
+
+ Copyright © 2026 + + Adumh00man. + + +
Licensed under MIT. + +
+
+ + + +
+
+ +
+
+ + diff --git a/posts/site/index.html b/posts/site/index.html new file mode 100644 index 0000000..5c4fa7b --- /dev/null +++ b/posts/site/index.html @@ -0,0 +1,346 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Making A Blog Using A Niche Markdown Language - Voidarc + + + +
+
+ + +
+ +
+ +
+

Making a Blog Using a Niche Markdown Language

+
+
+
+
+ + + + + + + +
+ + + +
+
+ + + +
+

Nonsense Preamble

Neorg is a markdown Language that is Org mode but with some different shit in it. It is supposed to be a replacement, but since I never really used Org mode in the first place, that doesn't really apply. However, after using it for a whole 10 seconds, I decided I could never go back to using Markdown ever again. Norg was just a superior language in almost every way, except widespread support. There are a plethora of plugins, but a distinct lack of real world uses, or even good utilities for using it outside of nvim, like it was intended. However, there was some random thing called Norgolith, that did apparently exactly what I needed it to, so here we are.

Norgolith

Apparently, as often happens on the internet, someone had thought of the same genius idea I had and made it already. I was fully prepared to have to spend 3 weeks making a custom solution in Javascript that would end up half baked, but fortunately someone had already done all the hard work for me!

A static site generator is exactly what it says on the tin. It takes in some manner of arbitrary markdown script, and spits out some html that can be served to the end user. Pretty simple if you ask me. Well, if you had asked me before I started that is. As things often go, I did things completely wrong the first time round. I assumed that, because I didn't know what generator meant, Norgolith would have some docker compose version that i could just shove some norg files into and it would handle the rest. That's literally what it says on the homepage, after all. Something something Sod's law. Turns out that I would have to use more than just docker in order to get something like this working.

The First Hurdle

When I first downloaded the app in question, the first problem I encountered was the blatant lack of documentation upkeep. As the docs indicated, I tried running lith serve to serve the app. Turns out, the command had been renamed to lith dev quite a while ago. The command itself hadn't changed, nor the functionality, just the name. Of course, this was as simple as I thought, because I tend not to think much when faced with simple concepts. The same thing happened when I decided on a whim to host an email server, which still to this day has not recieved a single email from anyone other than myself.

The First Attempt

Once I had realised that the docs were completely unreliable, I decided that it would be a great use of my time to try and follow them anyway. The creator (amartin) had done the usual blogger thing and hosted all the docs on Norgolith, which would be fine if Norgolith had a search function. Unfortunately, it does not, nor does it have a nice page where you can see all the pages that are outside of the post directory, which just so happened to be every page of the docs. In fact, on the doc site, there is a dead link to a theoretical post example, which was removed on github but not from the header.

Strange.

I initialised a Norg site in some random directory, still believing that I could host the whole thing self-sufficiently, and instead of reading more than the code snippets in the github readme, I set off immediately to make a docker container that would serve the app. By that, I mean I asked gemini and had to wait for the app to compile on my very old server. After a while, I gave up and went to do something else, because I'm lazy. The first site was a failiure.

The Second, More Successful, Attempt

For some reason, when I woke up the next day, something came over me. I realised that when I had run lith build, it had produced a static site , which made me realise that I might be stupid. I realised that using some complex webhooks, i.e. 1 webhook, I could have a local copy in norg form, and then have a git managed copy of the generated site. Shouldn't be too difficult using n8n, the only useful app I've ever installed. Before that, though, I could use the dev server for what it was actually intended for, and make a first post to style.

Styling, and my newfound love-hate relationship with Tailwind

Tailwind css was created in order to solve the really hard task of adding border-radius: 3; to anything on a website. Why use readable syntax when your css can be spread across 15 different files and require an interpreter, after all. Tailwind is based on immutable classes, and too many variables for my liking. Instead of using color: white; in a css file, you could apply the class text-text to every div on your page, provided that you set the --text variable to white beforehand, in a different file, and managed to compile it using the right version of tailwind. Because of the fact that I use nix, btw, the default package for tailwind provides tailwind 3, that requires npx nonsense packages in order to function, and also doesn't recognise half of the functions that are in the theme I stole borrowed and changed, as stated in the licence I definately read.

On my first try, having never used tailwind before, I decided to just edit the files and see what happened. Of course, because the tailwind.css file isn't the one that gets applied to the frontend, and nothing changed, so I gave up (I know, shocking).A On a retry, I used the tailwind_4 package, and it worked perfectly first try. Who could've guessed, I guess. Once I realised tailwind was actually pretty simple, and I was the problem, I managed to import my fonts and a Catppuccin css variable file, hence the current color scheme. Pretty nifty, huh.

In short, fuck tailwind. But also, use tailwind for everything you possibly can.

The Dreaded Backend

The concept was simple, as all concepts are, expecially when the person making said concept has no concept of how to properly make concepts. This person turned out to be me, and the concept was fairly simple. Have a primary repo, that contained 2 submodules. The primary repo would house the whole site, config, themes, etc. The first submodule would contain the raw .norg files that are in the content/ directory, and the second would have the output html files that would need to end up on the server serving the service that is currently letting you read this right now.

Said service would be a simple nginx docker container on some random port, that serves whatever it is asked. In order for such a service to be viable, I don't want to have to manage it manually. Instead, I can use a webhook to pull the html repo whenever there is a new commit. This could also be on a timer, but instant gratification is better.

Unfortunately, nothing ever goes to plan when linux is involved. The first indicator that my system wasn't going to work out was the fact that when you rebuilt the site, the repo within the public folder was erased. This is nonsense, and I have already opened an issue so that when it's fixed I have an excuse to remake the whole system.

Nginx Tangent

Nginx config is at the same time overly-complex and too basic. It's like python. It looks easy on the surface, but when you get into it, does things in the most roundabout way possible. Complaints about python aside, nginx is a nightmare to deal with on a usual basis. This is exactly why there are an infinite number of management solutions for it, one of which I am literally using to host this site (shoutout nginx proxy manager my love). Unfortunately not all of these solutions can host files at the raw level like I intend to, so here we are, once again, having to waste hours figuring out why the css is being denied. For future reference, the nginx config I'm using is as follows:

server {
+    listen 80 default_server;
+    listen [::]:80 default_server;
+
+    server_name _;
+
+    root /config/www/public;
+    index index.html index.htm index.php;
+
+    location / {
+        try_files $uri $uri/ =404;
+        autoindex on;
+        autoindex_exact_size off; # Displays file sizes in KB/MB/GB instead of bytes
+        autoindex_format html;     # The standard web view
+        autoindex_localtime on;   # Uses the server's local time for file dates
+  }
+

To any experienced web developer, such as not myself, this would look like a war crime. Because it is. This is 100% succeptible to every form of exploit one can think of. However, because I'm running this through nginx proxy manager, I don't have to worry about such trivial things as "security" and "ssl". Everything is managed in a different docker container! Thanks NPM.

Git tangent

Earlier, I said I wanted this to be automatic. And currently, it is. So, how? I host my own shit. That's everything. Including Git.

Gitea is the least complex option that everyone seems to like enough to tolerate. It also has webhooks. And I have n8n. N8n is an automation engine, that uses flows to achieve what can be done with basic intuition in a systemd service, or an assistant. Sadly, I have neither the time nor money to hire someone to update git repositories for me, so I guess we're doing it with bullshit. Gitea has the ability to trigger webhooks on a push event to a repo, and n8n can trigger commands when a webhook is triggered. This has the side effect of letting me have a repo that, if pushed to, can trigger a webhook that opens firefox on my pc. As you can tell, I shouldn't have permission to use automation tools. By hooking (no pun intended) n8n into gitea, I can run a command over ssh every time the repo is pushed to, so the changes are pulled to the server automatically. The only caveat is that you can't minify the build output, because if you do, any change will rewrite the whole file, which leads to truly insane git diffs. Such is git.

The Final Result

Everything starts on my local machine. There is a folder in my Documents that contains the repo for the site. This is also set in my nvim config as a Neorg workspace, so that I can make links between files, if I so wished. When I've written a post, I can build the site on my local machine, an endeavor that takes a tenth of a second, and commit, with such entertaining messages as "initial" and "changes". When said commit is pushed to my gitea repo, a webhook is triggered, telling n8n to ssh into server02 and pull the repo into the www folder in the nginx docker container. Because nginx isn't 50 years old, all files update on the fly, and the new article appears on the public facing instance.

See? web development is simple.

+
+ +
+ +
+
+ Copyright © 2026 + + Adumh00man. + + +
Licensed under MIT. + +
+
+ + + +
+
+ +
+
+ + diff --git a/rss.xml b/rss.xml new file mode 100644 index 0000000..8b5eac2 --- /dev/null +++ b/rss.xml @@ -0,0 +1,53 @@ + + + + voidarc + https://blog.voidarc.co.uk + Latest posts + Norgolith + en-US + Mon, 23 Mar 2026 21:55:51 +0000 + 60 + + + + https://blog.voidarc.co.uk/assets/favicon.png + voidarc + https://blog.voidarc.co.uk + 144 + 144 + + + + + Why Nixos is the Coolest Operating System + https://blog.voidarc.co.uk/posts/nix/ + https://blog.voidarc.co.uk/posts/nix/ + I really like Nix + Adumh00man + Sun, 22 Mar 2026 19:35:56 +0000 + linuxblognix + + + + Making a Blog Using a Niche Markdown Language + https://blog.voidarc.co.uk/posts/site/ + https://blog.voidarc.co.uk/posts/site/ + How to make a blog using Norg and some random project from github + Adumh00man + Sat, 21 Mar 2026 11:39:17 +0000 + blogneorgnvimvoidarcwebdev + + + + How I fell in with Linux + https://blog.voidarc.co.uk/posts/homelab/ + https://blog.voidarc.co.uk/posts/homelab/ + Haha war of the worlds reference + Adumh00man + Sat, 21 Mar 2026 19:08:28 +0000 + blogvoidarchomelablinuxwebdev + + + +