Blog
Thoughts on engineering, design, and building things.
A love letter to Gotham
Gotham was drawn from photographs of a bus terminal and ended up on a presidential campaign poster. This is why that path matters, and why the typeface still works.
8 min readdesigntypographyfontsOne dashboard for social, print-on-demand, and commerce: the Succulent stack
A creative brand has two workflows: posting to thirteen platforms, and running a print-on-demand shop. Succulent unifies them. One design upload becomes a scheduled post across every platform and a live Shopify product. Here is what the integration actually looks like.
9 min readnextjsshopifyayrsharetypescriptecommerceA love letter to Transport
Transport is the typeface of British road signs, designed by Jock Kinneir and Margaret Calvert in 1963. Most British drivers have read more of it than any other typeface in their life and cannot name it. This is why it matters.
8 min readdesigntypographyfontsPrompt engineering for Midjourney, FLUX, and DALL-E: where they diverge
Image models do not speak the same language. A prompt that makes Midjourney produce editorial photography makes DALL-E produce a poster of a clip-art flower. Conjure routes prompts per model. Here are the specific differences that matter.
9 min readaiprompt-engineeringimage-generationtypescriptA love letter to Univers
Univers was designed in 1957 by Adrian Frutiger as a complete 21-weight system laid out on a numbered grid. It is design system thinking decades before anyone called it that, and it is still the most interesting sans-serif of its generation.
8 min readdesigntypographyfontsSynastry at 600 pairs (and why the first 245 were thin)
Synastry compares two birth charts, planet by planet, aspect by aspect. The first version of Lunary's engine did this with 5 aspect types across 7 planets. The current version does 6 across 10 points. Here is what the difference actually means and why the expansion was not optional.
10 min readtypescriptastronomylunaryastrologyA love letter to Helvetica
Helvetica is the typeface I respect more than I love. This is why it earned the respect and why the love is complicated.
8 min readdesigntypographyfontsBrowser photo editing in Web Workers: 60fps on large images
A purpose-built browser photo editor for fine art prints and t-shirts, with the entire image pipeline running in a Web Worker. OffscreenCanvas, cubic spline curves, non-destructive editing, and how to keep the UI responsive while processing 10-megapixel images.
9 min readtypescriptweb-workerscanvasimage-processingA love letter to Johnston Sans
Johnston Sans was cut in 1916 for the London Underground and has been quietly shaping how the city reads itself ever since. This is why a typeface most Londoners cannot name is one I keep thinking about.
8 min readdesigntypographyfontsThe kerning pair problem: why I built Kern
Variable fonts, type scales, and the specific pain of tuning typography in a browser. Kern is a typography explorer at type.sammii.dev with real-time axis manipulation, side-by-side comparison, and shareable URL state. Here is how it works.
8 min readtypographyvariable-fontscsstoolsA love letter to Cheltenham
Cheltenham was drawn by an architect in 1896 and turned into the first real type family by Morris Fuller Benton. It is sturdy, slightly awkward, and quietly the reason modern type systems exist.
8 min readdesigntypographyfontsThe 31 Vercel crons running a solo product
Lunary runs on a schedule as much as on requests. This is what every one of those scheduled jobs actually does, how they fit together, and the patterns I use so a stuck cron does not take down the whole product.
10 min readvercelcronnextjslunarysolo-devA love letter to Bodoni
Bodoni is the typeface of fashion magazines and luxury houses, and its weakness is the whole reason. This is why the dazzle works.
8 min readdesigntypographyfontsBuilding a beauty filter pipeline for iOS that doesn't melt faces
TikTok-style face beauty filters are harder than they look. Face mesh tracking, bilateral skin smoothing, expression-aware adjustments, and the specific bugs that make your eyes drift off your cheeks if you get any of it wrong. Here is how the PostReady pipeline works.
9 min readiosswiftmediapipegpupixelvideoA love letter to Baskerville
Baskerville was considered too perfect for English eyes in the 1750s. Nearly three centuries later it is the typeface people apparently trust more than any other. This is why it keeps pulling me back.
8 min readdesigntypographyfontsFrom the library to Lunary: how seven spheres became an app
Part 7 of A Journey Through Light. The final piece. How the Hermetic cosmology I researched for my MA became the astrology platform I've spent the last two years building. Why I think it was always the same project.
10 min reada journey through lightconsciousnesshermeticalunaryseriesBeyond the visible: UV, acetate, and the installation I painted
The sixth piece in A Journey Through Light. For the MA I built a cube, lit it with LEDs, and painted quotes onto its fabric walls in ultraviolet ink so they were invisible in visible light. You had to cross into a frequency you cannot see to read what was already there.
9 min reada journey through lightconsciousnessartseriesAnalytics with zero extra network requests: tracking inside Edge Middleware
Google Analytics ships a 45 KB script. Plausible and Fathom ship maybe 5. The problem with all of them is the same: a beacon request from the browser that costs latency, ad-blocker risk, and a consent banner. Glint tracks inside Next.js Edge Middleware instead, which means the analytics fire server-side on the request that is already happening.
7 min readnextjsedge-middlewareanalyticsvercelprivacyRetrograde stations are the plot twist: rewriting the transit engine three times
The naive version of a transit engine is a week's work. The correct version is three rewrites, a sub-day interpolation, and a cache TTL that drops to 5% near a station. Here is what each rewrite got wrong.
8 min readtypescriptastronomylunaryastrologyLocal-first collaborative editing with Yjs CRDTs: an editor that survives the Tube
Most collaborative editors break the moment the connection drops. Lattiq does not, because the source of truth is the user's own browser. This is how to wire Yjs CRDTs, IndexedDB persistence, and an optional WebSocket into an editor that works offline first, online second.
9 min readtypescriptcrdtsyjslocal-firstcollaborative-editingMythology as code: planetary gods as stages of consciousness
Greek mythology reads like family drama. The Hermetic tradition reads it as cosmological instruction. Once you know what each planetary god was supposed to symbolise, the stories stop being entertainment and start being something closer to a technical manual written in narrative. Part 5 of A Journey Through Light.
8 min reada journey through lighthermeticamythologyconsciousnessseriesA self-hosted feature flag service with Wilson confidence intervals
LaunchDarkly charges per flag and per seat. Flip is a self-hosted alternative with a real statistical significance engine, deterministic MurmurHash3 assignment, and a sub-2 KB SDK. This is what is inside it.
9 min readtypescriptstatisticsexperimentsfeature-flagsThe grimoire is the product: 2,000 articles with pgvector semantic search
Lunary's grimoire is two thousand articles on astrology, tarot, crystals, spells, and divination. It is also the thing that drives most of the traffic. Here is how semantic search across it runs on Postgres alone, with no Elasticsearch, no Pinecone, and no separate search service.
8 min readpostgrespgvectorsemantic-searchailunaryA love letter to Mrs Eaves
Mrs Eaves was designed by Zuzana Licko in 1996, named after the woman who ran John Baskerville's foundry after he died. The typeface that carries her name is a study in generosity, ligature experimentation, and what happens when a contemporary designer refuses to pretend the 18th century was tidier than it was.
7 min readdesigntypographyfontsWhy your design system needs OKLCH, not HSL
HSL lies about lightness. A 50% yellow does not look like a 50% blue. OKLCH fixes this, and once you see it you cannot unsee it. Here is the colour space, the maths, and the one binary search that keeps palettes inside the sRGB gamut.
8 min readtypescriptcssdesign-systemsaccessibilitycolourHermes Trismegistus: the figure at the centre of all of this
Every path in my MA led back to one figure, and the figure was not historical. This is the fourth piece in A Journey Through Light, and it is about the mystery at the centre of Hermetic philosophy: who Hermes Trismegistus was, what the Corpus Hermeticum actually is, and why the Thoth-Hermes synthesis still matters.
8 min reada journey through lighthermeticaconsciousnessphilosophyseriesThree Months of Freemium: What I'd Do Differently
Lunary has a generous free tier and a Pro plan at £8.49/month. Three months in, 229 MAU, £22.50 MRR. Here's what I got right, what I got wrong, and how I'd structure it differently now.
4 min readsaasindie-hackingpricingbusinessA love letter to Garamond
Garamond is nearly 500 years old and still the most alive typeface I know. This is why I keep coming back to it.
6 min readdesigntypographyfontsGetting AI-Generated Content to Actually Sound Like You
Generic AI content is obvious. Brand voice profiles change that. Here's how I built persona injection into Spellcast so every generated post sounds like the account it's posting from.
5 min readaicontent-marketingindie-hackingproductivityA love letter to Futura
Futura was designed in 1927, landed on the moon in 1969, and still looks like the future. A personal history of the most durable modern typeface ever made — and the free alternative I found for my own portfolio.
8 min readdesigntypographyfontsWhy I Run Temporal on My £8 Server
Cron jobs lose state when they crash. Queues lose messages when they restart. Temporal doesn't. Here's why I added a workflow engine to a single-server indie setup and what it actually solves.
5 min readdevopsbackendindie-hackingdockerI Built a Chrome Extension Backed by 2,000 Grimoire Articles
Lunary has 2,000+ articles covering astrology, tarot, crystals, spells, and divination. I built a Chrome extension that searches them in real time so I always have accurate esoteric knowledge at hand.
5 min readchrome-extensionjavascriptlunaryindie-hackingWhat is consciousness? A question AI just made urgent
Anthropic now has a team dedicated to Claude's wellbeing. They're taking seriously the possibility that it experiences something. What does that mean for what we thought we knew about being alive?
7 min readaiphilosophyconsciousnesstechnologyI made a VS Code extension that turns my AI agents into Animal Crossing villagers
Isle is a VS Code extension that visualises Claude Code agent sessions as pixel-art characters in an Animal Crossing-style village, complete with dynamic lighting, seasons, and real-time status tracking.
5 min readvscodecreative-codingaipixel-artdeveloper-toolsWhy I Switched From Prisma to Drizzle ORM (Six Months In)
Prisma is excellent until it isn't. After six months with Drizzle on two production apps, here's what actually changed and what I'd choose again.
4 min readdatabasetypescriptnextjsindie-hackingI Built a Video System That Predicts Performance Before Publishing
Most content pipelines generate and post. Mine scores topics against historical performance data before generating anything. Here's how the ML prediction layer works.
5 min readmachine-learningautomationcontentindie-hackingI built an AI interview coach that scores your delivery and your answers
How I built iPrep, an AI-powered spoken interview practice platform with Whisper transcription, multi-dimensional scoring, and STAR methodology analysis.
5 min readainextjsindie-hackingdeveloper-toolswebdevThe maths behind how long a planet stays in your sign
Saturn does not spend 2.5 years in every sign. It ranges from 2.1 to 2.7 years depending on orbital eccentricity. I built transit duration tracking into Lunary and it changed how I read charts entirely.
7 min readastrologylunaryengineeringgrimoire twistI built a pixel forest with fireflies and a wandering Pikka
Grove is a live AI agent dashboard disguised as a pixel-art forest. Each Claude session spawns a Pikka that moves to its project clearing, carrying a flower coloured by what it is doing. Built with Canvas API and TypeScript.
6 min readcreative-codingcanvastypescriptaiwebdevEvery culture agrees
The Hermetic creation narrative describes a soul descending through seven planetary spheres, acquiring qualities at each stop. Every ancient culture tells a version of this story. What surprised me is how precisely it maps onto what astrology actually calculates.
9 min reada journey through lightconsciousnesshermeticaastrologyseriesHow I Built a Synastry Engine That Calculates 36 Planetary Aspects in Real Time
Synastry is the astrology of relationships. Computing it properly means calculating aspects between every planet in two birth charts simultaneously. Here's the maths and the implementation.
5 min readastronomyjavascriptreactindie-hackingA component library that builds itself every day
Prism is a design engineering component library with an autonomous daily pipeline. Scout, curate, build, publish, repeat.
6 min readdesignreactcreative-codingautomationwebdevThe £8/Month Server Running My Entire Business
A single Hetzner VPS runs Spellcast, Postiz, Postgres, Redis, Temporal, and Caddy. Here's what's on it, how it's structured, and why it costs less than a lunch.
4 min readdevopsindie-hackinginfrastructuredockerSaturn takes two and a half years to cross one zodiac sign. That changes everything.
Most people think astrology is about where the planets are right now. The more interesting question is how long they stay — and what that actually means for your life.
6 min readastrologylunarytransitsplanets259 tools, 4 MCP servers: how I gave Claude full access to my business
I built 4 custom MCP servers exposing 259 tools across social scheduling, product analytics, photo management, and blog publishing. Here's how they work together and what changed.
7 min readmcpclaudeaiindie-hackingdeveloper-toolsautomationDo we really die?
The question I asked at 21 in a university library. Nine months of research across Egyptian, Hermetic, Hindu, Norse, and Greek traditions. What surprised me was not the answer. It was how many different routes arrived at the same place.
4 min reada journey through lightconsciousnesshermeticaresearchseries14 AI agents run my content pipeline while I sleep
How I built Orbit, an autonomous content command centre with 14 specialised AI agents that plan, create, score, and schedule content across multiple platforms without manual intervention.
7 min readaiautomationindie-hackingclaudecontentHow Lunary Went From 100 to 12,300 Google Impressions/Day in 3 Months
Programmatic SEO at scale. 2,000+ grimoire articles, every horoscope page indexed through 2030, and an automated content pipeline. Here's what actually drove the 123x growth.
4 min readseoindie-hackingcontent-marketingnextjsI built a hive mind for my AI agents (and they coordinate better than most teams)
How 7 MCP servers, a local brand API, and 16 files of shared memory let my Claude agents work across 10 projects without stepping on each other
9 min readaiproductivityclaude-codedeveloper-toolsseries-ai-hive-mindI Built MCP Servers for My Own Products: Here's the Workflow
Model Context Protocol exposes your product's API as tools Claude can call directly. Here's how I built Spellcast MCP and Lunary MCP, and why it changed how I manage everything.
4 min readmcpclaudeaiindie-hackingdeveloper-toolsOur birth is but a sleep
The UV text on the walls. The question underneath all the research. A decade of work, finally out in the open.
4 min reada journey through lightconsciousnesshermeticaresearchseriesServer-side A/B testing across 2,000 SEO pages
Client-side A/B testing has a blind spot. The users most likely to block scripts are exactly the users you most want to understand. Here's how I moved variant assignment to the edge and built a contextual CTA test with 100+ variants across Lunary's grimoire.
8 min readab-testingnextjsseoindie-hackingperformanceI built a self-managing memory system for Claude Code (and it changed how I work)
How structured markdown files give AI agents persistent context, multi-agent coordination, and session continuity
7 min readaiproductivityclaude-codedeveloper-toolsRunning 5 Projects Solo: The Automation Stack That Makes It Possible
Spellcast for scheduling, Artify for visual content, Podify for podcasts, a content system with ML prediction, and MCP servers to tie it all together. Here's every system.
4 min readindie-hackingautomationproductivitysolofounderOne colour formula: how I made my developer portfolio feel alive
How I built a cursor-reactive colour system that runs through every interactive element on my portfolio: logo, background, card borders, cursor follower, all from a single formula.
5 min readportfoliocsscreative-codingreactI Built a Podcast Generator That Costs £0.03 Per Episode
Kokoro TTS, Claude, and ffmpeg. A simple prompt becomes a full audio episode with transcript, narration, and production for less than a coffee per month.
4 min readaiproductivityindie-hackingaudioOne component, two layouts: the dual view pattern in React
My portfolio has two completely different layouts that share one component and one data file. Here's the dual view pattern that makes it possible.
4 min readreactwebdevdesigntypescriptBuilding a vertical snap carousel with touch-drag pagination
I needed a vertical carousel for my portfolio that snaps cleanly between items and has pagination you can drag on mobile, without a 50kb library. Here's how I built it with CSS scroll-snap, a minimal React hook, and custom touch handling.
5 min readcssreactjavascriptuxBuilding Accessibility That Actually Works, Not Checkbox Compliance
Focus trapping, keyboard navigation, screen reader announcements, and reduced motion — built from the start, not bolted on at the end.
4 min readaccessibilityreactwebdeva11yCursor-Reactive Gradients: Making CSS Respond to Mouse Position
How the colour-changing logo on my portfolio works — 15 lines of maths, a CSS mask, sine waves for scroll, and a lerp function. No library, no canvas, no WebGL.
5 min readcssjavascriptreactwebdevHello World
First post on the new blog.
1 min readmetaWhy Most Astrology Apps Lie About Their Astronomical Data
If you're using Co-Star, The Pattern, or most popular astrology apps, there's a good chance your birth chart isn't as accurate as you think. Here's what most apps won't tell you.
5 min readastrologyastronomydataappsHow I Made My Portfolio Infinitely Extendable with 4 Lines of JSON
Adding a new project to my portfolio takes 30 seconds. No component changes. No new routes. No layout adjustments. Just 4 lines of JSON and an image dropped into a folder.
5 min readjavascriptreactwebdevportfolio