Commit 6eb7d43fc2
Unsigned
Layout: unified · split
build.py +25 −24
| @@ -104,7 +104,6 @@ def get_recent_posts_html(content_dir="./content/blog", num_posts=3): | ||
| 104 | 104 | #+title: Post Title |
| 105 | 105 | #+date: <YYYY-MM-DD Day HH:MM:SS> |
| 106 | 106 | #+slug: post-slug |
| 107 | #+filetags: :tag1:tag2:tag3: | |
| 108 | 107 | |
| 109 | 108 | Returns a string containing the section with the three most recent posts, |
| 110 | 109 | formatted like the snippet in the prompt. |
| @@ -115,7 +114,6 @@ def get_recent_posts_html(content_dir="./content/blog", num_posts=3): | ||
| 115 | 114 | "title": re.compile(r"^#\+title:\s*(.+)$", re.IGNORECASE), |
| 116 | 115 | "date": re.compile(r"^#\+date:\s*<(\d{4}-\d{2}-\d{2})"), |
| 117 | 116 | "slug": re.compile(r"^#\+slug:\s*(.+)$", re.IGNORECASE), |
| 118 | "filetags": re.compile(r"^#\+filetags:\s*(.+)$", re.IGNORECASE), | |
| 119 | 117 | "draft": re.compile(r"^#\+draft:\s*(.+)$", re.IGNORECASE), |
| 120 | 118 | } |
| 121 | 119 | |
| @@ -123,7 +121,6 @@ def get_recent_posts_html(content_dir="./content/blog", num_posts=3): | ||
| 123 | 121 | title = None |
| 124 | 122 | date_str = None |
| 125 | 123 | slug = None |
| 126 | tags = [] | |
| 127 | 124 | is_draft = False |
| 128 | 125 | |
| 129 | 126 | with org_path.open("r", encoding="utf-8") as f: |
| @@ -147,15 +144,6 @@ def get_recent_posts_html(content_dir="./content/blog", num_posts=3): | ||
| 147 | 144 | slug = m.group(1).strip() |
| 148 | 145 | continue |
| 149 | 146 | |
| 150 | if not tags: | |
| 151 | m = header_patterns["filetags"].match(line) | |
| 152 | if m: | |
| 153 | # filetags are in the form ":tag1:tag2:tag3:" | |
| 154 | raw = m.group(1).strip() | |
| 155 | # split on ":" and filter out empty strings | |
| 156 | tags = [t for t in raw.split(":") if t] | |
| 157 | continue | |
| 158 | ||
| 159 | 147 | m = header_patterns["draft"].match(line) |
| 160 | 148 | if m: |
| 161 | 149 | draft_value = m.group(1).strip().lower() |
| @@ -165,7 +153,7 @@ def get_recent_posts_html(content_dir="./content/blog", num_posts=3): | ||
| 165 | 153 | continue |
| 166 | 154 | |
| 167 | 155 | # Stop scanning once we have all required fields |
| 168 | if title and date_str and slug and tags: | |
| 156 | if title and date_str and slug: | |
| 169 | 157 | break |
| 170 | 158 | |
| 171 | 159 | if is_draft: |
| @@ -186,7 +174,6 @@ def get_recent_posts_html(content_dir="./content/blog", num_posts=3): | ||
| 186 | 174 | "date_obj": date_obj, |
| 187 | 175 | "date_full": date_full, |
| 188 | 176 | "slug": slug, |
| 189 | "tags": tags, | |
| 190 | 177 | } |
| 191 | 178 | ) |
| 192 | 179 | |
| @@ -199,21 +186,15 @@ def get_recent_posts_html(content_dir="./content/blog", num_posts=3): | ||
| 199 | 186 | # Build HTML lines |
| 200 | 187 | lines = [] |
| 201 | 188 | for post in recent: |
| 202 | lines.append('\t<div class="post">') | |
| 203 | lines.append('\t\t<div class="post-content">') | |
| 189 | lines.append('\t<div>') | |
| 204 | 190 | lines.append( |
| 205 | f'\t\t\t<a href="/blog/{post["slug"]}.html">{post["title"]}</a>' | |
| 191 | f'\t\t<time datetime="{post["date_str"]}">{post["date_full"]}</time>' | |
| 206 | 192 | ) |
| 207 | if post["tags"]: | |
| 208 | lines.append('\t\t\t<div class="post-tags">') | |
| 209 | for tag in post["tags"]: | |
| 210 | lines.append(f'\t\t\t\t<span class="tag">{tag}</span>') | |
| 211 | lines.append("\t\t\t</div>") | |
| 212 | lines.append("\t\t</div>") | |
| 213 | 193 | lines.append( |
| 214 | f'\t\t<time datetime="{post["date_str"]}">{post["date_full"]}</time>' | |
| 194 | f'\t\t\t<a href="/blog/{post["slug"]}.html">{post["title"]}</a>' | |
| 215 | 195 | ) |
| 216 | 196 | lines.append("\t</div>") |
| 197 | lines.append("\t<br>") | |
| 217 | 198 | |
| 218 | 199 | return "\n".join(lines) |
| 219 | 200 | |
| @@ -246,6 +227,20 @@ def minify_css(src_css, dest_css): | ||
| 246 | 227 | sys.exit(1) |
| 247 | 228 | |
| 248 | 229 | |
| 230 | def minify_html(src_html, dest_html): | |
| 231 | print(f"Minifying HTML: {src_html} → {dest_html}") | |
| 232 | result = subprocess.run( | |
| 233 | ["minify", "-o", str(dest_html), str(src_html)], | |
| 234 | stdout=subprocess.PIPE, | |
| 235 | stderr=subprocess.PIPE, | |
| 236 | text=True, | |
| 237 | ) | |
| 238 | if result.returncode != 0: | |
| 239 | print("Error during HTML minification:") | |
| 240 | print(result.stderr, file=sys.stderr) | |
| 241 | sys.exit(1) | |
| 242 | ||
| 243 | ||
| 249 | 244 | def run_emacs_publish(dev_mode=True): |
| 250 | 245 | if dev_mode: |
| 251 | 246 | print("Running Emacs publish script (development)...") |
| @@ -378,6 +373,9 @@ def main(): | ||
| 378 | 373 | # Update index page with latest posts |
| 379 | 374 | update_index_html(html_snippet) |
| 380 | 375 | |
| 376 | # Minify index page | |
| 377 | minify_html("./.build/index.html", "./.build/index.html") | |
| 378 | ||
| 381 | 379 | # Generate sitemap |
| 382 | 380 | generate_sitemap() |
| 383 | 381 | |
| @@ -399,6 +397,9 @@ def main(): | ||
| 399 | 397 | # Update index page with latest posts |
| 400 | 398 | update_index_html(html_snippet) |
| 401 | 399 | |
| 400 | # Minify index page | |
| 401 | minify_html("./.build/index.html", "./.build/index.html") | |
| 402 | ||
| 402 | 403 | # Generate sitemap |
| 403 | 404 | generate_sitemap() |
| 404 | 405 | |
content/about/index.org +1 −1
| @@ -6,7 +6,7 @@ Hey, I'm */~cmc/*. | ||
| 6 | 6 | I'm a technology audit manager, working on financial statement audits (SOX/MAR), |
| 7 | 7 | SOC 1-3 reports, and other attestations for KPMG. |
| 8 | 8 | |
| 9 | Read up on my [[https://cv.cleberg.net][CV]] or [[https://cleberg.net/salary/][salary]] for more information. | |
| 9 | Read up on my [[https://cv.cleberg.net][CV]] or [[https://cleberg.net/salary/][salary]] for more information. Otherwise, feel free to read more [[https://cleberg.net/about/][about me]]. | |
| 10 | 10 | |
| 11 | 11 | In my spare time, I like to: |
| 12 | 12 | |
content/wiki/blogroll.org deleted −31
| @@ -1,31 +0,0 @@ | ||
| 1 | #+title: Blogroll | |
| 2 | #+date: <2024-04-12> | |
| 3 | ||
| 4 | ** Aggregators | |
| 5 | - [[https://1mb.club/][1MB Club]] | |
| 6 | - [[https://250kb.club/][250KB Club]] | |
| 7 | - [[https://512kb.club/][512KB Club]] | |
| 8 | - [[https://darktheme.club/][Darktheme Club]] | |
| 9 | - [[https://nocss.club/][No CSS Club]] | |
| 10 | - [[https://no-js.club/][No-JS Club]] | |
| 11 | - [[https://blogroll.org/][Ye Olde Blogroll]] | |
| 12 | ||
| 13 | ** Plain Text | |
| 14 | A list of various plaintext websites and lists. | |
| 15 | ||
| 16 | - [[https://greycoder.com/a-list-of-text-only-new-sites/][A List Of Text-Only & Minimalist News Sites]] | |
| 17 | - [[https://harvardlawreview.org/][Harvard Law Review]] | |
| 18 | - [[https://sjmulder.nl/en/textonly.html][Hyperlinked Text]] | |
| 19 | - [[https://medium.com/@letsworkshop/plain-text-web-design-a78ccaf9dbc0][Plain-text web design]] | |
| 20 | - [[https://plaintextworld.com/][Plaintext World]] | |
| 21 | - [[https://github.com/masonarmand/txt2web][txt2web]] | |
| 22 | - [[https://justinjackson.ca/words.html][Words]] | |
| 23 | ||
| 24 | ** Webrings | |
| 25 | Instead of listing my personal favorites, I'm just going to drop a link to | |
| 26 | [[https://brisray.com/web/webring-list.htm][brisay's webring list]], which contains 237 webrings for a total of 7078 websites, | |
| 27 | as of 2024-03-15. | |
| 28 | ||
| 29 | ** Everything Else | |
| 30 | - [[https://deadsimplesites.com/][Dead Simple Sites]] | |
| 31 | - [[https://planet.emacslife.com/][Planet Emacslife]] | |
content/wiki/hardware.org deleted −95
| @@ -1,95 +0,0 @@ | ||
| 1 | #+title: Hardware | |
| 2 | #+date: <2024-03-16> | |
| 3 | ||
| 4 | ** Desktop | |
| 5 | *** macOS | |
| 6 | Probably should have added more RAM but Macbooks are stupid expensive. | |
| 7 | ||
| 8 | | Category | Details | | |
| 9 | |----------+-----------------| | |
| 10 | | Model | [[https://www.apple.com/macbook-pro/][Macbook Pro 16”]] | | |
| 11 | | CPU | Apple M2 Pro | | |
| 12 | | RAM | 16GB | | |
| 13 | | Storage | 512GB SSD | | |
| 14 | ||
| 15 | *** Linux | |
| 16 | A beauty. | |
| 17 | ||
| 18 | | Category | Details | | |
| 19 | |----------+---------------------------------------------| | |
| 20 | | Model | [[https://www.lenovo.com/us/en/p/laptops/thinkpad/thinkpade/thinkpad--e15-gen-4-(15-inch-amd)/len101t0023][Lenovo ThinkPad E15 Gen 4, model 21ED0048US]] | | |
| 21 | | CPU | AMD Ryzen 5 5625U with Radeon Graphics | | |
| 22 | | RAM | 16 GB | | |
| 23 | | Storage | 256 GB SSD | | |
| 24 | ||
| 25 | ** Mobile | |
| 26 | Previously used a Pixel 6 & Pixel 7 with GrapheneOS. | |
| 27 | ||
| 28 | | Category | Details | | |
| 29 | |----------+-------------------| | |
| 30 | | Model | [[https://www.apple.com/iphone-15-pro/][iPhone 15 Pro Max]] | | |
| 31 | | CPU | A17 Pro | | |
| 32 | | RAM | 8GB | | |
| 33 | | Storage | 256GB | | |
| 34 | ||
| 35 | ** Homelab | |
| 36 | I run a small homelab with a mix of consumer (compute/storage) and enterprise | |
| 37 | (network) hardware. I try to keep the lab energy efficient and quiet as my top | |
| 38 | priorities. | |
| 39 | ||
| 40 | *** IoT | |
| 41 | A collection of mainly smart lights, sensors, and smart appliances. My first | |
| 42 | preference is to disable all networking for new smart devices or simply not | |
| 43 | connect internet in the first place (e.g. I never enable internet on my smart | |
| 44 | TVs). If the smart device requires LAN access, I will connect the device to my | |
| 45 | guest-restricted IoT network. As a last resort, I will set-up the internet but | |
| 46 | monitor the DNS lookups via NextDNS and forcibly block any domains I do not want | |
| 47 | the device to be using. If the device is egregious or shady, I'll just sell it | |
| 48 | and either replace it or live without it. | |
| 49 | ||
| 50 | - Other Appliances (washer, dryer, humidifier, fans, etc.) | |
| 51 | - [[https://about.irobot.com/sitecore/content/north-america/irobot-us/home/roomba/i7-series][Roomba i7+]] | |
| 52 | - [[https://www.philips-hue.com/en-us/p/hue-white-and-color-ambiance-a19---e26-smart-bulb---60-w--3-pack-/046677562786][Philips Hue A19 Bulbs]] x 15 | |
| 53 | - [[https://www.philips-hue.com/en-us/p/hue-bundle-play-blk-ext/33001][Philips Hue Play Light Bars]] | |
| 54 | - [[https://www.philips-hue.com/en-us/p/hue-bridge/046677458478][Philips Hue Smart Bridge]] + play light bars and a ton of bulbs | |
| 55 | - [[https://store.ui.com/us/en/collections/unifi-camera-security-special-chime][UP Chime]] | |
| 56 | - [[https://store.ui.com/us/en/collections/unifi-camera-security-special-sensor][UP-Sense]] x 2 | |
| 57 | - [[https://store.ui.com/us/en/products/unifi-smart-power][USP-Plug]] | |
| 58 | - [[https://store.ui.com/us/en/collections/unifi-camera-security-compact-wifi-connected][UVC G4 Instant]] x 3 | |
| 59 | - [[https://store.ui.com/us/en/collections/unifi-camera-security-special-wifi-doorbell][UVC G4 Doorbell Pro]] | |
| 60 | ||
| 61 | *** Network | |
| 62 | A rack-mounted Dream Machine Pro, connected downstream to an access point, mesh | |
| 63 | extender, and a couple ethernet switches. | |
| 64 | ||
| 65 | - [[https://store.ui.com/us/en/collections/unifi-dream-machine/products/udm-pro][UDM-Pro]] | |
| 66 | - [[https://store.ui.com/us/en/collections/unifi-switching-standard-power-over-ethernet/products/usw-24-poe][USW-24-PoE]] | |
| 67 | - [[https://store.ui.com/us/en/collections/unifi-switching-utility-poe/products/usw-lite-8-poe][USW-Lite-8-PoE]] | |
| 68 | - [[https://store.ui.com/us/en/collections/unifi-wifi-flagship-high-capacity/products/u6-pro][U6-Pro]] | |
| 69 | - [[https://store.ui.com/us/en/collections/unifi-wifi-inwall-outlet-mesh][U6-Extender]] | |
| 70 | - [[https://store.ui.com/us/en/products/u7-pro-wall][U7-Pro-Wall]] x 2 | |
| 71 | - [[https://store.ui.com/us/en/collections/unifi-accessory-tech-installations-rackmount/products/uacc-rack-panel-patch-blank-24][USW 24-Port Patch Panel]] | |
| 72 | ||
| 73 | *** Servers | |
| 74 | 1. Rack-Mount Server | |
| 75 | ||
| 76 | I wasn't happy with using low-powered PCs as servers and I knew I did not | |
| 77 | want the ear-shattering enterprise rack-mounted servers, so I built my own. | |
| 78 | ||
| 79 | | Category | Details | | |
| 80 | |--------------------+----------------------------------------| | |
| 81 | | Case | Rosewill RSV-R4100U 4U | | |
| 82 | | Motherboard | NZXT B550 | | |
| 83 | | CPU | AMD Ryzen 7 5700G with Radeon Graphics | | |
| 84 | | RAM | 64GB RAM (2x32GB) | | |
| 85 | | Storage (On-board) | Western Digital 500GB M.2 NVME SSD | | |
| 86 | | Storage (HDD Bay) | 48TB HDD | | |
| 87 | | PSU | Corsair RM850 PSU | | |
| 88 | ||
| 89 | 2. Other | |
| 90 | ||
| 91 | These ran as my main servers before I built the rack-mounted server above. I | |
| 92 | have shut these down indefinitely for now as I have no use for them. | |
| 93 | ||
| 94 | - Dell OptiPlex | |
| 95 | - Raspberry Pi 4 | |
content/wiki/internet.org deleted −98
| @@ -1,98 +0,0 @@ | ||
| 1 | #+title: Internet | |
| 2 | #+date: <2024-05-02> | |
| 3 | ||
| 4 | ** Gemini | |
| 5 | The [[https://geminiprotocol.net/][Gemini Protocol]] is a network of interconnected plaintext documents. If | |
| 6 | you've used [[https://en.wikipedia.org/wiki/Gopher_(protocol)][Gopher]] before, Gemini will feel very familiar. | |
| 7 | ||
| 8 | Instead of web sites, Gemini uses the term "capsules" that can be access via | |
| 9 | =gemini://= links. | |
| 10 | ||
| 11 | In order to browse Gemini capsules, you will need a client capable of supporting | |
| 12 | Gemini. The Gemini Protocol website has a [[https://geminiprotocol.net/software/][Gemini software]] page with a list of | |
| 13 | clients for each platform. | |
| 14 | ||
| 15 | *** Gemtext | |
| 16 | [[https://geminiprotocol.net/docs/cheatsheet.gmi][Gemtext]] is a plaintext syntax, very similar to Markdown. | |
| 17 | ||
| 18 | To quote the Gemini Protocol's documentation: | |
| 19 | ||
| 20 | - Long lines get wrapped by the client to fit the screen. | |
| 21 | - Short lines /don't/ get joined together. | |
| 22 | - Write paragraphs as single long lines. | |
| 23 | - Blank lines are rendered verbatim. | |
| 24 | ||
| 25 | #+begin_src md | |
| 26 | [//]: <> (Headings) | |
| 27 | # Heading | |
| 28 | ## Sub-heading | |
| 29 | ### Sub-subheading | |
| 30 | ||
| 31 | [//]: <> (Lists) | |
| 32 | - Mercury | |
| 33 | - Gemini | |
| 34 | - Apollo | |
| 35 | ||
| 36 | [//]: <> (Quotes) | |
| 37 | > I contend that text-based websites should not exceed in size the major works of Russian literature. | |
| 38 | ||
| 39 | [//]: <> (Links) | |
| 40 | => gemini://geminiprotocol.net/docs/cheatsheet.gmi | |
| 41 | => gemini://geminiprotocol.net/docs/cheatsheet.gmi Gemtext cheatsheet | |
| 42 | ||
| 43 | [//]: <> (Preformatted text) | |
| 44 | Any line starting with three backticks (```) will tell the client to toggle to | |
| 45 | "preformatted mode", which disables the client's logical checks to render links, | |
| 46 | headings, etc. and will render the text as-is. | |
| 47 | #+end_src | |
| 48 | ||
| 49 | ** Gopher | |
| 50 | The [[https://en.wikipedia.org/wiki/Gopher_(protocol)][Gopher Protocol]] is a communication protocol, similar to Gemini, that allows | |
| 51 | for browsing of any ones of [[https://datatracker.ietf.org/doc/html/rfc1436#section-3.8][the 14 supported item types]]: | |
| 52 | ||
| 53 | #+begin_src txt | |
| 54 | 0 Item is a file | |
| 55 | 1 Item is a directory | |
| 56 | 2 Item is a CSO phone-book server | |
| 57 | 3 Error | |
| 58 | 4 Item is a BinHexed Macintosh file. | |
| 59 | 5 Item is DOS binary archive of some sort. | |
| 60 | Client must read until the TCP connection closes. Beware. | |
| 61 | 6 Item is a UNIX uuencoded file. | |
| 62 | 7 Item is an Index-Search server. | |
| 63 | 8 Item points to a text-based telnet session. | |
| 64 | 9 Item is a binary file! | |
| 65 | Client must read until the TCP connection closes. Beware. | |
| 66 | + Item is a redundant server | |
| 67 | T Item points to a text-based tn3270 session. | |
| 68 | g Item is a GIF format graphics file. | |
| 69 | I Item is some kind of image file. Client decides how to display. | |
| 70 | #+end_src | |
| 71 | ||
| 72 | *** Simplicity is Intentional | |
| 73 | Gopher is [[https://datatracker.ietf.org/doc/html/rfc1436#section-4][meant to be simplistic]]. | |
| 74 | ||
| 75 | #+begin_src txt | |
| 76 | As far as possible we desire any new features to be carried as new | |
| 77 | protocols that will be hidden behind new document-types. The | |
| 78 | internet Gopher philosophy is: | |
| 79 | ||
| 80 | (a) Intelligence is held by the server. Clients have the option | |
| 81 | of being able to access new document types (different, other types | |
| 82 | of servers) by simply recognizing the document-type character. | |
| 83 | Further intelligence to be borne by the protocol should be | |
| 84 | minimized. | |
| 85 | ||
| 86 | (b) The well-tempered server ought to send "text" (unless a file | |
| 87 | must be transferred as raw binary). Should this text include | |
| 88 | tabs, formfeeds, frufru? Probably not, but rude servers will | |
| 89 | probably send them anyway. Publishers of documents should be | |
| 90 | given simple tools (filters) that will alert them if there are any | |
| 91 | funny characters in the documents they wish to publish, and give | |
| 92 | them the opportunity to strip the questionable characters out; the | |
| 93 | publisher may well refuse. | |
| 94 | ||
| 95 | (c) The well-tempered client should do something reasonable with | |
| 96 | funny characters received in text; filter them out, leave them in, | |
| 97 | whatever. | |
| 98 | #+end_src | |
content/wiki/ios.org deleted −139
| @@ -1,139 +0,0 @@ | ||
| 1 | #+title: iOS | |
| 2 | #+date: <2024-05-01> | |
| 3 | ||
| 4 | Related: | |
| 5 | ||
| 6 | - [[https://cleberg.net/wiki/hardware.html][Hardware]] | |
| 7 | ||
| 8 | My primary mobile OS. Currently running iOS 17. This wiki page contains most of | |
| 9 | the apps I have used at one point or another across my different iPhones. | |
| 10 | ||
| 11 | (=*=) = My favorites | |
| 12 | ||
| 13 | ** Configuration | |
| 14 | *** Display | |
| 15 | - Light Mode | |
| 16 | - 08:00 to 16:00 | |
| 17 | - Dark Mode | |
| 18 | - 16:00 to 08:00 | |
| 19 | ||
| 20 | *** Focus Modes | |
| 21 | - Personal Focus | |
| 22 | - 06:00 to 21:00 | |
| 23 | - Allow Notifications From: | |
| 24 | - Alarms | |
| 25 | - Calendar | |
| 26 | - Contacts (1 person) | |
| 27 | - Messages | |
| 28 | - Phone | |
| 29 | - Reminders | |
| 30 | - Signal | |
| 31 | - UniFi Protect | |
| 32 | - Sleep Focus | |
| 33 | - 21:00 to 06:00 | |
| 34 | - Allow Notifications From: | |
| 35 | - Alarms | |
| 36 | - Contacts (1 person) | |
| 37 | - Reminders | |
| 38 | - Signal | |
| 39 | ||
| 40 | *** Privacy & Security | |
| 41 | I generally follow the [[https://en.wikipedia.org/wiki/Principle_of_least_privilege][principle of least privilege]] by only permitting the bare | |
| 42 | minimum privileges and revoking as soon as they are no longer required. | |
| 43 | ||
| 44 | Here's the baseline I start with: | |
| 45 | ||
| 46 | - Disable: | |
| 47 | - Analytics & Improvements | |
| 48 | - Apple Advertising | |
| 49 | - Apple ID > Sign-In & Security > Two-Factor Authentication | |
| 50 | - Location Services > System Services > Product Improvement | |
| 51 | - Tracking > Allow Apps to Request to Track | |
| 52 | - Safari > Advanced > Privacy Preserving Ad Measurement | |
| 53 | - Enable: | |
| 54 | - Apple ID > iCloud > Advanced Data Protection | |
| 55 | - Apple ID > Personal Information > Communication Preferences | |
| 56 | - App Privacy Report | |
| 57 | - Location Services only for Camera, Find My, UDisc, & WiFiman (=While Using=) | |
| 58 | - Safari > Prevent Cross-Site Tracking | |
| 59 | - Safari > Hide IP Address | |
| 60 | - Safari > Advanced > Advanced Tracking and Fingerprinting Protection | |
| 61 | ||
| 62 | ** Native Apps | |
| 63 | *** Business | |
| 64 | - [[https://apps.apple.com/us/app/element-messenger/id1083446067][Element]] - A cross-platform messenger, based on Matrix | |
| 65 | - [[https://apps.apple.com/us/app/linkedin-network-job-finder/id288429040][LinkedIn]] - One of the only social media apps I use | |
| 66 | ||
| 67 | *** Developer Tools | |
| 68 | - [[https://testflight.apple.com/join/F2vK7xo4][Harbour]] - Easily manage your Portainer service | |
| 69 | - [[https://apps.apple.com/us/app/ish-shell/id1436902243][iSH]] - A local shell with SSH functionality | |
| 70 | ||
| 71 | *** Entertainment | |
| 72 | - [[https://apps.apple.com/us/app/plex-watch-live-tv-and-movies/id383457673][Plex]] - A client for the Plex Media Server | |
| 73 | - [[https://apps.apple.com/us/app/steam-mobile/id495369748][Steam]] - The top gaming marketplace for computers | |
| 74 | ||
| 75 | *** Lifestyle | |
| 76 | - [[https://apps.apple.com/us/app/home/id1110145103][Home]] (=*=) - Apple homekit powered smart home manager | |
| 77 | - [[https://apps.apple.com/us/app/philips-hue/id1055281310][Hue]] - Philips Hue smart home manager | |
| 78 | - [[https://apps.apple.com/us/app/irobot-home/id1012014442][iRobot]] - Manage iRobot Roomba devices | |
| 79 | - [[https://apps.apple.com/us/app/unifi-protect/id1392492235][UniFi Protect]] - View and manage most UniFi Protect cameras and settings | |
| 80 | ||
| 81 | *** Music | |
| 82 | - [[https://apps.apple.com/us/app/apple-music/id1108187390][Apple Music]] (=*=) - Apple's native music streaming app | |
| 83 | - [[https://apps.apple.com/us/app/plexamp/id1500797510][Plexamp]] (=*=) - Top-notch music app for your Plex Media Server, with a neural | |
| 84 | network that provides excellent radio/shuffle suggestions | |
| 85 | ||
| 86 | *** Navigation | |
| 87 | - [[https://apps.apple.com/us/app/deedum/id1546810946][deedum]] - A Gemini Protocol browser | |
| 88 | ||
| 89 | *** News | |
| 90 | - [[https://apps.apple.com/us/app/netnewswire-rss-reader/id1480640210][NetNewsWire]] - A free and open source RSS reader for Mac, iPhone, and iPad | |
| 91 | ||
| 92 | *** Photo & Video | |
| 93 | - [[https://testflight.apple.com/join/Q6WyyEpS][Aislingeach]] - A quick way to generate and rate images from the Stable Horde | |
| 94 | - [[https://apps.apple.com/us/app/unsplash/id1290631746][Unsplash]] - Premium images, mostly free | |
| 95 | ||
| 96 | *** Productivity | |
| 97 | - [[https://apps.apple.com/us/app/beorg-to-do-list-agenda/id1238649962][beorg]] (=*=) - An org-mode editor, outline, and scheduler with paid extensions | |
| 98 | - [[https://apps.apple.com/us/app/bitwarden-password-manager/id1137397744][Bitwarden]] (=*=) - An open source password manager | |
| 99 | - [[https://apps.apple.com/us/app/bitwarden-authenticator/id6497335175][Bitwarden Authenticator]] (=*=) - Generate 2FA on your device | |
| 100 | - [[https://apps.apple.com/us/app/cryptomator/id1560822163][Cryptomator]] - A cross-platform encryption program | |
| 101 | - [[https://apps.apple.com/us/app/obsidian-connected-notes/id1557175442][Obsidian]] - A nice Markdown-based editor based on a "vault" structure. | |
| 102 | Offers a paid sync solution and community extensions | |
| 103 | - [[https://apps.apple.com/us/app/strongbox-password-manager/id897283731][Strongbox]] - Keepass password manager for iOS & macOS | |
| 104 | - [[https://apps.apple.com/us/app/unifi/id1057750338][UniFi Network]] - View and manage most UniFi Network settings | |
| 105 | ||
| 106 | *** Safari Extensions | |
| 107 | - [[https://apps.apple.com/us/app/adguard-adblock-privacy/id1047223162][AdGuard]] - Ad blocker | |
| 108 | - [[https://apps.apple.com/us/app/dark-reader-for-safari/id1438243180][Dark Reader]] - Dark mode for all the sites | |
| 109 | - [[https://apps.apple.com/us/app/pipifier/id1234771095][PiPifier]] - Force videos to support PiP | |
| 110 | - [[https://apps.apple.com/us/app/privacy-redirect/id1578144015][Privacy Redirect]] - Redirect select websites to others, usually to | |
| 111 | privacy-focused alternatives | |
| 112 | ||
| 113 | *** Social Networking | |
| 114 | - [[https://apps.apple.com/us/app/multitab-for-tumblr/id1071533778][MultiTab T]] (=*=) - A gallery-based Tumblr client with some unique features, | |
| 115 | such as tab history and sync | |
| 116 | - [[https://apps.apple.com/us/app/signal-private-messenger/id874139669][Signal]] (=*=) - A simple, powerful, and secure messenger | |
| 117 | - [[https://testflight.apple.com/join/mpVk1qIy][Three Cheers]] - A client for Tildes.net with a design focus that matches the | |
| 118 | intent of Tildes | |
| 119 | - [[https://apps.apple.com/us/app/voyager-for-lemmy/id6451429762][Voyager]] - A Lemmy client | |
| 120 | ||
| 121 | *** Sports | |
| 122 | - [[https://apps.apple.com/us/app/apple-sports/id6446788829][Apple Sports]] - Apple's new sports app - lacks notifications and live events | |
| 123 | - [[https://apps.apple.com/us/app/udisc-disc-golf/id1072228953][UDisc]] - Disc golf course maps, score cards, and more | |
| 124 | ||
| 125 | *** Utilities | |
| 126 | - [[https://apps.apple.com/us/app/backblaze/id628638330][Backblaze]] - Quickly view and manage Backblaze b2 cloud storage | |
| 127 | - [[https://apps.apple.com/us/app/mullvad-vpn/id1488466513][Mullvad VPN]] (=*=) - A private VPN service | |
| 128 | - [[https://apps.apple.com/us/app/otp-auth/id659877384][OTP Auth]] (=*=) - A minimalistic OTP app with support for biometrics, custom | |
| 129 | icons, import/export, and iCloud sync | |
| 130 | - [[https://apps.apple.com/us/app/plex-dash/id1500797677][Plex Dash]] - Stats about your Plex Media Server | |
| 131 | - [[https://apps.apple.com/us/app/safari/id1146562112][Safari]] - iOS default browser | |
| 132 | - [[https://apps.apple.com/us/app/ubiquiti-wifiman/id1385561119][Unifi WiFiman]] - Create visual layouts of WiFi strength and save heat maps to your phone | |
| 133 | ||
| 134 | ** Web Apps & Shortcuts | |
| 135 | - [[https://brutalist.report/][Brutalist Report]] - Minimal news aggregator | |
| 136 | - [[https://cyber.report/][_Cyber.Report]] - Cybersecurity news aggregator | |
| 137 | - [[https://news.ycombinator.com/][Hacker News]] - Mostly technical news | |
| 138 | - [[https://nextdns.io/][NextDNS]] - NextDNS statistics dashboard | |
| 139 | - [[https://readspike.com/][Readspike]] - Minimal news aggregator | |
content/wiki/macos.org deleted −148
| @@ -1,148 +0,0 @@ | ||
| 1 | #+title: macOS | |
| 2 | #+date: <2024-05-01> | |
| 3 | ||
| 4 | Related: | |
| 5 | ||
| 6 | - [[https://cleberg.net/wiki/hardware/][Hardware]] | |
| 7 | ||
| 8 | My primary OS. Currently running macOS Sonoma 14. This wiki page contains most | |
| 9 | of the apps I have used at one point or another across my different Macbooks. | |
| 10 | ||
| 11 | (=*=) = My favorites | |
| 12 | ||
| 13 | ** Configuration | |
| 14 | *** Disable System Services | |
| 15 | - [[https://developer.apple.com/documentation/security/disabling_and_enabling_system_integrity_protection][Disabling and Enabling System Integrity Protection]] | |
| 16 | - Disable Gatekeeper: =sudo spctl --master-disable= | |
| 17 | ||
| 18 | *** Dotfiles | |
| 19 | These are probably out of date, but they give a general idea of how I configure | |
| 20 | my machine. | |
| 21 | ||
| 22 | #+begin_src conf | |
| 23 | # ~/.zshrc | |
| 24 | export PATH="/opt/homebrew/bin:$PATH" | |
| 25 | export PATH="$HOME/.emacs.d/bin:$PATH" | |
| 26 | export EDITOR="/opt/homebrew/bin/emacs -nw" | |
| 27 | ZSH_THEME="bureau" | |
| 28 | plugins=(git zsh-autosuggestions) | |
| 29 | source $ZSH/oh-my-zsh.sh | |
| 30 | #+end_src | |
| 31 | ||
| 32 | #+begin_src conf | |
| 33 | # ~/.zprofile eval "$(/opt/homebrew/bin/brew shellenv)" | |
| 34 | #+end_src | |
| 35 | ||
| 36 | #+begin_src conf | |
| 37 | # ~/.config/skhd/skhdrc | |
| 38 | cmd - return : /Applications/iTerm.app/Contents/MacOS/iTerm2 | |
| 39 | cmd + shift - return : /Applications/LibreWolf.app/Contents/MacOS/librewolf | |
| 40 | #+end_src | |
| 41 | ||
| 42 | #+begin_src conf | |
| 43 | # ~/.config/yabai/yabairc | |
| 44 | yabai -m config \ | |
| 45 | mouse_follows_focus off \ | |
| 46 | focus_follows_mouse off \ | |
| 47 | window_origin_display default \ | |
| 48 | window_placement second_child \ | |
| 49 | window_zoom_persist on \ | |
| 50 | window_shadow on \ | |
| 51 | window_animation_duration 0.0 \ | |
| 52 | window_animation_frame_rate 120 \ | |
| 53 | window_opacity_duration 0.0 \ | |
| 54 | active_window_opacity 1.0 \ | |
| 55 | normal_window_opacity 0.90 \ | |
| 56 | window_opacity off \ | |
| 57 | insert_feedback_color 0xffd75f5f \ | |
| 58 | split_ratio 0.50 \ | |
| 59 | split_type auto \ | |
| 60 | auto_balance off \ | |
| 61 | top_padding 15 \ | |
| 62 | bottom_padding 15 \ | |
| 63 | left_padding 15 \ | |
| 64 | right_padding 15 \ | |
| 65 | window_gap 10 \ | |
| 66 | layout bsp \ | |
| 67 | mouse_modifier fn \ | |
| 68 | mouse_action1 move \ | |
| 69 | mouse_action2 resize \ | |
| 70 | mouse_drop_action swap | |
| 71 | echo "yabai configuration loaded.." | |
| 72 | #+end_src | |
| 73 | ||
| 74 | ** Software | |
| 75 | *** Browsers | |
| 76 | - [[https://librewolf.net/][Librewolf]] (=*=) - Custom version of Firefox, focused on privacy and security | |
| 77 | - [[https://bitwarden.com/][Bitwarden]] - An open source password manager | |
| 78 | - [[https://darkreader.org/][Dark Reader]] - Dark mode for all the websites | |
| 79 | - [[https://libredirect.github.io/][Libredirect]] - Automatic web redirections | |
| 80 | - [[https://strongboxsafe.com/][Strongbox]] - Keepass password manager for iOS & macOS | |
| 81 | - [[https://ublockorigin.com/][uBlock Origin]] - Free, open-source ad content blocker | |
| 82 | - [[https://github.com/ungoogled-software/ungoogled-chromium][Ungoogled Chromium]] - Google Chromium, sans integration with Google | |
| 83 | - [[https://www.gnu.org/software/emacs/manual/html_mono/eww.html][eww]] - Emacs Web Wowser, for TUI browsing | |
| 84 | - [[https://www.torproject.org/][Tor]] - Browse privately | |
| 85 | ||
| 86 | *** Command Line Tools | |
| 87 | - [[https://github.com/mr-karan/doggo][doggo]] - Command-line DNS Client for Humans | |
| 88 | - [[https://github.com/muesli/duf][duf]] - Disk Usage/Free Utility - a better 'df' alternative | |
| 89 | - [[https://github.com/bootandy/dust][dust]] - A more intuitive version of du in rust | |
| 90 | - [[https://github.com/eza-community/eza][eza]] - A modern alternative to ls | |
| 91 | - [[https://github.com/Macchina-CLI/macchina][macchina]] - A system information frontend with an emphasis on performance. | |
| 92 | - [[https://github.com/yt-dlp/yt-dlp][yt-dlp]] - A youtube-dl fork with additional features and fixes | |
| 93 | ||
| 94 | *** Communications | |
| 95 | - [[https://element.io/][Element]] - Matrix's default GUI client | |
| 96 | - [[https://github.com/tulir/gomuks][gomuks]] - A terminal based Matrix client | |
| 97 | - [[https://www.thunderbird.net/][Thunderbird]] (=*=) - An open source email client by Mozilla | |
| 98 | - [[https://signal.org/][Signal]] (=*=) - A simple, powerful, and secure messenger | |
| 99 | ||
| 100 | *** Development | |
| 101 | - [[https://www.docker.com/products/docker-desktop/][Docker Desktop]] - Docker containers for your desktop | |
| 102 | - [[https://github.com/open-webui/open-webui][open-webui]] - User-friendly WebUI for LLMs | |
| 103 | - [[https://iterm2.com/][iTerm2]] (=*=) - The best terminal for macOS, hands down | |
| 104 | - [[https://podman-desktop.io/][Podman Desktop]] (=*=) - Open source tool for containers and Kubernetes | |
| 105 | - [[https://developer.apple.com/xcode/][Xcode]] - Apple's IDE | |
| 106 | - [[https://en.wikipedia.org/wiki/Z_shell][zsh]] (=*=) - My shell preference due to its plugin and theme community | |
| 107 | - [[https://github.com/zsh-users/zsh-autosuggestions][zsh-autosuggestions]] - Fish-like autosuggestions for zsh | |
| 108 | - [[https://github.com/zsh-users/zsh-syntax-highlighting][zsh-syntax-highlighting]] - Fish shell like syntax highlighting for Zsh | |
| 109 | ||
| 110 | *** Editors | |
| 111 | - [[https://github.com/doomemacs/doomemacs][Doom Emacs]] (=*=) - An Emacs framework, great for working in org-mode | |
| 112 | - [[https://obsidian.md/][Obsidian]] - A nice Markdown-based editor based on a "vault" structure. Offers a | |
| 113 | paid sync solution and community extensions | |
| 114 | - [[https://standardnotes.com/][Standard Notes]] - A simple text editor focused on privacy and security. Offers | |
| 115 | a paid sync solution and community extensions | |
| 116 | - [[https://vscodium.com/][VSCodium]] - VS Code without proprietary blobs | |
| 117 | ||
| 118 | *** Media | |
| 119 | - [[https://skylum.com/luminar][Luminar]] - Luminar offers top-notch photo editing features- [[https://www.minecraft.net/][Minecraft]] - Block mining simulator | |
| 120 | - [[https://netnewswire.com/][NetNewsWire]] - A free and open source RSS reader for Mac, iPhone, and iPad | |
| 121 | - [[https://www.plex.tv/][Plex]] (=*=) - Desktop client for the Plex Media Server | |
| 122 | - [[https://store.steampowered.com/][Steam]] - The top gaming marketplace for computers | |
| 123 | - [[https://transmissionbt.com/][Transmission]] (=*=) - A Fast, Easy and Free Bittorrent Client | |
| 124 | - [[https://www.videolan.org/vlc/][VLC]] - A free and open source cross-platform multimedia player | |
| 125 | ||
| 126 | *** Package Management | |
| 127 | - [[https://brew.sh/][Homebrew]] (=*=) - The Missing Package Manager for macOS (or Linux) | |
| 128 | - [[https://www.macports.org/][MacPorts]] - A system to compile, install, and manage open source software | |
| 129 | ||
| 130 | *** Utilities | |
| 131 | - [[https://betterdisplay.pro/][BetterDisplay]] - Allows you to tweak a ton of features of built-in and external | |
| 132 | screens, such as scaling, configuration overrides, and color/brightness | |
| 133 | upscaling | |
| 134 | - [[https://bitwarden.com/][Bitwarden]] - An open source password manager | |
| 135 | - [[https://icemenubar.app/][Ice]] (=*=)- A powerful menu bar management tool | |
| 136 | - [[https://obdev.at/products/littlesnitch/index.html][LittleSnitch]] - Shows all network connections on your Macbook, including system | |
| 137 | and privileged services | |
| 138 | - [[https://obdev.at/products/microsnitch/index.html][MicroSnitch]] - Camera & microphone monitoring and alterting service | |
| 139 | - [[https://mullvad.net/][Mullvad]] (=*=) - A private VPN service | |
| 140 | - [[https://ollama.com/][Ollama]] - Run Llama 2, Code Llama, and other models locally on your machine | |
| 141 | - [[https://github.com/kghandour/Ollama-SwiftUI][Ollama Swift]] - User Interface made for Ollama.ai using Swift | |
| 142 | - [[https://orbstack.dev/][OrbStack]] - A fast and convenient GUI to manage Docker contains and Linux VMs | |
| 143 | - [[https://www.raycast.com/][Raycast]] - A collection of tools and shortcuts, an alternative to Spotlight | |
| 144 | - [[https://github.com/koekeishiya/skhd][skhd]] (=*=) - Simple hotkey daemon for macOS | |
| 145 | - [[https://strongboxsafe.com/][Strongbox]] - Keepass password manager for iOS & macOS | |
| 146 | - [[https://syncthing.net/][Syncthing]] (=*=) - Continuous file synchronization | |
| 147 | - [[https://www.bresink.com/osx/TinkerTool.html][TinkerTool]] - Unlock hidden configuration options for macOS | |
| 148 | - [[https://github.com/koekeishiya/yabai][yabai]] (=*=) - Automatic window tiling | |
content/wiki/services.org deleted −38
| @@ -1,38 +0,0 @@ | ||
| 1 | #+title: Services & Hosting | |
| 2 | #+date: <2025-08-22> | |
| 3 | ||
| 4 | * Domain Registration | |
| 5 | ||
| 6 | - [[https://njal.la][Njalla]]: Migrated all domains to Njalla. Some spare domains left on Cloudflare | |
| 7 | until I figure out if someone wants them or if I can just delete them | |
| 8 | outright. | |
| 9 | ||
| 10 | * DNS | |
| 11 | ||
| 12 | - [[https://njal.la][Njalla]]: I am using their name servers and DNS for my domain traffic. | |
| 13 | - [[https://mullvad.net][Mullvad]]: Since I use Mullvad's VPN on most of my devices, I am using their DNS | |
| 14 | with occasional content blockers enabled. | |
| 15 | - [[https://nextdns.io][NextDNS]]: Lastly, I enforce NextDNS's DNS at the router level on my home | |
| 16 | network so that any device without a VPN is still slightly protected and not | |
| 17 | using my ISP's DNS. | |
| 18 | ||
| 19 | * Hosting | |
| 20 | ||
| 21 | ** Web | |
| 22 | ||
| 23 | - N/A: I currently host all of my services on my server at home via Cox's | |
| 24 | residential fiber network. Since I have accounts on AWS, Azure, GCP, & IBM for | |
| 25 | my job, I use these as temporary backup solutions if I'm away from home and a | |
| 26 | service goes down that I need to use. | |
| 27 | ||
| 28 | ||
| 29 | ||
| 30 | - [[https://migadu.com/][Migadu]]: I've used a few different email providers over the last few years, but | |
| 31 | keep coming back to Migadu due to their drop-dead simplicity and proven | |
| 32 | reliability. | |
| 33 | ||
| 34 | ** Source Code | |
| 35 | ||
| 36 | - [[https://sourcehut.org/][Sourcehut]]: I flip back and forth between Sourcehut and GitHub, but I'm | |
| 37 | currently using Sourcehut. I love the minimal form factor and the company's | |
| 38 | mission, but tend to use GitHub to explore other's code. | |
content/wiki/sh.org deleted −49
| @@ -1,49 +0,0 @@ | ||
| 1 | #+title: Shell Commands & Scripts | |
| 2 | #+date: <2025-03-19> | |
| 3 | ||
| 4 | * File Loop | |
| 5 | ||
| 6 | #+begin_src shell | |
| 7 | # All files in current directory | |
| 8 | for file in *; do echo "${file}"; done | |
| 9 | ||
| 10 | # Files only | |
| 11 | for file in *; do if [ -f "$file" ]; then echo "$file"; fi; done | |
| 12 | ||
| 13 | # Directories only | |
| 14 | for file in *; do if [ -d "$file" ]; then echo "$file"; fi; done | |
| 15 | #+end_src | |
| 16 | ||
| 17 | * Exifdata | |
| 18 | ||
| 19 | #+begin_src shell | |
| 20 | sudo exiftool -r -all= -ext jpg -ext png . | |
| 21 | #+end_src | |
| 22 | ||
| 23 | * Optipng | |
| 24 | ||
| 25 | #+begin_src shell | |
| 26 | optipng -o7 image.png | |
| 27 | #+end_src | |
| 28 | ||
| 29 | * Nginx + Goaccess | |
| 30 | ||
| 31 | #+begin_src shell | |
| 32 | zcat /var/log/nginx/access.log.*.gz | goaccess /var/log/nginx/access.log - | |
| 33 | #+end_src | |
| 34 | ||
| 35 | * Distro Information | |
| 36 | ||
| 37 | #+begin_src shell | |
| 38 | echo /etc/*_ver* /etc/*-rel*; cat /etc/*_ver* /etc/*-rel* | |
| 39 | #+end_src | |
| 40 | ||
| 41 | * sed | |
| 42 | ||
| 43 | #+begin_src shell | |
| 44 | # Replace text within file | |
| 45 | sed -i '' 's/SEARCH_TEXT/REPLACEMENT_TEXT/g' file.txt | |
| 46 | ||
| 47 | # Delete empty lines | |
| 48 | sed '/^\s*$/d' | |
| 49 | #+end_src | |
publish.el −18
| @@ -44,23 +44,6 @@ | ||
| 44 | 44 | :output ".build/blog/index.html" |
| 45 | 45 | :url "/blog/") |
| 46 | 46 | |
| 47 | ;; Wiki post route | |
| 48 | (weblorg-route | |
| 49 | :name "wiki" | |
| 50 | :input-pattern "content/wiki/*.org" | |
| 51 | :template "post.html" | |
| 52 | :output ".build/wiki/{{ slug }}.html" | |
| 53 | :url "/wiki/{{ slug }}.html") | |
| 54 | ||
| 55 | ;; Wiki index page route | |
| 56 | (weblorg-route | |
| 57 | :name "wiki-index" | |
| 58 | :input-pattern "content/wiki/*.org" | |
| 59 | :input-aggregate #'weblorg-input-aggregate-all | |
| 60 | :template "wiki.html" | |
| 61 | :output ".build/wiki/index.html" | |
| 62 | :url "/wiki/") | |
| 63 | ||
| 64 | 47 | ;; Page post route |
| 65 | 48 | (weblorg-route |
| 66 | 49 | :name "pages" |
| @@ -101,7 +84,6 @@ | ||
| 101 | 84 | :output ".build/about/{{ slug }}.html" |
| 102 | 85 | :url "/about/{{ slug }}.html") |
| 103 | 86 | |
| 104 | ||
| 105 | 87 | ;; RSS feed route |
| 106 | 88 | (weblorg-route |
| 107 | 89 | :name "rss" |
theme/static/favicon.ico deleted
Binary file not shown.
theme/static/styles.css +16 −293
| @@ -1,338 +1,61 @@ | ||
| 1 | /*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */ | |
| 2 | html{line-height:1.15;-webkit-text-size-adjust:100%}main{display:block}h1{font-size:2em;margin:0.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type="button"],[type="reset"],[type="submit"],button{-webkit-appearance:button}[type="button"]::-moz-focus-inner,[type="reset"]::-moz-focus-inner,[type="submit"]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type="button"]:-moz-focusring,[type="reset"]:-moz-focusring,[type="submit"]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:0.35em 0.75em 0.625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type="checkbox"],[type="radio"]{box-sizing:border-box;padding:0}[type="number"]::-webkit-inner-spin-button,[type="number"]::-webkit-outer-spin-button{height:auto}[type="search"]{-webkit-appearance:textfield;outline-offset:-2px}[type="search"]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}template{display:none}[hidden]{display:none} | |
| 3 | ||
| 4 | /* CUSTOM CSS */ | |
| 5 | :root { | |
| 6 | --bg: #EDEDE7; | |
| 7 | --bg-bright: #E8D3BE; | |
| 8 | --fg: #201E1D; | |
| 9 | --link: #810208; | |
| 10 | --code: #810208; | |
| 11 | --border: #E8D3BE; | |
| 12 | } | |
| 13 | ||
| 14 | @media (prefers-reduced-motion: no-preference) { | |
| 15 | :root { | |
| 16 | scroll-behavior: smooth; | |
| 17 | } | |
| 18 | } | |
| 19 | ||
| 20 | 1 | body { |
| 21 | background-color: var(--bg); | |
| 22 | color: var(--fg); | |
| 23 | font-family: Iowan Old Style, Apple Garamond, Baskerville, Times New Roman, Droid Serif, Times, Source Serif Pro, serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol; | |
| 24 | font-size: 1rem; | |
| 25 | line-height: 1.5; | |
| 26 | max-width: 50em; | |
| 27 | margin: 0 auto; | |
| 28 | padding: 0 clamp(1rem, 5vw, 3rem); | |
| 29 | } | |
| 30 | ||
| 31 | @media only screen and (min-width: 768px) { | |
| 32 | body { | |
| 33 | font-size: 1.2rem; | |
| 34 | } | |
| 35 | } | |
| 36 | ||
| 37 | @media (min-width: 768px) { | |
| 38 | body { | |
| 39 | padding: 0 2rem; | |
| 40 | } | |
| 41 | } | |
| 42 | ||
| 43 | .site-nav, | |
| 44 | footer { | |
| 45 | border-color: var(--fg); | |
| 46 | } | |
| 47 | ||
| 48 | footer { | |
| 49 | padding-top: 1rem; | |
| 50 | margin: 1rem 0; | |
| 51 | } | |
| 52 | ||
| 53 | footer p { | |
| 54 | margin: 0; | |
| 2 | max-width: 50em; | |
| 3 | margin: 1.5rem; | |
| 55 | 4 | } |
| 56 | 5 | |
| 57 | ul { | |
| 58 | list-style-type: "- "; | |
| 59 | } | |
| 60 | ||
| 61 | .site-nav ul { | |
| 6 | nav ul { | |
| 62 | 7 | list-style-type: none; |
| 63 | 8 | display: flex; |
| 64 | align-items: center; | |
| 65 | 9 | padding: 0; |
| 66 | 10 | } |
| 67 | 11 | |
| 68 | .site-nav ul li { | |
| 12 | nav ul li { | |
| 69 | 13 | margin-right: 0.5rem; |
| 70 | 14 | } |
| 71 | 15 | |
| 72 | h1, | |
| 73 | h2, | |
| 74 | h3, | |
| 75 | h4 { | |
| 76 | color: var(--fg); | |
| 77 | } | |
| 78 | ||
| 79 | h1 { | |
| 80 | font-size: 1.75rem; | |
| 81 | font-weight: bold; | |
| 82 | margin-top: 1rem; | |
| 83 | margin-bottom: 0.75rem; | |
| 84 | } | |
| 85 | ||
| 86 | h2 { | |
| 87 | font-size: 1.5rem; | |
| 88 | margin-top: 1rem; | |
| 89 | margin-bottom: 0.5rem; | |
| 90 | } | |
| 91 | ||
| 92 | h3 { | |
| 93 | font-size: 1.25rem; | |
| 94 | margin-top: 1rem; | |
| 95 | margin-bottom: 0.25rem; | |
| 96 | } | |
| 97 | ||
| 98 | a, | |
| 99 | a:visited { | |
| 100 | color: var(--link); | |
| 101 | text-decoration: underline; | |
| 102 | text-decoration-skip-ink: auto; | |
| 103 | } | |
| 104 | ||
| 105 | a:focus-visible { | |
| 106 | outline: 2px solid var(--link); | |
| 107 | outline-offset: 2px; | |
| 108 | } | |
| 109 | ||
| 110 | a:hover { | |
| 111 | background: var(--link); | |
| 112 | color: var(--bg); | |
| 113 | text-decoration: none; | |
| 114 | } | |
| 115 | ||
| 116 | 16 | img { |
| 117 | 17 | border-style: none; |
| 118 | 18 | width: 100%; |
| 119 | 19 | } |
| 120 | 20 | |
| 121 | 21 | table { |
| 122 | border: 1px solid var(--border); | |
| 22 | border: 1px solid #111; | |
| 123 | 23 | border-collapse: collapse; |
| 124 | color: var(--fg); | |
| 125 | border-color: var(--bg-bright); | |
| 126 | font-size: inherit; | |
| 127 | 24 | width: 100%; |
| 128 | 25 | } |
| 129 | 26 | |
| 130 | thead, | |
| 131 | th, | |
| 132 | tr, | |
| 133 | td { | |
| 134 | border: 1px solid var(--border); | |
| 135 | padding: 0.25rem; | |
| 136 | } | |
| 137 | ||
| 138 | 27 | pre, |
| 139 | 28 | pre>code, |
| 140 | 29 | code { |
| 141 | font-family: | |
| 142 | Menlo, | |
| 143 | Consolas, | |
| 144 | Monaco, | |
| 145 | Liberation Mono, | |
| 146 | Lucida Console, | |
| 147 | monospace; | |
| 148 | 30 | font-size: 0.9rem; |
| 149 | 31 | } |
| 150 | 32 | |
| 151 | 33 | pre { |
| 152 | background-color: var(--bg-bright) !important; | |
| 34 | border: 1px solid #111; | |
| 153 | 35 | margin: 0.5rem 0; |
| 154 | 36 | padding: 0.5rem; |
| 155 | 37 | overflow-x: auto; |
| 156 | 38 | } |
| 157 | 39 | |
| 158 | :not(pre)>code { | |
| 159 | color: var(--code); | |
| 160 | } | |
| 161 | ||
| 162 | aside { | |
| 163 | background-color: var(--bg-bright); | |
| 164 | padding: 1rem; | |
| 165 | } | |
| 166 | ||
| 167 | blockquote { | |
| 168 | background-color: var(--bg-bright); | |
| 169 | border-left: 5px solid var(--link); | |
| 170 | margin: 1rem 0; | |
| 171 | padding: 0.5rem 1rem; | |
| 172 | } | |
| 173 | ||
| 174 | blockquote p { | |
| 175 | margin: 0; | |
| 176 | } | |
| 177 | ||
| 178 | .post, | |
| 179 | .wiki-post { | |
| 180 | display: flex; | |
| 181 | justify-content: space-between; | |
| 182 | } | |
| 183 | ||
| 184 | .post time { | |
| 185 | flex-shrink: 0; | |
| 186 | font-style: italic; | |
| 187 | margin-right: 0.5rem; | |
| 188 | opacity: 0.8; | |
| 189 | } | |
| 190 | ||
| 191 | .wiki-post { | |
| 192 | justify-content: space-between; | |
| 193 | } | |
| 194 | ||
| 195 | .wiki-post:first-of-type { | |
| 196 | border-bottom: 1px dotted var(--fg); | |
| 197 | margin-bottom: 1rem; | |
| 198 | } | |
| 199 | ||
| 200 | .wiki-post p { | |
| 201 | margin: 0; | |
| 202 | } | |
| 203 | ||
| 204 | .post-metadata { | |
| 205 | border: 1px dotted var(--border); | |
| 206 | padding: 1rem; | |
| 207 | } | |
| 208 | ||
| 209 | .post-metadata h1 { | |
| 210 | margin: 0; | |
| 211 | } | |
| 212 | ||
| 213 | .post-metadata p { | |
| 214 | margin: 0; | |
| 215 | } | |
| 216 | ||
| 217 | .post-metadata time { | |
| 218 | font-style: italic; | |
| 219 | } | |
| 220 | ||
| 221 | details { | |
| 40 | time { | |
| 222 | 41 | display: block; |
| 223 | margin-top: 1rem; | |
| 224 | } | |
| 225 | ||
| 226 | summary { | |
| 227 | display: list-item; | |
| 228 | font-weight: bold; | |
| 229 | } | |
| 230 | ||
| 231 | span.tag::before { | |
| 232 | content: "#"; | |
| 233 | } | |
| 234 | ||
| 235 | .footnote-definition { | |
| 236 | display: flex; | |
| 237 | justify-content: flex-start; | |
| 238 | align-items: top; | |
| 239 | margin: 1rem 0; | |
| 240 | } | |
| 241 | ||
| 242 | .footnote-definition sup { | |
| 243 | font-size: inherit; | |
| 244 | top: 0; | |
| 245 | line-height: inherit; | |
| 246 | padding-right: 0.5rem; | |
| 247 | 42 | } |
| 248 | 43 | |
| 249 | .footnote-definition sup::after { | |
| 250 | content: "."; | |
| 251 | } | |
| 252 | ||
| 253 | .footnote-definition p { | |
| 254 | display: inline-block; | |
| 255 | margin: 0; | |
| 256 | } | |
| 257 | ||
| 258 | .hidden { | |
| 259 | display: none; | |
| 260 | } | |
| 261 | ||
| 262 | .post { | |
| 263 | display: flex; | |
| 264 | flex-direction: row; | |
| 265 | margin-bottom: 1rem; | |
| 266 | } | |
| 267 | ||
| 268 | .post-content { | |
| 269 | display: flex; | |
| 270 | flex-direction: column; | |
| 271 | } | |
| 272 | ||
| 273 | .post-tags { | |
| 274 | font-size: 1rem; | |
| 275 | margin-top: 0.1rem; | |
| 276 | } | |
| 277 | ||
| 278 | .tag { | |
| 279 | margin-right: 0.3rem; | |
| 280 | font-style: normal; | |
| 281 | opacity: 0.5; | |
| 282 | } | |
| 283 | ||
| 284 | .tag::before { | |
| 285 | content: "#"; | |
| 286 | } | |
| 287 | ||
| 288 | .skip-link { | |
| 289 | position: absolute; | |
| 290 | left: -999px; | |
| 291 | top: auto; | |
| 292 | width: 1px; | |
| 293 | height: 1px; | |
| 294 | overflow: hidden; | |
| 295 | } | |
| 296 | ||
| 297 | .skip-link:focus { | |
| 298 | left: 1rem; | |
| 299 | top: 1rem; | |
| 300 | width: auto; | |
| 301 | height: auto; | |
| 302 | background: var(--bg-bright); | |
| 303 | color: var(--fg); | |
| 304 | padding: .5rem; | |
| 305 | border: 1px solid var(--fg); | |
| 44 | :not(pre)>code { | |
| 45 | color: #f00; | |
| 306 | 46 | } |
| 307 | 47 | |
| 308 | 48 | @media (prefers-color-scheme: dark) { |
| 309 | :root { | |
| 310 | --bg: #201E1D; | |
| 311 | --bg-bright: #2F2F2D; | |
| 312 | --fg: #EDEDE7; | |
| 313 | --link: #D9C2A6; | |
| 314 | --code: #D9C2A6; | |
| 315 | --border: #2F2F2D; | |
| 316 | } | |
| 317 | } | |
| 318 | ||
| 319 | @media print { | |
| 320 | 49 | body { |
| 321 | background: #fff; | |
| 322 | color: #000; | |
| 323 | font-size: 12pt; | |
| 324 | padding: 0; | |
| 325 | max-width: none; | |
| 50 | background-color: #222; | |
| 51 | color: #eee; | |
| 326 | 52 | } |
| 327 | ||
| 328 | .site-nav, | |
| 329 | footer, | |
| 330 | aside { | |
| 331 | display: none; | |
| 53 | ||
| 54 | a { | |
| 55 | color: #add8e6; | |
| 332 | 56 | } |
| 333 | 57 | |
| 334 | a::after { | |
| 335 | content: " (" attr(href) ")"; | |
| 336 | font-size: 90%; | |
| 58 | pre { | |
| 59 | border-color: #eee; | |
| 337 | 60 | } |
| 338 | 61 | } |
| \ No newline at end of file | ||
theme/templates/base.html +7 −11
| @@ -12,29 +12,25 @@ | ||
| 12 | 12 | {% if site_description is defined %}<meta name="description" content="{{ site_description }}" >{% endif %} |
| 13 | 13 | {% if site_keywords is defined %}<meta name="keywords" content="{{ site_keywords }}" >{% endif %} |
| 14 | 14 | <link rel="stylesheet" href="{{ url_for("static", file="styles.min.css") }}" type="text/css"> |
| 15 | <link rel="icon" type="image/x-icon" href="{{ url_for("static", file="favicon.ico") }}"> | |
| 15 | <link rel="icon" type="image/x-icon" href="data:,"> | |
| 16 | 16 | {% block meta %}{% endblock %} |
| 17 | 17 | {% endblock %} |
| 18 | 18 | </head> |
| 19 | 19 | <body> |
| 20 | <a href="#main" class="skip-link">Skip to content</a> | |
| 21 | <nav class="site-nav" aria-label="site-nav" role="navigation"> | |
| 20 | <nav aria-label="site-nav" role="navigation"> | |
| 22 | 21 | <ul> |
| 23 | 22 | <li><a href="/">Home</a></li> |
| 24 | 23 | <li><a href="/about/">About</a></li> |
| 25 | 24 | <li><a href="/blog/">Blog</a></li> |
| 26 | 25 | <li><a href="/services/">Services</a></li> |
| 27 | <li><a href="/wiki/">Wiki</a></li> | |
| 28 | 26 | </ul> |
| 29 | 27 | </nav> |
| 30 | <main id="main">{% block main %}{% endblock %}</main> | |
| 28 | <main>{% block main %}{% endblock %}</main> | |
| 31 | 29 | <footer> |
| 32 | <p> | |
| 33 | <a href="https://stats.uptimerobot.com/OwOWs7HU0z">Status</a> · | |
| 34 | <a href="https://git.cleberg.net/cleberg.net.git" target="_blank" | |
| 35 | rel="noopener">Source</a> · | |
| 36 | <a href="/feed.xml">RSS</a> | |
| 37 | </p> | |
| 30 | <a href="https://stats.uptimerobot.com/OwOWs7HU0z">Status</a> · | |
| 31 | <a href="https://git.cleberg.net/cleberg.net.git" target="_blank" | |
| 32 | rel="noopener">Source</a> · | |
| 33 | <a href="/feed.xml">RSS</a> | |
| 38 | 34 | </footer> |
| 39 | 35 | </body> |
| 40 | 36 | </html> |
theme/templates/blog.html +3 −11
| @@ -10,19 +10,11 @@ main %} | ||
| 10 | 10 | </p> |
| 11 | 11 | <br> |
| 12 | 12 | {% for post in posts %} |
| 13 | <div class="post"> | |
| 14 | <div class="post-content"> | |
| 15 | <a href='{{ url_for("blog", slug=post.slug) }}'>{{ post.title }}</a> | |
| 16 | {% if post.filetags %} | |
| 17 | <div class="post-tags"> | |
| 18 | {% for tag in post.filetags %} | |
| 19 | <span class="tag">{{ tag }}</span> | |
| 20 | {% endfor %} | |
| 21 | </div> | |
| 22 | {% endif %} | |
| 23 | </div> | |
| 13 | <div> | |
| 24 | 14 | <time datetime='{{ post.date | strftime("%Y-%m-%d") }}' |
| 25 | 15 | >{{ post.date|strftime("%B %d, %Y") }}</time |
| 26 | 16 | > |
| 17 | <a href='{{ url_for("blog", slug=post.slug) }}'>{{ post.title }}</a> | |
| 27 | 18 | </div> |
| 19 | <br> | |
| 28 | 20 | {% endfor %} {% endblock %} |
theme/templates/index.html +1 −14
| @@ -9,21 +9,8 @@ | ||
| 9 | 9 | </blockquote> |
| 10 | 10 | </section> |
| 11 | 11 | <section> |
| 12 | <h2>Blog Posts</h2> | |
| 12 | <h2>Recent Posts</h2> | |
| 13 | 13 | <!-- BEGIN_POSTS --> |
| 14 | 14 | <!-- END_POSTS --> |
| 15 | <a href="/blog/">All Posts →</a> | |
| 16 | </section> | |
| 17 | ||
| 18 | <section> | |
| 19 | <h2>Everything Else</h2> | |
| 20 | <ul> | |
| 21 | <li><a href="/about/">About</a></li> | |
| 22 | <li><a href="https://cv.cleberg.net">Curriculum Vitae</a></li> | |
| 23 | <li><a href="/now/">Now</a></li> | |
| 24 | <li><a href="/salary/">Salary</a></li> | |
| 25 | <li><a href="/services/">Services</a></li> | |
| 26 | <li><a href="/wiki/">Wiki</a></li> | |
| 27 | </ul> | |
| 28 | 15 | </section> |
| 29 | 16 | {% endblock %} |
theme/templates/wiki.html deleted −12
| @@ -1,12 +0,0 @@ | ||
| 1 | {% extends "base.html" %} {% block subtitle %}Wiki | {% endblock %} {% block | |
| 2 | main %} | |
| 3 | <h1>Wiki</h1> | |
| 4 | <p>Use <code>Ctrl + F</code> to search wiki pages for keywords.</p> | |
| 5 | {% for post in posts %} | |
| 6 | <div class="post"> | |
| 7 | <a href='{{ url_for("wiki", slug=post.slug) }}'>{{ post.title }}</a> | |
| 8 | <time datetime='{{ post.date | strftime("%Y-%m-%d") }}' | |
| 9 | >{{ post.date|strftime("%B %d, %Y") }}</time | |
| 10 | > | |
| 11 | </div> | |
| 12 | {% endfor %} {% endblock %} | |