Commit 11a5ca2792

11a5ca2792cd0debb6b8f510ffd716e6f734dbd6

parent: c7314b1052

Verified · cmc

cmc <hello@cleberg.net> · 2026-03-13 20:56 UTC

fix *.org headers and revert to minimal site theme

Layout: unified · split

.github/FUNDING.yml added +1
@@ -0,0 +1 @@
1github: [ccleberg]
.github/dependabot.yml added +6
@@ -0,0 +1,6 @@
1version: 2
2updates:
3 - package-ecosystem: "uv"
4 directory: "/"
5 schedule:
6 interval: "weekly"
.github/workflows/codeql.yml added +46
@@ -0,0 +1,46 @@
1name: "CodeQL Advanced"
2
3on:
4 push:
5 branches: [ "main" ]
6 pull_request:
7 branches: [ "main" ]
8
9jobs:
10 analyze:
11 name: Analyze (${{ matrix.language }})
12 runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }}
13 permissions:
14 security-events: write
15 packages: read
16 actions: read
17 contents: read
18
19 strategy:
20 fail-fast: false
21 matrix:
22 include:
23 - language: python
24 build-mode: none
25 steps:
26 - name: Checkout repository
27 uses: actions/checkout@v4
28 - name: Initialize CodeQL
29 uses: github/codeql-action/init@v4
30 with:
31 languages: ${{ matrix.language }}
32 build-mode: ${{ matrix.build-mode }}
33 - if: matrix.build-mode == 'manual'
34 shell: bash
35 run: |
36 echo 'If you are using a "manual" build mode for one or more of the' \
37 'languages you are analyzing, replace this with the commands to build' \
38 'your code, for example:'
39 echo ' make bootstrap'
40 echo ' make release'
41 exit 1
42
43 - name: Perform CodeQL Analysis
44 uses: github/codeql-action/analyze@v4
45 with:
46 category: "/language:${{matrix.language}}"
.github/workflows/deploy.yml added +68
@@ -0,0 +1,68 @@
1name: Build and Deploy
2
3on:
4 push:
5 branches:
6 - main
7 paths-ignore:
8 - '.github/**'
9 - 'screenshots/**'
10 - 'utils/**'
11 - 'LICENSE'
12 - 'README.org'
13
14jobs:
15 build-job:
16 runs-on: ubuntu-latest
17 container:
18 image: ghcr.io/ccleberg/cleberg.net:main
19
20 steps:
21 - name: Checkout code
22 uses: actions/checkout@v4
23
24 - name: Run Build
25 env:
26 ENV: "prod"
27 BUILD: "true"
28 DEPLOY: "false"
29 run: |
30 echo "Environment is ready. Running build..."
31 uv run build.py
32
33 - name: Upload Build Artifacts
34 uses: actions/upload-artifact@v4
35 with:
36 name: build-output
37 path: ${{ github.workspace }}/.build/
38 include-hidden-files: true
39
40 deploy-job:
41 runs-on: ubuntu-latest
42 needs: build-job
43 environment: production
44 container:
45 image: ghcr.io/ccleberg/cleberg.net:main
46
47 steps:
48 - name: Checkout code
49 uses: actions/checkout@v4
50
51 - name: Download Build Artifacts
52 uses: actions/download-artifact@v4
53 with:
54 name: build-output
55 path: ${{ github.workspace }}/.build/
56
57 - name: Setup SSH and Deploy
58 env:
59 SERVER_IP: ${{ secrets.SERVER_IP }}
60 SERVER_USER: ${{ secrets.SERVER_USER }}
61 SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
62 run: |
63 eval $(ssh-agent -s)
64 echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add -
65 rsync -avz --delete \
66 -e "ssh -p ${{ secrets.SSH_PORT }} -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" \
67 .build/ \
68 $SERVER_USER@$SERVER_IP:/var/www/cleberg.net/
.github/workflows/docker-build.yml added +41
@@ -0,0 +1,41 @@
1name: Build and Push Docker Image
2
3on:
4 push:
5 branches: [ "main" ]
6 paths:
7 - 'Dockerfile'
8 - 'requirements.txt'
9 - '.github/workflows/docker-build.yml'
10
11jobs:
12 build:
13 runs-on: ubuntu-latest
14 permissions:
15 contents: read
16 packages: write
17
18 steps:
19 - name: Checkout repository
20 uses: actions/checkout@v4
21
22 - name: Log in to GHCR
23 uses: docker/login-action@v3
24 with:
25 registry: ghcr.io
26 username: ${{ github.actor }}
27 password: ${{ secrets.GITHUB_TOKEN }}
28
29 - name: Extract metadata
30 id: meta
31 uses: docker/metadata-action@v5
32 with:
33 images: ghcr.io/${{ github.repository }}
34
35 - name: Build and push
36 uses: docker/build-push-action@v5
37 with:
38 context: .
39 push: true
40 tags: ${{ steps.meta.outputs.tags }}
41 labels: ${{ steps.meta.outputs.labels }}
.github/workflows/ruff.yml added +42
@@ -0,0 +1,42 @@
1name: Ruff
2
3on:
4 push:
5 branches: [ "main" ]
6 paths:
7 - '**.py'
8 pull_request:
9 branches: [ "main" ]
10 paths:
11 - '**.py'
12
13jobs:
14 build:
15 runs-on: ubuntu-latest
16 strategy:
17 matrix:
18 python-version: ["3.x"]
19 steps:
20 - uses: actions/checkout@v4
21 - name: Set up Python ${{ matrix.python-version }}
22 uses: actions/setup-python@v5
23 with:
24 python-version: ${{ matrix.python-version }}
25 ref: ${{ github.event.pull_request.head.ref }}
26 - name: Install dependencies
27 run: |
28 python -m pip install --upgrade pip
29 pip install pandas dash plotly.express
30 - name: Install Ruff
31 uses: astral-sh/ruff-action@v3.2.2
32 - name: Ruff Actions
33 run: |
34 ruff check --fix
35 ruff format
36 - name: Add and Commit
37 uses: EndBug/add-and-commit@v9
38 env:
39 GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
40 with:
41 default_author: github_actions
42 pathspec_error_handling: ignore
BRAND.md deleted −98
@@ -1,98 +0,0 @@
1# Brand Reference — cleberg.net
2
3Design decisions, usage rules, and porting checklist for this site and any
4future sites.
5
6---
7
8## Color
9
10All tokens live in `theme/static/tokens.css`. Import it before any other
11stylesheet.
12
13### Palette
14
15| Token | Light | Dark | Role |
16|----------------|-------------|-------------|-------------------------------------------|
17| `--bg` | `#F6F4F0` | `#161412` | Page background |
18| `--bg-soft` | `#EDEAE4` | `#1F1C1A` | Subtle surfaces (code blocks, inputs) |
19| `--fg` | `#111111` | `#F0EDE8` | Primary text, hard borders, table headers |
20| `--fg-soft` | `#555550` | `#888580` | Secondary text, metadata |
21| `--accent` | `#c0392b` | `#ee6f5c` | Interactive elements only (see below) |
22| `--salmon` | `#ee6f5c` | `#ee6f5c` | Decorative only (see below) |
23| `--border` | `#111111` | `#2C2825` | Hard borders (nav, tables) |
24| `--border-soft`| `#DDDAD4` | `#2C2825` | Dashed or subtle dividers |
25| `--code-bg` | `#E8E4DE` | `#0F0D0C` | Code blocks, blockquotes |
26| `--meta` | `#555550` | `#888580` | Timestamps, labels, footnote numbers |
27
28### Usage Rules
29
30**`--accent` is for interactive elements only:** links, `h2` left border,
31footnote numbers, focus indicators. It is text-safe (WCAG AA: 4.6:1 on `--bg` in
32light mode; ~4.5:1 on `--bg` in dark mode).
33
34**`--salmon` is decorative only.** Never use it for body text on a light
35background — it fails WCAG AA there. In dark mode, `--accent` and `--salmon`
36resolve to the same value (`#ee6f5c`), which is intentional.
37
38---
39
40## Typography
41
42- **Font stack:** `--font-mono` (ui-monospace, Cascadia Code, Source Code Pro,
43 Menlo, Consolas, monospace)
44- **Headings:** weight 900, uppercase, `line-height: 1.1`
45- **`h2` accent bar:** 10px left border in `--accent`
46- **Body:** `1rem`, `line-height: 1.6`
47- **Meta/labels:** `0.8–0.85rem`, uppercase, `--meta` color
48- **Date format:** `YYYY-MM-DD` everywhere, no exceptions
49
50---
51
52## Logo
53
54Files live in `~/Documents/brand/logo/`.
55
56| Variant | Use case |
57|-------------------------|--------------------------------------------------|
58| `koi_light.svg/png` | Full logo on light backgrounds |
59| `koi_dark.svg/png` | Full logo on dark backgrounds |
60| `koi_light_minimal.svg` | Favicon, nav, small UI contexts on light |
61| `koi_dark_minimal.svg` | Favicon, nav, small UI contexts on dark |
62
63**Rule:** Use the minimal variant for anything under ~64px or in navigation
64contexts. Use the full variant for headers, OG images, or anywhere it has room
65to breathe.
66
67---
68
69## Signature Patterns
70
71These are the things that make the site look like itself. Port all of them to
72any new site.
73
741. **Grayscale images with color on hover** — `img { filter: grayscale(1) }
75 img:hover { filter: grayscale(0) }`. Apply to all content images by default.
762. **Blockquote as raw org-mode markup** — `#+begin_quote` / `#+end_quote`
77 pseudo-elements. Extend the "visible markup" aesthetic to other block
78 elements where appropriate.
793. **Nav: uppercase, weight 900, invert on hover** — `background: var(--fg);
80 color: var(--bg)` on hover. No underlines in nav.
814. **Links: underline offset** — `text-underline-offset: 3px`, invert on hover
82 (same as nav pattern).
835. **Hard borders on tables** — `3px solid var(--fg)` outer border, `1px solid var(--fg)` internal. Table headers use `background: var(--fg); color: var(--bg)`.
84
85---
86
87## Porting Checklist (New Site)
88
89- [ ] Import `tokens.css` (or copy variables and update `tokens.css` as the
90 source)
91- [ ] Apply monospace font stack
92- [ ] Apply grayscale image treatment
93- [ ] Use minimal koi as favicon
94- [ ] Use `YYYY-MM-DD` date format
95- [ ] Confirm `--accent` WCAG contrast on new background colors if palette is
96 adjusted
97- [ ] Build or adapt OG/social card template using koi + palette + monospace
98 type
README.org −6
@@ -27,12 +27,6 @@ The publishing system depends on:
2727- The weblorg package, available at [[https://github.com/emacs-love/weblorg][emacs-love/weblorg]], which provides advanced
2828 Org publishing functionality and theming support.
2929
30** Screenshots
31
32| Light Mode | Dark Mode |
33|-------------------------+------------------------|
34| [[./screenshots/light.png]] | [[./screenshots/dark.png]] |
35
3630** Configuration
3731
3832You can customize site settings can within the ~publish.el~ file. This file
build.py +23 −38
@@ -185,13 +185,9 @@ def get_recent_posts_html(content_dir="./content/blog", num_posts=3):
185185 lines = []
186186 current_year = None
187187 for post in recent:
188 year = post["date_obj"].year
189 if year != current_year:
190 current_year = year
191 lines.append(f'\t<li class="post-list-year">{year}</li>')
192188 lines.append('\t<li class="post-list-item">')
193 lines.append(f'\t\t<a href="/blog/{post["slug"]}.html">{post["title"]}</a>')
194189 lines.append(f'\t\t<time datetime="{post["date_str"]}">{post["date_full"]}</time>')
190 lines.append(f'\t\t<a href="/blog/{post["slug"]}.html">{post["title"]}</a>')
195191 lines.append("\t</li>")
196192
197193 return "\n".join(lines)
@@ -454,58 +450,47 @@ def generate_tags_page(content_dir="./content/blog", build_dir="./.build"):
454450 posts = tag_map[tag]
455451 items = "\n".join(
456452 f'<li class="post-list-item">'
457 f'<a href="/blog/{p["slug"]}.html">{p["title"]}</a>'
458453 f'<time datetime="{p["date_str"]}">{p["date_str"]}</time>'
454 f'<a href="/blog/{p["slug"]}.html">{p["title"]}</a>'
459455 f'</li>'
460456 for p in posts
461457 )
462458 sections.append(f'<h2 id="{tag}">{tag}</h2>\n<ul class="post-list">\n{items}\n</ul>')
463459
464460 html = f"""<!doctype html>
465<html lang="en-us">
461<html lang=en-us>
466462<head>
467<meta charset="utf-8">
468<title>tags - seijaku</title>
469<meta name="viewport" content="width=device-width, initial-scale=1">
470<link rel="stylesheet" href="/styles.min.css" type="text/css">
471<link rel="icon" href="/favicon.svg" type="image/svg+xml">
463<meta charset=utf-8>
464<title>cleberg.net</title>
465<meta name=viewport content="width=device-width,initial-scale=1">
466<meta name=author content="Christian Cleberg <hello@cleberg.net>">
467<meta name=description content="Stillness amidst the chaos.">
468<link rel=stylesheet href=http://localhost:8000/styles.min.css>
469<link rel=icon href=data:,>
472470</head>
473471<body>
474<a href="#main-content" class="skip-link">Skip to content</a>
475<header class="masthead">
476<a href="/" class="masthead-title">seijaku</a>
477<p class="masthead-subtitle"><i>stillness amidst the chaos</i></p>
472<a href=#main-content class=skip-link>Skip to content</a>
478473<nav aria-label="Site Navigation">
479474<ul>
480<li><a href="/blog/">Blog</a></li>
481<li><a href="/tags/">Tags</a></li>
482<li><a href="/guides/index.html">Guides</a></li>
483<li><a href="/apps/">Apps</a></li>
484<li><a href="/garden/">Garden</a></li>
485<li><a href="/salary/">Salary</a></li>
475<li><a href=/>Home</a>
476<li><a href=/apps/>Apps</a>
477<li><a href=/blog/>Blog</a>
478<li><a href=/garden/>Garden</a>
479<li><a href=/guides/>Guides</a>
480<li><a href=/salary/>Salary</a>
481<li><a href=/tags/>Tags</a>
486482</ul>
487483</nav>
488</header>
489<main id="main-content">
484<main id=main-content>
490485<h1>Tags</h1>
491486<ul class="tag-toc">{toc_items}</ul>
492487{"".join(f"<section>{s}</section>" for s in sections)}
493488</main>
494<hr>
495489<footer>
496<div>
497<a href="https://github.com/ccleberg/cleberg.net">Source</a> &middot;
498<a href="/feed.xml">RSS</a> &middot;
499<a href="http://paske4urhs6nttrtlkuwa5cowum3fjkc6yv6kl4ncx3mjxcd77764nqd.onion/">Onion</a> &middot;
500<a href="/now/">Now</a> &middot;
501<a href="/uses/">Uses</a> &middot;
502<a href="/tips/">Tips</a> &middot;
503<a href="https://cv.cleberg.net">CV</a>
504</div>
505<div>
506<a href="mailto:hello@cleberg.net">hello@cleberg.net</a> [<a href="/gpg.txt">PGP</a>] &middot;
507Signal: @cmc.01
508</div>
490<a href=https://github.com/ccleberg/cleberg.net>Source</a>&#183;
491<a href=/feed.xml>RSS</a>&#183;
492<a href=http://paske4urhs6nttrtlkuwa5cowum3fjkc6yv6kl4ncx3mjxcd77764nqd.onion/>Onion</a>&#183;
493<a href=/tips/>Tips</a>
509494</footer>
510495</body>
511496</html>"""
content/apps/index.org +10 −37
@@ -1,4 +1,4 @@
1#+title: apps
1#+title: Apps
22#+slug: index
33#+options: toc:nil
44
@@ -7,43 +7,16 @@
77Small apps I've built for iOS. Fully offline. No ads, no accounts, no data
88collection.
99
10#+begin_export html
11<div class="app-card">
12 <a href="https://apps.apple.com/app/daybyday"><img class="app-icon" src="https://img.cleberg.net/apps/daybyday.png" alt="DayByDay icon"></a>
13 <div class="app-info">
14 <span class="app-title">Day By Day</span>
15 <span class="app-subtitle">Learn days, months & seasons!</span>
16 <div class="app-links">
17 <a href="https://apps.apple.com/app/daybyday">App Store</a> &middot;
18 <a href="https://github.com/ccleberg/DayByDay">GitHub</a>
19 </div>
20 </div>
21</div>
10#+begin_quote
11All 3 apps are currently in Apple's review queue and are not available on the
12App Store yet. I will update the links here as soon as Apple publishes them.
13#+end_quote
2214
23<div class="app-card">
24 <a href="https://apps.apple.com/app/space-explorers"><img class="app-icon" src="https://img.cleberg.net/apps/spaceexplorers.png" alt="Space Explorers icon"></a>
25 <div class="app-info">
26 <span class="app-title">Space Explorers</span>
27 <span class="app-subtitle">Explore the galaxy and learn!</span>
28 <div class="app-links">
29 <a href="https://apps.apple.com/app/space-explorers">App Store</a> &middot;
30 <a href="https://github.com/ccleberg/SpaceExplorers">GitHub</a>
31 </div>
32 </div>
33</div>
34
35<div class="app-card">
36 <a href="https://apps.apple.com/app/domaindig"><img class="app-icon" src="https://img.cleberg.net/apps/domaindig.png" alt="DomainDig icon"></a>
37 <div class="app-info">
38 <span class="app-title">Domain Dig</span>
39 <span class="app-subtitle">DNS lookup & SSL certificate checker</span>
40 <div class="app-links">
41 <a href="https://apps.apple.com/app/domaindig">App Store</a> &middot;
42 <a href="https://github.com/ccleberg/DomainDig">GitHub</a>
43 </div>
44 </div>
45</div>
46#+end_export
15| App | Description | GitHub |
16|-----------------+--------------------------------------+--------|
17| Day By Day | Learn days, months & seasons! | [[https://github.com/ccleberg/DayByDay][GitHub]] |
18| Domain Dig | DNS lookup & SSL certificate checker | [[https://github.com/ccleberg/DomainDig][GitHub]] |
19| Space Explorers | Explore the galaxy and learn! | [[https://github.com/ccleberg/SpaceExplorers][GitHub]] |
4720
4821* Web Projects
4922
content/blog/2018-11-28-aes-encryption.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2018-11-28 Wed 00:00:00]
2#+title: aes encryption: what the math actually does
3#+description: Detailed explanation of AES encryption, including key handling, encryption modes, algorithm structure, and implementation considerations for secure data protection.
1#+date: [2018-11-28 Wed 00:00:00]
2#+title: AES Encryption
3#+description: Let's learn about AES encryption, its method, and how it can be used.
44#+slug: aes-encryption
5#+filetags: :security:
5#+filetags: :security:
66
77* Basic AES
88
content/blog/2018-11-28-cpp-compiler.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2018-11-28 Wed 00:00:00]
2#+title: inside the c++ compiler
3#+description: Systematic presentation of the C++ compilation phases including preprocessing, compilation, assembly, and linking, with technical insights into each stage's function.
1#+date: [2018-11-28 Wed 00:00:00]
2#+title: The C++ Compiler
3#+description: A brief trip into the C++ compilation process.
44#+slug: cpp-compiler
5#+filetags: :linux:
5#+filetags: :linux:
66
77* A Brief Introduction
88
content/blog/2019-01-07-useful-css.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2019-01-07 Mon 00:00:00]
2#+title: css notes: flexbox, shadows, variables
3#+description: Practical guide on applying CSS rules and constructs such as flexbox, box shadows, and variable usage to achieve standard web styling and layout objectives.
1#+date: [2019-01-07 Mon 00:00:00]
2#+title: CSS Tips: Flexbox, Shadows, Variables
3#+description: A few quick tips on modern CSS features.
44#+slug: useful-css
5#+filetags: :web:
5#+filetags: :web:
66
77* Introduction to CSS
88
content/blog/2019-09-09-audit-analytics.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2019-09-09 Mon 00:00:00]
2#+title: audit analytics: pandas instead of pivot tables
3#+description: Examination of data analytical approaches applied within internal audit functions to improve risk evaluation, process efficiency, and decision support.
1#+date: [2019-09-09 Mon 00:00:00]
2#+title: Internal Audit Analytics
3#+description: Let's talk about data analytics and its use cases within the Internal Audit function.
44#+slug: audit-analytics
5#+filetags: :audit:
5#+filetags: :audit:
66
77* What Are Data Analytics?
88
content/blog/2019-12-03-the-ansoff-matrix.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2019-12-03 Tue 00:00:00]
2#+title: ansoff matrix: business school diagram, limited shelf life
3#+description: Analytical description of the Ansoff Matrix, detailing market and product development strategies for measured business expansion and competitive positioning.
1#+date: [2019-12-03 Tue 00:00:00]
2#+title: The Ansoff Matrix
3#+description: A detailed description of the Ansoff Matrix business model.
44#+slug: the-ansoff-matrix
5#+filetags: :audit:
5#+filetags: :audit:
66
77* Overview
88
content/blog/2019-12-16-password-security.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2019-12-16 Mon 00:00:00]
2#+title: nist passwords: the guidelines nobody implements
3#+description: Compilation of guidelines for password generation, storage, protection, and compliance with established standards such as NIST for maintaining digital security.
1#+date: [2019-12-16 Mon 00:00:00]
2#+title: NIST Password Security
3#+description: Let's look at what NIST currently recommends for passwords and secrets.
44#+slug: password-security
5#+filetags: :security:
5#+filetags: :security:
66
77* Users
88
content/blog/2020-01-25-linux-software.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2020-01-25 Sat 00:00:00]
2#+title: linux software: what i actually install first
3#+description: Inventory and description of key Linux applications including graphical and command-line tools, with installation instructions for various distributions.
1#+date: [2020-01-25 Sat 00:00:00]
2#+title: My Favorite Linux Software
3#+description: A quick list of my favorite apps on Linux.
44#+slug: linux-software
5#+filetags: :linux:
5#+filetags: :linux:
66
77* Graphical Applications
88
content/blog/2020-01-26-steam-on-ntfs.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2020-01-26 Sun 00:00:00]
2#+title: steam ntfs linux: it works, mostly
3#+description: Procedures for mounting NTFS drives using ntfs-3g to enable reliable execution of Steam gaming software on Linux environments.
1#+date: [2020-01-26 Sun 00:00:00]
2#+title: Steam NTFS Fix on Linux
3#+description: Procedures for mounting NTFS drives using ntfs-3g for Steam on Linux.
44#+slug: steam-on-ntfs
5#+filetags: :linux:
5#+filetags: :linux:
66
77* Auto-Mount Steam Drives
88
content/blog/2020-02-09-cryptography-basics.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2020-02-09 Sunday 00:00:00]
2#+title: cryptography basics: keys, certs, and why it matters
3#+description: Systematic overview of encryption methodologies, key categories, algorithmic frameworks, and their applications in data confidentiality and integrity.
1#+date: [2020-02-09 Sunday 00:00:00]
2#+title: Cryptography Basics
3#+description: An introduction to cryptographic methods for encryption.
44#+slug: cryptography
5#+filetags: :security:
5#+filetags: :security:
66
77* Similar Article Available
88
content/blog/2020-03-25-session-messenger.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2020-03-25 Wed 00:00:00]
2#+title: session messenger: is it secure?
3#+description: Technical description of the Session messaging protocol, including end-to-end encryption, metadata minimization, multi-device synchronization, and privacy-centric design.
1#+date: [2020-03-25 Wed 00:00:00]
2#+title: Review: Session Messenger
3#+description: A user review of the Session Messenger app on Linux, macOS, and iOS.
44#+slug: session-messenger
5#+filetags: :privacy:
5#+filetags: :privacy:
66
77* Privacy Warning
88
content/blog/2020-05-03-homelab.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2020-05-03 Sun 00:00:00]
2#+title: homelab: rack, network, what broke
3#+description: Comprehensive instructions on assembling and configuring a homelab environment, emphasizing hardware selection, software deployment, and network setup for operational efficiency.
1#+date: [2020-05-03 Sun 00:00:00]
2#+title: A Look Inside My Homelab
3#+description: A retrospective guide after throwing together the first iteration of my home lab.
44#+slug: homelab
5#+filetags: :self-hosting:
5#+filetags: :self-hosting:
66
77* What is a Homelab?
88
content/blog/2020-05-19-customizing-ubuntu.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2020-05-19 Tue 00:00:00]
2#+title: ubuntu gnome customization: making it not look terrible
3#+description: Detailed instructions for modifying system appearance and interface elements in Ubuntu 20.04, including setting themes, icon packs, font adjustments, terminal configurations, and related customization parameters.
1#+date: [2020-05-19 Tue 00:00:00]
2#+title: Ubuntu GNOME Customization
3#+description: Some tips and tricks to customize GNOME on Ubuntu 20.04.
44#+slug: customizing-ubuntu
5#+filetags: :linux:
5#+filetags: :linux:
66
77* More Information
88
content/blog/2020-07-20-video-game-sales.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2020-07-20 Mon 00:00:00]
2#+title: video game sales data: 40 years of numbers
3#+description: Presentation of analyzed data regarding global video game sales, covering platform distributions, genre classifications, and geographic market performance metrics.
1#+date: [2020-07-20 Mon 00:00:00]
2#+title: Data Analysis: Video Games Sales Data
3#+description: A simple data analysis of the video games sales dataset.
44#+slug: video-game-sales
5#+filetags: :personal:
5#+filetags: :personal:
66
77* Background Information
88
content/blog/2020-07-26-business-analysis.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2020-07-26 Sun 00:00:00]
2#+title: business location analysis: python maps, urban data
3#+description: Methodology for utilizing data science techniques and Foursquare API data to analyze and select promising business sites within urban environments.
1#+date: [2020-07-26 Sun 00:00:00]
2#+title: Data Analysis: Finding the Best Location for a Business
3#+description: Part of my data analysis course, I built an algorithm to find the best location for a new business in Lincoln.
44#+slug: business-analysis
5#+filetags: :audit:
5#+filetags: :audit:
66
77* Background Information
88
content/blog/2020-08-22-redirect-github-pages.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2020-08-22 Sat 00:00:00]
2#+title: github pages root domain: drop the www
3#+description: Stepwise instructions for configuring redirection of GitHub Pages sites from the www subdomain to the apex domain to improve domain resolution and access consistency.
1#+date: [2020-08-22 Sat 00:00:00]
2#+title: GitHub Pages Redirect Subdomain to TLD
3#+description: A quick recap of a Stack Overflow answer that I want to exist in perpetuity.
44#+slug: redirect-github-pages
5#+filetags: :web:
5#+filetags: :web:
66
77* Short answer
88
content/blog/2020-08-29-php-auth-flow.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2020-08-29 Sat 00:00:00]
2#+title: php auth: sessions from scratch
3#+description: Comprehensive guide to developing a secure user login system in PHP, including account creation, session management, and logout procedures.
1#+date: [2020-08-29 Sat 00:00:00]
2#+title: Learning PHP Auth
3#+description: A quick recap of my recent learning experience with PHP Auth.
44#+slug: php-auth-flow
5#+filetags: :web:
5#+filetags: :web:
66
77* Introduction
88
content/blog/2020-09-01-visual-recognition.org +3 −3
@@ -1,8 +1,8 @@
1#+date: [2020-09-01 Tue 00:00:00]
2#+title: ibm watson vision api: before they killed it
1#+date: [2020-09-01 Tue 00:00:00]
2#+title: IBM Watson Vision API
33#+description: Technical overview and application instructions for using IBM Watson Visual Recognition service, with focus on API configuration, image input processing, and classification output handling.
44#+slug: visual-recognition
5#+filetags: :linux:
5#+filetags: :linux:
66
77* What is IBM Watson?
88
content/blog/2020-09-22-internal-audit.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2020-09-22 Tue 00:00:00]
2#+title: internal audit: what it does vs. what management thinks it does
3#+description: Analysis of internal audit processes, their contribution to risk management, governance frameworks, and compliance monitoring within corporate structures.
1#+date: [2020-09-22 Tue 00:00:00]
2#+title: Internal Audit: Who Are They?
3#+description: Learn who your Internal Audit partners actually are.
44#+slug: internal-audit
5#+filetags: :audit:
5#+filetags: :audit:
66
77* Definitions
88
content/blog/2020-09-25-happiness-map.org +3 −3
@@ -1,8 +1,8 @@
11#+date: [2020-09-25 Fri 00:00:00]
2#+title: happiness choropleth: folium map, world data
3#+description: Instructions for creating an interactive choropleth map visualizing international happiness data based on metrics such as GDP, social support, health indicators, freedom indices, generosity, and corruption levels.
2#+title: Data Analysis: World Happiness Choropleth Map
3#+description: A quick dive into choropleth maps.
44#+slug: happiness-map
5#+filetags: :personal:
5#+filetags: :personal:
66
77* Background Information
88
content/blog/2020-10-12-mediocrity.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2020-10-12 Mon 00:00:00]
2#+title: when good is good enough—and when it isn't
3#+description: Examination of decision-making principles relating to achieving sufficient quality levels, including trade-offs between perfection and adequacy in professional and operational contexts.
1#+date: [2020-10-12 Mon 00:00:00]
2#+title: On Mediocrity
3#+description: Thoughts on mediocrity and when perfect is the enemy of good.
44#+slug: mediocrity
5#+filetags: :personal:
5#+filetags: :personal:
66
77* Perfect is the Enemy of Good
88
content/blog/2020-12-27-website-redesign.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2020-12-27 Sun 00:00:00]
2#+title: website redesign: 5kb, 100s on lighthouse, no framework
3#+description: Detailed process outlining methods for reducing website page size to approximately 5 kilobytes, enhancing loading speed, search engine indexing efficiency, and user interface responsiveness.
1#+date: [2020-12-27 Sun 00:00:00]
2#+title: Minimalist Website Redesign (5kb)
3#+description: A retrospective summary of recent changes to minimize my site.
44#+slug: website-redesign
5#+filetags: :web:
5#+filetags: :web:
66
77* A Brief History
88
content/blog/2020-12-28-neon-drive.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2020-12-28 Mon 00:00:00]
2#+title: neon drive: review
3#+description: Description of game mechanics, graphical style, and level design in Neon Drive, an arcade racing game inspired by 1980s synthwave aesthetics.
1#+date: [2020-12-28 Mon 00:00:00]
2#+title: Neon Drive
3#+description: My thoughts on Neon Drive, a synthwave-inspired arcade racer.
44#+slug: neon-drive
5#+filetags: :personal:
5#+filetags: :personal:
66
77* Game Description
88
content/blog/2020-12-29-zork.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2020-12-29 Tue 00:00:00]
2#+title: zork: the text adventure that started it all
3#+description: Detailed operational guide for navigating Zork, a text-based interactive fiction game from the 1980s. Includes instructions for exploration, puzzle resolution, and item collection.
1#+date: [2020-12-29 Tue 00:00:00]
2#+title: The Zork Anthology
3#+description: My thoughts on Zork (plus, some tips and a map).
44#+slug: zork
5#+filetags: :personal:
5#+filetags: :personal:
66
77* Download (Free)
88
content/blog/2021-01-01-seum.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2021-01-01 Fri 00:00:00]
2#+title: seum: speedrunners from hell
3#+description: Technical overview for utilizing the game SEUM, focusing on speedrunning techniques, gravity manipulation, teleportation functions, and level completion criteria.
1#+date: [2021-01-01 Fri 00:00:00]
2#+title: SEUM: Speedrunners from Hell
3#+description: A quick look at one of my favorite speedrunning games.
44#+slug: seum
5#+filetags: :personal:
5#+filetags: :personal:
66
77* Game Description
88
content/blog/2021-01-04-fediverse.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2021-01-04 Mon 00:00:00]
2#+title: fediverse: decentralized social, minus the algorithm
3#+description: Detailed introduction to the Fediverse network architecture, user registration procedures, platform navigation, and protocols ensuring content decentralization and censorship resistance.
1#+date: [2021-01-04 Mon 00:00:00]
2#+title: Fediverse: Decentralized Social
3#+description: A primer on the fediverse, how it works, and why I use it.
44#+slug: fediverse
5#+filetags: :privacy:
5#+filetags: :privacy:
66
77* What is the Fediverse?
88
content/blog/2021-01-07-ufw.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2021-01-07 Thu 00:00:00]
2#+title: ufw hardening: firewall config you should have set up already
3#+description: Stepwise instructions for installation, configuration, enabling, and management of the Uncomplicated Firewall utility to secure network interfaces on Ubuntu server environments.
1#+date: [2021-01-07 Thu 00:00:00]
2#+title: UFW: Firewall Setup on Ubuntu
3#+description: How to install and configure UFW on Ubuntu.
44#+slug: ufw
5#+filetags: :linux:security:
5#+filetags: :linux:security:
66
77* Uncomplicated Firewall
88
content/blog/2021-02-19-macos.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2021-02-19 Fri 00:00:00]
2#+title: macos for linux users: what to fix first
3#+description: Comprehensive overview for first-time macOS users transitioning from other OS platforms, including system setup, terminal usage, and user interface customization.
1#+date: [2021-02-19 Fri 00:00:00]
2#+title: macOS for Linux Users
3#+description: First steps for Linux users switching to macOS.
44#+slug: macos
5#+filetags: :linux:
5#+filetags: :linux:
66
77* Diving into macOS
88
content/blog/2021-03-19-clone-github-repos.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2021-03-19 Fri 00:00:00]
2#+title: github and sourcehut: scripting mass clones and remote updates
3#+description: Script-based methodology for cloning multiple repositories from GitHub and Sourcehut accounts. Includes automation techniques to streamline repository management and backups.
1#+date: [2021-03-19 Fri 00:00:00]
2#+title: Scripting Mass Clones from GitHub and Sourcehut
3#+description: Scripts to clone all your repos from GitHub or Sourcehut at once.
44#+slug: clone-github-repos
5#+filetags: :personal:
5#+filetags: :personal:
66
77* Cloning from GitHub
88
content/blog/2021-03-28-gemini-capsule.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2021-03-28 Sun 00:00:00]
2#+title: gemini capsule: deploy it, own your content
3#+description: Incremental procedural guide to initiate and maintain a Gemini capsule server. Covers installation, deployment, and operational best practices for beginners.
1#+date: [2021-03-28 Sun 00:00:00]
2#+title: Gemini Capsule: Deploy and Own Your Content
3#+description: How to set up and run your own Gemini capsule.
44#+slug: gemini-capsule
5#+filetags: :linux:web:
5#+filetags: :linux:web:
66
77* What is Gemini?
88
content/blog/2021-03-28-vaporwave-vs-outrun.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2021-03-28 Sun 00:00:00]
2#+title: vaporwave vs outrun: the aesthetic breakdown
3#+description: Systematic examination of Vaporwave and Outrun aesthetic frameworks, focusing on graphical elements, chromatic schemes, musical associations, and period-specific cultural influences.
1#+date: [2021-03-28 Sun 00:00:00]
2#+title: Vaporwave vs. Outrun
3#+description: Breaking down the differences between vaporwave and outrun aesthetics.
44#+slug: vaporwave-vs-outrun
5#+filetags: :personal:
5#+filetags: :personal:
66
77* Overview
88
content/blog/2021-03-30-vps-web-server.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2021-03-30 Tue 00:00:00]
2#+title: vps web server: get off shared hosting
3#+description: Instructional outline for setting up and maintaining a VPS environment configured for secure and scalable web hosting applications.
1#+date: [2021-03-30 Tue 00:00:00]
2#+title: VPS Web Server: Get Off Shared Hosting
3#+description: How to set up a VPS and host your own website.
44#+slug: vps-web-server
5#+filetags: :linux:self-hosting:
5#+filetags: :linux:self-hosting:
66
77* Shared Hosting vs. VPS (Virtual Private Server)
88
content/blog/2021-04-17-gemini-server.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2021-04-17 Sat 00:00:00]
2#+title: agate gemini server installation and firewall configuration
3#+description: Detailed directives for installation and configuration of a Gemini protocol server on Ubuntu, including network security and firewall setup.
1#+date: [2021-04-17 Sat 00:00:00]
2#+title: Agate Gemini Server Setup
3#+description: Installing Agate and configuring a firewall for a Gemini server on Ubuntu.
44#+slug: gemini-server
5#+filetags: :linux:web:
5#+filetags: :linux:web:
66
77* Similar Article Available
88
content/blog/2021-04-23-php-comment-system.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2021-04-23 Fri 00:00:00]
2#+title: building a lightweight php static commenting system without javascript
3#+description: Technical walkthrough for constructing a lightweight, privacy-oriented static comment system using PHP, with no client-side scripting or external dependencies.
1#+date: [2021-04-23 Fri 00:00:00]
2#+title: A Lightweight, Static PHP Comment System
3#+description: Building a simple PHP comment system with no JavaScript and no external dependencies.
44#+slug: php-comment-system
5#+filetags: :linux:web:
5#+filetags: :linux:web:
66
77* The Terrible-ness of Commenting Systems
88
content/blog/2021-04-28-photography.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2021-04-28 Wed 00:00:00]
2#+title: photography: gear and what actually matters
3#+description: Instructional document covering basic techniques in photography, including equipment selection, operational best practices, and methods for capturing high-quality images.
1#+date: [2021-04-28 Wed 00:00:00]
2#+title: My Photography Gear
3#+description: My approach to photography and the gear I use.
44#+slug: photography
5#+filetags: :personal:
5#+filetags: :personal:
66
77* Why Photography?
88
content/blog/2021-05-30-changing-git-authors.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2021-05-30 Sun 00:00:00]
2#+title: automated script for correcting git author details in multiple projects
3#+description: Detailed instructions for systematically updating the Git author name and email information in multiple repositories using command-line tools and scripts.
1#+date: [2021-05-30 Sun 00:00:00]
2#+title: Correcting Git Author Details Across Multiple Repos
3#+description: A script to update the git author name and email across multiple repos.
44#+slug: changing-git-authors
5#+filetags: :personal:
5#+filetags: :personal:
66
77* Changing Git Author/Email Based on Previously Committed Email
88
content/blog/2021-07-15-delete-gitlab-repos.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2021-07-15 Thu 00:00:00]
2#+title: automated deletion of all gitlab repositories using python
3#+description: Stepwise instructions for executing a Python script to delete all repositories associated with a GitLab account. Includes authentication and error handling procedures.
1#+date: [2021-07-15 Thu 00:00:00]
2#+title: Deleting All GitLab Repositories with Python
3#+description: A Python script to delete all your GitLab repositories at once.
44#+slug: delete-gitlab-repos
5#+filetags: :personal:
5#+filetags: :personal:
66
77* Background
88
content/blog/2021-08-25-audit-sampling.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2021-08-25 Wed 00:00:00]
2#+title: audit sampling: pandas for random and stratified samples
3#+description: Presentation of methods for implementing audit sampling techniques including simple random, stratified, and systematic sampling using Python's Pandas library for precise audit outcomes.
1#+date: [2021-08-25 Wed 00:00:00]
2#+title: Audit Sampling with Pandas
3#+description: Using Python and Pandas to run random and stratified audit samples.
44#+slug: audit-sampling
5#+filetags: :audit:
5#+filetags: :audit:
66
77* Introduction
88
content/blog/2021-10-09-apache-redirect.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2021-10-09 Sat 00:00:00]
2#+title: setting up apache rewrite rules for extensionless urls
3#+description: Technical guide to applying Apache mod_rewrite directives for transforming .html file requests into clean directory-style URL structures to enhance website navigation and indexing.
1#+date: [2021-10-09 Sat 00:00:00]
2#+title: Apache Rewrite Rules for Extensionless URLs
3#+description: Using mod_rewrite to serve clean, extensionless URLs in Apache.
44#+slug: apache-redirect
5#+filetags: :web:
5#+filetags: :web:
66
77* The Problem
88
content/blog/2021-12-04-cisa.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2021-12-04 Sat 00:00:00]
2#+title: cisa exam: what the test measures vs. what the job requires
3#+description: Comprehensive outline of study materials, preparation strategies, and procedural advice for passing the CISA examination on the initial attempt.
1#+date: [2021-12-04 Sat 00:00:00]
2#+title: I Passed the CISA Exam
3#+description: My take on the CISA exam: what it covers, and what it doesn't.
44#+slug: cisa
5#+filetags: :audit:
5#+filetags: :audit:
66
77* What is the CISA?
88
content/blog/2022-02-10-leaving-the-office.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2022-02-10 Thu 00:00:00]
2#+title: leaving the office: remote work without the linkedin take
3#+description: Examination of factors influencing the shift from traditional office environments to remote work, including benefits, constraints, and implementation recommendations.
1#+date: [2022-02-10 Thu 00:00:00]
2#+title: Leaving the Office
3#+description: My honest thoughts on leaving the office and working remotely.
44#+slug: leaving-the-office
5#+filetags: :personal:
5#+filetags: :personal:
66
77* The Working World is Changing
88
content/blog/2022-02-10-njalla-dns-api.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2022-02-10 Thu 00:00:00]
2#+title: automating dynamic dns record updates via njalla api using python
3#+description: Instructional material detailing automation of DNS record updates by interfacing with Njalla's API, suitable for environments with frequently changing IP addresses.
1#+date: [2022-02-10 Thu 00:00:00]
2#+title: Dynamic DNS Updates via the Njalla API
3#+description: A Python script to update DNS records automatically via the Njalla API.
44#+slug: njalla-dns-api
5#+filetags: :security:
5#+filetags: :security:
66
77* Njalla's API
88
content/blog/2022-02-16-debian-and-nginx.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2022-02-16 Wed 00:00:00]
2#+title: debian nginx migration: ditch ubuntu, move the stack
3#+description: Step-by-step protocol for transitioning web server infrastructure to Debian operating system, including installation, configuration, and security hardening of Nginx and Agate services.
1#+date: [2022-02-16 Wed 00:00:00]
2#+title: Migrating from Ubuntu to Debian with Nginx
3#+description: Moving my web server from Ubuntu to Debian and reconfiguring Nginx.
44#+slug: debian-and-nginx
5#+filetags: :linux:web:
5#+filetags: :linux:web:
66
77* Server Operating System (OS): Debian
88
content/blog/2022-02-17-exiftool.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2022-02-17 Thu 00:00:00]
2#+title: exiftool metadata: strip it before you post it
3#+description: Technical instructions for utilizing Exiftool to systematically strip metadata from image files to ensure privacy and reduce file size.
1#+date: [2022-02-17 Thu 00:00:00]
2#+title: ExifTool: Strip Metadata Before You Post
3#+description: How to use ExifTool to strip metadata from images before sharing them.
44#+slug: exiftool
5#+filetags: :linux:privacy:
5#+filetags: :linux:privacy:
66
77** Why Strip Metadata?
88
content/blog/2022-02-20-nginx-caching.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2022-02-20 Sun 00:00:00]
2#+title: nginx caching: static content, cache config
3#+description: Detailed methods for configuring Nginx to cache static resources such as CSS, JavaScript, and images to improve website loading times and resource efficiency.
1#+date: [2022-02-20 Sun 00:00:00]
2#+title: Nginx Caching for Static Content
3#+description: Configuring Nginx to cache static assets like CSS, JS, and images.
44#+slug: nginx-caching
5#+filetags: :linux:web:
5#+filetags: :linux:web:
66
77* Update Your Nginx Config to Cache Static Files
88
content/blog/2022-02-22-tuesday.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2022-02-22 Tue 00:00:00]
2#+title: twosday: 2 22 22 was a real date
3#+description: Examination of the date Tuesday, February 22, 2022, highlighting the palindromic properties and expected observations on this specific calendar occurrence.
1#+date: [2022-02-22 Tue 00:00:00]
2#+title: Twosday: 2/22/22
3#+description: A brief note on Tuesday, February 22nd, 2022.
44#+slug: tuesday
5#+filetags: :personal:
5#+filetags: :personal:
66
77* Tuesday, Twosday
88
content/blog/2022-03-02-reliable-notes.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2022-03-02 Wed 00:00:00]
2#+title: notes in plaintext: portable, no app dependency
3#+description: Instructions on applying standardized note-taking procedures with Markdown format, including synchronization and cross-platform compatibility considerations.
1#+date: [2022-03-02 Wed 00:00:00]
2#+title: Create Reliable Notes with Plaintext
3#+description: Why I keep my notes in plaintext Markdown, synced across devices.
44#+slug: reliable-notes
5#+filetags: :personal:
5#+filetags: :personal:
66
77* Choosing Durable File Formats
88
content/blog/2022-03-03-financial-database.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2022-03-03 Thu 00:00:00]
2#+title: financial tracker: sqlite over spreadsheets
3#+description: Procedures for creating and maintaining a personal financial database utilizing SQLite, Python programming language, and Jupyter Notebook interface.
1#+date: [2022-03-03 Thu 00:00:00]
2#+title: Personal Finance Tracker with SQLite
3#+description: Building a personal finance tracker with SQLite, Python, and Jupyter.
44#+slug: financial-database
5#+filetags: :self-hosting:
5#+filetags: :self-hosting:
66
77* Personal Financial Tracking
88
content/blog/2022-03-08-plex-migration.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2022-03-08 Tue 00:00:00]
2#+title: migrating plex media server to new hardware with nvidia gpu setup
3#+description: Stepwise instructions for transferring Plex Media Server to new hardware and enabling Nvidia GPU transcoding to optimize media processing performance.
1#+date: [2022-03-08 Tue 00:00:00]
2#+title: Migrating Plex to New Hardware with Nvidia GPU
3#+description: Moving Plex to new hardware and setting up Nvidia GPU transcoding.
44#+slug: plex-migration
5#+filetags: :self-hosting:
5#+filetags: :self-hosting:
66
77* Migration Phases
88
content/blog/2022-03-23-cloudflare-dns-api.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2022-03-23 Wed 00:00:00]
2#+title: dynamic dns record updates via cloudflare api
3#+description: Command-line procedures to automate updating of DNS A and AAAA records by interfacing with the Cloudflare API, suitable for environments with variable IP addresses.
1#+date: [2022-03-23 Wed 00:00:00]
2#+title: Dynamic DNS Updates via the Cloudflare API
3#+description: Automatically updating DNS A and AAAA records via the Cloudflare API.
44#+slug: cloudflare-dns-api
5#+filetags: :security:
5#+filetags: :security:
66
77* DDNS: Dynamic DNS
88:PROPERTIES:
content/blog/2022-03-23-nextcloud-on-ubuntu.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2022-03-23 Wed 00:00:00]
2#+title: self hosting guide: nextcloud
3#+description: Comprehensive guide for implementing Nextcloud as a self-hosted solution on an Ubuntu server, including installation steps, configuration parameters, and basic security measures.
1#+date: [2022-03-23 Wed 00:00:00]
2#+title: Self-Hosting Guide: Nextcloud
3#+description: How to install and configure Nextcloud on Ubuntu.
44#+slug: nextcloud-on-ubuntu
5#+filetags: :linux:self-hosting:
5#+filetags: :linux:self-hosting:
66
77* What is Nextcloud?
88:PROPERTIES:
content/blog/2022-03-24-server-hardening.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2022-03-24 Thu 00:00:00]
2#+title: server hardening: firewalls, ssh, vlans
3#+description: Detailed instructions to enhance the security posture of home servers exposed to public networks, including firewall setup, secure SSH configuration, fail2ban deployment, and network segmentation.
1#+date: [2022-03-24 Thu 00:00:00]
2#+title: Server Hardening: Firewalls, SSH, VLANs
3#+description: Hardening a home server with UFW, SSH config, fail2ban, and VLANs.
44#+slug: server-hardening
5#+filetags: :linux:security:
5#+filetags: :linux:security:
66
77* Planning Data Flows & Security
88
content/blog/2022-03-26-ssh-mfa.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2022-03-26 Sat 00:00:00]
2#+title: ssh mfa: totp on top of keys
3#+description: Step-by-step deployment guide for enabling TOTP multi-factor authentication on SSH services using Google Authenticator and Pluggable Authentication Module (PAM) integration.
1#+date: [2022-03-26 Sat 00:00:00]
2#+title: SSH MFA: TOTP on Top of Keys
3#+description: Adding TOTP two-factor authentication on top of SSH key auth.
44#+slug: ssh-mfa
5#+filetags: :security:
5#+filetags: :security:
66
77* Why Do I Need Multi-Factor Authentication (MFA) for SSH (Secure Shell Protocol)?
88
content/blog/2022-04-02-nginx-reverse-proxy.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2022-04-02 Sat 00:00:00]
2#+title: nginx reverse proxy: config and nothing else
3#+description: Technical guide for setting up Nginx server to operate as a reverse proxy on Ubuntu systems, including configuration files setup and operational parameters.
1#+date: [2022-04-02 Sat 00:00:00]
2#+title: Nginx Reverse Proxy Config
3#+description: Setting up Nginx as a reverse proxy on Ubuntu.
44#+slug: nginx-reverse-proxy
5#+filetags: :linux:web:
5#+filetags: :linux:web:
66
77* What is a Reverse Proxy?
88
content/blog/2022-04-09-pinetime.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2022-04-09 Sat 00:00:00]
2#+title: pinetime smartwatch: an open source hardware & software overview
3#+description: Technical description of PineTime smartwatch capabilities, including heart rate measurement, step counting, sleep monitoring, and smartphone connectivity functions.
1#+date: [2022-04-09 Sat 00:00:00]
2#+title: PineTime: Open Source Smartwatch Overview
3#+description: An overview of the PineTime open-source smartwatch and what it can do.
44#+slug: pinetime
5#+filetags: :linux:
5#+filetags: :linux:
66
77* PineTime Product Information
88
content/blog/2022-06-01-ditching-cloudflare.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2022-06-01 Wed 00:00:00]
2#+title: ditching cloudflare: dns under your own name, not theirs
3#+description: Evaluation and procedural explanation for migrating DNS management services from Cloudflare to Njalla, with emphasis on privacy controls and domain registration mechanics.
1#+date: [2022-06-01 Wed 00:00:00]
2#+title: Ditching Cloudflare
3#+description: Why I moved my DNS away from Cloudflare, and how I did it.
44#+slug: ditching-cloudflare
5#+filetags: :privacy:security:
5#+filetags: :privacy:security:
66
77* Registrar
88
content/blog/2022-06-07-self-hosting-freshrss.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2022-06-07 Tue 00:00:00]
2#+title: self hosting guide: freshrss
3#+description: Stepwise instructions for installing FreshRSS using Docker and configuring Nginx as a reverse proxy to enable secure and synchronized RSS feed access.
1#+date: [2022-06-07 Tue 00:00:00]
2#+title: Self-Hosting Guide: FreshRSS
3#+description: How to install FreshRSS with Docker and Nginx.
44#+slug: self-hosting-freshrss
5#+filetags: :linux:self-hosting:
5#+filetags: :linux:self-hosting:
66
77* Why Use Really Simple Syndication (RSS)?
88
content/blog/2022-06-16-terminal-lifestyle.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2022-06-16 Thu 00:00:00]
2#+title: terminal first: why the gui is optional
3#+description: Detailed procedures for reducing digital interruptions and increasing efficiency through terminal-based utilities for web browsing, communication, electronic mail, RSS feeds, and programming tasks.
1#+date: [2022-06-16 Thu 00:00:00]
2#+title: Terminal First: Why the GUI Is Optional
3#+description: My setup for handling email, browsing, IRC, and RSS from the terminal.
44#+slug: terminal-lifestyle
5#+filetags: :linux:
5#+filetags: :linux:
66
77* Text-Based Simplicity
88
content/blog/2022-06-22-daily-poetry.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2022-06-22 Wed 00:00:00]
2#+title: daily poetry: cron job, no subscription required
3#+description: Instructional guide for scheduling and automating the distribution of classic and contemporary poetry in plaintext format to an electronic mail inbox using Python scripting and SMTP protocol.
1#+date: [2022-06-22 Wed 00:00:00]
2#+title: Daily Poetry via Cron
3#+description: A Python script that emails you a poem every morning via cron.
44#+slug: daily-poetry
5#+filetags: :personal:
5#+filetags: :personal:
66
77* Source Code
88
content/blog/2022-06-24-fedora-i3.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2022-06-24 Fri 00:00:00]
2#+title: fedora i3: back on linux, tiling wm
3#+description: Examination of the transition from macOS to Linux, including a detailed description of Fedora operating system installation and i3 window manager configuration.
1#+date: [2022-06-24 Fri 00:00:00]
2#+title: Fedora and i3: Back on Linux
3#+description: Moving back to Linux: installing Fedora and setting up i3.
44#+slug: fedora-i3
5#+filetags: :linux:
5#+filetags: :linux:
66
77* Leaving macOS
88
content/blog/2022-07-01-git-server.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2022-07-01 Fri 00:00:00]
2#+title: self hosting guide: git & cgit
3#+description: Comprehensive instructions for secure and efficient setup, hosting, and management of personal Git repositories to facilitate collaborative development and remote access.
1#+date: [2022-07-01 Fri 00:00:00]
2#+title: Self-Hosting Guide: Git and cgit
3#+description: How to self-host Git repos and browse them with cgit.
44#+slug: git-server
5#+filetags: :linux:self-hosting:
5#+filetags: :linux:self-hosting:
66
77* My Approach to Self-Hosting Git
88
content/blog/2022-07-14-gnupg.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2022-07-14 Thu 00:00:00]
2#+title: gnupg: encryption, signing, web of trust
3#+description: Technical manual covering the architecture, cryptographic algorithms, vulnerability considerations, key management, and typical applications of GNU Privacy Guard for secure data and email encryption.
1#+date: [2022-07-14 Thu 00:00:00]
2#+title: GnuPG: Encryption, Signing, Web of Trust
3#+description: How GnuPG works and how I use it for encryption and signing.
44#+slug: gnupg
5#+filetags: :linux:security:
5#+filetags: :linux:security:
66
77* The History of GPG
88
content/blog/2022-07-25-curseradio.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2022-07-25 Mon 00:00:00]
2#+title: curseradio: a lightweight command line internet radio player for linux
3#+description: Stepwise instructions for installing and utilizing Curseradio, a lightweight command-line program for streaming radio stations within Linux environments.
1#+date: [2022-07-25 Mon 00:00:00]
2#+title: Curseradio: Internet Radio from the Terminal
3#+description: Installing and using Curseradio to stream internet radio from the terminal.
44#+slug: curseradio
5#+filetags: :linux:
5#+filetags: :linux:
66
77* Overview
88
content/blog/2022-07-30-flac-to-opus.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2022-07-30 Sat 00:00:00]
2#+title: automating recursive flac to opus conversion with a bash script
3#+description: Instructions for automating the conversion of audio files from FLAC to Opus format recursively within directory structures, including performance considerations and script usage.
1#+date: [2022-07-30 Sat 00:00:00]
2#+title: Recursive FLAC to Opus Conversion
3#+description: A bash script to convert FLAC files to Opus recursively.
44#+slug: flac-to-opus
5#+filetags: :linux:
5#+filetags: :linux:
66
77* Converting FLAC to OPUS
88
content/blog/2022-07-31-bash-it.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2022-07-31 Sun 00:00:00]
2#+title: bash it: plugins and autosuggestions for zsh refugees
3#+description: Guide to augmenting Bash shell features by integrating Bash-It framework along with ble.sh for input autosuggestions, improving command-line efficiency on Linux systems.
1#+date: [2022-07-31 Sun 00:00:00]
2#+title: Bash-It: Plugins and Autosuggestions
3#+description: Setting up Bash-It with ble.sh for a better shell experience.
44#+slug: bash-it
5#+filetags: :linux:
5#+filetags: :linux:
66
77* Bash
88
content/blog/2022-08-31-privacy-com-changes.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2022-08-31 Wed 00:00:00]
2#+title: privacy com changes: they changed the product, not the name
3#+description: Detailed examination of modifications to Privacy.com service terms and their implications on user privacy and payment security protocols.
1#+date: [2022-08-31 Wed 00:00:00]
2#+title: Privacy.com Changed the Product, Not the Name
3#+description: Privacy.com changed their terms. Here's what that means.
44#+slug: privacy-com-changes
5#+filetags: :privacy:
5#+filetags: :privacy:
66
77* Privacy.com Changes Their Terms
88
content/blog/2022-09-17-serenity-os.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2022-09-17 Sat 00:00:00]
2#+title: building and exploring serenityos: a retro inspired unix like desktop
3#+description: Technical overview of Serenity OS including system architecture, building procedures, and operational instructions for this Unix-like operating system with a 1990s user interface style.
1#+date: [2022-09-17 Sat 00:00:00]
2#+title: Building and Exploring SerenityOS
3#+description: Building and running SerenityOS, a retro Unix-like desktop OS.
44#+slug: serenity-os
5#+filetags: :linux:
5#+filetags: :linux:
66
77* Overview
88
content/blog/2022-09-21-graphene-os.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2022-09-21 Wed 00:00:00]
2#+title: installing grapheneos on pixel 6 pro
3#+description: Step-by-step instructions to perform secure installation of the GrapheneOS operating system on Google Pixel 6 Pro hardware platform.
1#+date: [2022-09-21 Wed 00:00:00]
2#+title: Installing GrapheneOS on Pixel 6 Pro
3#+description: How to install GrapheneOS on a Pixel 6 Pro.
44#+slug: graphene-os
5#+filetags: :linux:privacy:
5#+filetags: :linux:privacy:
66
77* Introduction
88
content/blog/2022-10-04-mtp-linux.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2022-10-04 Tue 00:00:00]
2#+title: mtp linux: mount your phone without a file manager
3#+description: Instructions for mounting and accessing Media Transfer Protocol (MTP) compatible mobile devices on Fedora Linux using jmtpfs for file transfer and management.
1#+date: [2022-10-04 Tue 00:00:00]
2#+title: MTP on Linux: Mount Your Phone Without a File Manager
3#+description: Mounting Android phones on Fedora Linux with jmtpfs.
44#+slug: mtp-linux
5#+filetags: :linux:
5#+filetags: :linux:
66
77I recently ran into trouble attempting to mount my GrapheneOS phone to my laptop
88running Fedora Linux via the [[https://en.wikipedia.org/wiki/Media_transfer_protocol][Media Transfer Protocol]] (MTP) and discovered a
content/blog/2022-10-04-syncthing.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2022-10-04 Tue 00:00:00]
2#+title: self hosting guide: syncthing
3#+description: Technical instructions for setting up Syncthing as a peer-to-peer self-hosted file synchronization system that preserves data privacy by eliminating third-party intermediaries.
1#+date: [2022-10-04 Tue 00:00:00]
2#+title: Self-Hosting Guide: Syncthing
3#+description: How to set up Syncthing for private, peer-to-peer file sync.
44#+slug: syncthing
5#+filetags: :linux:self-hosting:
5#+filetags: :linux:self-hosting:
66
77* An Overview of Syncthing
88
content/blog/2022-10-22-alpine-linux.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2022-10-22 Sat 00:00:00]
2#+title: alpine linux: minimal install, minimal attack surface
3#+description: Detailed procedure for deploying Alpine Linux to achieve a secure, lightweight server environment optimized for web hosting and containerization.
1#+date: [2022-10-22 Sat 00:00:00]
2#+title: Alpine Linux: Minimal Install, Minimal Attack Surface
3#+description: Installing Alpine Linux as a lightweight, secure server OS.
44#+slug: alpine-linux
5#+filetags: :linux:
5#+filetags: :linux:
66
77* Alpine Linux
88
content/blog/2022-10-30-linux-display-manager.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2022-10-30 Sun 00:00:00]
2#+title: managing display managers in void linux: disable, enable, and configure
3#+description: Stepwise instructions to manage and replace the display manager on a Void Linux installation, including service control and configuration editing.
1#+date: [2022-10-30 Sun 00:00:00]
2#+title: Void Linux: Remove the Display Manager
3#+description: Disabling the display manager on Void Linux and starting i3 manually.
44#+slug: linux-display-manager
5#+filetags: :linux:
5#+filetags: :linux:
66
77* Display Manager Services
88
content/blog/2022-11-07-self-hosting-matrix.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2022-11-07 Mon 00:00:00]
2#+title: self hosting guide: matrix synapse
3#+description: Systematic guide for deploying Matrix Synapse on Alpine Linux, covering dependency installation, reverse proxy setup, TLS certificate application, and user account management.
1#+date: [2022-11-07 Mon 00:00:00]
2#+title: Self-Hosting Guide: Matrix Synapse
3#+description: How to deploy Matrix Synapse on Alpine Linux with Nginx.
44#+slug: self-hosting-matrix
5#+filetags: :linux:self-hosting:
5#+filetags: :linux:self-hosting:
66
77* Synapse
88
content/blog/2022-11-11-nginx-tmp-errors.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2022-11-11 Fri 00:00:00]
2#+title: troubleshooting and fixing nginx permission denied errors on /var/lib/nginx
3#+description: Step-by-step remediation for addressing permission denied errors encountered by Nginx in the /var/lib/nginx directory to restore temporary file caching functionality.
1#+date: [2022-11-11 Fri 00:00:00]
2#+title: Fixing Nginx Permission Denied Errors on /var/lib/nginx
3#+description: Fixing permission denied errors on /var/lib/nginx in Nginx.
44#+slug: nginx-tmp-errors
5#+filetags: :web:
5#+filetags: :web:
66
77/This is a brief post so that I personally remember the solution as it
88has occurred multiple times for me./
content/blog/2022-11-27-server-build.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2022-11-27 Sun 00:00:00]
2#+title: server build: rack hardware, consumer parts, no enterprise markup
3#+description: Detailed instructions on selecting components, assembling, and configuring a rack-mounted server suitable for advanced computing tasks in a professional or laboratory setting.
1#+date: [2022-11-27 Sun 00:00:00]
2#+title: Server Build: Rack Hardware, Consumer Parts
3#+description: How I built a rack-mounted server with consumer parts.
44#+slug: server-build
5#+filetags: :linux:
5#+filetags: :linux:
66
77* The Dilemma
88
content/blog/2022-11-29-nginx-referrer-ban-list.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2022-11-29 Tue 00:00:00]
2#+title: nginx referrer ban: block the scrapers
3#+description: Technical guide to implementing a referrer ban list in Nginx configurations to prevent access from undesired domains and improve web server security.
1#+date: [2022-11-29 Tue 00:00:00]
2#+title: Nginx Referrer Ban List
3#+description: Blocking unwanted referrers in Nginx with a simple ban list.
44#+slug: nginx-referrer-ban-list
5#+filetags: :linux:web:
5#+filetags: :linux:web:
66
77* Creating the Ban List
88
content/blog/2022-12-01-nginx-compression.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2022-12-01 Thu 00:00:00]
2#+title: nginx gzip: compress text, nothing else
3#+description: Procedures for activating and configuring GZIP compression in Nginx to decrease data transmission size, reduce bandwidth consumption, and accelerate page load times.
1#+date: [2022-12-01 Thu 00:00:00]
2#+title: Nginx Gzip: Compress Text, Nothing Else
3#+description: Enabling and configuring GZIP compression in Nginx.
44#+slug: nginx-compression
5#+filetags: :linux:web:
5#+filetags: :linux:web:
66
77* Text Compression
88
content/blog/2022-12-07-nginx-wildcard-redirect.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2022-12-07 Wed 00:00:00]
2#+title: nginx wildcard redirect: domains, subdomains, trailing paths
3#+description: Instructional steps for applying regex-based redirects in Nginx to manage subdomain routing and trailing path modifications effectively.
1#+date: [2022-12-07 Wed 00:00:00]
2#+title: Nginx Wildcard Redirects
3#+description: Using regex-based redirects in Nginx for subdomain and path routing.
44#+slug: nginx-wildcard-redirect
5#+filetags: :web:
5#+filetags: :web:
66
77* Problem
88
content/blog/2022-12-17-st.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2022-12-17 Sat 00:00:00]
2#+title: installing and customizing the suckless simple terminal (st) on fedora linux
3#+description: Comprehensive instructions to obtain source code, compile, apply patches, and install the Simple Terminal application on Fedora Linux systems.
1#+date: [2022-12-17 Sat 00:00:00]
2#+title: Suckless Simple Terminal on Fedora
3#+description: Compiling and patching the Suckless Simple Terminal on Fedora.
44#+slug: st
5#+filetags: :linux:
5#+filetags: :linux:
66
77* st
88
content/blog/2022-12-23-alpine-desktop.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2022-12-23 Fri 00:00:00]
2#+title: alpine desktop: sway on alpine, minimal by default
3#+description: Stepwise procedures for installing and setting up Alpine Linux as a desktop operating system, including window manager setup and relevant system adjustments.
1#+date: [2022-12-23 Fri 00:00:00]
2#+title: Alpine Desktop with Sway
3#+description: Setting up Alpine Linux as a desktop with Sway as the window manager.
44#+slug: alpine-desktop
5#+filetags: :linux:
5#+filetags: :linux:
66
77* Isn't Alpine Linux for Servers?
88
content/blog/2023-01-03-recent-website-changes.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2023-01-03 Tue 00:00:00]
2#+title: website updates 2023: what changed and why
3#+description: Documentation of significant changes applied to site design, layout, and accessibility features to enhance navigability and content clarity.
1#+date: [2023-01-03 Tue 00:00:00]
2#+title: Website Updates 2023
3#+description: A rundown of recent changes to the site design and structure.
44#+slug: recent-website-changes
5#+filetags: :personal:web:
5#+filetags: :personal:web:
66
77* The State of This Website
88
content/blog/2023-01-05-mass-unlike-tumblr-posts.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2023-01-05 Thu 00:00:00]
2#+title: tumblr unlike all: script, done, get out
3#+description: Instructions for executing a JavaScript script to automate the mass unlike operation for Tumblr posts without requiring additional software.
1#+date: [2023-01-05 Thu 00:00:00]
2#+title: Mass Unlike All Tumblr Posts
3#+description: A JavaScript snippet to mass-unlike all your Tumblr posts.
44#+slug: mass-unlike-tumblr-posts
5#+filetags: :linux:personal:
5#+filetags: :linux:personal:
66
77* The Dilemma
88
content/blog/2023-01-08-fedora-login-manager.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2023-01-08 Sun 00:00:00]
2#+title: fedora i3 no login manager: remove it, start manually
3#+description: Step-by-step guide for uninstalling the default Fedora i3 login manager and configuring system to launch i3 window manager manually.
1#+date: [2023-01-08 Sun 00:00:00]
2#+title: Fedora i3: Remove the Login Manager
3#+description: Removing the Fedora login manager and launching i3 manually.
44#+slug: fedora-login-manager
5#+filetags: :linux:
5#+filetags: :linux:
66
77* Fedora i3's Login Manager
88
content/blog/2023-01-21-flatpak-symlinks.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2023-01-21 Sat 00:00:00]
2#+title: flatpak symlinks: shorten the command
3#+description: Detailed instructions for establishing symbolic links for Flatpak applications to facilitate faster execution from terminal or application launcher environments.
1#+date: [2023-01-21 Sat 00:00:00]
2#+title: Flatpak Symlinks: Shorten the Command
3#+description: Creating symlinks for Flatpak apps to make them easier to launch.
44#+slug: flatpak-symlinks
5#+filetags: :linux:
5#+filetags: :linux:
66
77* Running Flatpak Apps Should Be Faster
88
content/blog/2023-01-23-random-wireguard.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2023-01-23 Mon 00:00:00]
2#+title: automate random mullvad wireguard vpn connection on startup
3#+description: Stepwise method to configure system startup scripts for automatic connection to a randomly chosen Mullvad Wireguard VPN server to maintain privacy.
1#+date: [2023-01-23 Mon 00:00:00]
2#+title: Random Mullvad WireGuard on Startup
3#+description: A startup script to connect to a random Mullvad WireGuard server.
44#+slug: random-wireguard
5#+filetags: :linux:security:self-hosting:
5#+filetags: :linux:security:self-hosting:
66
77* Mullvad Wireguard
88
content/blog/2023-01-28-self-hosting-wger.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2023-01-28 Sat 00:00:00]
2#+title: self hosting guide: wger
3#+description: Comprehensive steps for installing, configuring, and operating the Wger workout management application on a dedicated server platform.
1#+date: [2023-01-28 Sat 00:00:00]
2#+title: Self-Hosting Guide: wger
3#+description: How to self-host wger, an open-source workout manager.
44#+slug: self-hosting-wger
5#+filetags: :linux:self-hosting:
5#+filetags: :linux:self-hosting:
66
77* Wger: The Self-Hosted Workout Manager
88
content/blog/2023-02-02-exploring-hare.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2023-02-02 Thu 00:00:00]
2#+title: hare lang: notes from first contact
3#+description: Overview of the Hare programming language features, installation procedure, and elementary programming examples targeting system-level development.
1#+date: [2023-02-02 Thu 00:00:00]
2#+title: Hare Lang: Notes from First Contact
3#+description: First impressions of the Hare programming language.
44#+slug: exploring-hare
5#+filetags: :linux:
5#+filetags: :linux:
66
77* A Quick Note
88
content/blog/2023-05-22-burnout.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2023-05-22 Mon 00:00:00]
2#+title: burnout: audit and consulting will take everything you let them
3#+description: Examination of burnout phenomena accompanied by strategies and practical approaches for workload management and restoration of optimal functioning.
1#+date: [2023-05-22 Mon 00:00:00]
2#+title: Burnout
3#+description: Honest thoughts on burning out in audit and consulting.
44#+slug: burnout
5#+filetags: :personal:
5#+filetags: :personal:
66
77* RE: Burnout
88
content/blog/2023-06-08-goaccess-geoip.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2023-06-08 Thu 00:00:00]
2#+title: real time traffic insights from nginx logs using goaccess + geoip
3#+description: Step-by-step instructions to utilize GoAccess tool incorporating MaxMind GeoIP integration for real-time geographic and traffic analysis of Nginx log files.
1#+date: [2023-06-08 Thu 00:00:00]
2#+title: Nginx Traffic Analysis with GoAccess and GeoIP
3#+description: Using GoAccess with MaxMind GeoIP to analyze Nginx traffic in real time.
44#+slug: goaccess-geoip
5#+filetags: :self-hosting:web:
5#+filetags: :self-hosting:web:
66
77* Overview
88
content/blog/2023-06-08-self-hosting-baikal.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2023-06-08 Thu 00:00:00]
2#+title: self hosting guide: baikal
3#+description: Detailed procedure for deploying the Baikal server software to provide CalDAV and CardDAV services, including security considerations and Docker deployment.
1#+date: [2023-06-08 Thu 00:00:00]
2#+title: Self-Hosting Guide: Baikal
3#+description: How to deploy Baikal for self-hosted CalDAV and CardDAV.
44#+slug: self-hosting-baikal
5#+filetags: :linux:self-hosting:
5#+filetags: :linux:self-hosting:
66
77* What is Baikal?
88
content/blog/2023-06-18-unifi-ip-blocklist.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2023-06-18 Sun 00:00:00]
2#+title: blocking malicious ips on unifi: manual firewall rule setup
3#+description: Instructions to identify and block harmful IP addresses and subnets through Unifi firewall settings to improve network security posture.
1#+date: [2023-06-18 Sun 00:00:00]
2#+title: Blocking Malicious IPs on Unifi
3#+description: Manually blocking malicious IPs via Unifi firewall rules.
44#+slug: unifi-ip-blocklist
5#+filetags: :linux:self-hosting:
5#+filetags: :linux:self-hosting:
66
77* Identifying Abusive IPs
88
content/blog/2023-06-20-audit-review-template.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2023-06-20 Tue 00:00:00]
2#+title: audit testing review checklist
3#+description: Practical audit testing review template with detailed steps to support comprehensive evaluation of financial audits and SOC reports.
1#+date: [2023-06-20 Tue 00:00:00]
2#+title: Audit Testing Review Checklist
3#+description: A practical checklist for reviewing audit testing on financial and SOC engagements.
44#+slug: audit-review-template
5#+filetags: :audit:
5#+filetags: :audit:
66
77* Overview
88
content/blog/2023-06-23-byobu.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2023-06-23 Fri 00:00:00]
2#+title: byobu: tmux with less configuration overhead
3#+description: Detailed overview of Byobu terminal multiplexer features, configuration settings, session management, and keybindings to enhance command-line efficiency.
1#+date: [2023-06-23 Fri 00:00:00]
2#+title: Byobu: tmux with Less Configuration Overhead
3#+description: Using Byobu as a tmux wrapper with sane defaults out of the box.
44#+slug: byobu
5#+filetags: :linux:self-hosting:
5#+filetags: :linux:self-hosting:
66
77* Byobu
88
content/blog/2023-06-23-self-hosting-convos.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2023-06-23 Fri 00:00:00]
2#+title: self hosting guide: convos
3#+description: Stepwise instructions for installation, Docker Compose configuration, Nginx reverse proxy setup, and IRC nickname registration for Convos web client hosting.
1#+date: [2023-06-23 Fri 00:00:00]
2#+title: Self-Hosting Guide: Convos
3#+description: How to self-host Convos, a web-based IRC client.
44#+slug: self-hosting-convos
5#+filetags: :linux:self-hosting:
5#+filetags: :linux:self-hosting:
66
77* Convos
88
content/blog/2023-06-28-backblaze-b2.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2023-06-28 Wed 00:00:00]
2#+title: backblaze b2 backups: before i moved off it
3#+description: Methodical guide for configuring and utilizing Backblaze B2 cloud storage services to perform reliable and secure offsite data backups.
1#+date: [2023-06-28 Wed 00:00:00]
2#+title: Backblaze B2 Backups
3#+description: Setting up Backblaze B2 for offsite backups before I moved on.
44#+slug: backblaze-b2
5#+filetags: :self-hosting:
5#+filetags: :self-hosting:
66
77* Overview
88
content/blog/2023-06-30-self-hosting-voyager.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2023-06-30 Fri 00:00:00]
2#+title: self hosting guide: voyager for lemmy
3#+description: Instructions for building, running, and reverse proxying Voyager, a Lemmy web client, on a server environment utilizing Docker and Nginx components.
1#+date: [2023-06-30 Fri 00:00:00]
2#+title: Self-Hosting Guide: Voyager for Lemmy
3#+description: How to self-host Voyager, a web client for Lemmy.
44#+slug: self-hosting-voyager
5#+filetags: :linux:self-hosting:
5#+filetags: :linux:self-hosting:
66
77* Installation Guide
88
content/blog/2023-07-12-wireguard-lan.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2023-07-12 Wed 00:00:00]
2#+title: enabling local network access with mullvad wireguard configs
3#+description: Detailed procedure to modify Mullvad Wireguard VPN configuration files and iptables rules to allow Local Area Network access while maintaining VPN connectivity.
1#+date: [2023-07-12 Wed 00:00:00]
2#+title: Mullvad WireGuard with LAN Access
3#+description: Modifying Mullvad WireGuard configs to allow LAN access while connected.
44#+slug: wireguard-lan
5#+filetags: :security:self-hosting:
5#+filetags: :security:self-hosting:
66
77* Download Configuration Files from Mullvad
88
content/blog/2023-07-19-plex-transcoder-errors.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2023-07-19 Wed 00:00:00]
2#+title: plex subtitle error: transcoder fails to start
3#+description: Technical procedures to identify and correct Plex transcoder failures at startup to maintain uninterrupted media conversion and playback.
1#+date: [2023-07-19 Wed 00:00:00]
2#+title: Plex Transcoder Errors: Subtitle Fix
3#+description: Fixing Plex transcoder startup failures caused by subtitle errors.
44#+slug: plex-transcoder-errors
5#+filetags: :linux:self-hosting:
5#+filetags: :linux:self-hosting:
66
77* Plex Transcoder Error
88
content/blog/2023-08-18-agile-auditing.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2023-08-18 Fri 00:00:00]
2#+title: agile auditing: consultants cosplaying as engineers
3#+description: Detailed examination of Agile auditing methodologies, including Scrum and Kanban frameworks, with practical steps for application in audit processes.
1#+date: [2023-08-18 Fri 00:00:00]
2#+title: Agile Auditing
3#+description: My take on agile auditing: what it is and how it actually plays out.
44#+slug: agile-auditing
5#+filetags: :audit:
5#+filetags: :audit:
66
77* What is Agile Auditing?
88
content/blog/2023-09-15-self-hosting-gitweb.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2023-09-15 Fri 00:00:00]
2#+title: self hosting guide: gitweb
3#+description: Stepwise instructions for deploying GitWeb on Linux servers using Nginx, configuring fastcgi, and managing git repositories effectively.
1#+date: [2023-09-15 Fri 00:00:00]
2#+title: Self-Hosting Guide: GitWeb
3#+description: Deploying GitWeb on Linux with Nginx and FastCGI.
44#+slug: self-hosting-gitweb
5#+filetags: :linux:self-hosting:
5#+filetags: :linux:self-hosting:
66
77* Overview
88
content/blog/2023-09-19-audit-sql-scripts.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2023-09-19 Tue 00:00:00]
2#+title: auditing user privileges in oracle, sql server, and mysql
3#+description: Collection of SQL queries designed for auditing user access parameters on Oracle, Microsoft SQL Server, and MySQL database systems.
1#+date: [2023-09-19 Tue 00:00:00]
2#+title: SQL Scripts for Auditing User Privileges
3#+description: SQL queries for auditing user access in Oracle, SQL Server, and MySQL.
44#+slug: audit-sql-scripts
5#+filetags: :audit:
5#+filetags: :audit:
66
77* Overview
88
content/blog/2023-10-04-digital-minimalism.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2023-10-04 Wed 00:00:00]
2#+title: digital minimalism: fewer inputs, more signal
3#+description: Practical guide for minimizing digital clutter and optimizing work focus by applying digital minimalism tactics.
1#+date: [2023-10-04 Wed 00:00:00]
2#+title: Digital Minimalism: Fewer Inputs, More Signal
3#+description: How I reduce digital noise and stay focused.
44#+slug: digital-minimalism
5#+filetags: :linux:privacy:
5#+filetags: :linux:privacy:
66
77I've written [[https://cleberg.net/wiki/#digital-garden][a note about minimalism]]
88before, but I wanted to dedicate some time to reflect on digital
content/blog/2023-10-11-self-hosting-authelia.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2023-10-11 Wed 00:00:00]
2#+title: self hosting guide: authelia
3#+description: Instructional guide for setting up Authelia to provide secure two-factor authentication and access control in self-hosted environments.
1#+date: [2023-10-11 Wed 00:00:00]
2#+title: Self-Hosting Guide: Authelia
3#+description: Setting up Authelia for two-factor auth and access control on self-hosted apps.
44#+slug: self-hosting-authelia
5#+filetags: :linux:security:self-hosting:
5#+filetags: :linux:security:self-hosting:
66
77* Overview
88
content/blog/2023-10-15-alpine-ssh-hardening.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2023-10-15 Sun 00:00:00]
2#+title: alpine linux ssh hardening guide
3#+description: Detailed guide to enhance Alpine Linux SSH server security through configuration adjustments and vulnerability mitigation.
1#+date: [2023-10-15 Sun 00:00:00]
2#+title: Alpine Linux SSH Hardening
3#+description: Hardening SSH on Alpine Linux with config changes and key-only auth.
44#+slug: alpine-ssh-hardening
5#+filetags: :linux:security:
5#+filetags: :linux:security:
66
77* Overview
88
content/blog/2023-10-17-self-hosting-anonymousoverflow.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2023-10-17 Tue 00:00:00]
2#+title: self hosting guide: anonymousoverflow
3#+description: Detailed installation and setup instructions for the AnonymousOverflow application using Docker Compose and Nginx reverse proxy.
1#+date: [2023-10-17 Tue 00:00:00]
2#+title: Self-Hosting Guide: AnonymousOverflow
3#+description: How to self-host AnonymousOverflow with Docker Compose and Nginx.
44#+slug: self-hosting-anonymousoverflow
5#+filetags: :linux:self-hosting:
5#+filetags: :linux:self-hosting:
66
77* Overview
88
content/blog/2023-11-08-scli.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2023-11-08 Wed 00:00:00]
2#+title: signal cli (scli) installation on alpine
3#+description: Step-by-step instructions for installing the Signal messenger command-line client scli on Alpine Linux with musl libc, including dependencies and configuration.
1#+date: [2023-11-08 Wed 00:00:00]
2#+title: Signal CLI (scli) on Alpine
3#+description: Installing the Signal CLI client on Alpine Linux.
44#+slug: scli
5#+filetags: :linux:
5#+filetags: :linux:
66
77[[https://github.com/isamert/scli][scli]] is a command-line tool that
88allows you to connect to your Signal messenger account. This program
content/blog/2023-12-03-unifi-nextdns.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2023-12-03 Sun 00:00:00]
2#+title: installing and configuring nextdns on unifi dream machine routers
3#+description: Procedural guide for installation and configuration of NextDNS on Unifi Dream Machine devices for network DNS filtering.
1#+date: [2023-12-03 Sun 00:00:00]
2#+title: NextDNS on Unifi Dream Machine
3#+description: Installing and configuring NextDNS on a Unifi Dream Machine.
44#+slug: unifi-nextdns
5#+filetags: :linux:self-hosting:
5#+filetags: :linux:self-hosting:
66
77* Overview
88
content/blog/2024-01-08-dont-say-hello.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2024-01-08 Mon 00:00:00]
2#+title: don't say hello
3#+description: Technical recommendations for improving professional communication by eliminating non-essential introductory phrases to enhance message clarity.
1#+date: [2024-01-08 Mon 00:00:00]
2#+title: Don't Say Hello
3#+description: Stop leading messages with 'hello' and nothing else.
44#+slug: dont-say-hello
5#+filetags: :privacy:
5#+filetags: :privacy:
66
77I recently came back from a winter break and have started working again... only
88to immediately run into the dilemma of people sending me cliffhanger messages
content/blog/2024-01-09-macos-customization.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2024-01-09 Tue 00:00:00]
2#+title: macos customization: terminal, tiling wm, widgets
3#+description: Detailed overview of methods and tools for modifying macOS system settings, including terminal usage, window management, and interface customization.
1#+date: [2024-01-09 Tue 00:00:00]
2#+title: macOS Customization: Terminal, Tiling WM, Widgets
3#+description: How I've customized macOS with a terminal, tiling WM, and widgets.
44#+slug: macos-customization
5#+filetags: :linux:
5#+filetags: :linux:
66
77I have been using macOS more than Linux lately, so I wrote this post to describe
88some simple options to customize macOS beyond the normal built-in settings menu.
content/blog/2024-01-13-local-llm.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2024-01-13 Sat 00:00:00]
2#+title: local llm: run the model, keep the data
3#+description: Technical guide to deploying and running local large language models on macOS and iOS devices focusing on open-source implementations and privacy considerations.
1#+date: [2024-01-13 Sat 00:00:00]
2#+title: Local LLM: Run the Model, Keep the Data
3#+description: Running local language models on macOS and iOS with open-source tools.
44#+slug: local-llm
5#+filetags: :linux:privacy:
5#+filetags: :linux:privacy:
66
77* Requirements
88
content/blog/2024-01-26-audit-dashboard.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2024-01-26 Fri 00:00:00]
2#+title: audit dashboard: alteryx + power bi, the corporate stack
3#+description: Instructions for transforming audit data into dynamic dashboards via data preparation with Alteryx and visualization using Microsoft Power BI.
1#+date: [2024-01-26 Fri 00:00:00]
2#+title: Audit Dashboard: Alteryx and Power BI
3#+description: Building an audit dashboard with Alteryx for data prep and Power BI for visuals.
44#+slug: audit-dashboard
5#+filetags: :audit:
5#+filetags: :audit:
66
77Alteryx and Power BI are powerful tools that can help turn your old-school audit
88trackers into interactive tools that provide useful insights and potential
content/blog/2024-01-27-tableau-dashboard.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2024-01-27 Sat 00:00:00]
2#+title: omaha crime data: tableau, 8 years of numbers
3#+description: Detailed procedure for data preparation and interactive visualization of crime trends in Omaha, using Tableau software from 2015 through 2023 data.
1#+date: [2024-01-27 Sat 00:00:00]
2#+title: Omaha Crime Data: 8 Years in Tableau
3#+description: Visualizing 8 years of Omaha crime data in Tableau.
44#+slug: tableau-dashboard
5#+filetags: :web:
5#+filetags: :web:
66
77In this project, I am going to show you how to use Tableau Public for free to
88create simple dashboards.
content/blog/2024-02-06-zfs.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2024-02-06 Tue 00:00:00]
2#+title: creating and managing zfs storage pools on ubuntu linux
3#+description: Stepwise guide to setting up ZFS storage pools on Ubuntu, including initial installation, pool creation, expansion, and maintenance.
1#+date: [2024-02-06 Tue 00:00:00]
2#+title: ZFS Storage Pools on Ubuntu
3#+description: Setting up and managing ZFS storage pools on Ubuntu.
44#+slug: zfs
5#+filetags: :linux:
5#+filetags: :linux:
66
77This post details the process I used to create ZFS pools, datasets, and
88snapshots on Ubuntu Server.
content/blog/2024-02-13-ubuntu-emergency-mode.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2024-02-13 Tue 00:00:00]
2#+title: resolving ubuntu boot issues caused by invalid /etc/fstab mounts
3#+description: Detailed instructions to identify errors in the /etc/fstab file causing Ubuntu to enter emergency mode and steps to edit and restore normal boot operations.
1#+date: [2024-02-13 Tue 00:00:00]
2#+title: Ubuntu Emergency Mode: Bad /etc/fstab Fix
3#+description: Fixing an invalid /etc/fstab that put Ubuntu into emergency mode.
44#+slug: ubuntu-emergency-mode
5#+filetags: :linux:
5#+filetags: :linux:
66
77* The Problem
88
content/blog/2024-02-21-self-hosting-otter-wiki.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2024-02-21 Wed 00:00:00]
2#+title: self hosting guide: an otter wiki
3#+description: Stepwise directions for installing Otter Wiki, configuring Docker Compose environment, and setting up Nginx reverse proxy for secure access.
1#+date: [2024-02-21 Wed 00:00:00]
2#+title: Self-Hosting Guide: Otter Wiki
3#+description: How to self-host Otter Wiki with Docker Compose and Nginx.
44#+slug: self-hosting-otter-wiki
5#+filetags: :linux:self-hosting:
5#+filetags: :linux:self-hosting:
66
77* An Otter Wiki
88
content/blog/2024-03-13-doom-emacs.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2024-03-13 Wed 00:00:00]
2#+title: doom emacs & org mode setup
3#+description: Technical manual covering installation, configuration files, and usage procedures for Doom Emacs and Org-Mode targeting note management and task organization.
1#+date: [2024-03-13 Wed 00:00:00]
2#+title: Doom Emacs and Org Mode Setup
3#+description: How I set up Doom Emacs and Org Mode for notes and task management.
44#+slug: doom-emacs
5#+filetags: :emacs:
5#+filetags: :emacs:
66
77** Screenshots
88
content/blog/2024-03-15-self-hosting-ddns-updater.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2024-03-15 Fri 00:00:00]
2#+title: self hosting guide: ddns updater
3#+description: Step-by-step configuration guide for deploying a Dynamic DNS updater using Docker Compose, integrating with Cloudflare API, and securing with Nginx reverse proxy.
1#+date: [2024-03-15 Fri 00:00:00]
2#+title: Self-Hosting Guide: DDNS Updater
3#+description: Deploying a DDNS updater with Docker Compose and Cloudflare.
44#+slug: self-hosting-ddns-updater
5#+filetags: :linux:self-hosting:
5#+filetags: :linux:self-hosting:
66
77#+caption: DDNS Updater Web View
88#+attr_html: :alt An example of the DDNS Updater app running and showing that cleberg.net's IP has been updated on Cloudflare.
content/blog/2024-03-29-org-blog.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2024-03-29 Fri 00:00:00]
2#+title: blogging with emacs org mode and weblorg
3#+description: Instructional content for preparing and publishing blogs using Emacs Org-Mode, including setup of static site generators and content management workflows.
1#+date: [2024-03-29 Fri 00:00:00]
2#+title: Blogging with Emacs Org Mode and weblorg
3#+description: How I set up this blog using Emacs Org Mode and weblorg.
44#+slug: org-blog
5#+filetags: :emacs:web:
5#+filetags: :emacs:web:
66
77First and foremost, apologies to those who subscribe via RSS as I know that my
88feed duplicated itself when I moved this blog over to org-mode last night.
content/blog/2024-04-06-convert-onenote-to-markdown.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2024-04-06 Sat 00:00:00]
2#+title: onenote to org: escape the microsoft format
3#+description: Detailed conversion instructions to transform OneNote document files into Markdown or Org-Mode formats using Pandoc command-line utility on Windows systems.
1#+date: [2024-04-06 Sat 00:00:00]
2#+title: OneNote to Org: Escape the Microsoft Format
3#+description: Converting OneNote files to Markdown or Org Mode with Pandoc.
44#+slug: convert-onenote-to-markdown
5#+filetags: :emacs:
5#+filetags: :emacs:
66
77If you're looking to convert your OneNote content to another format, such as
88Markdown or Org-Mode, you're in luck. I use a solution that doesn't require
content/blog/2024-04-08-docker-local-web-server.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2024-04-08 Mon 00:00:00]
2#+title: local web dev server setup with docker & nginx
3#+description: Instructions for setting up a local web development environment employing Docker Desktop and Nginx web server to facilitate development and testing workflows.
1#+date: [2024-04-08 Mon 00:00:00]
2#+title: Local Web Dev Server with Docker and Nginx
3#+description: Setting up a local web server for development with Docker and Nginx.
44#+slug: docker-local-web-server
5#+filetags: :self-hosting:web:
5#+filetags: :self-hosting:web:
66
77When developing websites locally, I often use a simple Python web server to
88observe the changes.
content/blog/2024-04-18-mu4e.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2024-04-18 Thu 00:00:00]
2#+title: configuring mu4e with doom emacs on macos
3#+description: Stepwise procedure for installing, configuring, and using Mu4e email client within Doom Emacs on macOS for organized email management.
1#+date: [2024-04-18 Thu 00:00:00]
2#+title: mu4e with Doom Emacs on macOS
3#+description: Setting up mu4e for email inside Doom Emacs on macOS.
44#+slug: mu4e
5#+filetags: :emacs:linux:
5#+filetags: :emacs:linux:
66
77This post was heavily inspired by [[https://macowners.club/posts/email-emacs-mu4e-macos/][Email setup in Emacs with Mu4e on macOS]], but
88with my own tweaks for a single-account configuration and some Doom-specific
content/blog/2024-05-03-ubuntu-on-macos.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2024-05-03 Fri 00:00:00]
2#+title: orbstack on macos: running a full ubuntu linux environment
3#+description: Technical guide outlining the installation and operation of OrbStack to run Ubuntu Linux containers natively on macOS systems with performance considerations.
1#+date: [2024-05-03 Fri 00:00:00]
2#+title: OrbStack on macOS: Running Ubuntu
3#+description: Running a full Ubuntu environment on macOS using OrbStack.
44#+slug: ubuntu-on-macos
5#+filetags: :linux:
5#+filetags: :linux:
66
77Being a macOS user who previously used Linux for many years, I often find myself
88searching for alternatives to the Linux-native tools and methods that I had
content/blog/2024-06-19-deprecated-trusted-gpg-fix.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2024-06-19 Wednesday 08:00:00]
2#+title: migrating ubuntu gpg keys to trusted.gpg.d
3#+description: Technical instructions to relocate GPG keys from the deprecated trusted.gpg keyring to the supported trusted.gpg.d directory for system security maintenance.
1#+date: [2024-06-19 Wed 08:00:00]
2#+title: Ubuntu: Migrate GPG Keys to trusted.gpg.d
3#+description: Moving Ubuntu GPG keys from the deprecated trusted.gpg to trusted.gpg.d.
44#+slug: deprecated-trusted-gpg-fix
5#+filetags: :linux:
5#+filetags: :linux:
66
77** System Warning
88
content/blog/2024-07-11-emacs-on-ipad.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2024-07-11 Thursday 20:24:02]
2#+title: running emacs natively on apple silicon ipad
3#+description: Procedural instructions for installing Emacs on iPadOS devices with Apple Silicon architecture, including configuration and operational guidance.
1#+date: [2024-07-11 Thu 20:24:02]
2#+title: Running Emacs Natively on an Apple Silicon iPad
3#+description: Installing and running Emacs natively on an iPad with Apple Silicon.
44#+slug: emacs-on-ipad
5#+filetags: :emacs:
5#+filetags: :emacs:
66
77This post describes the process to install and use Emacs on the iPad Air 13-inch
88(M2). The iPad used in this post is running iPadOS 17.6.
content/blog/2024-08-11-org-mode-features.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2024-08-11 Sun 12:48:00]
2#+title: org mode features: what i actually use
3#+description: Detailed overview of essential Org-Mode functionalities focusing on task organization, note-taking, and workflow optimization.
1#+date: [2024-08-11 Sun 12:48:00]
2#+title: Org Mode Features: What I Actually Use
3#+description: The Org Mode features I actually reach for, and how I use them.
44#+slug: org-mode-features
5#+filetags: :emacs:
5#+filetags: :emacs:
66
77* Cycling (Folding)
88
content/blog/2024-08-25-n8n-sentiment-analysis.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2024-08-25 Sunday 09:45:30]
2#+title: automate email sentiment analysis with n8n
3#+description: Detailed procedural steps for configuring an n8n workflow to perform sentiment analysis on incoming email messages, enabling automated classification based on sentiment.
1#+date: [2024-08-25 Sun 09:45:30]
2#+title: Email Sentiment Analysis with n8n
3#+description: Using n8n to automatically classify incoming emails by sentiment.
44#+slug: n8n-sentiment-analysis
5#+filetags: :self-hosting:
5#+filetags: :self-hosting:
66
77* n8n
88
content/blog/2024-09-20-prometheus-grafana-cloud.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2024-09-20 Friday 13:38:52]
2#+title: prometheus grafana: monitoring without paying for the cloud tier
3#+description: Stepwise method for deploying Prometheus with Docker to monitor Linux servers and integrating Grafana Cloud for visualization and analysis of collected metrics.
1#+date: [2024-09-20 Fri 13:38:52]
2#+title: Prometheus and Grafana Cloud for Server Monitoring
3#+description: Monitoring Linux servers with Prometheus and visualizing in Grafana Cloud.
44#+slug: prometheus-grafana-cloud
5#+filetags: :linux:self-hosting:
5#+filetags: :linux:self-hosting:
66
77This tutorial will guide you through the process of:
88
content/blog/2024-09-23-self-hosting-transmission.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2024-09-23 Monday 19:52:20]
2#+title: self hosting guide: transmission bittorrent client
3#+description: Comprehensive setup instructions for installing and configuring the Transmission BitTorrent client on a Linux server, including securing remote access through Nginx reverse proxy.
1#+date: [2024-09-23 Mon 19:52:20]
2#+title: Self-Hosting Guide: Transmission
3#+description: Setting up Transmission on a Linux server with Nginx for remote access.
44#+slug: self-hosting-transmission
5#+filetags: :linux:self-hosting:
5#+filetags: :linux:self-hosting:
66
77#+begin_quote
88If you're torrenting anything sensitive, I *highly* recommend you use a VPN.
content/blog/2024-10-31-continue-ollama-code-assistant.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2024-10-31 Thursday 11:01:05]
2#+title: ollama code assistant setup in vs codium
3#+description: Technical overview and configuration guide for incorporating Ollama as a code assistance tool within VS Codium and VS Code editors to enhance development workflows.
1#+date: [2024-10-31 Thu 11:01:05]
2#+title: Ollama Code Assistant in VS Codium
3#+description: Setting up Ollama as a local code assistant in VS Codium.
44#+slug: continue-ollama-code-assistant
5#+filetags: :linux:
5#+filetags: :linux:
66
77* Background
88
content/blog/2024-12-27-self-hosting-the-lounge.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2024-12-29 Sun 17:45:00]
2#+title: self hosting guide: the lounge (irc)
3#+description: Step-by-step instructions for installing and configuring The Lounge IRC web client on Linux systems utilizing Docker Compose to provide persistent and secure chat access.
1#+date: [2024-12-29 Sun 17:45:00]
2#+title: Self-Hosting Guide: The Lounge (IRC)
3#+description: How to self-host The Lounge IRC client with Docker Compose.
44#+slug: self-hosting-the-lounge
5#+filetags: :linux:self-hosting:
5#+filetags: :linux:self-hosting:
66
77* The Lounge
88
content/blog/2025-01-23-self-hosting-tandoor.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2025-01-23 Thursday 20:44:45]
2#+title: self hosting guide: tandoor recipe manager
3#+description: Detailed tutorial on deploying Tandoor, an open-source recipe management application, including installation steps and configuration for self-hosted operation.
1#+date: [2025-01-23 Thu 20:44:45]
2#+title: Self-Hosting Guide: Tandoor
3#+description: Self-hosting Tandoor, an open-source recipe manager.
44#+slug: self-hosting-tandoor
5#+filetags: :linux:self-hosting:
5#+filetags: :linux:self-hosting:
66
77* Overview
88
content/blog/2025-02-11-obscura-vpn.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2025-02-11 Tuesday 11:40:00]
2#+title: obscura vpn: a two party protocol review
3#+description: Analytical review outlining the features, implementation, and security aspects of Obscura VPN's two-party protocol in conjunction with Mullvad VPN.
1#+date: [2025-02-11 Tue 11:40:00]
2#+title: Obscura VPN: A Two-Party Protocol Review
3#+description: A review of Obscura VPN and its two-party protocol with Mullvad.
44#+slug: obscura-vpn
5#+filetags: :security:
5#+filetags: :security:
66
77#+begin_quote
88This review is written at a high-level for users, not a technical deep-dive of
content/blog/2025-02-24-email-migration.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2025-02-25 Mon 19:20:05]
2#+title: email migration: 5000+ emails, proton to migadu
3#+description: Detailed instructions describing the process and considerations involved in transferring email data securely from Proton Mail to Migadu email hosting.
1#+date: [2025-02-25 Mon 19:20:05]
2#+title: Email Migration: 5,000+ Emails, Proton to Migadu
3#+description: Moving 5,000+ emails from Proton Mail to Migadu.
44#+slug: email-migration
5#+filetags: :privacy:
5#+filetags: :privacy:
66
77* The Setup
88
content/blog/2025-04-05-git-mirror.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2025-04-05 Saturday 23:04:54]
2#+title: automating github to gitlab repository sync
3#+description: Technical steps for setting up automated synchronization and mirroring of source code repositories from GitHub to GitLab for redundancy and repository management.
1#+date: [2025-04-05 Sat 23:04:54]
2#+title: Automating GitHub to GitLab Repository Sync
3#+description: Automatically mirroring GitHub repos to GitLab for redundancy.
44#+slug: git-mirror
5#+filetags: :self-hosting:
5#+filetags: :self-hosting:
66
77This is a short post detailing how I maintained repositories on GitHub and
88mirrors on GitLab - including both public and private repositories.
content/blog/2025-05-02-asahi-linux.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2025-05-02 Friday 21:10:00]
2#+title: asahi linux: linux on apple silicon, current state
3#+description: Documented analysis of installation procedure, system performance, and software compatibility for running Asahi Linux on the Apple M2 MacBook Pro 16-inch model.
1#+date: [2025-05-02 Fri 21:10:00]
2#+title: Asahi Linux: Linux on Apple Silicon
3#+description: What it's actually like to run Asahi Linux on an Apple M2.
44#+slug: asahi-linux
5#+filetags: :linux:
5#+filetags: :linux:
66
77* Trying out Asahi Linux
88
content/blog/2025-05-30-it-audit-career.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2025-05-30 Friday 10:53:28]
2#+title: it audit career: skills that matter vs. skills that look good
3#+description: Instructional content detailing actionable knowledge areas including artificial intelligence, blockchain, cloud computing, DevOps, and automation relevant for audit professionals.
1#+date: [2025-05-30 Fri 10:53:28]
2#+title: IT Audit Career: Skills That Matter
3#+description: What skills actually matter in IT audit vs. what just looks good on paper.
44#+slug: it-audit-career
5#+filetags: :audit:
5#+filetags: :audit:
66
77* Introduction
88
content/blog/2025-06-02-private-ios-apps.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2025-06-03 Tue 11:38:40]
2#+title: private ios apps: what i actually use
3#+description: Curated listing of iOS applications prioritized for privacy preservation and data security, targeted at users requiring minimal data exposure.
1#+date: [2025-06-03 Tue 11:38:40]
2#+title: Private iOS Apps: What I Actually Use
3#+description: The iOS apps I use that prioritize privacy.
44#+slug: private-ios-apps
5#+filetags: :linux:privacy:
5#+filetags: :linux:privacy:
66
77The world is evolving into a privacy nightmare, where our own devices are being
88used by numerous parties to constantly track and report on our activities. This
content/blog/2025-09-04-website-redesign.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2025-09-05 Fri 10:21:00]
2#+title: website redesign 2025: what changed
3#+description: Read this post to understand my latest website redesign and the context for the refresh.
1#+date: [2025-09-05 Fri 10:21:00]
2#+title: Website Redesign 2025
3#+description: An overview of the 2025 redesign of this site.
44#+slug: human-website-design
5#+filetags: :web:
5#+filetags: :web:
66
77#+begin_quote
88/Please note that this redesign is a work-in-progress and is not complete. The
content/blog/2025-09-25-minimalist-website-redesign.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2025-09-25 Thu 21:08:00]
2#+title: minimalist site: strip it down
3#+description: This post details a complete redesign of a blog post, stripping away extraneous CSS and HTML elements to prioritize readability and user experience.
1#+date: [2025-09-25 Thu 21:08:00]
2#+title: Minimalist Site: Strip It Down
3#+description: A complete redesign stripping away extraneous CSS and HTML for readability.
44#+slug: minimalist-website-redesign
5#+filetags: :web:
5#+filetags: :web:
66
77I know what you're thinking: "ANOTHER blog post about redesigning the website?"
88
content/blog/2025-10-03-privacy-toolkit.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2025-10-03 Fri 4:23:00]
2#+title: my privacy toolkit
3#+description: Learn about the tools I use to keep my life private and data secure.
1#+date: [2025-10-03 Fri 4:23:00]
2#+title: My Privacy Toolkit
3#+description: The tools I use to keep my data private.
44#+slug: privacy-toolkit
5#+filetags: :privacy:
5#+filetags: :privacy:
66
77* VPN
88
content/blog/2025-10-06-rocket-league-macos.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2025-10-06 Mon 13:11:00]
2#+title: playing rocket league on macos via crossover
3#+description: Learn how to play Rocket League on macOS via CrossOver.
1#+date: [2025-10-06 Mon 13:11:00]
2#+title: Rocket League on macOS via CrossOver
3#+description: Getting Rocket League running on macOS through CrossOver.
44#+slug: rocket-league-macos
5#+filetags: :linux:
5#+filetags: :linux:
66
77#+caption: Rocket League on macOS
88#+attr_html: :alt The Rocket League launch screen on macOS.
content/blog/2025-10-24-digital-garden.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2025-10-24 Fri 19:41:41]
2#+title: digital garden
3#+description: A post dedicated to digital gardens, an online space for personal knowledge management, creative exploration, and reflection.
1#+date: [2025-10-24 Fri 19:41:41]
2#+title: Digital Garden
3#+description: What a digital garden is and how I think about mine.
44#+slug: digital-garden
5#+filetags: :web:
5#+filetags: :web:
66
77* What's a Digital Garden?
88
content/blog/2025-11-02-aerc-macos.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2025-11-02 Sun 10:07:14]
2#+title: using aerc on macos
3#+description: Learn how I use aerc, a TUI email client, on macOS.
1#+date: [2025-11-02 Sun 10:07:14]
2#+title: Using aerc on macOS
3#+description: How I use aerc, a TUI email client, on macOS.
44#+slug: aerc-macos
5#+filetags: :linux:
5#+filetags: :linux:
66
77#+caption: aerc-mail
88#+attr_html: :alt An image of aerc with an email opened in the reader window.
content/blog/2025-11-13-wcag.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2025-11-14 Fri 19:46:30]
2#+title: wcag compliance: accessibility as a real constraint, not a checkbox
3#+description: Read on to learn more about how I've ensured my humble site is compliant with WCAG 2.
1#+date: [2025-11-14 Fri 19:46:30]
2#+title: WCAG Compliance: Accessibility as a Real Constraint
3#+description: How I've made this site compliant with WCAG 2.
44#+slug: wcag
5#+filetags: :audit:web:
5#+filetags: :audit:web:
66
77* WCAG 2
88
content/blog/2025-11-23-it-audit-ai.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2025-11-23 17:43:57]
2#+title: it audit ai: where it helps and where it's theater
3#+description: Learn how I'm currently using AI in my role in Technology Assurance (i.e., IT Audit) at KPMG.
1#+date: [2025-11-23 Sun 17:43:57]
2#+title: IT Audit and AI: Where It Helps and Where It's Theater
3#+description: How I'm currently using AI in my Technology Assurance role at KPMG.
44#+slug: it-audit-ai
5#+filetags: :audit:
5#+filetags: :audit:
66
77* My AI Toolkit
88
content/blog/2025-12-06-self-hosting-tor.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2025-12-06 Sat 14:13:00]
2#+title: self hosting guide: tor websites
3#+description: Learn how to host your own website on Tor with an Onion Address in a few short steps!
1#+date: [2025-12-06 Sat 14:13:00]
2#+title: Self-Hosting Guide: Tor Websites
3#+description: How to host a website on Tor with an onion address.
44#+slug: self-hosting-tor
5#+filetags: :linux:self-hosting:
5#+filetags: :linux:self-hosting:
66
77* Installation
88
content/blog/2025-12-20-self-hosting-home-assistant.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2025-12-20 Sat 20:27:08]
2#+title: self hosting guide: home assistant
3#+description: A guide to configuring and customizing Home Assistant.
1#+date: [2025-12-20 Sat 20:27:08]
2#+title: Self-Hosting Guide: Home Assistant
3#+description: Configuring and customizing Home Assistant.
44#+slug: self-hosting-home-assistant
5#+filetags: :linux:self-hosting:
5#+filetags: :linux:self-hosting:
66
77* Overview
88
content/blog/2026-01-31-emacs-carnival-2026-01-this-year-i-will.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2026-01-31 Sat 20:32:11]
2#+title: emacs carnival: “this year, i will...”
3#+description: My response to the Emacs Carnival post for January 2026.
1#+date: [2026-01-31 Sat 20:32:11]
2#+title: Emacs Carnival: This Year, I Will...
3#+description: My response to the Emacs Carnival prompt for January 2026.
44#+slug: emacs-carnival-2026-01-this-year-i-will
5#+filetags: :emacs:personal:
5#+filetags: :emacs:personal:
66
77This year in Emacs, I expect to do a lot. However, here are some actionable
88goals for myself that should have a positive impact as I start out 2026.
content/blog/2026-02-02-emacs-carnival-2026-02-completion.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2026-02-02 18:40:21]
2#+title: emacs carnival: "completion"
3#+description: My response to the Emacs Carnival post for February 2026.
1#+date: [2026-02-02 Mon 18:40:21]
2#+title: Emacs Carnival: Completion
3#+description: My response to the Emacs Carnival prompt for February 2026.
44#+slug: emacs-carnival-2026-02-completion
5#+filetags: :emacs:personal:
5#+filetags: :emacs:personal:
66
77I'm having a great time with the Emacs Carnival, as it has inspired me to write
88two posts in such a short time. It's been a much needed inspiration to write
content/blog/2026-02-07-indieweb-carnival-2026-02-intersecting-interests.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2026-02-07 Sat 17:46:00]
2#+title: indieweb carnival: "intersecting interests"
3#+description: Contrasting my passions with technology vs. natural hobbies.
1#+date: [2026-02-07 Sat 17:46:00]
2#+title: IndieWeb Carnival: Intersecting Interests
3#+description: Contrasting my passion for technology with my interest in natural hobbies.
44#+slug: indiweb-carnival-2026-02-intersecting-interests
5#+filetags: :personal:web:
5#+filetags: :personal:web:
66
77I thought about this topic for a long time today before starting to write this
88post, as I don't think of myself as someone with intersecting interests. I
content/blog/2026-02-08-gnu-stow.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2026-02-08 Sun 12:17:42]
2#+title: managing my dotfiles with gnu stow and git
3#+description: Learn how I use GNU Stow to manage my user dotfiles and configurations.
1#+date: [2026-02-08 Sun 12:17:42]
2#+title: Managing Dotfiles with GNU Stow and Git
3#+description: How I use GNU Stow to manage my dotfiles and configs across machines.
44#+slug: gnu-stow
5#+filetags: :emacs:linux:
5#+filetags: :emacs:linux:
66
77* What is GNU Stow?
88
content/blog/2026-02-12-automating-weblorg-deployments.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2026-02-12 Thu 20:26:32]
2#+title: weblorg deployments: automated, no github actions dependency
3#+description: Learn how I've automated all deployment for my org-mode blog with GitHub Actions and a custom Docker image.
1#+date: [2026-02-12 Thu 20:26:32]
2#+title: Automating weblorg Deployments
3#+description: How I automated deployment for this org-mode blog without GitHub Actions.
44#+slug: automating-weblorg-deployments
5#+filetags: :self-hosting:web:
5#+filetags: :self-hosting:web:
66
77As I've mentioned in previous posts, I utilize a unique pipeline to draft posts,
88compose my website, and to build and deploy the static files.
content/blog/2026-02-21-auditing-aws-iam.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2026-02-21 Sat 18:58:39]
2#+title: auditing aws iam users
3#+description: Learn how to audit IAM user assignments in AWS.
1#+date: [2026-02-21 Sat 18:58:39]
2#+title: Auditing AWS IAM Users
3#+description: How to audit IAM user assignments in AWS.
44#+slug: auditing-aws-iam
5#+filetags: :audit:
5#+filetags: :audit:
66
77If you've ever asked an IT team for a list of who has access to an AWS account,
88you've probably received a spreadsheet that was already out of date. Or worse,
content/blog/2026-02-21-auditing-aws-passwords.org +4 −4
@@ -1,8 +1,8 @@
1#+date: [2026-02-21 Sat 21:13:45]
2#+title: auditing aws passwords
3#+description: Learn how to audit passwords in AWS.
1#+date: [2026-02-21 Sat 21:13:45]
2#+title: Auditing AWS Passwords
3#+description: How to audit password policies and usage in AWS.
44#+slug: auditing-aws-passwords
5#+filetags: :audit:
5#+filetags: :audit:
66
77One of the first controls an IT Auditor learns is how to audit passwords in any
88number of IT systems. However, things have changed with the introduction of
content/blog/2026-03-03-auditing-aws-s3.org +5 −5
@@ -1,8 +1,8 @@
1#+date: [2026-03-03 Tue 18:50:23]
2#+title: auditing aws s3 buckets
3#+description: Learn how to audit AWS S3 buckets for public access.
1#+date: [2026-03-03 Tue 18:50:23]
2#+title: Auditing AWS S3 Buckets
3#+description: How to audit AWS S3 buckets for public access and misconfigurations.
44#+slug: auditing-aws-s3
5#+filetags: :audit:
5#+filetags: :audit:
66
77This is the latest in my series of posts on auditing AWS, a cloud platform that
88has existed for around two decades but can still be a mystery to auditors who
@@ -79,7 +79,7 @@ The reverse is also true. A bucket with no public policy and no public ACLs is
7979still at risk if PAB is missing or incomplete, because nothing is in place to
8080prevent a future policy or ACL change from exposing it.
8181
82M* What the Script Does
82* What the Script Does
8383
8484The script lists every bucket in the account, determines each bucket's region,
8585runs all three checks against it, and appends the results to a CSV file.
content/guides/index.org +1 −1
@@ -1,4 +1,4 @@
1#+title: guides
1#+title: Guides
22#+slug: index
33#+options: toc:nil
44
content/salary/index.org +1 −1
@@ -1,4 +1,4 @@
1#+title: salary
1#+title: Salary
22#+slug: index
33#+options: toc:nil
44
screenshots/dark.png deleted

Binary file not shown.

screenshots/light.png deleted

Binary file not shown.

tag_preview.py deleted −177
@@ -1,177 +0,0 @@
1#!/usr/bin/env python3
2"""
3Preview tag assignments for all blog posts.
4Run with --write to actually add #+filetags to org files.
5"""
6import re
7import sys
8from pathlib import Path
9
10CONTENT_DIR = Path("./content/blog")
11
12# Explicit overrides take priority over rules
13OVERRIDES = {
14 "2018-11-28-cpp-compiler": ["linux"],
15 "2019-12-16-password-security": ["security"],
16 "2020-07-26-business-analysis": ["audit"],
17 "2020-08-22-redirect-github-pages": ["web"],
18 "2020-09-22-internal-audit": ["audit"],
19 "2020-12-28-neon-drive": ["personal"],
20 "2020-12-29-zork": ["personal"],
21 "2021-08-25-audit-sampling": ["audit"],
22 "2021-12-04-cisa": ["audit"],
23 "2023-05-22-burnout": ["personal"],
24 "2023-06-20-audit-review-template": ["audit"],
25 "2023-08-18-agile-auditing": ["audit"],
26 "2025-05-30-it-audit-career": ["audit"],
27 "2025-11-13-wcag": ["audit", "web"],
28 "2025-11-23-it-audit-ai": ["audit"],
29 "2026-02-21-auditing-aws-iam": ["audit"],
30 "2026-02-21-auditing-aws-passwords": ["audit"],
31 "2026-03-03-auditing-aws-s3": ["audit"],
32 "2020-09-01-visual-recognition": ["linux"],
33 "2024-01-26-audit-dashboard": ["audit"],
34 "2023-09-19-audit-sql-scripts": ["audit"],
35 "2021-04-28-photography": ["personal"],
36 "2022-06-22-daily-poetry": ["personal"],
37 "2020-09-25-happiness-map": ["personal"],
38 "2022-03-03-financial-database": ["self-hosting"],
39 "2023-01-03-recent-website-changes": ["personal", "web"],
40 "2025-09-25-minimalist-website-redesign": ["web"],
41 "2026-02-07-indieweb-carnival-2026-02-intersecting-interests": ["personal", "web"],
42}
43
44TAG_RULES = {
45 "audit": [
46 "audit", "cisa", "ansoff",
47 ],
48 "emacs": [
49 "emacs", "org-mode", "org-blog", "mu4e", "doom-emacs",
50 "emacs-carnival", "gnu-stow",
51 ],
52 "linux": [
53 "linux", "ubuntu", "debian", "fedora", "alpine",
54 "customizing-ubuntu", "linux-software", "linux-display",
55 "mtp-linux", "serenity-os", "fedora-i3", "fedora-login",
56 "flatpak", "zfs", "ubuntu-emergency", "ubuntu-on-macos",
57 "steam-on-ntfs", "bash-it", "byobu", "scli",
58 "terminal-lifestyle", "curseradio", "st", "flac-to-opus",
59 "pinetime", "server-build", "macos", "macos-customization",
60 "deprecated-trusted-gpg", "exiftool", "graphene",
61 "asahi", "aerc", "rocket-league",
62 ],
63 "self-hosting": [
64 "self-hosting", "homelab", "vps-web-server", "git-server",
65 "plex", "nextcloud", "wireguard", "backblaze", "syncthing",
66 "docker", "n8n", "prometheus-grafana", "transmission",
67 "goaccess", "unifi", "git-mirror", "automating-weblorg",
68 ],
69 "security": [
70 "aes-encryption", "cryptography", "gnupg", "password",
71 "server-hardening", "ssh-mfa", "ufw", "hardening",
72 "authelia", "wireguard", "njalla-dns", "cloudflare-dns",
73 "ditching-cloudflare", "obscura-vpn",
74 ],
75 "privacy": [
76 "privacy", "graphene-os", "session-messenger", "fediverse",
77 "digital-minimalism", "privacy-com", "local-llm",
78 "email-migration", "dont-say-hello",
79 ],
80 "web": [
81 "nginx", "apache", "php", "css", "redirect", "website-redesign",
82 "gemini", "indieweb", "weblorg", "html", "digital-garden",
83 "tableau",
84 ],
85 "personal": [
86 "mediocrity", "burnout", "tuesday", "leaving-the-office",
87 "vaporwave", "video-game-sales", "reliable-notes",
88 "mass-unlike-tumblr", "changing-git-authors", "delete-gitlab",
89 "clone-github", "this-year-i-will", "completion",
90 "seum", "neon-drive", "zork",
91 ],
92}
93
94def assign_tags(slug: str, title: str) -> list[str]:
95 if slug in OVERRIDES:
96 return OVERRIDES[slug]
97 slug_lower = slug.lower()
98 title_lower = title.lower()
99 tags = []
100 for tag, patterns in TAG_RULES.items():
101 for pattern in patterns:
102 if pattern in slug_lower or pattern in title_lower:
103 if tag not in tags:
104 tags.append(tag)
105 break
106 return sorted(tags)
107
108def get_title(path: Path) -> str:
109 title_pat = re.compile(r"^#\+title:\s*(.+)$", re.IGNORECASE)
110 with path.open("r", encoding="utf-8") as f:
111 for line in f:
112 m = title_pat.match(line)
113 if m:
114 return m.group(1).strip()
115 return path.stem
116
117def has_filetags(path: Path) -> bool:
118 with path.open("r", encoding="utf-8") as f:
119 for line in f:
120 if re.match(r"^#\+filetags:", line, re.IGNORECASE):
121 return True
122 return False
123
124def write_filetags(path: Path, tags: list[str]):
125 tag_str = ":" + ":".join(tags) + ":"
126 content = path.read_text(encoding="utf-8")
127 slug_pat = re.compile(r"(#\+slug:\s*.+\n)", re.IGNORECASE)
128 m = slug_pat.search(content)
129 if m:
130 insert_at = m.end()
131 new_content = content[:insert_at] + f"#+filetags: {tag_str}\n" + content[insert_at:]
132 path.write_text(new_content, encoding="utf-8")
133 return True
134 return False
135
136write_mode = "--write" in sys.argv
137
138untagged = []
139rows = []
140for org_path in sorted(CONTENT_DIR.glob("*.org")):
141 slug = org_path.stem
142 title = get_title(org_path)
143 tags = assign_tags(slug, title)
144 if not tags:
145 untagged.append((slug, title))
146 rows.append((slug, title, tags))
147
148print(f"{'SLUG':<50} {'TAGS'}")
149print("-" * 85)
150for slug, title, tags in rows:
151 tag_str = ", ".join(tags) if tags else "-- UNTAGGED --"
152 print(f"{slug:<50} {tag_str}")
153
154print(f"\nTotal: {len(rows)} posts | Untagged: {len(untagged)}")
155if untagged:
156 print("\nUntagged posts:")
157 for slug, title in untagged:
158 print(f" {slug}")
159
160if write_mode:
161 written = 0
162 skipped = 0
163 for org_path in sorted(CONTENT_DIR.glob("*.org")):
164 slug = org_path.stem
165 title = get_title(org_path)
166 tags = assign_tags(slug, title)
167 if not tags:
168 skipped += 1
169 continue
170 if has_filetags(org_path):
171 skipped += 1
172 continue
173 if write_filetags(org_path, tags):
174 written += 1
175 print(f"\nWrote filetags to {written} files, skipped {skipped}.")
176else:
177 print("\nRun with --write to apply filetags to org files.")
theme/static/favicon.svg deleted −14
@@ -1,14 +0,0 @@
1<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1500 1499.999933">
2 <style>
3 path { fill: #111111; }
4 @media (prefers-color-scheme: dark) { path { fill: #ffffff; } }
5 </style>
6 <defs>
7 <clipPath id="c">
8 <path d="M 246.484375 243.425781 L 1253.730469 243.425781 L 1253.730469 1256.457031 L 246.484375 1256.457031 Z" clip-rule="nonzero"/>
9 </clipPath>
10 </defs>
11 <g clip-path="url(#c)">
12 <path fill-rule="nonzero" d="M 562.695312 907.28125 C 514.085938 881.21875 396.300781 818.089844 368.757812 795.410156 C 351.777344 781.4375 345.167969 771.671875 345.152344 765.117188 C 345.152344 762.648438 346.535156 760.578125 348.84375 758.890625 C 352.042969 756.558594 356.808594 754.898438 362.398438 753.796875 C 381.738281 750.015625 408.554688 753.210938 419.015625 759.636719 C 433.589844 783.507812 445.734375 801.542969 451.113281 804.4375 C 442.617188 780.46875 429.820312 749.761719 426.273438 724.375 C 422.824219 699.628906 421.839844 674.320312 423.527344 648.550781 C 424.203125 638.359375 425.214844 628.765625 426.183594 619.714844 C 431 574.277344 434.464844 541.792969 390.460938 495.28125 C 384.738281 489.226562 377.890625 482.316406 370.613281 474.960938 C 321.140625 424.960938 250.707031 353.765625 261.152344 267.800781 C 315.074219 306.644531 342.925781 327.1875 407.71875 334.761719 C 431.320312 337.511719 456.527344 336.820312 478.058594 329.164062 C 516.382812 315.507812 544.5625 284.574219 556.761719 269.183594 C 585.796875 331.273438 570.703125 413.90625 557.585938 485.699219 C 555.382812 497.800781 553.21875 509.597656 551.347656 520.890625 L 550.988281 518.554688 C 548.242188 492 533.292969 467.066406 523.683594 458.480469 C 543.953125 487.382812 544.246094 547.246094 546.410156 585.914062 C 548.929688 630.609375 564.742188 669.382812 589.390625 702.851562 C 598.3125 714.96875 608.402344 726.378906 619.417969 737.101562 C 631.074219 748.449219 648.730469 762.6875 668.375 775.730469 C 694.527344 793.078125 719.457031 807.15625 744.265625 818.808594 C 813.890625 851.503906 901.886719 873.054688 977.726562 889.058594 C 1010.898438 896.054688 1096.996094 920.363281 1158.511719 953.554688 C 1194.910156 973.207031 1222.335938 995.527344 1223.371094 1018.152344 C 1224.523438 1043.605469 1204.757812 1067.1875 1177.46875 1086.679688 C 1137.429688 1115.277344 1081.878906 1134.636719 1050.003906 1139.148438 C 1031.6875 1141.75 1013.195312 1143.371094 994.636719 1144.058594 C 982.558594 1144.5 970.476562 1144.539062 958.371094 1144.191406 C 968.617188 1130.5 979.1875 1114.320312 979.929688 1104.875 C 941.871094 1141.261719 909.90625 1170.003906 864.242188 1199.265625 C 825.28125 1224.238281 781.023438 1245.164062 744.679688 1242.683594 C 727.714844 1241.515625 717.398438 1236.394531 712.25 1228.964844 C 708.503906 1223.5625 707.335938 1216.6875 708.210938 1209.125 C 709.167969 1200.882812 712.5 1191.832031 717.585938 1182.796875 C 731.828125 1157.542969 759.238281 1133.378906 786.851562 1127.394531 C 807.09375 1134.054688 858.996094 1138.113281 869.710938 1127.019531 C 850.992188 1126.398438 825.226562 1126.160156 785.628906 1112.675781 C 726.160156 1092.4375 669.730469 1062.9375 619.5 1025.476562 C 570.769531 989.117188 527.917969 945.246094 493.855469 895.03125 C 490.457031 890.042969 487.257812 885.117188 484.230469 880.289062 C 512.519531 895.828125 553.472656 909.324219 562.695312 907.28125 Z M 849.492188 843.15625 C 822.199219 835.515625 746.46875 809.984375 712.699219 787.941406 C 727.59375 784.449219 741.570312 775.574219 755.640625 766.617188 C 778.648438 751.992188 801.984375 737.167969 827.550781 750.769531 C 865.59375 771.007812 855.625 821.660156 849.492188 843.15625 Z M 1187.714844 1095.996094 C 1193.289062 1108.085938 1206.632812 1127.722656 1213.546875 1132.421875 C 1206.738281 1121.804688 1197.832031 1107.753906 1195.359375 1090.117188 C 1220.78125 1069.574219 1238.171875 1044.957031 1236.910156 1017.554688 C 1236.273438 1003.515625 1228.519531 990.085938 1215.964844 977.492188 C 1227.179688 964.300781 1238.597656 955.117188 1253.757812 947.238281 C 1236.328125 950.964844 1222.746094 958.582031 1210.03125 971.890625 C 1197.898438 961.117188 1182.367188 950.980469 1165.015625 941.609375 C 1102.1875 907.703125 1014.351562 882.890625 980.527344 875.761719 C 940.914062 867.402344 901.410156 858.167969 862.488281 846.980469 C 869.40625 822.773438 880.914062 763.816406 833.9375 738.800781 C 801.347656 721.457031 774.664062 738.429688 748.339844 755.164062 C 714.078125 776.953125 704.867188 785.246094 675.054688 764.835938 C 645.808594 744.8125 620.042969 721.589844 600.316406 694.808594 C 569.453125 652.917969 553.351562 602.132812 561.96875 541.046875 C 564.328125 524.25 567.570312 506.546875 570.925781 488.140625 C 585.132812 410.402344 601.589844 320.296875 563.734375 253.046875 L 558.328125 243.4375 L 552.183594 252.632812 C 552.089844 252.765625 521.253906 299.34375 473.464844 316.371094 C 454.113281 323.269531 431.039062 323.839844 409.285156 321.292969 C 344.542969 313.730469 305.648438 285.066406 251.222656 245.695312 L 249.367188 255.355469 C 230.609375 352.796875 307.546875 430.535156 360.976562 484.542969 C 367.878906 491.511719 374.386719 498.078125 380.570312 504.636719 C 420.316406 546.636719 417.140625 576.492188 412.707031 618.253906 C 411.726562 627.359375 410.703125 637.019531 410.011719 647.636719 C 408.25 674.414062 409.269531 700.664062 412.839844 726.246094 C 413.664062 732.140625 414.621094 738.003906 415.707031 743.84375 C 400.136719 739 377.105469 737.089844 359.808594 740.472656 C 352.363281 741.933594 345.738281 744.363281 340.839844 747.929688 C 335.050781 752.152344 331.585938 757.804688 331.585938 765.128906 C 331.613281 775.546875 339.617188 789.015625 360.15625 805.921875 C 375.710938 818.742188 417.804688 843.34375 460.855469 867.351562 C 464.039062 873.097656 467.453125 878.921875 471.089844 884.828125 C 474.886719 890.996094 478.734375 896.941406 482.613281 902.675781 C 517.539062 954.148438 561.460938 999.121094 611.414062 1036.371094 C 658.433594 1071.457031 710.828125 1099.710938 766.101562 1120.132812 C 741.265625 1131.347656 718.578125 1153.363281 705.757812 1176.121094 C 699.824219 1186.632812 695.921875 1197.433594 694.738281 1207.558594 C 693.503906 1218.375 695.347656 1228.417969 701.085938 1236.699219 C 708.519531 1247.433594 722.175781 1254.761719 743.75 1256.234375 C 810.464844 1260.796875 899.523438 1194.117188 943.382812 1157.15625 C 960.628906 1158.085938 977.910156 1158.246094 995.15625 1157.621094 C 1014.125 1156.917969 1033.054688 1155.246094 1051.890625 1152.578125 C 1095.21875 1146.4375 1152.65625 1121.753906 1187.714844 1095.996094"/>
13 </g>
14</svg>
\ No newline at end of file
theme/static/koi-hr.svg deleted −7
@@ -1,7 +0,0 @@
1<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1500 1500">
2 <style>
3 path { fill: #111111; }
4 @media (prefers-color-scheme: dark) { path { fill: #F0EDE8; } }
5 </style>
6 <path fill-rule="nonzero" d="M 562.695312 907.28125 C 514.085938 881.21875 396.300781 818.089844 368.757812 795.410156 C 351.777344 781.4375 345.167969 771.671875 345.152344 765.117188 C 345.152344 762.648438 346.535156 760.578125 348.84375 758.890625 C 352.042969 756.558594 356.808594 754.898438 362.398438 753.796875 C 381.738281 750.015625 408.554688 753.210938 419.015625 759.636719 C 433.589844 783.507812 445.734375 801.542969 451.113281 804.4375 C 442.617188 780.46875 429.820312 749.761719 426.273438 724.375 C 422.824219 699.628906 421.839844 674.320312 423.527344 648.550781 C 424.203125 638.359375 425.214844 628.765625 426.183594 619.714844 C 431 574.277344 434.464844 541.792969 390.460938 495.28125 C 384.738281 489.226562 377.890625 482.316406 370.613281 474.960938 C 321.140625 424.960938 250.707031 353.765625 261.152344 267.800781 C 315.074219 306.644531 342.925781 327.1875 407.71875 334.761719 C 431.320312 337.511719 456.527344 336.820312 478.058594 329.164062 C 516.382812 315.507812 544.5625 284.574219 556.761719 269.183594 C 585.796875 331.273438 570.703125 413.90625 557.585938 485.699219 C 555.382812 497.800781 553.21875 509.597656 551.347656 520.890625 L 550.988281 518.554688 C 548.242188 492 533.292969 467.066406 523.683594 458.480469 C 543.953125 487.382812 544.246094 547.246094 546.410156 585.914062 C 548.929688 630.609375 564.742188 669.382812 589.390625 702.851562 C 598.3125 714.96875 608.402344 726.378906 619.417969 737.101562 C 631.074219 748.449219 648.730469 762.6875 668.375 775.730469 C 694.527344 793.078125 719.457031 807.15625 744.265625 818.808594 C 813.890625 851.503906 901.886719 873.054688 977.726562 889.058594 C 1010.898438 896.054688 1096.996094 920.363281 1158.511719 953.554688 C 1194.910156 973.207031 1222.335938 995.527344 1223.371094 1018.152344 C 1224.523438 1043.605469 1204.757812 1067.1875 1177.46875 1086.679688 C 1137.429688 1115.277344 1081.878906 1134.636719 1050.003906 1139.148438 C 1031.6875 1141.75 1013.195312 1143.371094 994.636719 1144.058594 C 982.558594 1144.5 970.476562 1144.539062 958.371094 1144.191406 C 968.617188 1130.5 979.1875 1114.320312 979.929688 1104.875 C 941.871094 1141.261719 909.90625 1170.003906 864.242188 1199.265625 C 825.28125 1224.238281 781.023438 1245.164062 744.679688 1242.683594 C 727.714844 1241.515625 717.398438 1236.394531 712.25 1228.964844 C 708.503906 1223.5625 707.335938 1216.6875 708.210938 1209.125 C 709.167969 1200.882812 712.5 1191.832031 717.585938 1182.796875 C 731.828125 1157.542969 759.238281 1133.378906 786.851562 1127.394531 C 807.09375 1134.054688 858.996094 1138.113281 869.710938 1127.019531 C 850.992188 1126.398438 825.226562 1126.160156 785.628906 1112.675781 C 726.160156 1092.4375 669.730469 1062.9375 619.5 1025.476562 C 570.769531 989.117188 527.917969 945.246094 493.855469 895.03125 C 490.457031 890.042969 487.257812 885.117188 484.230469 880.289062 C 512.519531 895.828125 553.472656 909.324219 562.695312 907.28125 Z M 849.492188 843.15625 C 822.199219 835.515625 746.46875 809.984375 712.699219 787.941406 C 727.59375 784.449219 741.570312 775.574219 755.640625 766.617188 C 778.648438 751.992188 801.984375 737.167969 827.550781 750.769531 C 865.59375 771.007812 855.625 821.660156 849.492188 843.15625 Z M 1187.714844 1095.996094 C 1193.289062 1108.085938 1206.632812 1127.722656 1213.546875 1132.421875 C 1206.738281 1121.804688 1197.832031 1107.753906 1195.359375 1090.117188 C 1220.78125 1069.574219 1238.171875 1044.957031 1236.910156 1017.554688 C 1236.273438 1003.515625 1228.519531 990.085938 1215.964844 977.492188 C 1227.179688 964.300781 1238.597656 955.117188 1253.757812 947.238281 C 1236.328125 950.964844 1222.746094 958.582031 1210.03125 971.890625 C 1197.898438 961.117188 1182.367188 950.980469 1165.015625 941.609375 C 1102.1875 907.703125 1014.351562 882.890625 980.527344 875.761719 C 940.914062 867.402344 901.410156 858.167969 862.488281 846.980469 C 869.40625 822.773438 880.914062 763.816406 833.9375 738.800781 C 801.347656 721.457031 774.664062 738.429688 748.339844 755.164062 C 714.078125 776.953125 704.867188 785.246094 675.054688 764.835938 C 645.808594 744.8125 620.042969 721.589844 600.316406 694.808594 C 569.453125 652.917969 553.351562 602.132812 561.96875 541.046875 C 564.328125 524.25 567.570312 506.546875 570.925781 488.140625 C 585.132812 410.402344 601.589844 320.296875 563.734375 253.046875 L 558.328125 243.4375 L 552.183594 252.632812 C 552.089844 252.765625 521.253906 299.34375 473.464844 316.371094 C 454.113281 323.269531 431.039062 323.839844 409.285156 321.292969 C 344.542969 313.730469 305.648438 285.066406 251.222656 245.695312 L 249.367188 255.355469 C 230.609375 352.796875 307.546875 430.535156 360.976562 484.542969 C 367.878906 491.511719 374.386719 498.078125 380.570312 504.636719 C 420.316406 546.636719 417.140625 576.492188 412.707031 618.253906 C 411.726562 627.359375 410.703125 637.019531 410.011719 647.636719 C 408.25 674.414062 409.269531 700.664062 412.839844 726.246094 C 413.664062 732.140625 414.621094 738.003906 415.707031 743.84375 C 400.136719 739 377.105469 737.089844 359.808594 740.472656 C 352.363281 741.933594 345.738281 744.363281 340.839844 747.929688 C 335.050781 752.152344 331.585938 757.804688 331.585938 765.128906 C 331.613281 775.546875 339.617188 789.015625 360.15625 805.921875 C 375.710938 818.742188 417.804688 843.34375 460.855469 867.351562 C 464.039062 873.097656 467.453125 878.921875 471.089844 884.828125 C 474.886719 890.996094 478.734375 896.941406 482.613281 902.675781 C 517.539062 954.148438 561.460938 999.121094 611.414062 1036.371094 C 658.433594 1071.457031 710.828125 1099.710938 766.101562 1120.132812 C 741.265625 1131.347656 718.578125 1153.363281 705.757812 1176.121094 C 699.824219 1186.632812 695.921875 1197.433594 694.738281 1207.558594 C 693.503906 1218.375 695.347656 1228.417969 701.085938 1236.699219 C 708.519531 1247.433594 722.175781 1254.761719 743.75 1256.234375 C 810.464844 1260.796875 899.523438 1194.117188 943.382812 1157.15625 C 960.628906 1158.085938 977.910156 1158.246094 995.15625 1157.621094 C 1014.125 1156.917969 1033.054688 1155.246094 1051.890625 1152.578125 C 1095.21875 1146.4375 1152.65625 1121.753906 1187.714844 1095.996094"/>
7</svg>
theme/static/styles.css +11 −596
@@ -1,597 +1,12 @@
1@import url('tokens.css');
2
3/* ============================================================
4 HOMEPAGE INTRO
5 ============================================================ */
6.homepage-intro {
7 max-width: var(--prose-w);
8 margin: 3rem 0;
9 margin-top: 1rem;
10 font-family: var(--font-serif);
11 font-size: var(--text-body);
12 line-height: var(--lh-body);
13}
14.homepage-intro p { margin-bottom: 1.1rem; }
15.homepage-intro p:first-child {
16 font-size: 0.9rem;
17 text-transform: uppercase;
18 letter-spacing: 0.1em;
19 font-family: var(--font-sans);
20 color: var(--meta);
21 margin-bottom: 0.5rem;
22}
23.homepage-intro p:nth-child(2) {
24 font-size: 1.3rem;
25 font-weight: 700;
26 letter-spacing: -0.01em;
27 color: var(--fg);
28 margin-bottom: 1.5rem;
29}
30
31/* ============================================================
32 RESET & BASE
33 ============================================================ */
34*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
35
36body {
37 background: var(--bg);
38 color: var(--fg);
39 font-family: var(--font-sans);
40 font-size: var(--text-body);
41 line-height: var(--lh-body);
42 -webkit-font-smoothing: antialiased;
43 text-rendering: optimizeLegibility;
44}
45
46/* Full-bleed header — border and nav span 100vw */
47header {
48 width: 100%;
49}
50
51/* Centered content column */
52main,
53footer,
54header {
55 max-width: var(--outer-w);
56 margin: 0 auto;
57 padding-left: var(--pad);
58 padding-right: var(--pad);
59}
60footer { padding-bottom: 3rem; }
61
62/* Prose constraint — applied to article/page body text only */
63.prose {
64 max-width: var(--prose-w);
65}
66
67/* ============================================================
68 MASTHEAD
69 ============================================================ */
70.masthead {
71 border-top: 2px solid var(--fg);
72 padding-top: 1.5rem;
73 padding-bottom: 0;
74 padding-left: var(--pad);
75 padding-right: var(--pad);
76}
77
78.masthead-title {
79 display: block;
80 font-family: var(--font-serif);
81 font-size: var(--text-display);
82 font-weight: 700;
83 line-height: var(--lh-display);
84 letter-spacing: -0.03em;
85 text-decoration: none;
86 color: var(--fg);
87 margin-bottom: 1.25rem;
88}
89.masthead-title:hover { color: var(--accent); background: none; }
90
91.masthead-subtitle {
92 font-family: var(--font-sans);
93 font-size: var(--text-xs);
94 letter-spacing: 0.12em;
95 color: var(--meta);
96 text-transform: lowercase;
97 margin-bottom: 1rem;
98}
99
100/* ============================================================
101 NAV STRIP — full outer width, equal cells
102 ============================================================ */
103.masthead nav ul {
104 list-style: none;
105 display: flex;
106}
107.masthead nav li { flex: 1; }
108.masthead nav a {
109 display: block;
110 text-align: center;
111 padding: 0.55rem 0;
112 font-size: var(--text-xs);
113 font-weight: 700;
114 text-transform: uppercase;
115 letter-spacing: 0.16em;
116 text-decoration: none;
117 color: var(--meta);
118 border: 1px solid var(--border-soft);
119 transition: color 0.1s, background 0.1s;
120}
121.masthead nav a:hover { color: var(--bg); background: var(--fg); }
122
123/* ============================================================
124 MAIN CONTENT AREA
125 ============================================================ */
126main { padding-top: 2rem; }
127
128/* ============================================================
129 KOI HR
130 ============================================================ */
131hr {
132 border: none;
133 height: 2.5rem;
134 position: relative;
135 display: flex;
136 align-items: center;
137 justify-content: center;
138 background-image: url('koi-hr.svg');
139 background-repeat: no-repeat;
140 background-position: center;
141 background-size: auto 100%;
142 margin: 3rem 0;
143}
144hr::before, hr::after {
145 content: '';
146 position: absolute;
147 top: 50%;
148 transform: translateY(-50%);
149 width: calc(50% - 2rem);
150 height: 1px;
151 background: var(--border-soft);
152}
153hr::before { left: 0; }
154hr::after { right: 0; }
155
156/* ============================================================
157 FOOTER
158 ============================================================ */
159footer {
160 font-size: var(--text-xs);
161 text-transform: uppercase;
162 letter-spacing: 0.14em;
163 color: var(--meta);
164 display: flex;
165 flex-direction: column;
166 gap: 0.4rem;
167}
168footer a { color: var(--meta); text-decoration: none; transition: color 0.1s; }
169footer a:hover { color: var(--fg); background: none; }
170
171/* ============================================================
172 TYPOGRAPHY
173 ============================================================ */
174h1, h2, h3, h4 {
175 font-family: var(--font-serif);
176 font-weight: 700;
177 letter-spacing: -0.02em;
178 line-height: 1.1;
179}
180
181/* Page-level h1 (blog list, garden, guides) */
182h1 {
183 font-size: var(--text-h1);
184 margin-bottom: 0.5rem;
185}
186
187/* Article display title — larger, tighter */
188.article-title {
189 font-family: var(--font-serif);
190 font-size: clamp(2.4rem, 5vw, 3.6rem);
191 font-weight: 700;
192 line-height: 1.05;
193 letter-spacing: -0.03em;
194 margin: 0.4rem 0 0;
195}
196
197h2 {
198 font-size: var(--text-h2);
199 border-left: 1px solid var(--accent);
200 padding-left: 0.75rem;
201 margin-top: 2.5rem;
202 margin-bottom: 0.4rem;
203}
204h3 { font-size: 1.05rem; margin-top: 2rem; margin-bottom: 0.3rem; }
205
206p { margin-bottom: 1.2rem; }
207
208/* Accent ONLY on links and h2 bar — nowhere else */
209a {
210 color: var(--accent);
211 text-decoration: underline;
212 text-underline-offset: 3px;
213 transition: background 0.1s, color 0.1s;
214}
215a:hover { background: var(--accent); color: var(--bg); text-decoration: none; }
216
217/* ============================================================
218 SECTION LABEL — uppercase eyebrow text
219 ============================================================ */
220.label {
221 display: block;
222 font-size: var(--text-xs);
223 font-weight: 700;
224 text-transform: uppercase;
225 letter-spacing: 0.16em;
226 color: var(--meta);
227 border-bottom: 1px solid var(--fg);
228 padding-bottom: 0.5rem;
229 margin-bottom: 0;
230}
231
232/* ============================================================
233 INFO STRIP — homepage identity block
234 ============================================================ */
235
236
237/* ============================================================
238 POST LIST — numbered, full outer width
239 ============================================================ */
240.post-list {
241 list-style: none;
242 counter-reset: posts;
243}
244.post-list-item {
245 counter-increment: posts;
246 display: grid;
247 grid-template-columns: 2.5rem 1fr 7rem;
248 align-items: baseline;
249 gap: 0 1rem;
250 padding: 0.75rem 0;
251 border-bottom: 1px solid var(--border-soft);
252}
253.post-list-item:first-child { border-top: 1px solid var(--border-soft); }
254.post-list-item::before {
255 content: counter(posts, decimal-leading-zero);
256 font-family: var(--font-mono);
257 font-size: var(--text-xs);
258 color: var(--meta);
259 letter-spacing: 0.04em;
260 grid-column: 1;
261}
262.post-list-item a {
263 font-size: var(--text-sm);
264 justify-self: start;
265}
266.post-list-item time {
267 font-size: var(--text-xs);
268 font-family: var(--font-mono);
269 color: var(--meta);
270 text-align: right;
271 white-space: nowrap;
272 letter-spacing: 0.04em;
273}
274
275/* Year separator — full-width label, resets counter display */
276.post-list-year {
277 display: block;
278 font-family: var(--font-sans);
279 font-size: var(--text-xs);
280 font-weight: 700;
281 text-transform: uppercase;
282 letter-spacing: 0.14em;
283 color: var(--meta);
284 padding: 1.5rem 0 0.4rem;
285 counter-increment: none;
286}
287
288.all-posts-link {
289 display: inline-block;
290 margin-top: 1.5rem;
291 font-size: var(--text-xs);
292 font-weight: 700;
293 text-transform: uppercase;
294 letter-spacing: 0.12em;
295}
296
297/* ============================================================
298 ARTICLE — post page
299 ============================================================ */
300.article-dateline {
301 font-family: var(--font-mono);
302 font-size: var(--text-xs);
303 text-transform: uppercase;
304 letter-spacing: 0.14em;
305 color: var(--meta);
306 margin-bottom: 0.35rem;
307}
308
309.article-standfirst {
310 font-family: var(--font-serif);
311 font-size: 1.15rem;
312 line-height: 1.55;
313 color: var(--fg-soft);
314 padding: 1.25rem 0;
315 border-top: 1px solid var(--border-soft);
316 border-bottom: 1px solid var(--fg);
317 margin-top: 1rem;
318 max-width: var(--prose-w);
319}
320
321.article-body {
322 font-family: var(--font-serif);
323 font-size: var(--text-body);
324 line-height: var(--lh-body);
325 max-width: var(--prose-w);
326 margin-top: 2.5rem;
327}
328.article-body p { margin-bottom: 1.3rem; }
329
330.reply-link {
331 max-width: var(--prose-w);
332 margin-top: 4rem;
333 padding-top: 1.5rem;
334 border-top: 1px solid var(--border-soft);
335 font-size: var(--text-xs);
336 font-family: var(--font-sans);
337 text-transform: uppercase;
338 letter-spacing: 0.12em;
339}
340
341/* ============================================================
342 GENERIC PAGE (about, uses, etc.)
343 ============================================================ */
344.page-body {
345 font-family: var(--font-serif);
346 font-size: var(--text-body);
347 line-height: var(--lh-body);
348 max-width: var(--prose-w);
349 margin-top: 2rem;
350}
351.page-body p { margin-bottom: 1.3rem; }
352
353/* ============================================================
354 BLOG ARCHIVE
355 ============================================================ */
356.blog-meta {
357 font-size: var(--text-sm);
358 color: var(--meta);
359 margin: 0.75rem 0 2rem;
360}
361.blog-meta code {
362 font-size: var(--text-xs);
363 background: var(--code-bg);
364 padding: 0.1rem 0.35rem;
365 font-family: var(--font-mono);
366}
367
368/* Year separators in post list */
369.post-list-year {
370 font-family: var(--font-serif);
371 font-size: var(--text-xs);
372 font-weight: 700;
373 text-transform: uppercase;
374 letter-spacing: 0.14em;
375 color: var(--meta);
376 padding: 1.25rem 0 0.5rem;
377 list-style: none;
378 grid-column: 1 / -1;
379}
380
381/* Restore list styling inside content areas */
382.article-body ul,
383.article-body ol,
384.page-body ul,
385.page-body ol {
386 padding-left: 1.5rem;
387 margin-bottom: 1.2rem;
388}
389.article-body li,
390.page-body li {
391 margin-bottom: 0.3rem;
392}
393.article-body ul ul,
394.article-body ol ol,
395.page-body ul ul,
396.page-body ol ol {
397 margin-bottom: 0;
398}
399
400/* ============================================================
401 GARDEN
402 ============================================================ */
403.garden-index { list-style: none; }
404.garden-index li {
405 display: flex;
406 flex-direction: column;
407 gap: 0.15rem;
408 padding: 0.8rem 0;
409 border-bottom: 1px solid var(--border-soft);
410}
411.garden-index li:first-child { border-top: 1px solid var(--border-soft); }
412.garden-index a { font-size: var(--text-sm); }
413.garden-desc { font-size: var(--text-xs); color: var(--meta); }
414
415/* ============================================================
416 APP CARDS
417 ============================================================ */
418.app-card {
419 display: flex;
420 gap: 1.25rem;
421 align-items: flex-start;
422 padding: 1.25rem 0;
423 border-bottom: 1px solid var(--border-soft);
424}
425.app-card:first-of-type { border-top: 1px solid var(--border-soft); }
426.app-icon { width: 52px; height: 52px; border-radius: 12px; flex-shrink: 0; filter: none !important; margin: 0; display: block; }
427.app-card a:has(.app-icon):hover { background: none; }
428.app-info { display: flex; flex-direction: column; gap: 0.2rem; }
429.app-title { font-family: var(--font-sans); font-weight: 700; font-size: var(--text-sm); }
430.app-subtitle { font-size: var(--text-xs); color: var(--meta); }
431.app-links { font-size: var(--text-xs); margin-top: 0.3rem; }
432
433/* ============================================================
434 CODE & PRE
435 ============================================================ */
436pre {
437 padding: 1.25rem;
438 border-left: 1px solid var(--border-soft);
439 background: var(--code-bg);
440 overflow-x: auto;
441 font-size: var(--text-sm);
442 margin: 1.75rem 0;
443 line-height: 1.6;
444}
445code {
446 font-family: var(--font-mono);
447 background: var(--code-bg);
448 padding: 0.15rem 0.4rem;
449 font-size: 0.875em;
450}
451pre code { background: none; padding: 0; font-size: inherit; }
452
453/* ============================================================
454 BLOCKQUOTE — intentional Org-mode delimiters
455 ============================================================ */
456blockquote {
457 font-style: italic;
458 margin: 1.75rem 0;
459 padding: 0.75rem 1rem;
460 border-left: 1px solid var(--border-soft);
461 background: var(--code-bg);
462}
463blockquote p:last-child { margin-bottom: 0; }
1body { max-width: 800px; margin: 0 auto; }
2nav ul { list-style: none; padding: 0; display: flex; flex-direction: row; }
3nav ul li { padding-right: 0.5rem;}
4img { max-width: 100%; }
5.post-list-item { display: flexbox; list-style: none; }
6.post-list-item time { padding-right: 0.5rem; }
7.post-list-year { list-style: none; margin-top: 1rem; margin-bottom: 0.5rem; font-weight: bold; }
8.skip-link { display: none; }
9footer { margin: 2rem 0;}
10pre, blockquote { margin: 1rem 0; padding: 0.5rem; background-color: lightgrey; }
46411blockquote p { margin: 0; }
465blockquote::before {
466 content: "#+begin_quote";
467 display: block;
468 color: var(--meta);
469 font-style: normal;
470 font-size: var(--text-xs);
471 font-family: var(--font-mono);
472 letter-spacing: 0.04em;
473 margin-bottom: 0.5rem;
474}
475blockquote::after {
476 content: "#+end_quote";
477 display: block;
478 color: var(--meta);
479 font-style: normal;
480 font-size: var(--text-xs);
481 font-family: var(--font-mono);
482 letter-spacing: 0.04em;
483 margin-top: 0.5rem;
484}
485
486/* ============================================================
487 TABLES
488 ============================================================ */
489table {
490 display: block;
491 width: 100%;
492 max-width: 100%;
493 overflow-x: auto;
494 border: none;
495 border-collapse: collapse;
496 margin: 2rem 0;
497}
498
499table td, table th {
500 white-space: nowrap;
501 padding: 0.5rem 1rem;
502}
503th, td {
504 border-bottom: 1px solid var(--border-soft);
505 padding: 0.65rem 0.75rem;
506 text-align: left;
507 font-size: var(--text-sm);
508}
509th {
510 border-bottom: 1px solid var(--fg);
511 font-size: var(--text-xs);
512 text-transform: uppercase;
513 letter-spacing: 0.1em;
514 font-weight: 700;
515}
516tr:last-child td { border-bottom: none; }
517
518/* ============================================================
519 IMAGES
520 ============================================================ */
521img {
522 max-width: 100%;
523 height: auto;
524 filter: grayscale(1);
525 transition: filter 0.25s;
526 display: block;
527 margin: 2rem 0;
528}
529img:hover { filter: grayscale(0); }
530
531/* ============================================================
532 FOOTNOTES
533 ============================================================ */
534.footdef { display: flex; align-items: flex-start; gap: 1rem; margin-bottom: 0.5rem; }
535.footpara { margin: 0; flex: 1; font-size: var(--text-sm); }
536.footnum {
537 font-weight: 700;
538 min-width: 1.5rem;
539 text-align: right;
540 text-decoration: none;
541 font-size: var(--text-xs);
542 color: var(--meta);
543 font-family: var(--font-mono);
544}
545
546/* ============================================================
547 SKIP LINK
548 ============================================================ */
549.skip-link {
550 position: absolute;
551 top: -100px;
552 left: 50%;
553 transform: translateX(-50%);
554 background: var(--fg);
555 color: var(--bg);
556 padding: 0.75rem 1.5rem;
557 z-index: 999;
558 font-weight: 700;
559 font-size: var(--text-xs);
560 text-transform: uppercase;
561 letter-spacing: 0.12em;
562 text-decoration: none;
563 transition: top 0.2s;
564}
565.skip-link:focus { top: 0; outline: none; }
566#main-content:focus { outline: none; }
567
568/* ============================================================
569 RESPONSIVE
570 ============================================================ */
571@media (max-width: 700px) {
572 .masthead-title { font-size: clamp(3rem, 14vw, 5rem); }
573 .masthead nav ul { flex-wrap: wrap; }
574 .masthead nav li { flex: none; width: 50%; }
575 .masthead nav a { border-bottom: 1px solid var(--border-soft); }
576 .post-list-item { grid-template-columns: 2.25rem 1fr; }
577 .post-list-item time { display: none; }
578 .article-title { font-size: clamp(2rem, 9vw, 2.8rem); }
579}
580
581@media (max-width: 480px) {
582 .masthead nav li { width: 33.333%; }
583}
584
585/* Tags page */
586.tag-toc {
587 display: flex;
588 flex-wrap: wrap;
589 gap: 0.5rem 1.5rem;
590 list-style: none;
591 padding: 0;
592 margin: 0 0 3rem;
593}
594.tag-count {
595 color: var(--meta);
596 font-size: var(--text-xs);
597}
12code { color: darkred; }
\ No newline at end of file
theme/static/tokens.css deleted −51
@@ -1,51 +0,0 @@
1/* =============================================================================
2 BRAND TOKENS — cleberg.net
3 ============================================================================= */
4:root {
5 color-scheme: light dark;
6
7 /* Light */
8 --bg: #ffffff;
9 --bg-soft: #f5f5f5;
10 --fg: #0a0a0a;
11 --fg-soft: #444444;
12 --accent: #c0392b;
13 --border: #0a0a0a;
14 --border-soft: #dedede;
15 --code-bg: #f3f3f3;
16 --meta: #999999;
17
18 /* Fonts */
19 --font-serif: Georgia, 'Times New Roman', serif;
20 --font-sans: system-ui, -apple-system, 'Segoe UI', Helvetica, Arial, sans-serif;
21 --font-mono: ui-monospace, 'Cascadia Code', 'Source Code Pro', Menlo, Consolas, monospace;
22
23 /* Type scale */
24 --text-display: clamp(4rem, 8vw, 6.5rem);
25 --text-h1: clamp(2.2rem, 4vw, 3rem);
26 --text-h2: 1.2rem;
27 --text-body: 1.0625rem;
28 --text-sm: 0.875rem;
29 --text-xs: 0.6875rem; /* 11px — label tier */
30 --lh-display: 0.95;
31 --lh-body: 1.75;
32
33 /* Layout */
34 --outer-w: 1000px;
35 --prose-w: 720px;
36 --pad: clamp(1.25rem, 4vw, 2.5rem);
37}
38
39@media (prefers-color-scheme: dark) {
40 :root {
41 --bg: #080808;
42 --bg-soft: #111111;
43 --fg: #eeebe6;
44 --fg-soft: #aaa8a3;
45 --accent: #e05a48;
46 --border: #eeebe6;
47 --border-soft: #1e1e1e;
48 --code-bg: #0d0d0d;
49 --meta: #555555;
50 }
51}
theme/templates/base.html +20 −29
@@ -9,45 +9,36 @@
99 {% if site_description is defined %}<meta name="description" content="{{ site_description }}">{% endif %}
1010 {% if site_keywords is defined %}<meta name="keywords" content="{{ site_keywords }}">{% endif %}
1111 <link rel="stylesheet" href="{{ url_for("static", file="styles.min.css") }}" type="text/css">
12 <link rel="icon" href="{{ url_for("static", file="favicon.svg") }}" type="image/svg+xml">
12 <link rel="icon" href="data:,">
1313 {% block meta %}{% endblock %}
1414 {% endblock %}
1515</head>
1616<body>
1717 <a href="#main-content" class="skip-link">Skip to content</a>
18 <header class="masthead">
19 <a href="/" class="masthead-title">seijaku</a>
20 <p class="masthead-subtitle"><i>stillness amidst the chaos</i></p>
21 <nav aria-label="Site Navigation">
22 <ul>
23 <li><a href="/blog/">Blog</a></li>
24 <li><a href="/tags/">Tags</a></li>
25 <li><a href="/guides/index.html">Guides</a></li>
26 <li><a href="/apps/">Apps</a></li>
27 <li><a href="/garden/">Garden</a></li>
28 <li><a href="/salary/">Salary</a></li>
29 </ul>
30 </nav>
31 </header>
18
19 <nav aria-label="Site Navigation">
20 <ul>
21 <li><a href="/">Home</a></li>
22 <li><a href="/apps/">Apps</a></li>
23 <li><a href="/blog/">Blog</a></li>
24 <li><a href="/garden/">Garden</a></li>
25 <li><a href="/guides/">Guides</a></li>
26 <li><a href="/salary/">Salary</a></li>
27 <li><a href="/tags/">Tags</a></li>
28 </ul>
29 </nav>
30
3231 <main id="main-content">
3332 {% block main %}{% endblock %}
3433 </main>
35 <hr>
34
3635 <footer>
37 <div>
38 <a href="https://github.com/ccleberg/cleberg.net">Source</a> &middot;
39 <a href="/feed.xml">RSS</a> &middot;
40 <a href="http://paske4urhs6nttrtlkuwa5cowum3fjkc6yv6kl4ncx3mjxcd77764nqd.onion/">Onion</a> &middot;
41 <a href="/now/">Now</a> &middot;
42 <a href="/uses/">Uses</a> &middot;
43 <a href="/tips/">Tips</a> &middot;
44 <a href="https://cv.cleberg.net">CV</a>
45 </div>
46 <div>
47 <a href="mailto:hello@cleberg.net">hello@cleberg.net</a> [<a href="/gpg.txt">PGP</a>] &middot;
48 Signal: @cmc.01
49 </div>
36 <a href="https://github.com/ccleberg/cleberg.net">Source</a> &middot;
37 <a href="/feed.xml">RSS</a> &middot;
38 <a href="http://paske4urhs6nttrtlkuwa5cowum3fjkc6yv6kl4ncx3mjxcd77764nqd.onion/">Onion</a> &middot;
39 <a href="/tips/">Tips</a>
5040 </footer>
41
5142 <section class="indieweb-links" style="display:none">
5243 <link href="https://github.com/ccleberg" rel="me">
5344 <link href="https://gitlab.com/ccleberg" rel="me">
theme/templates/blog.html +8 −8
@@ -1,13 +1,13 @@
11{% extends "base.html" %} {% block subtitle %}blog - {% endblock %} {% block main %}
22<h1>Blog</h1>
3<p class="blog-meta">Use <code>⌘ F</code> / <code>Ctrl F</code> to search &middot; <a href="/feed.xml">RSS Feed</a></p>
4<p class="label">All Posts</p>
3<p>Use <code>⌘ F</code> / <code>Ctrl F</code> to search &middot; <a href="/feed.xml">RSS Feed</a></p>
4<p>All Posts</p>
55<ul class="post-list">
6{% for post in posts %}
7<li class="post-list-item">
8 <a href='{{ url_for("blog", slug=post.slug) }}'>{{ post.title }}</a>
9 <time datetime='{{ post.date | strftime("%Y-%m-%d") }}'>{{ post.date|strftime("%Y-%m-%d") }}</time>
10</li>
11{% endfor %}
6 {% for post in posts %}
7 <li class="post-list-item">
8 <time datetime='{{ post.date | strftime("%Y-%m-%d") }}'>{{ post.date|strftime("%Y-%m-%d") }}</time>
9 <a href='{{ url_for("blog", slug=post.slug) }}'>{{ post.title }}</a>
10 </li>
11 {% endfor %}
1212</ul>
1313{% endblock %}
theme/templates/garden.html +9 −9
@@ -14,14 +14,14 @@ around.</p>
1414 <span><strong>🍂 Compost:</strong> Ideas you no longer agree with but want to
1515 keep for historical context.</span><br><br>
1616</section>
17<ul class="garden-index">
18{% for post in posts %}
19<li>
20 <a href='{{ url_for("garden", slug=post.slug) }}'>{{ post.title }}</a>
21 {% if post.description %}
22 <span class="garden-desc">{{ post.description }}</span>
23 {% endif %}
24</li>
25{% endfor %}
17<ul>
18 {% for post in posts %}
19 <li>
20 <a href='{{ url_for("garden", slug=post.slug) }}'>{{ post.title }}</a>
21 {% if post.description %}
22 <span>{{ post.description }}</span>
23 {% endif %}
24 </li>
25 {% endfor %}
2626</ul>
2727{% endblock %}
theme/templates/index.html +19 −19
@@ -1,22 +1,22 @@
11{% extends "base.html" %} {% block main %}
2<div class="homepage-intro">
3 <p>My name is Christian.</p>
4 <p>I’m a technology auditor who doesn’t trust technology companies.</p>
5 <p>I run my own infrastructure. I audit everyone else's.</p>
6 <p>The infrastructure is the point. Self-hosted, self-managed, minimal
7 dependencies. This site is part of it: plaintext, no trackers, no
8 frameworks, no corporate CDN.</p>
9 <p>The audit job funds it. KPMG. Technology Assurance. I spend 50-80 hours a
10 week inside the systems I refuse to use personally. The irony is the
11 business model.</p>
12 <p>GPG key, salary, and server stack are all public. That's the whole
13 introduction.</p>
14</div>
2<section>
3 <p><b>Hi, I'm Christian.</b></p>
4 <p>I'm a Technology Assurance Manager @ KPMG.</p>
5 <p>I use this site as a place to think out loud (see my <a href="/blog/">blog</a>, <a href="/garden/">garden</a>, or
6 <a href="/guides/">guides</a>), a place to publish information (see
7 my <a href="https://cv.cleberg.net">CV</a> and <a href="/salary/">salary</a>
8 pages), and a foundational URI to use for my projects (see
9 my <a href="/apps/">apps</a>).</p>
10 <p>If you want to chat, you can find me in the following spaces:</p>
11 <ul>
12 <li>hello [at] cleberg.net (<a href="/gpg.txt">PGP Key</a>)</li>
13 <li>@cmc.01 on <a href="https://signal.org">Signal</a></li>
14 </ul>
15 <p>Curious about the technology behind this website? Check out my <a href="/uses/">/uses</a> page.</p>
16 <p>Curious about what I've been up to lately in my personal life? Check out my <a href="/now/">/now</a> page.</p>
17</section>
1518
16<p class="section-label">Recent Posts</p>
17<ul class="post-list">
18 <!-- BEGIN_POSTS -->
19 <!-- END_POSTS -->
20</ul>
21<a class="all-posts-link" href="/blog/">All Posts &rarr;</a>
19<p>Recent Posts</p>
20<!-- BEGIN_POSTS --><!-- END_POSTS -->
21<p><a href="/blog/">All Posts &rarr;</a></p>
2222{% endblock %}
theme/templates/page.html +1 −1
@@ -3,6 +3,6 @@
33{% block main %}
44<article>
55 <h1>{{ post.title }}</h1>
6 <div class="page-body">{{ post.html | safe }}</div>
6 <div>{{ post.html | safe }}</div>
77</article>
88{% endblock %}
theme/templates/post.html +5 −5
@@ -10,12 +10,12 @@
1010{% endblock %}
1111{% block main %}
1212<article>
13 <p class="article-dateline"><time datetime='{{ post.date|strftime("%Y-%m-%d") }}'>{{ post.date|strftime("%Y-%m-%d") }}</time></p>
14 <h1 class="article-title">{{ post.title }}</h1>
13 <p><time datetime='{{ post.date|strftime("%Y-%m-%d") }}'>{{ post.date|strftime("%Y-%m-%d") }}</time></p>
14 <h1>{{ post.title }}</h1>
1515 {% if post.description is defined %}
16 <p class="article-standfirst">{{ post.description }}</p>
16 <p>{{ post.description }}</p>
1717 {% endif %}
18 <div class="article-body">{{ post.html | safe }}</div>
19 <div class="reply-link"><a href="mailto:hello@cleberg.net">Reply via email &rarr;</a></div>
18 <div>{{ post.html | safe }}</div>
19 <div><a href="mailto:hello@cleberg.net">Reply via email &rarr;</a></div>
2020</article>
2121{% endblock %}
utils/nginx-dev.conf deleted −17
@@ -1,17 +0,0 @@
1server {
2 server_name cleberg.net www.cleberg.net;
3
4 root /usr/share/nginx/html;
5 index index.html;
6 autoindex on;
7
8 access_log /var/log/nginx/cleberg.net.access.log;
9 error_log /var/log/nginx/cleberg.net.error.log;
10
11 location / {
12 try_files $uri $uri/ =404;
13 }
14
15 listen [::]:80;
16 listen 80;
17}