how i built this blog
A static Astro + MDX blog on Cloudflare Pages. No backend or database; Pagefind search and the yap-mode toggle run in a few kilobytes of inline script.
stack
Built with Astro 7, MDX content collections, and Tailwind. Static output deployed to Cloudflare Pages on the free plan: unlimited static requests, zero functions, global CDN.
broke-boy architecture on purpose. no server, no database, no $20/mo Vercel bill. markdown in, HTML out, Cloudflare eats the bandwidth for free.
theme
Catppuccin Mocha accents on a blackened ramp. Page #08080a, text #cdd6f4, accent
mauve #cba6f7. System-sans body, JetBrains Mono headings and code. Single column,
76ch. Clean first, nerdy second.
vim bindings
| key | does |
|---|---|
j / k | next / prev post on lists, scroll in articles |
gg / G | top / bottom |
/ | search |
y | toggle yap mode |
t | toggle dark / light |
? | this cheatsheet |
search
Full-blown Pagefind: static index built at deploy time, no backend.
/ focuses it, arrows navigate, enter opens.
normal / yap
I write the yap. The normal version (frontmatter above) is written separately in a chat interface and pasted in. Normal is canonical for SEO and RSS; yap is client-side only.
normal is the resume. yap is the group chat. same URL, pick your fighter with y.
code blocks
Fenced code renders as postcards now: traffic lights, language label, copy button, line numbers. Shiki paints Catppuccin tokens that flip with the theme toggle.
def fill_form(fields, document):
for field in fields:
field.value = document.lookup(field.label) or field.value
return fields
diagrams
Mermaid fences render in place, themed to match, zoomable when wide. Same pipeline as everything else: markdown in, HTML out.
flowchart LR
A[write markdown] --> B[astro build]
B --> C[cloudflare pages]
B --> D[pagefind index]
B --> E[graph data]