<?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 (blog)</title>
    <description>David Bushell’s Blog only feed</description>
    <link>https://dbushell.com/blog/</link>
    <lastBuildDate>Fri, 10 Jul 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>Astro is fine I guess</title>
  <description>When I’m not fighting WordPress I deliver static HTML or the occasional JavaScript framework integration. For personal projects I have ‘fun’ with my own static site generator. This week was a side quest (soon to be main quest) to build my new company website. […]</description>
  <link>https://dbushell.com/2026/07/10/astro-is-fine/</link>
  <guid isPermaLink="true">https://dbushell.com/2026/07/10/astro-is-fine/</guid>
  <pubDate>Fri, 10 Jul 2026 15:00:00 GMT</pubDate>
  <content:encoded><![CDATA[<p>When I’m not fighting WordPress I deliver static HTML or the occasional JavaScript framework integration. For personal projects I have ‘fun’ with my own <a href="https://dbushell.com/2025/05/11/the-static-site-churns/">static site generator</a>.</p><p>This week was a side quest (soon to be main quest) to build my new company website. We’re talking proper business here so I can’t be messing about. I figured an off the shelf SSG would be most suitable.</p><p>I asked the socials, “<a href="https://www.11ty.dev/" rel="noopener noreferrer" target="_blank">11ty</a> or <a href="https://astro.build/" rel="noopener noreferrer" target="_blank">Astro</a>?” Both are popular but Astro had the edge. I gave Astro an early spin back in 2022 and <a href="https://dbushell.com/2022/07/27/is-fresh-fresh-and-astro-and-bun/#astro">found it slow</a>. Maybe it’s good now?</p><h2 id="the-install">The install</h2><p>I ran <code>pnpm create</code> with <a href="https://pnpm.io/blog/releases/10.16" rel="noopener noreferrer" target="_blank">minimum release age</a> to avoid immediately getting <a href="https://digital.nhs.uk/cyber-alerts/2026/cc-4781" rel="noopener noreferrer" target="_blank">pwned</a>.</p><p>I selected Astro’s <em>“Use minimal (empty) template”</em> option and it generated both an <code>AGENTS.md</code> and <code>CLAUDE.md</code> file — <em>are you f</em> — deep breaths, don’t fall for the rage bait.</p><p>I code in a <a href="https://dbushell.com/2026/07/02/the-modern-app/">modern editor</a> so I installed the recommended Astro extension. At first I struggled with <a href="https://zed.dev/" rel="noopener noreferrer" target="_blank">Zed</a> recognising HTML.</p><figure class="Image"><img src="https://dbushell.com/images/blog/2026/zed-error.avif" alt="Zed editor error confusing HTML elements with JSX. The error says: `JSX element implicitly has type &#39;any&#39; because no interface &#39;JSX.IntrinsicElements&#39; exists. (ts 7026)`" width="465" height="135" decoding="async" fetchpriority="low" loading="lazy" id="--img-8d95ce23"/></figure><p>I discovered a restart temporarily fixed the issue, but I guess I restarted one time too many because now the Astro LSP is completely broken.</p><figure class="Image"><img src="https://dbushell.com/images/blog/2026/zed-astro-lsp.avif" alt="Zed editor error: &#39;Failed to run astro-language-server.&#39;" width="380" height="140" decoding="async" fetchpriority="low" loading="lazy" id="--img-d224ac56"/></figure><p>No modern comforts for me then. At least I can look at HTML without the red squigglies.</p><p>I know what you’re going to say, <em>“Dave bro, you’re inflicting this pain upon yourself! Just write HTML!”</em> And I should. I just want native no-framework <a href="https://css-tricks.com/the-simplest-ways-to-handle-html-includes/" rel="noopener noreferrer" target="_blank">HTML includes</a>, you know? Can you imagine the civilisation we’d live in if that could happen?</p><h2 id="the-docs-are-nice">The docs are nice</h2><p>I persevered and got my templates built with minimal fuss. I added a <a href="https://docs.astro.build/en/guides/content-collections/" rel="noopener noreferrer" target="_blank">markdown collection</a> and got the blog part blogging. It’s obvious that people use Astro to <a href="https://set.studio/blog/astro-is-our-preferred-front-end-platform/" rel="noopener noreferrer" target="_blank">build real websites</a> because all my “how do I” questions had an answer in the documentation.</p><figure class="Image"><img src="https://dbushell.com/images/blog/2026/astro-jsx-meme.avif" alt="Fred from Scooby Doo unmasks a ghost hooded villian captioned &#39;.ASTRO&#39; saying &#39;Let&#39;s see who you really are!&#39; to reveal the React logo and &#39;.JSX&#39; underneath." width="500" height="706" decoding="async" fetchpriority="low" loading="lazy" id="--img-0a7882f3"/></figure><p>I’ve been forced to deploy way too many <a href="https://dbushell.com/notes/2026-04-16T07:30Z/">“React spaces”</a> in my templates because Astro’s whitespace treatment is a mystery. I don’t need many components so I haven’t gone deep on <a href="https://docs.astro.build/en/reference/astro-syntax/#differences-between-astro-and-jsx" rel="noopener noreferrer" target="_blank">Astro vs JSX</a>. My site has zero JavaScript on the front-end. I plan to keep it that way.</p><div class="Box"><p><strong>Edit:</strong> <a href="https://indieweb.social/@websident/116895099447927135" rel="noopener noreferrer" target="_blank">Christian Niklas on Mastodon</a> shared a link to a <a href="https://docs.astro.build/en/guides/upgrade-to/v7/#new-default-whitespace-handling-compresshtml-jsx" rel="noopener noreferrer" target="_blank">recent Astro update</a> where they added a <code>compressHTML: &quot;jsx&quot;</code> option that defaults to no longer “following HTML rules.” Umm… okay. Set this to <code>true</code> or <code>false</code> if you’re building a website? I set it to <code>false</code>. Minifying whitespace is over-optimisation.</p></div><h2 id="ill-keep-it-around">I’ll keep it around</h2><p>Astro has got the job done, despite the <smart-arse>developer experience</smart-arse> being broken out of the box. I dread to think what graveyard of dotfiles is installed if I choose a non-minimal start. I can easily de-Astro my templates should I need to. Right now Astro is solving the right problems and the issues are but a nuisance.</p><p>Final conclusion: Astro is fine I guess. I’m not convinced <a href="https://blog.cloudflare.com/astro-joins-cloudflare/" rel="noopener noreferrer" target="_blank">Cloudflare’s acquisition</a> is a good thing, considering their record for performative slop. I’ve lost my enthusiasm for DX and tooling to be honest. Even my own SSG experiments are collecting dust. I’d call the ecosystem a lost cause if I was being dramatic.</p><p>I just try to avoid the worst of it and care about the end product: shipping a damn fine website! Which I can’t do because I’ve got more businessing to business before this particular site sets sail. Maybe in a few months? It’s looking awesome on <code>localhost</code> though.</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>Select your starter class</title>
  <description>At the risk of pissing on people’s chips I figured it’d be helpful to illustrate the three classes of AI user I’ve identified in the slopageddon. You might be thinking: “Hey, those personas are all negative!” — and you’re absolutely right! Believe me, I’d love nothing more than to shut up about […]</description>
  <link>https://dbushell.com/2026/07/08/select-your-starter-class/</link>
  <guid isPermaLink="true">https://dbushell.com/2026/07/08/select-your-starter-class/</guid>
  <pubDate>Wed, 08 Jul 2026 15:00:00 GMT</pubDate>
  <content:encoded><![CDATA[
<p>
<strong>Hello RSS reader!</strong>
This post contains an interactive feature.
Please visit the canonical web page for an optimal viewing experience :)
</p>
<hr>
<p>At the risk of <a href="https://shkspr.mobi/blog/2026/07/im-just-so-bored-of-ai/" rel="noopener noreferrer" target="_blank">pissing on people’s chips</a> I figured it’d be helpful to illustrate the three classes of AI user I’ve identified in the slopageddon. You might be thinking: <em>“Hey, those personas are all negative!”</em> — and you’re absolutely right!</p><p>Believe me, I’d love nothing more than to shut up about “AI”.</p><p>The thing is, not a week goes by without one of my peers crying out in abject despair. Until the grifters cease <a href="https://dbushell.com/2026/05/20/google-just-spat-in-my-face/">spitting in my face</a> and threatening my career, please allow me to extend a middle finger their way.</p><p>I’m working on <a href="https://dbushell.com/2026/06/01/challenge-and-opportunity/#an-opportunity">more positive plans</a> that I hope to announce soon(-ish). Makes sense to be more proactive and spend energy where it matters. Not that this post didn’t! I enjoyed a few technical challenges artworking the page.</p><hr/><p><small>Images used with modifications:</small></p><p><small>Chalk Outline by Simon Child from <a href="https://thenounproject.com/browse/icons/term/chalk-outline/" target="_blank" title="Chalk Outline Icons" rel="noopener noreferrer">Noun Project</a> (CC BY 3.0)</small></p><p><small>Hand by Elisa Pintonello from <a href="https://thenounproject.com/browse/icons/term/hand/" target="_blank" title="Hand Icons" rel="noopener noreferrer">Noun Project</a> (CC BY 3.0)</small></p><p><small>Zombie by Hamstring from <a href="https://thenounproject.com/browse/icons/term/zombie/" target="_blank" title="Zombie Icons" rel="noopener noreferrer">Noun Project</a> (CC BY 3.0)</small></p><character-select data-speech-synth="none">  <ul class="cs-tabs"><li><a class="Button" href="#the-victim">The Victim</a></li><li><a class="Button" href="#the-zombie">The Zombie</a></li><li><a class="Button" href="#the-grifter">The Grifter</a></li></ul>  <section class="cs-item" id="the-victim" data-index="1"><div class="cs-main"><div class="Prose"><h2 id="the-victim">The Victim</h2><ul><li>Dabbles with free chatbots</li><li>Chuckles at social media slop</li><li>Forced to endure a work mandate</li><li>Never consented to any of this</li><li>Helpless to the human toll</li></ul><dl>          <div><dt>Constitution</dt><dd>-4</dd></div>          <div><dt>Salary</dt><dd>-6</dd></div>        </dl></div><svg width="400" height="400" viewbox="0 0 400 400">        <path d="M195.191 397.467a4.4 4.4 0 0 1-2.335-.348l-58.714-26.111c-1.148-.507-2.06-1.486-2.528-2.705a5.05 5.05 0 0 1 .062-3.766l42.184-99.664-9.336-65.434-76.949-4.377-6.425 93.964c-.182 2.651-2.327 4.609-4.832 4.45l-63.186-4.153c-1.291-.081-2.497-.728-3.321-1.8a5.05 5.05 0 0 1-1.017-3.766l2.223-16.896c.294-2.202 1.972-3.889 4.071-4.106l30.996-3.162 5.145-99.741c.124-2.469 2.01-4.423 4.353-4.52l97.117-4.369 27.919-50.221-34.858-30.875-40.417 3.289 1.438 11.064q.052.232.081.476c.321 2.663-1.465 5.07-3.997 5.375h-.015l-.077.008-10.391 1.084c-1.577.166-3.139-.538-4.125-1.861l-6.069-8.131-11.767 8.44c-1.894 1.362-4.469 1.033-6.031-.778L52.719 75.369c-1.581-1.827-1.628-4.594-.101-6.44l19.314-23.433c.769-.933 1.852-1.525 3.019-1.633l80.068-7.841a4.45 4.45 0 0 1 2.656.58l66.832 38.39.669-3.429c.043-.178.085-.352.139-.522l4.175-13.363a4.9 4.9 0 0 1 1.368-2.136l11.508-10.337c.376-.343.81-.618 1.28-.813l19.515-8.1a4.37 4.37 0 0 1 3-.132l22.093 6.912c1.542.48 2.741 1.769 3.182 3.398l5.88 22.272a5.06 5.06 0 0 1-.232 3.274l-8.045 18.866a4.67 4.67 0 0 1-1.921 2.21l-7.337 4.334 43.328 5.495 20.187-47.578-9.46-15.933c-1.14-1.92-.885-4.392.619-5.979l8.203-8.626c1.635-1.73 4.26-1.881 6.104-.356l9.904 8.177 14.404-9.408c1.999-1.3 4.616-.805 6.081 1.153l11.103 14.772c1.396 1.865 1.322 4.516-.178 6.258l-17.269 20.004-17.864 72.566c-.541 2.21-2.474 3.696-4.647 3.58l-82.094-4.35-50.151 64.165 4.968 75.318a4.83 4.83 0 0 1-.638 2.821L180.8 351.831l25.367 24.273c1.724 1.641 2.03 4.354.731 6.347l-8.47 12.972a4.52 4.52 0 0 1-3.236 2.039z"/>      </svg></div><p class="cs-nav">      <a href="#the-zombie" data-action="next">        <span class="hidden">Next</span>      </a>    </p></section>  <section class="cs-item" id="the-zombie" data-index="2"><div class="cs-main"><div class="Prose"><h2 id="the-zombie">The Zombie</h2><ul><li>Bends the knee to <em>Big Tech</em></li><li>Lives by “AI is inevitable” mantra</li><li>Anthropomorphises their chat box</li><li>Ignores self-inflicted deskilling</li><li>Gambles with house money</li></ul><dl>          <div><dt>Free will</dt><dd>-9</dd></div>          <div><dt>Cognition</dt><dd>-13</dd></div>        </dl></div><svg width="400" height="400" viewbox="0 0 400 400">        <path d="M141.978 393.691c30.89 8.752 63.405 8.064 93.585 0v-12.91a22.2 22.2 0 0 0-8.405-4.482c-.657-22.151-1.66-73.931 3.373-102.776a41.7 41.7 0 0 1 4.981 17.548c0 4.932-1.159 11.075 1.764 11.075 2.94 0 1.764-6.368 1.608-10.522a46.8 46.8 0 0 1 2.162-13.896c1.28-8.133 2.439-14.502 3.044-17.219 2.11-8.635 10.689-11.404 14.84-19.002 4.151-7.58 27.673-38.764 29.61-42.364s2.11-11.733 4.479-18.275c2.041-5.538 10.066-17.946 14.009-25.422l-.017.017a8.63 8.63 0 0 0 .675-6.317 106 106 0 0 1-2.992-16.613c-1.833-16.233-1.055-25.525-7.143-25.145-14.442.883-12.729 27.689-13.387 37.657-.657 9.968-21.083 26.754-25.909 25.024-4.808-1.713-7.921-30.838-9.132-40.806a30 30 0 0 1 0-6.368c.657-6.472 2.162-21.494 3.546-30.735a7.2 7.2 0 0 0 0-2.111 109.9 109.9 0 0 1 .329-36.549c2.491-13.516 6.693-26.252-.657-30.458-3.113-1.869-9.305-3.703-10.135-1.159a250 250 0 0 1-11.623 29.073 7.1 7.1 0 0 0-.657 2.613 125.8 125.8 0 0 1-6.261 31.011 6 6 0 0 0-.329 2.215c.45 10.072-1.28 22.532-1.332 33.226 0 1.18-.489 2.308-1.349 3.115a4.3 4.3 0 0 1-3.182 1.142c-1.557 0-2.491-4.049-2.94-5.538a99.8 99.8 0 0 1-1.833-36.099q.129-1.168 0-2.336a144 144 0 0 1 0-40.979c2.214-13.948 16.604-36.376 3.044-38.764-2.871-.45-6.866-1.436-7.852 1.159-2.11 5.261-11.449 22.151-16.932 33.953a5.95 5.95 0 0 0-.605 2.821 224.3 224.3 0 0 1-4.549 41.758 9.6 9.6 0 0 0 0 4.101c2.11 10.02-.934 27.308 0 35.165 0 1.609-.381 4.655-1.989 4.984-1.764.381-3.425-2.873-3.701-4.707-1.055-7.649-7.299-21.217-6.641-31.34a7.3 7.3 0 0 0-.346-2.665 54.55 54.55 0 0 1-2.041-35.667v-2.319c-.882-13.342 6.468-31.617-2.11-35.268-5.535-2.388-12.505 1.056-12.349 3.426h.017a89.9 89.9 0 0 1-5.535 34.715 5.16 5.16 0 0 0-.398 2.388 147.7 147.7 0 0 1-1.764 39.82 5.1 5.1 0 0 0 0 3.046 271 271 0 0 1 7.645 34.94c0 1.436.502 6.317-.778 7.026h-.329a4.55 4.55 0 0 1-4.168.225 4.55 4.55 0 0 1-2.594-3.271c-1.487-7.649-4.653-14.398-6.036-21.217v.017a9.6 9.6 0 0 0-1.263-3.046 58.25 58.25 0 0 1-9.737-26.201c-3.096-11.075-.502-25.197-7.091-27.689-2.214-.831-9.236.381-9.305 2.596 0 7.753-2.715 22.151-3.217 29.679l.017.017a7.1 7.1 0 0 0 0 2.267 225 225 0 0 1 9.184 31.565c2.767 11.075 5.535 32.725 5.535 32.725s1.989 11.075 4.376 24.141a3.66 3.66 0 0 0 3.476 2.942 4.13 4.13 0 0 1 3.822 2.492c2.11 5.036 5.984 8.307 6.866 11.577 1.28 4.482-4.255 10.297-3.926 14.502a10 10 0 0 1-.778 5.538 7.68 7.68 0 0 0-.45 5.538c5.206 17.444 13.283 37.83 15.497 48.679 2.715 13.793-6.59 53.769-8.959 70.276-1.885 12.737-3.926 41.364-4.756 52.438zm63.471-75.313c0 9.743-.83 20.992-1.885 31.565a25.37 25.37 0 0 1-11.83-17.548c-2.266-14.018-9.962-20.593-8.907-26.91.605-3.773 3.978-4.378 7.195-4.984l-.017-.017c.45-.104.917-.035 1.297.225.381.26.64.658.709 1.108.298 1.289.46 2.605.484 3.928 0 3.6-.882 7.926 1.28 7.926s1.332-4.655 1.159-7.753a21 21 0 0 1 0-2.544 26.3 26.3 0 0 1 2.767-9.085c3.044-6.265 1.487-11.526 5.863-16.994a5.9 5.9 0 0 1 1.833-1.557z"/>      </svg></div><p class="cs-nav">      <a href="#the-victim" data-action="previous">        <span class="hidden">Previous</span>      </a>      <a href="#the-grifter" data-action="next">        <span class="hidden">Next</span>      </a>    </p></section>  <section class="cs-item" id="the-grifter" data-index="3"><div class="cs-main"><div class="Prose"><h2 id="the-grifter">The Grifter</h2><ul><li>Flogs AI and AI paraphernalia</li><li>Will not take “no” for an answer</li><li>Dehumanises the effect of AI</li><li>Idolises the techno-fascists</li><li>Revels in gaslighting</li></ul><dl>          <div><dt>Morality</dt><dd>-99</dd></div>          <div><dt>Corruption</dt><dd>+99</dd></div>        </dl></div><svg width="400" height="400" viewbox="0 0 400 400">        <path d="M113.311 90.094c1.785 0 .357 58.455 1.07 66.958.357 7.085 14.99 52.079 17.131 54.559 2.855 3.897 11.777 15.234 13.562 16.296 3.212 1.417 6.782.708 7.138-1.417.357-1.772 1.07-21.611 2.142-30.468 1.07-8.503-5.71-28.696-4.283-32.594 1.428-3.897 4.997-18.776 4.997-21.965s-9.637-59.164-8.922-64.478c.357-3.897 1.785.355 1.785.355s10.35 64.832 11.064 76.17c.714 11.337-6.782 83.963-5.71 90.695 1.07 6.731 7.852 16.296 13.205 16.296 5.354 0 17.488-3.188 18.916-16.651s7.138-55.622 8.922-64.124c2.142-9.211-2.855-70.147-3.569-76.523-.357-4.96.714-3.188 1.428-1.772.357.355.357 1.772.714 2.48.357 4.251 1.785 22.319 1.785 22.319s7.495.708 10.35 1.772c1.785.708 13.919 6.023 15.704 10.628 2.855 6.731.357 41.451-3.212 55.622s8.565 20.194 17.488 18.423 11.777-9.211 14.632-14.171 10.35-15.588 10.35-25.154c0-9.565.357-40.034.357-46.764 0-2.835-.714-10.274-2.498-12.754-2.142-2.48-28.195-29.759-26.768-32.594 1.07-2.125 4.283 3.543 6.424 6.023 2.142 2.125 21.414 24.445 22.841 25.863 1.07 1.417 3.569 15.943 2.498 30.822-.357 6.023 24.269 15.234 32.835 17.36 8.565 2.48 39.616 2.48 44.612-6.377 4.64-8.857 4.997-10.983 4.283-14.88s-5.71-8.503-14.276-9.565c-8.565-1.063-29.623-3.188-34.976-7.44-5.354-4.252-56.747-68.73-64.242-83.255-7.852-15.234-14.99-30.468-20.701-35.782-6.782-6.731-54.249-6.377-81.016 12.045 0 0-18.559 16.651-32.121 48.89s-36.403 38.971-37.831 47.119c-3.569 10.983-4.283 35.428-4.283 43.576 0 1.772.714 3.543 1.785 4.96 5.354 6.731 21.771 26.925 28.195 27.634 4.997.708 10.35.355 12.849-2.48 2.498-3.188 4.283-12.045.714-16.651-4.64-6.377-13.205-14.525-15.704-17.36-1.785-2.125 1.785-19.485 3.212-23.028 1.428-4.251 21.771-7.795 26.411-7.795-.357-7.44.357-26.216 0-28.342 0 0-.357-2.48.714-2.48h.002Z"/>        <path d="M84.718 184.956a3.51 3.51 0 0 1 3.48-3.474 3.51 3.51 0 0 1 3.48 3.474v139.498a3.51 3.51 0 0 1-3.48 3.474 3.51 3.51 0 0 1-3.48-3.474zm56.555 37.338a3.51 3.51 0 0 1 3.48-3.474 3.51 3.51 0 0 1 3.48 3.474v144.708a3.51 3.51 0 0 1-3.48 3.474 3.51 3.51 0 0 1-3.48-3.474zm22.622 30.392a3.51 3.51 0 0 1 3.48-3.474 3.51 3.51 0 0 1 3.48 3.474v143.84a3.51 3.51 0 0 1-3.48 3.474 3.51 3.51 0 0 1-3.48-3.474zm62.644-45.153a3.51 3.51 0 0 1 3.48-3.474 3.51 3.51 0 0 1 3.48 3.474v138.63a3.51 3.51 0 0 1-3.48 3.474 3.51 3.51 0 0 1-3.48-3.474zm97.446-52.969a3.51 3.51 0 0 1 3.48-3.474 3.51 3.51 0 0 1 3.48 3.474v159.47a3.51 3.51 0 0 1-3.48 3.474 3.51 3.51 0 0 1-3.48-3.474z"/>      </svg></div><p class="cs-nav">      <a href="#the-zombie" data-action="previous">        <span class="hidden">Previous</span>      </a>    </p></section></character-select>
<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>Behold the perfect algorithm!</title>
  <description>1984, Minority Report, Black Mirror — bedtime stories compared to the horrors the UK Government publish, am I right? I’m led to believe “Watch this space” is the latest propaganda piece from His Majesty’s Nanny State. I haven’t read past the title but according to gaming site Dexerto, YouTube […]</description>
  <link>https://dbushell.com/2026/07/06/behold-the-perfect-algorithm/</link>
  <guid isPermaLink="true">https://dbushell.com/2026/07/06/behold-the-perfect-algorithm/</guid>
  <pubDate>Mon, 06 Jul 2026 15:00:00 GMT</pubDate>
  <content:encoded><![CDATA[<p>1984, Minority Report, Black Mirror — bedtime stories compared to the horrors the UK Government publish, am I right?</p><p>I’m led to believe <a href="https://www.gov.uk/government/consultations/watch-this-space-a-new-strategic-direction-for-uk-media-green-paper-and-public-consultation/watch-this-space-a-new-strategic-direction-for-uk-media-green-paper-and-public-consultation" rel="noopener noreferrer" target="_blank">“Watch this space”</a> is the latest propaganda piece from <em>His Majesty’s Nanny State</em>. I haven’t read past the title but according to gaming site Dexerto, YouTube lawyers read it and YouTube ain’t happy. Poor little YouTube.</p><blockquote><p>The government is consulting on options, considering whether to make public service news easier to discover on sites like YouTube and TikTok, with greater prominence and with more visibility during periods of major public importance. It also seeks to discuss misinformation and online viewing habits.</p><p><cite><a href="https://www.dexerto.com/entertainment/youtube-urges-creators-to-fight-proposed-uk-algorithm-changes-3383111/" rel="noopener noreferrer" target="_blank">YouTube urges creators to fight proposed UK algorithm changes</a> - Matthew Benson, Dexerto</cite></p></blockquote><p>I glossed over the Dexerto article too. This whole thing is something about kids being hooked on <em>Skibidi</em> and not paying their <a href="https://www.bbctvlicence.com/" rel="noopener noreferrer" target="_blank"><del>racketeering</del> license fee</a>. <em>Minecraft Let’s Plays</em> will be spliced with a BBC impartiality report on what some <a href="https://www.bbc.co.uk/search?q=farage" rel="noopener noreferrer" target="_blank">fascist gammon</a> thinks. Should the proposal become law, of course.</p><p>This is somewhat of a dilemma for a guy like me. If there’s one thing I hate more than a meddling GOV.UK, that might just be <em>Big Tech</em>. The thought of Google et al being ruffled warms my heart like a hot cup of tea on the summer solstice.</p><hr/><p>That was too many words on something I never read so I’ll get to the lede. I’m about to reveal the secret sauce that <em>Big Tech</em> has tried to suppress. The one true algorithm, which ironically might be their saviour.</p><figure><pre data-lang="sql" tabindex="0" id="pre-3d65864c"><code><span class="line"><span class="syntax-1656d967">SELECT</span><span class="space"> </span><span class="syntax-26f6a8db">p.</span><span class="syntax-1656d967">*</span><span class="space"> </span><span class="syntax-1656d967">FROM</span><span class="space"> </span><span class="syntax-26f6a8db">posts</span><span class="space"> </span><span class="syntax-26f6a8db">p</span></span>
<span class="line"><span class="syntax-1656d967">JOIN</span><span class="space"> </span><span class="syntax-26f6a8db">follows</span><span class="space"> </span><span class="syntax-26f6a8db">f</span><span class="space"> </span><span class="syntax-1656d967">ON</span><span class="space"> </span><span class="syntax-765b360f">p</span><span class="syntax-26f6a8db">.</span><span class="syntax-765b360f">user_id</span><span class="space"> </span><span class="syntax-1656d967">=</span><span class="space"> </span><span class="syntax-765b360f">f</span><span class="syntax-26f6a8db">.</span><span class="syntax-765b360f">following_id</span></span>
<span class="line"><span class="syntax-1656d967">WHERE</span><span class="space"> </span><span class="syntax-765b360f">f</span><span class="syntax-26f6a8db">.</span><span class="syntax-765b360f">follower_id</span><span class="space"> </span><span class="syntax-1656d967">=</span><span class="space"> </span><span class="syntax-26f6a8db">?</span></span>
<span class="line"><span class="syntax-1656d967">ORDER</span><span class="space"> </span><span class="syntax-1656d967">BY</span><span class="space"> </span><span class="syntax-765b360f">p</span><span class="syntax-26f6a8db">.</span><span class="syntax-765b360f">created_at</span><span class="space"> </span><span class="syntax-1656d967">DESC</span><span class="syntax-26f6a8db">;</span></span></code></pre><figcaption>This is nerd bait. <sup>†</sup></figcaption></figure><p>Only one parameter is required in the perfect algorithm: <strong>who I choose to follow.</strong></p><figure class="Image"><img src="https://dbushell.com/images/blog/2026/obi-wan-follow.avif" alt="&#39;That&#39;s... why I follow them.&#39; says a slightly puzzled Obi-Wan Kenobi, from Star Wars: Episode II – Attack of the Clones" width="606" height="412" decoding="async" fetchpriority="low" loading="lazy" id="--img-a938bb20"/></figure><p>I’m literally providing the exact data needed to curate my feed.</p><p>I know what defenders of the deceptive arts are thinking: <smart-arse>but algorithms are proven to increase engagement!</smart-arse> — I know, Sherlock. Do you enjoy your doomscrolling misery? Not every metric needs to be min-maxed at the expense of human health.</p><p><a href="https://dbushell.com/2026/07/02/the-modern-app/">Modern apps sucks.</a> Modern media sucks. Stick your “algorithm”.</p><hr/><p><small><sup>†</sup> It’s been decades since I studied SQL and database normalisation so please have mercy.</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>Fixing full-bleed CSS</title>
  <description>I’m a front-end developer not a medical practitioner. If you’re bleeding IRL visit the hospital and stop googling medical issues! The full-bleed layout — as described there by Josh Comeau — can be done with CSS grid (and subgrid). Sometimes you can’t grid the entire page. […]</description>
  <link>https://dbushell.com/2026/07/03/fixing-full-bleed-css/</link>
  <guid isPermaLink="true">https://dbushell.com/2026/07/03/fixing-full-bleed-css/</guid>
  <pubDate>Fri, 03 Jul 2026 15:00:00 GMT</pubDate>
  <content:encoded><![CDATA[<div class="Alert"><p>I’m a front-end developer not a medical practitioner. If you’re bleeding IRL visit the hospital and stop googling medical issues!</p></div><p>The <a href="https://www.joshwcomeau.com/css/full-bleed/" rel="noopener noreferrer" target="_blank">full-bleed layout</a> — as described there by Josh Comeau — can be done with CSS grid (<a href="https://dbushell.com/2026/04/02/css-subgrid-is-super-good/">and subgrid</a>). Sometimes you can’t grid the entire page.</p><p>That’s where <a href="https://piccalil.li/blog/creating-a-full-bleed-css-utility/" rel="noopener noreferrer" target="_blank">Andy Bell’s utility class</a> is useful.</p><pre data-lang="css" tabindex="0" id="pre-c770d7de"><code><span class="line"><span class="syntax-4ddd3d58">.full-bleed</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-3eeadcf9">width</span><span class="syntax-1656d967">:</span><span class="space"> </span><span class="syntax-765b360f">100</span><span class="syntax-1656d967">vw</span><span class="syntax-26f6a8db">;</span></span>
<span class="line"><span class="space"> </span><span class="space"> </span><span class="syntax-3eeadcf9">margin-left</span><span class="syntax-1656d967">:</span><span class="space"> </span><span class="syntax-3eeadcf9">calc</span><span class="syntax-26f6a8db">(</span><span class="syntax-765b360f">50</span><span class="syntax-1656d967">%</span><span class="space"> </span><span class="syntax-1656d967">-</span><span class="space"> </span><span class="syntax-765b360f">50</span><span class="syntax-1656d967">vw</span><span class="syntax-26f6a8db">);</span></span>
<span class="line"><span class="syntax-26f6a8db">}</span></span></code></pre><p>But it ain’t perfect. The issue is that viewport units don’t solve the <a href="https://www.smashingmagazine.com/2023/12/new-css-viewport-units-not-solve-classic-scrollbar-problem/" rel="noopener noreferrer" target="_blank">classic scrollbar problem</a>. If you’re on macOS or a fancy OS that has fancy scrollbars, test on Windows! <code>100vw</code> can be wider than the viewport. Because why would browsers do anything sensible?</p><p>It’s hard to see in <a href="https://codepen.io/piccalilli/pen/vYOJjNw" rel="noopener noreferrer" target="_blank">Andy’s CodePen</a> but a few pixels can be cropped either side. Add something like a border or shadow and it’s easier to see.</p><pre data-lang="css" tabindex="0" id="pre-926afc7e"><code><span class="line"><span class="syntax-4ddd3d58">.full-bleed</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-3eeadcf9">box-shadow</span><span class="syntax-1656d967">:</span><span class="space"> </span><span class="syntax-765b360f">inset</span><span class="space"> </span><span class="syntax-765b360f">0</span><span class="space"> </span><span class="syntax-765b360f">0</span><span class="space"> </span><span class="syntax-765b360f">0</span><span class="space"> </span><span class="syntax-765b360f">10</span><span class="syntax-1656d967">px</span><span class="space"> </span><span class="syntax-765b360f">yellow</span><span class="syntax-26f6a8db">;</span></span>
<span class="line"><span class="syntax-26f6a8db">}</span></span></code></pre><figure class="Image"><img src="https://dbushell.com/images/blog/2026/full-bleed-crop.avif" alt="Yellow border is slightly clipped either side." width="375" height="150" decoding="async" fetchpriority="low" loading="lazy" id="--img-f718a368"/><figcaption>Ignore the pink left border that’s my blog style.</figcaption></figure><p>This is not always a problem but it can lead to subtle alignment issues. By the way, macOS has a scrollbar setting <em>“Show scroll bars &gt; Always”</em> that’ll let you test the issue.</p><figure class="Image"><img src="https://dbushell.com/images/blog/2026/macos-scrollbar-preferences.avif" alt="macOS scrollbar settings on the appearance tab." width="540" height="118" decoding="async" fetchpriority="low" loading="lazy" id="--img-fec9c3ac"/></figure><p>Andy solves this partially by hiding horizontal overflow on the <code>&lt;body&gt;</code> element.</p><pre data-lang="css" tabindex="0" id="pre-194af6f5"><code><span class="line"><span class="syntax-1656d967">body</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-3eeadcf9">overflow-x</span><span class="syntax-1656d967">:</span><span class="space"> </span><span class="syntax-765b360f">hidden</span><span class="syntax-26f6a8db">;</span></span>
<span class="line"><span class="syntax-26f6a8db">}</span></span></code></pre><p>An alternative fix is to always reserve space for the classic scrollbar.</p><pre data-lang="css" tabindex="0" id="pre-5ae2ebc6"><code><span class="line"><span class="syntax-1656d967">html</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-3eeadcf9">scrollbar-gutter</span><span class="syntax-1656d967">:</span><span class="space"> </span><span class="syntax-26f6a8db">stable;</span></span>
<span class="line"><span class="syntax-26f6a8db">}</span></span></code></pre><p>That can look weird if there is no vertical scroll necessary.</p><h2 id="modern-solution">Modern solution</h2><p>The “modern” approach is to use <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Guides/Containment" rel="noopener noreferrer" target="_blank">CSS containment</a>. Turn the <code>&lt;body&gt;</code> element (or any 100% width child) into a container. Then replace the viewport units with container units.</p><pre data-lang="css" tabindex="0" id="pre-f8beed2c"><code><span class="line"><span class="syntax-1656d967">body</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-3eeadcf9">container</span><span class="syntax-1656d967">:</span><span class="space"> </span><span class="syntax-26f6a8db">body</span><span class="space"> </span><span class="syntax-26f6a8db">/</span><span class="space"> </span><span class="syntax-26f6a8db">inline-size;</span></span>
<span class="line"><span class="space"> </span><span class="space"> </span><span class="syntax-3eeadcf9">overflow-x</span><span class="syntax-1656d967">:</span><span class="space"> </span><span class="syntax-765b360f">clip</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-4ddd3d58">.full-bleed</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-3eeadcf9">inline-size</span><span class="syntax-1656d967">:</span><span class="space"> </span><span class="syntax-765b360f">100</span><span class="syntax-1656d967">cqi</span><span class="syntax-26f6a8db">;</span></span>
<span class="line"><span class="space"> </span><span class="space"> </span><span class="syntax-3eeadcf9">margin-inline-start</span><span class="syntax-1656d967">:</span><span class="space"> </span><span class="syntax-3eeadcf9">calc</span><span class="syntax-26f6a8db">(</span><span class="syntax-765b360f">50</span><span class="syntax-1656d967">%</span><span class="space"> </span><span class="syntax-1656d967">-</span><span class="space"> </span><span class="syntax-765b360f">50</span><span class="syntax-1656d967">cqi</span><span class="syntax-26f6a8db">);</span></span>
<span class="line"><span class="syntax-26f6a8db">}</span></span></code></pre><p>Now hiding overflow is not strictly necessary. I prefer <code>clip</code> — see <a href="https://ishadeed.com/article/overflow-clip/" rel="noopener noreferrer" target="_blank">Overflow Clip guide</a> by Ahmad Shadeed. I clip out of caution because <a href="https://dbushell.com/2026/07/02/the-modern-app/">I make dumb things.</a> I also use <a href="https://dbushell.com/2021/02/02/changing-css-for-good-logical-properties-and-values/">logical properties and values</a> to support right-to-left (RTL) text direction. Ahmad has an excellent <a href="https://rtlstyling.com/" rel="noopener noreferrer" target="_blank">RTL Styling 101</a> too.</p><p>But wait!</p><p>Using <code>cqi</code> units assumes <code>body</code> is the parent container of the <code>.full-bleed</code> element. What if we have nested containers? Check this out. <a href="https://codepen.io/dbushell/pen/rajYvPj" rel="noopener noreferrer" target="_blank">I’ve forked Andy’s CodePen</a> to add another <code>.inside</code> container that is <strong>not</strong> the full viewport width.</p><figure class="Image"><img src="https://dbushell.com/images/blog/2026/full-bleed-inside.avif" alt="Inspecting CSS container layout using Chromium dev tools to show that the inside container is smaller." width="1084" height="654" decoding="async" fetchpriority="low" loading="lazy" id="--img-6b856c86"/></figure><p>This alone would usually break the new <code>.full-bleed</code> class and ruin the fun.</p><p>But we can fix that!</p><pre data-lang="css" tabindex="0" id="pre-011df034"><code><span class="line"><span class="syntax-1656d967">@property</span><span class="space"> </span><span class="syntax-26f6a8db">--body-size</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">syntax:</span><span class="space"> </span><span class="syntax-1656d967">"&#x3C;length></span><span class="space"> </span><span class="syntax-1656d967">|</span><span class="space"> </span><span class="syntax-1656d967">&#x3C;percentage>";</span></span>
<span class="line"><span class="space"> </span><span class="space"> </span><span class="syntax-1656d967">inherits:</span><span class="space"> </span><span class="syntax-1656d967">true;</span></span>
<span class="line"><span class="space"> </span><span class="space"> </span><span class="syntax-1656d967">initial-value:</span><span class="space"> </span><span class="syntax-1656d967">100%;</span></span>
<span class="line"><span class="syntax-1656d967">}</span></span>
<span class="line"></span>
<span class="line"><span class="syntax-1656d967">body</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-3eeadcf9">container</span><span class="syntax-1656d967">:</span><span class="space"> </span><span class="syntax-26f6a8db">body</span><span class="space"> </span><span class="syntax-26f6a8db">/</span><span class="space"> </span><span class="syntax-26f6a8db">inline-size;</span></span>
<span class="line"><span class="syntax-26f6a8db">}</span></span>
<span class="line"></span>
<span class="line"><span class="syntax-4ddd3d58">.inside</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-26f6a8db">--body-size</span><span class="syntax-1656d967">:</span><span class="space"> </span><span class="syntax-765b360f">100</span><span class="syntax-1656d967">cqi</span><span class="syntax-26f6a8db">;</span></span>
<span class="line"><span class="space"> </span><span class="space"> </span><span class="syntax-3eeadcf9">container</span><span class="syntax-1656d967">:</span><span class="space"> </span><span class="syntax-765b360f">inside</span><span class="space"> </span><span class="syntax-26f6a8db">/</span><span class="space"> </span><span class="syntax-26f6a8db">inline-size;</span></span>
<span class="line"><span class="syntax-26f6a8db">}</span></span>
<span class="line"></span>
<span class="line"><span class="syntax-4ddd3d58">.full-bleed</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-3eeadcf9">inline-size</span><span class="syntax-1656d967">:</span><span class="space"> </span><span class="syntax-3eeadcf9">var</span><span class="syntax-26f6a8db">(--body-size);</span></span>
<span class="line"><span class="space"> </span><span class="space"> </span><span class="syntax-3eeadcf9">margin-inline-start</span><span class="syntax-1656d967">:</span><span class="space"> </span><span class="syntax-3eeadcf9">calc</span><span class="syntax-26f6a8db">(</span><span class="syntax-765b360f">50</span><span class="syntax-1656d967">%</span><span class="space"> </span><span class="syntax-1656d967">-</span><span class="space"> </span><span class="syntax-26f6a8db">(</span><span class="syntax-765b360f">0.5</span><span class="space"> </span><span class="syntax-1656d967">*</span><span class="space"> </span><span class="syntax-3eeadcf9">var</span><span class="syntax-26f6a8db">(--body-size)));</span><span class="space"> </span><span class="syntax-7b4433fd">/*</span><span class="space"> </span><span class="syntax-7b4433fd">†</span><span class="space"> </span><span class="syntax-7b4433fd">*/</span></span>
<span class="line"><span class="syntax-26f6a8db">}</span></span></code></pre><p>What is that <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/At-rules/@property" rel="noopener noreferrer" target="_blank"><code>@property</code> magic?</a></p><p>To be honest I struggle to wrap my smooth brain around this!</p><p>Let me try to explain it to myself. Without the at-rule the value of <code>--body-size</code> is calculated at the time of use, i.e. within <code>.full-bleed</code> and therefore relative to the <code>inside</code> container. By explicitly defining a <code>@property</code> the value is now calculated when it’s set within <code>.inside</code>. There <code>100cqi</code> refers to the parent <code>body</code> container and <code>.full-bleed</code> inherits that value.</p><p>But what if you have more containers?</p><p role="img" aria-label="ASCII art of an incensed person flipping a table.">(╯°□°)╯︵ ┻━┻</p><p><em>Gosh!</em> Stop being so difficult!</p><p>I would have a direct child of <code>&lt;body&gt;</code> like <code>&lt;main&gt;</code> set the <code>--body-size</code> value.</p><pre data-lang="html" tabindex="0" id="pre-b14b429b"><code><span class="line"><span class="syntax-26f6a8db">&#x3C;</span><span class="syntax-1656d967">body</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">main</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-7b4433fd">&#x3C;!--</span><span class="space"> </span><span class="syntax-7b4433fd">blah</span><span class="space"> </span><span class="syntax-7b4433fd">--></span></span>
<span class="line"><span class="space"> </span><span class="space"> </span><span class="syntax-26f6a8db">&#x3C;/</span><span class="syntax-1656d967">main</span><span class="syntax-26f6a8db">></span></span>
<span class="line"><span class="syntax-26f6a8db">&#x3C;/</span><span class="syntax-1656d967">body</span><span class="syntax-26f6a8db">></span></span></code></pre><p><small><sup>†</sup> I’m multiplying by 0.5 because division is for chumps.</small></p><h2 id="next-gen-solution">Next-gen solution</h2><p>What CSS needs is a way to reference a container when using container units.</p><p><a href="https://github.com/w3c/csswg-drafts/issues/7858" rel="noopener noreferrer" target="_blank">Ideas have been proposed</a> for example:</p><pre data-lang="css" tabindex="0" id="pre-de80f5a5"><code><span class="line"><span class="syntax-4ddd3d58">.full-bleed</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-3eeadcf9">inline-size</span><span class="syntax-1656d967">:</span><span class="space"> </span><span class="syntax-765b360f">100</span><span class="syntax-1656d967">cqi</span><span class="syntax-26f6a8db">(body);</span></span>
<span class="line"><span class="space"> </span><span class="space"> </span><span class="syntax-3eeadcf9">inline-size</span><span class="syntax-1656d967">:</span><span class="space"> </span><span class="syntax-3eeadcf9">calc</span><span class="syntax-26f6a8db">(</span><span class="syntax-765b360f">100</span><span class="space"> </span><span class="syntax-1656d967">*</span><span class="space"> </span><span class="syntax-26f6a8db">cqi(body));</span></span>
<span class="line"><span class="space"> </span><span class="space"> </span><span class="syntax-3eeadcf9">inline-size</span><span class="syntax-1656d967">:</span><span class="space"> </span><span class="syntax-3eeadcf9">calc</span><span class="syntax-26f6a8db">(</span><span class="syntax-765b360f">100</span><span class="space"> </span><span class="syntax-1656d967">*</span><span class="space"> </span><span class="syntax-26f6a8db">container(cqi,</span><span class="space"> </span><span class="syntax-26f6a8db">body));</span></span>
<span class="line"><span class="syntax-26f6a8db">}</span></span></code></pre><p>Cancel <a href="https://wpt.fyi/interop-2026" rel="noopener noreferrer" target="_blank">Interop 2026</a> and make this happen!</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>The modern app</title>
  <description>Today I’m introducing the next generation of code editor. A modern app to satiate the needs of the discerning coder. We’re talkin’ blazing fast collaboration between man and machine. Try out the demo below (for best experience: desktop Chrome, obvs). […]</description>
  <link>https://dbushell.com/2026/07/02/the-modern-app/</link>
  <guid isPermaLink="true">https://dbushell.com/2026/07/02/the-modern-app/</guid>
  <pubDate>Thu, 02 Jul 2026 15:00:00 GMT</pubDate>
  <content:encoded><![CDATA[
<p>
<strong>Hello RSS reader!</strong>
This post contains an interactive feature.
Please visit the canonical web page for an optimal viewing experience :)
</p>
<hr>
<p>Today I’m introducing the <strong>next generation of code editor.</strong> A modern app to satiate the needs of the discerning coder. We’re talkin’ blazing fast collaboration between <em>man and machine</em>.</p><p>Try out the demo below (for best experience: desktop Chrome, obvs).</p><p><small>If you’re reading this in RSS I have no clue what you’re about to see… <a href="https://dbushell.com/2026/07/02/the-modern-app/">maybe visit the demo</a> it’s a fun one!</small></p><modern-editor>  <div class="me-app">    <div class="me-menubar">      <svg aria-hidden="true" focusable="false" width="64" height="16" viewbox="0 0 64 16">        <circle fill="#FF5756" cx="8" cy="8" r="8" />        <circle fill="#EBBD44" cx="32" cy="8" r="8" />        <circle fill="#4EC043" cx="56" cy="8" r="8" />      </svg>      <h2>The Modern Editor</h2>      <p>Update ready <code>v0.420</code> (restart required)</p>    </div>    <div class="me-window">      <noscript>        <div class="me-editor">          <div>A modern app requires JavaScript, bro.</div>        </div>      </noscript>      <div class="me-caret" popover="manual"></div>      <div class="me-reference" popover="manual">        <p>          <b>Error loading documentation.</b>          Please disable your adblocker and try again.          We and our 9172 partners value your personal data.          You must accept the terms and conditions.          Application error: a client-side exception has occurred          (see the browser console for more information).        </p>      </div>      <p class="me-reference" popover="manual">        Last edit: <del>DELETED USER</del> – 1 January 1970 – is this working?      </p>      <div class="me-reference" popover="manual">        <p>aardvark</p>        <p>abandonment</p>        <p>abbreviation</p>        <p>aerodynamically</p>        <p>antidisestablishmentarianism</p>        <p><a href="#">[Advertisement: 1% off subscription]</a></p>      </div>      <div class="me-reference" popover="manual">        <p>          <svg aria-hidden="true" focusable="false" width="24" height="24" viewbox="0 0 24 24"><path d="M14 10h5.75c.69 0 1.25-.56 1.25-1.25V3h-1.5v4.03A8.976 8.976 0 0 0 12 3c-4.96 0-9 4.04-9 9s4.04 9 9 9a9.012 9.012 0 0 0 8.695-6.67l-1.45-.39A7.513 7.513 0 0 1 12 19.5c-4.135 0-7.5-3.365-7.5-7.5S7.865 4.5 12 4.5c2.805 0 5.34 1.55 6.635 4H14V10Z"/></svg>          Thinking…</p>      </div>    </div>    <div class="me-iconbar">      <p class="hidden">an icon bar full of indecipherable icons with no label</p>      <svg aria-hidden="true" focusable="false" width="24" height="24" viewbox="0 0 24 24"><path fill-rule="evenodd" clip-rule="evenodd" d="M5.5 3.5h7v4.75c0 .69.56 1.25 1.25 1.25h4.75v3H20V8.44L13.56 2H4v20h10v-1.5H5.5v-17ZM14 4.56 17.44 8H14V4.56ZM17.75 14h-1.5c0 1.79-1.46 3.25-3.25 3.25v1.5c1.79 0 3.25 1.46 3.25 3.25h1.5c0-1.79 1.46-3.25 3.25-3.25v-1.5c-1.79 0-3.25-1.46-3.25-3.25ZM17 19.45A4.775 4.775 0 0 0 15.55 18 4.775 4.775 0 0 0 17 16.55c.37.58.865 1.075 1.45 1.45-.58.37-1.075.865-1.45 1.45Zm-9.5-8.2c.965 0 1.75-.785 1.75-1.75h1.5c0 .965.785 1.75 1.75 1.75v1.5c-.965 0-1.75.785-1.75 1.75h-1.5c0-.965-.785-1.75-1.75-1.75v-1.5Z"/></svg>      <svg aria-hidden="true" focusable="false" width="24" height="24" viewbox="0 0 24 24"><path fill-rule="evenodd" clip-rule="evenodd" d="M5.5 4.207c0-1.114 1.346-1.671 2.134-.884L9.31 5H14a6.502 6.502 0 0 1 6.48 5.979A1.25 1.25 0 0 0 21.5 9.75v-1H23v1a2.75 2.75 0 0 1-2.576 2.745A6.51 6.51 0 0 1 17 17.265v1.985c0 .69-.56 1.25-1.25 1.25H12.5V18H10v1.25c0 .69-.56 1.25-1.25 1.25H5.5v-3.523A6.536 6.536 0 0 1 3.523 15H2.25C1.56 15 1 14.44 1 13.75v-3c0-.69.56-1.25 1.25-1.25h.568A6.517 6.517 0 0 1 5.5 6.023V4.207Zm1.5.604v2.084l-.39.213a5.014 5.014 0 0 0-2.488 3.305l-.13.587H2.5v2.5h1.895l.213.39a5.034 5.034 0 0 0 2.002 2.002l.39.213V19h1.5v-2.5H14V19h1.5v-2.706l.456-.194A5.002 5.002 0 0 0 19 11.5a5 5 0 0 0-5-5H8.69L7 4.81Z"/></svg>      <svg aria-hidden="true" focusable="false" width="24" height="24" viewbox="0 0 24 24"><path fill-rule="evenodd" clip-rule="evenodd" d="M17.25 2h1.5c0 1.79 1.46 3.25 3.25 3.25v1.5c-1.79 0-3.25 1.46-3.25 3.25h-1.5c0-1.79-1.46-3.25-3.25-3.25v-1.5c1.79 0 3.25-1.46 3.25-3.25Zm-.7 4c.585.375 1.08.87 1.45 1.45.375-.585.87-1.08 1.45-1.45A4.775 4.775 0 0 1 18 4.55 4.775 4.775 0 0 1 16.55 6Zm-.935 5.325L11.5 15.44l-1.365-1.365a1.258 1.258 0 0 0-1.77 0L4.5 17.94V5.75c0-.69.56-1.25 1.25-1.25h6.75V3H5.75A2.755 2.755 0 0 0 3 5.75v12.5A2.755 2.755 0 0 0 5.75 21h12.5A2.755 2.755 0 0 0 21 18.25v-3.31l-3.615-3.615a1.258 1.258 0 0 0-1.77 0ZM19.5 18.25c0 .69-.56 1.25-1.25 1.25H5.75c-.2 0-.39-.045-.56-.13l4.06-4.06 2.25 2.25 5-5 3 3v2.69ZM6 8.5a2.5 2.5 0 0 0 5 0 2.5 2.5 0 0 0-5 0Zm3.5 0c0 .55-.45 1-1 1s-1-.45-1-1 .45-1 1-1 1 .45 1 1Z"/></svg>      <svg aria-hidden="true" focusable="false" width="24" height="24" viewbox="0 0 24 24"><path d="M12.5 21.545a1.245 1.245 0 0 1-1.25-1.25v-6.48l-3.47 3.47-1.06-1.06 4.22-4.22L6.72 7.78l1.06-1.06 3.47 3.47V3.705c0-.505.306-.96.77-1.155a1.237 1.237 0 0 1 1.36.27l4.426 4.425-4.75 4.75 4.75 4.75-4.425 4.425c-.24.24-.56.365-.88.365v.01Zm.25-7.735v5.88l2.94-2.94-2.94-2.94Zm0-9.5v5.88l2.94-2.94-2.94-2.94Z"/></svg>      <svg aria-hidden="true" focusable="false" width="24" height="24" viewbox="0 0 24 24"><path fill-rule="evenodd" clip-rule="evenodd" d="M5.5 4.4A9.945 9.945 0 0 1 12 2v-.005c5.515 0 10 4.485 10 10 0 1.115-.18 2.205-.54 3.25l-1.42-.485c.305-.885.46-1.815.46-2.76 0-4.685-3.815-8.5-8.5-8.5-2.03 0-3.945.715-5.46 1.995H8.5v1.5H4V2.5h1.5v1.9Zm11.96 14.105H15.5V17.01H20v4.495h-1.5v-1.9a9.945 9.945 0 0 1-6.5 2.4c-5.515 0-10-4.485-10-10 0-1.115.18-2.205.54-3.25l1.42.485A8.457 8.457 0 0 0 3.5 12c0 4.685 3.815 8.5 8.5 8.5 2.03 0 3.945-.715 5.46-1.995ZM13.25 14h1.5c0-1.79 1.46-3.25 3.25-3.25v-1.5c-1.79 0-3.25-1.46-3.25-3.25h-1.5c0 1.79-1.46 3.25-3.25 3.25v1.5c1.79 0 3.25 1.46 3.25 3.25ZM14 8.55c.37.58.865 1.075 1.45 1.45-.58.37-1.075.865-1.45 1.45A4.775 4.775 0 0 0 12.55 10 4.775 4.775 0 0 0 14 8.55Zm-7.5 5.7c.965 0 1.75-.785 1.75-1.75h1.5c0 .965.785 1.75 1.75 1.75v1.5c-.965 0-1.75.785-1.75 1.75h-1.5c0-.965-.785-1.75-1.75-1.75v-1.5Z"/></svg>      <svg aria-hidden="true" focusable="false" width="24" height="24" viewbox="0 0 24 24"><path fill-rule="evenodd" clip-rule="evenodd" d="M11 6C12.1046 6 13 5.10457 13 4C13 2.89543 12.1046 2 11 2C9.89543 2 9 2.89543 9 4C9 5.10457 9.89543 6 11 6ZM3 22H4.5L4.505 22.01V12.97L7.165 8.64501C7.355 8.33501 7.675 8.12001 8.035 8.06501C8.39 8.01001 8.76 8.11001 9.04 8.35001L10.975 10.005H15.5V8.50501H11.525L10.015 7.21001C9.405 6.68501 8.595 6.45501 7.8 6.58001C7.005 6.70501 6.305 7.17001 5.885 7.85501L3 12.54V22ZM13.75 15H15.75C16.44 15 17 14.44 17 13.75V11.5H15.5V13.5H14V12.75C14 12.06 13.44 11.5 12.75 11.5H11V13H12.5V13.75C12.5 14.44 13.06 15 13.75 15ZM20.5 13.75C20.5 14.4404 19.9404 15 19.25 15C18.5596 15 18 14.4404 18 13.75C18 13.0596 18.5596 12.5 19.25 12.5C19.9404 12.5 20.5 13.0596 20.5 13.75ZM21 16H9V17.5H21V16ZM6 22H7.5V13.975L9.375 11.165L8.125 10.335L6 13.525V22Z"/></svg>      <svg aria-hidden="true" focusable="false" width="24" height="24" viewbox="0 0 24 24"><path fill-rule="evenodd" clip-rule="evenodd" d="M20.975 3.025A3.48 3.48 0 0 0 18.5 2a3.48 3.48 0 0 0-2.475 1.025l-13.17 13.17-.845 4.93a.74.74 0 0 0 .21.655c.14.14.335.22.53.22.04 0 .085 0 .125-.01l4.93-.845 13.17-13.17A3.48 3.48 0 0 0 22 5.5a3.48 3.48 0 0 0-1.025-2.475Zm-13.89 16.72-3.415.585.585-3.415 9.3-9.3 2.83 2.83-9.3 9.3Zm10.36-10.36-2.83-2.83 2.47-2.47c.755-.755 2.07-.755 2.83 0a2.002 2.002 0 0 1 0 2.83l-2.47 2.47ZM5.25 10h1.5c0-1.79 1.46-3.25 3.25-3.25v-1.5C8.21 5.25 6.75 3.79 6.75 2h-1.5c0 1.79-1.46 3.25-3.25 3.25v1.5c1.79 0 3.25 1.46 3.25 3.25ZM6 4.55c.37.58.865 1.075 1.45 1.45-.58.37-1.075.865-1.45 1.45A4.775 4.775 0 0 0 4.55 6 4.775 4.775 0 0 0 6 4.55ZM16.75 15h1.5c0 .965.785 1.75 1.75 1.75v1.5c-.965 0-1.75.785-1.75 1.75h-1.5c0-.965-.785-1.75-1.75-1.75v-1.5c.965 0 1.75-.785 1.75-1.75Z"/></svg>      <svg aria-hidden="true" focusable="false" width="24" height="24" viewbox="0 0 24 24"><path fill-rule="evenodd" clip-rule="evenodd" d="M19.58 11.485a7.99 7.99 0 0 1-.425.515v.01l.128.154c.102.121.202.241.297.361 1.36 1.74 1.745 3.335 1.08 4.485-.375.645-1.225 1.4-3.175 1.4H17.3l.035-1.5c1.04.03 1.775-.21 2.025-.65.33-.57-.03-1.62-.96-2.815a4.684 4.684 0 0 0-.197-.24l-.098-.115c-.53.49-1.115.97-1.745 1.435-.495 4.49-2.225 7.485-4.36 7.485-1.615 0-2.82-1.58-3.575-3.81-.685.135-1.34.215-1.94.215-1.43 0-2.575-.42-3.145-1.405-.385-.665-.615-1.835.465-3.61l1.28.78c-.54.885-.7 1.64-.45 2.08.34.59 1.585.825 3.38.495-.165-.71-.29-1.46-.375-2.225C4 11.855 2.27 8.86 3.34 7.01c.81-1.4 2.78-1.65 5.085-1.19.755-2.23 1.96-3.81 3.575-3.81.775 0 1.9.385 2.9 2.22l-1.32.715c-.495-.915-1.07-1.44-1.58-1.44-.68 0-1.505.96-2.12 2.68.7.215 1.41.475 2.115.785C16.13 5.15 19.59 5.15 20.66 7c.66 1.15.28 2.74-1.08 4.485Zm-1.18-.92c.93-1.195 1.29-2.245.96-2.815-.475-.82-2.645-.93-5.555.11a21.124 21.124 0 0 1 4.3 3.06l.098-.116c.069-.08.136-.158.197-.239ZM8.02 7.255c-1.795-.33-3.04-.095-3.38.495-.475.82.51 2.755 2.865 4.755C7.5 12.335 7.5 12.17 7.5 12c0-1.615.18-3.265.52-4.745Zm1.445.355C9.18 8.84 9 10.315 9 12c0 1.685.18 3.16.465 4.39 1.205-.365 2.575-.945 4.035-1.79 1.36-.785 2.575-1.68 3.565-2.6-.99-.925-2.205-1.815-3.565-2.6-1.46-.84-2.825-1.42-4.035-1.79Zm.415 10.205c.61 1.72 1.44 2.685 2.12 2.685v-.005c.95 0 2.13-1.825 2.685-4.865l-.094.059c-.112.07-.224.14-.341.206-1.4.81-2.915 1.475-4.37 1.92ZM13.5 12a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0Z"/></svg>      <svg aria-hidden="true" focusable="false" width="24" height="24" viewbox="0 0 24 24"><path fill-rule="evenodd" clip-rule="evenodd" d="M19.25 4H4.75A2.755 2.755 0 0 0 2 6.75v10.5A2.755 2.755 0 0 0 4.75 20h8.75v-1.5H4.75c-.69 0-1.25-.56-1.25-1.25V10.5h17V13H22V6.75A2.755 2.755 0 0 0 19.25 4Zm1.25 4.5h-17V6.75c0-.69.56-1.25 1.25-1.25h14.5c.69 0 1.25.56 1.25 1.25V8.5Zm-9 6.5h-6v1.5h6V15Zm7.25 2.19 1.97-1.97 1.06 1.06-1.97 1.97 1.97 1.97-1.06 1.06-1.97-1.97-1.97 1.97-1.06-1.06 1.97-1.97-1.97-1.97 1.06-1.06 1.97 1.97Z"/></svg>      <svg aria-hidden="true" focusable="false" width="24" height="24" viewbox="0 0 24 24">&gt;<path fill-rule="evenodd" clip-rule="evenodd" d="M6.5 2a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5Zm-1 2.5a1 1 0 1 1 2 0 1 1 0 0 1-2 0Z"/><path d="M3.5 16.5v-7h6v7H11V9.25C11 8.56 10.44 8 9.75 8h-6.5C2.56 8 2 8.56 2 9.25v7.25h1.5Z"/><path d="M4.5 22v-7.5H6V22H4.5ZM7 14.5V22h1.5v-7.5H7Zm8.826-5-1.851 6.943-1.45-.386 1.901-7.13A1.25 1.25 0 0 1 15.634 8h3.732c.566 0 1.062.38 1.208.928l1.9 7.129-1.449.386L19.174 9.5h-3.348Z"/><path fill-rule="evenodd" clip-rule="evenodd" d="M17.5 2a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5Zm-1 2.5a1 1 0 1 1 2 0 1 1 0 0 1-2 0Z"/><path d="M15.5 22v-7.5H17V22h-1.5Zm2.5-7.5V22h1.5v-7.5H18Z"/></svg>    </div>    <div class="me-watermark">      <p>Activate Windows</p>      <p>Go to Settings to activate Windows.</p>    </div>    <div class="me-statusbar">      <dl>        <div>          <dt>Syntax errors:</dt>          <dd>3453</dd>        </div>        <div>          <dt>CI warnings:</dt>          <dd>6462</dd>        </div>        <div>          <dt>Merge conflicts:</dt>          <dd>1130</dd>        </div>        <div>          <dt>Tokens maxxed:</dt>          <dd>9512</dd>        </div>        <div>          <dt>Logged in as:</dt>          <dd data-ignore>ghp_nD7FQLmQlmaoRis27Lq2C69HWTFwsU420CvL</dd>        </div>      </dl>    </div>    <div class="me-sidebar">      <p>Fix the bug and make no mistake</p>      <p>The user has asked me to fix his shitty code and to “make no mistake”… is he stupid?</p>      <p>Thinking…</p>      <p>Thinking harder…</p>      <p>On second review his code is garbage slop, should I search the internet and plagiarise ZA̡͊͠͝LGΌ ISͮ̂ TO͇̹̺ͅƝ̴ȳ̳ TH̘Ë͖́̉ ͠P̯͍̭O̚​N̐Y̡ H̸̡̪̯ͨ͊̽̅̾̎Ȩ̬̩̾͛ͪ̈́̀́͘ ̶̧̨̱̹̭̯ͧ̾ͬC̷̙̲̝͖ͭ̏ͥͮ͟Oͮ͏̮̪̝͍M̲̖͊̒ͪͩͬ̚̚͜Ȇ̴̟̟͙̞ͩ͌͝S̨̥̫͎̭ͯ̿̔̀ͅ</p>      <p>        <svg aria-hidden="true" focusable="false" width="24" height="24" viewbox="0 0 24 24"><path d="M14 10h5.75c.69 0 1.25-.56 1.25-1.25V3h-1.5v4.03A8.976 8.976 0 0 0 12 3c-4.96 0-9 4.04-9 9s4.04 9 9 9a9.012 9.012 0 0 0 8.695-6.67l-1.45-.39A7.513 7.513 0 0 1 12 19.5c-4.135 0-7.5-3.365-7.5-7.5S7.865 4.5 12 4.5c2.805 0 5.34 1.55 6.635 4H14V10Z"/></svg>        Thinking…</p>    </div>    <div class="me-clippy">      <p>Would you like to play a game?</p>    </div>    <ul class="me-toaster" popover="manual">      <li>Running NPM post-install scripts.</li>      <li>Claude is not in the sudoers file. This incident will be reported.</li>      <li>Windows will restart in 5 minutes.</li>      <li>Production database was dropped.</li>      <li>GitHub connection timed out.</li>      <li>Incoming phone call from your mother.</li>      <li>CI/CD deployment failed again.</li>      <li><svg aria-hidden="true" focusable="false" width="24" height="24" viewbox="0 0 24 24"><path d="M14 10h5.75c.69 0 1.25-.56 1.25-1.25V3h-1.5v4.03A8.976 8.976 0 0 0 12 3c-4.96 0-9 4.04-9 9s4.04 9 9 9a9.012 9.012 0 0 0 8.695-6.67l-1.45-.39A7.513 7.513 0 0 1 12 19.5c-4.135 0-7.5-3.365-7.5-7.5S7.865 4.5 12 4.5c2.805 0 5.34 1.55 6.635 4H14V10Z"/></svg> Thinking…</li>      <li>Family photos were deleted to resolve low disk space error.</li>      <li>iOS 26.6.9 is available, update now?</li>      <li>Amazon driver is lost in your neighbourhood.</li>      <li>Alice’s personal access token expired, switching to Bob’s.</li>      <li>Tailwind language server crashed.</li>      <li>SAMSUNG SMART REFRIDGERATOR ® has detected low milk levels: five gallons ordered.</li>      <li>418 I’m a teapot.</li>    </ul>    <div class="me-changelog" popover="manual">      <button type="button">        <svg aria-hidden="true" focusable="false" width="24" height="24" viewbox="0 0 24 24"><path d="m20.28 4.78-1.06-1.06L12 10.94 4.78 3.72 3.72 4.78 10.94 12l-7.22 7.22 1.06 1.06L12 13.06l7.22 7.22 1.06-1.06L13.06 12l7.22-7.22Z"/></svg>        <span class="hidden">close</span>      </button>      <h2><b>v0.419 Release Notes</b></h2>      <p>AI, AI, AI! We’ve heard you. There are now 26 new sparkle buttons! Can you find them all?</p>      <p>Release notes dialog now has an embedded WSL 1.0 terminal emulator. It’s broken (issue: #25293).</p>      <p>Reduced RAM usage when typing on the home row.</p>      <p>Keystrokes are now logged in the correct Slack channel (fixes #7 and #933 through #980).</p>      <p>        <span><span>root@localhost</span> <span>system32</span> <span>C:\</span></span>        <span><span>$</span><span>_</span></span>      </p>    </div>  </div></modern-editor><h2 id="ahhhhh">Ahhhhh!</h2><p>Yeah so um… have you noticed that all modern software is teetering on the enshitty cliff? Everything in my dock is an <a href="https://www.electronjs.org/" rel="noopener noreferrer" target="_blank">Electron-ified</a> enshittybomb one update from disaster. There used to be alternatives. Now those suck too.</p><p>I don’t want to collaborate. How about you leave me alone and I’ll email you the file when I’m finished? Here, take a hard copy and jog on. You want to comment? I don’t remember asking for an opinion. Oh fantastic, now the computer thinks it’s people! I’ve got dialogs and popovers all up in my face yammering about agentic bollocks. Mystery icons everywhere. Wait… did they move my cheese? Ahhhhh!</p><p>It’s all your fault! I sure as heck didn’t ask for it. Remember when they made entire video games on a 32 KB floppy disk? Those were real developers.</p><blockquote><p>v1 Release Notes: done.</p></blockquote><p>Can you stop adding new “features”, please? You had <em>one</em> good idea. Finish it already? Now you’ve got ten thousand GitHub issues. Well done.</p><p>I used to enjoy making things on a computer :(</p><hr/><p><small>Icons used: <a href="https://griddyicons.com/" rel="noopener noreferrer" target="_blank">Griddy Icons</a> MIT License. “Clippy” © Microsoft (this is parody).</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>ARIA, anti-patterns, and you</title>
  <description>Please take a minute to understand what ARIA is and is not. ARIA and especially the ARIA Authoring Practices Guide (APG) are commonly misunderstood. I read an article the other day that had this facepalm moment: “And with modern LLM agents, turning a spec into working code is surprisingly fast. […]</description>
  <link>https://dbushell.com/2026/06/26/aria-anti-patterns-and-you/</link>
  <guid isPermaLink="true">https://dbushell.com/2026/06/26/aria-anti-patterns-and-you/</guid>
  <pubDate>Fri, 26 Jun 2026 15:00:00 GMT</pubDate>
  <content:encoded><![CDATA[<p>Please take a minute to understand what <a href="https://www.w3.org/WAI/standards-guidelines/aria/" rel="noopener noreferrer" target="_blank">ARIA</a> is and is not. ARIA and especially the <a href="https://www.w3.org/WAI/ARIA/apg/" rel="noopener noreferrer" target="_blank">ARIA Authoring Practices Guide (APG)</a> are commonly misunderstood.</p><p>I read an article <a href="https://dbushell.com/notes/2026-06-24T05:31Z/">the other day</a> that had this facepalm moment:</p><blockquote><p>And with modern LLM agents, turning a spec into working code is surprisingly fast. Point the agent at the APG pattern, describe your component’s markup, and get a solid first draft you can refine and test.</p></blockquote><p>This is worrying, and the use of “LLM agents” isn’t the worst part!</p><p>The APG is <strong>not</strong> a how-to guide of ‘best practices’ for building accessible websites. It exists to demonstrate how the ARIA specification should work in theory — regardless of support and regardless of whether more accessible, non-ARIA patterns exist (they do).</p><p>As Eric Bailey notes —</p><blockquote><p>The guide was originally authored to help demonstrate ARIA’s capabilities. As a result, its code examples near-exclusively, overwhelmingly, and disproportionately favor ARIA.</p><p><cite><a href="https://www.smashingmagazine.com/2025/06/what-i-wish-someone-told-me-aria/#the-downsides" rel="noopener noreferrer" target="_blank">What I Wish Someone Told Me When I Was Getting Into ARIA</a> - Eric Bailey</cite></p></blockquote><p>— which makes sense, because:</p><blockquote><p>Browser and assistive technology developers can thus utilize code in this guide to help assess the quality of their support for ARIA 1.2.</p><p><cite><a href="https://www.w3.org/WAI/ARIA/apg/practices/read-me-first/#:~:text=Except%20in%20cases,for%20ARIA%201.2." rel="noopener noreferrer" target="_blank">Read Me First</a> - ARIA Authoring Practices Guide (APG)</cite></p></blockquote><p>Even if ARIA was fully supported (<a href="https://a11ysupport.io/" rel="noopener noreferrer" target="_blank">it’s not</a>) the APG still wouldn’t be a ‘best practice’ guide. ‘Best practice’ is not using ARIA at all.</p><blockquote><p>If you can use a native HTML element or attribute with the semantics and behavior you require <strong>already built in</strong>, instead of re-purposing an element and adding an ARIA role, state or property to make it accessible, <strong>then do so</strong>.</p><p><cite><a href="https://www.w3.org/TR/using-aria/#rule1" rel="noopener noreferrer" target="_blank">2.1 First Rule of ARIA Use</a> - Using ARIA, W3C</cite></p></blockquote><p>APG exists in a vacuum to show off the ARIA spec.</p><p>The <a href="https://www.w3.org/WAI/ARIA/apg/patterns/button/examples/button/" rel="noopener noreferrer" target="_blank">button example</a> includes this code, for crying out loud!</p><pre data-lang="html" tabindex="0" id="pre-39909e61"><code><span class="line"><span class="syntax-26f6a8db">&#x3C;</span><span class="syntax-1656d967">div</span><span class="space"> </span><span class="syntax-4ddd3d58">tabindex</span><span class="syntax-1656d967">=</span><span class="syntax-6168685d">"</span><span class="syntax-e661ac3e">0</span><span class="syntax-6168685d">"</span></span>
<span class="line"><span class="space"> </span><span class="space"> </span><span class="space"> </span><span class="space"> </span><span class="space"> </span><span class="syntax-4ddd3d58">role</span><span class="syntax-1656d967">=</span><span class="syntax-6168685d">"</span><span class="syntax-e661ac3e">button</span><span class="syntax-6168685d">"</span></span>
<span class="line"><span class="space"> </span><span class="space"> </span><span class="space"> </span><span class="space"> </span><span class="space"> </span><span class="syntax-4ddd3d58">id</span><span class="syntax-1656d967">=</span><span class="syntax-6168685d">"</span><span class="syntax-e661ac3e">action</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">Print</span><span class="space"> </span><span class="syntax-26f6a8db">Page</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’m unaware of any circumstance where <code>&lt;div role=&quot;button&quot;&gt;</code> should ever be used over a <code>&lt;button&gt;</code>. Before you tell me you can’t edit your <glossary-term id="--term-react"><a href="https://jsx.lol/" rel="noopener noreferrer" target="_blank">React</a></glossary-term> component library, do the web a favour and delete your codebase.</p><p>In fairness, the button example has a <a href="https://www.w3.org/WAI/ARIA/apg/patterns/button/examples/button/#support-notice-header" rel="noopener noreferrer" target="_blank">“Read This First”</a> disclosure — and guess what: they use a <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/details" rel="noopener noreferrer" target="_blank"><code>&lt;details&gt;</code> element</a> and not the <a href="https://www.w3.org/WAI/ARIA/apg/patterns/disclosure/" rel="noopener noreferrer" target="_blank">disclosure pattern</a> because the APG isn’t best practice. It’s hard to blame developers for misusing ARIA and the APG. I’ve been confused myself. As W3C documentation goes, APG is rather sexy. It’s a useful resource if you understand why it exists.</p><p>Misuse of ARIA has made the web less accessible.</p><blockquote><p>Increased ARIA usage on pages was associated with higher detected errors. The more ARIA attributes that were present, the more detected accessibility errors could be expected.</p><p><cite><a href="https://webaim.org/projects/million/#aria" rel="noopener noreferrer" target="_blank">The WebAIM Million</a> - WebAIM</cite></p></blockquote><h2 id="tldr">TL;DR</h2><p>Avoid ARIA where ever possible. Don’t point a freaking LLM at the APG! I can’t believe I’m saying this but use <a href="https://dbushell.com/2026/05/20/google-just-spat-in-my-face/">Google’s slop</a> if you absolutely refuse to learn/code yourself. Apparently <a href="https://adrianroselli.com/2025/10/openai-aria-and-seo-making-the-web-worse.html" rel="noopener noreferrer" target="_blank">OpenAI is throwing ARIA</a> at the web and seeing what sticks. Ahhh! I don’t know anymore, take some pride in your expertise?</p><hr/><p>P.S. name an assistive technology that isn’t a screen reader.</p><p>Ain’t easy, is it? So don’t be casually punctuating with the word “test” like it’s some <em>get-out-of-jail-free </em>card for your dubious practice and advice.</p><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 a great help if you want to win this game at parties.</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>Life is too short for lowercase ASCII</title>
  <description>CSS is hard and it should be hard. For good reason: “CSS isn’t just a complex language, it’s one of the most advanced graphics, layout, and typesetting languages available in computing. The deskilling of web dev is harming the product but, more importantly, it’s damaging our health – this is why […]</description>
  <link>https://dbushell.com/2026/06/19/css-methodology/</link>
  <guid isPermaLink="true">https://dbushell.com/2026/06/19/css-methodology/</guid>
  <pubDate>Fri, 19 Jun 2026 15:00:00 GMT</pubDate>
  <content:encoded><![CDATA[<p>CSS is hard and it <em>should</em> be hard. For good reason:</p><blockquote><p>CSS isn’t just a complex language, it’s one of the most advanced graphics, layout, and typesetting languages available in computing.</p><p><cite><a href="https://www.baldurbjarnason.com/2024/the-deskilling-of-web-dev-is-harming-us-all/" rel="noopener noreferrer" target="_blank">The deskilling of web dev is harming the product but, more importantly, it’s damaging our health – this is why burnout happens</a> - Baldur Bjarnason</cite></p></blockquote><p>Hard isn’t a negative label. You know what else is hard? Applying <a href="https://en.wikipedia.org/wiki/Silicone_rubber" rel="noopener noreferrer" target="_blank">silicone sealant</a> to waterproof bathroom fixtures. It’s hard enough that such expertise are worthy of a profession. Regardless, I decide it should be easy. I made a proper mess and my hands are now hydrophobic. Seriously, any tips applying this gunk?</p><p>CSS is deceptively hard as a whole despite many of the constitute parts being simple. CSS syntax is simple (mostly). CSS properties and values are simple (<a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Reference" rel="noopener noreferrer" target="_blank">to lookup</a>). What is hard is deciding how to organise styles. What we like to call: <strong>CSS methodology.</strong></p><h2 id="methodology">Methodology</h2><p>Every developer has their own preferred methodology. Over the years we’ve seen many notable examples published — <a href="https://smacss.com/" rel="noopener noreferrer" target="_blank">SMACSS</a>, <a href="https://github.com/stubbornella/oocss/wiki" rel="noopener noreferrer" target="_blank">OOCSS</a>, <a href="https://getbem.com/" rel="noopener noreferrer" target="_blank">BEM</a>, <a href="https://csswizardry.com/2018/11/itcss-and-skillshare/" rel="noopener noreferrer" target="_blank">ITCSS</a>, <a href="https://cube.fyi/" rel="noopener noreferrer" target="_blank">CUBE</a> — to name a few. These methodologies have several things in common:</p><ul><li>Naming conventions</li><li>Modular composition</li><li>Cascade management</li><li>Controlled specificity</li></ul><p>The CSS spec does not dictate methodology. You are left to bring order to chaos. The correct methodology is the one that you and your team can adhere to.</p><aside class="Alert"><p><strong>Caveat:</strong> the only wrong CSS methodology is “CSS-in-JS” — fight me.</p></aside><p>Historically, I’ve used a basic BEM-like naming convention. I prefer flat specificity and a logical order to match the design hierarchy. I think component-first and avoid getting too <a href="https://en.wikipedia.org/wiki/Don%27t_repeat_yourself" rel="noopener noreferrer" target="_blank">DRY</a> because I can’t control who is going try their hand at styling later.</p><p>Modern CSS is moving too fast to settle on one methodology. <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Guides/Cascading_variables/Using_custom_properties" rel="noopener noreferrer" target="_blank">Custom properties</a> allow <a href="https://www.alwaystwisted.com/articles/a-design-tokens-workflow-part-1" rel="noopener noreferrer" target="_blank">design tokens</a> to be part of the system. <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Guides/Containment/Container_queries" rel="noopener noreferrer" target="_blank"><code>@container</code></a> and <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/At-rules/@scope" rel="noopener noreferrer" target="_blank"><code>@scope</code></a> rules add a new depth to encapsulation. <a href="https://css-tricks.com/css-cascade-layers/" rel="noopener noreferrer" target="_blank">Cascade layers</a> and the unassuming <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Selectors/:where" rel="noopener noreferrer" target="_blank"><code>:where</code> pseudo-class</a> have all but nullified specificity wars.</p><p>As CSS gets more complex, I dare say CSS is actually getting <em>easier</em> (for a professional).</p><p>Strict methodological conventions become less important when the laws they impose can be safeguarded by the code itself. That frees us to explore more adventurous and less rigorous styles. Safe in the knowledge that any mess is more readily contained. CSS technical debt is a cheaper commodity. Some kind of CSS methodology is still necessary but breaking the rules is not the headache it used to be. Gnarly selectors are not the <a href="https://dbushell.com/notes/2026-04-01T13:51Z/">bane of my existence</a> anymore.</p><h2 id="behold">Behold!</h2><p>Now this is the point where you’re expecting me to announce my brand new CSS methodology with a trendy domain and a ten part TikTok series. Maybe a few practical code examples to backup my bold claims?</p><p>You’re going to be very disappointed. That is not this post.</p><p>I just think it’s neat to <strong>capitalise</strong> component class names like they’re proper nouns.</p><pre data-lang="html" tabindex="0" id="pre-e4893529"><code><span class="line"><span class="syntax-26f6a8db">&#x3C;</span><span class="syntax-1656d967">article</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">Post</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="syntax-26f6a8db">>Hello,</span><span class="space"> </span><span class="syntax-26f6a8db">world!&#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">article</span><span class="syntax-26f6a8db">></span></span>
<span class="line"><span class="syntax-7b4433fd">&#x3C;!--/Post--></span></span></code></pre><p>Isn’t that fun? I find it adds clarity to a component’s scope. I even add an HTML comment after the closing tag so that source-spelunkers don’t get lost.</p><p>I do plan to write a more groundbreaking thesis on CSS one day. The world is not ready for my radical ideas yet and I’ve got a bathroom to finish redecorating.</p><hr/><p>Interesting tidbit from the original CSS level 1 specification (emphasis mine).</p><blockquote><p>CSS gives so much power to the CLASS attribute, that in many cases it doesn’t even matter what HTML element the class is set on -- you can make any element emulate almost any other. Relying on this power is <strong>not recommended,</strong> since it removes the level of structure that has a universal meaning (HTML elements). A structure based on CLASS is only useful within a restricted domain, where the meaning of a class has been mutually agreed upon.</p><p><cite><a href="https://www.w3.org/TR/CSS1/#class-as-selector" rel="noopener noreferrer" target="_blank">1.4 Class as selector</a> - Cascading Style Sheets, level 1</cite></p></blockquote><p><code>class</code> considered harmful!</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 #008: Duck duck, swan?</title>
  <description>This is an RSS-only post, thank you for subscribing :) If you’re only here for web and tech talk you can skip this one! I rescued an animal today! Probably… The UK has its fair share of canals. I like canals. They cut through urban life offering an escape back to nature and are teaming with […]</description>
  <link>https://dbushell.com/2026/06/13/RSS008/</link>
  <guid isPermaLink="true">https://dbushell.com/2026/06/13/RSS008/</guid>
  <pubDate>Sat, 13 Jun 2026 15:00:00 GMT</pubDate>
  <content:encoded><![CDATA[<p>This is an RSS-only post, thank you for subscribing :) If you’re only here for web and tech talk you can skip this one!</p><p>I rescued an animal today! Probably…</p><p>The UK has its fair share of canals. I like canals. They cut through urban life offering an escape back to nature and are teaming with wildlife.</p><p>Canal towpaths are perfect for running. They’re easy underfoot — until late spring when the goslings hatch and then I’m doing a ballet to avoid trouble. Canada goose are the most visible bird living here all year round. They gather in groups and are rather docile around humans until the little yellow fluffballs arrive and then it’s mayhem.</p><p>Mute swans are a less common sight on the routes I run. This year a pair chose to nest in a safe but visible spot which was wonderful to witness. Swan nests are huge mounds of dirt, twigs, and coke bottles, apparently.</p><figure class="Image"><img src="https://dbushell.com/images/blog/2026/RSS008-1.avif" alt="Mute swan nest with both parents and cygnets in the reeds behind the canal water." width="750" height="405" decoding="async" fetchpriority="low" loading="lazy" id="--img-d13b9297"/><figcaption>Sorry for the bad iPhone 12 photography.</figcaption></figure><p>This morning I found dad-swan charging back and forth across the water. He stopped to peer into an overflow trench around 2–3 feet deep aside the canal. As I ran closer I saw a young bird has fallen in. It was older than a fluffball but still covered in muddied down. Larger than a duck, for scale. It was still too young to  fly out of its predicament. At first I thought it was one of the cygnets. Mum-swan was in the nest with the others not far away.</p><figure class="Image"><img src="https://dbushell.com/images/blog/2026/RSS008-2.avif" alt="Canal overflow trench below the water level." width="750" height="412" decoding="async" fetchpriority="low" loading="lazy" id="--img-429f0cc0"/><figcaption>Scene of the drama. It’s a little deeper than it looks.</figcaption></figure><p>I don’t speak bird but dad-swan seemed more aggressive than concerned. As I got closer he paddled a short distance away to observe.</p><p>I went down on my stomach and slowly reach under the guard rails wondering how painful a finger-pecking would be. I kept my ears open for a charge attack. The young bird didn’t flinch. It allowed me to reach under its belly and lift it up.</p><p>Before I could place it safely on the ground it attempted a Loony Tunes escape by running in the air. This unbalanced and forced me to tip it sideways, thankfully onto the stones just below water level and not back into the trench. It then frantically hopped not into the water, but up onto the towpath and quickly waddled behind me into the grass.</p><p>As I got back to my feet dad-swan returned to investigate and looked satisfied the young bird was gone before returning to his nest. It took me a minute to find the young bird now resting deep in the brambles. It was only then did I realise this might not be a swan but a goose. It was large enough to have outgrown the distinct yellow colouring.</p><p>I left it where it was hiding. My presence would only cause further distress. It was not physically injured otherwise I might have called the <a href="https://www.rspca.org.uk/" rel="noopener noreferrer" target="_blank">RSPCA</a> who can rescue wildlife (<a href="https://www.rspb.org.uk/" rel="noopener noreferrer" target="_blank">RSPB</a> don’t; common misconception).</p><p>I don’t go running with my phone anyway so I returned later to check and take photos. The young bird had vanished from its hiding spot. I’m almost certain it was a goose now after seeing this family not far from the scene.</p><figure class="Image"><img src="https://dbushell.com/images/blog/2026/RSS008-3.avif" alt="Canada goose parents with two goslings on the grass aside the canal." width="750" height="375" decoding="async" fetchpriority="low" loading="lazy" id="--img-3b0e8f75"/><figcaption>Was it one of you two?</figcaption></figure><p>It’s funny, despite being so common I’ve never once seen an actual goose nest. I’ve no idea where they hide them.</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>Apple deepfakes</title>
  <description>Apple’s WWDC 2026 keynote was a snoozefest but one section left me rather perplexed. Early in the show Apple gave a performance about “child safety”. Apple ended the show with their new AI photo mangler. That’s some serious cognitive dissonance! […]</description>
  <link>https://dbushell.com/2026/06/12/apple-deepfakes/</link>
  <guid isPermaLink="true">https://dbushell.com/2026/06/12/apple-deepfakes/</guid>
  <pubDate>Fri, 12 Jun 2026 15:00:00 GMT</pubDate>
  <content:encoded><![CDATA[<p>Apple’s <a href="https://developer.apple.com/videos/play/wwdc2026/101/" rel="noopener noreferrer" target="_blank">WWDC 2026 keynote</a> was a snoozefest but one section left me rather perplexed. Early in the show Apple gave a performance about <a href="https://www.apple.com/child-safety/" rel="noopener noreferrer" target="_blank">“child safety”</a>. Apple ended the show with their new <a href="https://www.theverge.com/tech/946850/apple-ai-photo-editing-tools-ios27-wwdc-2026-deepfakes" rel="noopener noreferrer" target="_blank">AI photo mangler</a>.</p><p>That’s some serious cognitive dissonance!</p><p><em>404 Media</em> recently reported on <a href="https://www.404media.co/radnor-high-school-pennsylvania-ai-deepfakes-child-sexual-abuse-material/" rel="noopener noreferrer" target="_blank">“How Deepfakes Tore a High School Apart”</a>. Kids are using <a href="https://www.bbc.co.uk/news/topics/crm5plqk980t" rel="noopener noreferrer" target="_blank">deepfake</a> apps (from Apple’s App Store) to victimise their classmates. Adults are doing it too, of course. Deepfakes on demand are a cornerstone of <a href="https://www.bbc.co.uk/news/articles/cwy875j28k0o" rel="noopener noreferrer" target="_blank">new <del>Twitter</del></a>.</p><p>Apple front-loaded the keynote with a <em>“we care about children”</em> narrative that the media and fanboys lapped up. Then they advertised features that are suspiciously at odds (if you stop to think). It was a shrewd marketing stunt they’ve pulled before. In past events Apple has greenwashed the opening spiel before flogging a new iPhone model with an annual upgrade plan. Don’t worry, it’s all recycled. Totally eco-friendly to ship mass-produced luxury goods around the world to meet a manufactured demand. I’m sure Apple-branded slop will be harmless too, I remember someone telling me they care about this stuff.</p><h2 id="non-consent">Non-consent</h2><p>I’ve written about <a href="https://dbushell.com/2026/01/22/proton-spam/">AI’s consent problem</a> in more trivial context before. The AI industry simply cannot take “no” for an answer. You <em>will</em> use it. You <em>will</em> suffer it. You <em>will</em> be a victim.</p><p>Jared White makes a point on this topic:</p><blockquote><p>I don’t know about y’all, but I think it should be <em>illegal</em> to generate slop imagery of other people without their consent.</p><p>Apple really fell down hard on this feature (and I’ve been hearing other podcasters saying the exact same thing). I hope they come to their senses and realize the “ick” isn’t worth a flashy keynote demo.</p><p><cite><a href="https://indieweb.social/@jaredwhite/116729917769860541" rel="noopener noreferrer" target="_blank">@jaredwhite@indieweb.social</a> - Mastodon</cite></p></blockquote><p>At the very least I implore the ‘court of public opinion’ to vilify generative AI. It’s seriously creepy, and not just the uncanny valley aesthetic.</p><p>Jared makes a stronger point on the <a href="https://vibe.coded.show/16" rel="noopener noreferrer" target="_blank">Vibe Coded podcast</a>. What happens when someone deepfakes a person with a disability that wasn’t visible in the original photo? Good chance it’ll erase their disability. That ain’t okay. That might be traumatic for some people.</p><p>But sure, Photoshop exists. We must accept that new technology can be misused, right? Seriously, whole lotta money riding on this! <a href="https://dbushell.com/2026/04/28/alternative-thoughts/#its-just-a-tool">It’s just a tool.</a></p><p>AI apologists are quick to abandon all moral and common sense for the most mediocre slop. Whether or not Apple’s own app is capable of anything doesn’t matter. Its presence will only help to normalise the dehumanising efforts of the AI industry.</p><p>This future sucks! They did fix those rounded corners on macOS though.</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>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>
  <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>
</channel>
</rss>
