<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet href="/rss/style.xsl" type="text/xsl"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>
    Notes | Stefan Judis Web Development
  </title>
  <subtitle>
    Cool stuff online
  </subtitle>
  <link href="https://www.stefanjudis.com/feeds/notes.xml" rel="self"/>
  <link href="https://www.stefanjudis.com/"/>
  <updated>
    2026-02-18T23:00:00+00:00
  </updated>
  <id>
    https://www.stefanjudis.com/
  </id>
  <author>
    <name>
      Stefan Judis
    </name>
    <email>
      stefanjudis@gmail.com
    </email>
  </author>
    
    <entry>
      <title>
        Notes on relying on the ARIA Authoring Practices Guide 
      </title>
      <link href="https://www.stefanjudis.com/notes/notes-on-relying-on-the-aria-authoring-practices-guide/"/>
      <published>2026-02-18T23:00:00+00:00</published>
      <updated>2026-02-18T23:00:00+00:00</updated>
      <id>
        https://www.stefanjudis.com/notes/notes-on-relying-on-the-aria-authoring-practices-guide/
      </id>
      <category term="note"></category>
        <category term="Accessibility"></category>
      
      <content type="html">
        <![CDATA[
          <div class="markdown"><p>Eric wrote about <a href="https://ericwbailey.website/published/heres-how-to-instruct-a-llm-to-reference-the-aria-authoring-practices-guide/" style="--image-url: url('https://avatar.stefanjudis.com/https%3A%2F%2Fericwbailey.website%2Fpublished%2Fheres-how-to-instruct-a-llm-to-reference-the-aria-authoring-practices-guide%2F')">how to instruct an LLM to fetch the &quot;valuable stuff&quot; from the ARIA Authoring Practices Guide (APG)</a>. The article includes some points about APG itself that are worth highlighting. And what's the valuable stuff?</p>
<p>If you don't know <a href="https://www.w3.org/WAI/ARIA/apg/" style="--image-url: url('https://avatar.stefanjudis.com/https%3A%2F%2Fwww.w3.org%2FWAI%2FARIA%2Fapg%2F')">the Authoring Practice Guide</a>, here's what you'll see after finding it online looking for ARIA patterns.</p>
<p>
      <div class="sqip-container margin-top-l margin-bottom-l">
        <figure class="sqip-image" style="
          --color1: rgb(227,210,98); --color2: rgb(109,126,153); --color3: rgb(132,163,202); --color4: rgb(176,188,206); --color5: rgb(63,74,101);
          --sqip-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMDAgMTQxIj48cGF0aCBmaWxsPSIjM2Y0YTY1IiBkPSJNMCAwaDMwMHYxNDFIMHoiLz48ZyBmaWxsLW9wYWNpdHk9Ii41IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSguNiAuNikgc2NhbGUoMS4xNzE4OCkiPjxlbGxpcHNlIGN4PSI5NyIgY3k9IjUiIGZpbGw9IiNmZmYiIHJ4PSIyNTUiIHJ5PSIxMCIvPjxlbGxpcHNlIGN4PSIxMTIiIGN5PSIxMTgiIGZpbGw9IiNmZmYiIHJ4PSIyNTUiIHJ5PSIxMCIvPjxjaXJjbGUgcj0iMSIgZmlsbD0iI2ZmZiIgdHJhbnNmb3JtPSJtYXRyaXgoLTcuMjgxOTcgNjcuOTczMjIgLTE3LjU0NjgyIC0xLjg3OTc5IDI1NSA1OC42KSIvPjxlbGxpcHNlIGN4PSIyIiBjeT0iNjIiIGZpbGw9IiNmZmYiIHJ4PSI4IiByeT0iMTIwIi8+PGVsbGlwc2UgY3g9IjEwOCIgY3k9IjQiIGZpbGw9IiNmZmYiIHJ4PSIyNTUiIHJ5PSIxMCIvPjxlbGxpcHNlIGN4PSI3NSIgY3k9IjExNSIgZmlsbD0iI2ZmZiIgcng9IjI1NSIgcnk9IjciLz48cGF0aCBmaWxsPSIjZmZmIiBkPSJNMjQgODRoMzV2MTJIMjR6Ii8+PHBhdGggZmlsbD0iIzAwMmM2YyIgZD0ibTQuMyAxMDcuNyAxNzcgMS44IDY1LjUtMi40LTE5LjMtNjJ6Ii8+PC9nPjwvc3ZnPg==');
        ">
          <a href="//images.ctfassets.net/f20lfrunubsq/xGGpWkiudi4RXenbtEFo8/a5a8f6deca99777a8a57192cb5054318/Screenshot_2026-02-19_at_06.47.03.png">
            <picture>
              <source type="image/avif"
                srcset="//images.ctfassets.net/f20lfrunubsq/xGGpWkiudi4RXenbtEFo8/a5a8f6deca99777a8a57192cb5054318/Screenshot_2026-02-19_at_06.47.03.png?fm=avif&fit=scale&q=75&w=300&h=141 300w, //images.ctfassets.net/f20lfrunubsq/xGGpWkiudi4RXenbtEFo8/a5a8f6deca99777a8a57192cb5054318/Screenshot_2026-02-19_at_06.47.03.png?fm=avif&fit=scale&q=75&w=500&h=236 500w, //images.ctfassets.net/f20lfrunubsq/xGGpWkiudi4RXenbtEFo8/a5a8f6deca99777a8a57192cb5054318/Screenshot_2026-02-19_at_06.47.03.png?fm=avif&fit=scale&q=75&w=700&h=331 700w, //images.ctfassets.net/f20lfrunubsq/xGGpWkiudi4RXenbtEFo8/a5a8f6deca99777a8a57192cb5054318/Screenshot_2026-02-19_at_06.47.03.png?fm=avif&fit=scale&q=75&w=900&h=425 900w, //images.ctfassets.net/f20lfrunubsq/xGGpWkiudi4RXenbtEFo8/a5a8f6deca99777a8a57192cb5054318/Screenshot_2026-02-19_at_06.47.03.png?fm=avif&fit=scale&q=75&w=1100&h=520 1100w"
                sizes="(max-width: 50em) 98vw, 700px">
              <source type="image/webp"
                srcset="//images.ctfassets.net/f20lfrunubsq/xGGpWkiudi4RXenbtEFo8/a5a8f6deca99777a8a57192cb5054318/Screenshot_2026-02-19_at_06.47.03.png?fm=webp&fit=scale&q=75&w=300&h=141 300w, //images.ctfassets.net/f20lfrunubsq/xGGpWkiudi4RXenbtEFo8/a5a8f6deca99777a8a57192cb5054318/Screenshot_2026-02-19_at_06.47.03.png?fm=webp&fit=scale&q=75&w=500&h=236 500w, //images.ctfassets.net/f20lfrunubsq/xGGpWkiudi4RXenbtEFo8/a5a8f6deca99777a8a57192cb5054318/Screenshot_2026-02-19_at_06.47.03.png?fm=webp&fit=scale&q=75&w=700&h=331 700w, //images.ctfassets.net/f20lfrunubsq/xGGpWkiudi4RXenbtEFo8/a5a8f6deca99777a8a57192cb5054318/Screenshot_2026-02-19_at_06.47.03.png?fm=webp&fit=scale&q=75&w=900&h=425 900w, //images.ctfassets.net/f20lfrunubsq/xGGpWkiudi4RXenbtEFo8/a5a8f6deca99777a8a57192cb5054318/Screenshot_2026-02-19_at_06.47.03.png?fm=webp&fit=scale&q=75&w=1100&h=520 1100w"
                sizes="(max-width: 50em) 98vw, 700px">
              <img width="1000" height="473"
                srcset="//images.ctfassets.net/f20lfrunubsq/xGGpWkiudi4RXenbtEFo8/a5a8f6deca99777a8a57192cb5054318/Screenshot_2026-02-19_at_06.47.03.png?fm=jpg&fit=scale&q=75&w=300&h=141 300w, //images.ctfassets.net/f20lfrunubsq/xGGpWkiudi4RXenbtEFo8/a5a8f6deca99777a8a57192cb5054318/Screenshot_2026-02-19_at_06.47.03.png?fm=jpg&fit=scale&q=75&w=500&h=236 500w, //images.ctfassets.net/f20lfrunubsq/xGGpWkiudi4RXenbtEFo8/a5a8f6deca99777a8a57192cb5054318/Screenshot_2026-02-19_at_06.47.03.png?fm=jpg&fit=scale&q=75&w=700&h=331 700w, //images.ctfassets.net/f20lfrunubsq/xGGpWkiudi4RXenbtEFo8/a5a8f6deca99777a8a57192cb5054318/Screenshot_2026-02-19_at_06.47.03.png?fm=jpg&fit=scale&q=75&w=900&h=425 900w, //images.ctfassets.net/f20lfrunubsq/xGGpWkiudi4RXenbtEFo8/a5a8f6deca99777a8a57192cb5054318/Screenshot_2026-02-19_at_06.47.03.png?fm=jpg&fit=scale&q=75&w=1100&h=520 1100w"
                sizes="(max-width: 50em) 98vw, 700px"
                src="//images.ctfassets.net/f20lfrunubsq/xGGpWkiudi4RXenbtEFo8/a5a8f6deca99777a8a57192cb5054318/Screenshot_2026-02-19_at_06.47.03.png"
                alt="ARIA Authoring Practices Guide (APG) Home  Learn to use the accessibility semantics defined by the Accessible Rich Internet Application (ARIA) specification to create accessible web experiences. "
                loading="lazy"
                onload="this.classList.add('kf-fade-in')">
            </picture>
          </a>
        </figure>
      </div>
    </p>
<p>As you see above, the guide is supposed to teach how to use <em>accessibility semantics defined by the Accessible Rich Internet Application (ARIA)</em>. And it looks <strong>very</strong> authoritative. When I first discovered it after some googling, I treated this guide as the source of truth because it lives under <code>w3<wbr>.org</code> and looks very official. I learned early on that using ARIA correctly is hard; and thought that APG must be the place showing me how to do ARIA correctly.</p>
<p>It sort of is but not really.</p>
<p>Lately, I've seen many accessibility folks raise concerns about APG, and Eric's article echoes some of them.</p>
<blockquote>
<p>The APG was created to demonstrate ARIA's capabilities. Because of this, it disproportionately favors ARIA in its code examples.</p>
</blockquote>
<p>The guide is there to <strong>showcase</strong> ARIA usage patterns and if people want to showcase something they might overuse it at times. This is true for ARIA usage in the APG, too.</p>
<blockquote>
<p>The APG was also not created to serve as a pattern library, design system, or single source of truth for the &quot;right way&quot; to make something. Unfortunately, a lot of people treat it this way.</p>
</blockquote>
<p>I understand Eric's point, but I also can't blame people for treating the guide as &quot;the right way&quot;. The home page literally says that &quot;APG provides design patterns and functional examples&quot;. It's hosted on <code>w3<wbr>.org</code>. It looks very official. If there's a line between &quot;a collection of design patterns&quot; and a &quot;pattern library&quot; at all, it's a very thin one.</p>
<p>Of course people treat the Authoring Practice Guide as the right way to do things — when I discovered it, I did, too.</p>
<blockquote>
<p>Recall here that the original reason for APG code is to be a showpiece for how ARIA could hypothetically be used. Because of this, it is not the APG's concern that ARIA does not have perfect support.</p>
</blockquote>
<p>This is by far the biggest reason why I don't pretend to know when something is truly accessible. <strong>Nothing is ever fully accessible to everyone, and the world of assistive technology is huge.</strong> A single ARIA attribute might make things more accessible in theory, but who knows if it works across all browser-screen reader combinations.</p>
<p>The effort alone to verify that an ARIA pattern works well across assistive technologies is massive.</p>
<hr aria-hidden="true"><p>But what are the guide's valuable parts? Eric highlights the pattern names, &quot;about this pattern&quot; section and the keyboard interaction specification.</p>
<blockquote>
<p>The pattern names. Having a standardized way to refer to a discrete piece of UI that is larger than any one company is highly beneficial.</p>
</blockquote>
<blockquote>
<p>The content contained in the &quot;About This Pattern&quot; section. This is what the discrete piece of UI does, and how it goes about doing it.</p>
</blockquote>
<blockquote>
<p>The content contained in the &quot;Keyboard Interaction&quot; section. This is how people who use assistive technology will expect things to work.</p>
</blockquote>
<p>That's good to know!</p>
<hr aria-hidden="true"><p><strong>So if you've been treating APG as the definitive source of truth, think again.</strong> Its examples demonstrate <em>what ARIA can do</em>, not necessarily <em>what you should do</em>.</p>
<p>It doesn't matter if you've discovered the ARIA Authoring Practices Guide or not, before reaching for a complex ARIA pattern found on the internet, the usual rules apply:</p>
<ul>
<li>Always start with native HTML: the <a href="https://www.w3.org/TR/using-aria/#firstrule" style="--image-url: url('https://avatar.stefanjudis.com/https%3A%2F%2Fwww.w3.org%2FTR%2Fusing-aria%2F%23firstrule')">first rule of ARIA</a> is to use a native HTML element before adding ARIA. A <code>&lt;button&gt;</code> beats a <code>&lt;div role=&quot;button&quot;&gt;</code> every time regardless of what's written in a fancy ARIA guide or what your LLM claims to be accessible.</li>
<li>Test with assistive technology yourself: nothing beats firing up a screen reader and actually navigating your own UI. It's hard and time-consuming but you can't claim that something is accessible if you haven't tested it.</li>
<li>Follow practitioners who do the testing: as you might know, I'm a huge fan of <a href="https://adrianroselli.com/" style="--image-url: url('https://avatar.stefanjudis.com/https%3A%2F%2Fadrianroselli.com%2F')">Adrian Roselli</a> who constantly puts in the work of testing ARIA patterns with different assistive technology combination. He publishes findings on what actually works versus what the spec promises. Huge!</li>
</ul>
<p>Edit: Eric (partly responsible for the Authoring Practices Guide) shared on Mastodon <a href="https://yatil.social/@yatil/116096277826640376" style="--image-url: url('https://avatar.stefanjudis.com/https%3A%2F%2Fyatil.social%2F%40yatil%2F116096277826640376')">how the project evolved into what it is today</a>.</p>
</div>

          <a href="mailto:stefanjudis@gmail.com?subject=Re%3A%20Notes on relying on the ARIA Authoring Practices Guide ">
            Reply to Stefan
          </a>
        ]]>
      </content>
    </entry>
    
    <entry>
      <title>
        Clean up your Mac with open source
      </title>
      <link href="https://www.stefanjudis.com/notes/clean-up-your-mac-with-open-source/"/>
      <published>2026-01-12T23:00:00+00:00</published>
      <updated>2026-01-12T23:00:00+00:00</updated>
      <id>
        https://www.stefanjudis.com/notes/clean-up-your-mac-with-open-source/
      </id>
      <category term="note"></category>
        <category term="macOS"></category>
      
        <category term="Tools"></category>
      
      <content type="html">
        <![CDATA[
          <div class="markdown"><p>My Mac was running out of disk space the other day, and because I wasn't in the mood to hunt for custom solutions, I reached for <a href="https://cleanmymac.com/" style="--image-url: url('https://avatar.stefanjudis.com/https%3A%2F%2Fcleanmymac.com%2F')">Clean My Mac</a>. It's a nice tool, and I knew it would do the job just fine. It freed up 60GB in about twenty minutes. Nice! Cleaning up disk space without any hassle was worth paying for.</p>
<p>A couple of days later, Nick sent out his <a href="https://one-tip-a-week.beehiiv.com/" style="--image-url: url('https://avatar.stefanjudis.com/https%3A%2F%2Fone-tip-a-week.beehiiv.com%2F')">&quot;One tip a week&quot; newsletter</a>, and dang it... He shared <a href="https://github.com/tw93/Mole" style="--image-url: url('https://avatar.stefanjudis.com/https%3A%2F%2Fgithub.com%2Ftw93%2FMole')">Mole — a free open source CLI tool</a> that does the same thing as Clean My Mac. Too late, Nick. Too late.</p>
<p>
      <div class="sqip-container margin-top-l margin-bottom-l">
        <figure class="sqip-image" style="
          --color1: rgb(110.11363636363635,208.63636363636363,46.36363636363638); --color2: rgb(129,126,174); --color3: rgb(179.6590909090909,230.89090909090908,146.50909090909093); --color4: rgb(235,230,221); --color5: rgb(60,84,60);
          --sqip-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMDAgMTY3Ij48cGF0aCBmaWxsPSIjM2M1NDNjIiBkPSJNMCAwaDMwMHYxNjdIMHoiLz48Y2lyY2xlIHI9IjEiIGZpbGw9IiNmZmRmZGIiIGZpbGwtb3BhY2l0eT0iLjUiIHRyYW5zZm9ybT0ibWF0cml4KDE5LjMzODE4IDM3LjYyODAyIC0zNi4zNjU1NCAxOC42ODkzNSA1NSA1OS44KSIvPjxjaXJjbGUgcj0iMSIgZmlsbD0iIzBiMDAxOCIgZmlsbC1vcGFjaXR5PSIuNSIgdHJhbnNmb3JtPSJtYXRyaXgoLTExLjg4NTIyIDEwMi43MjA5NCAtMTQzLjI1NTc2IC0xNi41NzUyNiAyNTEgNjAuNykiLz48Y2lyY2xlIHI9IjEiIGZpbGwtb3BhY2l0eT0iLjUiIHRyYW5zZm9ybT0ibWF0cml4KDguMjMzMTUgLTE3LjIzODM4IDI5LjE0NTcyIDEzLjkyMDE3IDUzLjMgNTguOCkiLz48cGF0aCBmaWxsPSIjZmZmIiBmaWxsLW9wYWNpdHk9Ii41IiBkPSJNMTAwLjkgMzkuMiA5MC4zIDU3LjVsLTUxLjctMzBMNDkgOS40ek05MiA4Mi42bC00OS4yIDEzLTI0LjYtMjEuMnoiLz48cGF0aCBmaWxsPSIjYTFiMzllIiBmaWxsLW9wYWNpdHk9Ii41IiBkPSJNMTguMiAxNDYuNXYtMzEuN2g1MS41djMxLjd6Ii8+PHBhdGggZmlsbD0iI2ZmZiIgZmlsbC1vcGFjaXR5PSIuNSIgZD0iTTIzLjIgNzIuNyAzMyA2MS41IDE3LjggMzkuM2wtNiAyM3oiLz48cGF0aCBmaWxsPSIjNDMzYjQ1IiBmaWxsLW9wYWNpdHk9Ii41IiBkPSJtMTg1LjcgMTc4LjctMTY0LTgyIDI5Ni41LTd6Ii8+PC9zdmc+');
        ">
          <a href="//images.ctfassets.net/f20lfrunubsq/1KzqfZsAOOW23MkQGZEc4r/b683eb402d46807bbb05472d5de4a05d/Screenshot_2026-01-13_at_21.24.34.png">
            <picture>
              <source type="image/avif"
                srcset="//images.ctfassets.net/f20lfrunubsq/1KzqfZsAOOW23MkQGZEc4r/b683eb402d46807bbb05472d5de4a05d/Screenshot_2026-01-13_at_21.24.34.png?fm=avif&fit=scale&q=75&w=300&h=168 300w, //images.ctfassets.net/f20lfrunubsq/1KzqfZsAOOW23MkQGZEc4r/b683eb402d46807bbb05472d5de4a05d/Screenshot_2026-01-13_at_21.24.34.png?fm=avif&fit=scale&q=75&w=500&h=280 500w, //images.ctfassets.net/f20lfrunubsq/1KzqfZsAOOW23MkQGZEc4r/b683eb402d46807bbb05472d5de4a05d/Screenshot_2026-01-13_at_21.24.34.png?fm=avif&fit=scale&q=75&w=700&h=392 700w, //images.ctfassets.net/f20lfrunubsq/1KzqfZsAOOW23MkQGZEc4r/b683eb402d46807bbb05472d5de4a05d/Screenshot_2026-01-13_at_21.24.34.png?fm=avif&fit=scale&q=75&w=900&h=504 900w, //images.ctfassets.net/f20lfrunubsq/1KzqfZsAOOW23MkQGZEc4r/b683eb402d46807bbb05472d5de4a05d/Screenshot_2026-01-13_at_21.24.34.png?fm=avif&fit=scale&q=75&w=1100&h=616 1100w"
                sizes="(max-width: 50em) 98vw, 700px">
              <source type="image/webp"
                srcset="//images.ctfassets.net/f20lfrunubsq/1KzqfZsAOOW23MkQGZEc4r/b683eb402d46807bbb05472d5de4a05d/Screenshot_2026-01-13_at_21.24.34.png?fm=webp&fit=scale&q=75&w=300&h=168 300w, //images.ctfassets.net/f20lfrunubsq/1KzqfZsAOOW23MkQGZEc4r/b683eb402d46807bbb05472d5de4a05d/Screenshot_2026-01-13_at_21.24.34.png?fm=webp&fit=scale&q=75&w=500&h=280 500w, //images.ctfassets.net/f20lfrunubsq/1KzqfZsAOOW23MkQGZEc4r/b683eb402d46807bbb05472d5de4a05d/Screenshot_2026-01-13_at_21.24.34.png?fm=webp&fit=scale&q=75&w=700&h=392 700w, //images.ctfassets.net/f20lfrunubsq/1KzqfZsAOOW23MkQGZEc4r/b683eb402d46807bbb05472d5de4a05d/Screenshot_2026-01-13_at_21.24.34.png?fm=webp&fit=scale&q=75&w=900&h=504 900w, //images.ctfassets.net/f20lfrunubsq/1KzqfZsAOOW23MkQGZEc4r/b683eb402d46807bbb05472d5de4a05d/Screenshot_2026-01-13_at_21.24.34.png?fm=webp&fit=scale&q=75&w=1100&h=616 1100w"
                sizes="(max-width: 50em) 98vw, 700px">
              <img width="1000" height="560"
                srcset="//images.ctfassets.net/f20lfrunubsq/1KzqfZsAOOW23MkQGZEc4r/b683eb402d46807bbb05472d5de4a05d/Screenshot_2026-01-13_at_21.24.34.png?fm=jpg&fit=scale&q=75&w=300&h=168 300w, //images.ctfassets.net/f20lfrunubsq/1KzqfZsAOOW23MkQGZEc4r/b683eb402d46807bbb05472d5de4a05d/Screenshot_2026-01-13_at_21.24.34.png?fm=jpg&fit=scale&q=75&w=500&h=280 500w, //images.ctfassets.net/f20lfrunubsq/1KzqfZsAOOW23MkQGZEc4r/b683eb402d46807bbb05472d5de4a05d/Screenshot_2026-01-13_at_21.24.34.png?fm=jpg&fit=scale&q=75&w=700&h=392 700w, //images.ctfassets.net/f20lfrunubsq/1KzqfZsAOOW23MkQGZEc4r/b683eb402d46807bbb05472d5de4a05d/Screenshot_2026-01-13_at_21.24.34.png?fm=jpg&fit=scale&q=75&w=900&h=504 900w, //images.ctfassets.net/f20lfrunubsq/1KzqfZsAOOW23MkQGZEc4r/b683eb402d46807bbb05472d5de4a05d/Screenshot_2026-01-13_at_21.24.34.png?fm=jpg&fit=scale&q=75&w=1100&h=616 1100w"
                sizes="(max-width: 50em) 98vw, 700px"
                src="//images.ctfassets.net/f20lfrunubsq/1KzqfZsAOOW23MkQGZEc4r/b683eb402d46807bbb05472d5de4a05d/Screenshot_2026-01-13_at_21.24.34.png"
                alt="Mole — clean your mac."
                loading="lazy"
                onload="this.classList.add('kf-fade-in')">
            </picture>
          </a>
        </figure>
      </div>
    </p>
<p>I haven't tried it, but I trust Nick's judgment here. You might want to give it a try if you're running low on disk space.</p>
</div>

          <a href="mailto:stefanjudis@gmail.com?subject=Re%3A%20Clean up your Mac with open source">
            Reply to Stefan
          </a>
        ]]>
      </content>
    </entry>
    
    <entry>
      <title>
        The Trust Equation
      </title>
      <link href="https://www.stefanjudis.com/notes/the-trust-equation/"/>
      <published>2026-01-11T23:00:00+00:00</published>
      <updated>2026-01-11T23:00:00+00:00</updated>
      <id>
        https://www.stefanjudis.com/notes/the-trust-equation/
      </id>
      <category term="note"></category>
        <category term="People"></category>
      
        <category term="Shower thoughts"></category>
      
      <content type="html">
        <![CDATA[
          <div class="markdown"><p>How do you know that you can trust someone?</p>
<p>I struggle to answer this question objectively because trust feels like such a subjective matter. Some people just don't &quot;sit right with me,&quot; and that's okay. I also can't expect that I'm trusted and liked by everyone. That's okay, too.</p>
<p>But why is it so hard to explain why you trust someone or not?</p>
<p>Explaining feelings is hard for many, but I just discovered a helpful tool: <a href="https://www.designative.info/2025/06/02/book-review-trusted-advisor-david-maister-charles-green-robert-galford/" style="--image-url: url('https://avatar.stefanjudis.com/https%3A%2F%2Fwww.designative.info%2F2025%2F06%2F02%2Fbook-review-trusted-advisor-david-maister-charles-green-robert-galford%2F')">the trust equation</a>. The formula is like math for feelings — yay!</p>
<p>[Interactive component: visit the article to see it...]</p>
<div class="highlightBox info margin-top-xl margin-bottom-xl">
      
          <div class="cornerBubble">
            <svg aria-hidden="true">
              <use xlink:href="/sprite.svg#icon-info"/>
            </svg>
          </div>
        

      
      <p>One reason to blog about this was that I could use <a href="https://developer.mozilla.org/en-US/docs/Web/MathML" style="--image-url: url('https://avatar.stefanjudis.com/https%3A%2F%2Fdeveloper.mozilla.org%2Fen-US%2Fdocs%2FWeb%2FMathML')"><code>MathML</code></a> for the first time (check the source above). That's some funky markup isn't it?</p>
</div><p>Here's a direct quote from the post explaining what all the variables mean:</p>
<blockquote>
<p><strong>Credibility</strong>: What we say and the expertise we bring.</p>
<p><strong>Reliability</strong>: What we do consistently.</p>
<p><strong>Intimacy</strong>: How safe others feel sharing with us.</p>
<p><strong>Self-Orientation</strong>: How much we appear to be acting in our own interest (lower is better).</p>
</blockquote>
<p>Looking back at my own professional experience, this equation makes a ton of sense.</p>
<p>For me, the biggest kicker is reliability. I've worked with too many people promising the world while constantly failing to deliver. It drives me up the wall that overpromising is &quot;normal&quot; for some folks.</p>
<p>In close second place is self-orientation. I've also worked with the classic solo career climber and backstabber. It was clear that I was working with someone who had an agenda that didn't include me or the team. No fun, no trust.</p>
<p>Credibility and intimacy are also important, but not as important for me as the first two.</p>
<p>However, I guess the formula checks out, and I'll definitely come back to it when I need to evaluate why I don't trust someone.</p>
</div>

          <a href="mailto:stefanjudis@gmail.com?subject=Re%3A%20The Trust Equation">
            Reply to Stefan
          </a>
        ]]>
      </content>
    </entry>
    
    <entry>
      <title>
        Firefox DevTools hides unreferenced CSS variables
      </title>
      <link href="https://www.stefanjudis.com/notes/firefox-devtools-unreferenced-css-variables/"/>
      <published>2026-01-09T23:00:00+00:00</published>
      <updated>2026-01-09T23:00:00+00:00</updated>
      <id>
        https://www.stefanjudis.com/notes/firefox-devtools-unreferenced-css-variables/
      </id>
      <category term="note"></category>
        <category term="Firefox"></category>
      
        <category term="CSS"></category>
      
      <content type="html">
        <![CDATA[
          <div class="markdown"><p>Here's a quick and handy addition to the Firefox DevTools.</p>
<p>Whenever you debug CSS that's full of CSS variables, it becomes annoyingly hard to parse everything going on in the DevTools because the custom properties are cluttering <code>:root</code> or <code>*</code> or whatever.</p>
<p>
      <div class="sqip-container margin-top-l margin-bottom-l">
        <figure class="sqip-image" style="
          --color1: rgb(19,126,220); --color2: rgb(112,139,170); --color3: rgb(236,160,87); --color4: rgb(211,183,155); --color5: rgb(47,62,82);
          --sqip-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMDAgMjU3Ij48cGF0aCBmaWxsPSIjMmYzZTUyIiBkPSJNMCAwaDMwMHYyNTdIMHoiLz48ZyBmaWxsLW9wYWNpdHk9Ii41IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSguNiAuNikgc2NhbGUoMS4xNzE4OCkiPjxlbGxpcHNlIGN4PSI0MyIgY3k9Ijg2IiBmaWxsPSIjZmZmIiByeD0iMjkiIHJ5PSIxMTgiLz48ZWxsaXBzZSBjeD0iNDMiIGN5PSI5NSIgZmlsbD0iI2ZmZiIgcng9IjI4IiByeT0iODIiLz48ZWxsaXBzZSBjeD0iNTIiIGN5PSIzIiByeD0iMjU1IiByeT0iMTEiLz48cGF0aCBmaWxsPSIjMGIwZjFmIiBkPSJNMCAxNzVoMjU2djQ1SDB6Ii8+PGVsbGlwc2UgY3g9IjE2NyIgY3k9Ijk0IiBmaWxsPSIjMjkyNjIyIiByeD0iOTgiIHJ5PSIyMTkiLz48cGF0aCBmaWxsPSIjZmZmIiBkPSJNMTYgMTE5aDU0djU1SDE2em0xLTEwNGg1M3Y2MEgxN3oiLz48ZWxsaXBzZSBjeD0iNCIgY3k9IjEwMCIgZmlsbD0iIzAwMDAwYyIgcng9IjEyIiByeT0iMTQ3Ii8+PC9nPjwvc3ZnPg==');
        ">
          <a href="//images.ctfassets.net/f20lfrunubsq/XFm9r7Z1F2TMJk6SGY8C1/827f2e4c4a2dfa344339880609808ffd/inac-css.jpg">
            <picture>
              <source type="image/avif"
                srcset="//images.ctfassets.net/f20lfrunubsq/XFm9r7Z1F2TMJk6SGY8C1/827f2e4c4a2dfa344339880609808ffd/inac-css.jpg?fm=avif&fit=scale&q=75&w=300&h=258 300w, //images.ctfassets.net/f20lfrunubsq/XFm9r7Z1F2TMJk6SGY8C1/827f2e4c4a2dfa344339880609808ffd/inac-css.jpg?fm=avif&fit=scale&q=75&w=500&h=430 500w, //images.ctfassets.net/f20lfrunubsq/XFm9r7Z1F2TMJk6SGY8C1/827f2e4c4a2dfa344339880609808ffd/inac-css.jpg?fm=avif&fit=scale&q=75&w=700&h=602 700w, //images.ctfassets.net/f20lfrunubsq/XFm9r7Z1F2TMJk6SGY8C1/827f2e4c4a2dfa344339880609808ffd/inac-css.jpg?fm=avif&fit=scale&q=75&w=900&h=774 900w, //images.ctfassets.net/f20lfrunubsq/XFm9r7Z1F2TMJk6SGY8C1/827f2e4c4a2dfa344339880609808ffd/inac-css.jpg?fm=avif&fit=scale&q=75&w=1100&h=946 1100w"
                sizes="(max-width: 50em) 98vw, 700px">
              <source type="image/webp"
                srcset="//images.ctfassets.net/f20lfrunubsq/XFm9r7Z1F2TMJk6SGY8C1/827f2e4c4a2dfa344339880609808ffd/inac-css.jpg?fm=webp&fit=scale&q=75&w=300&h=258 300w, //images.ctfassets.net/f20lfrunubsq/XFm9r7Z1F2TMJk6SGY8C1/827f2e4c4a2dfa344339880609808ffd/inac-css.jpg?fm=webp&fit=scale&q=75&w=500&h=430 500w, //images.ctfassets.net/f20lfrunubsq/XFm9r7Z1F2TMJk6SGY8C1/827f2e4c4a2dfa344339880609808ffd/inac-css.jpg?fm=webp&fit=scale&q=75&w=700&h=602 700w, //images.ctfassets.net/f20lfrunubsq/XFm9r7Z1F2TMJk6SGY8C1/827f2e4c4a2dfa344339880609808ffd/inac-css.jpg?fm=webp&fit=scale&q=75&w=900&h=774 900w, //images.ctfassets.net/f20lfrunubsq/XFm9r7Z1F2TMJk6SGY8C1/827f2e4c4a2dfa344339880609808ffd/inac-css.jpg?fm=webp&fit=scale&q=75&w=1100&h=946 1100w"
                sizes="(max-width: 50em) 98vw, 700px">
              <img width="1000" height="860"
                srcset="//images.ctfassets.net/f20lfrunubsq/XFm9r7Z1F2TMJk6SGY8C1/827f2e4c4a2dfa344339880609808ffd/inac-css.jpg?fm=jpg&fit=scale&q=75&w=300&h=258 300w, //images.ctfassets.net/f20lfrunubsq/XFm9r7Z1F2TMJk6SGY8C1/827f2e4c4a2dfa344339880609808ffd/inac-css.jpg?fm=jpg&fit=scale&q=75&w=500&h=430 500w, //images.ctfassets.net/f20lfrunubsq/XFm9r7Z1F2TMJk6SGY8C1/827f2e4c4a2dfa344339880609808ffd/inac-css.jpg?fm=jpg&fit=scale&q=75&w=700&h=602 700w, //images.ctfassets.net/f20lfrunubsq/XFm9r7Z1F2TMJk6SGY8C1/827f2e4c4a2dfa344339880609808ffd/inac-css.jpg?fm=jpg&fit=scale&q=75&w=900&h=774 900w, //images.ctfassets.net/f20lfrunubsq/XFm9r7Z1F2TMJk6SGY8C1/827f2e4c4a2dfa344339880609808ffd/inac-css.jpg?fm=jpg&fit=scale&q=75&w=1100&h=946 1100w"
                sizes="(max-width: 50em) 98vw, 700px"
                src="//images.ctfassets.net/f20lfrunubsq/XFm9r7Z1F2TMJk6SGY8C1/827f2e4c4a2dfa344339880609808ffd/inac-css.jpg"
                alt="Chrome DevTools with open CSS panel showing tons of unused custom properties."
                loading="lazy"
                onload="this.classList.add('kf-fade-in')">
            </picture>
          </a>
        </figure>
      </div>
    </p>
<p>Firefox 145 (released Nov 11, 2025) now added a tiny adjustment that helps out massively.</p>
<p>
      <div class="sqip-container margin-top-l margin-bottom-l">
        <figure class="sqip-image" style="
          --color1: rgb(4,140,243); --color2: rgb(132,140,76); --color3: rgb(244,185,59); --color4: rgb(176,193,207); --color5: rgb(49,61,81);
          --sqip-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMDAgMjE3Ij48cGF0aCBmaWxsPSIjMzEzZDUxIiBkPSJNMCAwaDMwMHYyMTdIMHoiLz48ZyBmaWxsLW9wYWNpdHk9Ii41IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSguNiAuNikgc2NhbGUoMS4xNzE4OCkiPjxlbGxpcHNlIGN4PSI0NCIgY3k9Ijc0IiBmaWxsPSIjZmZmIiByeD0iMzYiIHJ5PSI2NyIvPjxlbGxpcHNlIGN4PSI0NCIgY3k9Ijc0IiBmaWxsPSIjZmZmIiByeD0iMzIiIHJ5PSI2NCIvPjxjaXJjbGUgcj0iMSIgZmlsbD0iIzEyMGYxMyIgdHJhbnNmb3JtPSJyb3RhdGUoLTMuNyAxNjEyLjkgLTMzMjguOCkgc2NhbGUoMTQxLjc2Njg2IDI0NS4yMjczOSkiLz48cGF0aCBmaWxsPSIjZmZmIiBkPSJNMTMgMTFoNjN2MTI0SDEzeiIvPjxwYXRoIGZpbGw9IiMwMDAwMTUiIGQ9Im0tMTYtLjEgMjg3IC43LTExNy45IDE0LjgtMTMxLjgtMS41eiIvPjxjaXJjbGUgcj0iMSIgZmlsbD0iIzBjMDAwZCIgdHJhbnNmb3JtPSJtYXRyaXgoLTQwLjc4ODMyIC02Ljc2NDU0IDUuNjAxNjYgLTMzLjc3NjQ4IDQ0LjkgMTY4LjgpIi8+PGVsbGlwc2UgY3g9IjIiIGN5PSI3NCIgZmlsbD0iIzAwMDAwNSIgcng9IjEwIiByeT0iMTY3Ii8+PHBhdGggZmlsbD0iIzZmOWRlZSIgZD0iTTgwIDQwaDUxdjEzSDgweiIvPjwvZz48L3N2Zz4=');
        ">
          <a href="//images.ctfassets.net/f20lfrunubsq/6Xy88dfG6YI4IotLZzcAZ8/c78286b1af4b0e86e7c5a6578e34f084/ff.jpg">
            <picture>
              <source type="image/avif"
                srcset="//images.ctfassets.net/f20lfrunubsq/6Xy88dfG6YI4IotLZzcAZ8/c78286b1af4b0e86e7c5a6578e34f084/ff.jpg?fm=avif&fit=scale&q=75&w=300&h=219 300w, //images.ctfassets.net/f20lfrunubsq/6Xy88dfG6YI4IotLZzcAZ8/c78286b1af4b0e86e7c5a6578e34f084/ff.jpg?fm=avif&fit=scale&q=75&w=500&h=365 500w, //images.ctfassets.net/f20lfrunubsq/6Xy88dfG6YI4IotLZzcAZ8/c78286b1af4b0e86e7c5a6578e34f084/ff.jpg?fm=avif&fit=scale&q=75&w=700&h=511 700w, //images.ctfassets.net/f20lfrunubsq/6Xy88dfG6YI4IotLZzcAZ8/c78286b1af4b0e86e7c5a6578e34f084/ff.jpg?fm=avif&fit=scale&q=75&w=900&h=657 900w, //images.ctfassets.net/f20lfrunubsq/6Xy88dfG6YI4IotLZzcAZ8/c78286b1af4b0e86e7c5a6578e34f084/ff.jpg?fm=avif&fit=scale&q=75&w=1100&h=803 1100w"
                sizes="(max-width: 50em) 98vw, 700px">
              <source type="image/webp"
                srcset="//images.ctfassets.net/f20lfrunubsq/6Xy88dfG6YI4IotLZzcAZ8/c78286b1af4b0e86e7c5a6578e34f084/ff.jpg?fm=webp&fit=scale&q=75&w=300&h=219 300w, //images.ctfassets.net/f20lfrunubsq/6Xy88dfG6YI4IotLZzcAZ8/c78286b1af4b0e86e7c5a6578e34f084/ff.jpg?fm=webp&fit=scale&q=75&w=500&h=365 500w, //images.ctfassets.net/f20lfrunubsq/6Xy88dfG6YI4IotLZzcAZ8/c78286b1af4b0e86e7c5a6578e34f084/ff.jpg?fm=webp&fit=scale&q=75&w=700&h=511 700w, //images.ctfassets.net/f20lfrunubsq/6Xy88dfG6YI4IotLZzcAZ8/c78286b1af4b0e86e7c5a6578e34f084/ff.jpg?fm=webp&fit=scale&q=75&w=900&h=657 900w, //images.ctfassets.net/f20lfrunubsq/6Xy88dfG6YI4IotLZzcAZ8/c78286b1af4b0e86e7c5a6578e34f084/ff.jpg?fm=webp&fit=scale&q=75&w=1100&h=803 1100w"
                sizes="(max-width: 50em) 98vw, 700px">
              <img width="1000" height="730"
                srcset="//images.ctfassets.net/f20lfrunubsq/6Xy88dfG6YI4IotLZzcAZ8/c78286b1af4b0e86e7c5a6578e34f084/ff.jpg?fm=jpg&fit=scale&q=75&w=300&h=219 300w, //images.ctfassets.net/f20lfrunubsq/6Xy88dfG6YI4IotLZzcAZ8/c78286b1af4b0e86e7c5a6578e34f084/ff.jpg?fm=jpg&fit=scale&q=75&w=500&h=365 500w, //images.ctfassets.net/f20lfrunubsq/6Xy88dfG6YI4IotLZzcAZ8/c78286b1af4b0e86e7c5a6578e34f084/ff.jpg?fm=jpg&fit=scale&q=75&w=700&h=511 700w, //images.ctfassets.net/f20lfrunubsq/6Xy88dfG6YI4IotLZzcAZ8/c78286b1af4b0e86e7c5a6578e34f084/ff.jpg?fm=jpg&fit=scale&q=75&w=900&h=657 900w, //images.ctfassets.net/f20lfrunubsq/6Xy88dfG6YI4IotLZzcAZ8/c78286b1af4b0e86e7c5a6578e34f084/ff.jpg?fm=jpg&fit=scale&q=75&w=1100&h=803 1100w"
                sizes="(max-width: 50em) 98vw, 700px"
                src="//images.ctfassets.net/f20lfrunubsq/6Xy88dfG6YI4IotLZzcAZ8/c78286b1af4b0e86e7c5a6578e34f084/ff.jpg"
                alt="Firefox DevTools hiding &quot;52 unused CSS properties&quot;."
                loading="lazy"
                onload="this.classList.add('kf-fade-in')">
            </picture>
          </a>
        </figure>
      </div>
    </p>
<p>Love it!</p>
</div>

          <a href="mailto:stefanjudis@gmail.com?subject=Re%3A%20Firefox DevTools hides unreferenced CSS variables">
            Reply to Stefan
          </a>
        ]]>
      </content>
    </entry>
    
    <entry>
      <title>
        If you don&#39;t care, I don&#39;t care...
      </title>
      <link href="https://www.stefanjudis.com/notes/if-you-dont-care-i-dont-care/"/>
      <published>2026-01-06T23:00:00+00:00</published>
      <updated>2026-01-06T23:00:00+00:00</updated>
      <id>
        https://www.stefanjudis.com/notes/if-you-dont-care-i-dont-care/
      </id>
      <category term="note"></category>
        <category term="Tools"></category>
      
      <content type="html">
        <![CDATA[
          <div class="markdown"><p>Jim is, as always, on point.</p>
<blockquote>
<p>My desire to give you constructive feedback is in direct correlation to your effort to care — about your communications, about what you ship, even about what you don't ship.</p>
</blockquote>
<p>Shipping something unfinished, half-assed or broken to &quot;gather feedback&quot; just won't do any good. There is a certain (and often obvious) level of quality that needs to be reached before asking for feedback. If laziness shows, nobody will care...</p>
</div>

          <a href="mailto:stefanjudis@gmail.com?subject=Re%3A%20If you don&#39;t care, I don&#39;t care...">
            Reply to Stefan
          </a>
        ]]>
      </content>
    </entry>
    
    <entry>
      <title>
        A ready-to-use diff component
      </title>
      <link href="https://www.stefanjudis.com/notes/a-ready-to-use-diff-component/"/>
      <published>2026-01-02T23:00:00+00:00</published>
      <updated>2026-01-02T23:00:00+00:00</updated>
      <id>
        https://www.stefanjudis.com/notes/a-ready-to-use-diff-component/
      </id>
      <category term="note"></category>
        <category term="Tools"></category>
      
      <content type="html">
        <![CDATA[
          <div class="markdown"><p>I just stumbled over this package: <a href="https://www.npmjs.com/package/@pierre/diffs" style="--image-url: url('https://avatar.stefanjudis.com/https%3A%2F%2Fwww.npmjs.com%2Fpackage%2F%40pierre%2Fdiffs')"><code>@pierre/diffs</code></a>.</p>
<blockquote>
<p><code>@pierre/diffs</code> is an open source diff and code rendering library. It's built on Shiki for syntax highlighting and theming, is super customizable, and comes packed with features.</p>
</blockquote>
<p>The package just hit <code>v1</code> and seems to be pretty new. <a href="https://diffs.com" style="--image-url: url('https://avatar.stefanjudis.com/https%3A%2F%2Fdiffs.com')">The docs</a> live on <code>diffs<wbr>.com</code> (no idea how one could snatch this domain in 2026) and it looks amazing.</p>
<p>
      <div class="sqip-container margin-top-l margin-bottom-l">
        <figure class="sqip-image" style="
          --color1: rgb(243,164,100); --color2: rgb(173,122,79); --color3: rgb(158,106,235); --color4: rgb(150,191,209); --color5: rgb(52,47,80);
          --sqip-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMDAgMTg4Ij48cGF0aCBmaWxsPSIjMzQyZjUwIiBkPSJNMCAwaDMwMHYxODhIMHoiLz48ZyBmaWxsLW9wYWNpdHk9Ii41IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSguNiAuNikgc2NhbGUoMS4xNzE4OCkiPjxlbGxpcHNlIGN4PSIxMjUiIGN5PSI4IiBmaWxsPSIjZmZmIiByeD0iMjU1IiByeT0iMTYiLz48ZWxsaXBzZSBjeD0iMTMzIiBjeT0iMTU3IiBmaWxsPSIjZmZmIiByeD0iMjU1IiByeT0iNyIvPjxlbGxpcHNlIGN4PSIyIiBjeT0iNjIiIGZpbGw9IiNmZmYiIHJ4PSI5IiByeT0iMTYwIi8+PGVsbGlwc2UgY3g9IjI1MiIgY3k9IjgwIiBmaWxsPSIjZmZmIiByeD0iNyIgcnk9IjE1NyIvPjxlbGxpcHNlIGN4PSIxMTEiIGN5PSI5IiBmaWxsPSIjZmZmIiByeD0iMjU1IiByeT0iMTQiLz48Y2lyY2xlIHI9IjEiIHRyYW5zZm9ybT0ibWF0cml4KC03NC40MTg2MyAtMzUuMDE4NzUgMjMuNTgyNTcgLTUwLjExNTUyIDg3LjcgODMuNikiLz48cGF0aCBmaWxsPSIjMDAwYzAwIiBkPSJtMTYxLjMgMjUgODItMi45IDMuNCA5Ny04MiAyLjh6Ii8+PGVsbGlwc2UgY3g9IjExNiIgY3k9IjE1OCIgZmlsbD0iI2ZmZiIgcng9IjI1NSIgcnk9IjgiLz48L2c+PC9zdmc+');
        ">
          <a href="//images.ctfassets.net/f20lfrunubsq/4R5BUqZIMxOniy7LOh7uqJ/0fd1f7771fe1b7b90743e05bec331026/Screenshot_2026-01-03_at_12.08.00.png">
            <picture>
              <source type="image/avif"
                srcset="//images.ctfassets.net/f20lfrunubsq/4R5BUqZIMxOniy7LOh7uqJ/0fd1f7771fe1b7b90743e05bec331026/Screenshot_2026-01-03_at_12.08.00.png?fm=avif&fit=scale&q=75&w=300&h=189 300w, //images.ctfassets.net/f20lfrunubsq/4R5BUqZIMxOniy7LOh7uqJ/0fd1f7771fe1b7b90743e05bec331026/Screenshot_2026-01-03_at_12.08.00.png?fm=avif&fit=scale&q=75&w=500&h=315 500w, //images.ctfassets.net/f20lfrunubsq/4R5BUqZIMxOniy7LOh7uqJ/0fd1f7771fe1b7b90743e05bec331026/Screenshot_2026-01-03_at_12.08.00.png?fm=avif&fit=scale&q=75&w=700&h=441 700w, //images.ctfassets.net/f20lfrunubsq/4R5BUqZIMxOniy7LOh7uqJ/0fd1f7771fe1b7b90743e05bec331026/Screenshot_2026-01-03_at_12.08.00.png?fm=avif&fit=scale&q=75&w=900&h=567 900w, //images.ctfassets.net/f20lfrunubsq/4R5BUqZIMxOniy7LOh7uqJ/0fd1f7771fe1b7b90743e05bec331026/Screenshot_2026-01-03_at_12.08.00.png?fm=avif&fit=scale&q=75&w=1100&h=693 1100w"
                sizes="(max-width: 50em) 98vw, 700px">
              <source type="image/webp"
                srcset="//images.ctfassets.net/f20lfrunubsq/4R5BUqZIMxOniy7LOh7uqJ/0fd1f7771fe1b7b90743e05bec331026/Screenshot_2026-01-03_at_12.08.00.png?fm=webp&fit=scale&q=75&w=300&h=189 300w, //images.ctfassets.net/f20lfrunubsq/4R5BUqZIMxOniy7LOh7uqJ/0fd1f7771fe1b7b90743e05bec331026/Screenshot_2026-01-03_at_12.08.00.png?fm=webp&fit=scale&q=75&w=500&h=315 500w, //images.ctfassets.net/f20lfrunubsq/4R5BUqZIMxOniy7LOh7uqJ/0fd1f7771fe1b7b90743e05bec331026/Screenshot_2026-01-03_at_12.08.00.png?fm=webp&fit=scale&q=75&w=700&h=441 700w, //images.ctfassets.net/f20lfrunubsq/4R5BUqZIMxOniy7LOh7uqJ/0fd1f7771fe1b7b90743e05bec331026/Screenshot_2026-01-03_at_12.08.00.png?fm=webp&fit=scale&q=75&w=900&h=567 900w, //images.ctfassets.net/f20lfrunubsq/4R5BUqZIMxOniy7LOh7uqJ/0fd1f7771fe1b7b90743e05bec331026/Screenshot_2026-01-03_at_12.08.00.png?fm=webp&fit=scale&q=75&w=1100&h=693 1100w"
                sizes="(max-width: 50em) 98vw, 700px">
              <img width="1000" height="630"
                srcset="//images.ctfassets.net/f20lfrunubsq/4R5BUqZIMxOniy7LOh7uqJ/0fd1f7771fe1b7b90743e05bec331026/Screenshot_2026-01-03_at_12.08.00.png?fm=jpg&fit=scale&q=75&w=300&h=189 300w, //images.ctfassets.net/f20lfrunubsq/4R5BUqZIMxOniy7LOh7uqJ/0fd1f7771fe1b7b90743e05bec331026/Screenshot_2026-01-03_at_12.08.00.png?fm=jpg&fit=scale&q=75&w=500&h=315 500w, //images.ctfassets.net/f20lfrunubsq/4R5BUqZIMxOniy7LOh7uqJ/0fd1f7771fe1b7b90743e05bec331026/Screenshot_2026-01-03_at_12.08.00.png?fm=jpg&fit=scale&q=75&w=700&h=441 700w, //images.ctfassets.net/f20lfrunubsq/4R5BUqZIMxOniy7LOh7uqJ/0fd1f7771fe1b7b90743e05bec331026/Screenshot_2026-01-03_at_12.08.00.png?fm=jpg&fit=scale&q=75&w=900&h=567 900w, //images.ctfassets.net/f20lfrunubsq/4R5BUqZIMxOniy7LOh7uqJ/0fd1f7771fe1b7b90743e05bec331026/Screenshot_2026-01-03_at_12.08.00.png?fm=jpg&fit=scale&q=75&w=1100&h=693 1100w"
                sizes="(max-width: 50em) 98vw, 700px"
                src="//images.ctfassets.net/f20lfrunubsq/4R5BUqZIMxOniy7LOh7uqJ/0fd1f7771fe1b7b90743e05bec331026/Screenshot_2026-01-03_at_12.08.00.png"
                alt="Diff interface with several controls."
                loading="lazy"
                onload="this.classList.add('kf-fade-in')">
            </picture>
          </a>
        </figure>
      </div>
    </p>
<p>It comes as a React and Vanilla JS component, supports server-side rendering, and the configuration options look solid.</p>
<p>Disclaimer: I haven't tried <code>diffs</code> but I can imagine that I will take it as a starter for this blog eventually.</p>
</div>

          <a href="mailto:stefanjudis@gmail.com?subject=Re%3A%20A ready-to-use diff component">
            Reply to Stefan
          </a>
        ]]>
      </content>
    </entry>
    
    <entry>
      <title>
        Simon Willison on delivering AI generated code
      </title>
      <link href="https://www.stefanjudis.com/notes/simon-willison-on-delivering-ai-generated-code/"/>
      <published>2025-12-18T23:00:00+00:00</published>
      <updated>2025-12-18T23:00:00+00:00</updated>
      <id>
        https://www.stefanjudis.com/notes/simon-willison-on-delivering-ai-generated-code/
      </id>
      <category term="note"></category>
        <category term="AI"></category>
      
      <content type="html">
        <![CDATA[
          <div class="markdown"><p>Simon Willison published <a href="https://simonwillison.net/2025/Dec/18/code-proven-to-work/" style="--image-url: url('https://avatar.stefanjudis.com/https%3A%2F%2Fsimonwillison.net%2F2025%2FDec%2F18%2Fcode-proven-to-work%2F')">&quot;Your job is to deliver code you have proven to work&quot;</a>.</p>
<p>It frustrates me that the developer community is at a point in which posts like this need to be written, but let me share some highlights.</p>
<blockquote>
<p>[Coworkers submitting huge untested PRs is] a dereliction of duty as a software developer.</p>
</blockquote>
<p><em>A dereliction of duty as a software developer</em>...</p>
<p>When I got into tech, nerds were proud to be nerds. People were excited about creating things with nothing but their ideas and a computer. Everyone in my community was excited to put in the work and we all celebrated the results. I loved it!</p>
<p>The pride and excitement in crafting something seems to be vanishing. AI enthusiasts question doing the actual work, and &quot;Can't AI do this?&quot; is one of 2025's most annoying questions.</p>
<p>Where did the pride in doing the work or becoming an expert go?</p>
<p>Tech workers (myself included) had a good run the last 15 years because we cared and built up expertise. Should we now really expect to make the same living with some prose prompting that everyone can learn in a couple of weeks? I really doubt it.</p>
<p>We call ourselves engineers; let's celebrate the craft, be excited about our own ideas, and put in the work to create software.</p>
<blockquote>
<p>Your job is to deliver code you have proven to work. [...] Not doing that directly shifts the burden of the actual work to whoever is expected to review our code.</p>
</blockquote>
<p>Every reckless AI submission can take someone else hours to deal with. Throwing unreviewed AI Slop onto someone else's table is careless and tells more about you than you think. Don't do it.</p>
<p>If AI did your part in five minutes, it rarely means that the work is done.</p>
<blockquote>
<p>A computer can never be held accountable. That's your job as the human in the loop.</p>
</blockquote>
<p>Claude won't get fired for your buggy pull request. Just saying...</p>
</div>

          <a href="mailto:stefanjudis@gmail.com?subject=Re%3A%20Simon Willison on delivering AI generated code">
            Reply to Stefan
          </a>
        ]]>
      </content>
    </entry>
    
    <entry>
      <title>
        Syntax-highlighting for JS template strings in VS Code
      </title>
      <link href="https://www.stefanjudis.com/notes/syntax-highlighted-template-strings-vs-code/"/>
      <published>2025-11-14T23:00:00+00:00</published>
      <updated>2025-11-14T23:00:00+00:00</updated>
      <id>
        https://www.stefanjudis.com/notes/syntax-highlighted-template-strings-vs-code/
      </id>
      <category term="note"></category>
        <category term="VSCode"></category>
      
      <content type="html">
        <![CDATA[
          <div class="markdown"><p>Here's <a href="https://remysharp.com/2025/11/12/syntax-highlighting-in-web-component-templates" style="--image-url: url('https://avatar.stefanjudis.com/https%3A%2F%2Fremysharp.com%2F2025%2F11%2F12%2Fsyntax-highlighting-in-web-component-templates')">Remy sharing how to enable template string syntax highlighting via JavaScript comments</a>.</p>
<p>The problem of unhighlighted template strings never really bugged me. I write many of this blog's interactive components without proper syntax highlighting, because I've built myself a custom mini <a href="https://astro.build/" style="--image-url: url('https://avatar.stefanjudis.com/https%3A%2F%2Fastro.build%2F')">Astro</a> framework. And of course, like many homegrown solutions, it lacks a good developer experience. Missing syntax highlighting was never an issue, though, and things are fine.</p>
<p>However, now that I've read Remy's post, why not make things a little nicer to look at?</p>
<p>
      <div class="sqip-container margin-top-l margin-bottom-l">
        <figure class="sqip-image" style="
          --color1: rgb(184,127,207); --color2: rgb(164,94,130); --color3: rgb(164,196,132); --color4: rgb(148,178,121); --color5: rgb(52,68,100);
          --sqip-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMDAgMTM5Ij48cGF0aCBmaWxsPSIjMzQ0NDY0IiBkPSJNMCAwaDMwMHYxMzlIMHoiLz48ZyBmaWxsLW9wYWNpdHk9Ii41IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSguNiAuNikgc2NhbGUoMS4xNzE4OCkiPjxjaXJjbGUgY3g9IjE2NiIgY3k9IjQ1IiByPSIyMDkiIGZpbGw9IiMyMjFiMDgiLz48Y2lyY2xlIHI9IjEiIGZpbGw9IiM0MTRiNDgiIHRyYW5zZm9ybT0ibWF0cml4KDM5Ljc4OTgxIDIzLjE1ODIyIC05LjkzMTY3IDE3LjA2NDMxIDU0LjQgMzIpIi8+PGNpcmNsZSByPSIxIiBmaWxsPSIjM2Q0YjQwIiB0cmFuc2Zvcm09Im1hdHJpeCgzNC4yMDg3NCAyMC45NDE0IC0xMy4xNTkyNSAyMS40OTYyMyA2Ny4yIDEwOCkiLz48cGF0aCBmaWxsPSIjOGU2Nzk2IiBkPSJNMTAgMTBoNDl2NEgxMHoiLz48cGF0aCBmaWxsPSIjNjE3OTU2IiBkPSJNMzQgOTBoNzV2NEgzNHoiLz48cGF0aCBmaWxsPSIjNTM2ODRjIiBkPSJNMTMuOCA1MC45IDQ1IDUzLjFsNjguOC44LS4zLTQuMnoiLz48Y2lyY2xlIGN4PSIyMDQiIGN5PSI2OCIgcj0iOTMiIGZpbGw9IiMyNTI5MzIiLz48ZWxsaXBzZSBjeD0iNjciIGN5PSIxMTIiIGZpbGw9IiM1YjcxNTMiIHJ4PSIzNyIgcnk9IjIiLz48L2c+PC9zdmc+');
        ">
          <a href="//images.ctfassets.net/f20lfrunubsq/1vnaqqFTc2CAVJxgvOhwMO/0f425c781564a6dc6d413f36d52f323b/Screenshot_2025-11-15_at_10.18.32.png">
            <picture>
              <source type="image/avif"
                srcset="//images.ctfassets.net/f20lfrunubsq/1vnaqqFTc2CAVJxgvOhwMO/0f425c781564a6dc6d413f36d52f323b/Screenshot_2025-11-15_at_10.18.32.png?fm=avif&fit=scale&q=75&w=300&h=139 300w, //images.ctfassets.net/f20lfrunubsq/1vnaqqFTc2CAVJxgvOhwMO/0f425c781564a6dc6d413f36d52f323b/Screenshot_2025-11-15_at_10.18.32.png?fm=avif&fit=scale&q=75&w=500&h=233 500w, //images.ctfassets.net/f20lfrunubsq/1vnaqqFTc2CAVJxgvOhwMO/0f425c781564a6dc6d413f36d52f323b/Screenshot_2025-11-15_at_10.18.32.png?fm=avif&fit=scale&q=75&w=700&h=326 700w, //images.ctfassets.net/f20lfrunubsq/1vnaqqFTc2CAVJxgvOhwMO/0f425c781564a6dc6d413f36d52f323b/Screenshot_2025-11-15_at_10.18.32.png?fm=avif&fit=scale&q=75&w=900&h=419 900w, //images.ctfassets.net/f20lfrunubsq/1vnaqqFTc2CAVJxgvOhwMO/0f425c781564a6dc6d413f36d52f323b/Screenshot_2025-11-15_at_10.18.32.png?fm=avif&fit=scale&q=75&w=1100&h=513 1100w"
                sizes="(max-width: 50em) 98vw, 700px">
              <source type="image/webp"
                srcset="//images.ctfassets.net/f20lfrunubsq/1vnaqqFTc2CAVJxgvOhwMO/0f425c781564a6dc6d413f36d52f323b/Screenshot_2025-11-15_at_10.18.32.png?fm=webp&fit=scale&q=75&w=300&h=139 300w, //images.ctfassets.net/f20lfrunubsq/1vnaqqFTc2CAVJxgvOhwMO/0f425c781564a6dc6d413f36d52f323b/Screenshot_2025-11-15_at_10.18.32.png?fm=webp&fit=scale&q=75&w=500&h=233 500w, //images.ctfassets.net/f20lfrunubsq/1vnaqqFTc2CAVJxgvOhwMO/0f425c781564a6dc6d413f36d52f323b/Screenshot_2025-11-15_at_10.18.32.png?fm=webp&fit=scale&q=75&w=700&h=326 700w, //images.ctfassets.net/f20lfrunubsq/1vnaqqFTc2CAVJxgvOhwMO/0f425c781564a6dc6d413f36d52f323b/Screenshot_2025-11-15_at_10.18.32.png?fm=webp&fit=scale&q=75&w=900&h=419 900w, //images.ctfassets.net/f20lfrunubsq/1vnaqqFTc2CAVJxgvOhwMO/0f425c781564a6dc6d413f36d52f323b/Screenshot_2025-11-15_at_10.18.32.png?fm=webp&fit=scale&q=75&w=1100&h=513 1100w"
                sizes="(max-width: 50em) 98vw, 700px">
              <img width="1000" height="466"
                srcset="//images.ctfassets.net/f20lfrunubsq/1vnaqqFTc2CAVJxgvOhwMO/0f425c781564a6dc6d413f36d52f323b/Screenshot_2025-11-15_at_10.18.32.png?fm=jpg&fit=scale&q=75&w=300&h=139 300w, //images.ctfassets.net/f20lfrunubsq/1vnaqqFTc2CAVJxgvOhwMO/0f425c781564a6dc6d413f36d52f323b/Screenshot_2025-11-15_at_10.18.32.png?fm=jpg&fit=scale&q=75&w=500&h=233 500w, //images.ctfassets.net/f20lfrunubsq/1vnaqqFTc2CAVJxgvOhwMO/0f425c781564a6dc6d413f36d52f323b/Screenshot_2025-11-15_at_10.18.32.png?fm=jpg&fit=scale&q=75&w=700&h=326 700w, //images.ctfassets.net/f20lfrunubsq/1vnaqqFTc2CAVJxgvOhwMO/0f425c781564a6dc6d413f36d52f323b/Screenshot_2025-11-15_at_10.18.32.png?fm=jpg&fit=scale&q=75&w=900&h=419 900w, //images.ctfassets.net/f20lfrunubsq/1vnaqqFTc2CAVJxgvOhwMO/0f425c781564a6dc6d413f36d52f323b/Screenshot_2025-11-15_at_10.18.32.png?fm=jpg&fit=scale&q=75&w=1100&h=513 1100w"
                sizes="(max-width: 50em) 98vw, 700px"
                src="//images.ctfassets.net/f20lfrunubsq/1vnaqqFTc2CAVJxgvOhwMO/0f425c781564a6dc6d413f36d52f323b/Screenshot_2025-11-15_at_10.18.32.png"
                alt="A template string without syntax highlighting applied to a `styles` variable"
                loading="lazy"
                onload="this.classList.add('kf-fade-in')">
            </picture>
          </a>
        </figure>
      </div>
    </p>
<p>Remy describes that when using the right JS comments, Prettier and the VS Code formatter will work together to format and syntax-highlight the template string content.</p>
<p>Unfortunately, that didn't work in VS Code and I had to install two additional VS Code extensions:</p>
<ul>
<li><a href="https://marketplace.visualstudio.com/items?itemName=bashmish.es6-string-css" style="--image-url: url('https://avatar.stefanjudis.com/https%3A%2F%2Fmarketplace.visualstudio.com%2Fitems%3FitemName%3Dbashmish.es6-string-css')">es6-string-css</a></li>
<li><a href="https://marketplace.visualstudio.com/items?itemName=Tobermory.es6-string-html" style="--image-url: url('https://avatar.stefanjudis.com/https%3A%2F%2Fmarketplace.visualstudio.com%2Fitems%3FitemName%3DTobermory.es6-string-html')">es6-string-html</a></li>
</ul>
<p>But now I can use <code>/* CSS */</code> to get some template string CSS highlighting.</p>
<p>
      <div class="sqip-container margin-top-l margin-bottom-l">
        <figure class="sqip-image" style="
          --color1: rgb(114,171,233); --color2: rgb(92,132,172); --color3: rgb(218,187,124); --color4: rgb(172,179,188); --color5: rgb(52,68,100);
          --sqip-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMDAgMTQxIj48cGF0aCBmaWxsPSIjMzQ0NDY0IiBkPSJNMCAwaDMwMHYxNDFIMHoiLz48ZyBmaWxsLW9wYWNpdHk9Ii41IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSguNiAuNikgc2NhbGUoMS4xNzE4OCkiPjxjaXJjbGUgY3g9IjEzNyIgY3k9IjUyIiByPSIxODIiIGZpbGw9IiMyMTFhMGEiLz48Y2lyY2xlIHI9IjEiIGZpbGw9IiM0MTQ0NGIiIHRyYW5zZm9ybT0ibWF0cml4KDEyLjY2MTcyIC0xNi4zNDEyNCA0MS45NTE3MyAzMi41MDU1NiA0My44IDIwLjIpIi8+PHBhdGggZmlsbD0iIzNkNDY0OCIgZD0ibTkyLjcgNzMuNCAxLjUgNDMtNjMgMi4yLTEuNC00M3oiLz48cGF0aCBmaWxsPSIjN2Q2MDg3IiBkPSJNNSA3aDQ4djVINXoiLz48ZWxsaXBzZSBjeD0iNzEiIGN5PSI0OCIgZmlsbD0iIzUwNTk1NiIgcng9IjQ0IiByeT0iMyIvPjxwYXRoIGZpbGw9IiMzOTdhODQiIGQ9Ik0yOCAzN2gyOHY0SDI4eiIvPjxwYXRoIGZpbGw9IiM3ZDVlNDgiIGQ9Ik03MCA4NGgzNHY1SDcweiIvPjxjaXJjbGUgY3g9IjE5OSIgY3k9IjY1IiByPSI5NyIgZmlsbD0iIzI2MjkzMSIvPjwvZz48L3N2Zz4=');
        ">
          <a href="//images.ctfassets.net/f20lfrunubsq/BQ831jxBYzRuejYi8MqAv/e88f6d501aebe736a160f8dc069ebf5f/Screenshot_2025-11-15_at_10.28.38.png">
            <picture>
              <source type="image/avif"
                srcset="//images.ctfassets.net/f20lfrunubsq/BQ831jxBYzRuejYi8MqAv/e88f6d501aebe736a160f8dc069ebf5f/Screenshot_2025-11-15_at_10.28.38.png?fm=avif&fit=scale&q=75&w=300&h=141 300w, //images.ctfassets.net/f20lfrunubsq/BQ831jxBYzRuejYi8MqAv/e88f6d501aebe736a160f8dc069ebf5f/Screenshot_2025-11-15_at_10.28.38.png?fm=avif&fit=scale&q=75&w=500&h=236 500w, //images.ctfassets.net/f20lfrunubsq/BQ831jxBYzRuejYi8MqAv/e88f6d501aebe736a160f8dc069ebf5f/Screenshot_2025-11-15_at_10.28.38.png?fm=avif&fit=scale&q=75&w=700&h=331 700w, //images.ctfassets.net/f20lfrunubsq/BQ831jxBYzRuejYi8MqAv/e88f6d501aebe736a160f8dc069ebf5f/Screenshot_2025-11-15_at_10.28.38.png?fm=avif&fit=scale&q=75&w=900&h=425 900w, //images.ctfassets.net/f20lfrunubsq/BQ831jxBYzRuejYi8MqAv/e88f6d501aebe736a160f8dc069ebf5f/Screenshot_2025-11-15_at_10.28.38.png?fm=avif&fit=scale&q=75&w=1100&h=520 1100w"
                sizes="(max-width: 50em) 98vw, 700px">
              <source type="image/webp"
                srcset="//images.ctfassets.net/f20lfrunubsq/BQ831jxBYzRuejYi8MqAv/e88f6d501aebe736a160f8dc069ebf5f/Screenshot_2025-11-15_at_10.28.38.png?fm=webp&fit=scale&q=75&w=300&h=141 300w, //images.ctfassets.net/f20lfrunubsq/BQ831jxBYzRuejYi8MqAv/e88f6d501aebe736a160f8dc069ebf5f/Screenshot_2025-11-15_at_10.28.38.png?fm=webp&fit=scale&q=75&w=500&h=236 500w, //images.ctfassets.net/f20lfrunubsq/BQ831jxBYzRuejYi8MqAv/e88f6d501aebe736a160f8dc069ebf5f/Screenshot_2025-11-15_at_10.28.38.png?fm=webp&fit=scale&q=75&w=700&h=331 700w, //images.ctfassets.net/f20lfrunubsq/BQ831jxBYzRuejYi8MqAv/e88f6d501aebe736a160f8dc069ebf5f/Screenshot_2025-11-15_at_10.28.38.png?fm=webp&fit=scale&q=75&w=900&h=425 900w, //images.ctfassets.net/f20lfrunubsq/BQ831jxBYzRuejYi8MqAv/e88f6d501aebe736a160f8dc069ebf5f/Screenshot_2025-11-15_at_10.28.38.png?fm=webp&fit=scale&q=75&w=1100&h=520 1100w"
                sizes="(max-width: 50em) 98vw, 700px">
              <img width="1000" height="473"
                srcset="//images.ctfassets.net/f20lfrunubsq/BQ831jxBYzRuejYi8MqAv/e88f6d501aebe736a160f8dc069ebf5f/Screenshot_2025-11-15_at_10.28.38.png?fm=jpg&fit=scale&q=75&w=300&h=141 300w, //images.ctfassets.net/f20lfrunubsq/BQ831jxBYzRuejYi8MqAv/e88f6d501aebe736a160f8dc069ebf5f/Screenshot_2025-11-15_at_10.28.38.png?fm=jpg&fit=scale&q=75&w=500&h=236 500w, //images.ctfassets.net/f20lfrunubsq/BQ831jxBYzRuejYi8MqAv/e88f6d501aebe736a160f8dc069ebf5f/Screenshot_2025-11-15_at_10.28.38.png?fm=jpg&fit=scale&q=75&w=700&h=331 700w, //images.ctfassets.net/f20lfrunubsq/BQ831jxBYzRuejYi8MqAv/e88f6d501aebe736a160f8dc069ebf5f/Screenshot_2025-11-15_at_10.28.38.png?fm=jpg&fit=scale&q=75&w=900&h=425 900w, //images.ctfassets.net/f20lfrunubsq/BQ831jxBYzRuejYi8MqAv/e88f6d501aebe736a160f8dc069ebf5f/Screenshot_2025-11-15_at_10.28.38.png?fm=jpg&fit=scale&q=75&w=1100&h=520 1100w"
                sizes="(max-width: 50em) 98vw, 700px"
                src="//images.ctfassets.net/f20lfrunubsq/BQ831jxBYzRuejYi8MqAv/e88f6d501aebe736a160f8dc069ebf5f/Screenshot_2025-11-15_at_10.28.38.png"
                alt="Template string with syntax highlighting assigned to a `styles` variable"
                loading="lazy"
                onload="this.classList.add('kf-fade-in')">
            </picture>
          </a>
        </figure>
      </div>
    </p>
<p>And if I use HTML in template strings, it'll be highlighted and <strong>even formatted via Prettier</strong>.</p>
<p>
      <div class="sqip-container margin-top-l margin-bottom-l">
        <figure class="sqip-image" style="
          --color1: rgb(236,188,78); --color2: rgb(92,123,161); --color3: rgb(243,202,88); --color4: rgb(164,172,188); --color5: rgb(60,68,78);
          --sqip-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMDAgMTcyIj48cGF0aCBmaWxsPSIjM2M0NDRlIiBkPSJNMCAwaDMwMHYxNzJIMHoiLz48ZyBmaWxsLW9wYWNpdHk9Ii41IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSguNiAuNikgc2NhbGUoMS4xNzE4OCkiPjxjaXJjbGUgY3g9IjE0MiIgY3k9IjU5IiByPSIxNzUiIGZpbGw9IiMxYTFhMjAiLz48Y2lyY2xlIHI9IjEiIGZpbGw9IiMzZDNlNDkiIHRyYW5zZm9ybT0ibWF0cml4KDM4LjM5NDcyIDM1LjE4MjI4IC0yMi44MzQ5NyAyNC45MiA1NyA0Ny41KSIvPjxlbGxpcHNlIGN4PSI1NCIgY3k9IjMzIiBmaWxsPSIjOTI2YTdmIiByeD0iNDQiIHJ5PSIyIi8+PGVsbGlwc2UgY3g9IjEwNSIgY3k9IjYzIiBmaWxsPSIjNjE2MDZhIiByeD0iNzYiIHJ5PSIyIi8+PHBhdGggZmlsbD0iIzY2NWU1ZCIgZD0iTTMwIDEwOWg4OHY0SDMweiIvPjxlbGxpcHNlIGN4PSI5OCIgY3k9IjU1IiBmaWxsPSIjNTc2MjZlIiByeD0iODUiIHJ5PSIyIi8+PHBhdGggZmlsbD0iIzNlNzU5ZiIgZD0iTTE5IDQ2aDU2djNIMTl6Ii8+PHBhdGggZmlsbD0iIzgzNjU0NyIgZD0iTTY3IDc4aDU1djNINjd6Ii8+PC9nPjwvc3ZnPg==');
        ">
          <a href="//images.ctfassets.net/f20lfrunubsq/2XXpDt5sVV36DNbmASD0QT/5923a8285dca94d4a210e3921fd6fca9/Screenshot_2025-11-15_at_10.30.02.png">
            <picture>
              <source type="image/avif"
                srcset="//images.ctfassets.net/f20lfrunubsq/2XXpDt5sVV36DNbmASD0QT/5923a8285dca94d4a210e3921fd6fca9/Screenshot_2025-11-15_at_10.30.02.png?fm=avif&fit=scale&q=75&w=300&h=172 300w, //images.ctfassets.net/f20lfrunubsq/2XXpDt5sVV36DNbmASD0QT/5923a8285dca94d4a210e3921fd6fca9/Screenshot_2025-11-15_at_10.30.02.png?fm=avif&fit=scale&q=75&w=500&h=288 500w, //images.ctfassets.net/f20lfrunubsq/2XXpDt5sVV36DNbmASD0QT/5923a8285dca94d4a210e3921fd6fca9/Screenshot_2025-11-15_at_10.30.02.png?fm=avif&fit=scale&q=75&w=700&h=403 700w, //images.ctfassets.net/f20lfrunubsq/2XXpDt5sVV36DNbmASD0QT/5923a8285dca94d4a210e3921fd6fca9/Screenshot_2025-11-15_at_10.30.02.png?fm=avif&fit=scale&q=75&w=900&h=518 900w, //images.ctfassets.net/f20lfrunubsq/2XXpDt5sVV36DNbmASD0QT/5923a8285dca94d4a210e3921fd6fca9/Screenshot_2025-11-15_at_10.30.02.png?fm=avif&fit=scale&q=75&w=1100&h=634 1100w"
                sizes="(max-width: 50em) 98vw, 700px">
              <source type="image/webp"
                srcset="//images.ctfassets.net/f20lfrunubsq/2XXpDt5sVV36DNbmASD0QT/5923a8285dca94d4a210e3921fd6fca9/Screenshot_2025-11-15_at_10.30.02.png?fm=webp&fit=scale&q=75&w=300&h=172 300w, //images.ctfassets.net/f20lfrunubsq/2XXpDt5sVV36DNbmASD0QT/5923a8285dca94d4a210e3921fd6fca9/Screenshot_2025-11-15_at_10.30.02.png?fm=webp&fit=scale&q=75&w=500&h=288 500w, //images.ctfassets.net/f20lfrunubsq/2XXpDt5sVV36DNbmASD0QT/5923a8285dca94d4a210e3921fd6fca9/Screenshot_2025-11-15_at_10.30.02.png?fm=webp&fit=scale&q=75&w=700&h=403 700w, //images.ctfassets.net/f20lfrunubsq/2XXpDt5sVV36DNbmASD0QT/5923a8285dca94d4a210e3921fd6fca9/Screenshot_2025-11-15_at_10.30.02.png?fm=webp&fit=scale&q=75&w=900&h=518 900w, //images.ctfassets.net/f20lfrunubsq/2XXpDt5sVV36DNbmASD0QT/5923a8285dca94d4a210e3921fd6fca9/Screenshot_2025-11-15_at_10.30.02.png?fm=webp&fit=scale&q=75&w=1100&h=634 1100w"
                sizes="(max-width: 50em) 98vw, 700px">
              <img width="1000" height="576"
                srcset="//images.ctfassets.net/f20lfrunubsq/2XXpDt5sVV36DNbmASD0QT/5923a8285dca94d4a210e3921fd6fca9/Screenshot_2025-11-15_at_10.30.02.png?fm=jpg&fit=scale&q=75&w=300&h=172 300w, //images.ctfassets.net/f20lfrunubsq/2XXpDt5sVV36DNbmASD0QT/5923a8285dca94d4a210e3921fd6fca9/Screenshot_2025-11-15_at_10.30.02.png?fm=jpg&fit=scale&q=75&w=500&h=288 500w, //images.ctfassets.net/f20lfrunubsq/2XXpDt5sVV36DNbmASD0QT/5923a8285dca94d4a210e3921fd6fca9/Screenshot_2025-11-15_at_10.30.02.png?fm=jpg&fit=scale&q=75&w=700&h=403 700w, //images.ctfassets.net/f20lfrunubsq/2XXpDt5sVV36DNbmASD0QT/5923a8285dca94d4a210e3921fd6fca9/Screenshot_2025-11-15_at_10.30.02.png?fm=jpg&fit=scale&q=75&w=900&h=518 900w, //images.ctfassets.net/f20lfrunubsq/2XXpDt5sVV36DNbmASD0QT/5923a8285dca94d4a210e3921fd6fca9/Screenshot_2025-11-15_at_10.30.02.png?fm=jpg&fit=scale&q=75&w=1100&h=634 1100w"
                sizes="(max-width: 50em) 98vw, 700px"
                src="//images.ctfassets.net/f20lfrunubsq/2XXpDt5sVV36DNbmASD0QT/5923a8285dca94d4a210e3921fd6fca9/Screenshot_2025-11-15_at_10.30.02.png"
                alt="Custom Element definition with a syntax-highlighted template string containing HTML content."
                loading="lazy"
                onload="this.classList.add('kf-fade-in')">
            </picture>
          </a>
        </figure>
      </div>
    </p>
<p>That's very nice! Thank you Remy for the push!</p>
</div>

          <a href="mailto:stefanjudis@gmail.com?subject=Re%3A%20Syntax-highlighting for JS template strings in VS Code">
            Reply to Stefan
          </a>
        ]]>
      </content>
    </entry>
    
    <entry>
      <title>
        A Raycast confetti shell command
      </title>
      <link href="https://www.stefanjudis.com/notes/a-raycast-confetti-shell-command/"/>
      <published>2025-11-14T23:00:00+00:00</published>
      <updated>2025-11-14T23:00:00+00:00</updated>
      <id>
        https://www.stefanjudis.com/notes/a-raycast-confetti-shell-command/
      </id>
      <category term="note"></category>
        <category term="Bash"></category>
      
        <category term="Raycast"></category>
      
      <content type="html">
        <![CDATA[
          <div class="markdown"><p>Disclaimer, I didn't come up with the idea of firing the Raycast confetti from the command line.</p>
<p>
      <div class="sqip-container margin-top-l margin-bottom-l">
        <figure class="sqip-image" style="
          --color1: rgb(218,72,70); --color2: rgb(80,106,155); --color3: rgb(83,145,224); --color4: rgb(159,177,183); --color5: rgb(72,52,96);
          --sqip-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMDAgMTk0Ij48cGF0aCBmaWxsPSIjNDgzNDYwIiBkPSJNMCAwaDMwMHYxOTRIMHoiLz48ZyBmaWxsLW9wYWNpdHk9Ii41IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSguNiAuNikgc2NhbGUoMS4xNzE4OCkiPjxlbGxpcHNlIGN4PSIxMjkiIGZpbGw9IiNmZmYiIHJ4PSIyNTUiIHJ5PSI3Ii8+PGVsbGlwc2UgY3g9IjI1NSIgY3k9Ijg2IiBmaWxsPSIjZmZmIiByeD0iOCIgcnk9IjE2NSIvPjxjaXJjbGUgcj0iMSIgZmlsbD0iIzU4N2E2MCIgdHJhbnNmb3JtPSJtYXRyaXgoLTIyMy4xOTY2IDEzLjI2MDMyIC02Ljc2NzA4IC0xMTMuOTAyODcgMjcuMiAxMjAuNikiLz48cGF0aCBmaWxsPSIjZmZmIiBkPSJtOCAxNjcuNC0xMyAuMi0zLTE2NSAxMy0uMnoiLz48ZWxsaXBzZSBjeD0iMTMzIiBmaWxsPSIjZmZmIiByeD0iMjUwIiByeT0iNiIvPjxlbGxpcHNlIGN4PSIxMjgiIGN5PSIxNjUiIGZpbGw9IiNkZmRiY2YiIHJ4PSIyNDEiIHJ5PSI2Ii8+PGNpcmNsZSByPSIxIiBmaWxsPSIjZmZmZmY1IiB0cmFuc2Zvcm09InJvdGF0ZSgtMTc5LjkgMTI3LjIgNDEuOSkgc2NhbGUoNC44ODc4NCAxMjIuNjgyODMpIi8+PGVsbGlwc2UgY3g9IjExOSIgY3k9IjE1MiIgZmlsbD0iIzFjMmIyZiIgcng9IjExNSIgcnk9IjgiLz48L2c+PC9zdmc+');
        ">
          <a href="//images.ctfassets.net/f20lfrunubsq/6E4czbnkn7yR6tKhZ3AP25/d4818cdfbc6b4609c9710bad64cbf675/Screenshot_2025-11-15_at_20.08.45.png">
            <picture>
              <source type="image/avif"
                srcset="//images.ctfassets.net/f20lfrunubsq/6E4czbnkn7yR6tKhZ3AP25/d4818cdfbc6b4609c9710bad64cbf675/Screenshot_2025-11-15_at_20.08.45.png?fm=avif&fit=scale&q=75&w=300&h=195 300w, //images.ctfassets.net/f20lfrunubsq/6E4czbnkn7yR6tKhZ3AP25/d4818cdfbc6b4609c9710bad64cbf675/Screenshot_2025-11-15_at_20.08.45.png?fm=avif&fit=scale&q=75&w=500&h=325 500w, //images.ctfassets.net/f20lfrunubsq/6E4czbnkn7yR6tKhZ3AP25/d4818cdfbc6b4609c9710bad64cbf675/Screenshot_2025-11-15_at_20.08.45.png?fm=avif&fit=scale&q=75&w=700&h=455 700w, //images.ctfassets.net/f20lfrunubsq/6E4czbnkn7yR6tKhZ3AP25/d4818cdfbc6b4609c9710bad64cbf675/Screenshot_2025-11-15_at_20.08.45.png?fm=avif&fit=scale&q=75&w=900&h=585 900w, //images.ctfassets.net/f20lfrunubsq/6E4czbnkn7yR6tKhZ3AP25/d4818cdfbc6b4609c9710bad64cbf675/Screenshot_2025-11-15_at_20.08.45.png?fm=avif&fit=scale&q=75&w=1100&h=715 1100w"
                sizes="(max-width: 50em) 98vw, 700px">
              <source type="image/webp"
                srcset="//images.ctfassets.net/f20lfrunubsq/6E4czbnkn7yR6tKhZ3AP25/d4818cdfbc6b4609c9710bad64cbf675/Screenshot_2025-11-15_at_20.08.45.png?fm=webp&fit=scale&q=75&w=300&h=195 300w, //images.ctfassets.net/f20lfrunubsq/6E4czbnkn7yR6tKhZ3AP25/d4818cdfbc6b4609c9710bad64cbf675/Screenshot_2025-11-15_at_20.08.45.png?fm=webp&fit=scale&q=75&w=500&h=325 500w, //images.ctfassets.net/f20lfrunubsq/6E4czbnkn7yR6tKhZ3AP25/d4818cdfbc6b4609c9710bad64cbf675/Screenshot_2025-11-15_at_20.08.45.png?fm=webp&fit=scale&q=75&w=700&h=455 700w, //images.ctfassets.net/f20lfrunubsq/6E4czbnkn7yR6tKhZ3AP25/d4818cdfbc6b4609c9710bad64cbf675/Screenshot_2025-11-15_at_20.08.45.png?fm=webp&fit=scale&q=75&w=900&h=585 900w, //images.ctfassets.net/f20lfrunubsq/6E4czbnkn7yR6tKhZ3AP25/d4818cdfbc6b4609c9710bad64cbf675/Screenshot_2025-11-15_at_20.08.45.png?fm=webp&fit=scale&q=75&w=1100&h=715 1100w"
                sizes="(max-width: 50em) 98vw, 700px">
              <img width="1000" height="650"
                srcset="//images.ctfassets.net/f20lfrunubsq/6E4czbnkn7yR6tKhZ3AP25/d4818cdfbc6b4609c9710bad64cbf675/Screenshot_2025-11-15_at_20.08.45.png?fm=jpg&fit=scale&q=75&w=300&h=195 300w, //images.ctfassets.net/f20lfrunubsq/6E4czbnkn7yR6tKhZ3AP25/d4818cdfbc6b4609c9710bad64cbf675/Screenshot_2025-11-15_at_20.08.45.png?fm=jpg&fit=scale&q=75&w=500&h=325 500w, //images.ctfassets.net/f20lfrunubsq/6E4czbnkn7yR6tKhZ3AP25/d4818cdfbc6b4609c9710bad64cbf675/Screenshot_2025-11-15_at_20.08.45.png?fm=jpg&fit=scale&q=75&w=700&h=455 700w, //images.ctfassets.net/f20lfrunubsq/6E4czbnkn7yR6tKhZ3AP25/d4818cdfbc6b4609c9710bad64cbf675/Screenshot_2025-11-15_at_20.08.45.png?fm=jpg&fit=scale&q=75&w=900&h=585 900w, //images.ctfassets.net/f20lfrunubsq/6E4czbnkn7yR6tKhZ3AP25/d4818cdfbc6b4609c9710bad64cbf675/Screenshot_2025-11-15_at_20.08.45.png?fm=jpg&fit=scale&q=75&w=1100&h=715 1100w"
                sizes="(max-width: 50em) 98vw, 700px"
                src="//images.ctfassets.net/f20lfrunubsq/6E4czbnkn7yR6tKhZ3AP25/d4818cdfbc6b4609c9710bad64cbf675/Screenshot_2025-11-15_at_20.08.45.png"
                alt="Raycast UI highlighting the native confetti command."
                loading="lazy"
                onload="this.classList.add('kf-fade-in')">
            </picture>
          </a>
        </figure>
      </div>
    </p>
<p>Josh's tip is too good not to write down, though, because more people need to know about it. And, obviously, shell sessions need more confetti!</p>
<p>But who's Josh? <a href="https://github.com/jbranchaud/til" style="--image-url: url('https://avatar.stefanjudis.com/https%3A%2F%2Fgithub.com%2Fjbranchaud%2Ftil')">Josh maintains a public TIL repo</a> that I'm following via RSS. <a href="https://github.com/jbranchaud/til/commit/45b269abf16282bcb427fe06fe265c1710d82e87" style="--image-url: url('https://avatar.stefanjudis.com/https%3A%2F%2Fgithub.com%2Fjbranchaud%2Ftil%2Fcommit%2F45b269abf16282bcb427fe06fe265c1710d82e87')">He (and I now) learned how to use the Raycast <code>Confetti</code> command from the CLI</a>.</p>
<p>Implementing the command is almost too easy. Here's my new <code>~/<wbr>.bin/confetti</code> command.</p>
<pre class="language-bash"><code class="language-bash"><span class="token shebang important">#!/bin/bash</span>

<span class="token function">open</span> raycast://extensions/raycast/raycast/confetti
</code></pre>
<p>That's it!</p>
<p>
      <div class="sqip-container margin-top-l margin-bottom-l">
        <figure class="sqip-image" style="
          --color1: rgb(68,140,220); --color2: rgb(90,164,109); --color3: rgb(136,237,166); --color4: rgb(185,203,197); --color5: rgb(41,47,73);
          --sqip-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMDAgMTc2Ij48cGF0aCBmaWxsPSIjMjkyZjQ5IiBkPSJNMCAwaDMwMHYxNzZIMHoiLz48ZyBmaWxsLW9wYWNpdHk9Ii41IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSguNiAuNikgc2NhbGUoMS4xNzE4OCkiPjxlbGxpcHNlIGN4PSIxMDIiIGN5PSI2MSIgZmlsbD0iIzAwMDAwMSIgcng9IjE3NCIgcnk9IjE1MCIvPjxjaXJjbGUgY3g9IjgiIGN5PSI1OSIgcj0iNSIgZmlsbD0iI2QwZmZmZiIvPjxwYXRoIGZpbGw9IiMzNzllNmIiIGQ9Ik01MSAxNmg2MXY2SDUxeiIvPjxwYXRoIGZpbGw9IiMyMGEyZmYiIGQ9Im00NiAxMTQtMTEgMTZ2LTExeiIvPjxwYXRoIGZpbGw9IiNiY2EyNzMiIGQ9Im0yNTAuOSAxMDkuNCAyMC4xIDE0LjItNy4yIDcuMS05LjMtMzYuMXoiLz48cGF0aCBmaWxsPSIjM2M4ZTVjIiBkPSJNMTk2IDgyaDV2MzloLTV6Ii8+PHBhdGggZmlsbD0iI2ZjZGQ1YyIgZD0iTTIzMyA2N2g0djExaC00eiIvPjxwYXRoIGZpbGw9IiNkZWM3NTUiIGQ9Im0yMjggNTIuMiAzLjUgMi01LjUgOS42LTMuNS0yeiIvPjwvZz48L3N2Zz4=');
        ">
          <a href="//images.ctfassets.net/f20lfrunubsq/6vqoJcm6sbGRmKaf3jCUO4/4c39ddc6f8e7c3ca0749366b007d3f31/Screenshot_2025-11-15_at_20.14.47.png">
            <picture>
              <source type="image/avif"
                srcset="//images.ctfassets.net/f20lfrunubsq/6vqoJcm6sbGRmKaf3jCUO4/4c39ddc6f8e7c3ca0749366b007d3f31/Screenshot_2025-11-15_at_20.14.47.png?fm=avif&fit=scale&q=75&w=300&h=177 300w, //images.ctfassets.net/f20lfrunubsq/6vqoJcm6sbGRmKaf3jCUO4/4c39ddc6f8e7c3ca0749366b007d3f31/Screenshot_2025-11-15_at_20.14.47.png?fm=avif&fit=scale&q=75&w=500&h=295 500w, //images.ctfassets.net/f20lfrunubsq/6vqoJcm6sbGRmKaf3jCUO4/4c39ddc6f8e7c3ca0749366b007d3f31/Screenshot_2025-11-15_at_20.14.47.png?fm=avif&fit=scale&q=75&w=700&h=413 700w, //images.ctfassets.net/f20lfrunubsq/6vqoJcm6sbGRmKaf3jCUO4/4c39ddc6f8e7c3ca0749366b007d3f31/Screenshot_2025-11-15_at_20.14.47.png?fm=avif&fit=scale&q=75&w=900&h=531 900w, //images.ctfassets.net/f20lfrunubsq/6vqoJcm6sbGRmKaf3jCUO4/4c39ddc6f8e7c3ca0749366b007d3f31/Screenshot_2025-11-15_at_20.14.47.png?fm=avif&fit=scale&q=75&w=1100&h=649 1100w"
                sizes="(max-width: 50em) 98vw, 700px">
              <source type="image/webp"
                srcset="//images.ctfassets.net/f20lfrunubsq/6vqoJcm6sbGRmKaf3jCUO4/4c39ddc6f8e7c3ca0749366b007d3f31/Screenshot_2025-11-15_at_20.14.47.png?fm=webp&fit=scale&q=75&w=300&h=177 300w, //images.ctfassets.net/f20lfrunubsq/6vqoJcm6sbGRmKaf3jCUO4/4c39ddc6f8e7c3ca0749366b007d3f31/Screenshot_2025-11-15_at_20.14.47.png?fm=webp&fit=scale&q=75&w=500&h=295 500w, //images.ctfassets.net/f20lfrunubsq/6vqoJcm6sbGRmKaf3jCUO4/4c39ddc6f8e7c3ca0749366b007d3f31/Screenshot_2025-11-15_at_20.14.47.png?fm=webp&fit=scale&q=75&w=700&h=413 700w, //images.ctfassets.net/f20lfrunubsq/6vqoJcm6sbGRmKaf3jCUO4/4c39ddc6f8e7c3ca0749366b007d3f31/Screenshot_2025-11-15_at_20.14.47.png?fm=webp&fit=scale&q=75&w=900&h=531 900w, //images.ctfassets.net/f20lfrunubsq/6vqoJcm6sbGRmKaf3jCUO4/4c39ddc6f8e7c3ca0749366b007d3f31/Screenshot_2025-11-15_at_20.14.47.png?fm=webp&fit=scale&q=75&w=1100&h=649 1100w"
                sizes="(max-width: 50em) 98vw, 700px">
              <img width="1000" height="590"
                srcset="//images.ctfassets.net/f20lfrunubsq/6vqoJcm6sbGRmKaf3jCUO4/4c39ddc6f8e7c3ca0749366b007d3f31/Screenshot_2025-11-15_at_20.14.47.png?fm=jpg&fit=scale&q=75&w=300&h=177 300w, //images.ctfassets.net/f20lfrunubsq/6vqoJcm6sbGRmKaf3jCUO4/4c39ddc6f8e7c3ca0749366b007d3f31/Screenshot_2025-11-15_at_20.14.47.png?fm=jpg&fit=scale&q=75&w=500&h=295 500w, //images.ctfassets.net/f20lfrunubsq/6vqoJcm6sbGRmKaf3jCUO4/4c39ddc6f8e7c3ca0749366b007d3f31/Screenshot_2025-11-15_at_20.14.47.png?fm=jpg&fit=scale&q=75&w=700&h=413 700w, //images.ctfassets.net/f20lfrunubsq/6vqoJcm6sbGRmKaf3jCUO4/4c39ddc6f8e7c3ca0749366b007d3f31/Screenshot_2025-11-15_at_20.14.47.png?fm=jpg&fit=scale&q=75&w=900&h=531 900w, //images.ctfassets.net/f20lfrunubsq/6vqoJcm6sbGRmKaf3jCUO4/4c39ddc6f8e7c3ca0749366b007d3f31/Screenshot_2025-11-15_at_20.14.47.png?fm=jpg&fit=scale&q=75&w=1100&h=649 1100w"
                sizes="(max-width: 50em) 98vw, 700px"
                src="//images.ctfassets.net/f20lfrunubsq/6vqoJcm6sbGRmKaf3jCUO4/4c39ddc6f8e7c3ca0749366b007d3f31/Screenshot_2025-11-15_at_20.14.47.png"
                alt="Terminal executing `confetti` covered in confetti"
                loading="lazy"
                onload="this.classList.add('kf-fade-in')">
            </picture>
          </a>
        </figure>
      </div>
    </p>
<p>Apparently, Raycast registers a protocol handler (<code>raycast://</code>) which you can call from anywhere. Whenever you open this URL (your browser works fine, too), the Raycast &quot;confetti&quot; command will be triggered. Magic!</p>
</div>

          <a href="mailto:stefanjudis@gmail.com?subject=Re%3A%20A Raycast confetti shell command">
            Reply to Stefan
          </a>
        ]]>
      </content>
    </entry>
    
    <entry>
      <title>
        Stop citing AI
      </title>
      <link href="https://www.stefanjudis.com/notes/stop-citing-ai/"/>
      <published>2025-10-30T23:00:00+00:00</published>
      <updated>2025-10-30T23:00:00+00:00</updated>
      <id>
        https://www.stefanjudis.com/notes/stop-citing-ai/
      </id>
      <category term="note"></category>
        <category term="AI"></category>
      
      <content type="html">
        <![CDATA[
          <div class="markdown"><p>I can't help it but I just love single-purpose URLs. There's for example <a href="https://dontasktoask.com/" style="--image-url: url('https://avatar.stefanjudis.com/https%3A%2F%2Fdontasktoask.com%2F')">dontasktoask.com</a>. I love it! Or <a href="https://nohello.net" style="--image-url: url('https://avatar.stefanjudis.com/https%3A%2F%2Fnohello.net')">nohello.net</a>. I love this one, too! And, of course there's <a href="https://shouldiuseacarousel.com/" style="--image-url: url('https://avatar.stefanjudis.com/https%3A%2F%2Fshouldiuseacarousel.com%2F')">shouldiuseacarousel.com</a>. Fabulous!</p>
<p>And now there's a new one in town: <a href="https://stopcitingai.com/" style="--image-url: url('https://avatar.stefanjudis.com/https%3A%2F%2Fstopcitingai.com%2F')">stopcitingai.com</a>. To whoever created this: thank you!</p>
<p>
      <div class="sqip-container margin-top-l margin-bottom-l">
        <figure class="sqip-image" style="
          --color1: rgb(56.220472440944896,122.48031496062984,198.7795275590551); --color2: rgb(99,130,152); --color3: rgb(151.63464566929136,186.08976377952752,225.76535433070865); --color4: rgb(178,196,205); --color5: rgb(61,63,71);
          --sqip-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMDAgMTg2Ij48cGF0aCBmaWxsPSIjM2QzZjQ3IiBkPSJNMCAwaDMwMHYxODZIMHoiLz48ZyBmaWxsLW9wYWNpdHk9Ii41IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSguNiAuNikgc2NhbGUoMS4xNzE4OCkiPjxjaXJjbGUgcj0iMSIgdHJhbnNmb3JtPSJtYXRyaXgoMTEuNTQxOCA3Ni41MDkxNCAtMTg3Ljg2NTQ4IDI4LjM0MDUgMTQ5LjkgMjQuNikiLz48Y2lyY2xlIHI9IjEiIHRyYW5zZm9ybT0ibWF0cml4KC0xLjgzNTM0IC0zMC4wMDc1NyAxODMuOTgwMyAtMTEuMjUyNzIgMTU4LjIgMTU4KSIvPjxlbGxpcHNlIGN4PSIxMTEiIGN5PSIxMDgiIGZpbGw9IiNjZGQwZDMiIHJ4PSIxMDQiIHJ5PSI0Ii8+PHBhdGggZmlsbD0iI2Q3ZGFlMSIgZD0iTTc4LjQgNTAgNzcgNDNsOTYuNS0xNyAxLjMgN3oiLz48Y2lyY2xlIHI9IjEiIGZpbGw9IiMwMjA4MTUiIHRyYW5zZm9ybT0icm90YXRlKC0yMi41IDI4NS41IC01NzUuNikgc2NhbGUoNDAuMTU3MDUgMTQwLjQ5MTcpIi8+PGVsbGlwc2UgY3g9IjgxIiBjeT0iMTIyIiBmaWxsPSIjYjJiYWJmIiByeD0iMTQ3IiByeT0iNCIvPjxwYXRoIGZpbGw9IiNlM2U2ZTgiIGQ9Ik0xNiAxMzNoNTd2N0gxNnoiLz48ZWxsaXBzZSBjeT0iNjIiIGZpbGw9IiMwMDAxMGUiIHJ4PSIxOCIgcnk9IjE1NiIvPjwvZz48L3N2Zz4=');
        ">
          <a href="//images.ctfassets.net/f20lfrunubsq/58H30NJYU5zsRhqTio9RUf/680401c82aa5f335a17cff39b3710851/Screenshot_2025-10-31_at_14.14.24.png">
            <picture>
              <source type="image/avif"
                srcset="//images.ctfassets.net/f20lfrunubsq/58H30NJYU5zsRhqTio9RUf/680401c82aa5f335a17cff39b3710851/Screenshot_2025-10-31_at_14.14.24.png?fm=avif&fit=scale&q=75&w=300&h=186 300w, //images.ctfassets.net/f20lfrunubsq/58H30NJYU5zsRhqTio9RUf/680401c82aa5f335a17cff39b3710851/Screenshot_2025-10-31_at_14.14.24.png?fm=avif&fit=scale&q=75&w=500&h=311 500w, //images.ctfassets.net/f20lfrunubsq/58H30NJYU5zsRhqTio9RUf/680401c82aa5f335a17cff39b3710851/Screenshot_2025-10-31_at_14.14.24.png?fm=avif&fit=scale&q=75&w=700&h=436 700w, //images.ctfassets.net/f20lfrunubsq/58H30NJYU5zsRhqTio9RUf/680401c82aa5f335a17cff39b3710851/Screenshot_2025-10-31_at_14.14.24.png?fm=avif&fit=scale&q=75&w=900&h=560 900w, //images.ctfassets.net/f20lfrunubsq/58H30NJYU5zsRhqTio9RUf/680401c82aa5f335a17cff39b3710851/Screenshot_2025-10-31_at_14.14.24.png?fm=avif&fit=scale&q=75&w=1100&h=685 1100w"
                sizes="(max-width: 50em) 98vw, 700px">
              <source type="image/webp"
                srcset="//images.ctfassets.net/f20lfrunubsq/58H30NJYU5zsRhqTio9RUf/680401c82aa5f335a17cff39b3710851/Screenshot_2025-10-31_at_14.14.24.png?fm=webp&fit=scale&q=75&w=300&h=186 300w, //images.ctfassets.net/f20lfrunubsq/58H30NJYU5zsRhqTio9RUf/680401c82aa5f335a17cff39b3710851/Screenshot_2025-10-31_at_14.14.24.png?fm=webp&fit=scale&q=75&w=500&h=311 500w, //images.ctfassets.net/f20lfrunubsq/58H30NJYU5zsRhqTio9RUf/680401c82aa5f335a17cff39b3710851/Screenshot_2025-10-31_at_14.14.24.png?fm=webp&fit=scale&q=75&w=700&h=436 700w, //images.ctfassets.net/f20lfrunubsq/58H30NJYU5zsRhqTio9RUf/680401c82aa5f335a17cff39b3710851/Screenshot_2025-10-31_at_14.14.24.png?fm=webp&fit=scale&q=75&w=900&h=560 900w, //images.ctfassets.net/f20lfrunubsq/58H30NJYU5zsRhqTio9RUf/680401c82aa5f335a17cff39b3710851/Screenshot_2025-10-31_at_14.14.24.png?fm=webp&fit=scale&q=75&w=1100&h=685 1100w"
                sizes="(max-width: 50em) 98vw, 700px">
              <img width="1000" height="623"
                srcset="//images.ctfassets.net/f20lfrunubsq/58H30NJYU5zsRhqTio9RUf/680401c82aa5f335a17cff39b3710851/Screenshot_2025-10-31_at_14.14.24.png?fm=jpg&fit=scale&q=75&w=300&h=186 300w, //images.ctfassets.net/f20lfrunubsq/58H30NJYU5zsRhqTio9RUf/680401c82aa5f335a17cff39b3710851/Screenshot_2025-10-31_at_14.14.24.png?fm=jpg&fit=scale&q=75&w=500&h=311 500w, //images.ctfassets.net/f20lfrunubsq/58H30NJYU5zsRhqTio9RUf/680401c82aa5f335a17cff39b3710851/Screenshot_2025-10-31_at_14.14.24.png?fm=jpg&fit=scale&q=75&w=700&h=436 700w, //images.ctfassets.net/f20lfrunubsq/58H30NJYU5zsRhqTio9RUf/680401c82aa5f335a17cff39b3710851/Screenshot_2025-10-31_at_14.14.24.png?fm=jpg&fit=scale&q=75&w=900&h=560 900w, //images.ctfassets.net/f20lfrunubsq/58H30NJYU5zsRhqTio9RUf/680401c82aa5f335a17cff39b3710851/Screenshot_2025-10-31_at_14.14.24.png?fm=jpg&fit=scale&q=75&w=1100&h=685 1100w"
                sizes="(max-width: 50em) 98vw, 700px"
                src="//images.ctfassets.net/f20lfrunubsq/58H30NJYU5zsRhqTio9RUf/680401c82aa5f335a17cff39b3710851/Screenshot_2025-10-31_at_14.14.24.png"
                alt="But llama said... You’ve been sent here because you cited AI as a source to try and prove something."
                loading="lazy"
                onload="this.classList.add('kf-fade-in')">
            </picture>
          </a>
        </figure>
      </div>
    </p>
</div>

          <a href="mailto:stefanjudis@gmail.com?subject=Re%3A%20Stop citing AI">
            Reply to Stefan
          </a>
        ]]>
      </content>
    </entry>
    
    <entry>
      <title>
        Quoting Pablo Enoc
      </title>
      <link href="https://www.stefanjudis.com/notes/quoting-pablo-enoc/"/>
      <published>2025-10-30T23:00:00+00:00</published>
      <updated>2025-10-30T23:00:00+00:00</updated>
      <id>
        https://www.stefanjudis.com/notes/quoting-pablo-enoc/
      </id>
      <category term="note"></category>
        <category term="AI"></category>
      
      <content type="html">
        <![CDATA[
          <div class="markdown"><p>I don't agree with everything Pablo writes in <a href="https://blog.pabloecortez.com/its-insulting-to-read-your-ai-generated-blog-post/" style="--image-url: url('https://avatar.stefanjudis.com/https%3A%2F%2Fblog.pabloecortez.com%2Fits-insulting-to-read-your-ai-generated-blog-post%2F')">It's insulting to read your AI-generated blog post</a>. For example, I think it's fine to use AI for grammar fixes or translations when neeeded.</p>
<p>This opening sentence is a real banger, though!</p>
<blockquote>
<p>It seems so rude and careless to make me, a person with thoughts, ideas, humor, contradictions and life experience to read something spit out by the equivalent of a lexical bingo machine because you were too lazy to write it yourself.</p>
</blockquote>
</div>

          <a href="mailto:stefanjudis@gmail.com?subject=Re%3A%20Quoting Pablo Enoc">
            Reply to Stefan
          </a>
        ]]>
      </content>
    </entry>
    
    <entry>
      <title>
        When AI will browse the web for me
      </title>
      <link href="https://www.stefanjudis.com/notes/when-ai-will-browse-the-web-for-me/"/>
      <published>2025-09-22T22:00:00+00:00</published>
      <updated>2025-09-22T22:00:00+00:00</updated>
      <id>
        https://www.stefanjudis.com/notes/when-ai-will-browse-the-web-for-me/
      </id>
      <category term="note"></category>
        <category term="AI"></category>
      
      <content type="html">
        <![CDATA[
          <div class="markdown"><p>It's a shame that the latest AI trend is figuring out how to replace our beloved internet. To state the obvious: the master plan is to make websites invisible to the public and let agents do &quot;the web browsing&quot; for us.</p>
<p>Every AI-focused product tries exactly this on a smaller scale for a while; &quot;Hey you! Do you want to use our slurped-in and almost accurate content summary instead of reading something yourself? It's great (but, remember, use it at your own risk)!&quot;.</p>
<p>To scale up, browser makers now try to convince us to use LLMs and AI makers try to build and sell browsers. Web browsing isn't the goal, though, and the direction is pretty clear. AI companies need to reach more people and the old web we know is the obvious target.</p>
<p><a href="https://idiallo.com/blog/the-great-ai-filter" style="--image-url: url('https://avatar.stefanjudis.com/https%3A%2F%2Fidiallo.com%2Fblog%2Fthe-great-ai-filter')">Ibrahim struck a nerve in his recent post</a>:</p>
<blockquote>
<p>When Chrome browses for me, it will surface what it wants me to see, filtered through corporate priorities, advertising relationships, and engagement metrics. Over time, through a kind of digital Stockholm syndrome, I'll start believing these curated choices reflect my authentic preferences. I'll mistake algorithmic manipulation for personal agency.</p>
</blockquote>
<p>Accessing a curated or filtered internet isn't a new problem, though. Search became the first gatekeeper decades ago. If a site isn't on Google Search it might not exist, right? But regardless of whether a site is visible on search or not, it can still be accessed, linked to and discovered. The open web is still out there!</p>
<p>To work around this filter problem, I avoid relying on search or algorithms to discover and consume content as much as possible. My RSS reader and email inbox are always full. Every day, I hear from fellow humans, trusted publications and my favorite bloggers. They'll reach me without a middleman and there's no algorithm or feed that can cut this connection.</p>
<p>But what will happen when LLMs manage all the internet content for us? What will happen when we won't be browsing <em>the web</em> but <em>generated answers</em>? Will all the manipulation we know from social media enter the general web; just on a bigger and much scarier scale?</p>
<p>If LLMs will become the new information gatekeeper, we won't be in charge of our consumed content anymore. If LLMs will curate and summarize the web for the general public, ignored sites might as well not exist and our internet reality might be controlled by software developed in silicon valley.</p>
<p>What could go wrong, right?</p>
</div>

          <a href="mailto:stefanjudis@gmail.com?subject=Re%3A%20When AI will browse the web for me">
            Reply to Stefan
          </a>
        ]]>
      </content>
    </entry>
    
    <entry>
      <title>
        Talking about the Polypane browser with Kilian Valkhof
      </title>
      <link href="https://www.stefanjudis.com/notes/talking-about-the-polypane-browser-with-kilian-valkhof/"/>
      <published>2025-08-02T22:00:00+00:00</published>
      <updated>2025-08-02T22:00:00+00:00</updated>
      <id>
        https://www.stefanjudis.com/notes/talking-about-the-polypane-browser-with-kilian-valkhof/
      </id>
      <category term="note"></category>
        <category term="Tools"></category>
      
      <content type="html">
        <![CDATA[
          <div class="markdown"><p>I've been using <a href="https://polypane.app/" style="--image-url: url('https://avatar.stefanjudis.com/https%3A%2F%2Fpolypane.app%2F')">the Polypane frontend development browser</a> for over a year now, and I've always known that I'm not using the tool to its fullest potential.</p>
<p>To solve this problem and improve my frontend workflows, I invited <a href="https://kilianvalkhof.com/" style="--image-url: url('https://avatar.stefanjudis.com/https%3A%2F%2Fkilianvalkhof.com%2F')">Kilian</a> to show me his favorite tips and tricks.</p>
<p>
        <lite-youtube videoid="ThOq55qbJ2Y" style="background-image: url('https://i.ytimg.com/vi/ThOq55qbJ2Y/hqdefault.jpg');">
          <div class="lty-playbtn"></div>
        </lite-youtube>
      </p>
<p>If you're wondering why you should use Polypane or if you're like me and don't know about all the hidden pro-features, this video is for you!</p>
</div>

          <a href="mailto:stefanjudis@gmail.com?subject=Re%3A%20Talking about the Polypane browser with Kilian Valkhof">
            Reply to Stefan
          </a>
        ]]>
      </content>
    </entry>
    
    <entry>
      <title>
        Quoting Jeffrey Zeldman
      </title>
      <link href="https://www.stefanjudis.com/notes/quoting-jeffrey-zeldman/"/>
      <published>2025-07-31T22:00:00+00:00</published>
      <updated>2025-07-31T22:00:00+00:00</updated>
      <id>
        https://www.stefanjudis.com/notes/quoting-jeffrey-zeldman/
      </id>
      <category term="note"></category>
        <category term="AI"></category>
      
        <category term="Web"></category>
      
      <content type="html">
        <![CDATA[
          <div class="markdown"><p>As someone fearing about the future of web development, I can only say that I hope <a href="https://bsky.app/profile/zeldman.bsky.social/post/3lvbtogkspk27" style="--image-url: url('https://avatar.stefanjudis.com/https%3A%2F%2Fbsky.app%2Fprofile%2Fzeldman.bsky.social%2Fpost%2F3lvbtogkspk27')">Jeffrey is right on this one</a>.</p>
<blockquote>
<p>As vibe-coded apps and self-creating websites become the norm, luxe companies will pay large dollars for bespoke, hand-crafted HTML and CSS.</p>
</blockquote>
<p>It would be great to continue making a living by working in the field we used to call web development...</p>
</div>

          <a href="mailto:stefanjudis@gmail.com?subject=Re%3A%20Quoting Jeffrey Zeldman">
            Reply to Stefan
          </a>
        ]]>
      </content>
    </entry>
    
    <entry>
      <title>
        Open new tabs next to the current one in Firefox
      </title>
      <link href="https://www.stefanjudis.com/notes/open-new-tabs-next-to-the-current-one-in-firefox/"/>
      <published>2025-07-24T22:00:00+00:00</published>
      <updated>2025-07-24T22:00:00+00:00</updated>
      <id>
        https://www.stefanjudis.com/notes/open-new-tabs-next-to-the-current-one-in-firefox/
      </id>
      <category term="note"></category>
        <category term="Firefox"></category>
      
      <content type="html">
        <![CDATA[
          <div class="markdown"><p>You might know that I'm still holding on to using Firefox as my daily driver. Things aren't looking great at Mozilla and I'm still peeking at Vivaldi, but so far I simply haven't made the switch.</p>
<p>Now, Kaushik shared some Firefox styling tricks in <a href="https://kau.sh/blog/how-to-firefox/" style="--image-url: url('https://avatar.stefanjudis.com/https%3A%2F%2Fkau.sh%2Fblog%2Fhow-to-firefox%2F')">&quot;How to Firefox&quot;</a> that I didn't apply, but I learned how to fix a behavior that was silently bugging me for 20 years now.</p>
<p>You know when you open a new tab with <code>CMD+T</code> and the new tab always goes to the end of your tab list. For people with a few open tabs this might not be a big deal, but I'm a tab hoarder with 177 open tabs right now. If I'm on tab 50 and decide to open a new tab, chances are pretty high that the new tab is related to the fiftieth tab.</p>
<p>If you want to open tabs next to your current tabs, head over to your <code>about:config</code> and change <code>browser<wbr>.tabs<wbr>.insertAfterCurrent</code> and <code>browser<wbr>.tabs<wbr>.insertAfterCurrentExceptPinned</code> to <code>true</code>.</p>
<p>
      <div class="sqip-container margin-top-l margin-bottom-l">
        <figure class="sqip-image" style="
          --color1: rgb(127.50000000000003,123.63636363636361,131.3636363636364); --color2: rgb(119,119,126); --color3: rgb(188.7,186.6909090909091,190.70909090909092); --color4: rgb(189,187,191); --color5: rgb(60,60,68);
          --sqip-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMDAgNTAiPjxwYXRoIGZpbGw9IiMzYzNjNDQiIGQ9Ik0wIDBoMzAwdjUwSDB6Ii8+PGcgZmlsbC1vcGFjaXR5PSIuNSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLjYgLjYpIHNjYWxlKDEuMTcxODgpIj48Y2lyY2xlIHI9IjEiIGZpbGw9IiMwZTBjMTMiIHRyYW5zZm9ybT0icm90YXRlKDEwOS42IDgzIDU4LjUpIHNjYWxlKDU0LjkzNDY1IDE2OS43MDQ3MSkiLz48cGF0aCBmaWxsPSIjZGVkZGUyIiBkPSJNMTIgMzNoMTEydjJIMTJ6Ii8+PHBhdGggZmlsbD0iI2MyYzFjMyIgZD0iTTE0IDIxaDYydjNIMTR6Ii8+PGVsbGlwc2UgY3g9IjIyMSIgY3k9IjgiIGZpbGw9IiNhNGE0YTgiIHJ4PSIzNSIgcnk9IjIiLz48ZWxsaXBzZSBjeD0iMjIiIGN5PSI0MCIgZmlsbD0iIzA5MDcwZiIgcng9IjExMCIgcnk9IjUiLz48ZWxsaXBzZSBjeT0iMTUiIGZpbGw9IiMwYjBhMTEiIHJ4PSI5NyIgcnk9IjYiLz48cGF0aCBmaWxsPSIjMDQwMjBiIiBkPSJNMCAyNWg5N3Y3SDB6Ii8+PGVsbGlwc2UgY3g9IjM4IiBjeT0iOCIgZmlsbD0iIzk3OTY5YyIgcng9IjM1IiByeT0iMiIvPjwvZz48L3N2Zz4=');
        ">
          <a href="//images.ctfassets.net/f20lfrunubsq/6TwZCVeIRrCHgYZ9WB5bRH/2eb0bddb58c722566cebfb5f0a468f4a/Screenshot_2025-07-25_at_19.38.33.png">
            <picture>
              <source type="image/avif"
                srcset="//images.ctfassets.net/f20lfrunubsq/6TwZCVeIRrCHgYZ9WB5bRH/2eb0bddb58c722566cebfb5f0a468f4a/Screenshot_2025-07-25_at_19.38.33.png?fm=avif&fit=scale&q=75&w=300&h=51 300w, //images.ctfassets.net/f20lfrunubsq/6TwZCVeIRrCHgYZ9WB5bRH/2eb0bddb58c722566cebfb5f0a468f4a/Screenshot_2025-07-25_at_19.38.33.png?fm=avif&fit=scale&q=75&w=500&h=85 500w, //images.ctfassets.net/f20lfrunubsq/6TwZCVeIRrCHgYZ9WB5bRH/2eb0bddb58c722566cebfb5f0a468f4a/Screenshot_2025-07-25_at_19.38.33.png?fm=avif&fit=scale&q=75&w=700&h=119 700w, //images.ctfassets.net/f20lfrunubsq/6TwZCVeIRrCHgYZ9WB5bRH/2eb0bddb58c722566cebfb5f0a468f4a/Screenshot_2025-07-25_at_19.38.33.png?fm=avif&fit=scale&q=75&w=900&h=153 900w, //images.ctfassets.net/f20lfrunubsq/6TwZCVeIRrCHgYZ9WB5bRH/2eb0bddb58c722566cebfb5f0a468f4a/Screenshot_2025-07-25_at_19.38.33.png?fm=avif&fit=scale&q=75&w=1100&h=187 1100w"
                sizes="(max-width: 50em) 98vw, 700px">
              <source type="image/webp"
                srcset="//images.ctfassets.net/f20lfrunubsq/6TwZCVeIRrCHgYZ9WB5bRH/2eb0bddb58c722566cebfb5f0a468f4a/Screenshot_2025-07-25_at_19.38.33.png?fm=webp&fit=scale&q=75&w=300&h=51 300w, //images.ctfassets.net/f20lfrunubsq/6TwZCVeIRrCHgYZ9WB5bRH/2eb0bddb58c722566cebfb5f0a468f4a/Screenshot_2025-07-25_at_19.38.33.png?fm=webp&fit=scale&q=75&w=500&h=85 500w, //images.ctfassets.net/f20lfrunubsq/6TwZCVeIRrCHgYZ9WB5bRH/2eb0bddb58c722566cebfb5f0a468f4a/Screenshot_2025-07-25_at_19.38.33.png?fm=webp&fit=scale&q=75&w=700&h=119 700w, //images.ctfassets.net/f20lfrunubsq/6TwZCVeIRrCHgYZ9WB5bRH/2eb0bddb58c722566cebfb5f0a468f4a/Screenshot_2025-07-25_at_19.38.33.png?fm=webp&fit=scale&q=75&w=900&h=153 900w, //images.ctfassets.net/f20lfrunubsq/6TwZCVeIRrCHgYZ9WB5bRH/2eb0bddb58c722566cebfb5f0a468f4a/Screenshot_2025-07-25_at_19.38.33.png?fm=webp&fit=scale&q=75&w=1100&h=187 1100w"
                sizes="(max-width: 50em) 98vw, 700px">
              <img width="1000" height="170"
                srcset="//images.ctfassets.net/f20lfrunubsq/6TwZCVeIRrCHgYZ9WB5bRH/2eb0bddb58c722566cebfb5f0a468f4a/Screenshot_2025-07-25_at_19.38.33.png?fm=jpg&fit=scale&q=75&w=300&h=51 300w, //images.ctfassets.net/f20lfrunubsq/6TwZCVeIRrCHgYZ9WB5bRH/2eb0bddb58c722566cebfb5f0a468f4a/Screenshot_2025-07-25_at_19.38.33.png?fm=jpg&fit=scale&q=75&w=500&h=85 500w, //images.ctfassets.net/f20lfrunubsq/6TwZCVeIRrCHgYZ9WB5bRH/2eb0bddb58c722566cebfb5f0a468f4a/Screenshot_2025-07-25_at_19.38.33.png?fm=jpg&fit=scale&q=75&w=700&h=119 700w, //images.ctfassets.net/f20lfrunubsq/6TwZCVeIRrCHgYZ9WB5bRH/2eb0bddb58c722566cebfb5f0a468f4a/Screenshot_2025-07-25_at_19.38.33.png?fm=jpg&fit=scale&q=75&w=900&h=153 900w, //images.ctfassets.net/f20lfrunubsq/6TwZCVeIRrCHgYZ9WB5bRH/2eb0bddb58c722566cebfb5f0a468f4a/Screenshot_2025-07-25_at_19.38.33.png?fm=jpg&fit=scale&q=75&w=1100&h=187 1100w"
                sizes="(max-width: 50em) 98vw, 700px"
                src="//images.ctfassets.net/f20lfrunubsq/6TwZCVeIRrCHgYZ9WB5bRH/2eb0bddb58c722566cebfb5f0a468f4a/Screenshot_2025-07-25_at_19.38.33.png"
                alt="Firefox about:config showing `browser.tabs.insertAfterCurrent` settings"
                loading="lazy"
                onload="this.classList.add('kf-fade-in')">
            </picture>
          </a>
        </figure>
      </div>
    </p>
<p>That's it! Right now I'm pretty happy with this change. Let's see if it lasts.</p>
<p><em>Update:</em> I've had this setting turned on for a week and it drives me insane because it doesn't only open new tabs open &quot;inline&quot;. New tabs coming from clicking on URLs outside Firefox will also open at the current tab position and this leads messed up tab order.</p>
</div>

          <a href="mailto:stefanjudis@gmail.com?subject=Re%3A%20Open new tabs next to the current one in Firefox">
            Reply to Stefan
          </a>
        ]]>
      </content>
    </entry>
    
    <entry>
      <title>
        WCAG success criteria that can&#39;t be autmatically tested
      </title>
      <link href="https://www.stefanjudis.com/notes/wcag-success-criteria-that-cant-be-autmatically-tested/"/>
      <published>2025-03-25T23:00:00+00:00</published>
      <updated>2025-03-25T23:00:00+00:00</updated>
      <id>
        https://www.stefanjudis.com/notes/wcag-success-criteria-that-cant-be-autmatically-tested/
      </id>
      <category term="note"></category>
        <category term="Accessibility"></category>
      
      <content type="html">
        <![CDATA[
          <div class="markdown"><p>There are many accessibility audit tools out there. The most mainstream one is probably Chrome's Lighthouse Accessibility audit. But let me tell you a secret.</p>
<p>Accessibility testing isn't done after achieving a green Lighthouse score.</p>
<p>Here's <a href="https://html5accessibility.com/stuff/2025/03/24/a-tools-errand/#:~:text=automation%20blues" style="--image-url: url('https://avatar.stefanjudis.com/https%3A%2F%2Fhtml5accessibility.com%2Fstuff%2F2025%2F03%2F24%2Fa-tools-errand%2F%23%3A~%3Atext%3Dautomation%2520blues')">Steve Faulkner listing WCAG success criteria</a> that aren't covered by today's tools.</p>
<p>Some obvious examples:</p>
<blockquote>
<p>Automated tools can detect missing <code>alt</code> attributes but cannot determine if alternative text is meaningful.</p>
</blockquote>
<blockquote>
<p>Tools can check for semantic HTML elements (e.g., headings, lists, tables) but cannot determine if relationships are accurately conveyed.</p>
</blockquote>
<blockquote>
<p>Tools can analyze DOM order, but manual review is needed to verify if reading order makes sense.</p>
</blockquote>
<blockquote>
<p>Tools can verify the presence and structure of the <code>title</code> element, but cannot determine whether the title text is meaningful or descriptive.</p>
</blockquote>
<blockquote>
<p>Tools can detect link text, but manual testing is needed to verify if the link text makes sense in context.</p>
</blockquote>
<p>Tools are great for &quot;obvious&quot; technical accessibility but for everything else manual testing is still required.</p>
</div>

          <a href="mailto:stefanjudis@gmail.com?subject=Re%3A%20WCAG success criteria that can&#39;t be autmatically tested">
            Reply to Stefan
          </a>
        ]]>
      </content>
    </entry>
    
    <entry>
      <title>
        To blog something to show
      </title>
      <link href="https://www.stefanjudis.com/notes/blogging-is-about-having-something-to-show/"/>
      <published>2024-12-22T23:00:00+00:00</published>
      <updated>2024-12-22T23:00:00+00:00</updated>
      <id>
        https://www.stefanjudis.com/notes/blogging-is-about-having-something-to-show/
      </id>
      <category term="note"></category>
        <category term="Blogging"></category>
      
        <category term="Shower thoughts"></category>
      
      <content type="html">
        <![CDATA[
          <div class="markdown"><p>Here's <a href="https://simonwillison.net/2024/Dec/22/link-blog/" style="--image-url: url('https://avatar.stefanjudis.com/https%3A%2F%2Fsimonwillison.net%2F2024%2FDec%2F22%2Flink-blog%2F')">Simon Willison explaining his approach to link blogging</a>. If you haven't heard of link blogging, it's social media's worst enemy.</p>
<p>Instead of feeding third-party platforms with your thoughts and relying on algorithms for people to discover them, you post links on your corner of the internet (aka your website). The world can then follow your updates via RSS. You might be surprised how much your RSS feed can feel like if you subscribe to enough link blogs.</p>
<p>But what if no one is following or reading along? What value do link posts have in your hidden internet corner?</p>
<p>There's a saying that every written post has a unique perspective. While this sentence holds for blog posts, I have a hard time finding the uniqueness of &quot;Check this out! [link]&quot; posts. Is it worth to put these on my site?</p>
<p>Here's Simon again:</p>
<blockquote>
<p>The value is in writing frequently and <strong>having something to show</strong> for it over time – worthwhile even if you don’t attract much of an audience (or any audience at all).</p>
</blockquote>
<p>Yes! &quot;Having something to show&quot; is a blog benefit we need to talk about more often.</p>
<p>From the beginning, blogging helped me build my professional network and get jobs. One of <a href="http://4waisenkinder.de/blog/2013/09/21/getting-started-with-web-components-and-polymer-dot-js/" style="--image-url: url('https://avatar.stefanjudis.com/http%3A%2F%2F4waisenkinder.de%2Fblog%2F2013%2F09%2F21%2Fgetting-started-with-web-components-and-polymer-dot-js%2F')">my first blog posts</a> got a bit of traction, and Googlers commented on it. Wild! Occasionally, people tell me that they know me from my blog. #wat?! 😅</p>
<p>But most importantly, I can (and do pretty often) show people this blog. Am I an expert in everything written here? Not at all... But having written about a topic often makes me more of an expert than someone who hasn't.</p>
<p>This blog played a role in most of my job interviews. Noted, I'm working in developer relations these days (writing is somewhat essential in this job), but either way, having a relevant online presence will earn you bonus points.</p>
<p>Because having a blog shows that you care. You care about the internet. You care about a specific topic. You care about sharing knowledge. You're into something.</p>
<p>Of course, running a blog in today's tech world and job market is not required, but having &quot;something to show&quot; is always better than having nothing to show, even if it's &quot;just&quot; a collection of relevant links. Hit publish and show it to the world!</p>
<div class="highlightBox info margin-top-xl margin-bottom-xl">
      
          <div class="cornerBubble">
            <svg aria-hidden="true">
              <use xlink:href="/sprite.svg#icon-info"/>
            </svg>
          </div>
        

      
      <p>If you want to get more of a social media feeling in your RSS reader, I can recommend these link feeds</p>
<ul>
<li><a href="https://hidde.blog/feed-links" style="--image-url: url('https://avatar.stefanjudis.com/https%3A%2F%2Fhidde.blog%2Ffeed-links')">Hidde's links</a></li>
<li><a href="https://simonwillison.net/atom/links/" style="--image-url: url('https://avatar.stefanjudis.com/https%3A%2F%2Fsimonwillison.net%2Fatom%2Flinks%2F')">Simon's blogmarks</a></li>
<li><a href="https://frontenddogma.com/posts/feed/" style="--image-url: url('https://avatar.stefanjudis.com/https%3A%2F%2Ffrontenddogma.com%2Fposts%2Ffeed%2F')">Frontend Dogma</a></li>
<li><a href="https://notes.jim-nielsen.com/feed.xml" style="--image-url: url('https://avatar.stefanjudis.com/https%3A%2F%2Fnotes.jim-nielsen.com%2Ffeed.xml')">Jim's Notes</a></li>
</ul>
</div></div>

          <a href="mailto:stefanjudis@gmail.com?subject=Re%3A%20To blog something to show">
            Reply to Stefan
          </a>
        ]]>
      </content>
    </entry>
    
    <entry>
      <title>
        Space shuttle style coding
      </title>
      <link href="https://www.stefanjudis.com/notes/space-shuttle-style-coding/"/>
      <published>2024-08-14T10:45:00+00:00</published>
      <updated>2024-08-14T10:45:00+00:00</updated>
      <id>
        https://www.stefanjudis.com/notes/space-shuttle-style-coding/
      </id>
      <category term="note"></category>
        <category term="Computer Science"></category>
      
      <content type="html">
        <![CDATA[
          <div class="markdown"><p>I learned about a new coding style today: the space shuttle.</p>
<p>It's described in <a href="https://github.com/kubernetes/kubernetes/blob/60c4c2b2521fb454ce69dee737e3eb91a25e0535/pkg/controller/volume/persistentvolume/pv_controller.go" style="--image-url: url('https://avatar.stefanjudis.com/https%3A%2F%2Fgithub.com%2Fkubernetes%2Fkubernetes%2Fblob%2F60c4c2b2521fb454ce69dee737e3eb91a25e0535%2Fpkg%2Fcontroller%2Fvolume%2Fpersistentvolume%2Fpv_controller.go')">the kubernetes source code</a>:</p>
<blockquote>
<p>This controller is intentionally written in a very verbose style. You will notice:</p>
<ol>
<li>Every 'if' statement has a matching 'else' (exception: simple error checks for a client API call)</li>
<li>Things that may seem obvious are commented explicitly</li>
</ol>
<p>We call this style <strong>'space shuttle style'</strong>. Space shuttle style is meant to ensure that every branch and condition is considered and accounted for - the same way code is written at NASA for applications like the space shuttle.</p>
</blockquote>
<p>I love it! Usually I'm not working on projects bringing people to space, but treating critical code with the same care seems like a good idea. 😅</p>
</div>

          <a href="mailto:stefanjudis@gmail.com?subject=Re%3A%20Space shuttle style coding">
            Reply to Stefan
          </a>
        ]]>
      </content>
    </entry>
    
    <entry>
      <title>
        Support your local content dealers
      </title>
      <link href="https://www.stefanjudis.com/notes/support-your-local-content-dealers/"/>
      <published>2024-06-10T22:00:00+00:00</published>
      <updated>2024-06-10T22:00:00+00:00</updated>
      <id>
        https://www.stefanjudis.com/notes/support-your-local-content-dealers/
      </id>
      <category term="note"></category>
        <category term="Shower thoughts"></category>
      
      <content type="html">
        <![CDATA[
          <div class="markdown"><p><a href="https://sidebar.io" style="--image-url: url('https://avatar.stefanjudis.com/https%3A%2F%2Fsidebar.io')">The Sidebar newsletter</a> was one of my primary sources when I started in webdev. Every workday, it shares (or used to share) web design links. <a href="https://sidebar.io/break/" style="--image-url: url('https://avatar.stefanjudis.com/https%3A%2F%2Fsidebar.io%2Fbreak%2F')">It's now taking a break</a>.</p>
<p>The reasons: lack of time, good content becoming less accessible and money.</p>
<p>Let's get to the last point. Sidebar wasn't a small newsletter. 60k people received five emails a week and <strong>it was not sustainable anymore</strong>. Wow!</p>
<p>Here's Sacha Greif talking about the money part:</p>
<div class="highlightBox quote margin-top-xl margin-bottom-xl">
      
          <div class="cornerBubble">
            <svg aria-hidden="true">
              <use xlink:href="/sprite.svg#icon-quote"/>
            </svg>
          </div>
        

      
      <blockquote>
<p>I could justify the time expenditure when Sidebar was self-sustaining, but for a while now the site has cost far more to run than it makes. It turns out, sending 20 emails a month to about 60,000 people costs quite a bit of money!</p>
<p>It’s admittedly my fault for not working harder at getting sponsors, but again: no time.</p>
</blockquote>
</div><p>Very sad. What many don't see, running a newsletter eats a ton of time.</p>
<p>Let's do some math: in Sidebar's case, we're talking about five weekly emails with a few links. That's quickly done, right?</p>
<p>To make things easy to calculate: let's ignore the content reading and curation part and assume that writing, grammar checking and sending these mails take an hour each.</p>
<p>This makes 5 hours a week, 20 hours a month, or roughly 250 hours a year. If we put an easy-to-calculate hourly rate of $100 next to this time, we end up looking at time worth $500 a week, $2000 a month and $25000 a year.</p>
<p>On top of that, sending over a million monthly emails (20 monthly emails sent to 60k subscribers) isn't cheap either. That's another few hundred dollars a month.</p>
<p>It's neither quickly done nor cheap.</p>
<p>Sacha points out that he failed to get enough sponsors on board. Meaning, he hasn't had time to knock on doors and ask for money. But is he really the one to blame for favoring sharing good stuff over putting ads in front of his readers? This feels off.</p>
<p>Good content is already becoming rare with AI and Search enshittification in full swing. Algorithms promote hate, drama, and &quot;engagement&quot;. The state of online content discovery is bad — really bad — and it won't get better soon.</p>
<p>So, what am I getting at here?</p>
<p>We, you and I need to <strong>support our local content dealers</strong>. Content creators, newsletters and curators are essential for discovering &quot;the good stuff&quot;™.</p>
<p>I'll revisit my content subscriptions and feeds this month to see whom I can support. If you can, you might want to do the same.</p>
<div class="highlightBox info margin-top-xl margin-bottom-xl">
      
          <div class="cornerBubble">
            <svg aria-hidden="true">
              <use xlink:href="/sprite.svg#icon-info"/>
            </svg>
          </div>
        

      
      <p>If you're looking for excellent content sources to support, I'll keep track of the ones I support:</p>
<ul>
<li><a href="https://csscade.com/" style="--image-url: url('https://avatar.stefanjudis.com/https%3A%2F%2Fcsscade.com%2F')">The Cascade</a> ($10 / year)</li>
<li><a href="https://openwebdocs.org/" style="--image-url: url('https://avatar.stefanjudis.com/https%3A%2F%2Fopenwebdocs.org%2F')">The Open Web docs</a> ($10 / month)</li>
<li><a href="https://css-tip.com/" style="--image-url: url('https://avatar.stefanjudis.com/https%3A%2F%2Fcss-tip.com%2F')">Temani Afif and their CSS magic</a> ($3 / month)</li>
<li><a href="https://www.404media.co" style="--image-url: url('https://avatar.stefanjudis.com/https%3A%2F%2Fwww.404media.co')">404 Media</a> ($10 / month)</li>
<li>🇩🇪 <a href="https://workingdraft.de/" style="--image-url: url('https://avatar.stefanjudis.com/https%3A%2F%2Fworkingdraft.de%2F')">Working Draft Podcast</a> (€5 / month)</li>
<li>🇩🇪 <a href="https://lagedernation.org/" style="--image-url: url('https://avatar.stefanjudis.com/https%3A%2F%2Flagedernation.org%2F')">Lage der Nation Podcast</a> (€5 / month)</li>
</ul>
<p>And if you're only looking for good web content, check <a href="/blogroll/">my blogroll</a>.</p>
</div><p>Either way, <strong>thanks, Sacha, for showing me the web dev and design ropes ten years ago! 💙</strong></p>
<hr aria-hidden="true"><p>Update: <a href="https://hachyderm.io/@sachagreif/112600110466766732" style="--image-url: url('https://avatar.stefanjudis.com/https%3A%2F%2Fhachyderm.io%2F%40sachagreif%2F112600110466766732')">Sacha himself has read this post and commented</a>:</p>
<blockquote>
<p>Just to be clear I definitely don't blame Sidebar readers for any of this, I'm sure if I had asked for payment or even donations I would've earned enough. It's really mostly about the time and focus.</p>
</blockquote>
</div>

          <a href="mailto:stefanjudis@gmail.com?subject=Re%3A%20Support your local content dealers">
            Reply to Stefan
          </a>
        ]]>
      </content>
    </entry>
    
    <entry>
      <title>
        Why do I fail at achieving personal goals?
      </title>
      <link href="https://www.stefanjudis.com/notes/failing-at-personal-goals/"/>
      <published>2024-04-04T22:00:00+00:00</published>
      <updated>2024-04-04T22:00:00+00:00</updated>
      <id>
        https://www.stefanjudis.com/notes/failing-at-personal-goals/
      </id>
      <category term="note"></category>
        <category term="Productivity"></category>
      
      <content type="html">
        <![CDATA[
          <div class="markdown"><p><strong>Disclaimer: I don't have the answer to this hefty post title</strong>, but <a href="https://jacobian.org/2024/apr/4/not-writing-about-productivity/" style="--image-url: url('https://avatar.stefanjudis.com/https%3A%2F%2Fjacobian.org%2F2024%2Fapr%2F4%2Fnot-writing-about-productivity%2F')">Jacob Kaplan-Moss just woke me up to think about life</a>. So, let's blog about it.</p>
<div class="highlightBox quote margin-top-xl margin-bottom-xl">
      
          <div class="cornerBubble">
            <svg aria-hidden="true">
              <use xlink:href="/sprite.svg#icon-quote"/>
            </svg>
          </div>
        

      
      <p>Why are you giving less time and attention to your personal goals than you give to work?</p>
</div><p>I don't know Jacob, but wow... this is an excellent and very uncomfortable question.</p>
<p>At work, I'm structured, focused and transparent. I have processes and guardrails in place to hit my targets. I reflect, write <a href="https://jvns.ca/blog/brag-documents/" style="--image-url: url('https://avatar.stefanjudis.com/https%3A%2F%2Fjvns.ca%2Fblog%2Fbrag-documents%2F')">brag documents</a>, and plan ahead. I hold myself accountable if I don't deliver. Being good at my job is important to me. Being a good colleague is important to me. And somehow, I succeed at all this (most of the time).</p>
<p>But looking into my private life, I've been hunting the same goals for years. Of course, my todo list includes the personal classics: &quot;Eat healthier!&quot;, &quot;Meditate!&quot;, &quot;Reflect!&quot;, &quot;Be kind and calm!&quot;. And these items are okay because we all struggle with them, right?</p>
<p>However, the list also includes quick tasks like filing taxes or calling loved family members and friends; I can ignore these for months.</p>
<p>I'd never treat a work task this way, but it's acceptable to ignore the private tasks. For whatever reason, <strong>it's fine to deprioritize the things that should matter most</strong>. Isn't this weird? Am I weird?</p>
<p>I've no idea why it's like it is or how I can fix my divided personality (does it even need fixing?), but Jacob's question hits home big time this early morning...</p>
</div>

          <a href="mailto:stefanjudis@gmail.com?subject=Re%3A%20Why do I fail at achieving personal goals?">
            Reply to Stefan
          </a>
        ]]>
      </content>
    </entry>
    
    <entry>
      <title>
        Bun&#39;s trusted dependencies
      </title>
      <link href="https://www.stefanjudis.com/notes/buns-trusted-dependencies/"/>
      <published>2024-04-02T22:00:00+00:00</published>
      <updated>2024-04-02T22:00:00+00:00</updated>
      <id>
        https://www.stefanjudis.com/notes/buns-trusted-dependencies/
      </id>
      <category term="note"></category>
        <category term="NodeJS"></category>
      
      <content type="html">
        <![CDATA[
          <div class="markdown"><p><a href="https://bun.sh/blog/bun-v1.1" style="--image-url: url('https://avatar.stefanjudis.com/https%3A%2F%2Fbun.sh%2Fblog%2Fbun-v1.1')">Bun <code>1<wbr>.1</code> was released</a>, and of course, &quot;Everything's faster&quot; — again.</p>
<p>Fun fact: the runtime added a native <code>stringWidth</code> method to evaluate character widths on the command line — and, wait for it... it's 6000x times faster than Sindre's <a href="https://www.npmjs.com/package/string-width" style="--image-url: url('https://avatar.stefanjudis.com/https%3A%2F%2Fwww.npmjs.com%2Fpackage%2Fstring-width')"><code>string-width</code></a>. I don't know, but I have a hard time taking these announcements seriously. In Bun, everything's &quot;just faster&quot; — it doesn't matter whether the improvement matters. Let's slap a big number onto it... 🤷</p>
<p>And while I remain skeptical of the new JS runtime, bundler, package manager, [ADD YOUR DESIRED JS TOOLING], and overall JavaScript BFF, I love that Bun's pushing the JS ecosystem.</p>
<p>You know that with <code>npm</code>, whenever you install dependencies, the installed packages can run arbitrary scripts via <code>postinstall</code>? Isn't this wild? And why doesn't the JS ecosystem collapse? Nobody knows.</p>
<p>Bun now tackles this problem with <a href="https://bun.sh/guides/install/trusted" style="--image-url: url('https://avatar.stefanjudis.com/https%3A%2F%2Fbun.sh%2Fguides%2Finstall%2Ftrusted')">trusted dependencies</a>. Mark packages as trustworthy with <code>bun pm trust</code>, add them to your <code>package<wbr>.json</code> and be a bit safer when downloading the internet to install your app's dependencies.</p>
<pre class="language-json"><code class="language-json"><span class="token punctuation">{</span>
  <span class="token property">"name"</span><span class="token operator">:</span> <span class="token string">"my-app"</span><span class="token punctuation">,</span>
  <span class="token property">"version"</span><span class="token operator">:</span> <span class="token string">"1.0.0"</span><span class="token punctuation">,</span>
  <span class="token property">"dependencies"</span><span class="token operator">:</span> <span class="token punctuation">{</span>
    <span class="token property">"@biomejs/biome"</span><span class="token operator">:</span> <span class="token string">"1.6.1"</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token property">"trustedDependencies"</span><span class="token operator">:</span> <span class="token punctuation">[</span>
    <span class="token string">"@biomejs/biome"</span>
  <span class="token punctuation">]</span>
<span class="token punctuation">}</span>
</code></pre>
<p>With trusted dependencies, you can define <strong>what packages are allowed to run lifecycle scripts when you run <code>bun install</code></strong>. If a package isn't trusted, it can't sniff out your environment variables or mine bitcoins — seems reasonable.</p>
<p>Let's see if there'll be an <code>npm</code> reaction.</p>
</div>

          <a href="mailto:stefanjudis@gmail.com?subject=Re%3A%20Bun&#39;s trusted dependencies">
            Reply to Stefan
          </a>
        ]]>
      </content>
    </entry>
    
    <entry>
      <title>
        Unit testing AI apps
      </title>
      <link href="https://www.stefanjudis.com/notes/ai-app-unit-testing/"/>
      <published>2024-03-31T22:00:00+00:00</published>
      <updated>2024-03-31T22:00:00+00:00</updated>
      <id>
        https://www.stefanjudis.com/notes/ai-app-unit-testing/
      </id>
      <category term="note"></category>
        <category term="AI"></category>
      
        <category term="Testing"></category>
      
      <content type="html">
        <![CDATA[
          <div class="markdown"><p>How do you evaluate your software's doing what it's supposed to do?</p>
<p>Do you test all your app's possible cases, branches and states? I don't, at least not manually. Nobody aint time to manually click through all the edge cases. QA'ing a simple login form takes time, let alone testing complex applications.</p>
<p>Having robots do that helps a ton, and I recommend writing automated tests to help you sleep well at night (and release fewer bugs)!</p>
<p>Ignoring the burden of writing and maintaining tests, testing a &quot;normal&quot; web application is straightforward because it's predictable. Throw something at your app and expect a result. It should always do the same. Most apps are CRUD apps anyway — easy peasy.</p>
<p><strong>But what if there are unpredictable parts in your app's core?</strong></p>
<p>If you're riding the AI buzzword wave, you probably implemented an &quot;I know everything&quot; smart-ass right in your app's core that's known for lying and spreading fake news. <em>(Yes, I mean some sort of LLM.)</em></p>
<p>How would you test your app's quality if you're building software on top of software you probably don't understand?</p>
<p>Here's Hamel Husain's recommendation:</p>
<blockquote>
<p>There are three levels of evaluation to consider:</p>
<ul>
<li>Level 1: Unit Tests</li>
<li>Level 2: Model &amp; Human Eval (this includes debugging)</li>
<li>Level 3: A/B testing</li>
</ul>
</blockquote>
<p>I'm not planning to get into serious AI work or LLM programming anytime soon, but <a href="https://hamel.dev/blog/posts/evals/" style="--image-url: url('https://avatar.stefanjudis.com/https%3A%2F%2Fhamel.dev%2Fblog%2Fposts%2Fevals%2F')">unit testing software sitting on top of LLMs</a> is fascinating and worth more than a bookmark!</p>
</div>

          <a href="mailto:stefanjudis@gmail.com?subject=Re%3A%20Unit testing AI apps">
            Reply to Stefan
          </a>
        ]]>
      </content>
    </entry>
    
    <entry>
      <title>
        disabled vs aria-disabled on form elements
      </title>
      <link href="https://www.stefanjudis.com/notes/disabled-vs-aria-disabled-on-form-elements/"/>
      <published>2024-03-29T23:00:00+00:00</published>
      <updated>2024-03-29T23:00:00+00:00</updated>
      <id>
        https://www.stefanjudis.com/notes/disabled-vs-aria-disabled-on-form-elements/
      </id>
      <category term="note"></category>
        <category term="Accessibility"></category>
      
        <category term="HTML"></category>
      
      <content type="html">
        <![CDATA[
          <div class="markdown"><p>I'll definitely reference the following blog post in the future. Kitty Giraudel describes <a href="https://kittygiraudel.com/2024/03/29/on-disabled-and-aria-disabled-attributes/" style="--image-url: url('https://avatar.stefanjudis.com/https%3A%2F%2Fkittygiraudel.com%2F2024%2F03%2F29%2Fon-disabled-and-aria-disabled-attributes%2F')">when to use <code>disabled</code> and <code>aria-disabled</code></a>.</p>
<p>Ready? Because here comes some solid HTML attribute advice.</p>
<div class="highlightBox quote margin-top-xl margin-bottom-xl">
      
          <div class="cornerBubble">
            <svg aria-hidden="true">
              <use xlink:href="/sprite.svg#icon-quote"/>
            </svg>
          </div>
        

      
      <blockquote>
<p>The <code>disabled</code> attribute is totally fine and should be used when relevant! What’s important is not to use it when the element’s interactivity is necessary to proceed, or when the lack of discoverability is problematic. In these cases, the aria-disabled attribute is better to still convey the same semantics, without impairing on usability.</p>
</blockquote>
</div><p>Generally, Kitty shares the following guidelines on when to use which attribute:</p>
<ol>
<li>Use <code>readonly</code> on elements which's values still matter to the user and should be sent to the server.</li>
<li>Use <code>disabled</code> on elements which's values became irrelevant for some reason.</li>
<li>Use <code>aria-disabled</code> on elements which's interactivity is essential to succeed, because they'll stay focusable and can still trigger validations.</li>
</ol>
<p>Great great guidelines!</p>
</div>

          <a href="mailto:stefanjudis@gmail.com?subject=Re%3A%20disabled vs aria-disabled on form elements">
            Reply to Stefan
          </a>
        ]]>
      </content>
    </entry>
    
    <entry>
      <title>
        The death of custom media queries
      </title>
      <link href="https://www.stefanjudis.com/notes/The-death-of-custom-media-queries/"/>
      <published>2024-03-09T23:00:00+00:00</published>
      <updated>2024-03-09T23:00:00+00:00</updated>
      <id>
        https://www.stefanjudis.com/notes/The-death-of-custom-media-queries/
      </id>
      <category term="note"></category>
        <category term="CSS"></category>
      
      <content type="html">
        <![CDATA[
          <div class="markdown"><p>You know the problem: you want to reuse custom properties in media queries but can't.</p>
<pre class="language-css"><code class="language-css"><span class="token selector">:root</span> <span class="token punctuation">{</span>
  <span class="token property">--width</span><span class="token punctuation">:</span> 20em<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token comment">/* this doesn't work :/ */</span>
<span class="token atrule"><span class="token rule">@media</span> <span class="token punctuation">(</span><span class="token property">min-width</span><span class="token punctuation">:</span> <span class="token function">var</span><span class="token punctuation">(</span>--width<span class="token punctuation">)</span><span class="token punctuation">)</span></span> <span class="token punctuation">{</span>
<span class="token punctuation">}</span>
</code></pre>
<p>I discovered the solution to this problem a while ago — <a href="https://www.stefanjudis.com/notes/can-we-have-custom-media-queries-please/">custom media queries</a>.</p>
<pre class="language-css"><code class="language-css"><span class="token comment">/* this isn't supported anywhere */</span>
<span class="token atrule"><span class="token rule">@custom-media</span> --narrow-window <span class="token punctuation">(</span><span class="token property">max-width</span><span class="token punctuation">:</span> 30em<span class="token punctuation">)</span><span class="token punctuation">;</span></span>

<span class="token atrule"><span class="token rule">@media</span> <span class="token punctuation">(</span>--narrow-window<span class="token punctuation">)</span></span> <span class="token punctuation">{</span>
  <span class="token comment">/* narrow window styles */</span>
<span class="token punctuation">}</span>
</code></pre>
<p>Unfortunately, as far as I know, custom media queries have never been implemented anywhere. Bummer.</p>
<p>However, the CSS evolution is still in full swing, and we have CSS features we couldn't even dream of years ago. <code>:has()</code>, native CSS nesting and container queries are ready to use.</p>
<p>With container queries, custom property style queries are slowly becoming a thing.</p>
<div class="highlightBox mdn margin-top-xl margin-bottom-xl">
        <div class="cornerBubble">
          <svg aria-hidden="true"><use xlink:href="/sprite.svg#icon-mdn"></use></svg>
        </div>
        <div class="highlightBox__header">MDN Compat Data (<a href="https://raw.githubusercontent.com/mdn/browser-compat-data/main/css/at-rules/container.json">source</a>)</div>
        <div class="highlightBox__body">
          <div class="highlightBox__overflow">
            <table class="highlightBox__compat">
              <caption>Browser support info for Style queries for custom properties </caption>
              <thead>
                <tr>
                  <td>
                        <img src="/assets/browsers/chrome.webp"
                              srcset="/assets/browsers/chrome.webp, /assets/browsers/chrome@2.webp 2x"
                              width="48" height="51" alt="chrome">
                      </td><td>
                        <img src="/assets/browsers/chrome_android.webp"
                              srcset="/assets/browsers/chrome_android.webp, /assets/browsers/chrome_android@2.webp 2x"
                              width="48" height="51" alt="chrome_android">
                      </td><td>
                        <img src="/assets/browsers/edge.webp"
                              srcset="/assets/browsers/edge.webp, /assets/browsers/edge@2.webp 2x"
                              width="48" height="51" alt="edge">
                      </td><td>
                        <img src="/assets/browsers/firefox.webp"
                              srcset="/assets/browsers/firefox.webp, /assets/browsers/firefox@2.webp 2x"
                              width="48" height="51" alt="firefox">
                      </td><td>
                        <img src="/assets/browsers/firefox_android.webp"
                              srcset="/assets/browsers/firefox_android.webp, /assets/browsers/firefox_android@2.webp 2x"
                              width="48" height="51" alt="firefox_android">
                      </td><td>
                        <img src="/assets/browsers/safari.webp"
                              srcset="/assets/browsers/safari.webp, /assets/browsers/safari@2.webp 2x"
                              width="48" height="51" alt="safari">
                      </td><td>
                        <img src="/assets/browsers/safari_ios.webp"
                              srcset="/assets/browsers/safari_ios.webp, /assets/browsers/safari_ios@2.webp 2x"
                              width="48" height="51" alt="safari_ios">
                      </td><td>
                        <img src="/assets/browsers/samsunginternet_android.webp"
                              srcset="/assets/browsers/samsunginternet_android.webp, /assets/browsers/samsunginternet_android@2.webp 2x"
                              width="48" height="51" alt="samsunginternet_android">
                      </td><td>
                        <img src="/assets/browsers/webview_android.webp"
                              srcset="/assets/browsers/webview_android.webp, /assets/browsers/webview_android@2.webp 2x"
                              width="48" height="51" alt="webview_android">
                      </td>
                </tr>
              </thead>
              <tbody>
                <tr>
                  <td>
                        <span class="highlightBox__pill success margin-top-s">
                        111
                        </span>
                      </td><td>
                        <span class="highlightBox__pill success margin-top-s">
                        111
                        </span>
                      </td><td>
                        <span class="highlightBox__pill success margin-top-s">
                        111
                        </span>
                      </td><td>
                        <span class="highlightBox__pill failure margin-top-s">
                        preview*
                        </span>
                      </td><td>
                        <span class="highlightBox__pill success margin-top-s">
                        preview
                        </span>
                      </td><td>
                        <span class="highlightBox__pill success margin-top-s">
                        18
                        </span>
                      </td><td>
                        <span class="highlightBox__pill success margin-top-s">
                        18
                        </span>
                      </td><td>
                        <span class="highlightBox__pill success margin-top-s">
                        22.0
                        </span>
                      </td><td>
                        <span class="highlightBox__pill success margin-top-s">
                        111
                        </span>
                      </td>
                </tr>
              </tbody>
            </table>
          </div>
<p><div class="padding-top-m fs-75" >* Please <a href="undefined">check MDN for more details</a>.</div></p>
<p></div>
</div></p>
<p>Could we use custom properties to formalize variables in media / container queries? <a href="https://thathtml.blog/2024/03/superpowered-container-style-queries/" style="--image-url: url('https://avatar.stefanjudis.com/https%3A%2F%2Fthathtml.blog%2F2024%2F03%2Fsuperpowered-container-style-queries%2F')">Here's Jared White doing just that</a>.</p>
<pre class="language-css"><code class="language-css"><span class="token selector">:root</span> <span class="token punctuation">{</span>
  <span class="token property">--is-mobile</span><span class="token punctuation">:</span> false<span class="token punctuation">;</span>

  <span class="token atrule"><span class="token rule">@media</span> <span class="token punctuation">(</span><span class="token property">max-width</span><span class="token punctuation">:</span> 500px<span class="token punctuation">)</span></span> <span class="token punctuation">{</span>
    <span class="token property">--is-mobile</span><span class="token punctuation">:</span> true<span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token selector">aside.sidebar</span> <span class="token punctuation">{</span>
  <span class="token property">font-size</span><span class="token punctuation">:</span> 1.5rem<span class="token punctuation">;</span>
  <span class="token property">line-height</span><span class="token punctuation">:</span> 1.5<span class="token punctuation">;</span>
  <span class="token property">font-weight</span><span class="token punctuation">:</span> 600<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token atrule"><span class="token rule">@container</span> <span class="token function">style</span><span class="token punctuation">(</span><span class="token property">--is-mobile</span><span class="token punctuation">:</span> true<span class="token punctuation">)</span></span> <span class="token punctuation">{</span>
  <span class="token selector">aside.sidebar</span> <span class="token punctuation">{</span>
    <span class="token property">font-size</span><span class="token punctuation">:</span> 1.1rem<span class="token punctuation">;</span>
    <span class="token property">line-height</span><span class="token punctuation">:</span> 1.25<span class="token punctuation">;</span>
    <span class="token property">font-weight</span><span class="token punctuation">:</span> 500<span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre>
<p>The style query approach is somewhat different than custom media queries, but it does the job. And if style queries for custom properties ship across browsers, we can call it for custom media queries.</p>
<p>They were a nice idea, but if a media / container query mix allows me to toggle and reuse custom properties based on viewport width, that does the trick for me.</p>
</div>

          <a href="mailto:stefanjudis@gmail.com?subject=Re%3A%20The death of custom media queries">
            Reply to Stefan
          </a>
        ]]>
      </content>
    </entry>
    
    <entry>
      <title>
        Forever projects
      </title>
      <link href="https://www.stefanjudis.com/notes/forever-projects/"/>
      <published>2024-03-02T23:00:00+00:00</published>
      <updated>2024-03-02T23:00:00+00:00</updated>
      <id>
        https://www.stefanjudis.com/notes/forever-projects/
      </id>
      <category term="note"></category>
        <category term="Shower thoughts"></category>
      
      <content type="html">
        <![CDATA[
          <div class="markdown"><p>I have the constant urge to &quot;do stuff&quot;. My to-do and idea lists are endless collections of things I'd love to do one day. But there's a problem — my side hustle schedule is pretty busy already.</p>
<p>I want to keep this blog active. <a href="https://webweekly.email/" style="--image-url: url('https://avatar.stefanjudis.com/https%3A%2F%2Fwebweekly.email%2F')">I run a weekly web development newsletter</a>. I maintain some open-source projects. <a href="https://tiny-helpers.dev/" style="--image-url: url('https://avatar.stefanjudis.com/https%3A%2F%2Ftiny-helpers.dev%2F')">I collect online tools</a>.</p>
<p>These projects alone eat a good chunk of my free time, and while I love doing them, they add up. There are only so many hours in the day.</p>
<p>For years, I ran <a href="https://twitter.com/randommdn" style="--image-url: url('https://avatar.stefanjudis.com/https%3A%2F%2Ftwitter.com%2Frandommdn')">the @randomMDN Twitter bot</a>. Then Elmo broke the Twitter APIs. I was puzzled. &quot;This is one of my projects; it can't just be over, can it?&quot; buzzed in my head. I've had a hard time letting go, I guess.</p>
<p>Fast forward. I hadn't had time to fix or deal with the problem, and it was over. Just like that, one of my projects dropped off the list.</p>
<div class="highlightBox info margin-top-xl margin-bottom-xl">
      
          <div class="cornerBubble">
            <svg aria-hidden="true">
              <use xlink:href="/sprite.svg#icon-info"/>
            </svg>
          </div>
        

      
      <p>Lovely people <a href="https://botsin.space/@randomMDN" style="--image-url: url('https://avatar.stefanjudis.com/https%3A%2F%2Fbotsin.space%2F%40randomMDN')">ported Random MDN to the Fediverse</a> if you want random web dev facts in your feed.</p>
</div><p>I realized I treat most projects as <em>&quot;forever projects&quot;</em>.</p>
<p>Of course, I work on this project every week. Of course, I'll answer these GitHub issues over the weekend. Of course, I keep this online resource up-to-date. <strong>And, of course, this isn't a sustainable.</strong></p>
<p>As Jamie Wilkinson puts it, <a href="https://dianaberlin.com/posts/no-more-forever-projects" style="--image-url: url('https://avatar.stefanjudis.com/https%3A%2F%2Fdianaberlin.com%2Fposts%2Fno-more-forever-projects')">he doesn't want to do forever projects anymore</a>. Everything has a shelf life. Kicking things off is great, but letting things go is as important.</p>
<div class="highlightBox quote margin-top-xl margin-bottom-xl">
      
          <div class="cornerBubble">
            <svg aria-hidden="true">
              <use xlink:href="/sprite.svg#icon-quote"/>
            </svg>
          </div>
        

      
      <blockquote>
<p>Treat beginnings like endings: celebrate them, document them.</p>
</blockquote>
</div><p>It's simple: to have time for new projects and passions, one has to let go.</p>
<div class="highlightBox quote margin-top-xl margin-bottom-xl">
      
          <div class="cornerBubble">
            <svg aria-hidden="true">
              <use xlink:href="/sprite.svg#icon-quote"/>
            </svg>
          </div>
        

      
      <blockquote>
<p>By ending well, you give yourself the freedom to begin again.</p>
</blockquote>
</div><p>Great advice.</p>
</div>

          <a href="mailto:stefanjudis@gmail.com?subject=Re%3A%20Forever projects">
            Reply to Stefan
          </a>
        ]]>
      </content>
    </entry>
</feed>
