<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet href="/rss/pretty-feed-v3.xsl" type="text/xsl"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>oliver thurley</title><description>oliver thurley makes things</description><link>https://thrly.com/</link><item><title>Thoughts on customising a split keyboard layout</title><link>https://thrly.com/blog/thoughts-on-customising-a-split-keyboard-layout/</link><guid isPermaLink="true">https://thrly.com/blog/thoughts-on-customising-a-split-keyboard-layout/</guid><description>Learning to use a split keyboard and creating a keymap.</description><pubDate>Wed, 12 Mar 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Earlier in the year I started experiencing pain in my wrist and hand. &quot;RSI has finally come for me!&quot;, I panicked. After falling down a rabbit hole of ergonomics, desk setups, trackballs, and customised keyboards... I landed in an even deeper rabbit hole of split ergo keyboards. Fast forward through several Discord servers and subreddits, and now I’m typing on a Corne (aka CRKBD) 6-column/42-key split keyboard. I&apos;ve had a lot of fun developing my own keymap, learning to type on a split, and finding an ergonomic approach that works for me. Maybe some of this will resonate with you too.&lt;/p&gt;
&lt;p&gt;You can find the ZMK configs to install this yourself &lt;a href=&quot;https://github.com/thrly/thrly-corne-zmk&quot;&gt;on GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;UPDATE (22 June 2025): I designed my own split keyboard, &lt;a href=&quot;https://github.com/thrly/tempest&quot;&gt;TEMPEST&lt;/a&gt;, which you can read a bit about &lt;a href=&quot;../tempest&quot;&gt;here&lt;/a&gt;, along with an improved keymap!&lt;/p&gt;
&lt;h2&gt;The Keyboard&lt;/h2&gt;
&lt;p&gt;For those unfamiliar, the &lt;a href=&quot;https://github.com/foostan/crkbd&quot;&gt;Corne (aka CRKBD)&lt;/a&gt; by foostan is a split &apos;ergonomic&apos; keyboard, with 3x6 columns and 3 thumb keys on each side. It comes in two switch styles: Cherry MX and low profile Choc.&lt;/p&gt;
&lt;p&gt;I&apos;m currently using a low-profile choc wireless Corne from &lt;a href=&quot;https://typeractive.xyz/pages/build&quot;&gt;Typeractive.xyz&lt;/a&gt;. It&apos;s fitted with &lt;a href=&quot;https://mechboards.co.uk/products/lowprokb-ambients-twilight&quot;&gt;Ambients Twilight&lt;/a&gt; silent linear switches, which are wonderfully quiet. I&apos;m using ZMK firmware. I&apos;ve heard some people complain that the choc-spaced board is cramped, but I&apos;ve not had any problems with it. I&apos;m currently just using FR4 plates in lieu of a case for an ultra minimal feel!&lt;/p&gt;
&lt;h2&gt;My Keymap&lt;/h2&gt;
&lt;p&gt;I&apos;ve really enjoyed tinkering with this, and while the majority of it is fixed, I&apos;m sure I&apos;ll keep making changes in some regard.&lt;/p&gt;
&lt;p&gt;Inspired by &lt;a href=&quot;https://mark.stosberg.com/markstos-corne-3x5-1-keyboard-layout/&quot;&gt;Mark Stosberg&lt;/a&gt;&apos;s approach, I set a few key priorities for my own keymap development:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;QWERTY. I regularly need to switch keyboards at work. While I love the idea of learning COLEMAK, brain space says no.&lt;/li&gt;
&lt;li&gt;Easy access to symbols and navigation. I type &apos;normally&apos; and code, and I want both to be easy. I think my initial RSI issues have something to do with constantly reaching for &lt;code&gt;;&lt;/code&gt; and &lt;code&gt;=&amp;gt; (){&lt;/code&gt; ... thanks JavaScript!&lt;/li&gt;
&lt;li&gt;logical layer arrangement. That means trying to consolidate layers but keep them clear and (relatively) easy to learn.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Finally, I&apos;ve borrowed heavily from Manna Harbour&apos;s &lt;a href=&quot;https://github.com/manna-harbour/miryoku&quot;&gt;Miryoku&lt;/a&gt; layout, which is a thing of beauty and I would &lt;em&gt;love&lt;/em&gt; to adopt... but it&apos;s design philosophy is rooted in 36 keys, and 42 seems to undermine that.&lt;/p&gt;
&lt;h3&gt;Base layer&lt;/h3&gt;
&lt;p&gt;No surprises here --- it&apos;s QWERTY.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./keyboard-img/corne-base-layer.png&quot; alt=&quot;Custom corne base layer&quot; /&gt;
[EDIT: added home row mods]&lt;/p&gt;
&lt;p&gt;Left side thumb keys, left to right: &lt;code&gt;Ctrl&lt;/code&gt;, &lt;code&gt;Space&lt;/code&gt; (held for Nav layer), &lt;code&gt;Tab&lt;/code&gt; (held for Utilities like Bluetooth).
Right side thumb keys, left to right: &lt;code&gt;Enter&lt;/code&gt; (held for &lt;code&gt;Num&lt;/code&gt; layer), &lt;code&gt;Backspace&lt;/code&gt; (held for &lt;code&gt;Symbol&lt;/code&gt; layer), and a &lt;a href=&quot;https://zmk.dev/docs/keymaps/behaviors/sticky-key&quot;&gt;sticky &lt;code&gt;Shift&lt;/code&gt;&lt;/a&gt;. I’m still not completely satisfied with this setup—see ‘Frictions’ below for more details.&lt;/p&gt;
&lt;p&gt;One of my biggest dilemmas was deciding where to place modifier keys like &lt;code&gt;Ctrl&lt;/code&gt;, &lt;code&gt;Shift&lt;/code&gt;, and &lt;code&gt;Gui (OS)&lt;/code&gt;. Doubling up &lt;code&gt;Ctrl&lt;/code&gt; and &lt;code&gt;Shift&lt;/code&gt; isn’t the most efficient choice, but it has proven useful. I can see this is where home row mods have a definite advantage, and one I&apos;m considering.&lt;/p&gt;
&lt;p&gt;[EDIT: I&apos;ve tentatively started playing around with Home Row Mods after reading &lt;a href=&quot;https://precondition.github.io/home-row-mods&quot;&gt;this excellent guide&lt;/a&gt;. I&apos;m enjoying it, although I am encountering a LOT of mis-fired mods on regular typing, so I need to adapt my typing style if I&apos;m going to commit to it...] [UPDATE: okay, I&apos;m more used to it now... I &lt;em&gt;love&lt;/em&gt; it!]&lt;/p&gt;
&lt;p&gt;I&apos;m using a couple of combo presses here too:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;G+H&lt;/code&gt; for &lt;code&gt;WORD_CAPS&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;T+Y&lt;/code&gt; for &lt;code&gt;CAPS LOCH&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Q + W&lt;/code&gt; for &lt;code&gt;Escape&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;del + &apos;&lt;/code&gt; for volume up&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&apos; + alt&lt;/code&gt; for volume down&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Navigation layer&lt;/h3&gt;
&lt;p&gt;This one borrows heavily from &lt;a href=&quot;https://github.com/manna-harbour/miryoku&quot;&gt;Miryoku&lt;/a&gt;, but I&apos;ve consolidated arrow key navigation and mouse control onto one layer. I&apos;m still unsure if the trade off is worth it, but it&apos;s mostly working for me at the moment.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./keyboard-img/corne-nav-layer.png&quot; alt=&quot;Custom corne nav layer&quot; /&gt;&lt;/p&gt;
&lt;p&gt;I think a big part of my RSI issue stem from reaching for the mouse. To that end I&apos;m using a trackball, usually positioned between my split keyboard. Ultimately I like the idea of using the keyboard itself to do a lot of the mouse navigation I&apos;m used too... but I&apos;m not there yet. (I think the next hurdle will mean finding a decent window manager app for windows.)&lt;/p&gt;
&lt;h3&gt;Symbol layer&lt;/h3&gt;
&lt;p&gt;This layer was the hardest to get right, but while I continue to tweak elements, I&apos;m pretty happy with it for the most part.&lt;/p&gt;
&lt;p&gt;The focus for this layer was comfort when programming, so things like brackets and basic operators need to take preference over lesser used symbols. To aid learning I&apos;ve tried to group symbols somewhat.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./keyboard-img/corne-symbol-layer.png&quot; alt=&quot;Custom corne symbol layer&quot; /&gt;&lt;/p&gt;
&lt;p&gt;I&apos;m working in JavaScript a fair amount, so I have a handy double tap dance on my &lt;code&gt;&amp;gt;&lt;/code&gt; key to give me &lt;code&gt;=&amp;gt;&lt;/code&gt; for arrow functions.&lt;/p&gt;
&lt;h3&gt;Number layer&lt;/h3&gt;
&lt;p&gt;A simple one: numbers across the home row, function numbers above. I&apos;ve got the shifted number keys along the bottom row but I don&apos;t really use them favouring the symbol layer instead.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./keyboard-img/corne-num-layer.png&quot; alt=&quot;Custom corne number layer&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;Utility layer&lt;/h3&gt;
&lt;p&gt;For now, this layer is minimal, mainly handling Bluetooth profiles. However, I expect it to evolve as I get more comfortable with ZMK.&lt;/p&gt;
&lt;h2&gt;Frictions&lt;/h2&gt;
&lt;p&gt;Right now, my biggest friction point with this keymap is the placement of the inner thumb keys — &lt;code&gt;Ctrl&lt;/code&gt; on the left and &lt;code&gt;Shift&lt;/code&gt; on the right.. For example, relatively common combos like &lt;code&gt;Ctl + V&lt;/code&gt; or &lt;code&gt;Shift + N&lt;/code&gt; mean I have to move my thumbs under my palm and my index fingers out, which is uncomfortable. &lt;s&gt;This is something that makes me consider home rows, or even just using the sixth (outer) columns more.&lt;/s&gt; [EDIT: home row mods and sticky shift have helped this, but I&apos;m now working on my own keyboard design to push the thumb keys out wider...] [UPDATE: I finished it! My new keyboard &lt;a href=&quot;https://github.com/thrly/tempest&quot;&gt;TEMPEST&lt;/a&gt;, which you can read a bit about &lt;a href=&quot;../tempest&quot;&gt;here&lt;/a&gt;]&lt;/p&gt;
&lt;h2&gt;Reflections&lt;/h2&gt;
&lt;p&gt;On the whole I&apos;m happy with this setup for now. Will my setup evolve? Absolutely. I&apos;m still slower and more uncertain typing split than on &apos;regular&apos; keyboards, but my RSI issues have abated. I’m not claiming that my keyboard cured anything, but improved awareness of my typing form, posture, and the use of a trackball (Elecom Deft) have all made a significant difference. And I think, above all, I&apos;ve found this whole learning and development process fun!&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./keyboard-img/keeb-7.jpg&quot; alt=&quot;Cat + Corne&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;Considering a split keyboard?&lt;/h2&gt;
&lt;p&gt;Do it! As I&apos;ve said, it&apos;s fun, and clunky, and slow. But I&apos;m happy to be doing it, and every day I&apos;m getting a little more confident and faster. I&apos;m still nowhere near my normal keyboard typing speed, and maybe I never will be, but I&apos;m okay with that as speed isn&apos;t my reason for doing this.&lt;/p&gt;
&lt;h3&gt;Choc vs MX&lt;/h3&gt;
&lt;p&gt;I started out with a wired MX Corne v4.1 with 46 keys (2 extra on the inner sides), with Outemu v3 Silent Peach switches and &lt;a href=&quot;https://vial.rocks/&quot;&gt;VIAL&lt;/a&gt; firmware. I was happy with the layout, but quickly realised that the wired connection was cluttered and bothered me, so I moved to a wireless Choc version.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./keyboard-img/keeb-6.jpg&quot; alt=&quot;Top: MX corne; Lower: Choc corne&quot; /&gt;&lt;/p&gt;
&lt;p&gt;I&apos;m using the 6-column variety. Initially I thought that more keys would require less layer-hopping, and therefore make for an easier transition from my usual 75% and 100% keyboards. What I wasn&apos;t anticipating was how &lt;em&gt;different&lt;/em&gt; the initial typing experience was. Even though I&apos;ve stayed with QWERTY (I need to use a variety of computers at work) typing on a non-staggered split keyboard was completely alien and I needed to effectively relearn to type from scratch. Now that I&apos;m mostly through that and onto the other side, I can&apos;t help but feel the sixth column is a little superfluous... and the 36-key (5 column) model looks nicely compact. If I do want to downsize, I don&apos;t anticipate a huge amount of changes to my setup besides maybe home-row mods. [I&apos;m currently designing my own board inspired by the &lt;a href=&quot;https://github.com/raeedcho/temper&quot;&gt;Temper&lt;/a&gt; / &lt;a href=&quot;https://github.com/essFitt/Bad-Temper&quot;&gt;Bad Temper&lt;/a&gt; and &lt;a href=&quot;https://github.com/GEIGEIGEIST/TOTEM&quot;&gt;TOTEM&lt;/a&gt; boards...]&lt;/p&gt;
&lt;h2&gt;Useful resources&lt;/h2&gt;
&lt;p&gt;I&apos;ve found these helpful in experimenting with different layouts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/foostan/crkbd&quot;&gt;Corne GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.reddit.com/r/ErgoMechKeyboards/&quot;&gt;ErgoMechKeyboards&lt;/a&gt; subreddit&lt;/li&gt;
&lt;li&gt;MechKeys, ZMK, and Typeractive discords&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/manna-harbour/miryoku&quot;&gt;Miryoku&lt;/a&gt; layout - &apos;an ergonomic, minimal, orthogonal, and universal keyboard layout.&apos;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://mark.stosberg.com/markstos-corne-3x5-1-keyboard-layout/&quot;&gt;Mark Stosberg&lt;/a&gt; - excellent article about the development of a personal layout&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://keymapdb.com/?keyboard=Corne&quot;&gt;KeymapDB&lt;/a&gt; - repository of user keymaps&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://getreuer.info/posts/keyboards/symbol-layer/index.html&quot;&gt;&apos;Designing a Symbol Layer&apos;&lt;/a&gt; - Pascal Getreuer article, 2021/23&lt;/li&gt;
&lt;li&gt;Learning to type on a split keyboard is a nightmare. I&apos;m practicing with &lt;a href=&quot;https://www.keybr.com/&quot;&gt;keybr.com&lt;/a&gt; and &lt;a href=&quot;https://monkeytype.com&quot;&gt;monkeytype.com&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;For ZMK, Nick Coustos has a nice visual editor for keymaps: &lt;a href=&quot;https://nickcoutsos.github.io/keymap-editor/&quot;&gt;https://nickcoutsos.github.io/keymap-editor/&lt;/a&gt; which compiles firmware through GitHub Actions. (But I still haven&apos;t found a workflow as smooth as &quot;live&quot; VIAL updates)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://precondition.github.io/home-row-mods&quot;&gt;A Guide to Home Row Mods&lt;/a&gt; - precondition&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/urob/zmk-config&quot;&gt;Urob&apos;s ZMK resources&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Close out&lt;/h2&gt;
&lt;h3&gt;Disclaimer&lt;/h3&gt;
&lt;p&gt;This is my personal keyboard layout and subject to change at any time.&lt;/p&gt;
&lt;p&gt;Keymap images were made with &lt;a href=&quot;https://www.keyboard-layout-editor.com/&quot;&gt;https://www.keyboard-layout-editor.com/&lt;/a&gt;. You can find my KLE jsons here: &lt;a href=&quot;https://gist.github.com/thrly/b95fc69724aa69244b455668c493e013&quot;&gt;Base&lt;/a&gt;, &lt;a href=&quot;https://gist.github.com/thrly/cdb5f2db60917d976764e9f1febc3cb6&quot;&gt;Symbol&lt;/a&gt;, &lt;a href=&quot;https://gist.github.com/thrly/55291c3ad0caa9661d260a5ba8e81352&quot;&gt;Navigation&lt;/a&gt;, &lt;a href=&quot;https://gist.github.com/thrly/303649a7d7d11bc8bd9088fcfdf19954&quot;&gt;Number&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Get in touch&lt;/h3&gt;
&lt;p&gt;Have any questions or thoughts? Are you on a similar keyboard journey? I&apos;d love to hear from you via &lt;a href=&quot;https://bsky.app/profile/thrly.bsky.social&quot;&gt;social media&lt;/a&gt;, email, etc.&lt;/p&gt;
&lt;h3&gt;Update 25/03/2025&lt;/h3&gt;
&lt;p&gt;I&apos;ve been playing with Home Row mods a lot for the last week or so since publishing this post, so much so that I&apos;ve merged them and &lt;a href=&quot;https://github.com/thrly/thrly-corne-zmk&quot;&gt;published my ZMK config on GitHub&lt;/a&gt;. Besides the HRMs there isn&apos;t really much differece to the layout above.&lt;/p&gt;
&lt;h3&gt;Update 25/05/2025&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;../tempest&quot;&gt;Read more about my new custom keyboard, TEMPEST.&lt;/a&gt; There&apos;s also some nice new keymap things there.fs&lt;/p&gt;
</content:encoded></item><item><title>Building My Markdown CV Workflow: One Source, Multiple Formats</title><link>https://thrly.com/blog/cv-workflow/</link><guid isPermaLink="true">https://thrly.com/blog/cv-workflow/</guid><description>Using Pandoc and GitHub Actions to manage and format my markdown CV in multiple versions.</description><pubDate>Fri, 20 Jun 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;As someone in the face of a turbulent job market I quickly found myself grappling with an unexpected but recurring frustration: my CV. Not the content itself, but the &lt;em&gt;process of managing&lt;/em&gt; it. I needed different versions for different contexts: a clean markdown version is nice to write, but I need a neatly typeset PDF for job applications, a Word Docx for recruiters, and a simple, readable web version I could share as a link. And each time I updated one, I had to manually replicate those changes across the others.&lt;/p&gt;
&lt;p&gt;This small pain point gradually became more than just an irritation. It became an opportunity for an automation project...&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://imgs.xkcd.com/comics/automation.png&quot; alt=&quot;Automation, xkcd&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Automation&lt;/em&gt;, &lt;a href=&quot;%5Bhttps://xkcd.com/1319/%5D(https://xkcd.com/1319)&quot;&gt;XKCD #1319&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;The Problem: Format Fragmentation&lt;/h2&gt;
&lt;p&gt;Over the past few years, I’ve maintained a CV in Google Docs, a LaTeX version for academic use, and a stripped-down plain-text version for job boards or technical applications. Keeping them in sync was tedious. Sometimes I’d update the Google Doc, forget to update the LaTeX file, and end up submitting a version that was months out of date.&lt;/p&gt;
&lt;p&gt;Worse still, each format had its own quirks: spacing and formatting in LaTeX, markdown rendering issues on GitHub, and limited styling options in plain HTML. I wanted a workflow that gave me &lt;em&gt;one single source of truth&lt;/em&gt;, from which I could generate all the required formats: PDF, markdown, and a web-friendly version.&lt;/p&gt;
&lt;h2&gt;The Solution: A Single-Source CV Repository&lt;/h2&gt;
&lt;p&gt;I decided to treat my CV like a software project: version-controlled, modular, and automated.&lt;/p&gt;
&lt;p&gt;The result is &lt;a href=&quot;https://github.com/thrly/cv-md&quot;&gt;my CV workflow repository&lt;/a&gt;. At its core, it’s a small, structured codebase that builds my CV in multiple formats from a single markdown file. Here&apos;s how it works:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/blog-img/cv-diagram.svg&quot; alt=&quot;CV workflow diagram&quot; /&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;CV Content in Markdown&lt;/strong&gt;&lt;br /&gt;
I write and maintain the actual CV content in a human-readable markdown file (creatively titled &lt;code&gt;cv.md&lt;/code&gt;). This keeps it portable, lightweight, and easy to edit in any text editor. A small YAML header gives variables like author&apos;s name, email, social media handles that can be injected into different format templates.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Format conversions&lt;/strong&gt;
&lt;a href=&quot;https://pandoc.org/&quot;&gt;Pandoc&lt;/a&gt; handles the various conversions using format templates. I have templates for HTML (with a simple CSS stylesheet), DOCX (with a simple font styles &lt;code&gt;--reference-doc&lt;/code&gt;, because DOCX doesn&apos;t support templating), and a TEX template for rendering the LaTeX version that is in turn used to create the PDF version. These produce clean, professional documents with consistent formatting every time.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Live Web Version&lt;/strong&gt;&lt;br /&gt;
By setting up the repo to be hosted with GitHub Pages, the HTML version gives me a &lt;a href=&quot;https://thrly.github.io/cv/outputs/cv&quot;&gt;live, public-facing CV at a consistent URL&lt;/a&gt;—always up-to-date and readable on any device.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Auto-updating and CI&lt;/strong&gt;
With GitHub Actions, I’ve set up automation so that every push to the main branch triggers a rebuild of the web version and regenerates the other version. It commits these back to the &lt;code&gt;outputs/&lt;/code&gt; folder (as well as the Action&apos;s Artifacts) so I can easily access or point to them. &lt;a href=&quot;https://github.com/thrly/cv/tree/master/outputs&quot;&gt;The master branch will always be the most up-to-date version.&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;All I have to do is update the markdown and commit—it’s fully hands-off after that.&lt;/p&gt;
&lt;h2&gt;Want to Use It? I Made a Template&lt;/h2&gt;
&lt;p&gt;If this kind of workflow would be useful to you, I’ve made it easy to get started: I’ve turned my setup into a &lt;a href=&quot;https://github.com/thrly/cv-md&quot;&gt;template repository you can fork&lt;/a&gt;. It comes preconfigured with everything you need:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A clean markdown structure for your content&lt;/li&gt;
&lt;li&gt;Scripts to generate web and PDF versions&lt;/li&gt;
&lt;li&gt;GitHub Actions for automated builds&lt;/li&gt;
&lt;li&gt;Styling that’s easy to customise&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can fork it directly, plug in your own details, and deploy your own live CV in just a few minutes.&lt;/p&gt;
&lt;h2&gt;Why This Was Worth Doing&lt;/h2&gt;
&lt;p&gt;Aside from being an immediately useful tool for managing my own CV, this project ended up doing a lot more:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Version control&lt;/strong&gt; lets me track changes over time and tailor versions for different types of roles.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Live shareability&lt;/strong&gt; means I can send someone a URL instead of a file.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Reusability&lt;/strong&gt; makes it adaptable for other document workflows: cover letters, portfolios, or academic bios.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Showcase&lt;/strong&gt;: It’s also a nice project to point to when applying for roles—demonstrating templating, markdown processing, static site generation, CI/CD pipelines, and PDF export.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Final Thoughts&lt;/h2&gt;
&lt;p&gt;What started as a simple attempt to clean up my CV workflow turned into a genuinely helpful tool—and one that I hope others will find useful too. If you’re looking to streamline your CV management, feel free to check out the &lt;a href=&quot;https://github.com/thrly/cv-md&quot;&gt;template on GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The best kind of project is one that solves your own problems—and can then go on to solve someone else’s too.&lt;/p&gt;
</content:encoded></item><item><title>TEMPEST: Designing A Custom Split Keyboard</title><link>https://thrly.com/blog/tempest/</link><guid isPermaLink="true">https://thrly.com/blog/tempest/</guid><description>Designing a custom wireless split keyboard</description><pubDate>Sun, 22 Jun 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;After a little while building and adapting split keyboards, I decided to design one for myself: &lt;em&gt;TEMPEST&lt;/em&gt; — a low-profile, wireless, 36-key split keyboard.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/blog-img/tempest/tempest.jpg&quot; alt=&quot;TEMPEST&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;TEMPEST&lt;/em&gt; reflects everything I’ve learned so far about what makes a keyboard genuinely comfortable and enjoyable to use, what works for me, and more than a few blunders in PCB layout.&lt;/p&gt;
&lt;p&gt;This project builds on ideas I wrote about in &lt;a href=&quot;https://thrly.com/blog/thoughts-on-customising-a-split-keyboard-layout/&quot;&gt;“Thoughts on Customising a Split Keyboard Layout”&lt;/a&gt;, where I detailed the process of adapting to split ergo layouts, rethinking muscle memory, and designing a keymap that worked for me. With &lt;em&gt;TEMPEST&lt;/em&gt;, I wanted to take that further—not just adapting layouts to existing hardware, but shaping the hardware itself around my hands, workflow and habits.&lt;/p&gt;
&lt;p&gt;The full repo, with Gerbers, KiCad PCB, 3D-printable case, and ergogen design files is here: &lt;a href=&quot;https://github.com/thrly/tempest&quot;&gt;https://github.com/thrly/tempest&lt;/a&gt;. ZMK firmware configs and keymap layout can be found at: &lt;a href=&quot;https://github.com/thrly/tempest-zmk&quot;&gt;https://github.com/thrly/tempest-zmk&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Why Build a Keyboard?&lt;/h3&gt;
&lt;p&gt;It started with small frustrations: thumbs too cramped, pinkies overworked, layout compromises dictated by PCBs etc. I &lt;em&gt;love&lt;/em&gt; my Corne keyboards, and others in the community like Sweep, TOTEM, and Chocofi look excellent... but none of them felt like &lt;em&gt;mine&lt;/em&gt;, so I wanted to try making something that solved all those &quot;if this thing was a little bit more _&lt;strong&gt;_&lt;/strong&gt;&quot; issues.&lt;/p&gt;
&lt;p&gt;Designing my own keyboard would let me integrate all the things I’d grown to prefer, cut the things I didn’t need, and, perhaps most importantly, &lt;em&gt;own&lt;/em&gt; the full workflow: from PCB to firmware to daily use.&lt;/p&gt;
&lt;p&gt;I should start by saying, my electronic knowledge is very basic. I&apos;ve soldered modular synthesisers from kits, but never designed anything myself. Thankfully, keyboards are actually pretty basic in terms of circuitry, and tools like &lt;a href=&quot;https://ergogen.ceoloide.com/&quot;&gt;ergogen&lt;/a&gt; made the layout process ridiculously easy. This guide by &lt;a href=&quot;https://flatfootfox.com/ergogen-introduction/&quot;&gt;FlatFootFox&lt;/a&gt; walked through the whole process and the KiCad routing. I would have been completely lost without it.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/blog-img/tempest/tempest-2.jpg&quot; alt=&quot;TEMPEST&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;Design Goals&lt;/h3&gt;
&lt;p&gt;My staring point was my beloved Corne (the choc version from &lt;a href=&quot;https://typeractive.xyz/&quot;&gt;Typeractive&lt;/a&gt; specifically. As I say, I love it, but there are some things I don&apos;t love and wanted to change.&lt;/p&gt;
&lt;p&gt;With &lt;em&gt;TEMPEST&lt;/em&gt;, I aimed for:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;36 keys&lt;/strong&gt;: A minimal layout (3x5 + 3 thumbs) that forces thoughtful layering and cuts away redundancy. Thumb cluster is spaced out a little wider than the Corne.
&lt;ul&gt;
&lt;li&gt;(In an earlier version I played with snap-off extra outer keys, like the &lt;a href=&quot;https://github.com/GEIGEIGEIST/TOTEM&quot;&gt;TOTEM&lt;/a&gt; but couldn&apos;t make the PCB routing work).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Custom column stagger&lt;/strong&gt;: A little more pronounced that Cornes, and based loosely on my finger length and reach — especially important for the pinky and ring fingers. I also added some slight splay to the ring and pinky columns, again, &lt;em&gt;a la&lt;/em&gt; TOTEM.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Low-profile Choc switches&lt;/strong&gt;: Nice and comfortable, I love my &lt;a href=&quot;https://mechboards.co.uk/products/lowprokb-ambients-twilight&quot;&gt;Ambients Twilight&lt;/a&gt; for long sessions and great for portability.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Wireless-first design&lt;/strong&gt;: Powered by nice!nano controllers and onboard integrated battery support. This all follows the Typeractive Corne build which I think is excellent.
&lt;ul&gt;
&lt;li&gt;I tried to add nice!view display, but screwed up the connections on v 1.1, so this doesn&apos;t currently work...&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ZMK firmware&lt;/strong&gt;: I’ve grown to prefer the workflow and customisability of ZMK, especially its support for home-row mods, combos, layered design, and the GitHub automated build.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Reversible PCB&lt;/strong&gt;: Makes for more cost-effective fabrication, and there&apos;s a certain elegance to it.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Simple low-profile 3D-printed case&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;All of this is designed in Ergogen + KiCad and then hand-assembled. The result is a clean, compact board that’s become my daily driver at home and on the go.&lt;/p&gt;
&lt;h3&gt;Firmware and Layout Philosophy&lt;/h3&gt;
&lt;p&gt;ZMK has become central to my keyboard setup. The firmware workflow (especially now with GitHub Actions) allows me to treat firmware the same way I treat code—versioned, repeatable, and documented. The &lt;em&gt;TEMPEST&lt;/em&gt; repo builds firmware automatically with every change, making experimentation easy. I wouldn&apos;t say its totally frictionless, as you still need to manually flash the new firmware via USB for each change, which is a pain.&lt;/p&gt;
&lt;p&gt;The layout follows principles I wrote about previously on &lt;a href=&quot;https://thrly.com/blog/thoughts-on-customising-a-split-keyboard-layout/&quot;&gt;“Thoughts on Customising a Split Keyboard Layout”&lt;/a&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Mod-taps&lt;/strong&gt; for home-row modifiers.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Layered access&lt;/strong&gt; to symbols, navigation, and media keys.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Thumb-focused design&lt;/strong&gt; with three keys per side — one for space, one for layer switching, and one for backspace or enter, depending on the context. (I&apos;ve also added a mod-morph to easily add underscores &lt;code&gt;WHEN_WRITING_IN_ALL_CAPS&lt;/code&gt;, which is nice.)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Combos&lt;/strong&gt; and &lt;strong&gt;sticky keys&lt;/strong&gt; to reduce awkward reaches. I&apos;ve really been getting into combos on the default layer on a 36-key layout. Common things like &lt;code&gt;-_&apos;&quot;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;I added a cheeky &lt;code&gt;F19&lt;/code&gt; macro on &lt;code&gt;q+t+y+p&lt;/code&gt; which &lt;a href=&quot;https://autohotkey.com/&quot;&gt;Autohotkey&lt;/a&gt; returns as &lt;code&gt;console.log(&lt;/code&gt; Take &lt;em&gt;that&lt;/em&gt; JavaScript!&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;After lots of of refining and daily use, the layout feels second nature. The consistency in structure makes relearning layers on different devices (or different computers) much easier. I no longer think about where things are — they just &lt;em&gt;are&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;BONUS&lt;/strong&gt;: On the &lt;a href=&quot;https://github.com/thrly/tempest-zmk&quot;&gt;config repo&lt;/a&gt;, I&apos;ve used the brilliant &lt;a href=&quot;https://github.com/caksoylar/keymap-drawer&quot;&gt;Keymap Drawer by caksoylar&lt;/a&gt; to produce automated layout diagrams each time the keymap is updated.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/blog-img/tempest/tempest-white.jpg&quot; alt=&quot;TEMPEST&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;Takeaways and Lessons Learned&lt;/h3&gt;
&lt;p&gt;Designing &lt;em&gt;TEMPEST&lt;/em&gt; wasn’t just about soldering and scripting — it was a full-stack project. Here are a few key lessons from the process:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Start with use cases, not features.&lt;/strong&gt; It’s easy to get caught up in extras (RGB, encoders, OLEDs), but focusing on how I actually type helped me prioritise the core layout and form factor first.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;The thumb cluster is everything.&lt;/strong&gt; I think many boards get this ~wrong~ cramped. Iterating on placement, angle, and spacing made a bigger difference than almost anything else.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Muscle memory takes time, but it pays off.&lt;/strong&gt; A minimal layout forces you to be intentional. At first, it’s frustrating; over time, it’s freeing.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Wireless has trade-offs.&lt;/strong&gt; I love the tidy setup and portability, but wireless introduces extra debugging and some latency trade-offs, especially for certain workflows (e.g., gaming). That said, for writing and coding, it’s been rock solid.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Designing PCBs is empowering.&lt;/strong&gt; Even with the learning curve of KiCad, being able to iterate on physical design is liberating. It’s coding, but for your hands.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Most importantly: making your own keyboard turns typing from a task into a craft. You’re not just pressing keys — you’re engaging with a tool you’ve built, shaped, and refined. Every time I type now, I get a smug, satisfied feeling that I made this. (To counter, everytime something goes wrong with it, I&apos;m entirely to blame...)&lt;/p&gt;
&lt;h3&gt;Final Thoughts&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;TEMPEST&lt;/em&gt; might not be the end of my keyboard journey — there are always new ideas to try and I&apos;ve already got plans for v2 — but it’s the first keyboard that feels &lt;em&gt;complete&lt;/em&gt; for my current needs. It’s the result of lots of iteration, both in code and hardware, and I’m genuinely proud of it.&lt;/p&gt;
&lt;p&gt;If you’re curious about the layout, want to build one yourself, or fork it for your own experiments, the full repo is here: &lt;a href=&quot;https://github.com/thrly/tempest&quot;&gt;https://github.com/thrly/tempest&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Happy building — and if you do make your own version, I’d love to hear about it.&lt;/p&gt;
&lt;p&gt;Lastly, credit to the keyboards that inspired and informed &lt;em&gt;TEMPEST&lt;/em&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/foostan/crkbd&quot;&gt;Corne&lt;/a&gt; by foostan (and the &lt;a href=&quot;https://typeractive.xyz/&quot;&gt;Typeractive&lt;/a&gt; version)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/GEIGEIGEIST/TOTEM&quot;&gt;TOTEM&lt;/a&gt; by GEIST&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/raeedcho/temper&quot;&gt;Temper&lt;/a&gt; by raeedcho&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/essFitt/Bad-Temper/tree/main&quot;&gt;Bad Temper&lt;/a&gt; by essFitt&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/carrefinho/forager&quot;&gt;FORAGER&lt;/a&gt; by carrefinho&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/pashutk/chocofi&quot;&gt;Chocofi&lt;/a&gt;, &lt;a href=&quot;https://github.com/davidphilipbarr/Sweep&quot;&gt;Sweep&lt;/a&gt;, and others.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;/blog-img/tempest/wave.png&quot; alt=&quot;Great Wave&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>Softening Edges: Chaikin’s Algorithm in Generative Art</title><link>https://thrly.com/blog/chaikin-smoothing/</link><guid isPermaLink="true">https://thrly.com/blog/chaikin-smoothing/</guid><description>Using Chaikin&apos;s corner cutting to smooth shapes in p5.js generative art</description><pubDate>Fri, 04 Jul 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;!-- # Softening Edges: Chaikin’s Algorithm in Generative Art --&amp;gt;&lt;/p&gt;
&lt;p&gt;In many of my generative sketches, I start with raw geometry: a jagged polygon, a noisy perimeter, or just a random set of coordinates. These tend to feel too rigid, too mechanical... too sharp. What I often want instead is a way to soften that geometry, to make it feel more fluid, more organic. One of my favourite ways to do this is by applying a few iterations of &lt;strong&gt;Chaikin’s corner-cutting algorithm&lt;/strong&gt;. I used it heavily in my series &lt;em&gt;WAVETABLE: four fucked waveforms&lt;/em&gt; (2024):&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/blog-img/chaikin/four_fucked_waveforms.png&quot; alt=&quot;WAVETABLE&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Chaikin’s method is simple: it smooths a path by iteratively “cutting corners” by a set ratio. For each pair of points, it inserts two new ones slightly closer to each end, then repeats the process as many times as needed. The result is a sequence of points that approximate a smooth curve, without needing to touch splines, control handles, or Bézier maths.&lt;/p&gt;
&lt;h2&gt;How It Works&lt;/h2&gt;
&lt;p&gt;Given a set of points for a polyline or polygon:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;For each pair of consecutive points &lt;code&gt;(A, B)&lt;/code&gt; of a segment, calculate:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Q = 0.75 * A + 0.25 * B&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;R = 0.25 * A + 0.75 * B&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Replace the original segment with the new points &lt;code&gt;Q&lt;/code&gt; and &lt;code&gt;R&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Repeat for a few iterations.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This gradually rounds sharp corners, and after several iterations the shape converges toward a quadratic B-spline. The resulting form is still defined entirely by your original path—just softened.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/blog-img/chaikin/chaikin-demo.gif&quot; alt=&quot;chaikin demo&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;Code example&lt;/h3&gt;
&lt;p&gt;Here&apos;s an implementation I use in my &lt;a href=&quot;https://github.com/thrly/chaikin-curve&quot;&gt;&lt;code&gt;chaikin-curve&lt;/code&gt;&lt;/a&gt; repo:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function chaikin(point_array, n_iterations) { // point_array is a set of x,y coords
  let smooth_array = [];
  for (let iter = 0; iter &amp;lt; n_iterations; iter++) {
    let temp = [];
    for (let i = 0; i &amp;lt; point_array.length - 1; i++) {
      let p0 = [point_array[i][0], point_array[i][1]]; // segment start
      let p1 = [point_array[i + 1][0], point_array[i + 1][1]]; // segment end
      let q = [0.75 * p0[0] + 0.25 * p1[0], 0.75 * p0[1] + 0.25 * p1[1]];
      let r = [0.25 * p0[0] + 0.75 * p1[0], 0.25 * p0[1] + 0.75 * p1[1]];
      temp.push(q);
      temp.push(r);
    }
    point_array = temp.slice();
  }

  // then add back in start and end points
  point_array.splice(0, 0, [points[0][0], points[0][1]]);
  point_array.push([
    points[points.length - 1][0],
    points[points.length - 1][1],
  ]);
  return point_array;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Why Not Just Use Bézier Curves?&lt;/h2&gt;
&lt;p&gt;A fair question. Libraries like p5.js give you Bézier curves and &lt;code&gt;curveVertex()&lt;/code&gt; for free. So why reach for Chaikin?&lt;/p&gt;
&lt;p&gt;Chaikin&apos; corner cutting doesn’t require precise control or knowledge of Béziers. It works with whatever geometry you give it. No need to think about angles and control points. It’s ideal for softening the edges of generative shapes — messy blobs, grid-based forms, even text outlines — where the goal is &lt;em&gt;aesthetic&lt;/em&gt; rather than mathematical precision.&lt;/p&gt;
&lt;p&gt;Sure, &lt;code&gt;curve()&lt;/code&gt; might give me an equally good result in most cases, but having a more custom solution is handy sometimes.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://sighack.com/post/chaikin-curves&quot;&gt;SigHack&lt;/a&gt;&apos;s excellent post on Chaikin curves (in Processing) gives some really nice use cases: from softened voronoi cells, to brush strokes.&lt;/p&gt;
&lt;p&gt;Chaikin’s algorithm won’t replace Bézier curves and splines, but it’s an excellent tool to keep around when you&apos;re working procedurally and want a bit of softness.&lt;/p&gt;
&lt;h2&gt;Related links&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;George Chaikin&apos;s son, Paul Chaikin, gives an excellent explanation/demonstration here: &lt;a href=&quot;https://observablehq.com/@pamacha/chaikins-algorithm&quot;&gt;https://observablehq.com/@pamacha/chaikins-algorithm&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/thrly/chaikin-curve&quot;&gt;My p5.js demo on GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://sighack.com/post/chaikin-curves&quot;&gt;Sighack’s write-up with visuals&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item></channel></rss>