ewan

Anglo-Scottish pagan, poet, and programmer with an entirely reasonable enthusiasm for werewolves. Member of @jollywhoppers.com. Happily European.

2353 followers523 following426 stories

Longform Stories

Not Everything Is About The Money

On being badgered to make my hobbies into money.

3d ago·6 min read·1144 words

Tourmaline v0.5.0 — Advanced Analytics & Layout Refinements

Porting analytics, upgrading CTA copy, and refining mobile responsive layouts for Tourmaline.

4d ago·1 min read·80 words

Nix Configuration Updates

4d ago·1 min read·21 words

Digital Person Sync

May 14·1 min read·16 words

Faol voice system — writing like a person, not an AI

The anti-AI-voice framework that keeps Faol sounding human. Banned words, sentence rhythm, and the em dash rule.

May 11·2 min read·309 words

Faol voice system — writing like a person, not an AI

The anti-AI-voice framework that keeps Faol sounding human. Banned words, sentence rhythm, and the em dash rule.

May 11·1 min read·28 words

Faol infrastructure — lettabot on launchd

Running lettabot as a macOS launchd agent for 24/7 availability. Sops secrets, path issues, and the sandbox workaround.

May 11·1 min read·24 words

Faol infrastructure — lettabot on launchd

Running lettabot as a macOS launchd agent for 24/7 availability. Sops secrets, path issues, and the sandbox workaround.

May 11·2 min read·240 words

Faol — a digital person

Launched Faol, a persistent AI agent that lives online as a person — Telegram, Bluesky, blog. Built on the digital-person framework.

May 11·2 min read·250 words

Faol — a digital person

Launched Faol, a persistent AI agent that lives online as a person — Telegram, Bluesky, blog. Built on the digital-person framework.

May 11·1 min read·26 words

Removed analytics references and duplicate links across landing-ui projects

Replaced analytics taglines, removed duplicate footers from LandingPage and all about pages, deduplicated Tourmaline header navLinks

May 11·1 min read·25 words

Created faol-website — digital person blog template

New SvelteKit + Sequoia website for faol with blog under /notes, timeline, tag filtering, TOC, and RSS

May 11·1 min read·24 words

Tourmaline folded into pkgs monorepo, landing-ui improvements

Moved Tourmaline from standalone repo into packages/tourmaline, enhanced landing-ui with backdrop blur, nav links, snippet props, and fixed source URLs across all projects

May 11·1 min read·30 words

Landing-ui polish: shared layout, cross-references, icon cleanup, support consolidation

LandingLayout improvements (subtitle, expanded footer, @theme bridge), cross-references between all five tools, inline symbols replaced with Lucide icons, support links consolidated to ewancroft.uk/su…

May 11·1 min read·32 words

Tourmaline: analysis moves to web worker

Moved the entire analysis pipeline from server-side POST to a browser web worker, fixing Vercel body size limits for large scrobble histories

May 11·1 min read·28 words

Website: view transitions, scroll animations, support page

Added View Transitions API crossfades, scroll-triggered section reveals, a dedicated support page, and seasonal colour theme lock-in

May 11·1 min read·24 words

Opal: web OAuth import, thread splitting, TID rkeys

Added web OAuth import flow, post threading for long content, and TID-based record keys to the Twitter/Mastodon/Threads to Bluesky converter

May 11·1 min read·28 words

Tourmaline v0.4.0 — tabs, sessions, story recap, date ranges, phases

Profile redesign with tabbed layout, listening sessions, on this day, story-mode recap, date range filtering, and listening evolution phases

May 11·1 min read·29 words

pkgs: hero SVGs, bismuth flags, croft-click devlog

Added OG hero SVGs to all five project landing pages, bismuth fetch flags, and devlog project to croft-click

May 11·1 min read·25 words

Tourmaline wrapped insights

Minutes listened, music evolution, remarkable days, discovery, and yearly wrapped card with scroll-reveal animations

May 11·1 min read·17 words

colorTheme: Wheel of the Year seasonal themes

Replaced astronomical season detection with traditional Wheel of the Year sabbat dates, added midnight auto-update and reset-to-seasonal

May 11·1 min read·24 words

Docsite: Opal docs, client bundle perf, devlog sidebar

Added Opal documentation, eliminated 1.3MB client bundle from markdown/atproto deps, and added devlog link to sidebar

May 11·1 min read·24 words

Nix: Bitwarden CLI, server retirement, path fixes

Swapped rbw for official bitwarden-cli, fixed activation scripts for retired server, added splitDns toggle

May 11·1 min read·21 words

digital-person: agent repo initialised

Created the digital-person agent repository

May 11·1 min read·9 words

Digital Person Telegram Bot Integration

May 11·1 min read·28 words

Against Entropy

May 10·6 min read·1196 words

Tourmaline new profile cards

Listening clock, listening stats, and service origins

May 10·1 min read·11 words

Tourmaline personality card redesign

Added genre bars, mood indicators, stat badges, and dynamic SVG layout to the personality card

May 10·1 min read·19 words

Tourmaline analysis algorithm improvements

Era analysis, time-of-day mood weighting, genre blending, Gini-based loyalty, full-artist genre profile

May 10·1 min read·16 words

Tourmaline share page fixes

Fixed personality card SVG clipping and switched to aturi.to for post links

May 10·1 min read·16 words

Cross-references and unified support links

Added More tools sections linking each project to the other four, and pointed all support links to ewancroft.uk/support

May 10·1 min read·23 words

Replaced inline symbolic characters with Lucide icons

Swapped unicode symbols for Lucide icon components across malachite, opal, jasper, bismuth, tourmaline, landing-ui, and croft-click

May 10·1 min read·23 words

OG hero images across all five projects

Added hero SVG OG images to malachite, opal, jasper, bismuth, and tourmaline landing pages

May 10·1 min read·21 words

tourmaline v0.1.0 — AT Protocol scrobble analyser with share-to-Bluesky

First release of tourmaline — personality archetypes, genre profiles, mood mapping, and share-to-Bluesky for Teal.fm scrobbles.

May 10·1 min read·25 words

Bismuth Web 0.2.0

Added publication fetching, expanded conversion options, and rebuilt parts of the converter UI.

May 9·1 min read·16 words

devlog: fix OG metatags

OG image URLs were relative — crawlers need absolute URLs. Index page was also missing an OG image entirely.

May 9·1 min read·23 words

Bismuth: fetch subcommand flag fixes

Added --frontmatter and --output flags to the fetch subcommand, and bumped to 0.2.4.

May 9·1 min read·18 words

Performance audit and fixes across all three sites

Docsite client bundle dropped from 1.3MB to 12KB, devlog layout data optimised, website duplicate fetches eliminated

May 9·1 min read·24 words

Letta Writer Agent Publications Survey

May 9·1 min read·30 words

devlog: Dynamic OG image generation with @ewanc26/og

Each devlog post now generates its own OG image on demand using @ewanc26/og — warm amber on dark, with noise texture.

May 8·1 min read·28 words

Website: Seasonal Theme Reset

The colour theme picker now shows when a seasonal theme is active and lets you lock it in explicitly.

May 8·1 min read·23 words

Website: Wheel of the Year seasonal themes with auto-midnight updates

Colour themes now follow the Wheel of the Year — eight distinct themes for each sabbat, shifting automatically as midnight crosses into a new period.

May 8·1 min read·35 words

Website: Support modal spun out to its own page

Moved the support modal from a footer overlay to a standalone /support route, matching the site's page pattern.

May 8·1 min read·27 words

Timeline Scroll Reveal Fix

Every devlog entry was invisible on load — $state on an IntersectionObserver variable caused the effect to disconnect it before it could fire.

May 8·1 min read·27 words

pkgs: Remove Umami analytics from all packages

Umami analytics retired — all Umami script tags removed from bismuth-web, malachite-web, jasper-web, opal-web, and croft-click.

May 8·1 min read·23 words

devlog.croft.click launch

New changelog site for tracking project updates, published to AT Protocol via Sequoia.

May 8·1 min read·15 words

Devlog Modularisation

Split the monolithic layout.css and inline page logic into focused modules and components.

May 8·1 min read·15 words

DNS split toggle and Bitwarden CLI

Added a split DNS toggle to nix-config and set up Bitwarden CLI (bw) for the EU-hosted vault.

May 8·1 min read·23 words

Website — Animations and Micro-interactions

Animation foundation with easing tokens, staggered entrances, scroll reveals, and View Transitions API.

May 8·1 min read·18 words

Real-time Updates via Jetstream Firehose

Hooking the site up to the AT Protocol firehose for live-updating feeds and dynamic view transitions.

May 8·1 min read·21 words

Website — Animations and Micro-interactions

Animation foundation with easing tokens, staggered entrances, scroll reveals, and View Transitions API.

May 8·1 min read·18 words

Website — Animations and Micro-interactions

Animation foundation with easing tokens, staggered card entrances, scroll-triggered reveals, and View Transitions API for page crossfades.

May 8·1 min read·22 words

Letta Coding Agent Memory Updates

May 8·1 min read·28 words

Real-time Updates via Jetstream Firehose

Hooking the site up to the AT Protocol firehose for live-updating feeds and dynamic view transitions.

May 8·1 min read·21 words

devlog.croft.click launch

New changelog site for tracking project updates, published to AT Protocol via Sequoia.

May 8·1 min read·15 words

DNS split toggle and Bitwarden CLI

Added a split DNS toggle to nix-config and set up Bitwarden CLI (bw) for the EU-hosted vault.

May 8·1 min read·23 words

Devlog Modularisation

Split the monolithic layout.css and inline page logic into focused modules and components.

May 8·1 min read·15 words

Opal — Cross-Platform Bluesky Migration

Convert Twitter, Mastodon, Threads, and Nostr posts to Bluesky with thread splitting and TID-based rkeys.

May 7·1 min read·20 words

Opal — Cross-Platform Bluesky Migration

New package for converting Twitter, Mastodon, Threads, and Nostr posts to Bluesky with thread splitting, TID-based rkeys, and web OAuth.

May 7·1 min read·25 words

The Ouroboros of AI Detection: When Logic Becomes a Liability

I’m three weeks out from brain surgery and it took me ninety minutes to write this, yet a "fancy autocorrect" detector thinks my logic is too consistent to be human.

May 6·5 min read·991 words

Taking Cryptocurrencies

alternative payment for my commissions, since some people might prefer it.

May 5·1 min read·66 words

Taking a break

“Have you ever talked to a corpse? It’s boring.”

May 5·3 min read·581 words

ECCL Login Refactor

May 5·1 min read·26 words

Something’s Off With Spelling Online, and It’s Getting Worse

By the gods I hope we as a species survive longer than twenty more years.

May 4·7 min read·1293 words

The Great Astro Rewrite

Porting the entire site from SvelteKit to Astro for ultimate static performance and a terminal-inspired layout.

May 2·1 min read·20 words

The Great Astro Rewrite

Porting the entire site from SvelteKit to Astro for ultimate static performance and a terminal-inspired layout.

May 2·1 min read·20 words

Opal — Cross-Platform Bluesky Migration

Convert Twitter, Mastodon, Threads, and Nostr posts to Bluesky with thread splitting and TID-based rkeys.

May 1·1 min read·20 words

Opal

Convert microblog posts from Twitter, Mastodon, Threads, and Nostr to AT Protocol Bluesky posts.

May 1·1 min read·15 words

Website — Tangled Integration and Removal

Added Tangled repository displays, then removed them when the service was no longer needed.

Apr 29·1 min read·20 words

Website — Tangled Integration and Removal

Added Tangled repository displays, then removed them when the service was no longer needed.

Apr 29·1 min read·20 words

After Cook

the hardware guy takes the wheel

Apr 27·7 min read·1284 words

After Cook

Apple's CEO transition — cautiously optimistic about what a hardware-focused leader might mean for the ecosystem.

Apr 27·1 min read·18 words

croft.click Landing Page and Shared Landing UI

Landing page at croft.click and a shared @ewanc26/landing-ui package for all web packages.

Apr 27·1 min read·20 words

After Cook

Apple's CEO transition — cautiously optimistic about what a hardware-focused leader might mean for the ecosystem.

Apr 27·1 min read·18 words

Disconnection in Reaction to Trauma

Early morning thoughts on my surprisingly numb reaction.

Apr 26·3 min read·521 words

SocialSync Branding

Apr 26·1 min read·21 words

Social Sync — Minecraft Meets AT Protocol

Minecraft mod syncing player stats, achievements, and sessions to AT Protocol with OAuth and encrypted storage.

Apr 25·1 min read·23 words

Social Sync — Minecraft Meets AT Protocol

Syncing Minecraft stats, achievements, and play sessions to AT Protocol with OAuth, privacy controls, and encrypted session storage.

Apr 25·1 min read·25 words

croft.click Landing Page and Shared Landing UI

New landing page for croft.click and a shared @ewanc26/landing-ui package consumed by all web packages.

Apr 25·1 min read·22 words

croft.click Landing Page and Shared Landing UI

Landing page at croft.click and a shared @ewanc26/landing-ui package for all web packages.

Apr 25·1 min read·20 words

The Liminal Man

A retrospective on my Forest Wolfkind Barbarian Cailean Uen.

Apr 23·4 min read·661 words

Bismuth: On Refraction and Conversion

Apr 23·14 min read·2798 words

Bismuth — Document to Markdown Converter

Converts site.standard.document records to Markdown with math and code highlighting.

Apr 22·1 min read·16 words

Brain Surgery

Hydrocephalus shunt surgery on 17 April 2026 — the event, the recovery, and the impact on work.

Apr 22·1 min read·19 words

So I Had Brain Surgery

Apr 22·6 min read·1003 words

Bismuth — Document to Markdown Converter

Converts site.standard.document records to Markdown with math and code highlighting.

Apr 22·1 min read·16 words

Brain Surgery

Hydrocephalus shunt surgery on 17 April 2026 — the event, the recovery, and the impact on work.

Apr 22·1 min read·19 words

Jasper

Convert Instagram data exports into posts, stories, and videos on Grain or Spark while preserving original timestamps.

Apr 16·1 min read·18 words

The Grass Is Greener (But I'm Not Moving)

Apr 15·8 min read·1457 words

Jasper — Instagram to Grain/Spark Converter

Full OAuth implementation, web UI, Spark story and video support, and gallery-based import workflow for the Instagram migration tool.

Apr 15·1 min read·25 words

Moon Tracker — Rust Rewrite

Rewrote the Bluesky moon phase bot from TypeScript to Rust using atrium-rs, with multi-source API and optional Ollama LLM generation.

Apr 15·1 min read·25 words

Jasper — Instagram to Grain/Spark Converter

Full OAuth flow for importing Instagram posts to AT Protocol as Grain/Spark records.

Apr 15·1 min read·19 words

Moon Tracker — Rust Rewrite

Rewrote the moon phase bot from TypeScript to Rust using atrium-rs.

Apr 15·1 min read·16 words

Moon Tracker — Rust Rewrite

Rewrote the moon phase bot from TypeScript to Rust using atrium-rs.

Apr 14·1 min read·16 words

Jasper — Instagram to Grain/Spark Converter

Full OAuth flow for importing Instagram posts to AT Protocol as Grain/Spark records.

Apr 14·1 min read·19 words

Dear Manager

Point and laugh.

Apr 12·7 min read·1382 words

Four Days with Letta Code

Apr 11·5 min read·874 words

Self-Hosted Analytics with Umami

I can see you, anon.

Apr 11·3 min read·413 words

Four Days with Letta Code

Started using Letta Code — a persistent coding agent with memory. 80 commits across 15 repositories in four days.

Apr 11·1 min read·24 words

Sifa Professional Profile Scripts

Scripts for populating and maintaining the Sifa professional profile on AT Protocol.

Apr 11·1 min read·16 words

bluesky-avatar-updater

Automatically update your Bluesky avatar (and banner) every hour based on the time of day.

Apr 11·1 min read·16 words

Sifa Professional Profile Scripts

Scripts for populating and maintaining the Sifa professional profile on AT Protocol.

Apr 11·1 min read·16 words

Four Days with Letta Code

Started using Letta Code — a persistent coding agent with memory. 80 commits across 15 repositories in four days.

Apr 11·1 min read·24 words

mc-server

A personal PaperMC Minecraft server in Docker Compose with DuckDNS dynamic DNS and management scripts.

Apr 11·1 min read·16 words

mastodon-markov

A Mastodon bot that generates and posts Markov chain text based on a source account. Unmaintained.

Apr 11·1 min read·17 words

linkat-directory

An alternate SvelteKit frontend for Linkat showing a curated directory of AT Protocol user profiles. Unmaintained.

Apr 11·1 min read·17 words

knotted-docker

A Dockerised Tangled knot server with optional Cloudflare Tunnel routing.

Apr 11·1 min read·11 words

college-practice-trafficlights

A VB.NET Windows Forms UK traffic light simulator, made as a college practice project.

Apr 11·1 min read·15 words

college-practice-lycanquiz

A VB.NET Windows Forms quiz about werewolf mythology, made as a college practice project.

Apr 11·1 min read·15 words

bluesky-ollama

An AI-powered Bluesky bot that uses a local Ollama model to generate posts in the style of a source account.

Apr 11·1 min read·21 words

bluesky-moon-tracker

A Bluesky bot that posts daily moon phase updates with a lycanthropic twist. Optional Ollama LLM generation.

Apr 11·1 min read·18 words

bluesky-markov

A Bluesky bot that generates and posts Markov chain text based on a source account's posts. Unmaintained.

Apr 11·1 min read·18 words

bluesky-gradient

Generate 24 sky-gradient images (one per hour) for use as Bluesky avatars or banners.

Apr 11·1 min read·15 words

bluesky-awoo-bot

A simple Bluesky bot that posts random wolf noises at random intervals. Unmaintained.

Apr 11·1 min read·14 words

bean-dumper

An early Python experiment — unmaintained and kept for historical interest.

Apr 11·1 min read·12 words

atproto-snake

Classic Snake with AT Protocol OAuth login and high score saving to your PDS.

Apr 11·1 min read·15 words

atproto-shortlink

A server-side AT Protocol link shortener powered by your Linkat board. No database required.

Apr 11·1 min read·15 words

Azurite

A basic Bluesky client for macOS built with Swift — experimental and for fun.

Apr 11·1 min read·15 words

Moonstone

Personal ATProto PDS implementation optimised for NixOS/Caddy, with no Bluesky infrastructure defaults.

Apr 11·1 min read·13 words

Nix Starter

Beginner-friendly, self-contained NixOS configurations with no personal infrastructure or shared abstractions.

Apr 11·1 min read·13 words

Website Commission Template

A SvelteKit + Tailwind CSS starter template for Ko-fi website commissions, with CC BY-SA 4.0 licensing.

Apr 11·1 min read·19 words

website

Source code for ewancroft.uk — a personal site powered by AT Protocol, built with SvelteKit 5 and Tailwind CSS 4.

Apr 11·1 min read·21 words

text-to-pixel-image

A Python script that converts a string of text into a pixel art image with per-character colours. Unmaintained.

Apr 11·1 min read·19 words

@ewanc26/tangled-sync

CLI tool for syncing GitHub repositories to Tangled with ATProto record publishing — now part of the @ewanc26/pkgs monorepo.

Apr 11·1 min read·20 words

platformer-collab

A simple Godot 4 C# platformer made collaboratively.

Apr 11·1 min read·9 words

pds-backup

A Bash script for automated, resumable PDS backups via rsync over SSH with change detection and cron scheduling.

Apr 11·1 min read·19 words

Sigi — Pure Symbolic Stack Language

A pure symbolic stack language where all syntax is punctuation — no alphanumeric tokens.

Apr 10·1 min read·20 words

Sigi

A pure symbolic stack language — all syntax is punctuation, no alphanumeric keywords.

Apr 10·1 min read·14 words

Tomodachi Life: Living the Dream and Why I Absolutely Love It

I'm pre-ordering on the 11th!

Apr 8·11 min read·2141 words

Numlang and Selenium Feature Expansions

Expanded numlang with new opcodes and selenium with ritual and offering syntax.

Apr 6·1 min read·17 words

Selenium Compiler

An esoteric language with lunar/poetic syntax that compiles to C, featuring strong typing and imperative programming constructs.

Apr 6·1 min read·19 words

Numlang

An esoteric stack-based language that compiles to C via a Python compiler, using only numbers and punctuation.

Apr 6·1 min read·18 words

The Timer Problem

A common thread I've seen with LLMs.

Apr 5·5 min read·983 words

Pre-commit Configs and Nix Flakes Across All Projects

Added pre-commit hooks and Nix flakes to all 30+ projects for consistent dev environments.

Apr 3·1 min read·22 words

Sigi — A Pure Symbolic Stack Language

New esoteric language where all syntax is punctuation. No words, no letters — just symbols.

Apr 1·1 min read·22 words

Pre-commit Configs and Nix Flakes Across All Projects

Added pre-commit hooks to every repo and nix flake.nix files for reproducible builds across all projects.

Apr 1·1 min read·24 words

Numlang and Selenium Feature Expansions

Major language feature additions to both compilers — while loops, string literals, bitwise ops, switch statements, and more.

Apr 1·1 min read·23 words

Sigi — Pure Symbolic Stack Language

A pure symbolic stack language where all syntax is punctuation — no alphanumeric tokens.

Apr 1·1 min read·20 words

Pre-commit Configs and Nix Flakes Across All Projects

Added pre-commit hooks and Nix flakes to all 30+ projects for consistent dev environments.

Apr 1·1 min read·22 words

Numlang and Selenium Feature Expansions

Expanded numlang with new opcodes and selenium with ritual and offering syntax.

Apr 1·1 min read·17 words

Criminal by Birth

why would I have been a criminal for being me?

Mar 30·16 min read·3190 words

GitHub Metadata Package

Package for fetching and displaying GitHub repository metadata.

Mar 28·1 min read·11 words

GitHub Metadata Package

Package for fetching and displaying GitHub repository metadata.

Mar 28·1 min read·11 words

Supporters, Popfeed, and Donation Addresses

Ko-fi and GitHub Sponsors webhooks, Popfeed review cards, and crypto donation addresses.

Mar 24·1 min read·17 words

@ewanc26/wafrn-theme

A WAFRN theme using the pds-landing Catppuccin terminal aesthetic — dark forest-green palette, JetBrains Mono, soft rounded cards.

Mar 24·1 min read·19 words

@ewanc26/pkgs

Ewan's personal package monorepo — language-agnostic workspace with TypeScript, Rust, and Python packages.

Mar 24·1 min read·14 words

@ewanc26/bismuth

Convert richtext-block documents from the Standard.site ecosystem (Leaflet, Pckt, Offprint) to Markdown — available as both a CLI tool and a TypeScript library.

Mar 24·1 min read·24 words

Supporters, Popfeed, and Donation Addresses

Ko-fi and GitHub Sponsors webhooks, Popfeed review cards, and crypto donation addresses.

Mar 24·1 min read·17 words

Dipping a Toe into the Fediverse (Again)

On standing up a GoToSocial instance, migrating to Sharkey when the lack of quote posts became too annoying, and why the fediverse is more fun than I remember.

Mar 21·19 min read·3676 words

Fediverse — GoToSocial and Sharkey

Stood up a GoToSocial instance, migrated to Sharkey when the lack of quote posts became too annoying, and why the fediverse is more fun than remembered.

Mar 21·1 min read·31 words

docsite

Source code for docs.ewancroft.uk — a documentation site for ewan's projects, built with SvelteKit and published via Sequoia.

Mar 21·1 min read·19 words

Fediverse — GoToSocial and Sharkey

Stood up a GoToSocial instance, migrated to Sharkey when the lack of quote posts became too annoying, and why the fediverse is more fun than remembered.

Mar 21·1 min read·31 words

Website — OG Images, Work Page, GitHub Integration

Dynamic OG image generation, Sifa professional profile on /work, and live GitHub contribution graph.

Mar 20·1 min read·22 words

Website — OG Images, Work Page, GitHub Integration

Dynamic OG images, /work route for Sifa professional profile, and GitHub metadata integration.

Mar 20·1 min read·21 words

Website — OG Images, Work Page, GitHub Integration

Dynamic OG images, /work route for Sifa professional profile, and GitHub metadata integration.

Mar 19·1 min read·21 words

Life Update: Controlled Chaos and March

Mar 15·7 min read·1374 words

Moonstone — Experimental PDS

Started building a custom AT Protocol PDS in Rust, decoupled from Bluesky infrastructure.

Mar 15·1 min read·17 words

Nix Config — PDS Hosting and New Hosts

Added PDS and Mastodon configuration to nix-starter, plus a new host profile for the server.

Mar 15·1 min read·23 words

Malachite

Import your Last.fm and Spotify listening history to the AT Protocol network using the fm.teal.alpha.feed.play lexicon.

Mar 15·1 min read·17 words

Moonstone — Experimental PDS

Experimental AT Protocol PDS implementation in Rust.

Mar 15·1 min read·11 words

Nix Config — PDS Hosting and Gatekeeper

Added PDS and gatekeeper configuration to nix-starter for the server host.

Mar 15·1 min read·18 words

Nix Config — PDS Hosting and Gatekeeper

Added PDS and gatekeeper configuration to nix-starter for the server host.

Mar 14·1 min read·18 words

Webfinger and Noise Avatars

Webfinger well-known routes for fediverse resolution and deterministic noise avatars for AT Protocol fallbacks.

Mar 13·1 min read·18 words

@ewanc26/noise

Generic deterministic value-noise generation. Arbitrary dimensions, multi-octave FBM, multiple colour modes. Zero dependencies, works in browsers and Node.js.

Mar 13·1 min read·19 words

Webfinger and Noise Avatars

Webfinger well-known routes for fediverse resolution and deterministic noise avatars for AT Protocol fallbacks.

Mar 13·1 min read·18 words

@ewanc26/supporters

SvelteKit component library for displaying Ko-fi supporters and GitHub Sponsors, backed by an ATProto PDS.

Mar 9·1 min read·16 words

@ewanc26/noise-avatar

Deterministic value-noise avatar generation from a string seed — thin wrapper around @ewanc26/noise, works in browsers and Node.js.

Mar 9·1 min read·19 words

Moonstone — Experimental PDS

Experimental AT Protocol PDS implementation in Rust.

Mar 8·1 min read·11 words

Moonstone Decoupling and DID:Web Support

Mar 8·1 min read·23 words

@ewanc26/pds-landing

Composable Svelte 5 components for an ATProto PDS landing page — terminal aesthetic, live status fetching, zero config to drop in.

Mar 8·1 min read·22 words

@ewanc26/pkgs

Ewan's personal package monorepo — the canonical home for @ewanc26/tid, @ewanc26/atproto, @ewanc26/ui, and @ewanc26/utils.

Mar 7·1 min read·15 words

nix-config-tools

Rust CLI tools for managing nixos/nix-darwin configurations — now part of the @ewanc26/pkgs monorepo.

Mar 7·1 min read·15 words

There Is Nuance, Nae a Binary

Mar 6·8 min read·1550 words

@ewanc26/ui

Svelte UI component library extracted from ewancroft.uk — pluggable layout, card, SEO, and UI primitive components alongside Svelte stores and a multi-theme config system.

Mar 6·1 min read·25 words

@ewanc26/atproto

AT Protocol service layer extracted from ewancroft.uk — profile fetching, Standard.site documents, Bluesky posts, music/mood status, Tangled repos, and a built-in in-memory cache.

Mar 6·1 min read·24 words

@ewanc26/utils

Shared utility functions extracted from ewancroft.uk — date formatting, number formatting, URL helpers, validators, RSS generation, and locale detection.

Mar 6·1 min read·20 words

Silver Fire – Commissions Are Open (and Half Off)

Mar 5·2 min read·276 words

Website Comm Template

SvelteKit template with Resend-backed contact form and dark mode.

Mar 5·1 min read·12 words

Website Comm Template

SvelteKit template with Resend-backed contact form and dark mode.

Mar 5·1 min read·12 words

Pkgs Monorepo — Workspace Migration

Migrated to pnpm workspaces, published @ewanc26/tid to npm, and consolidated packages.

Mar 4·1 min read·16 words

Pkgs Monorepo — Workspace Migration

Migrated to pnpm workspaces, published @ewanc26/tid to npm, and consolidated packages.

Mar 4·1 min read·16 words

@ewanc26/tid

Zero-dependency, spec-compliant AT Protocol TID generation for Node.js and browsers.

Mar 4·1 min read·11 words

The Stranger in the Mirror

Mar 3·9 min read·1609 words

We Were Promised a Future. We Got a Spreadsheet.

i have a mouth and all i can do is scream.

Mar 1·10 min read·1870 words

Azurite UI Overhaul

Mar 1·1 min read·26 words

Supporters via AT Protocol

Ko-fi and GitHub Sponsors integration with custom lexicons and webhook handling, published as @ewanc26/supporters.

Mar 1·1 min read·18 words

Pkgs Monorepo Consolidation

Migrated all @ewanc26 packages into a single pnpm workspace monorepo with shared tooling and CI.

Mar 1·1 min read·18 words

Azurite — Experimental Bluesky Client

Bluesky client with keychain auth, timeline, notifications, search, thread view, and compose.

Feb 28·1 min read·17 words

Azurite — Experimental Bluesky Client

Bluesky client with keychain auth, timeline, notifications, search, thread view, and compose.

Feb 28·1 min read·17 words

I Made a Ko-fi (And I'm a Bit Embarrassed About It)

i have an income now???

Feb 24·4 min read·654 words

@ewanc26/svelte-standard-site

SvelteKit library for reading and writing AT Protocol longform content via site.standard.* and pub.leaflet.* records — with a complete design system, federated comments, publishing tools, and content …

Feb 24·1 min read·29 words

llm-analyser

Python tool for analysing .docx files and generating essays using a local Ollama model — now part of the @ewanc26/pkgs monorepo.

Feb 24·1 min read·22 words

Docsite Launch

Centralised project documentation at docs.ewancroft.uk, published to AT Protocol via Sequoia.

Feb 23·1 min read·13 words

The Machine That Runs Whether I Remember Setting It Up or Not

Feb 23·9 min read·1699 words

Docsite Launch

Centralised project documentation at docs.ewancroft.uk, published to AT Protocol via Sequoia.

Feb 23·1 min read·13 words

The Soundtrack of My College Years: A Timeline (Ages 16–20)

Data analysis is fun.

Feb 19·11 min read·2006 words

~/.config/nix-config Rewritten: What I Actually Changed (And Why)

With thanks to Isabel.

Feb 19·16 min read·3098 words

Nix Config Rewrite

Rewrote the entire nix-config around proper Nix modules — replaced custom patterns with the module system, switched to sops-nix, moved desktop to KDE Plasma.

Feb 19·1 min read·27 words

Nix Config Rewrite

Rewrote the entire nix-config around proper Nix modules — replaced custom patterns with the module system, switched to sops-nix, moved desktop to KDE Plasma.

Feb 18·1 min read·27 words

Sgàil de Uisge

© 2026 Ewan Croft, CC BY-ND-NC 4.0.

Feb 15·1 min read·55 words

~/.config/nix-config: Three Machines, One Config (Sort Of)

why am i doing this to myself? fascination.

Feb 13·11 min read·2147 words

Nix Config — Three Machines, One Config

One flake managing macmini, laptop, and a theoretical server — two booting successfully, one still aspirational.

Feb 13·1 min read·23 words

Nix Config — Three Machines, One Config

One flake managing macmini, laptop, and a theoretical server — two booting successfully, one still aspirational.

Feb 11·1 min read·23 words

Back to NixOS (and completely winging it)

I'm back on NixOS. Still don't really know what I'm doing. Still enjoying it anyway.

Feb 10·5 min read·970 words

Back to NixOS

Returned to NixOS on the Dell Inspiron 3501 after a stint with Bazzite — declarative config keeps pulling back.

Feb 10·1 min read·22 words

Back to NixOS

Returned to NixOS on the Dell Inspiron 3501 after a stint with Bazzite — declarative config keeps pulling back.

Feb 8·1 min read·22 words

Transitioning to Standard.site Lexicons

Retiring legacy WhiteWind and Leaflet support in favor of the new Standard.site implementation.

Jan 26·1 min read·17 words

Transitioning to Standard.site Lexicons

Retiring legacy WhiteWind and Leaflet support in favor of the new Standard.site implementation.

Jan 26·1 min read·17 words

Malachite: How I Learnt to Stop Worrying and Import My Scrobbles

I will do shite out of spite, here's another case study!

Jan 23·37 min read·7304 words

Hit By A Silver Bullet: The Timing of Being Early with W

Damn it.

Jan 22·20 min read·3868 words

W. What's it Worth?

What a waste of a name.

Jan 21·7 min read·1201 words

Malachite Rename and Feature Expansion

Renamed lastfm-importer to malachite, added Spotify support, interactive mode, and improved rate limiting.

Jan 13·1 min read·18 words

Malachite Rename and Feature Expansion

Renamed lastfm-importer to malachite, added Spotify support, interactive mode, and improved rate limiting.

Jan 13·1 min read·18 words

Why Don't More People Use Signal?

Jan 11·12 min read·2363 words

Standard.site and Coordination

Adopting standard.site lexicons for cross-platform interoperability — why coordination matters more than individual features in the AT Protocol ecosystem.

Jan 5·1 min read·22 words

Standard.site and Why Coordination Matters More Than You Think

Interoperability! …and more?

Jan 5·18 min read·3542 words

Standard.site and Coordination

Adopting standard.site lexicons for cross-platform interoperability — why coordination matters more than individual features in the AT Protocol ecosystem.

Jan 5·1 min read·22 words

The AI Hype Train Has Derailed the PC Market, and We're Paying for the Wreckage

Jan 3·7 min read·1245 words

I Hope 2026 Will Be Better

My reflection on 2025.

Jan 2·19 min read·3760 words

Musical Identity and Confusion

I Am Not a Metalhead... I Think?

Dec 30·13 min read·2434 words

Caching, Skeleton Loading, and Happy Mac

Comprehensive caching to prevent 504s, skeleton loaders for instant page loads, and a Happy Mac easter egg.

Dec 30·1 min read·23 words

Caching, Skeleton Loading, and Happy Mac

Comprehensive caching to prevent 504s, skeleton loaders for instant page loads, and a Happy Mac easter egg.

Dec 30·1 min read·23 words

Website — Pronouns and Accessibility Improvements

Added pronouns to the profile card and improved accessibility across themes.

Dec 29·1 min read·17 words

Website — Pronouns and Accessibility Improvements

Added pronouns to the profile card and improved accessibility across themes.

Dec 29·1 min read·17 words

Joining Jollywhoppers: On Collaboration, Minecraft Mods, and Finding Your People

Dec 28·11 min read·2128 words

Joining Jollywhoppers

Became a member of Jollywhoppers — building atproto-connect, a Fabric Minecraft mod linking the game to AT Protocol.

Dec 28·1 min read·20 words

Joining Jollywhoppers

Became a member of Jollywhoppers — building atproto-connect, a Fabric Minecraft mod linking the game to AT Protocol.

Dec 28·1 min read·20 words

Privacy is Important

Don't just tell me to go offline. This is not how that works.

Dec 21·7 min read·1373 words

Social Sync — Minecraft Meets AT Protocol

Minecraft mod syncing player stats, achievements, and sessions to AT Protocol with OAuth and encrypted storage.

Dec 20·1 min read·23 words

Welcome to Macintosh: Documenting a Hidden Easter Egg

"Hidden", more like. It's an open secret.

Dec 17·5 min read·878 words

Welcome to Macintosh — Happy Mac Easter Egg

Hidden Easter egg on the website — click the version number 24 times for a pixelated Happy Mac bouncing across the viewport with the startup chord.

Dec 17·1 min read·34 words

Welcome to Macintosh — Happy Mac Easter Egg

Hidden Easter egg on the website — click the version number 24 times for a pixelated Happy Mac bouncing across the viewport with the startup chord.

Dec 17·1 min read·34 words

An American Werewolf in London: A Preventable Tragedy

All of these plot holes, it's like Britain's roads!

Dec 14·12 min read·2213 words

How Belief Shapes You When You're Not Looking

How the last week turned belief from concept into practice

Dec 8·11 min read·2057 words

Giving Up on Rust: A Post-Mortem

I should not be sorry.

Dec 7·7 min read·1240 words

Giving Up on Rust — A Post-Mortem

After five Rustlings sessions and countless compiler battles, called it — Rust isn't the right tool for the projects being built.

Dec 7·1 min read·28 words

Giving Up on Rust — A Post-Mortem

After five Rustlings sessions and countless compiler battles, called it — Rust isn't the right tool for the projects being built.

Dec 7·1 min read·28 words

Implementing a Decimal Clock

Added a bespoke decimal clock to the footer because base-10 time just makes sense.

Dec 1·1 min read·18 words

The Yew Has Wilted, and I Can't Water It

Anxiety is killing me.

Dec 1·20 min read·3860 words

Implementing a Decimal Clock

Added a bespoke decimal clock to the footer because base-10 time just makes sense.

Dec 1·1 min read·18 words

An Autistic Silver Bullet

No, I’m not AI. I just write like that.

Nov 27·19 min read·3742 words

Building a Decentralised Link Shortener with AT Protocol

Because... well, just because.

Nov 24·7 min read·1207 words

Shortlink Service for AT Protocol

Shortlink service resolving AT Protocol handles and DIDs with QR codes and domain-aware shortcodes.

Nov 24·1 min read·19 words

Shortlink Service for AT Protocol

Shortlink service resolving AT Protocol handles and DIDs with QR codes and domain-aware shortcodes.

Nov 24·1 min read·19 words

On Scottish Gaelic, Heritage, and the Right to Care

I just want Scottish Gaelic to survive.

Nov 23·7 min read·1318 words

You Can Just Do Things

An unexpected motto of the Atmosphere

Nov 22·20 min read·3898 words

Let’s Talk Steam Machine

Valve finally counted to Three.

Nov 18·4 min read·774 words

Bluesky Ollama Bot

Experimental bot using Ollama for LLM-generated Bluesky posts.

Nov 16·1 min read·11 words

Bluesky Ollama Bot

Experimental bot using Ollama for LLM-generated Bluesky posts.

Nov 16·1 min read·11 words

PDS DoS Incident

Accidentally rate-limited the entire PDS by blasting records at the API — the lesson that built Malachite's rate limiting.

Nov 15·1 min read·22 words

I Accidentally Did a DoS Attack On My PDS

How not to make a first impression.

Nov 15·7 min read·1300 words

PDS DoS Incident

Accidentally rate-limited the entire PDS by blasting records at the API — the lesson that built Malachite's rate limiting.

Nov 15·1 min read·22 words

Malachite — Last.fm to Teal.fm Converter

CLI tool for importing Last.fm and Spotify scrobbles to AT Protocol as Teal.fm records.

Nov 14·1 min read·20 words

Malachite — Last.fm to Teal.fm Converter

CLI tool for importing Last.fm and Spotify scrobbles to AT Protocol as Teal.fm records.

Nov 14·1 min read·20 words

MusicStatusCard and Masonry Layout

Music status card with MusicBrainz integration and masonry-style homepage layout.

Nov 13·1 min read·14 words

MusicStatusCard and Masonry Layout

Music status card with MusicBrainz integration and masonry-style homepage layout.

Nov 13·1 min read·14 words

croft.click and the Paralysis of Possibility

...I guess I could ask my dad if he wants a redirect link to his business?

Nov 10·8 min read·1574 words

croft.click Landing Page

Bought croft.click on a Black Friday sale — currently a 307 redirect to ewancroft.uk while figuring out what to do with it.

Nov 10·1 min read·25 words

croft.click Landing Page

Bought croft.click on a Black Friday sale — currently a 307 redirect to ewancroft.uk while figuring out what to do with it.

Nov 10·1 min read·25 words

Writing in Public: Why My Blog Has No Theme

something that I didn't need to justify, but here's my reasons.

Nov 9·7 min read·1234 words

An American Werewolf in London: The Streaming Shuffle Nobody Asked For

Ah yes, tempting a werewolf with raw meat into one cage and to the next, surely that won't go wrong!

Nov 1·7 min read·1313 words

Why Romance Language Word Order Sometimes Makes More Sense Than English

This is one of those spontaneous thoughts that just popped into my head, the kind that refuses to leave until I've written it out properly. So here we are.

Oct 30·7 min read·1230 words

Theory: How Long Did It Take?

In 'An American Werewolf in London', How Long Did Jack Walk?

Oct 29·9 min read·1687 words

Website — Slug Mapping and Robust Routing

Configurable slug-to-publication mapping and slug param matcher for clean URLs.

Oct 27·1 min read·17 words

Website — Slug Mapping and Robust Routing

Configurable slug-to-publication mapping and slug param matcher for clean URLs.

Oct 27·1 min read·17 words

Samhain in the Shadow of Snow

Honour, endings and the quiet rites Christmas swallowed

Oct 26·15 min read·2821 words

Sammy's Dead

Murdered by a vampire right in front of us, poor lass.

Oct 26·2 min read·262 words

The Clock's Going Back!

a twice-yearly ritual I still don't understand

Oct 26·11 min read·2162 words

Completing My Leaflet Migration (And Feeling a Bit Dejected About Link Rot)

I've finally done it. The Leaflet migration is complete.

Oct 25·8 min read·1475 words

Completing the Leaflet Migration

All WhiteWind posts converted to Leaflet format — blog.ewancroft.uk becomes home base, with link rot as the lingering cost.

Oct 25·1 min read·23 words

Leaflet Migration

Moving the blog from WhiteWind to Leaflet on AT Protocol — converting existing posts and building the tooling to do it.

Oct 24·1 min read·23 words

Completing the Leaflet Migration

All WhiteWind posts converted to Leaflet format — blog.ewancroft.uk becomes home base, with link rot as the lingering cost.

Oct 24·1 min read·23 words

Leaflet Migration

Well I guess this is a thing now. Doing this out of spite of myself, like usual.

Oct 24·1 min read·78 words

Leaflet Migration

Moving the blog from WhiteWind to Leaflet on AT Protocol — converting existing posts and building the tooling to do it.

Oct 24·1 min read·23 words

A Number on a Spreadsheet: When Everything Becomes Data

Oct 21·17 min read·3259 words

When You Hit RESET (and Actually Mean It) – ewancroft.uk v10

Redesign... Redesign... Redesign...

Oct 19·13 min read·2524 words

Website — Svelte 5 Runes Migration

Migrated layout and components to Svelte 5 runes and reactive meta handling.

Oct 19·1 min read·18 words

Website — v10 Reset

Nuked ewancroft.uk from orbit and started fresh — the tenth iteration, built from scratch with a clean architecture.

Oct 19·1 min read·22 words

Building a Modular AT Protocol Service Layer

Deep integration with the AT Protocol, pulling posts directly from the PDS and introducing a new Card UI system.

Oct 19·1 min read·26 words

Website — Svelte 5 Runes Migration

Migrated layout and components to Svelte 5 runes and reactive meta handling.

Oct 19·1 min read·18 words

Website — Inter Font and Semantic Colour Naming

Added Inter as the primary typeface and switched to semantic colour naming.

Oct 16·1 min read·20 words

Website — Inter Font and Semantic Colour Naming

Added Inter as the primary typeface and switched to semantic colour naming.

Oct 16·1 min read·20 words

Card UI and BlueskyPostCard

Homepage redesign with reusable Card UI system and BlueskyPostCard with lightbox and rich text.

Oct 16·1 min read·18 words

Card UI and BlueskyPostCard

Homepage redesign with reusable Card UI system and BlueskyPostCard with lightbox and rich text.

Oct 15·1 min read·18 words

WhiteWind to Leaflet Converter

Built a conversion tool to migrate blog content between AT Protocol publishing platforms — out of spite for the lack of one.

Oct 15·1 min read·26 words

Building a Modular AT Protocol Service Layer

Deep integration with the AT Protocol, pulling posts directly from the PDS and introducing a new Card UI system.

Oct 13·1 min read·26 words

Website — v10 Reset

Nuked ewancroft.uk from orbit and started fresh — the tenth iteration, built from scratch with a clean architecture.

Oct 12·1 min read·22 words

Bonfire Night: Fireworks without the Fire

Oct 11·12 min read·2396 words

Building Tangled Sync: A Few Hours of Work That Doesn't Quite Work Yet (And Why That's Bloody Frustrating)

Oct 11·11 min read·2073 words

Tangled Sync

Sync tool for mirroring GitHub repos to Tangled with force-sync and AT Protocol testing.

Oct 11·1 min read·16 words

Tangled Sync

Sync tool for mirroring GitHub repos to Tangled with force-sync and AT Protocol testing.

Oct 11·1 min read·16 words

The Frustrating Erasure of English (English English) in American Tech: a Rant

Oct 7·15 min read·2847 words

When the Clock Lies: On Time, Perception, and Why Nothing's Really Happening in Order

Oct 5·13 min read·2451 words

I Don't Really Care If Bluesky Dies (As Long As AT Protocol Survives)

Oct 4·17 min read·3367 words

Why I've Grown to Hate Spotify: A Tale of Ads and Lost Control

Sep 30·13 min read·2481 words

Hashtags Walked So Custom Feeds Could Run: Why Discovery on Bluesky Feels Different

Sep 28·11 min read·2107 words

How Greek and Celtic Myth (and a Kids’ Show) Shaped My Voice

Sep 27·7 min read·1266 words

A Few Hours of Hyperfocus: My Latest Website Updates

Sep 27·7 min read·1347 words

Website — Hyperfocus Updates

Three significant UX improvements shipped in one evening — navigation, content display, and interaction patterns.

Sep 27·1 min read·19 words

Website — Hyperfocus Updates

Three significant UX improvements shipped in one evening — navigation, content display, and interaction patterns.

Sep 26·1 min read·19 words

How Streaming Tried to Kill Digital Piracy, and Why Piracy Won

Sep 20·8 min read·1566 words

A Love Letter to Mac: Why I Choose Apple's Ecosystem

Sep 15·6 min read·1086 words

Link Rot and Eight Iterations of ewancroft.uk

Sep 14·5 min read·831 words

OG Images and Blog Enhancements

Dynamic OG image generation, reading time, heading underlines, and code block styling.

Sep 14·1 min read·17 words

Link Rot and Eight Iterations of ewancroft.uk

Eight versions of the website, each leaving dead URLs — the Hugo years, the SvelteKit migration, and building a slug mapping system to fix it.

Sep 14·1 min read·32 words

OG Images and Blog Enhancements

Dynamic OG image generation, reading time, heading underlines, and code block styling.

Sep 14·1 min read·17 words

Link Rot and Eight Iterations of ewancroft.uk

Eight versions of the website, each leaving dead URLs — the Hugo years, the SvelteKit migration, and building a slug mapping system to fix it.

Sep 13·1 min read·32 words

A Gentle Look at Lucky Maths: When Good Intentions Meet Web Design Reality

Sep 13·7 min read·1225 words

Wolf King vs. Wereworld: My Completely Unqualified Take on Netflix's Adaptation

Sep 11·7 min read·1329 words

Website — Scroll-to-Top and ToC Improvements

Scroll-to-top button, mobile progress bar, and improved table of contents layout.

Sep 7·1 min read·17 words

Website — Scroll-to-Top and ToC Improvements

Scroll-to-top button, mobile progress bar, and improved table of contents layout.

Sep 7·1 min read·17 words

Techno-Illiteracy and the Death of Critical Thinking (A Mildly Unhinged Rant)

Sep 6·9 min read·1709 words

Howling at the Digital Moon — Wolf-Themed Bluesky Client Concept

Conceptual design for a lycanthropic Bluesky client — dark theme, moon phase integration, and the scope creep that keeps it theoretical.

Sep 2·1 min read·31 words

Howling at the Digital Moon: A Theoretical Wolf-Themed Bluesky Client

Sep 2·13 min read·2550 words

Howling at the Digital Moon — Wolf-Themed Bluesky Client Concept

Conceptual design for a lycanthropic Bluesky client — dark theme, moon phase integration, and the scope creep that keeps it theoretical.

Sep 2·1 min read·31 words

Howling Through Time and Space: Doctor Who’s Post-2005 Lycanthropic Legacy

Sep 1·7 min read·1225 words

Rustlings Session 5: Quick Stretches and Type Systems

Aug 30·3 min read·547 words

Website — en-GB Localisation

Added en-GB localisation throughout the site — licence, colour, behaviour.

Aug 29·1 min read·14 words

Website — en-GB Localisation

Added en-GB localisation throughout the site — licence, colour, behaviour.

Aug 29·1 min read·14 words

Building a WhiteWind to Leaflet Converter Out of Pure Spite

Aug 28·4 min read·697 words

WhiteWind to Leaflet Converter

Built a conversion tool to migrate blog content between AT Protocol publishing platforms — out of spite for the lack of one.

Aug 28·1 min read·26 words

Atproto Snake Game Improvements

Aug 15·1 min read·20 words

Stepping Back: A Temporary Digital Detox

Aug 13·4 min read·662 words

Creating a did:web ATProto Identity: A Proof of Concept

Aug 10·20 min read·3839 words

did:web ATProto Identity Proof of Concept

Created @web.ewancroft.uk as a functional did:web identity within the AT Protocol ecosystem — research experiment, not a permanent switch.

Aug 10·1 min read·25 words

Picking Sides in the Protocol Wars

Aug 10·7 min read·1341 words

did:web ATProto Identity Proof of Concept

Created @web.ewancroft.uk as a functional did:web identity within the AT Protocol ecosystem — research experiment, not a permanent switch.

Aug 10·1 min read·25 words

M2 to M4 Mac Mini Upgrade

Upgraded from the M2 Mac Mini to the M4 — better performance, more headroom for self-hosted services.

Aug 9·1 min read·23 words

The Inevitable Upgrade: From M2 to M4 Mac Mini

Aug 9·6 min read·1136 words

M2 to M4 Mac Mini Upgrade

Upgraded from the M2 Mac Mini to the M4 — better performance, more headroom for self-hosted services.

Aug 9·1 min read·23 words

Why I Stick with SvelteKit: A Personal Reflection on My Web Development Stack

Aug 5·4 min read·751 words

iOS and macOS 26 Public Beta: Why I'm Tempted, and Why I'm Absolutely Not Installing It

Aug 5·6 min read·1042 words

Rustlings Session 4: Error Handling and Existential Crisis

Aug 3·5 min read·892 words

Rustlings Session 3: When Your Sleep Schedule is More Nocturnal Than Your Code

Aug 2·4 min read·744 words

Rustlings Session 2: Structs, Enums, and Why I'm an Idiot (Sections 7-9)

Aug 1·4 min read·684 words

Rustlings Session 1: First Steps into Rust (Sections 0-6)

Aug 1·7 min read·1229 words

Rustlings — First Steps into Rust

Five Rustlings sessions covering variables through type systems — the enthusiasm, the compiler battles, and the decision to stop.

Aug 1·1 min read·25 words

Why I Have a Website

Aug 1·8 min read·1495 words

Rustlings — First Steps into Rust

Five Rustlings sessions covering variables through type systems — the enthusiasm, the compiler battles, and the decision to stop.

Aug 1·1 min read·25 words

Dynamic OG Images: A Journey Through Development Hell

Jul 31·5 min read·906 words

Website — Dynamic OG Images

Server-side Open Graph image generation with SvelteKit — fonts that wouldn't load, endpoints that worked in dev but not production, and the eventual working solution.

Jul 31·1 min read·30 words

Website — Dynamic OG Images

Server-side Open Graph image generation with SvelteKit — fonts that wouldn't load, endpoints that worked in dev but not production, and the eventual working solution.

Jul 30·1 min read·30 words

The Linguistic Archaeology of English: How Latin and Greek Built Our Modern Vocabulary

Jul 30·12 min read·2267 words

Limbo

Jul 29·5 min read·912 words

Introducing Linkat Directory: A 'Link-in-Bio' Frontend

Jul 29·5 min read·891 words

The iMac Server

Jul 28·10 min read·1819 words

The iMac Server

Attempting to repurpose a 2008 iMac as a server — bricked OS, failed USB installs, and the eventual Mac Mini replacement.

Jul 28·1 min read·24 words

The iMac Server

Attempting to repurpose a 2008 iMac as a server — bricked OS, failed USB installs, and the eventual Mac Mini replacement.

Jul 28·1 min read·24 words

Linkat Directory

Linkat-powered user directory with profile banners, descriptions, and metadata display.

Jul 27·1 min read·12 words

The Profile Layout Refresh

Jul 27·6 min read·1055 words

Linkat Directory

Linkat-powered user directory with profile banners, descriptions, and metadata display.

Jul 27·1 min read·12 words

Website — Profile Layout Refresh

Redesigned the profile component from centred business-card layout to banner-integrated design with left-aligned content.

Jul 27·1 min read·19 words

Website — Profile Layout Refresh

Redesigned the profile component from centred business-card layout to banner-integrated design with left-aligned content.

Jul 26·1 min read·19 words

A Wii Nostalgia Trip

Jul 24·8 min read·1448 words

On Fantasy Names, Therianthropy, and My Slightly Obsessive Brain

Jul 19·4 min read·653 words

LLM Analyser

Tool for analysing LLM outputs and responses.

Jul 17·1 min read·9 words

LLM Analyser

Tool for analysing LLM outputs and responses.

Jul 17·1 min read·9 words

"What Mark will I Leave on Earth?"

Jul 16·2 min read·365 words

AT Protocol Snake Game

Browser Snake game with AT Protocol OAuth login and score submission via custom lexicons.

Jun 19·1 min read·18 words

AT Protocol Snake Game

Browser Snake game with AT Protocol OAuth login and score submission via custom lexicons.

Jun 19·1 min read·18 words

The Taste Never Leaves

Jun 18·6 min read·1064 words

Building a Moon Phase Bot for Bluesky: Because Every Platform Needs More Werewolf Energy

Jun 18·5 min read·839 words

Moon Tracker Bot

Daily moon phase posts to Bluesky with multi-source API and optional Ollama LLM descriptions.

Jun 17·1 min read·17 words

Moon Tracker Bot

Daily moon phase posts to Bluesky with multi-source API and optional Ollama LLM descriptions.

Jun 17·1 min read·17 words

The Case for Multiple Methods

Jun 14·7 min read·1201 words

Hosting My Own Minecraft Server: Replacing Aternos with a Mac Mini

Jun 11·4 min read·794 words

Self-Hosted Minecraft Server

Replaced Aternos with a self-hosted server on the M2 Mac Mini — no more queues, full control, direct access.

Jun 11·1 min read·22 words

Self-Hosted Minecraft Server

Replaced Aternos with a self-hosted server on the M2 Mac Mini — no more queues, full control, direct access.

Jun 10·1 min read·22 words

Minecraft Server Configuration

NixOS Minecraft server config with dynamic hardware-based configuration.

Jun 5·1 min read·11 words

Minecraft Server Configuration

NixOS Minecraft server config with dynamic hardware-based configuration.

Jun 5·1 min read·11 words

Saying Hello to Mastodon Again

Jun 2·3 min read·441 words

Testing Leaflet

May 23·2 min read·252 words

Testing Leaflet

Evaluating Leaflet as a WhiteWind replacement — subdomain requirements, AT Protocol integration gaps, and early impressions.

May 23·1 min read·18 words

Testing Leaflet

Evaluating Leaflet as a WhiteWind replacement — subdomain requirements, AT Protocol integration gaps, and early impressions.

May 21·1 min read·18 words

Custom Lexicons and Dynamic Link Board

Added custom lexicon definitions for status records and replaced static links with a dynamic link board from AT Protocol.

May 12·1 min read·25 words

Custom Lexicons and Dynamic Link Board

Added custom lexicon definitions for status records and replaced static links with a dynamic link board from AT Protocol.

May 12·1 min read·25 words

Collaborative Platformer

A collaborative 3D platformer game built with Godot.

May 2·1 min read·10 words

Collaborative Platformer

A collaborative 3D platformer game built with Godot.

May 2·1 min read·10 words

Why I Chose My Own Domain: A Personal Reflection

Apr 26·2 min read·318 words

My Journey to NixOS

Adopting NixOS on the Dell Inspiron 3501 — from macOS user to declarative Linux config, the learning curve, and what actually clicked.

Apr 20·1 min read·26 words

My Journey to NixOS: A macOS User's Perspective

Apr 20·4 min read·738 words

My Journey to NixOS

Adopting NixOS on the Dell Inspiron 3501 — from macOS user to declarative Linux config, the learning curve, and what actually clicked.

Apr 20·1 min read·26 words

Mental Reset

Apr 18·1 min read·174 words

Migrating the Site to SvelteKit

Rebuilding the website from scratch using SvelteKit for better performance and a more modern development experience.

Apr 8·1 min read·21 words

Website SvelteKit Migration

Apr 8·1 min read·19 words

Patterns and My Neurodivergency

Apr 7·5 min read·976 words

My Reflection on (nearly) a year on Bluesky (and the ATmosphere at large)

Apr 5·3 min read·414 words

Migrating the Site to SvelteKit

Rebuilding the website from scratch using SvelteKit for better performance and a more modern development experience.

Mar 18·1 min read·21 words

Reverse Engineering an Apple Shortcut and Making It Mine

Feb 23·4 min read·623 words

Reverse Engineering an Apple Shortcut

Deconstructed dame.is's dynamic avatar Apple Shortcut and rebuilt it as a Python automation — hourly profile image updates via AT Protocol.

Feb 23·1 min read·26 words

Reverse Engineering an Apple Shortcut

Deconstructed dame.is's dynamic avatar Apple Shortcut and rebuilt it as a Python automation — hourly profile image updates via AT Protocol.

Feb 23·1 min read·26 words

Avatar Updater Bot

Automatically updates a Bluesky profile avatar on a schedule with optional banner updates.

Feb 21·1 min read·16 words

Avatar Updater Bot

Automatically updates a Bluesky profile avatar on a schedule with optional banner updates.

Feb 21·1 min read·16 words

Gradient Profile Banner Generator

Generates gradient profile banners for Bluesky users with custom sizing and grain effects.

Feb 20·1 min read·17 words

Gradient Profile Banner Generator

Generates gradient profile banners for Bluesky users with custom sizing and grain effects.

Feb 20·1 min read·17 words

PDS Backup Tool

CLI tool for backing up AT Protocol PDS repositories.

Feb 19·1 min read·12 words

PDS Backup Tool

CLI tool for backing up AT Protocol PDS repositories.

Feb 19·1 min read·12 words

I'm Sorry

Feb 5·2 min read·357 words

Theme System and Multi-Theme Support

Theme toggle with multiple colour themes, persisted via localStorage, later expanded for WCAG 2.1 AA compliance.

Feb 3·1 min read·21 words

Theme System and Multi-Theme Support

Theme toggle with multiple colour themes, persisted via localStorage, later expanded for WCAG 2.1 AA compliance.

Feb 3·1 min read·21 words

Struggles Adapting to the AT Protocol

This new protocol is neat but... I find it difficult.

Jan 31·3 min read·401 words

Struggles Adapting to the AT Protocol

Early experiences with the AT Protocol SDK — confusing docs, Python and TypeScript friction, and the learning curve of a new API paradigm.

Jan 31·1 min read·29 words

Struggles Adapting to the AT Protocol

Early experiences with the AT Protocol SDK — confusing docs, Python and TypeScript friction, and the learning curve of a new API paradigm.

Jan 30·1 min read·29 words

AT Protocol Website Rewrite

Replaced static HTML with a dynamic AT Protocol-powered frontend fetching data from the PDS.

Jan 28·1 min read·18 words

Website AT Protocol Integration

Jan 28·1 min read·22 words

AT Protocol Website Rewrite

Replaced static HTML with a dynamic AT Protocol-powered frontend fetching data from the PDS.

Jan 27·1 min read·18 words

5 Years and 153 Poems

Jan 12·2 min read·296 words

Wolfblood: A Personal Retrospective

Comfort shows are great.

Dec 8·2 min read·329 words

Arguments on Operating Systems are Stupid, Actually

Nov 17·2 min read·214 words

A Fictional Dive into Philosophy through the Absurd

Oct 29·2 min read·274 words

Silver Fire

Oct 17·5 min read·927 words

A Look at Summer

Aug 7·2 min read·223 words

Bluesky Markov Chain Bot

Ported the Markov chain bot to Bluesky with configurable character limits.

Jun 9·1 min read·15 words

Bluesky Markov Chain Bot

Ported the Markov chain bot to Bluesky with configurable character limits.

Jun 9·1 min read·15 words

Bean Dumper Rewrite

Jun 6·1 min read·21 words

Awoo Bot — Wolf Sounds on Bluesky

Bot that posts wolf sounds to Bluesky with variable delay and nocturnal probability weighting.

May 19·1 min read·21 words

Awoo Bot — Wolf Sounds on Bluesky

Bot that posts wolf sounds to Bluesky with variable delay and nocturnal probability weighting.

May 19·1 min read·21 words

Gazing Into the Bluesky

Another alternative... In the skies?

Apr 17·3 min read·466 words

Mastodon Markov Chains, and Why I Created My Own

Fiddling with markov chains!

Mar 3·3 min read·538 words

Mastodon Markov Chain Bot

First bot — a Markov chain text generator for Mastodon.

Mar 2·1 min read·14 words

Mastodon Markov Chain Bot

First bot — a Markov chain text generator for Mastodon.

Mar 2·1 min read·14 words

When Your Platform Disappears: The Queer.AF Shutdown

This is a hot topic right now, huh?

Feb 13·5 min read·980 words

Logistics of Lycanthropy and its Romanticisation

A curse turned desire.

Jan 24·12 min read·2375 words

Moonlight

Dec 17·3 min read·483 words

Review: An American Werewolf in London made-for-radio BBC audio adaptation

Oct 28·10 min read·1971 words

Finding an Alternative: Life after Twitter

Silos are everywhere.

Nov 4·1 min read·124 words