<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="/assets/css/rss.xsl" type="text/xsl"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>dbushell.com (all feeds)</title>
    <description>David Bushell’s Blog + Notes combined feed</description>
    <link>https://dbushell.com</link>
    <lastBuildDate>Fri, 05 Jun 2026 15:00:00 GMT</lastBuildDate>
    <atom:link href="https://dbushell.com/rss.xml" rel="self" type="application/rss+xml"/>
    <author>David Bushell</author>
    <language>en-GB</language>
<item>
  <title>Are you standard.site?</title>
  <description>Standard.site provides shared AT Protocol lexicons. Atproto is just spicy JSON and asymmetric cryptography. I’ve tried to explain atproto in more detail before. Bluesky has always supported a few open graph meta tags which I use to generate images for blog posts. […]</description>
  <link>https://dbushell.com/2026/06/05/are-you-standard-site/</link>
  <guid isPermaLink="true">https://dbushell.com/2026/06/05/are-you-standard-site/</guid>
  <pubDate>Fri, 05 Jun 2026 15:00:00 GMT</pubDate>
  <content:encoded><![CDATA[<p><a href="https://standard.site/" rel="noopener noreferrer" target="_blank">Standard.site</a> provides shared <glossary-term id="--term-atproto"><a href="https://atproto.com/" rel="noopener noreferrer" target="_blank">AT Protocol</a></glossary-term> lexicons. Atproto is just spicy <glossary-term id="--term-json"><a href="https://www.json.org/" rel="noopener noreferrer" target="_blank">JSON</a></glossary-term> and asymmetric cryptography. I’ve <a href="https://dbushell.com/2026/03/10/building-on-at-protocol/">tried to explain atproto</a> in more detail before.</p><p>Bluesky has always supported a few <a href="https://ogp.me/" rel="noopener noreferrer" target="_blank">open graph meta tags</a> which I use to <a href="https://dbushell.com/2024/11/15/generate-open-graph-images-with-playwright/">generate images</a> for blog posts. That’s part of the social media game; get in people’s faces as loudly as possible. Now the game has changed!</p><h2 id="fancy-button">Fancy button</h2><p>I return Monday <a href="https://dbushell.com/2026/06/01/challenge-and-opportunity/">ready to work</a> and suddenly I start seeing a fancy new “View publication” button appear in my Bluesky feed. I’ve never wanted nor needed a button before but now that people are rocking buttons, what am I supposed to be, a buttonless pleb?</p><p>I got my own button it looks like this:</p><figure class="Image"><img src="https://dbushell.com/images/blog/2026/bluesky-view-publication.avif" alt="example of a Bluesky embed with the &#39;View publication&#39; button" width="606" height="480" decoding="async" fetchpriority="low" loading="lazy" id="--img-e6e30467"/></figure><p>Mat Marquis, fellow button connoisseur, was quick with a guide to <a href="https://wil.to/posts/standard-site/" rel="noopener noreferrer" target="_blank">“Implementing Standard.Site”</a> which I hastily copied.</p><h2 id="automation">Automation</h2><p>Mat used an <a href="https://pdsls.dev/" rel="noopener noreferrer" target="_blank">atproto explorer</a> to edit records which is akin to rawdoggin’ SQL in production. Given the weekly GitHub and NPM malware party this is probably a safer play than running <code>npm install</code> yourself. I’m never going to remember to publish manually though.</p><p>I have a <a href="https://dbushell.com/2025/05/11/the-static-site-churns/">janky build script</a> and some experience with the <a href="https://github.com/mary-ext/atcute/tree/trunk/packages/clients/client" rel="noopener noreferrer" target="_blank">@atcute libraries</a>. How hard can it be? My script begins by generating a manifest of pages by parsing markdown before rendering the HTML template.</p><p>I added a new step that fetches all atproto records in the <code>site.standard.document</code> collection. It cross-references the paths in my manifest. Any unknown path has the record deleted. It then iterates the manifest and either updates the atproto record (if title or description has changed), or creates a new record if none existed. Finally it adds the atproto URI to the manifest for the <code>&lt;link&gt;</code> element.</p><p>Now my blog is <a href="https://standard.site/" rel="noopener noreferrer" target="_blank">standard.site</a> and I have a fancy button to prove it.</p>
<hr>
<p>
Thanks for reading! Follow me on <a href="https://dbushell.com/mastodon/">Mastodon</a> and <a href="https://dbushell.com/bluesky/">Bluesky</a>.
Subscribe to my <a href="https://dbushell.com/rss.xml">Blog</a> and <a href="https://dbushell.com/notes/rss.xml">Notes</a> or <a href="https://dbushell.com/merge/rss.xml">Combined</a> feeds.
</p>
]]></content:encoded>
</item>
<item>
  <description>I can’t decide whether I like the headingoffset attribute. Manuel Matuzović has written “Context-aware headings in HTML” for the uninitiated. Jake Firefox has a good garage wall video covering the attribute too. It solves a real problem for component libraries and basic template includes. I just can’t vibe with seeing the &lt;h1&gt; to &lt;h6&gt; elements being a different level than their names imply. Has a simple &lt;h&gt; element been discussed? I’m curious if the slop machines are able to “parse” the correct heading levels. On the basis that I imagine they’ll fail spectacularly, I give headingoffset the thumbs up!</description>
  <link>https://dbushell.com/notes/2026-06-03T13:45Z/</link>
  <guid isPermaLink="true">https://dbushell.com/notes/2026-06-03T13:45Z/</guid>
  <pubDate>Wed, 03 Jun 2026 13:45:00 GMT</pubDate>
  <content:encoded><![CDATA[<p>I can’t decide whether I like the <a href="https://html.spec.whatwg.org/multipage/sections.html#heading-levels-&amp;-offsets" rel="noopener noreferrer" target="_blank"><code>headingoffset</code> attribute</a>.</p><p>Manuel Matuzović has written <a href="https://matuzo.at/blog/2026/content-aware-headings" rel="noopener noreferrer" target="_blank">“Context-aware headings in HTML”</a> for the uninitiated. Jake Firefox has a good <a href="https://bsky.app/profile/webdevs.firefox.com/post/3mncp42h7ik2b" rel="noopener noreferrer" target="_blank">garage wall video</a> covering the attribute too.</p><p>It solves a real problem for component libraries and basic template includes. I just can’t vibe with seeing the <code>&lt;h1&gt;</code> to <code>&lt;h6&gt;</code> elements being a different level than their names imply. Has a simple <code>&lt;h&gt;</code> element been discussed?</p><p>I’m curious if the slop machines are able to “parse” the correct heading levels. On the basis that I imagine they’ll fail spectacularly, I give <code>headingoffset</code> the thumbs up!</p>
<hr>
<p>
Thanks for reading! Follow me on <a href="https://dbushell.com/mastodon/">Mastodon</a> and <a href="https://dbushell.com/bluesky/">Bluesky</a>.
Subscribe to my <a href="https://dbushell.com/rss.xml">Blog</a> and <a href="https://dbushell.com/notes/rss.xml">Notes</a> or <a href="https://dbushell.com/merge/rss.xml">Combined</a> feeds.
</p>
]]></content:encoded>
</item>
<item>
  <description>Get in! My ascension 10 wins in Slay the Spire 2 continue. I finally ran a deck with The Defect that felt coherent. 4 Claw combined with 3 Feral and just enough block.</description>
  <link>https://dbushell.com/notes/2026-06-02T17:34Z/</link>
  <guid isPermaLink="true">https://dbushell.com/notes/2026-06-02T17:34Z/</guid>
  <pubDate>Tue, 02 Jun 2026 17:34:00 GMT</pubDate>
  <content:encoded><![CDATA[<p>Get in! My <a href="https://dbushell.com/notes/2026-05-31T17:29Z/">ascension 10 wins</a> in <strong>Slay the Spire 2</strong> continue. I finally ran a deck with <em>The Defect</em> that felt coherent. 4 <a href="https://slaythespire.wiki.gg/wiki/Slay_the_Spire_2:Claw" rel="noopener noreferrer" target="_blank">Claw</a> combined with 3 <a href="https://slaythespire.wiki.gg/wiki/Slay_the_Spire_2:Feral" rel="noopener noreferrer" target="_blank">Feral</a> and just enough block.</p><figure class="Image"><img src="https://dbushell.com/images/blog/2026/stp2-a10-claw.avif" alt="Slay the Spire 2 run stats for The Defect ascension 10 showing relics and cards." width="1920" height="1080" decoding="async" fetchpriority="low" loading="lazy" id="--img-aec065c5"/></figure>
<hr>
<p>
Thanks for reading! Follow me on <a href="https://dbushell.com/mastodon/">Mastodon</a> and <a href="https://dbushell.com/bluesky/">Bluesky</a>.
Subscribe to my <a href="https://dbushell.com/rss.xml">Blog</a> and <a href="https://dbushell.com/notes/rss.xml">Notes</a> or <a href="https://dbushell.com/merge/rss.xml">Combined</a> feeds.
</p>
]]></content:encoded>
</item>
<item>
  <description>Overview of Digital Accessibility Technologies by Declan Chidlow is an insightful list of lesser-known technology. How do website makers ensure what we’ve built is accessible? It is impractical to test everything. Even with access to all devices we’d struggle to experience their usage like those who depend upon assistive tech daily. Testing matters but “fixing accessibility” as an afterthought is guaranteed failure. We have web standards for a reason. Declarative HTML allows us to express web content and UI semantically. This allows browsers to understand and adapt. It’s remarkably effective. It’s criminal that we have a generation of developers who fail this simple step. Get the basic foundations right and there will be less cracks to paper over. Nothing can be perfectly accessible but we can at least give assistive tech a chance.</description>
  <link>https://dbushell.com/notes/2026-06-02T05:39Z/</link>
  <guid isPermaLink="true">https://dbushell.com/notes/2026-06-02T05:39Z/</guid>
  <pubDate>Tue, 02 Jun 2026 05:39:00 GMT</pubDate>
  <content:encoded><![CDATA[<p><a href="https://vale.rocks/posts/digital-accessibility-technologies" rel="noopener noreferrer" target="_blank">Overview of Digital Accessibility Technologies</a> by Declan Chidlow is an insightful list of lesser-known technology.</p><p>How do website makers ensure what we’ve built is accessible? It is impractical to test everything. Even with access to all devices we’d struggle to experience their usage like those who depend upon assistive tech daily.</p><p>Testing matters but “fixing accessibility” as an afterthought is guaranteed failure. We have web standards for a reason. Declarative HTML allows us to express web content and UI semantically. This allows browsers to understand and adapt. It’s remarkably effective. It’s criminal that we have a <a href="https://dbushell.com/2025/10/23/react-regulation/">generation of developers</a> who fail this simple step.</p><p>Get the basic foundations right and there will be less cracks to paper over. Nothing can be perfectly accessible but we can at least give assistive tech a chance.</p>
<hr>
<p>
Thanks for reading! Follow me on <a href="https://dbushell.com/mastodon/">Mastodon</a> and <a href="https://dbushell.com/bluesky/">Bluesky</a>.
Subscribe to my <a href="https://dbushell.com/rss.xml">Blog</a> and <a href="https://dbushell.com/notes/rss.xml">Notes</a> or <a href="https://dbushell.com/merge/rss.xml">Combined</a> feeds.
</p>
]]></content:encoded>
</item>
<item>
  <title>Challenge and opportunity</title>
  <description>I am back! Ten days “offline”. For me that just means online without talking to anyone. My break came at a time of high industry (and personal) stress. “Seeing talented people lose motivation bums me the hell out. Reach out and say thanks - Kevin Powell”Thank you to those who reached out whilst I […]</description>
  <link>https://dbushell.com/2026/06/01/challenge-and-opportunity/</link>
  <guid isPermaLink="true">https://dbushell.com/2026/06/01/challenge-and-opportunity/</guid>
  <pubDate>Mon, 01 Jun 2026 15:00:00 GMT</pubDate>
  <content:encoded><![CDATA[<p>I am back! Ten days “offline”. For me that just means <em>online</em> without talking to anyone.</p><p>My break came at a time of high industry (and personal) stress.</p><blockquote><p>Seeing talented people lose motivation bums me the hell out.</p><p><cite><a href="https://www.kevinpowell.co/article/tell-someone-you-appreciate-them/" rel="noopener noreferrer" target="_blank">Reach out and say thanks</a> - Kevin Powell</cite></p></blockquote><p>Thank you to those who reached out whilst I was offline :)</p><p>Catching up on <glossary-term id="--term-rss"><a href="https://en.wikipedia.org/wiki/RSS" rel="noopener noreferrer" target="_blank">RSS</a></glossary-term> and reading <a href="https://webweekly.email/archive/web-weekly-193/" rel="noopener noreferrer" target="_blank">educators question their worth</a> makes me angry. Seeing more people cite <glossary-term id="--term-ai"><a href="https://dbushell.com/ai/">“AI”</a></glossary-term> as a primary reason to <a href="https://dbushell.com/notes/2026-04-25T06:26Z/">exit tech</a> boils my blood!</p><blockquote><p>AI was the last straw. Have you heard of that island off India where the indigenous population kills any outsiders fool-hardy enough to land? They are doing the rest of us a favor by preserving a way of life we may need again someday, or at the very least should not want to see completely extinguished.</p><p><cite><a href="https://openpath.quest/2026/i-am-retiring-from-tech-to-live-offline/" rel="noopener noreferrer" target="_blank">I Am Retiring from Tech to Live Offline</a> - Chad Whitacre</cite></p></blockquote><p>The <a href="https://techcrunch.com/2026/05/27/tech-ceos-are-apparently-suffering-from-ai-psychosis/" rel="noopener noreferrer" target="_blank">chatbox psychosis</a> epidemic remains in full force. Despite countless studies suggesting <a href="https://fortune.com/2026/05/11/ai-automation-layoffs-gartner-study-roi/" rel="noopener noreferrer" target="_blank">AI isn’t paying off</a>. Despite countless examples showing that <a href="https://lenz.io/research/llm-disagreement" rel="noopener noreferrer" target="_blank">AI is broken by design</a>. Despite growing sentiment that <a href="https://www.bbc.co.uk/news/articles/ce8pqd54qneo" rel="noopener noreferrer" target="_blank">AI isn’t welcome</a>. Despite everything, the stochastic parrot feeders insist that our future is token servitude.</p><p>I crashed out hard at <a href="https://dbushell.com/2026/05/20/google-just-spat-in-my-face/">Google’s deskilling</a>. That incensed me. To see the word “skill” redefined and sold as a directory of markdown files is a grave insult.</p><h2 id="an-opportunity">An opportunity</h2><p><a href="https://dbushell.com/2026/02/09/big-design-and-bold-ideas/#why-change">I’m still motivated</a>. In the face of career-ending threats I see opportunity. I’ll be setting up shop as a limited company soon(-ish) after 15+ years of self-employment. Expect more news on that front later in the year.</p><p>First I need to get a grip on unhealthy levels of stress. That means prioritising paid client work over my blog and social media antics! I work Mon–Thursday for exactly that reason. Friday is my personal day. Lately though I’ve found myself in keyboard warrior mode at 11am midweek. That must stop if I am to survive!</p><p>The challenge is to continue enjoying my profession. I want to find a way to encourage and remotivate others too. At the same time, I can’t ignore the continued assault. The web must be fought for. That ain’t easy when it’s all so demoralising. I won’t be silenced in my fight against <a href="https://dbushell.com/2026/04/28/alternative-thoughts/">alternative thoughts</a>. The gatekeepers cannot be allowed to turn one of humanity’s greatest creations into a tokendollar economy.</p><p>I can’t believe this needs repeating but: <strong>do not replace real skills with a directory of markdown files.</strong> Stay hungry to learn. Fight for the web.</p>
<hr>
<p>
Thanks for reading! Follow me on <a href="https://dbushell.com/mastodon/">Mastodon</a> and <a href="https://dbushell.com/bluesky/">Bluesky</a>.
Subscribe to my <a href="https://dbushell.com/rss.xml">Blog</a> and <a href="https://dbushell.com/notes/rss.xml">Notes</a> or <a href="https://dbushell.com/merge/rss.xml">Combined</a> feeds.
</p>
]]></content:encoded>
</item>
<item>
  <description>Holy moly! I pulled of back-to-back shiv builds in Slay the Spire 2 to destroy my first ascension 10! And I was beginning to lament how difficult The Silent is to pilot. I even took down the two bosses without popping either of two fairy potions.</description>
  <link>https://dbushell.com/notes/2026-05-31T17:29Z/</link>
  <guid isPermaLink="true">https://dbushell.com/notes/2026-05-31T17:29Z/</guid>
  <pubDate>Sun, 31 May 2026 17:29:00 GMT</pubDate>
  <content:encoded><![CDATA[<p>Holy moly! I pulled of <a href="https://dbushell.com/notes/2026-05-31T11:22Z/">back-to-back shiv builds</a> in <strong>Slay the Spire 2</strong> to destroy my first ascension 10! And I was beginning to lament how difficult <em>The Silent</em> is to pilot. I even took down the two bosses without popping either of two fairy potions.</p><figure class="Image"><img src="https://dbushell.com/images/blog/2026/stp2-a10-win.avif" alt="Slay the Spire 2 run stats for The Silent ascension 10 showing relics and cards." width="1920" height="1080" decoding="async" fetchpriority="low" loading="lazy" id="--img-18a53d2e"/></figure>
<hr>
<p>
Thanks for reading! Follow me on <a href="https://dbushell.com/mastodon/">Mastodon</a> and <a href="https://dbushell.com/bluesky/">Bluesky</a>.
Subscribe to my <a href="https://dbushell.com/rss.xml">Blog</a> and <a href="https://dbushell.com/notes/rss.xml">Notes</a> or <a href="https://dbushell.com/merge/rss.xml">Combined</a> feeds.
</p>
]]></content:encoded>
</item>
<item>
  <description>Following Friday’s antics I have achieved a Slay the Spire 2 milestone. Ascension level 10 on all characters! The Silent was last to arrive. After many anaemic runs I finally got shivs working with two upgraded Afterimage. I’ve always played at the highest ascension rank possible so my winrate is around 8–10% except for The Regent at 20%. I suspect that’ll fall much lower before I beat A10. I’ve reached the final boss a few times but it’s a brutal affair.</description>
  <link>https://dbushell.com/notes/2026-05-31T11:22Z/</link>
  <guid isPermaLink="true">https://dbushell.com/notes/2026-05-31T11:22Z/</guid>
  <pubDate>Sun, 31 May 2026 11:22:00 GMT</pubDate>
  <content:encoded><![CDATA[<p>Following <a href="https://dbushell.com/notes/2026-05-29T13:41Z/">Friday’s antics</a> I have achieved a <strong>Slay the Spire 2</strong> milestone. Ascension level 10 on all characters! <em>The Silent</em> was last to arrive. After many anaemic runs I finally got shivs working with two upgraded <a href="https://slaythespire.wiki.gg/wiki/Slay_the_Spire_2:Afterimage" rel="noopener noreferrer" target="_blank">Afterimage</a>.</p><figure><video autoplay controls loop muted playsinline preload="metadata" width="600" height="280" aria-label="Slay the Spire 2 start screen showing ascension level 10 on all characters" poster="/images/blog/2026/stp2-a10.avif">    <source src="/images/blog/2026/stp2-a10.mp4" type="video/mp4"/>  </video><figcaption>Of course, I have yet to beat A10.</figcaption></figure><p>I’ve always played at the highest ascension rank possible so my winrate is around 8–10% except for <em>The Regent</em> at 20%. I suspect that’ll fall much lower before I beat A10. I’ve reached the final boss a few times but it’s a brutal affair.</p>
<hr>
<p>
Thanks for reading! Follow me on <a href="https://dbushell.com/mastodon/">Mastodon</a> and <a href="https://dbushell.com/bluesky/">Bluesky</a>.
Subscribe to my <a href="https://dbushell.com/rss.xml">Blog</a> and <a href="https://dbushell.com/notes/rss.xml">Notes</a> or <a href="https://dbushell.com/merge/rss.xml">Combined</a> feeds.
</p>
]]></content:encoded>
</item>
<item>
  <description>⚠️ Slay the Spire 2 major spoilers! Steam says I’ve put 300+ hours into Slay the Spire 2 if that’s to be believed. I’m up to ascension level 9–10 on all characters. Except The Regent because that requires brain power. A10 has decimated my win rate. Anyway, go away now if you want to avoid a big spoiler. Seriously, don’t let me ruin this for you. I heard about a secret boss and I found it! You probably won’t believe a secret boss exists. When I read the rumour I thought it was a silkpost. Last warning… So yeah I just kinda murdered the fake Merchant??? and stole all the goods. Edit: I beat the run. The Ice Cream relic to conserve energy between turns is over-powered. The Diamond Diadem relic came it clutch on the final boss allowing me to setup a 382 damage Sovereign Blade.</description>
  <link>https://dbushell.com/notes/2026-05-29T13:41Z/</link>
  <guid isPermaLink="true">https://dbushell.com/notes/2026-05-29T13:41Z/</guid>
  <pubDate>Fri, 29 May 2026 13:41:00 GMT</pubDate>
  <content:encoded><![CDATA[<div class="Alert"><p>⚠️ <strong>Slay the Spire 2 major spoilers!</strong></p></div><p>Steam says I’ve put 300+ hours into <a href="https://store.steampowered.com/app/2868840/Slay_the_Spire_2/" rel="noopener noreferrer" target="_blank">Slay the Spire 2</a> if that’s to be believed. I’m up to ascension level 9–10 on all characters. Except <em>The Regent</em> because that requires brain power. A10 has decimated my win rate.</p><p>Anyway, go away now if you want to avoid a big spoiler.</p><p>Seriously, don’t let me ruin this for you.</p><p>I heard about a secret boss and I found it!</p><p>You probably won’t believe a secret boss exists.</p><p>When I read the rumour I thought it was a <a href="https://en.wiktionary.org/wiki/silkpost" rel="noopener noreferrer" target="_blank">silkpost.</a></p><p>Last warning…</p><figure><video controls muted playsinline preload="metadata" width="1280" height="720" aria-label="Slay the Spire 2 secret boss fight!" poster="/images/blog/2026/stp2-secret-boss.avif">    <source src="/images/blog/2026/stp2-secret-boss.mp4" type="video/mp4"/>  </video><figcaption>Audio removed (failed to capture). No backseating please I did not play my cards optimally.</figcaption></figure><p>So yeah I just kinda murdered the fake <em>Merchant???</em> and stole all the goods.</p><p><strong>Edit:</strong> I beat the run. The <em>Ice Cream</em> relic to conserve energy between turns is over-powered. The <em>Diamond Diadem</em> relic came it clutch on the final boss allowing me to setup a 382 damage <em>Sovereign Blade</em>.</p><figure class="Image"><img src="https://dbushell.com/images/blog/2026/stp2-secret-boss-run.avif" alt="Slay the Spire 2 end screen showing cards and relics collected during the run." width="1280" height="720" decoding="async" fetchpriority="low" loading="lazy" id="--img-ae7bfdeb"/></figure>
<hr>
<p>
Thanks for reading! Follow me on <a href="https://dbushell.com/mastodon/">Mastodon</a> and <a href="https://dbushell.com/bluesky/">Bluesky</a>.
Subscribe to my <a href="https://dbushell.com/rss.xml">Blog</a> and <a href="https://dbushell.com/notes/rss.xml">Notes</a> or <a href="https://dbushell.com/merge/rss.xml">Combined</a> feeds.
</p>
]]></content:encoded>
</item>
<item>
  <description>“If your job doesn’t require you to burn tokens, then probably ignore MWG and, by extensions, LLM for code. In case the environmental damage, intellectual property theft, wealth redistribution to the rich, encoded biases, and built-in support of fascism weren’t enough. Maybe Don’t Rely on Google’s “Modern Web Guidance” - Adrian Roselli”I’ve quoted the part that I find most relevant but Roselli does provide more constructive criticism.</description>
  <link>https://dbushell.com/notes/2026-05-26T07:00Z/</link>
  <guid isPermaLink="true">https://dbushell.com/notes/2026-05-26T07:00Z/</guid>
  <pubDate>Tue, 26 May 2026 07:00:00 GMT</pubDate>
  <content:encoded><![CDATA[<blockquote><p>If your job doesn’t require you to burn tokens, then probably ignore MWG and, by extensions, LLM for code. In case the environmental damage, intellectual property theft, wealth redistribution to the rich, encoded biases, and built-in support of fascism weren’t enough.</p><p><cite><a href="https://adrianroselli.com/2026/05/maybe-dont-rely-on-googles-modern-web-guidance.html" rel="noopener noreferrer" target="_blank">Maybe Don’t Rely on Google’s “Modern Web Guidance”</a> - Adrian Roselli</cite></p></blockquote><p>I’ve quoted the part that <a href="https://dbushell.com/2026/05/20/google-just-spat-in-my-face/">I find most relevant</a> but Roselli does provide more constructive criticism.</p>
<hr>
<p>
Thanks for reading! Follow me on <a href="https://dbushell.com/mastodon/">Mastodon</a> and <a href="https://dbushell.com/bluesky/">Bluesky</a>.
Subscribe to my <a href="https://dbushell.com/rss.xml">Blog</a> and <a href="https://dbushell.com/notes/rss.xml">Notes</a> or <a href="https://dbushell.com/merge/rss.xml">Combined</a> feeds.
</p>
]]></content:encoded>
</item>
<item>
  <description>I am offline until June. If you catch me online please insist I disconnect immediately.</description>
  <link>https://dbushell.com/notes/2026-05-21T13:04Z/</link>
  <guid isPermaLink="true">https://dbushell.com/notes/2026-05-21T13:04Z/</guid>
  <pubDate>Thu, 21 May 2026 13:04:00 GMT</pubDate>
  <content:encoded><![CDATA[<p>I am offline until June.</p><p>If you catch me online please insist I disconnect immediately.</p>
<hr>
<p>
Thanks for reading! Follow me on <a href="https://dbushell.com/mastodon/">Mastodon</a> and <a href="https://dbushell.com/bluesky/">Bluesky</a>.
Subscribe to my <a href="https://dbushell.com/rss.xml">Blog</a> and <a href="https://dbushell.com/notes/rss.xml">Notes</a> or <a href="https://dbushell.com/merge/rss.xml">Combined</a> feeds.
</p>
]]></content:encoded>
</item>
<item>
  <description>AI Resist List looks interesting. I sent feedback: they host with Vercel and Cloudflare. Two Big Tech villains entrenched in slop. The inititive has notable people behind it. Including Karen Hao who announced it on Twitter. I suppose there is an argument for reaching a particular audience? Maybe this has teeth. Maybe it exists to promote a book reprint. Hao’s book is a good read, to be fair.</description>
  <link>https://dbushell.com/notes/2026-05-21T04:46Z/</link>
  <guid isPermaLink="true">https://dbushell.com/notes/2026-05-21T04:46Z/</guid>
  <pubDate>Thu, 21 May 2026 04:46:00 GMT</pubDate>
  <content:encoded><![CDATA[<p><a href="https://airesistlist.org/" rel="noopener noreferrer" target="_blank">AI Resist List</a> looks interesting. I sent feedback: they host with <a href="https://dbushell.com/2025/06/13/your-framework-is-showing-nextjs-error/">Vercel</a> and <a href="https://dbushell.com/notes/2026-01-27T19:11Z/">Cloudflare</a>. Two <em>Big Tech</em> villains entrenched in slop. The inititive has notable people behind it. Including <a href="https://xcancel.com/_KarenHao/status/2057230251093074268" rel="noopener noreferrer" target="_blank">Karen Hao</a> who announced it on <a href="https://dbushell.com/notes/2026-05-17T07:01Z/"><del>Twitter</del></a>. I suppose there is an argument for reaching a particular audience? Maybe this has teeth. Maybe it exists to promote a book reprint. Hao’s book is a good read, to be fair.</p>
<hr>
<p>
Thanks for reading! Follow me on <a href="https://dbushell.com/mastodon/">Mastodon</a> and <a href="https://dbushell.com/bluesky/">Bluesky</a>.
Subscribe to my <a href="https://dbushell.com/rss.xml">Blog</a> and <a href="https://dbushell.com/notes/rss.xml">Notes</a> or <a href="https://dbushell.com/merge/rss.xml">Combined</a> feeds.
</p>
]]></content:encoded>
</item>
<item>
  <description>“[Generative AI exists] to keep entry-level workers pruned all the way back to the roots, in the interest of keeping wages low, employment tenuous, staff nervous, and the unfathomably rich insulated from the potential financial repercussions of destroying countless lives. If you can never advance beyond a “press the button, generate the thing,” you’re as replaceable as the next person — if there’s nothing beyond entry-level experience, they’ll never have to pay you more than an “entry-level” salary. LLemdashes - Mat Marquis”</description>
  <link>https://dbushell.com/notes/2026-05-20T12:47Z/</link>
  <guid isPermaLink="true">https://dbushell.com/notes/2026-05-20T12:47Z/</guid>
  <pubDate>Wed, 20 May 2026 12:47:00 GMT</pubDate>
  <content:encoded><![CDATA[<blockquote><p>[Generative AI exists] to keep entry-level workers pruned all the way back to the roots, in the interest of keeping wages low, employment tenuous, staff nervous, and the unfathomably rich insulated from the potential financial repercussions of destroying countless lives. If you can never advance beyond a “press the button, generate the thing,” you’re as replaceable as the next person — if there’s nothing beyond entry-level experience, they’ll never have to pay you more than an “entry-level” salary.</p><p><cite><a href="https://wil.to/posts/llemdashes/" rel="noopener noreferrer" target="_blank">LLemdashes</a> - Mat Marquis</cite></p></blockquote>
<hr>
<p>
Thanks for reading! Follow me on <a href="https://dbushell.com/mastodon/">Mastodon</a> and <a href="https://dbushell.com/bluesky/">Bluesky</a>.
Subscribe to my <a href="https://dbushell.com/rss.xml">Blog</a> and <a href="https://dbushell.com/notes/rss.xml">Notes</a> or <a href="https://dbushell.com/merge/rss.xml">Combined</a> feeds.
</p>
]]></content:encoded>
</item>
<item>
  <title>Google just spat in my face</title>
  <description>It’s Google I/O week and this year’s theme is performative slop. Budding Googlers battle it out on stage vying for executive eyeballs. The prize? Exemption from the next culling. As you might know AI isn’t my cup of tea and my AI policy explains why. […]</description>
  <link>https://dbushell.com/2026/05/20/google-just-spat-in-my-face/</link>
  <guid isPermaLink="true">https://dbushell.com/2026/05/20/google-just-spat-in-my-face/</guid>
  <pubDate>Wed, 20 May 2026 10:00:00 GMT</pubDate>
  <content:encoded><![CDATA[<p>It’s <a href="https://io.google/2026/" rel="noopener noreferrer" target="_blank">Google I/O</a> week and this year’s theme is <em>performative slop</em>. Budding Googlers battle it out on stage vying for executive eyeballs. The prize? Exemption from <a href="https://www.teamblind.com/layoffs/company/google" rel="noopener noreferrer" target="_blank">the next culling</a>.</p><div class="Box"><p>As you might know AI isn’t my cup of tea and my <a href="https://dbushell.com/ai/">AI policy</a> explains why.</p></div><p>AI peddlers like Google have made one thing abundantly clear: their product will take your skills. It will take your profession. It will dehumanise you and you’ll pay for it.</p><h2 id="googles-web">Google’s web</h2><p>I figured <a href="https://wil.to/posts/googles-prompt-api/" rel="noopener noreferrer" target="_blank">Google’s Prompt API</a> would be the most offensive attack on an open web I’d witness this month. Nope! Google’s new microsite has sent me apoplectic.</p><blockquote><p>Modern Web Guidance is a set of evergreen and expert-vetted skills that guide your AI coding agents across many common use cases to build modern web experiences that are accessible, performant, and secure.</p><p><cite><a href="https://developer.chrome.com/docs/modern-web-guidance" rel="noopener noreferrer" target="_blank">Build with Modern Web Guidance</a></cite></p></blockquote><p>At first glance this is nothing more than an advertisement for the AI industrial complex. I made the mistake of engaging my brain for a closer look. Brain engagement is discouraged so I only have myself to blame for the ensuing rage.</p><p>Google spits in the face of professional web development.</p><p>Where do I even start?</p><h3 id="modern-web">“modern web”</h3><p>The repeated use of “modern web” implies that current development practices are out of date. Throw away all established knowledge because Google has <a href="https://bsky.app/profile/sarahedo.bsky.social/post/3mmacszhlno2t" rel="noopener noreferrer" target="_blank">changed the game</a>.</p><h3 id="evergreen">“evergreen”</h3><p>The entire <em>chat-box-driven-development</em> craze has been a long series of “you’re prompting it wrong” arguments. Are we to understand that Google’s new magic incantations have settled the debate once and for all?</p><h3 id="expert-vetted">“expert-vetted”</h3><p>Which experts? Google, I assume. You are no longer an expert. You are token consumer number six. Expertise are not a privilege extended to consumers.</p><h3 id="skills">“skills”</h3><p>Forgive my ignorance but I struggle to understand how AI addicts define “skills”. From what I can understand these “skills” are text prompts? “Skills” used to refer to the trained abilities required to do a professional job. I’m no prescriptivist but this is slopaganda.</p><h2 id="deskilling">Deskilling</h2><p>Google’s idea of “modern web” is a deskilling effort that should deeply offend developers to their core. It should also offend the AI apologists. Google thinks you’re too stupid to articulate your prayers coherently so just copy-paste the ten commandments. Defer to the almighty bullshitter in the cloud!</p><p>What do you think a fair wage is for a professional developer who has less agency than <a href="https://rickandmorty.fandom.com/wiki/Purpose_Robot" rel="noopener noreferrer" target="_blank">Butter Bot?</a> They’ll say this “democratises” web development alongside all and <em>every</em> profession in which AI has been <a href="https://tante.cc/2026/04/21/ai-as-a-fascist-artifact/" rel="noopener noreferrer" target="_blank">violently forced</a>.</p><p>And what is the end goal? To deskill you so far down the ladder you’ll be forced into token servitude. To make a handful of billionaires even richer.</p><p>Prompt boxes are not <a href="https://dbushell.com/2026/04/28/alternative-thoughts/#its-just-a-tool">“just a tool”</a> they are the end of your career.</p><hr/><blockquote><p>Implement a starter Content Security Policy (CSP) without breaking my app.</p></blockquote><p>Don’t break it bro! Pinky promise?</p>
<hr>
<p>
Thanks for reading! Follow me on <a href="https://dbushell.com/mastodon/">Mastodon</a> and <a href="https://dbushell.com/bluesky/">Bluesky</a>.
Subscribe to my <a href="https://dbushell.com/rss.xml">Blog</a> and <a href="https://dbushell.com/notes/rss.xml">Notes</a> or <a href="https://dbushell.com/merge/rss.xml">Combined</a> feeds.
</p>
]]></content:encoded>
</item>
<item>
  <title>Web whetstones</title>
  <description>How do you stay sharp as a web developer and/or designer? I’ll share my advice below. I’m also looking for front-end folk to advise me too. What are your whetstones? That is to say: sources of news and knowledge to level up professionally. Does that metaphor work? […]</description>
  <link>https://dbushell.com/2026/05/18/web-whetstone/</link>
  <guid isPermaLink="true">https://dbushell.com/2026/05/18/web-whetstone/</guid>
  <pubDate>Mon, 18 May 2026 10:00:00 GMT</pubDate>
  <content:encoded><![CDATA[<p>How do you stay sharp as a web developer and/or designer?</p><p>I’ll share my advice below. I’m also looking for front-end folk to advise me too. What are your whetstones? That is to say: sources of news and knowledge to level up professionally. Does that metaphor work? We’re sharpening our minds, and I suppose the web too with our minds… are minds the whetstone here?</p><p>Moving swiftly on, in rough order of preference:</p><h2 id="rss-feeds">RSS feeds</h2><p>People love to declare “RSS is dead” because they’ve chosen the likes of Google to gate-keep their web access. Interesting choice, but RSS remains alive and well.</p><p>When I discover a new blog and like what I read, I’ll subscribe. There’s a good chance that person will write something useful again one day! Funny how that works. I don’t flood my reader with big sites that exist to generate content. I collect personal blogs that may only post once a year. That’s still plenty of unique insights as the list grows.</p><p>I won’t share my list because I feel for RSS to work you have to curate it yourself.</p><h2 id="podcasts">Podcasts</h2><p><a href="https://shoptalkshow.com/" rel="noopener noreferrer" target="_blank">Shop Talk Show</a> has been number one forever. <a href="https://syntax.fm/" rel="noopener noreferrer" target="_blank">Syntax</a> remains a decent second if you’re deft with the fast-forward button (it’s a little ‘sloppy’ these days.) <a href="https://www.igalia.com/chats/" rel="noopener noreferrer" target="_blank">Igalia Chats</a> is packed with wisdom. <a href="https://vivaldi.com/blog/better-web/" rel="noopener noreferrer" target="_blank">For a Better Web</a> is Bruce Lawson in your ears. <a href="https://web-weaving.jamesg.blog/" rel="noopener noreferrer" target="_blank">Wonders of Web Weaving</a> from James is new and hopefully a regular listen.</p><p>I’ve unsubscribed from too many podcasts that pivoted to AI servitude which is disheartening. I’m not adverse to such discussion but the level of mindless platitudes and gigglefests about what their wacky chat boxes said ain’t my cup of tea.</p><h2 id="social-media">Social media</h2><p><a href="https://dbushell.com/mastodon/">Mastodon</a> and <a href="https://dbushell.com/bluesky/">Bluesky</a> is where I follow folk in the web industry. Socials can be a great whetstone if you manage your follow list carefully. Everyone uses these platforms for different reasons which can be difficult to balance. Personally I stick to shop talk and mute politics for example. I follow individuals and rarely organisations to avoid “brand engagement”.</p><h2 id="newsletters">Newsletters</h2><p>Email newsletters are useful to catch stuff I’ve missed. Many exist in RSS form too. My favourites are typically link dumps with a side of commentary.</p><p>Current favourites:</p><ul><li><a href="https://webweekly.email/" rel="noopener noreferrer" target="_blank">Web Weekly</a></li><li><a href="https://piccalil.li/the-index/" rel="noopener noreferrer" target="_blank">The Index</a></li><li><a href="https://frontendfoc.us/" rel="noopener noreferrer" target="_blank">Frontend Focus</a></li><li><a href="https://news.design.systems/" rel="noopener noreferrer" target="_blank">Design Systems News</a></li></ul><p><a href="https://sidebar.io/" rel="noopener noreferrer" target="_blank">Sidebar</a> still has the odd gem if I care to sift through the “AI” links.</p><p>Newsletters are a declining category for me. Perhaps because I keep getting unsubscribed by those with failed tracking pixels. Email costs money to send so I’ll accept my loss.</p><h2 id="toxic-forums">Toxic forums</h2><p><a href="https://lobste.rs/" rel="noopener noreferrer" target="_blank">Lobste.rs</a>, <a href="https://news.ycombinator.com/" rel="noopener noreferrer" target="_blank">Hacker News</a>, Reddit (e.g. <a href="https://old.reddit.com/r/webdev/" rel="noopener noreferrer" target="_blank">web dev</a>, <a href="https://old.reddit.com/r/experienceddevs/" rel="noopener noreferrer" target="_blank">experienced devs</a>, <a href="https://old.reddit.com/r/frontend/" rel="noopener noreferrer" target="_blank">frontend</a> etc). Does <a href="https://dev.arabicstore1.workers.dev/" rel="noopener noreferrer" target="_blank">dev.to</a> have any humans left? These forums are a good source of links — <strong>if</strong> you can filter the bot spam and avoid the cesspit of comments. Toxicity spreads and it’s all too easy to get dragged in. Sometimes you just have to let people be wrong on the internet.</p><h2 id="meet-ups">Meet-ups</h2><p>I’ve heard these still happen! I only leave my house now to scavenge for essentials so I don’t have much to say. <a href="https://clearleft.com/events" rel="noopener noreferrer" target="_blank">Clearleft events</a> are guaranteed value if you’re in the UK. Some conferences have online tickets but I find the in-person socialising to be the main benefit.</p><h2 id="bookmarks">Bookmarks</h2><p>Everything listed above is (or has) a website. I’m poor at organising and utilising bookmarks. I’ll manually visit bigger blogs like <a href="https://css-tricks.com/" rel="noopener noreferrer" target="_blank">CSS-Tricks</a> and <a href="https://www.smashingmagazine.com/" rel="noopener noreferrer" target="_blank">Smashing Magazine</a> once a month to see if anything interests me. I bookmark a handful of YouTube channels like <a href="https://www.youtube.com/@KevinPowell" rel="noopener noreferrer" target="_blank">Kevin Powell</a> because I have no Google account to <em>“smash that subscribe button”</em>. YouTube isn’t my thing though. I have an allergic reaction to algorithm driven content.</p><p><strong>Edit:</strong> I’ve been reminded that YouTube has RSS feeds. Personally too noisy for my RSS use but a great tip to remember!</p><h2 id="discord"><del>Discord</del></h2><p>I don’t use Discord but I hear it get promoted often. Are these communities lively or are they a ghost town? That’s my problem with Discord. It’s a blackhole for information; antithetical to an open web! Am I missing out? Not sure I care.</p><hr/><p>For no particular reason I’ll end with this quote from Seth Rogen.</p><blockquote><p>“I don’t understand what it’s supposed to do. Every time I see a video on Instagram that’s like, ‘Hollywood is cooked,’ what follows is, like, the most stupid dog shit I’ve ever seen in my life,” he said. “And if your instinct is to use AI and not go through that process, you shouldn’t be a writer, because then you’re not writing.”</p><p><cite><a href="https://www.hollywoodreporter.com/tv/tv-news/seth-rogen-ai-write-scripts-shouldnt-be-a-writer-1236597822/" rel="noopener noreferrer" target="_blank">Seth Rogen Says If “Your Instinct Is to Use AI” to Write Scripts, “You Shouldn’t Be a Writer”</a> - The Hollywood Reporter</cite></p></blockquote><p>P.S. no more blog posts until June. I’m due a holiday!</p>
<hr>
<p>
Thanks for reading! Follow me on <a href="https://dbushell.com/mastodon/">Mastodon</a> and <a href="https://dbushell.com/bluesky/">Bluesky</a>.
Subscribe to my <a href="https://dbushell.com/rss.xml">Blog</a> and <a href="https://dbushell.com/notes/rss.xml">Notes</a> or <a href="https://dbushell.com/merge/rss.xml">Combined</a> feeds.
</p>
]]></content:encoded>
</item>
<item>
  <title>Surveys will continue until diversity improves</title>
  <description>The web and tech industry is a veritable sausage party. We don’t need surveys to prove it but we have surveys to prove it. State of surveys have been running for a decade now. Let’s look at the 2025 survey demographics: Yes I think “sausage party” is accurate. Weißwurstfest even. […]</description>
  <link>https://dbushell.com/2026/05/15/surveys-will-continue-until-diversity-improves/</link>
  <guid isPermaLink="true">https://dbushell.com/2026/05/15/surveys-will-continue-until-diversity-improves/</guid>
  <pubDate>Fri, 15 May 2026 15:00:00 GMT</pubDate>
  <content:encoded><![CDATA[<p>The web and tech industry is a veritable sausage party. We don’t need surveys to prove it but we have <a href="https://www.devographics.com/" rel="noopener noreferrer" target="_blank">surveys to prove it</a>. <em>State of</em> surveys have been running for a decade now.</p><p>Let’s look at the 2025 survey demographics:</p><div class="Table"><table>    <thead>      <tr>        <th>Survey</th>        <th>Men</th>        <th>White</th>      </tr>    </thead>    <tbody>      <tr>        <td><a href="https://2025.stateofjs.com/en-US/demographics/" rel="noopener noreferrer" target="_blank">JS</a></td>        <td>93%</td>        <td>70%</td>      </tr>      <tr>        <td><a href="https://2025.stateofcss.com/en-US/demographics/" rel="noopener noreferrer" target="_blank">CSS</a></td>        <td>86%</td>        <td>80%</td>      </tr>      <tr>        <td><a href="https://2025.stateofhtml.com/en-US/demographics/" rel="noopener noreferrer" target="_blank">HTML</a></td>        <td>87%</td>        <td>82%</td>      </tr>      <tr>        <td><a href="https://2025.stateofreact.com/en-US/demographics/" rel="noopener noreferrer" target="_blank">React</a></td>        <td>90%</td>        <td>66%</td>      </tr>      <tr>        <td><a href="https://2025.stateofai.dev/en-US/demographics/" rel="noopener noreferrer" target="_blank">AI</a></td>        <td>90%</td>        <td>77%</td>      </tr>      <tr>        <td><a href="https://2025.stateofdevs.com/en-US/demographics/" rel="noopener noreferrer" target="_blank">Devs</a></td>        <td>82%</td>        <td>80%</td>      </tr>    </tbody>  </table></div><p>Yes I think “sausage party” is accurate. <em>Weißwurstfest</em> even. And yes cock jokes are part of the problem. When I worked in London in the early 2010’s every tech meet-up was plaid shirts and IPA frosted moustaches. Larger tech conferences were better. They had a few women attending and occasionally allowed to speak and a better variety of beers. I worked and mingled with a good bunch of lads. Even good lads make cock jokes after a craft beer. Just a joke, innit? When you read <a href="https://ohhelloana.blog/woman-in-tech/" rel="noopener noreferrer" target="_blank">accounts like Ana Rodrigues’</a> it’s easy to think “not my lads” but then you remember the boisterous punchlines, and that one guy… but he was more of a tagalong.</p><p>Some of us grow up but the industry doesn’t. These days I work remotely and don’t get out much but I get the impression little has changed. Certainly the online bro-culture amplifies the worst traits. Now we have LLMs built by and trained on that culture. Ain’t that wonderful.</p><p>The <em>State of</em> surveys continue to report alarming numbers. Are they a fair representation of the industry? Do they help or hinder diversity?</p><p>Miriam Suzanne raised the concern in 2024.</p><blockquote><p>These correlations don’t tell us much without knowing how representative the data is. I’m just not sure what I’m looking at, or how it should be read. But it concerns me that browsers use surveys like this as a primary gauge of developer interest – seemingly without asking who’s represented, or who might be missing from the data.</p><p><cite><a href="https://www.oddbird.net/2024/11/04/css-demographics/" rel="noopener noreferrer" target="_blank">What do survey demographics tell us?</a> - Miriam Suzanne</cite></p></blockquote><p>As Miriam noted the <em>State of</em> surveys do influence browser vendors.</p><blockquote><p>The focus areas for 2026 include several areas identified as top interop issues in the State of HTML and State of CSS surveys.</p><p><cite><a href="https://web.dev/blog/interop-2026#:~:text=The%20focus%20areas%20for%202026%20include%20several%20areas%20identified%20as%20top%20interop%20issues%20in%20the%20State%20of%20HTML%20and%20State%20of%20CSS%20surveys." rel="noopener noreferrer" target="_blank">Interop 2026: Continuing to improve the web for developers</a> - Rachel Andrew</cite></p></blockquote><p>Yet survey after survey after survey the demographics remain the same. Maybe the web industry is actually dominated by white guys (and now their new chat box companions). Oh and 60–70% of those surveyed report “None” under “Disability Status” so there’s that too.</p><p>This is all kind of a big problem, obviously. Other humans need to use the web. Their voices need to influence the web platform. Maybe if we actually listened we could support more diverse needs and spend less time <a href="https://dbushell.com/notes/2026-05-06T17:31Z/">fast-tracking bro-tech</a>.</p><p>So yeah <a href="https://bsky.app/profile/dbushell.com/post/3mlupn7s4s22c" rel="noopener noreferrer" target="_blank">I mock the <em>State of</em> surveys</a> because what are we doing here? Why are we looking at these numbers and concluding: <em>“Wow! I can’t believe Axios is still popular in [current year]!”</em>  Lack of diversity is the only relevant takeaway that means anything. I don’t know if these surveys are part of the problem. I know they’re not the solution. But who knows, if we keep asking six times a year maybe diversity will improve?</p>
<hr>
<p>
Thanks for reading! Follow me on <a href="https://dbushell.com/mastodon/">Mastodon</a> and <a href="https://dbushell.com/bluesky/">Bluesky</a>.
Subscribe to my <a href="https://dbushell.com/rss.xml">Blog</a> and <a href="https://dbushell.com/notes/rss.xml">Notes</a> or <a href="https://dbushell.com/merge/rss.xml">Combined</a> feeds.
</p>
]]></content:encoded>
</item>
<item>
  <title>Unscrewing lightbulbs</title>
  <description>Giving lightbulbs a MAC address was a mistake that I’m living with. “I’m literally unscrewing lightbulbs to renew their DHCP lease @dbushell.com - Bluesky”Instead of enjoying the bank holiday Monday I updated my homelab software. I was ‘inspired’ by the Copy Fail Linux bug to run full distro […]</description>
  <link>https://dbushell.com/2026/05/08/self-hosted-update-spring-2026/</link>
  <guid isPermaLink="true">https://dbushell.com/2026/05/08/self-hosted-update-spring-2026/</guid>
  <pubDate>Fri, 08 May 2026 15:00:00 GMT</pubDate>
  <content:encoded><![CDATA[<p>Giving lightbulbs a MAC address was a mistake that I’m living with.</p><blockquote><p>I’m literally unscrewing lightbulbs to renew their DHCP lease</p><p><cite><a href="https://bsky.app/profile/dbushell.com/post/3mkzs4jro6s2r" rel="noopener noreferrer" target="_blank">@dbushell.com</a> - Bluesky</cite></p></blockquote><p>Instead of enjoying the bank holiday Monday I updated my homelab software. I was ‘inspired’ by the <a href="https://copy.fail/" rel="noopener noreferrer" target="_blank">Copy Fail Linux bug</a> to run full distro upgrades. This is my self-hosted update for Spring 2026 (rough documentation to give future me a chance).</p><p>Monday’s fun risked a week of pain. I do have backups but restoring them on a broken LAN is tricky. I have an ISP provided wifi router to dust off in an emergency. Along with an absurdly long 15 metre HDMI cable I do not care to unravel. <a href="https://dbushell.com/2026/01/19/self-hosted-update-winter-2026/">My winter update</a> added a hardware fallback but that too requires careful rejigging.</p><h2 id="debian-trixie">Debian Trixie</h2><p>I have Proxmox hosts, virtual machines, and Raspberry <a href="https://dietpi.com/docs/" rel="noopener noreferrer" target="_blank">DietPis</a>. They were all on Debian 12 (Bookworm) with a kernel potentially susceptible to the bug.</p><p>Minimal Debian installs are perfect because I run everything in Docker anyway. Data volumes are easy to backup or network mount. I can change host at will for any service. Debian is just sensible, well documented no-fuss Linux.</p><details><summary>Ubuntu is not for me</summary><p>I used to run “minimal” Ubuntu server. Following 24.04 I found myself debloating most of the Ubuntu part (i.e. snaps). It sounds like the <a href="https://seclists.org/oss-sec/2026/q2/332" rel="noopener noreferrer" target="_blank">new coreutils are a CVE party</a>. Glad I escaped before that drama! As it happens, this week’s <a href="https://linuxunplugged.com/665" rel="noopener noreferrer" target="_blank">Linux Unplugged episode</a> had Canonical’s VP of Engineering spewing embarrassing AI platitudes. <em>“Ubuntu is not for you”</em> was the only thing said worth remembering.</p></details><h3 id="virtual-machine-upgrades">Virtual machine upgrades</h3><p>I updated most of my VMs first because they’re easy to restore if anything fails. I followed <a href="https://linuxconfig.org/how-to-upgrade-debian-to-latest-version" rel="noopener noreferrer" target="_blank">Lubos Rendek’s guide</a>. Start with a full package update and then change the package sources before running another step-by-step upgrade.</p><figure><pre data-lang="sh" tabindex="0" id="pre-8a94650b"><code><span class="line"><span class="syntax-c01639ae">sed</span><span class="space"> </span><span class="syntax-765b360f">-i</span><span class="space"> </span><span class="syntax-6168685d">'</span><span class="syntax-e661ac3e">s/bookworm/trixie/g</span><span class="syntax-6168685d">'</span><span class="space"> </span><span class="syntax-e661ac3e">/etc/apt/sources.list</span></span>
<span class="line"><span class="syntax-c01639ae">find</span><span class="space"> </span><span class="syntax-e661ac3e">/etc/apt/sources.list.d</span><span class="space"> </span><span class="syntax-765b360f">-name</span><span class="space"> </span><span class="syntax-6168685d">"</span><span class="syntax-e661ac3e">*.list</span><span class="syntax-6168685d">"</span><span class="space"> </span><span class="syntax-765b360f">-exec</span><span class="space"> </span><span class="syntax-e661ac3e">sed</span><span class="space"> </span><span class="syntax-765b360f">-i</span><span class="space"> </span><span class="syntax-6168685d">'</span><span class="syntax-e661ac3e">s/bookworm/trixie/g</span><span class="syntax-6168685d">'</span><span class="space"> </span><span class="syntax-e661ac3e">{}</span><span class="space"> </span><span class="syntax-1656d967">\;</span></span></code></pre><figcaption>Neat command to find and replace <code>bookworm</code> with <code>trixie</code> in the apt sources.</figcaption></figure><p>The only non-Debian sources I have are Docker and Tailscale. Yes that means I run Docker inside Proxmox VMs — and you can’t stop me! That’s not even my worse crime…</p><p>After the Trixie upgrade I found VMs were failing to obtain a LAN IP address. The virtual network device had been renamed from <code>enp6s18</code> to <code>ens18</code>. I edited <code>interfaces</code> and just changed the reference.</p><pre data-lang="sh" tabindex="0" id="pre-e32ca793"><code><span class="line"><span class="syntax-7b4433fd">#</span><span class="space"> </span><span class="syntax-7b4433fd">/etc/network/interfaces</span></span>
<span class="line"><span class="syntax-c01639ae">allow-hotplug</span><span class="space"> </span><span class="syntax-e661ac3e">ens18</span></span>
<span class="line"><span class="syntax-c01639ae">iface</span><span class="space"> </span><span class="syntax-e661ac3e">ens18</span><span class="space"> </span><span class="syntax-e661ac3e">inet</span><span class="space"> </span><span class="syntax-e661ac3e">dhcp</span></span></code></pre><p>There is surely a better/more predictable fix but this was the quickest. The same name was used across all VMs so I guess 18 is the magic number.</p><p>Everything has been stable so far. If issues arise I’ll just nuke and pave from a Debian 13 ISO. Docker config and volumes are backed up independently of the VM images.</p><h3 id="dietpi-upgrades">DietPi upgrades</h3><p>DietPi has a <a href="https://dietpi.com/blog/?p=4014#upgrade" rel="noopener noreferrer" target="_blank">long Trixie upgrade post</a> I didn’t read. I just curled to bash:</p><pre data-lang="sh" tabindex="0" id="pre-1de06fe5"><code><span class="line"><span class="syntax-c01639ae">sudo</span><span class="space"> </span><span class="syntax-e661ac3e">bash</span><span class="space"> </span><span class="syntax-765b360f">-c</span><span class="space"> </span><span class="syntax-6168685d">"</span><span class="syntax-e661ac3e">$(</span><span class="syntax-c01639ae">curl</span><span class="space"> </span><span class="syntax-765b360f">-sSf</span><span class="space"> </span><span class="syntax-6168685d">'</span><span class="syntax-e661ac3e">https://raw.githubusercontent.com/MichaIng/DietPi/dev/.meta/dietpi-trixie-upgrade</span><span class="syntax-6168685d">'</span><span class="syntax-e661ac3e">)</span><span class="syntax-6168685d">"</span></span></code></pre><p>I gave the script a cursory glance before hitting enter. I have a Pi 4 running failover DNS and a Pi 5 running <a href="https://dbushell.com/2025/08/11/github-ensloppification/#enter-forgejo">my public Forgejo instance</a>. DietPi is ideal because of the tiny footprint; I run Docker here too. <a href="https://forums.raspberrypi.com/viewtopic.php?t=397946" rel="noopener noreferrer" target="_blank">Raspberry Pi still hasn’t merged upstream Copy Fail fixes.</a> I’m already in trouble if this bug can be exploited but I did the temporary fix out of caution.</p><h3 id="proxmox-8-to-9">Proxmox 8 to 9</h3><p>I wasn’t going to bother with Proxmox 9 but after a GUI update I was informed version 8 “end of life” was <a href="https://pve.proxmox.com/wiki/FAQ#:~:text=2026%2D08-,2026%2D08,-Proxmox%20VE%207" rel="noopener noreferrer" target="_blank">August 2026</a>. That is soon! I followed the <a href="https://pve.proxmox.com/wiki/Upgrade_from_8_to_9" rel="noopener noreferrer" target="_blank">official upgrade guide</a> on my <a href="https://dbushell.com/2024/07/30/self-hosted-update-summer-2024/">Mini-ITX server</a>. Proxmox has a tool to check compatibility.</p><pre data-lang="sh" tabindex="0" id="pre-7e28a905"><code><span class="line"><span class="syntax-c01639ae">pve8to9</span><span class="space"> </span><span class="syntax-765b360f">--full</span></span></code></pre><p>I saw no red lights so I stopped all VMs, updated package sources to Trixie, and ran the upgrade. It is critical to run <code>pve8to9</code> again before rebooting. I ran into the <a href="https://pve.proxmox.com/wiki/Upgrade_from_8_to_9#Systemd-boot_meta-package_changes_the_bootloader_configuration_automatically_and_should_be_uninstalled" rel="noopener noreferrer" target="_blank">systemd-boot issue</a>. Apparently if this is not removed the system fails to boot. If my particular box fails to boot I’m in big trouble because I broke video output and have yet to fix it.</p><h3 id="the-worst-crime">The worst crime</h3><p>I have another Proxmox machine running <a href="https://dbushell.com/2026/01/14/self-hosted-update-winter-2026/#disaster">virtualised OPNsense</a> for my home router. I can’t stop the OPNsense VM and upgrade the host to Proxmox 9 because the host would have no network access. I had two options:</p><ol><li><a href="https://dbushell.com/2026/01/19/self-hosted-update-winter-2026/">Use my failover VM</a></li><li>YOLO it live</li></ol><p>I specifically set up option 1 for such a purpose. I went with option 2.</p><p>I figured any software running in memory is still alive until I reboot, right? I didn’t question whether Proxmox would kill any processes itself (it didn’t). The update was suspiciously fast. I ran <code>pve8to9</code> again and saw a lot of yellow warnings. Yikes. Eventually I noticed I’d failed to update some sources to Trixie and I’d installed a franken-distro.</p><p>After fixing mistakes all I could do was reboot and pray for an agonising two minutes.</p><pre data-lang="sh" tabindex="0" id="pre-4f39c921"><code><span class="line"><span class="syntax-c01639ae">Request</span><span class="space"> </span><span class="syntax-e661ac3e">timeout</span><span class="space"> </span><span class="syntax-e661ac3e">for</span><span class="space"> </span><span class="syntax-e661ac3e">icmp_seq</span><span class="space"> </span><span class="syntax-765b360f">107</span></span>
<span class="line"><span class="syntax-c01639ae">ping:</span><span class="space"> </span><span class="syntax-e661ac3e">sendto:</span><span class="space"> </span><span class="syntax-e661ac3e">Host</span><span class="space"> </span><span class="syntax-e661ac3e">is</span><span class="space"> </span><span class="syntax-e661ac3e">down</span></span>
<span class="line"><span class="syntax-c01639ae">Request</span><span class="space"> </span><span class="syntax-e661ac3e">timeout</span><span class="space"> </span><span class="syntax-e661ac3e">for</span><span class="space"> </span><span class="syntax-e661ac3e">icmp_seq</span><span class="space"> </span><span class="syntax-765b360f">108</span></span>
<span class="line"><span class="syntax-c01639ae">ping:</span><span class="space"> </span><span class="syntax-e661ac3e">sendto:</span><span class="space"> </span><span class="syntax-e661ac3e">Host</span><span class="space"> </span><span class="syntax-e661ac3e">is</span><span class="space"> </span><span class="syntax-e661ac3e">down</span></span>
<span class="line"><span class="syntax-c01639ae">Request</span><span class="space"> </span><span class="syntax-e661ac3e">timeout</span><span class="space"> </span><span class="syntax-e661ac3e">for</span><span class="space"> </span><span class="syntax-e661ac3e">icmp_seq</span><span class="space"> </span><span class="syntax-765b360f">109</span></span>
<span class="line"><span class="syntax-c01639ae">ping:</span><span class="space"> </span><span class="syntax-e661ac3e">sendto:</span><span class="space"> </span><span class="syntax-e661ac3e">Host</span><span class="space"> </span><span class="syntax-e661ac3e">is</span><span class="space"> </span><span class="syntax-e661ac3e">down</span></span>
<span class="line"><span class="syntax-c01639ae">64</span><span class="space"> </span><span class="syntax-e661ac3e">bytes</span><span class="space"> </span><span class="syntax-e661ac3e">from</span><span class="space"> </span><span class="syntax-e661ac3e">192.168.1.1:</span><span class="space"> </span><span class="syntax-e661ac3e">icmp_seq=</span><span class="syntax-765b360f">110</span><span class="space"> </span><span class="syntax-e661ac3e">ttl=</span><span class="syntax-765b360f">64</span><span class="space"> </span><span class="syntax-e661ac3e">time=</span><span class="syntax-765b360f">6.039</span><span class="space"> </span><span class="syntax-e661ac3e">ms</span></span>
<span class="line"><span class="syntax-c01639ae">64</span><span class="space"> </span><span class="syntax-e661ac3e">bytes</span><span class="space"> </span><span class="syntax-e661ac3e">from</span><span class="space"> </span><span class="syntax-e661ac3e">192.168.1.1:</span><span class="space"> </span><span class="syntax-e661ac3e">icmp_seq=</span><span class="syntax-765b360f">111</span><span class="space"> </span><span class="syntax-e661ac3e">ttl=</span><span class="syntax-765b360f">64</span><span class="space"> </span><span class="syntax-e661ac3e">time=</span><span class="syntax-765b360f">4.834</span><span class="space"> </span><span class="syntax-e661ac3e">ms</span></span></code></pre><figure class="Image"><img src="https://dbushell.com/images/blog/2026/relieved-robert-downey-jr.avif" alt="Robert Downey Jr. with eyes closed and hand over chest exhaling with great relief" width="500" height="490" decoding="async" fetchpriority="low" loading="lazy" id="--img-1683ac96"/></figure><h2 id="opnsense-upgrade">OPNsense upgrade</h2><p>OPNsense is the only non-Debian operating system in my homelab. I manage it entirely via the web GUI. The <a href="https://www.deciso.com/opnsense-26-1-witty-woodpecker-delivers-smarter-security-better-visibility-stronger-control/" rel="noopener noreferrer" target="_blank">26.1 update</a> had quite a few significant changes. My DHCP setup was considered “legacy” and my firewall rules required a manual migration.</p><p>Despite <a href="https://dbushell.com/2024/09/19/dumb-home/">dumbening my smart home</a> my lightbulbs still demand a WiFi connection. <a href="https://dbushell.com/2025/04/23/zig-smart-lights/">I program them myself</a> to avoid Home Assistant and proprietary apps. Turns out I hard-coded IP addresses (discovery protocols are a joke.) Despite having dynamic IPs they remained stable until the OPNsense 26.1 DHCP update.</p><p>I had no easy way to identify each light. Why would they name themselves anything useful? That’s how I ended up unscrewing the bulbs one by one to see which MAC address fell off the network. I gave them static IPs on a VLAN for future me to appreciate.</p><p>And with that, my home network is up to date!</p><hr/><p><strong>Edit:</strong> you know what maybe I should follow this advice: <a href="https://xeiaso.net/blog/2026/abstain-from-install/" rel="noopener noreferrer" target="_blank">“Maybe you shouldn’t install new software for a bit.”</a></p>
<hr>
<p>
Thanks for reading! Follow me on <a href="https://dbushell.com/mastodon/">Mastodon</a> and <a href="https://dbushell.com/bluesky/">Bluesky</a>.
Subscribe to my <a href="https://dbushell.com/rss.xml">Blog</a> and <a href="https://dbushell.com/notes/rss.xml">Notes</a> or <a href="https://dbushell.com/merge/rss.xml">Combined</a> feeds.
</p>
]]></content:encoded>
</item>
<item>
  <title>GitHub is sinking</title>
  <description>TL;DR: GitHub used to be cool and now it’s a lame slop graveyard. GitHub is racing towards the mythical zero nines of uptime. Users are starting to notice that GitHub is now a Microsoft product. Eww! Official uptime paints a concerning chart. The missing status page tell a far worse story. […]</description>
  <link>https://dbushell.com/2026/04/29/github-is-sinking/</link>
  <guid isPermaLink="true">https://dbushell.com/2026/04/29/github-is-sinking/</guid>
  <pubDate>Wed, 29 Apr 2026 15:00:00 GMT</pubDate>
  <content:encoded><![CDATA[<div class="Box"><p><strong>TL;DR:</strong> GitHub used to be cool and now it’s a lame slop graveyard.</p></div><p>GitHub is racing towards the mythical <a href="https://en.wikipedia.org/wiki/High_availability#Percentage_calculation" rel="noopener noreferrer" target="_blank">zero nines</a> of uptime. Users are starting to notice that GitHub is now a Microsoft product. <em>Eww!</em></p><p>Official uptime paints a concerning chart. The <a href="https://mrshu.github.io/github-statuses/" rel="noopener noreferrer" target="_blank">missing status page</a> tell a far worse story. Whatever the truth, it’s impossible to miss the <em>delightful</em> experience that is Microsoft GitHub if you use it semi-regularly.</p><figure class="Image"><img src="https://dbushell.com/images/blog/2026/github-microsoft-chart.avif" alt="Line chart showing GitHub average uptime by month following the Microsoft acquisition. A green line turns into an orange and red roller coaster." width="1266" height="727" decoding="async" fetchpriority="low" loading="lazy" id="--img-1772d480"/><figcaption><a href="https://damrnelson.github.io/github-historical-uptime/" rel="noopener noreferrer" target="_blank">GitHub’s Historic Uptime</a></figcaption></figure><p><a href="https://news.microsoft.com/announcement/microsoft-acquires-github/" rel="noopener noreferrer" target="_blank">Microsoft acquired GitHub</a> and applied their unique brand of enshittification. Amongst their achievements was the spawning of the <a href="https://teybannerman.com/strategy/2026/03/31/how-many-microsoft-copilot-are-there.html" rel="noopener noreferrer" target="_blank">Copilot circle of hell</a>. Now they’re effectively <a href="https://github.blog/news-insights/company-news/an-update-on-github-availability/" rel="noopener noreferrer" target="_blank">DDoSing themselves with slop</a>. I won’t dwell on what else went wrong. I don’t know and I don’t care. GitHub is impressively bad now. <a href="https://trunk.io/blog/what-happens-if-a-merge-queue-builds-on-the-wrong-commit" rel="noopener noreferrer" target="_blank">It’s embarrassing.</a> <a href="https://www.theregister.com/2026/03/26/github_ai_training_policy_changes/" rel="noopener noreferrer" target="_blank">Shameful.</a></p><p>As I write this the obituaries are flooding in:</p><ul><li><a href="https://lonami.dev/blog/ditching-github/" rel="noopener noreferrer" target="_blank">Ditching GitHub - Lonami</a></li><li><a href="https://mitchellh.com/writing/ghostty-leaving-github" rel="noopener noreferrer" target="_blank">Ghostty Is Leaving GitHub - Mitchell Hashimoto</a></li><li><a href="https://lucumr.pocoo.org/2026/4/28/before-github/" rel="noopener noreferrer" target="_blank">Before GitHub - Armin Ronacher</a></li><li><a href="https://www.jonashietala.se/blog/2026/04/28/from_github_to_codebergforgejo/" rel="noopener noreferrer" target="_blank">From GitHub to Codeberg/Forgejo - Jonas Hietala</a></li><li><a href="https://www.alexhyett.com/newsletter/github-is-dead-whats-next/" rel="noopener noreferrer" target="_blank">GitHub is dead, What’s next? - Alex Hyett</a></li><li><a href="https://jorijn.com/en/blog/leaving-github-for-forgejo/" rel="noopener noreferrer" target="_blank">Why I’m leaving GitHub for Forgejo - Jorijn Schrijvershof</a></li></ul><p><strong>It’s long past time to get off this sinking ship!</strong></p><h2 id="git-is-not-github">Git is not GitHub</h2><p>GitHub has become synonymous with “source control” and I worry too many users don’t know that Git is not GitHub. The core technology of Git is open source. It’s distributed, meaning that all repositories are equal. Git works without a centralised service. Such a practice is a construct of social convenience. GitHub was a useful add-on. Microsoft has turned GitHub into an expensive liability.</p><h3 id="but-network-effect">But network effect…</h3><p>Network effects are hard to topple but if anyone can do it, Microsoft can. GitHub’s <a href="https://awesomeagents.ai/news/github-fake-stars-investigation/" rel="noopener noreferrer" target="_blank">fake star economy</a> is worthless. GitHub is inundated with bots and <a href="https://www.theregister.com/2026/02/18/godot_maintainers_struggle_with_draining/" rel="noopener noreferrer" target="_blank">drowning in slop</a> and doing everything to encourage it. Microsoft is turning GitHub into the <a href="https://en.wikipedia.org/wiki/Moltbook" rel="noopener noreferrer" target="_blank">Moltbook</a> of code, it ain’t for you and me anymore.</p><h3 id="but-continuous-integration">But continuous integration…</h3><p>Your CI pipeline is over-engineered and GitHub Actions are an abomination (see: <a href="https://www.iankduncan.com/engineering/2026-02-05-github-actions-killing-your-team/" rel="noopener noreferrer" target="_blank">[1]</a> <a href="https://nesbitt.io/2026/04/28/github-actions-is-the-weakest-link.html" rel="noopener noreferrer" target="_blank">[2]</a>). Finding another solution is an absolute chore but do you trust GitHub to be reliable?</p><h3 id="but-more-excuses">But more excuses…</h3><p>Look, the ship is sinking! Sure, the water looks freezing. Don’t hang around and allow Microsoft to pull you under. You don’t need to move everything in one go. Start the process.</p><h2 id="alternatives">Alternatives</h2><p>The nearest lifeboat to escape GitHub is another centralised Git forge. Just sign up and push your repo to the new upstream. Some services can automate the migration and maybe even import issues. Personally I’d leave issues behind in a tragic boating accident.</p><div class="Alert"><p><strong>Edit:</strong> none of the options below are 100% rainbows and butterflies. They are <em>not GitHub</em>, that’s all I can vouch for. Do your own research etc.</p></div><p><a href="https://codeberg.org/" rel="noopener noreferrer" target="_blank">Codeberg</a> — a non-profit and community-led project with an established track record. This is the safe alternative that’ll stick around. It’s the flagship instance of <a href="https://forgejo.org/" rel="noopener noreferrer" target="_blank">Forgejo</a>.</p><p><a href="https://tangled.org/" rel="noopener noreferrer" target="_blank">Tangled</a> — an alpha stage start-up with interesting <a href="https://dbushell.com/2026/03/10/building-on-at-protocol/">AT protocol</a> integration. Worth considering for smaller solo projects.</p><p><a href="https://about.gitea.com/" rel="noopener noreferrer" target="_blank">Gitea</a> — they offer cloud managed Git hosting. It’s the original open source project that Codeberg/Forgejo forked away from.</p><p><a href="https://about.gitlab.com/" rel="noopener noreferrer" target="_blank">GitLab</a> — enterprise grade, meaning it’s bloated and confusing but it’ll impress your boss. This could be the choice if you need multiple meetings to make the choice. (<strong>Edit:</strong> oh dear, <a href="https://dbushell.com/notes/2026-05-12T05:14Z/">they’ve contracted the rot</a>)</p><p><a href="https://bitbucket.org/" rel="noopener noreferrer" target="_blank">Bitbucket</a> — trade one soul destroying corpo fun vacuum for another. Strongly discouraged, but Bitbucket does technically fit the <em>anything but GitHub</em> category.</p><p><strong>Edit:</strong> <a href="https://gothub.org/" rel="noopener noreferrer" target="_blank">Game of Trees</a>, <a href="https://radicle.dev/" rel="noopener noreferrer" target="_blank">Radicle</a>, and <a href="https://sr.ht/" rel="noopener noreferrer" target="_blank">Sourcehut</a> were suggested to me. I’ve no idea how they work, investigate yourself!</p><h2 id="self-hosted">Self-hosted</h2><p>If you’re <a href="https://dbushell.com/2025/08/11/github-ensloppification/">cool like me</a>, you or your organisation can self-host a Git forge with <a href="https://dbushell.com/2025/08/15/self-hosted-forgejo-actions-runner/">actions</a> and <a href="https://dbushell.com/2025/08/25/self-hosted-forgejo-actions-releases/">releases</a>. My recommendation is <glossary-term id="--term-forgejo"><a href="https://forgejo.org/" rel="noopener noreferrer" target="_blank">Forgejo</a></glossary-term>. There is <a href="https://codeberg.org/forgejo-contrib/federation" rel="noopener noreferrer" target="_blank">talk of federation</a> between Forgejo instances (<strong>edit:</strong> <a href="https://blog.tangled.org/federation/" rel="noopener noreferrer" target="_blank">and Tangled</a>) but it’s not happening anytime soon. If you want open collaboration push a copy to Codeberg. Gitea and GitLab also have self-hosted options. Be aware, GitLab is a comparative chonker.</p><p>When I said “Git is not GitHub” the same applies to other forges. Do you need those add-ons? Nothing is stopping you from raw-doggin’ Git over SSH:</p><pre data-lang="sh" tabindex="0" id="pre-ccac6525"><code><span class="line"><span class="syntax-c01639ae">git</span><span class="space"> </span><span class="syntax-e661ac3e">clone</span><span class="space"> </span><span class="syntax-e661ac3e">user@192.168.1.67:/path/to/repo</span></span></code></pre><p>How you manage collaboration is another question. If Linux can be maintained by sending patches to an email mailing list, <em>“doesn’t work at scale”</em> arguments are skill issues. But seriously, a centralised Git forge is a decent compromise in my opinion. Maybe they collapse like GitHub in future. Always have an exit plan.</p><p>Just use anything but GitHub.</p>
<hr>
<p>
Thanks for reading! Follow me on <a href="https://dbushell.com/mastodon/">Mastodon</a> and <a href="https://dbushell.com/bluesky/">Bluesky</a>.
Subscribe to my <a href="https://dbushell.com/rss.xml">Blog</a> and <a href="https://dbushell.com/notes/rss.xml">Notes</a> or <a href="https://dbushell.com/merge/rss.xml">Combined</a> feeds.
</p>
]]></content:encoded>
</item>
<item>
  <title>Alternative thoughts</title>
  <description>My regular schedule of CSS and HTML tips will return after this brief look at the sorry state of the web and tech industry. It’s grim. “Our press secretary, Sean Spicer, gave alternative facts to that… Alternative facts - Kellyanne Conway (Wikipedia)”Following the 2017 inauguration of Mr “grab ’em […]</description>
  <link>https://dbushell.com/2026/04/28/alternative-thoughts/</link>
  <guid isPermaLink="true">https://dbushell.com/2026/04/28/alternative-thoughts/</guid>
  <pubDate>Tue, 28 Apr 2026 15:00:00 GMT</pubDate>
  <content:encoded><![CDATA[<div class="Alert"><p>My regular schedule of CSS and HTML tips will return after this brief look at the sorry state of the web and tech industry. It’s grim.</p></div><blockquote><p>Our press secretary, Sean Spicer, gave alternative facts to that…</p><p><cite><a href="https://en.wikipedia.org/wiki/Alternative_facts" rel="noopener noreferrer" target="_blank">Alternative facts</a> - Kellyanne Conway (Wikipedia)</cite></p></blockquote><p>Following the 2017 inauguration of Mr <a href="https://www.vox.com/2016/10/7/13205842/trump-secret-recording-women" rel="noopener noreferrer" target="_blank">“grab ’em by the pussy”</a> the world was treated to a deluge of <em>alternative facts</em>. Few were prepared for the new era of <a href="https://xcancel.com/elonmusk/status/1872151527546409057" rel="noopener noreferrer" target="_blank">“you can just say things”</a>. The rule books were torn to shreds. Whilst liberals were angsting over decorum, the techno-fascists were rising up. When America decided for a second time that a pedo-in-chief was preferable to a woman, <a href="https://en.wikipedia.org/wiki/Elon_Musk_salute_controversy" rel="noopener noreferrer" target="_blank">all pretence fell away</a>.</p><p>The AI industrial complex is the culmination of tech, money, and power that the Musk’s and Thiel’s of the world were waiting for. For a monthly subscription users can disengage their brain and choose <em>alternative thoughts</em> to escape a dystopia they voted for.</p><p>The endgame of techno-facism is more money, more power; a <a href="https://dbushell.com/2026/04/01/i-quit-the-clankers-won/#pay-to-play">price tag on humanity</a>.</p><h2 id="its-just-a-tool">It’s just a tool</h2><p>At this point, those who work in tech and refuse to acknowledge <a href="https://dbushell.com/ai/#morals-and-ethics">the harm</a> and <a href="https://tante.cc/2026/04/21/ai-as-a-fascist-artifact/" rel="noopener noreferrer" target="_blank">the violence</a> are hopelessly naive and/or complicit in their selfishness.</p><blockquote><p>Violence is more than just hitting people. Taking away people’s agency is violence, exposing people to suffering is violence. Violence has many shapes and forms. And “AI” needs an acceptance of endless amounts of violence</p><p><cite><a href="https://tante.cc/2026/04/21/ai-as-a-fascist-artifact/" rel="noopener noreferrer" target="_blank">AI as a Fascist Artifact</a> - Jürgen Geuter</cite></p></blockquote><p>I can understand why someone doomscrolling slop-tok shorts might not pause to consider the effect of their implicit acceptance. But the “it’s just a tool” crowd in the tech industry — well, is it wilful ignorance or feeble apologism?</p><p>Why is it that those most embedded in tech are most eager to push the AI narrative? Hint: they’re almost all looking to get in on the grift. Sell shovels. Sell guides on how to shovel. Sell B2B automated shovelling logistics. All the while enriching the pockets of the techno-facists looking to control those hooked on tokens. It’s quite a tool. A tool that has the tech industry clapping like sea lions and giddily proclaiming <a href="https://en.wikipedia.org/wiki/Chain_of_Command_%28Star_Trek:_The_Next_Generation%29#Part_II:~:text=five%20lights" rel="noopener noreferrer" target="_blank">there are five lights</a>.</p><p><small>Apparently the public at large <a href="https://www.theverge.com/podcast/917029/software-brain-ai-backlash-databases-automation" rel="noopener noreferrer" target="_blank">don’t yearn for automation</a>. Let’s hope those across the pond can connect the red flags before we get Vance/Kirk 2028.</small></p><h2 id="its-just-a-job">It’s just a job</h2><p>Software “engineers” have been more than happy to pull the <a href="https://dbushell.com/#bandit">one-armed code bandit</a> and recite the 10× productivity mantra. What incentive do they have to care when they’re strongly encouraged to gamble on their employer’s dime.</p><p><em>More. Faster. Burn those tokens! Stop thinking, your context is getting cold!</em></p><p>They get subsidised rates and front row seats to the looming collapse. Collapse it assuredly will. <a href="https://www.theverge.com/ai-artificial-intelligence/917380/ai-monetization-anthropic-openai-token-economics-revenue" rel="noopener noreferrer" target="_blank">The wheels</a> are <a href="https://github.blog/news-insights/company-news/github-copilot-is-moving-to-usage-based-billing/" rel="noopener noreferrer" target="_blank">falling off</a>. Are the thrills of addiction waning, too? Anecdotally, I’ve seen an increase in developers becoming bored with their new toys.</p><p>When the bubble bursts it will be too late for many. The AI mandate has been busy destroying the careers and opportunities of those who still care.</p><p>Craig Cook said “fuck AI” and quit.</p><blockquote><p>The fantasy of AI efficiency has rapidly devoured the brains of every Silicon Valley MBA prick like a body-snatcher invasion. Predator-class oligarchs are positively horny to replace their annoying human workforces with a compliant, manufactured slave race that doesn’t demand a living wage and won’t whine about their “health” and “dignity” and “fundamental rights.”</p><p><cite><a href="https://www.focalcurve.com/journal/the-end/" rel="noopener noreferrer" target="_blank">The End</a> - Craig Cook</cite></p></blockquote><p>Ky Decker quit too, questioning whether they belong in tech anymore.</p><blockquote><p>Tech organizations have now given up on pushing back against an unethical and violent administration, deciding that it is in their best business interest to flatter the president’s ego with gold trophies and pandering praise. Elon Musk and the “Department of Government Efficiency” took a sledgehammer to 18F and replaced it with National Design Studio, a propaganda shop whose main talent is building expensive and inaccessible landing pages.</p><p><cite><a href="https://ky.fyi/posts/ai-burnout" rel="noopener noreferrer" target="_blank">Do I belong in tech anymore?</a> - Ky Decker</cite></p></blockquote><p>These are just two stories from those brave enough to speak out.</p><p>The usual <em>“you’re prompting it wrong”</em> commenters on <a href="https://news.ycombinator.com/item?id=47895380" rel="noopener noreferrer" target="_blank">Hacker News</a> and <a href="https://lobste.rs/s/xgtyyu/do_i_belong_tech_anymore" rel="noopener noreferrer" target="_blank">Lobste.rs</a> were atypically sympathetic to Ky’s plight. Perhaps reality is sinking in? Or the reply-bots were offline. That’s a good sign I guess. Nevertheless, the ostracising and harassment towards a “no thanks” stance on AI and techno-facism remains a real problem (source: my inbox).</p><p>I don’t care about the anonymous cowards that think I’ll read one thousand words of LLM-extruded abuse after they gave the game away in the subject line. They exist, but I’m talking about the private conversations I’ve had with those suffering the burnout alone. They are trapped in jobs. They’re forced to bear the <em>alternative thoughts</em> proxied via the mouth holes of their managers. They are afraid to speak up.</p><h2 id="its-just-a-life">It’s just a life</h2><p>It takes some combination of financial privilege, mental exhaustion, or foolhardiness to quit a job when the market is so bleak. I respect those that do but I don’t blame anyone for bunkering down. <a href="https://bell.bz/wait-it-out/" rel="noopener noreferrer" target="_blank">Wait it out</a> is practical advice but it doesn’t ease the anxiety. “Preserve your mental health” is key but what that means is different for each of us.</p><blockquote><p>And throughout all of this, I felt such an energetic sense of purpose and activation in creating new music for the first time in over a decade that I also felt I had rediscovered my true self.</p><p><cite><a href="https://whitep4nth3r.com/blog/new-electronica-music-manchester-uk/" rel="noopener noreferrer" target="_blank">I released a song for the first time in 15 years</a> - Salma Alam-Naylor</cite></p></blockquote><p>Salma Alam-Naylor released a certified banger: <a href="https://chromasetica.com/" rel="noopener noreferrer" target="_blank">reject the machine</a>. Salma created this music to fight against an <a href="https://whitep4nth3r.com/blog/i-am-in-an-abusive-relationship-with-the-technology-industry/" rel="noopener noreferrer" target="_blank">abusive relationship with the technology industry.</a></p><p>I see this passion project as a middle finger to the <a href="https://newsocialist.org.uk/transmissions/ai-the-new-aesthetics-of-fascism/" rel="noopener noreferrer" target="_blank">aesthetics of fascism</a>. To me it’s a reminder that by rejecting the <em>alternative thoughts</em> peddled by techno-facists we deny what they really want: control. I’ve been inspired to continue pursuing <a href="https://dbushell.com/notes/2026-04-24T16:32Z/">my own creativity</a>. Will that bear fruit? It doesn’t matter. It’s my life and I will remain in control.</p>
<hr>
<p>
Thanks for reading! Follow me on <a href="https://dbushell.com/mastodon/">Mastodon</a> and <a href="https://dbushell.com/bluesky/">Bluesky</a>.
Subscribe to my <a href="https://dbushell.com/rss.xml">Blog</a> and <a href="https://dbushell.com/notes/rss.xml">Notes</a> or <a href="https://dbushell.com/merge/rss.xml">Combined</a> feeds.
</p>
]]></content:encoded>
</item>
<item>
  <title>RSS Club #007: Running</title>
  <description>Today Sabastian Sawe ran an historic sub-two-hour marathon in a competitive race. A marathon is around 42 kilometres, aka 26 miles in freedom units (we use miles in the UK too but not for running distances). I feel the record is a little unfair on Kipchoge who achieved the milestone first under […]</description>
  <link>https://dbushell.com/2026/04/26/RSS007/</link>
  <guid isPermaLink="true">https://dbushell.com/2026/04/26/RSS007/</guid>
  <pubDate>Sun, 26 Apr 2026 15:00:00 GMT</pubDate>
  <content:encoded><![CDATA[<p>Today <a href="https://www.bbc.co.uk/sport/athletics/articles/crm1m7e0zwzo" rel="noopener noreferrer" target="_blank">Sabastian Sawe</a> ran an historic sub-two-hour marathon in a competitive race.</p><p>A marathon is around 42 kilometres, aka 26 miles in freedom units (we use miles in the UK too but not for running distances). I feel the record is a little unfair on <strong>Kipchoge</strong> who <a href="https://en.wikipedia.org/wiki/Ineos_1:59_Challenge" rel="noopener noreferrer" target="_blank">achieved the milestone</a> first under non-competitive conditions. Even more unfair on <strong>Kejelcha</strong> who finishing second today in 1:59:41. Two unbelievable athletes in the same day.</p><p>If my maths is correct that’s not far off a 14 min 5km pace. That’s simply outrageous!</p><p>My personal best for a 5km is 22 mins. With the caveat of questionable GPS cutting a park corner. My fastest half-marathon is 1:51:42. Basically half as slow as an elite marathon runner. Of course, they run half-marathons even faster. I do not believe my knees could withstand double that distance. Anyone who can drag their body 42km deserves applause.</p><p>I doubt I could even <em>sprint</em> 100 metres as fast as these guys maintain a marathon pace. More napkin maths suggest that is 100 metres in around 16 seconds? Usain Bolt did it once in 9.58s. Maintaining a pace of 16s/100m for 42,000 metres in incredible.</p><p>If the maths ain’t exciting you see this video of <a href="https://www.youtube.com/watch?v=SRYtn0j5ccA" rel="noopener noreferrer" target="_blank">runners attempting to match Kipchoge’s pace</a>.</p><p>Elite sprinting in <em>anaerobic</em>. Long distance running is <em>aerobic</em> (aka “cardio”). I wont feign expertise on the exact science. All I know is the 200 metre sprint is notoriously difficult. It pushes the human body beyond what it can maintain for anaerobic sprinting. You gotta just start sucking in oxygen and try to ignore the fact that it feels like you’re dying.</p><p>When it comes to superiority over other animals, top of the list is our brain and our dexterity. But more impressive I think is our <strong>endurance</strong>. Our ancestors started walking upright and evolved as <a href="https://en.wikipedia.org/wiki/Persistence_hunting" rel="noopener noreferrer" target="_blank">persistence hunters</a>. Prey cramps up and physically cannot move to save its life. Brutal way to go!</p><p>Long-distance running is more about breathing, a steady pace, and good form to avoid injury. The perfect running shoe is less important than people want to think. A good fit matters. <em>Pheidippides</em> didn’t run the first marathon in Nikes (fashion sneakers fall apart instantly). He probably wore sandals or was barefoot.</p><p>The most important attire is short shorts, underwear of synthetic material to keep your bits in place, and plenty of lube on the thighs. Never wear a cotton T-shirt unless you want bloody nipples. Chafing is like the boiling frog parable. You don’t realise until it’s too late and you’re walking like a cowboy for a week.</p><p>Unless you’re running competitively, never compare yourself to others. It does not help you in the slightest. There is no “good” time to run any particular distance.</p>
<hr>
<p>
Thanks for reading! Follow me on <a href="https://dbushell.com/mastodon/">Mastodon</a> and <a href="https://dbushell.com/bluesky/">Bluesky</a>.
Subscribe to my <a href="https://dbushell.com/rss.xml">Blog</a> and <a href="https://dbushell.com/notes/rss.xml">Notes</a> or <a href="https://dbushell.com/merge/rss.xml">Combined</a> feeds.
</p>
]]></content:encoded>
</item>
<item>
  <title>Web tools are cool</title>
  <description>My website has a new page! The /uses URL pathname is an “official” slash page. I’m only listing web tools I use for now. My default apps change too frequently. The list is an evolution of an old post I was secretly maintaining. 👉 Visit my /uses page! […]</description>
  <link>https://dbushell.com/2026/04/21/web-tools/</link>
  <guid isPermaLink="true">https://dbushell.com/2026/04/21/web-tools/</guid>
  <pubDate>Tue, 21 Apr 2026 15:00:00 GMT</pubDate>
  <content:encoded><![CDATA[<p>My website has a <a href="https://dbushell.com/uses/">new page!</a> The <code>/uses</code> URL pathname is an “official” <a href="https://slashpages.net/" rel="noopener noreferrer" target="_blank">slash page</a>. I’m only listing web tools I use for now. My <a href="https://dbushell.com/2026/01/08/app-defaults/">default apps</a> change too frequently. The list is an evolution of an <a href="https://dbushell.com/2024/11/25/links-initiative/">old post</a> I was secretly maintaining.</p><div class="Box"><p>👉 <a href="https://dbushell.com/uses/">Visit my /uses page!</a></p></div><h2 id="web-tools">Web tools</h2><p>Web tools are web-based tools, obviously. Used in a web browser without a download. Some may be installed as <glossary-term id="--term-pwa"><a href="https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps/Guides/What_is_a_progressive_web_app" rel="noopener noreferrer" target="_blank">progressive web apps</a></glossary-term> but I prefer a <em>progressive browser tabs</em>. Most tools do <strong>one thing</strong> and do it well. Some of my links are actually just text information, but <em>“web tools and documentation and specifications”</em> is a mouthful.</p><p>All the tools I’m collating are related to web development. I’d guess I use <a href="https://squoosh.app/" rel="noopener noreferrer" target="_blank">Squoosh</a> the most, followed by <a href="https://caniuse.com/" rel="noopener noreferrer" target="_blank">Can I use</a> or this <a href="https://specificity.keegan.st/" rel="noopener noreferrer" target="_blank">specificity calculator</a> (there are many, I like that one.) Stu Robson’s <a href="https://www.alwaystwisted.com/relicss/" rel="noopener noreferrer" target="_blank">ReliCSS</a> is a new addition that looks very useful.</p><p>I realise now I’m not hosting any web tools myself. Many moons ago I maintained a few NPM packages that did stuff (<a href="https://gruntjs.com/" rel="noopener noreferrer" target="_blank">grunted</a>, mostly). Web tools are so much better. Less malware, for one. I once hosted a <a href="https://dbushell.com/2020/03/05/bundle-a-pwa-as-an-android-app/">to-do app</a>, but who hasn’t? That reminds me, sub-domains are the secret to hosting side projects. I must stop buying short-lived project domains.</p><p>Anyway, I should build a <a href="https://dbushell.com/uses/#web-tools">web tool</a>. Any ideas?</p><p>Do you have any favourite web tools I should be aware of? I’m not looking to list everything, just stuff I might personally use.</p><p><small>P.S. This is definitely not another bookmarks project I’ll forget about.</small></p>
<hr>
<p>
Thanks for reading! Follow me on <a href="https://dbushell.com/mastodon/">Mastodon</a> and <a href="https://dbushell.com/bluesky/">Bluesky</a>.
Subscribe to my <a href="https://dbushell.com/rss.xml">Blog</a> and <a href="https://dbushell.com/notes/rss.xml">Notes</a> or <a href="https://dbushell.com/merge/rss.xml">Combined</a> feeds.
</p>
]]></content:encoded>
</item>
<item>
  <title>Warning: containment breach in cascade layer!</title>
  <description>CSS cascade layers are the ultimate tool to win the specificity wars. Used alongside the :where selector, specificity problems are a thing of the past. Or so I thought. Turns out cascade layers are leakier than a xenonite sieve. Cross-layer shenanigans can make bad CSS even badder. […]</description>
  <link>https://dbushell.com/2026/04/15/containment-breach-in-cascade-layer/</link>
  <guid isPermaLink="true">https://dbushell.com/2026/04/15/containment-breach-in-cascade-layer/</guid>
  <pubDate>Wed, 15 Apr 2026 15:00:00 GMT</pubDate>
  <content:encoded><![CDATA[<p><a href="https://css-tricks.com/css-cascade-layers/" rel="noopener noreferrer" target="_blank">CSS cascade layers</a> are the ultimate tool to win the specificity wars. Used alongside the <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Selectors/:where" rel="noopener noreferrer" target="_blank"><code>:where</code></a> selector, specificity problems are a thing of the past.</p><p>Or so I thought. Turns out cascade layers are leakier than a xenonite sieve. Cross-layer shenanigans can make bad CSS even badder. I discovered a whole new level of specificity hell. Scroll down if you dare! There are advantages too, I’ll start with a neat trick.</p><h2 id="neat-trick">Neat trick</h2><p>To setup this trick I’ll quickly cover my favoured CSS methodology for a small website. I find defining three cascade layers is plenty.</p><figure><pre data-lang="css" tabindex="0" id="pre-47925b80"><code><span class="line"><span class="syntax-1656d967">@layer</span><span class="space"> </span><span class="syntax-26f6a8db">base,</span><span class="space"> </span><span class="syntax-26f6a8db">components,</span><span class="space"> </span><span class="syntax-26f6a8db">utility;</span></span></code></pre><figcaption>It’s important to name layers such that maximum bikeshedding is achieved.</figcaption></figure><p>In <code>base</code> I add <a href="https://dbushell.com/2025/09/12/css-reset/">my reset styles</a>, custom properties, anything that touches a global element, etc. In <code>components</code> I add the core of the website. In <code>utility</code> I add classes that look suspiciously like <em>Tailwind</em>, for pragmatic use. <a href="https://dbushell.com/2026/02/20/visually-hidden/">Visually-hidden</a> is a utility class in my system.</p><h3 id="figma-betrayel">Figma betrayel</h3><p>I recently built a design where many headings and UI elements used an alternate font with a unique style. It made practical sense to use a utility class like the one below.</p><figure><pre data-lang="css" tabindex="0" id="pre-7da519dc"><code><span class="line"><span class="syntax-1656d967">@layer</span><span class="space"> </span><span class="syntax-26f6a8db">utility</span><span class="space"> </span><span class="syntax-26f6a8db">{</span></span>
<span class="line"><span class="space"> </span><span class="space"> </span><span class="syntax-4ddd3d58">.font-brand</span><span class="space"> </span><span class="syntax-26f6a8db">{</span></span>
<span class="line"><span class="space"> </span><span class="space"> </span><span class="space"> </span><span class="space"> </span><span class="syntax-3eeadcf9">font-family</span><span class="syntax-1656d967">:</span><span class="space"> </span><span class="syntax-6168685d">"</span><span class="syntax-e661ac3e">Garish</span><span class="space"> </span><span class="syntax-e661ac3e">Sans</span><span class="syntax-6168685d">"</span><span class="syntax-26f6a8db">;</span></span>
<span class="line"><span class="space"> </span><span class="space"> </span><span class="space"> </span><span class="space"> </span><span class="syntax-3eeadcf9">letter-spacing</span><span class="syntax-1656d967">:</span><span class="space"> </span><span class="syntax-765b360f">20</span><span class="syntax-1656d967">%</span><span class="syntax-26f6a8db">;</span></span>
<span class="line"><span class="space"> </span><span class="space"> </span><span class="space"> </span><span class="space"> </span><span class="syntax-3eeadcf9">text-transform</span><span class="syntax-1656d967">:</span><span class="space"> </span><span class="syntax-765b360f">uppercase</span><span class="syntax-26f6a8db">;</span></span>
<span class="line"><span class="space"> </span><span class="space"> </span><span class="syntax-26f6a8db">}</span></span>
<span class="line"><span class="syntax-26f6a8db">}</span></span></code></pre><figcaption>I don’t wrap every class in <code>@layer</code> I’m just doing that here for clarity.</figcaption></figure><p>This is but a tribute, the real class had more properties. The class is <a href="https://en.wikipedia.org/wiki/Don%27t_repeat_yourself" rel="noopener noreferrer" target="_blank">DRY</a> and easily integrated into templates and content editors.</p><p>Adding this to the highest cascade layer makes sense. I don’t have to worry about juggling source order or overriding properties on the class itself. I especially do not have to care about specificity or slap <code>!important</code> everywhere like a fool.</p><p>This worked well. Then I zoom further into the Figma picture and was <a href="https://dbushell.com/2026/03/23/top-ten-figma-betrayls/">betrayed!</a></p><h3 id="escape-hatch">Escape hatch</h3><p>The design had an edge case where letter-spacing varied for one specific component. It made sense for the design. It did not make sense for my system.</p><p>If you remember, my <code>utility</code> cascade layer takes priority over my <code>components</code> layer so I can’t simply apply a unique style to the component.</p><pre data-lang="css" tabindex="0" id="pre-47925b80"><code><span class="line"><span class="syntax-1656d967">@layer</span><span class="space"> </span><span class="syntax-26f6a8db">base,</span><span class="space"> </span><span class="syntax-26f6a8db">components,</span><span class="space"> </span><span class="syntax-26f6a8db">utility;</span></span></code></pre><p>For the sake of a demo let’s assume my component has this markup.</p><pre data-lang="html" tabindex="0" id="pre-ff4afafb"><code><span class="line"><span class="syntax-26f6a8db">&#x3C;</span><span class="syntax-1656d967">div</span><span class="space"> </span><span class="syntax-4ddd3d58">class</span><span class="syntax-1656d967">=</span><span class="syntax-6168685d">"</span><span class="syntax-e661ac3e">Component</span><span class="syntax-6168685d">"</span><span class="syntax-26f6a8db">></span></span>
<span class="line"><span class="space"> </span><span class="space"> </span><span class="syntax-26f6a8db">&#x3C;</span><span class="syntax-1656d967">h2</span><span class="space"> </span><span class="syntax-4ddd3d58">class</span><span class="syntax-1656d967">=</span><span class="syntax-6168685d">"</span><span class="syntax-e661ac3e">font-brand</span><span class="syntax-6168685d">"</span><span class="syntax-26f6a8db">>Heading</span><span class="space"> </span><span class="syntax-26f6a8db">whatever&#x3C;/</span><span class="syntax-1656d967">h2</span><span class="syntax-26f6a8db">></span></span>
<span class="line"><span class="syntax-26f6a8db">&#x3C;/</span><span class="syntax-1656d967">div</span><span class="syntax-26f6a8db">></span></span></code></pre><p>I want to change back to the normal letter-spacing.</p><pre data-lang="css" tabindex="0" id="pre-bd795def"><code><span class="line"><span class="syntax-1656d967">@layer</span><span class="space"> </span><span class="syntax-26f6a8db">components</span><span class="space"> </span><span class="syntax-26f6a8db">{</span></span>
<span class="line"><span class="space"> </span><span class="space"> </span><span class="syntax-4ddd3d58">.Component</span><span class="space"> </span><span class="syntax-1656d967">h2</span><span class="space"> </span><span class="syntax-26f6a8db">{</span></span>
<span class="line"><span class="space"> </span><span class="space"> </span><span class="space"> </span><span class="space"> </span><span class="syntax-3eeadcf9">letter-spacing</span><span class="syntax-1656d967">:</span><span class="space"> </span><span class="syntax-765b360f">normal</span><span class="syntax-26f6a8db">;</span></span>
<span class="line"><span class="space"> </span><span class="space"> </span><span class="syntax-26f6a8db">}</span></span>
<span class="line"><span class="syntax-26f6a8db">}</span></span></code></pre><p>Oops, I’ve lost the specificity war regardless of what selector I use. The <code>font-brand</code> utility class wins because I set it up to win.</p><p>My “escape hatch” uses <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Guides/Cascading_variables/Using_custom_properties#custom_property_fallback_values" rel="noopener noreferrer" target="_blank">custom property fallback values</a>.</p><pre data-lang="css" tabindex="0" id="pre-0e763266"><code><span class="line"><span class="syntax-1656d967">@layer</span><span class="space"> </span><span class="syntax-26f6a8db">utility</span><span class="space"> </span><span class="syntax-26f6a8db">{</span></span>
<span class="line"><span class="space"> </span><span class="space"> </span><span class="syntax-4ddd3d58">.font-brand</span><span class="space"> </span><span class="syntax-26f6a8db">{</span></span>
<span class="line"><span class="space"> </span><span class="space"> </span><span class="space"> </span><span class="space"> </span><span class="syntax-3eeadcf9">font-family</span><span class="syntax-1656d967">:</span><span class="space"> </span><span class="syntax-6168685d">"</span><span class="syntax-e661ac3e">Garish</span><span class="space"> </span><span class="syntax-e661ac3e">Sans</span><span class="syntax-6168685d">"</span><span class="syntax-26f6a8db">;</span></span>
<span class="line"><span class="space"> </span><span class="space"> </span><span class="space"> </span><span class="space"> </span><span class="syntax-3eeadcf9">letter-spacing</span><span class="syntax-1656d967">:</span><span class="space"> </span><span class="syntax-3eeadcf9">var</span><span class="syntax-26f6a8db">(--letter-spacing,</span><span class="space"> </span><span class="syntax-765b360f">20</span><span class="syntax-1656d967">%</span><span class="syntax-26f6a8db">);</span></span>
<span class="line"><span class="space"> </span><span class="space"> </span><span class="space"> </span><span class="space"> </span><span class="syntax-3eeadcf9">text-transform</span><span class="syntax-1656d967">:</span><span class="space"> </span><span class="syntax-765b360f">uppercase</span><span class="syntax-26f6a8db">;</span></span>
<span class="line"><span class="space"> </span><span class="space"> </span><span class="syntax-26f6a8db">}</span></span>
<span class="line"><span class="syntax-26f6a8db">}</span></span></code></pre><p>In most cases <code>--letter-spacing</code> is not defined and the default <code>20%</code> is applied.</p><p>For my edge case component I can ‘configure’ the utility class.</p><pre data-lang="css" tabindex="0" id="pre-dcbb5c77"><code><span class="line"><span class="syntax-1656d967">@layer</span><span class="space"> </span><span class="syntax-26f6a8db">components</span><span class="space"> </span><span class="syntax-26f6a8db">{</span></span>
<span class="line"><span class="space"> </span><span class="space"> </span><span class="syntax-4ddd3d58">.Component</span><span class="space"> </span><span class="syntax-26f6a8db">{</span></span>
<span class="line"><span class="space"> </span><span class="space"> </span><span class="space"> </span><span class="space"> </span><span class="syntax-26f6a8db">--letter-spacing</span><span class="syntax-1656d967">:</span><span class="space"> </span><span class="syntax-765b360f">normal</span><span class="syntax-26f6a8db">;</span></span>
<span class="line"><span class="space"> </span><span class="space"> </span><span class="syntax-26f6a8db">}</span></span>
<span class="line"><span class="syntax-26f6a8db">}</span></span></code></pre><p>I’ve found this to be an effective solution that feels logical and intuitive. I’m working with the cascade. It’s a good thing that custom properties are not locked within cascade layers! I don’t think anyone would expect that to happen.</p><h2 id="important-breach">Important breach</h2><p>In drafting this post I was going to use an example to show the power of cascade layers.</p><figure><pre data-lang="css" tabindex="0" id="pre-1849c08e"><code><span class="line"><span class="syntax-1656d967">@layer</span><span class="space"> </span><span class="syntax-26f6a8db">components</span><span class="space"> </span><span class="syntax-26f6a8db">{</span></span>
<span class="line"><span class="space"> </span><span class="space"> </span><span class="syntax-4ddd3d58">.Component</span><span class="space"> </span><span class="syntax-1656d967">h2</span><span class="space"> </span><span class="syntax-26f6a8db">{</span></span>
<span class="line"><span class="space"> </span><span class="space"> </span><span class="space"> </span><span class="space"> </span><span class="syntax-3eeadcf9">letter-spacing</span><span class="syntax-1656d967">:</span><span class="space"> </span><span class="syntax-765b360f">normal</span><span class="space"> </span><span class="syntax-1656d967">!important</span><span class="syntax-26f6a8db">;</span></span>
<span class="line"><span class="space"> </span><span class="space"> </span><span class="syntax-26f6a8db">}</span></span>
<span class="line"><span class="syntax-26f6a8db">}</span></span></code></pre><figcaption>This code didn’t fail as exepected.</figcaption></figure><p>I was going to say that not even <code>!important</code> wins. Then I tested my example and found that <code>!important</code> does actually override higher cascade layers. It breaches containment too!</p><p>What colour are the paragraphs?</p><pre data-lang="css" tabindex="0" id="pre-03d9b442"><code><span class="line"><span class="syntax-1656d967">@layer</span><span class="space"> </span><span class="syntax-26f6a8db">one,</span><span class="space"> </span><span class="syntax-26f6a8db">two,</span><span class="space"> </span><span class="syntax-26f6a8db">three;</span></span>
<span class="line"></span>
<span class="line"><span class="syntax-1656d967">@layer</span><span class="space"> </span><span class="syntax-26f6a8db">one</span><span class="space"> </span><span class="syntax-26f6a8db">{</span></span>
<span class="line"><span class="space"> </span><span class="space"> </span><span class="syntax-1656d967">p</span><span class="space"> </span><span class="syntax-26f6a8db">{</span><span class="space"> </span><span class="syntax-3eeadcf9">color</span><span class="syntax-1656d967">:</span><span class="space"> </span><span class="syntax-765b360f">blue</span><span class="space"> </span><span class="syntax-1656d967">!important</span><span class="syntax-26f6a8db">;</span><span class="space"> </span><span class="syntax-26f6a8db">}</span></span>
<span class="line"><span class="syntax-26f6a8db">}</span></span>
<span class="line"></span>
<span class="line"><span class="syntax-1656d967">@layer</span><span class="space"> </span><span class="syntax-26f6a8db">two</span><span class="space"> </span><span class="syntax-26f6a8db">{</span></span>
<span class="line"><span class="space"> </span><span class="space"> </span><span class="syntax-1656d967">p</span><span class="space"> </span><span class="syntax-26f6a8db">{</span><span class="space"> </span><span class="syntax-3eeadcf9">color</span><span class="syntax-1656d967">:</span><span class="space"> </span><span class="syntax-765b360f">white</span><span class="space"> </span><span class="syntax-1656d967">!important</span><span class="syntax-26f6a8db">;</span><span class="space"> </span><span class="syntax-26f6a8db">}</span></span>
<span class="line"><span class="syntax-26f6a8db">}</span></span>
<span class="line"></span>
<span class="line"><span class="syntax-1656d967">@layer</span><span class="space"> </span><span class="syntax-26f6a8db">three</span><span class="space"> </span><span class="syntax-26f6a8db">{</span></span>
<span class="line"><span class="space"> </span><span class="space"> </span><span class="syntax-1656d967">p</span><span class="space"> </span><span class="syntax-26f6a8db">{</span><span class="space"> </span><span class="syntax-3eeadcf9">color</span><span class="syntax-1656d967">:</span><span class="space"> </span><span class="syntax-765b360f">black</span><span class="syntax-26f6a8db">;</span><span class="space"> </span><span class="syntax-26f6a8db">}</span></span>
<span class="line"><span class="syntax-26f6a8db">}</span></span></code></pre><p>Suffice it to say that things get very weird. <a href="https://codepen.io/editor/dbushell/pen/019d76b2-dcc6-7244-a269-d8308838179e" rel="noopener noreferrer" target="_blank">See my CodePen</a>.</p><p>Spoiler: blue wins.</p><p>I’m sure there is a perfectly cromulent reason for this behaviour but on face value I don’t like it! Bleh! I feel like <code>!important</code> should be locked within a cascade layer. I don’t even want to talk about <a href="https://developer.chrome.com/blog/cascade-layers#:~:text=If%20you%20have%20multiple%20layers%2C%20the%20first%20layer" rel="noopener noreferrer" target="_blank">the inversion…</a></p><p>I’m sure there are GitHub issues, IRC logs, and cave wall paintings that discuss how cascade layers should handle <code>!important</code> — they got it wrong! The fools! We could have had something good here! Okay, maybe I’m being dramatic. I’m missing the big picture, is there a real reason it has to work this way? It just feels… wrong? I’ve never seen a use case for <code>!important</code> that wasn’t tear-inducing technical debt.</p><p>Permeating layers with <code>!important</code> feels wrong even though custom properties behaving similar feels right. It’s hard to explain. I reckon if you’ve built enough websites you’ll get that sense too? Or am I just talking nonsense?</p><hr/><p>I subscribe to the dogma that says <code>!important</code> should never be used but <strong>it’s not always my choice</strong>. I build a lot of bespoke themes. The WordPress + plugin ecosystem is the ultimate specificity war. WordPress core laughs in the face of “CSS methodology” and loves to put <a href="https://dbushell.com/2024/05/07/modern-wordpress-themes-yikes/#stylin">styles where they don’t belong</a>. Plugin authors are forced to write even gnarlier selectors. When I finally get to play, styles are an unmitigated disaster.</p><p>Cascade layers can <a href="https://dbushell.com/notes/2026-04-01T13:51Z/">curtail unruly WordPress plugins</a> but if they use <code>!important</code> it’s game over; I’m back to writing even worse code.</p><div class="Box"><p class="cursive">Update for 16 Apr 2026</p><p>Thinking about this more, it makes sense from the perspective of <a href="https://css-tricks.com/css-cascade-layers/#:~:text=But%20the%20creators%20of%20CSS%20were%20very%20clear" rel="noopener noreferrer" target="_blank">giving users the final word</a>, and browsers having a spec-defined way to achieve that.</p><p>Practically though, for developers, even when everyone is on the same team a single <code>!important</code> can ruin the party. In scenarios like WordPress these problems manifest as more than just gnarly selectors. Bad and unmaintainable CSS snowballs into bugs and broken dreams.</p><p>In short, it might make sense in theory but in practice the evidence suggests otherwise. I remain unconvinced it needed to be this way.</p></div>
<hr>
<p>
Thanks for reading! Follow me on <a href="https://dbushell.com/mastodon/">Mastodon</a> and <a href="https://dbushell.com/bluesky/">Bluesky</a>.
Subscribe to my <a href="https://dbushell.com/rss.xml">Blog</a> and <a href="https://dbushell.com/notes/rss.xml">Notes</a> or <a href="https://dbushell.com/merge/rss.xml">Combined</a> feeds.
</p>
]]></content:encoded>
</item>
</channel>
</rss>
