{
  "path": "/still-blogging.html",
  "site": "at://did:plc:x67qh7v3fd7znbdhauc45ng3/site.standard.publication/3mjcd2t6afe25",
  "$type": "site.standard.document",
  "title": "Still blogging",
  "updatedAt": "2026-04-23T00:00:00.000Z",
  "bskyPostRef": {
    "cid": "bafyreih33yw4hbdss5l3nxssqpurtwooxzl4acktm5rojdftsghhmqncfy",
    "uri": "at://did:plc:x67qh7v3fd7znbdhauc45ng3/app.bsky.feed.post/3mk5obqeahs2y"
  },
  "publishedAt": "2026-04-23T00:00:00.000Z",
  "textContent": "I published three posts on this blog just in April.\nBefore that, I've published 3 posts since May 2020.\nGoing back to freelance work\nand having an interesting [bioinformatics project][rastair]\nmade me want to write again,\nand it feels good.\nBut this blog had to feel a bit nicer first!\nThis site has been around since 2016[^older],\nand it was always just Markdown files in a git repo.\nLet's update the toolchain around it as a little spring cleaning for 2026.\n\n[rastair]: https://deterministic.space/rastair.html \"Notes on Rastair, a variant and methylation caller\"\n\n[^older]: Some of the content is even older, imported from a previous site.\n\nHugo\n\nThe blog ran on [Jekyll] from its inception until last month.\nI chose it because GitHub Pages shipped it by default\nand I wanted to publish something.\nThat worked in 2016,\nand I'm glad it's actually still supported today.\nBut, in 2026, getting Jekyll to build locally\nmeans fighting bundler, native extensions,\nand a Ruby toolchain I haven't used for anything else in years.\nI could publish blindly and just see what I get out of it,\nbut that's no fun.\n\n[Jekyll]: https://jekyllrb.com/ \"Jekyll: Transform your plain text into static websites and blogs\"\n\nSo, I looked for something else:\nStable, usable, and likely to be maintained for the next years.\n[Hugo] looked like a great option.\nIt's a single binary, one brew install away.\nYou run it, and the site builds in about 60 milliseconds.\nThe expected content is Markdown with YAML frontmatter,\nso that I already had.\nIf I move to something else in 2036,\nI expect a similar afternoon of find-and-replace.\n\n[Hugo]: https://gohugo.io/ \"Hugo: The world's fastest framework for building websites\"\n\nOf course, I also wanted to make my own theme.\nAt first I copy-pasted the one I had in Jekyll\nbut I knew I wanted to take it further.\nHugo's templating language is Go templates.\nThey have a pipe syntax that looks clean at first,\nbut some functions don't compose well in pipelines\nso you end up wrapping things in parentheses.[^gotmpl]\nIt gets the job done.\n\n[^gotmpl]: For example, {{ .Title | truncate 50 }} reads naturally. But conditionally wrapping output requires nesting {{ if }} blocks or calling printf with parenthesized arguments instead of piping. Not awful, just occasionally surprising.\n\nA nice thing Hugo has is [render hooks]\nthat let you customize how individual Markdown elements get rendered\n(e.g., links, images, code blocks)\nwithout touching the main templates.\nI wish they went further, though.\nThe table of contents, for example,\nis generated as a blob of HTML\nwith no hook to customize its structure.[^toc]\n\n[render hooks]: https://gohugo.io/render-hooks/introduction/ \"Introduction to render hooks in Hugo\"\n\n[^toc]: Unless I missed something.\n  You can set startLevel and endLevel in the config, and that's about it.\n  I'd love to be able to control the markup or wrap individual entries.\n\nThe theme\n\nThe design is loosly based on a personal website I had around 2015.\nThat one had sidenotes, a serif font, and a lot of whitespace.\nWhen I started the new theme,\nI went for something quite clean and polished,\nwith a lot of focs on typography.\nI now use [Piazzolla], a really nice serif font[^piazzolla].\n\nThen, my wife looked at it and said the older one was better.\nMore nerdy and authentic, less magazine.\nShe was right.\nWhat made the old site feel like mine\nwas that the rendered HTML looked a bit like the Markdown source\nand was basically just about the content,\nin full monospace glory.\n\n[^piazzolla]: By Juan Pablo del Peral at [Huerta Tipográfica], who also made [Alegreya], which I used before.\n\n[Piazzolla]: https://piazzolla.huertatipografica.com/ \"Piazzolla: a variable font family with old-style proportional numerals\"\n[Huerta Tipográfica]: https://huertatipografica.com/\n[Alegreya]: https://www.huertatipografica.com/en/fonts/alegreya-ht-pro\n\nMarkdown style\n\nSo I combined the two.\nI added a CSS @layer markdown-look:\nHeadings get prefixed with ##,\ninline code gets wrapped in backtick markers,\nlists use – instead of bullets,\nhorizontal rules render as ---.\nand footnotes get [^x] styling.\n\nNeat little bonus:\nThe / \"\" in the content value is an\n[alternative text][content-a11y]\nso screen readers don't announce the decoration.\n\n[content-a11y]: https://developer.mozilla.org/en-US/docs/Web/CSS/content#alternative_text \"CSS content alternative text on MDN\"\n\nSidenotes\n\nI write a lot of footnotes[^footnotes]\nand having them at the bottom of the page\nalways felt too far away.\nParentheses are too noisy.\n[Tufte-style] sidenotes sit right next to the text,\nwhich is where you want the context.\n\n[^footnotes]: tangents, caveats, small jokes, stuff too long to put in parantheses, just like this one here\n\n[Tufte-style]: https://edwardtufte.github.io/tufte-css/ \"Tufte CSS: Dave Liepmann's take on Edward Tufte's layout ideas\"\n\nOn wide viewports (72rem and up),\nfootnotes move into the right margin.\nLinks that have title attribute\nalso get pulled into the margin as annotations,\nshowing the domain and the title text.\nThe table of contents sticks to the left.\nAnd on narrow screens, everything is just one column.\n\nThe implementation is about 60 lines of JavaScript.\nIt runs before first paint and\nclones both Hugo's footnote content and links with a title attribute\ninto <span> elements next to each reference\nand floats them into the margin.\n\nThe CSS is actually quite simple\nand has been done many times before.\nIt's just more fun with CSS features from 2026.\n\nOh, and there's a also a .wide class\nto make tables and some code blocks easier to read.\n\nColors and dark mode\n\nOn big gap in the old blog design was that it was just black and white and pink links.\nNow, all colors are in [oklch],\na pretty neat color space that works well when adjusting lightness and blending colors.\nMy entire accent palette actually comes from one (pink) --hue variable.\nSuper satisfying that I can do this directly in code\nand get nice colors from some math.\n\n[oklch]: https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/oklch \"oklch() on MDN\"\n\nDark mode (a new feature)\nfollows prefers-color-scheme by default\nwith a [data-theme] attribute for manual override (currently unused).\nBoth themes use the same token names, different oklch values.\ncolor-mix() handles the subtler bits,\nlike blending the accent with transparency for link underlines:\n\nThere are a few other 2025/2026 CSS features in here\nthat I'm happy to finally use:\ntext-wrap: balance on headings to avoid orphaned words,\ntext-wrap: pretty on body text,\nand scroll-state() container queries[^scroll-state]\nfor showing the table of contents header\nonly when it's stuck to the top of the viewport.\n\n[^scroll-state]: @container scroll-state(stuck: top) landed in Chrome 133 and Safari 18.4\n  and as of May 2026 doesn't work in Firefox.\n  \nDiagrams\n\nFor my recent posts I also felt the urge to include some diagrams.\nI've gotten used to adding [Mermaid] diagrams to markdown files\nand this blog feels no different.\nAdding diagrams via code blocks with annotations also means the source stays just text\nand people are you these a lot so I guess they will stay around.\n\nI didn't want to include Mermaid's client-side JS rendering library\nsince it's quite big and also won't work in feed readers.\nSo I was happy to see [kroki.io],\nwhich provides a public API that you can post text diagram formats to\n(incl. Mermaid, GraphViz, and even Vega)\nand get SVGs back.\nWith a bit of config,\nyou can call HTTP endpoints from Hugo templates:\nA match made in heaven!\n\n[Mermaid]: https://mermaid.js.org/ \"Create diagrams and visualizations using text and code\"\n[kroki.io]: https://kroki.io/ \"A unified API for rendering text diagrams as SVGs\"\n\nWith this, we have diagrams as SVGs directly embedded in the rendered post pages.\nBut they come with their own styles (at least the Mermaid ones).\nNo worries. With a little bit of !important CSS styling,\nI overwrote the colors and fonts\nso its looks more \"native\" to the blog\nand also works in dark mode.\n\nI wasnt't sure how to demostrate this but here we go:\n\nOpen Social Stuff\n\nI like the idea of having a simple website\nthat serves content directly\non a domain that I own.\nFeel nicer than to publish\non Medium[^medium], dev.to, Substack,\nor some social media channel.\n\n[^medium]: Is that still a thing people use?\n\nThis blog has an RSS feed,\nand as someone who uses a feedreader daily,\nthis is important to me.\nNo need to visit this website if you want to read my content.\n\nPublishing on the \"ATmosphere\"[^at] was quite simple.\nI set up an account for this blog (on [Eurosky])\nand then used [Sequoia] which syncs the blog content with it.\nIt was very easy!\nYou can now follow this blog [here][bsky-acc] on Bluesky.\n\nOne more thing I used from Sequoia is their comments feature.\nSince the Bluesky API is public[^twitter-api],\nSequoia comes with a little Web Component\nthat allows showing all Bluesky replies just like comments.\n(I also added support for showing quote posts.)\nThis means that the best way to reply to my blog posts\nis now to reply on Bluesky.\n\nI also looked into publishing the content\nas an ActivityPub account,\nbut in contrast to some tutorials I've seen\nit doesn't really work with a static site.\nLooks like I need a slightly more dynamic setup\nto make it work[^dynamic].\n\n[^dynamic]: This blog is currently hosted on Cloudflare,\n  so dymanic ActivityPub stuff as well as hosting my own PDS for AT\n  would be both doable,\n  but outside the \"everything is Markdown files\" realm,\n  so I didn't do anything for this yet.\n\n[^at]: This is what Bluesky is built on, the AT protocol.\n[^twitter-api]: Like APIs were in the good old days!\n\n[Eurosky]: https://eurosky.tech/\n[Sequoia]: https://sequoia.pub/ \"Publish evergreen content to the ATmosphere\"\n[bsky-acc]: https://bsky.app/profile/deterministic.space \"This blog on bluesky\"\n\nMore writing\n\nIt's fun to write!\nMaybe right now I'm a bit obsessed with putting on my thoughts into text after not doing it much for a while,\n",
  "canonicalUrl": "https://deterministic.space/still-blogging.html"
}