<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet href="/pretty-feed.xsl" type="text/xsl"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Blog posts by Saneef</title>
  
    <link href="https://saneef.com/feed.xml" rel="self" />
    <link href="https://saneef.com" rel="alternate" type="text/html" />
    <updated>2026-04-08T09:16:00Z</updated>
    <id>https://saneef.com/</id>
    <author>
      <name>Saneef H. Ansari</name>
      <uri>https://saneef.com/</uri>
    </author><entry>
        <title>Learning notes 2026-W15</title>
        <link href="https://saneef.com/blog/learning-notes-2026-w15/" />
        <published>2026-04-10T03:30:00Z</published>
        <updated>2026-04-08T09:16:00Z</updated>
        <id>https://saneef.com/blog/learning-notes-2026-w15/</id>
        <content type="html"
          ><![CDATA[<h2 id="node.js-test-runner" tabindex="-1"><a href="https://nodejs.org/api/test.html">Node.js Test Runner</a><a class="link link--anchor" href="https://saneef.com/blog/learning-notes-2026-w15/#node.js-test-runner" aria-hidden="true" tabindex="-1"></a></h2> <p>This week, I learned that Node.js comes with a test runner. It has been included since <a href="https://nodejs.org/en/blog/release/v20.0.0#stable-test-runner">Node.js v20.0 (in 2023)</a>!</p> <p>Not that I write unit tests daily. Once in a while, I do write unit tests. At least in those cases, I don’t have to add another NPM dependency.</p> <h2 id="write-alt-text-like-you%E2%80%99re-talking-to-a-friend" tabindex="-1"><a href="https://cloudfour.com/thinks/write-alt-text-like-youre-talking-to-a-friend/">Write Alt Text Like You’re Talking To A Friend</a><a class="link link--anchor" href="https://saneef.com/blog/learning-notes-2026-w15/#write-alt-text-like-you%E2%80%99re-talking-to-a-friend" aria-hidden="true" tabindex="-1"></a></h2> <p>I religiously write alt-text for images. This old gem by Scott Vandehey points out a handful of mistakes I make.</p> <h2 id="developing-taste" tabindex="-1"><a href="https://emilkowal.ski/ui/developing-taste">Developing Taste</a><a class="link link--anchor" href="https://saneef.com/blog/learning-notes-2026-w15/#developing-taste" aria-hidden="true" tabindex="-1"></a></h2> <blockquote> <p>…what is good taste? It’s commonly mistaken as personal preference, but it’s more than that — it’s a trained instinct. The ability to see beyond the obvious and recognize what elevates</p> </blockquote> 
          


          ]]></content
        >
      </entry><entry>
        <title>Learning notes 2026-W14</title>
        <link href="https://saneef.com/blog/learning-notes-2026-w14/" />
        <published>2026-04-03T03:30:00Z</published>
        <updated>2026-04-03T14:41:48Z</updated>
        <id>https://saneef.com/blog/learning-notes-2026-w14/</id>
        <content type="html"
          ><![CDATA[<h2 id="designing-for-people-with-anxiety" tabindex="-1"><a href="https://tetralogical.com/blog/2026/03/10/designing-for-people-with-anxiety/">Designing for people with anxiety</a><a class="link link--anchor" href="https://saneef.com/blog/learning-notes-2026-w14/#designing-for-people-with-anxiety" aria-hidden="true" tabindex="-1"></a></h2> <p>In other words, how to make calm and transparent softwares for everyone.</p> <h2 id="beautiful-design-doesn%E2%80%99t-matter-for-the-reasons-you-think" tabindex="-1"><a href="https://www.ft.io/blog/beautiful-design/">Beautiful design doesn’t matter for the reasons you think</a><a class="link link--anchor" href="https://saneef.com/blog/learning-notes-2026-w14/#beautiful-design-doesn%E2%80%99t-matter-for-the-reasons-you-think" aria-hidden="true" tabindex="-1"></a></h2> <p>Frank writes about when is beautiful design important and when it isn’t.</p> <h2 id="designer-as-writer" tabindex="-1"><a href="https://stasaki.com/designer-as-writer/">Designer as Writer</a><a class="link link--anchor" href="https://saneef.com/blog/learning-notes-2026-w14/#designer-as-writer" aria-hidden="true" tabindex="-1"></a></h2> <p>Stas Aki explains first principles of design using principles of writing.</p> <blockquote> <p>When designers have nothing to say they wrap their designs into memes.</p> </blockquote> <p><em>Warning: the essay uses scroll driven animations.</em></p> 
          


          ]]></content
        >
      </entry><entry>
        <title>Learning notes 2026-W13</title>
        <link href="https://saneef.com/blog/learning-notes-2026-w13/" />
        <published>2026-03-28T03:30:00Z</published>
        <updated>2026-03-31T05:34:44Z</updated>
        <id>https://saneef.com/blog/learning-notes-2026-w13/</id>
        <content type="html"
          ><![CDATA[<h2 id="video%3A-a-solo-designer%E2%80%99s-survival-guide-to-the-fediverse" tabindex="-1"><a href="https://www.youtube.com/watch?v=oNxpTvbTy54">Video: A Solo Designer’s Survival Guide to the Fediverse</a><a class="link link--anchor" href="https://saneef.com/blog/learning-notes-2026-w13/#video%3A-a-solo-designer%E2%80%99s-survival-guide-to-the-fediverse" aria-hidden="true" tabindex="-1"></a></h2> <p><a href="https://mastodon.social/@imanijoy">Imani Joy</a> talks about her experience and challenges being a solo designer at Mastodon. I really like one of her idea from the talk, ‘decide who to disappoint.’</p> <h2 id="tools-for-thinking-and-tools-for-systems" tabindex="-1"><a href="https://css-tricks.com/tools-thinking-tools-systems/">Tools for Thinking and Tools for Systems</a><a class="link link--anchor" href="https://saneef.com/blog/learning-notes-2026-w13/#tools-for-thinking-and-tools-for-systems" aria-hidden="true" tabindex="-1"></a></h2> <p>A note from 2018 by <a href="https://robinrendle.com">Robin Rendle</a>, on need for…</p> <blockquote> <p>tools that help us think and that remove distractions so that we can focus on the larger and more important architectural, organizational and content problems that we ought to deal with first.</p> </blockquote> <h2 id="macintosh-checklist" tabindex="-1"><a href="https://marioaguzman.github.io/design/macintoshchecklist/">Macintosh Checklist</a><a class="link link--anchor" href="https://saneef.com/blog/learning-notes-2026-w13/#macintosh-checklist" aria-hidden="true" tabindex="-1"></a></h2> <p>About the checklist in Mario Guzman’s words:</p> <blockquote> <p>The following is a collection of features and conventions available on macOS that can help bring that same level of polish to your own app. By embracing these long-standing Mac-isms, you can elevate the experience of your software and make it feel like a natural citizen of the Macintosh ecosystem.</p> </blockquote> 
          


          ]]></content
        >
      </entry><entry>
        <title>Learning notes 2026-W12</title>
        <link href="https://saneef.com/blog/learning-notes-2026-w12/" />
        <published>2026-03-21T03:30:00Z</published>
        <updated>2026-03-31T05:18:42Z</updated>
        <id>https://saneef.com/blog/learning-notes-2026-w12/</id>
        <content type="html"
          ><![CDATA[<h2 id="video-%26-tutorial%3A-little-dummies-simple-fpo-content-helpers" tabindex="-1"><a href="https://cloudfour.com/thinks/little-dummies-simple-fpo-content-helpers/">Video &amp; Tutorial: Little Dummies Simple FPO Content Helpers</a><a class="link link--anchor" href="https://saneef.com/blog/learning-notes-2026-w12/#video-%26-tutorial%3A-little-dummies-simple-fpo-content-helpers" aria-hidden="true" tabindex="-1"></a></h2> <p>Tyler shows how his company wields Builds Awesome (previously 11ty 😜) for rapid prototyping. I really like how they create placeholder contents that reads realistic using helper functions in Build Awesome.</p> <h2 id="a-design-turn" tabindex="-1"><a href="https://www.jonkolko.com/writing/a-design-turn">A Design Turn</a><a class="link link--anchor" href="https://saneef.com/blog/learning-notes-2026-w12/#a-design-turn" aria-hidden="true" tabindex="-1"></a></h2> <blockquote> <p>This turn (of using Generative AI in design) says that we don’t need more people to make things. We need more people to be thoughtfully and meaningfully critical of the things that are made.</p> </blockquote> <h2 id="introducing-tods-%E2%80%93-a-typographic-and-opentype-default-stylesheet" tabindex="-1"><a href="https://clagnut.com/blog/2433">Introducing TODS – a typographic and OpenType default stylesheet</a><a class="link link--anchor" href="https://saneef.com/blog/learning-notes-2026-w12/#introducing-tods-%E2%80%93-a-typographic-and-opentype-default-stylesheet" aria-hidden="true" tabindex="-1"></a></h2> <p>I learned a few techniques about OpenType features in CSS from the article. I’m stealing some and adding them to my starter stylesheets.</p> 
          


          ]]></content
        >
      </entry><entry>
        <title>Learning notes 2026-W11</title>
        <link href="https://saneef.com/blog/learning-notes-2026-w11/" />
        <published>2026-03-13T03:30:00Z</published>
        <updated>2026-03-31T05:18:42Z</updated>
        <id>https://saneef.com/blog/learning-notes-2026-w11/</id>
        <content type="html"
          ><![CDATA[<h2 id="video%3A-a-typographer%E2%80%99s-view-of-optical-size" tabindex="-1"><a href="https://www.youtube.com/watch?v=rDhQyZHvUag">Video: A typographer’s view of optical size</a><a class="link link--anchor" href="https://saneef.com/blog/learning-notes-2026-w11/#video%3A-a-typographer%E2%80%99s-view-of-optical-size" aria-hidden="true" tabindex="-1"></a></h2> <p>I was confused about optical sizes in typefaces. Are they changes in weights? How do I utilise them in different contexts? Eber Sorkin explains the optical sizes in this talk from ISType 2024.</p> <h2 id="design-docs-considered-harmful" tabindex="-1"><a href="https://www.lucasfcosta.com/blog/design-docs">Design docs considered harmful</a><a class="link link--anchor" href="https://saneef.com/blog/learning-notes-2026-w11/#design-docs-considered-harmful" aria-hidden="true" tabindex="-1"></a></h2> <blockquote> <p>The fundamental problem with design docs is the same one that killed waterfall: you have the least information at the beginning of a project, which is exactly when design docs ask you to make the most decisions.</p> </blockquote> <h2 id="how-the-same-content-always-has-multiple-different-versions" tabindex="-1"><a href="https://a11yblog.com/2026/01/30/how-the-same-content-always-has-multiple-different-versions/">How the same content always has multiple different versions</a><a class="link link--anchor" href="https://saneef.com/blog/learning-notes-2026-w11/#how-the-same-content-always-has-multiple-different-versions" aria-hidden="true" tabindex="-1"></a></h2> <p>A short and illustrated article on how to make the text on the web accessible.</p> 
          


          ]]></content
        >
      </entry><entry>
        <title>Create pages from JSON files with Eleventy</title>
        <link href="https://saneef.com/blog/create-pages-from-json-files-with-eleventy/" />
        <published>2026-02-26T03:30:00Z</published>
        <updated>2026-02-26T13:52:16Z</updated>
        <id>https://saneef.com/blog/create-pages-from-json-files-with-eleventy/</id>
        <content type="html"
          ><![CDATA[<p>A few days ago <a href="https://sunny.garden/@kayserifserif/116118026044330191">Katherine asked</a>: in Eleventy, is there a way to generate pages from separate data (like <code>person-a.json</code>, <code>person-b.json</code>, …) instead of single data file with all the data. Right after seeing the question, I wrote up <a href="https://github.com/saneef/11ty-pages-from-json/blob/main/src/index.11tydata.js">a JS script</a> which reads all JSON files in a specified folder, combines them into an array and passes them as data to Eleventy. I had the feeling I was going against the Eleventy’s grain. Anyway, it worked.</p> <p>Today, I stumbled upon <a href="https://codeberg.org/ashur/demo-nested-data">the solution</a> by <a href="https://front-end.social/@ashur">Ashur</a>. A solution that is <em>going with the Eleventy’s grain!</em> A reminder for me to RTFM.</p> <p>I spent some time going through it to understand how it works, and here are my learning notes. You can find the working prototype in <a href="https://codeberg.org/saneef/11ty-prototype-pages-from-json">this repo</a>.</p> <h2 id="loading-json-files-as-eleventy-data" tabindex="-1">Loading JSON files as Eleventy Data<a class="link link--anchor" href="https://saneef.com/blog/create-pages-from-json-files-with-eleventy/#loading-json-files-as-eleventy-data" aria-hidden="true" tabindex="-1"></a></h2> <p>Eleventy natively supports <a href="https://www.11ty.dev/docs/data-global/#folders">loading JSON files as data</a>. The JSON (or JS files) kept within the <code>_data</code> folder (which can be changed <a href="https://www.11ty.dev/docs/config/#directory-for-global-data-files">through config</a>) will be loaded as data.</p> <p>Consider these files:</p> <pre class="language-txt"><code class="language-txt">src<br>└── _data<br>    └── possums<br>        ├── possum-01.json<br>        └── possum-02.json</code></pre> <p>…with content</p> <pre class="language-js"><code class="language-js"><span class="token comment">// src/_data/possums/possum-01.json</span><br><span class="token punctuation">{</span><br>  <span class="token string-property property">"name"</span><span class="token operator">:</span> <span class="token string">"First Possum"</span><span class="token punctuation">,</span><br>  <span class="token string-property property">"age"</span><span class="token operator">:</span> <span class="token number">1</span><br><span class="token punctuation">}</span><br><br><span class="token comment">// src/_data/possums/possum-02.json</span><br><span class="token punctuation">{</span><br>  <span class="token string-property property">"name"</span><span class="token operator">:</span> <span class="token string">"Second Possum"</span><span class="token punctuation">,</span><br>  <span class="token string-property property">"age"</span><span class="token operator">:</span> <span class="token number">2</span><br><span class="token punctuation">}</span></code></pre> <p>In the template you can access <code>possum</code> as an object with base filenames keys and their content as values.</p> <pre class="language-json"><code class="language-json"><span class="token punctuation">{</span><br>  <span class="token property">"possum-01"</span><span class="token operator">:</span> <span class="token punctuation">{</span><br>    <span class="token property">"name"</span><span class="token operator">:</span> <span class="token string">"First Possum"</span><span class="token punctuation">,</span><br>    <span class="token property">"age"</span><span class="token operator">:</span> <span class="token number">1</span><br>  <span class="token punctuation">}</span><span class="token punctuation">,</span><br>  <span class="token property">"possum-02"</span><span class="token operator">:</span> <span class="token punctuation">{</span><br>    <span class="token property">"name"</span><span class="token operator">:</span> <span class="token string">"Second Possum"</span><span class="token punctuation">,</span><br>    <span class="token property">"age"</span><span class="token operator">:</span> <span class="token number">2</span><br>  <span class="token punctuation">}</span><br><span class="token punctuation">}</span></code></pre> <p>I can generate a list of possums in Nunjucks with:</p> <pre class="language-nunjucks"><code class="language-nunjucks"><span class="token operator">&lt;</span><span class="token variable">ul</span><span class="token operator">></span><br><span class="token punctuation">{</span><span class="token operator">%</span> <span class="token keyword">for</span> <span class="token variable">key</span><span class="token punctuation">,</span> <span class="token variable">value</span> <span class="token keyword">in</span> <span class="token variable">possums</span> <span class="token operator">%</span><span class="token punctuation">}</span><br>  <span class="token operator">&lt;</span><span class="token variable">li</span><span class="token operator">></span><span class="token punctuation">{</span><span class="token punctuation">{</span> <span class="token variable">value</span><span class="token punctuation">.</span><span class="token variable">name</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token operator">&lt;</span><span class="token operator">/</span><span class="token variable">li</span><span class="token operator">></span><br><span class="token punctuation">{</span><span class="token operator">%</span> <span class="token variable">endfor</span> <span class="token operator">%</span><span class="token punctuation">}</span><br><span class="token operator">&lt;</span><span class="token operator">/</span><span class="token variable">ul</span><span class="token operator">></span><br></code></pre> <h2 id="creating-pages" tabindex="-1">Creating pages<a class="link link--anchor" href="https://saneef.com/blog/create-pages-from-json-files-with-eleventy/#creating-pages" aria-hidden="true" tabindex="-1"></a></h2> <p>Eleventy can <a href="https://www.11ty.dev/docs/pages-from-data/">generate pages from data</a>. Like you have seen earlier, the data from the JSON files are loaded as an <code>object</code>. Eleventy has <a href="https://www.11ty.dev/docs/pagination/#paging-an-object">some tricks</a> under its sleeve for that too!</p> <p>By default, when paging an object in Eleventy it provides each <code>key</code> as the value. Using pagination front matter <code>resolve: values</code>, Eleventy provides each <code>value</code> without having to use <code>object[key]</code> to get the value.</p> <pre class="language-nunjucks"><code class="language-nunjucks"><span class="token operator">-</span><span class="token operator">-</span><span class="token operator">-</span><br><span class="token variable">pagination</span><span class="token punctuation">:</span><br>  <span class="token variable">data</span><span class="token punctuation">:</span> <span class="token variable">possums</span><br>  <span class="token variable">alias</span><span class="token punctuation">:</span> <span class="token variable">possum</span><br>  <span class="token variable">resolve</span><span class="token punctuation">:</span> <span class="token variable">values</span> # 🪄 <span class="token variable">Iterates</span> <span class="token variable">over</span> <span class="token variable">values</span><span class="token punctuation">,</span> <span class="token variable">instead</span> <span class="token variable">of</span> <span class="token variable">keys</span><br>  <span class="token variable">size</span><span class="token punctuation">:</span> <span class="token number">1</span><br><span class="token variable">permalink</span><span class="token punctuation">:</span> <span class="token string">"possums/{{ possum.name | slugify }}/"</span><br><span class="token operator">-</span><span class="token operator">-</span><span class="token operator">-</span><br><br><span class="token punctuation">{</span><span class="token punctuation">{</span> <span class="token variable">possum</span><span class="token punctuation">.</span><span class="token variable">name</span> <span class="token punctuation">}</span><span class="token punctuation">}</span> <span class="token keyword">is</span> <span class="token punctuation">{</span><span class="token punctuation">{</span> <span class="token variable">possum</span><span class="token punctuation">.</span><span class="token variable">age</span> <span class="token punctuation">}</span><span class="token punctuation">}</span> <span class="token variable">years</span> <span class="token variable">old</span><br></code></pre> <hr> <p>If JSON is not your thing, you can use <a href="https://www.11ty.dev/docs/data-custom/">YAML, TOML or any other data format</a> for maintaining data with Eleventy.</p> 
          


          ]]></content
        >
      </entry><entry>
        <title>Learning notes 2026-W08</title>
        <link href="https://saneef.com/blog/learning-notes-2026-w08/" />
        <published>2026-02-21T03:30:00Z</published>
        <updated>2026-03-31T05:18:42Z</updated>
        <id>https://saneef.com/blog/learning-notes-2026-w08/</id>
        <content type="html"
          ><![CDATA[<h2 id="judge-the-contents%2C-not-the-box" tabindex="-1"><a href="https://sive.rs/u35">Judge the contents, not the box</a><a class="link link--anchor" href="https://saneef.com/blog/learning-notes-2026-w08/#judge-the-contents%2C-not-the-box" aria-hidden="true" tabindex="-1"></a></h2> <blockquote> <p>Listen to ideas, not their messenger. Focus on the contents, not the box. Avoid ideology.</p> </blockquote> <p>I struggle with this bias a lot. I find it hard to separate the message from the messenger. Another to thing to work on.</p> <h2 id="unsung-heroes-flickr%E2%80%99s-urls-scheme" tabindex="-1"><a href="https://unsung.aresluna.org/unsung-heroes-flickrs-urls-scheme/">Unsung heroes Flickr’s URLs scheme</a><a class="link link--anchor" href="https://saneef.com/blog/learning-notes-2026-w08/#unsung-heroes-flickr%E2%80%99s-urls-scheme" aria-hidden="true" tabindex="-1"></a></h2> <blockquote> <p>It was a beautiful and predictable scheme. Once you knew how it worked, you could guess other URLs. If I were typing an email or authoring a blog post and I happened to have a link to your photo in Flickr, I could also easily include a link to your Flickr homepage just by editing the URL, without having to jump back to the browser to verify.</p> </blockquote> <p>I’m a big fan of well designed URLs.</p> <h2 id="hanoi-%26-the-many-faces-of-northern-vietnam" tabindex="-1"><a href="https://theflore.com/blog-posts/2026/02/16/vietnam-hanoi-catba-mountains">Hanoi &amp; the Many Faces of Northern Vietnam</a><a class="link link--anchor" href="https://saneef.com/blog/learning-notes-2026-w08/#hanoi-%26-the-many-faces-of-northern-vietnam" aria-hidden="true" tabindex="-1"></a></h2> <p>I virtually experienced Hanoi and nearby places through Florian’s beautiful pictures.</p> 
          


          ]]></content
        >
      </entry><entry>
        <title>Learning notes 2026-W07</title>
        <link href="https://saneef.com/blog/learning-notes-2026-w07/" />
        <published>2026-02-13T03:30:00Z</published>
        <updated>2026-03-31T05:18:42Z</updated>
        <id>https://saneef.com/blog/learning-notes-2026-w07/</id>
        <content type="html"
          ><![CDATA[<h2 id="not-all-browser-apis-are-%E2%80%9Cweb%E2%80%9D-apis" tabindex="-1"><a href="https://polypane.app/blog/not-all-browser-apis-are-web-apis/">Not All Browser APIs Are “Web” APIs</a><a class="link link--anchor" href="https://saneef.com/blog/learning-notes-2026-w07/#not-all-browser-apis-are-%E2%80%9Cweb%E2%80%9D-apis" aria-hidden="true" tabindex="-1"></a></h2> <blockquote> <p>The interface is standardized. The specification is maintained by the W3C. The docs on MDN are excellent. But the actual implementation? That’s entirely up to the browser vendor.</p> </blockquote> <p>I was wrong to believe that all Web APIs are private.</p> <h2 id="backseat-software" tabindex="-1"><a href="https://blog.mikeswanson.com/backseat-software/">Backseat Software</a><a class="link link--anchor" href="https://saneef.com/blog/learning-notes-2026-w07/#backseat-software" aria-hidden="true" tabindex="-1"></a></h2> <blockquote> <p>Software didn’t break all at once. It eroded slowly, one reasonable justification at a time.</p> <p>Each step made sense in isolation, and each step could be defended. Together, they reshaped the priorities of an entire industry. Once software became measurable in this way, it became optimizable in this way. And optimization has a way of eating everything else.</p> </blockquote> <p>Mike Swanson gives us a short history of enshittified software and guidances to makes them better.</p> <h2 id="easy-measures-doing%2C-simple-measures-understanding" tabindex="-1"><a href="https://blog.jim-nielsen.com/2026/easy-vs-simple/">Easy Measures Doing, Simple Measures Understanding</a><a class="link link--anchor" href="https://saneef.com/blog/learning-notes-2026-w07/#easy-measures-doing%2C-simple-measures-understanding" aria-hidden="true" tabindex="-1"></a></h2> <blockquote> <p>Easy means you can do with little effort. Simple means you can understand what you do with little effort.</p> </blockquote> 
          


          ]]></content
        >
      </entry><entry>
        <title>Learning notes 2026-W06</title>
        <link href="https://saneef.com/blog/learning-notes-2026-w06/" />
        <published>2026-02-06T03:30:00Z</published>
        <updated>2026-03-31T05:18:42Z</updated>
        <id>https://saneef.com/blog/learning-notes-2026-w06/</id>
        <content type="html"
          ><![CDATA[<h2 id="how-ai-is-redefining-the-way-we-find-content" tabindex="-1"><a href="https://clearleft.com/thinking/how-ai-is-redefining-the-way-we-find-content">How AI is redefining the way we find content</a><a class="link link--anchor" href="https://saneef.com/blog/learning-notes-2026-w06/#how-ai-is-redefining-the-way-we-find-content" aria-hidden="true" tabindex="-1"></a></h2> <p>It looks like the SEO Specialists will be recasting themselves as the Generative Engine Optimisation (GEO) Specialists very soon. Like always, the article emphasizes the importance of getting the fundamentals right: good quality content, structured data and keeping the content up to date.</p> <h2 id="some-css-only-contrast-options-until-contrast-color()-is-baseline-widely-available" tabindex="-1"><a href="https://piccalil.li/blog/some-css-only-contrast-options-until-contrast-color-is-baseline-widely-available/">Some CSS only contrast options until contrast-color() is Baseline widely available</a><a class="link link--anchor" href="https://saneef.com/blog/learning-notes-2026-w06/#some-css-only-contrast-options-until-contrast-color()-is-baseline-widely-available" aria-hidden="true" tabindex="-1"></a></h2> <p>In a way, I like Donnie’s solution better than the browser implementation of <code>contrast-color()</code>. The browse implementation gives us either <code>black</code> or <code>white</code>. Donnie shares a method that can blend the generated contrast colour with the background to create more harmonious combinations. He does some CSS wizardry there.</p> <h2 id="front-load-key-words" tabindex="-1"><a href="https://sketchplanations.com/front-load-key-words">Front-load Key Words</a><a class="link link--anchor" href="https://saneef.com/blog/learning-notes-2026-w06/#front-load-key-words" aria-hidden="true" tabindex="-1"></a></h2> <p>A good technique to keep under your belt while writing for web. It is like <a href="https://mattstromawn.com/writing/bluf/">BLUF</a>, but for short text.</p> 
          


          ]]></content
        >
      </entry><entry>
        <title>Learning notes 2026-W05</title>
        <link href="https://saneef.com/blog/learning-notes-2026-w05/" />
        <published>2026-01-30T14:00:00Z</published>
        <updated>2026-03-31T05:18:42Z</updated>
        <id>https://saneef.com/blog/learning-notes-2026-w05/</id>
        <content type="html"
          ><![CDATA[<p>I didn’t put out any notes in 2026-W04, in case you were wondering.</p> <h2 id="how-an-accessibility-designer-adds-keyboard-shortcuts-to-a-web-app" tabindex="-1"><a href="https://ericwbailey.website/published/how-an-accessibility-designer-adds-keyboard-shortcuts-to-a-web-app/">How an accessibility designer adds keyboard shortcuts to a web app</a><a class="link link--anchor" href="https://saneef.com/blog/learning-notes-2026-w05/#how-an-accessibility-designer-adds-keyboard-shortcuts-to-a-web-app" aria-hidden="true" tabindex="-1"></a></h2> <p>Don’t break accessibility by adding accessibility features.</p> <h2 id="a-culture-of-work-we-believe-in" tabindex="-1"><a href="https://www.fathom.info/notebook/260109/">A culture of work we believe in</a><a class="link link--anchor" href="https://saneef.com/blog/learning-notes-2026-w05/#a-culture-of-work-we-believe-in" aria-hidden="true" tabindex="-1"></a></h2> <p><a href="https://www.fathom.info">Fathom’s</a> take on generative AI. It’s a relief to know that there are folks who still believe in real expertise and collaboration.</p> <h2 id="5-accessibility-checks-to-run-on-every-component" tabindex="-1"><a href="https://zeroheight.com/blog/5-accessibility-checks-to-run-on-every-component/">5 accessibility checks to run on every component</a><a class="link link--anchor" href="https://saneef.com/blog/learning-notes-2026-w05/#5-accessibility-checks-to-run-on-every-component" aria-hidden="true" tabindex="-1"></a></h2> <p><a href="https://hidde.blog/about-me/">Hidde</a> lists some high-impact accessibility checks that we can do to improve our design systems.</p> 
          


          ]]></content
        >
      </entry><entry>
        <title>Learning notes 2026-W03</title>
        <link href="https://saneef.com/blog/learning-notes-2026-w03/" />
        <published>2026-01-16T03:30:00Z</published>
        <updated>2026-03-31T05:18:42Z</updated>
        <id>https://saneef.com/blog/learning-notes-2026-w03/</id>
        <content type="html"
          ><![CDATA[<h2 id="we%E2%80%99re-just-temporarily-abled" tabindex="-1"><a href="https://uxmag.com/articles/were-just-temporarily-abled">We’re Just Temporarily Abled</a><a class="link link--anchor" href="https://saneef.com/blog/learning-notes-2026-w03/#we%E2%80%99re-just-temporarily-abled" aria-hidden="true" tabindex="-1"></a></h2> <p>Don’t forget our future selves when designing products.</p> <h2 id="so-you-wanna-de-bog-yourself" tabindex="-1"><a href="https://www.experimental-history.com/p/so-you-wanna-de-bog-yourself">So you wanna de-bog yourself</a><a class="link link--anchor" href="https://saneef.com/blog/learning-notes-2026-w03/#so-you-wanna-de-bog-yourself" aria-hidden="true" tabindex="-1"></a></h2> <p>We feel stuck in many stages of our life. Adam classified those baffling states with funny names and shares some clues how to get out of them.</p> <h2 id="you-can%E2%80%99t-design-software-you-don%E2%80%99t-work-on" tabindex="-1"><a href="https://www.seangoedecke.com/you-cant-design-software-you-dont-work-on/">You can’t design software you don’t work on</a><a class="link link--anchor" href="https://saneef.com/blog/learning-notes-2026-w03/#you-can%E2%80%99t-design-software-you-don%E2%80%99t-work-on" aria-hidden="true" tabindex="-1"></a></h2> <p>Contextual knowledge is more important in software projects than generic knowledge. Both influence differently in the successes and failures of projects.</p> 
          


          ]]></content
        >
      </entry><entry>
        <title>Learning notes 2026-W02</title>
        <link href="https://saneef.com/blog/learning-notes-2026-w02/" />
        <published>2026-01-10T17:00:00Z</published>
        <updated>2026-03-31T05:18:42Z</updated>
        <id>https://saneef.com/blog/learning-notes-2026-w02/</id>
        <content type="html"
          ><![CDATA[<h2 id="response-times%3A-the-3-important-limits" tabindex="-1"><a href="https://www.nngroup.com/articles/response-times-3-important-limits/">Response Times: The 3 Important Limits</a><a class="link link--anchor" href="https://saneef.com/blog/learning-notes-2026-w02/#response-times%3A-the-3-important-limits" aria-hidden="true" tabindex="-1"></a></h2> <p>Rereading Jakob Nielsen’s article from 1993. I find it a good refresher on practical time durations for user interface interactions and the feedback mechanisms. One of the time durations he mentions is 0.1 seconds. If an interaction can be completed within this timeframe, users feel a sense of control, as if they are actively manipulating the data. On the other hand, if the interaction exceeds 0.2 seconds, users may feel like they are instructing the computer to perform the manipulation. I like such notions.</p> <h2 id="video%3A-fast-tracking-inclusive-testing" tabindex="-1"><a href="https://www.youtube.com/watch?v=1cYQYLzA7y8">Video: Fast-Tracking inclusive Testing</a><a class="link link--anchor" href="https://saneef.com/blog/learning-notes-2026-w02/#video%3A-fast-tracking-inclusive-testing" aria-hidden="true" tabindex="-1"></a></h2> <p>Michelle shows how to optimise the accessibility testing strategy to have better coverage.</p> <h2 id="the-future-of-software-development-is-software-developers" tabindex="-1"><a href="https://codemanship.wordpress.com/2025/11/25/the-future-of-software-development-is-software-developers/">The Future of Software Development is Software Developers</a><a class="link link--anchor" href="https://saneef.com/blog/learning-notes-2026-w02/#the-future-of-software-development-is-software-developers" aria-hidden="true" tabindex="-1"></a></h2> <p>Jason Gorman takes us through various ‘___ is going to replace programmers’ cycles from the past. He writes why that is not going to happen in the near future.</p> <blockquote> <p>The hard part of computer programming isn’t expressing what we want the machine to do in code. The hard part is turning human thinking – with all its wooliness and ambiguity and contradictions – into <em>computational thinking</em> that is logically precise and unambiguous, and that can then be expressed formally in the syntax of a programming language.</p> </blockquote> <p>I came across this article through <a href="https://blog.jim-nielsen.com/2025/making-software-is-translating-intent/">a post by Jim Nielsen</a>.</p> 
          


          ]]></content
        >
      </entry><entry>
        <title>Learning notes 2026-W01</title>
        <link href="https://saneef.com/blog/learning-notes-2026-w01/" />
        <published>2026-01-02T03:30:00Z</published>
        <updated>2026-03-31T05:18:42Z</updated>
        <id>https://saneef.com/blog/learning-notes-2026-w01/</id>
        <content type="html"
          ><![CDATA[<h2 id="design-is-more-than-code" tabindex="-1"><a href="https://linear.app/now/design-is-more-than-code">Design is more than code</a><a class="link link--anchor" href="https://saneef.com/blog/learning-notes-2026-w01/#design-is-more-than-code" aria-hidden="true" tabindex="-1"></a></h2> <blockquote> <p>Our industry is not very patient, and once you start building designs directly to production as the default, the culture and organizational reasons to consider problems, concepts, and intentions start evaporating. We start devaluing the why behind our designs in favor of output.</p> </blockquote> <p>Karri presents the value of designing the problem and solutions in stages.</p> <h2 id="our-interfaces-have-lost-their-senses" tabindex="-1"><a href="https://wattenberger.com/thoughts/our-interfaces-have-lost-their-senses">Our interfaces have lost their senses</a><a class="link link--anchor" href="https://saneef.com/blog/learning-notes-2026-w01/#our-interfaces-have-lost-their-senses" aria-hidden="true" tabindex="-1"></a></h2> <p>I agree to Amelia’s message. The human computer interfaces are devolving in modalities and converging on ‘touches on glass.’ We should explore more ways of interactions.</p> <p>At the same time, I find the essay somewhat ironic. She talks about joy of doing by hand, the feel of pen on paper, the whole essay is filled with AI generated images.</p> <h2 id="how-to-complain" tabindex="-1"><a href="https://outerproduct.net/trivial/2024-03-25_complain.html">How to complain</a><a class="link link--anchor" href="https://saneef.com/blog/learning-notes-2026-w01/#how-to-complain" aria-hidden="true" tabindex="-1"></a></h2> <p>It’s difficult to change other people’s opinions. You have a better chance by presenting your perspective without antagonizing them. This article shows how to write such propositions.</p> <h2 id="how-to-win" tabindex="-1"><a href="https://www.todepond.com/sky/how-to-win/">How to win</a><a class="link link--anchor" href="https://saneef.com/blog/learning-notes-2026-w01/#how-to-win" aria-hidden="true" tabindex="-1"></a></h2> <p>Lu uses her tennis experience to teach about elements that help you succeed.</p> 
          


          ]]></content
        >
      </entry><entry>
        <title>Learning notes 2025-W52</title>
        <link href="https://saneef.com/blog/learning-notes-2025-w52/" />
        <published>2025-12-26T03:30:00Z</published>
        <updated>2026-03-31T05:18:42Z</updated>
        <id>https://saneef.com/blog/learning-notes-2025-w52/</id>
        <content type="html"
          ><![CDATA[<h2 id="the-aura-of-care" tabindex="-1"><a href="https://fasterandworse.com/the-aura-of-care/">The Aura of Care</a><a class="link link--anchor" href="https://saneef.com/blog/learning-notes-2025-w52/#the-aura-of-care" aria-hidden="true" tabindex="-1"></a></h2> <blockquote> <p>UX needs to make clear distinctions between commercial design work and design as a social good so the aura of care is not just an aura. Until that happens we’ll continue to see the worst companies hire the best people to help them make the worst things.</p> </blockquote> <p>A harsh reminder that most of the instances of care, delivered through design, are shallow. It pains me to realize that I’m also a part of that narrative.</p> <h2 id="thinking-about-design" tabindex="-1"><a href="https://www.muledesign.com/blog/design-thinking">Thinking About Design</a><a class="link link--anchor" href="https://saneef.com/blog/learning-notes-2025-w52/#thinking-about-design" aria-hidden="true" tabindex="-1"></a></h2> <p>On a similar note, though design thinking is so pervasive, why do we fail to create real care?</p> <blockquote> <p>Design is fundamentally intention, so doing the wrong thing with greater intention only makes it more wrong.</p> <p>There’s nothing particularly transformative or humane about reproducing and strengthening harmful systems, or getting into new lines of business that are doomed to fail because they exceed the capabilities, capacity, or true purview of an organization.</p> </blockquote> <h2 id="aborting-async-javascript" tabindex="-1"><a href="https://lea.codes/posts/2025-09-07-aborting-async-javascript/">Aborting async JavaScript</a><a class="link link--anchor" href="https://saneef.com/blog/learning-notes-2025-w52/#aborting-async-javascript" aria-hidden="true" tabindex="-1"></a></h2> <p>I learned how to give an exit hatch for JavaScript async functions from <a href="http://lea.codes">Lea</a>.</p> <h2 id="i-am-sorry%2C-but-everyone-is-getting-syntax-highlighting-wrong" tabindex="-1"><a href="https://tonsky.me/blog/syntax-highlighting/">I am sorry, but everyone is getting syntax highlighting wrong</a><a class="link link--anchor" href="https://saneef.com/blog/learning-notes-2025-w52/#i-am-sorry%2C-but-everyone-is-getting-syntax-highlighting-wrong" aria-hidden="true" tabindex="-1"></a></h2> <blockquote> <p>If everything is highlighted, nothing is highlighted.</p> </blockquote> <p>I started using a colour scheme with few highlights, and I’m liking it.</p> 
          


          ]]></content
        >
      </entry><entry>
        <title>Learning notes 2025-W51</title>
        <link href="https://saneef.com/blog/learning-notes-2025-w51/" />
        <published>2025-12-19T03:30:00Z</published>
        <updated>2026-03-31T05:18:42Z</updated>
        <id>https://saneef.com/blog/learning-notes-2025-w51/</id>
        <content type="html"
          ><![CDATA[<h2 id="github-killed-toasts" tabindex="-1"><a href="https://primer.style/accessibility/patterns/accessible-notifications-and-messages/#toasts">Github killed Toasts</a><a class="link link--anchor" href="https://saneef.com/blog/learning-notes-2025-w51/#github-killed-toasts" aria-hidden="true" tabindex="-1"></a></h2> <p>They did it for the right reasons. The toasts have a lot of accessibility problems. The guide provides alternatives for different contexts. In some simple cases, we don’t need to communicate success as they are self-evident.</p> <h2 id="taking-away-opportunities-from-the-next-generation" tabindex="-1"><a href="https://people-work.io/blog/junior-hiring-crisis/">Taking away opportunities from the next generation</a><a class="link link--anchor" href="https://saneef.com/blog/learning-notes-2025-w51/#taking-away-opportunities-from-the-next-generation" aria-hidden="true" tabindex="-1"></a></h2> <p>One of the unintended consequences of AI adoption across the industry is that it’s getting harder for the next generation to get their first job. When a company shoves AI onto their workforce, the jobs meant for juniors are getting replaced. If this situation continues, it’s a grim career growth path for the next generation.</p> <h2 id="video%3A-designing-scissors-by-craighill" tabindex="-1"><a href="https://www.youtube.com/watch?v=txoZacPFLZg">Video: Designing Scissors by Craighill</a><a class="link link--anchor" href="https://saneef.com/blog/learning-notes-2025-w51/#video%3A-designing-scissors-by-craighill" aria-hidden="true" tabindex="-1"></a></h2> <p>A short walkthrough of the design process behind their Chroma Scissors. There was a step where they excluded certain design directions to pursue; I’m reminding myself to explicitly note down those next time.</p> <h2 id="grow%2C-like-a-tree-not-like-a-cancer" tabindex="-1"><a href="https://blog.jim-nielsen.com/2025/grow-like-a-tree-not-a-cancer/">Grow, like a tree not like a cancer</a><a class="link link--anchor" href="https://saneef.com/blog/learning-notes-2025-w51/#grow%2C-like-a-tree-not-like-a-cancer" aria-hidden="true" tabindex="-1"></a></h2> <p>Jim’s post expands on Mandy Brown’s notion of <a href="https://aworkinglibrary.com/writing/psychology-of-craft">growing down</a> nicely. I’m a freelancer, and I’m selling my expertise to each client. I always worry about getting obsolete and push myself to keep learning. The idea of growing down hit me on those notes.</p> <h2 id="the-harvest-will-come" tabindex="-1"><a href="https://www.joanwestenberg.com/the-harvest-will-come/">The Harvest Will Come</a><a class="link link--anchor" href="https://saneef.com/blog/learning-notes-2025-w51/#the-harvest-will-come" aria-hidden="true" tabindex="-1"></a></h2> <blockquote> <p>…humans are not factories. We are, as obvious as this may seem, organisms. And organisms live through cycles.</p> </blockquote> <p>Embrace the unproductive and out-of-form days.</p> 
          


          ]]></content
        >
      </entry><entry>
        <title>Sunsets eleventy-plugin-img2picture</title>
        <link href="https://saneef.com/blog/sunsets-eleventy-plugin-img2picture/" />
        <published>2025-12-16T03:30:00Z</published>
        <updated>2025-12-16T11:37:18Z</updated>
        <id>https://saneef.com/blog/sunsets-eleventy-plugin-img2picture/</id>
        <content type="html"
          ><![CDATA[<p>I’m sunsetting the <a href="https://github.com/saneef/eleventy-plugin-img2picture"><code>eleventy-plugin-img2picture</code></a>, an Eleventy plugin that replaces regular <code>&lt;img&gt;</code> tags with <code>&lt;picture&gt;</code> and generating responsive-optimized sizes of each image.</p> <p>I had created the plugin at a time when I couldn’t find any plugins to do that job. Two years ago, the official <a href="https://www.11ty.dev/docs/plugins/image/">Eleventy Image plugin</a> released <a href="https://www.11ty.dev/docs/plugins/image/#html-transform">the feature</a> to generate <code>&lt;picture&gt;</code> tags from <code>&lt;img&gt;</code>. The same plugin that I use internally in my plugin to generate different image sizes.</p> <p>Following the spirit of Eleventy maintainers <a href="https://www.11ty.dev/blog/dependency-watch/">meticulously reducing third-party dependencies</a>, I urge folks to use the official Image plugin.</p> <p>Today, I’m marking <a href="https://www.npmjs.com/package/eleventy-plugin-img2picture">my plugin on NPM repository</a> as deprecated.</p> <h2 id="migrate-to-the-eleventy-image-plugin" tabindex="-1">Migrate to the Eleventy Image Plugin<a class="link link--anchor" href="https://saneef.com/blog/sunsets-eleventy-plugin-img2picture/#migrate-to-the-eleventy-image-plugin" aria-hidden="true" tabindex="-1"></a></h2> <h3 id="1.-replace-plugins" tabindex="-1">1. Replace plugins<a class="link link--anchor" href="https://saneef.com/blog/sunsets-eleventy-plugin-img2picture/#1.-replace-plugins" aria-hidden="true" tabindex="-1"></a></h3> <p>Remove <code>eleventy-plugin-img2picture</code> and install <code>@11ty/eleventy-img</code> package.</p> <p>Update Eleventy config for Eleventy Image Transform plugin:</p> <pre class="language-diff-js"><code class="language-diff-js"><span class="token deleted-sign deleted language-js"><span class="token prefix deleted">-</span> <span class="token keyword">import</span> img2picture <span class="token keyword">from</span> <span class="token string">"eleventy-plugin-img2picture"</span><span class="token punctuation">;</span><br></span><span class="token inserted-sign inserted language-js"><span class="token prefix inserted">+</span> <span class="token keyword">import</span> <span class="token punctuation">{</span> eleventyImageTransformPlugin <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">"@11ty/eleventy-img"</span><span class="token punctuation">;</span><br></span><br><span class="token unchanged language-js"><span class="token prefix unchanged"> </span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">eleventyConfig</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br></span><span class="token deleted-sign deleted language-js"><span class="token prefix deleted">-</span>   eleventyConfig<span class="token punctuation">.</span><span class="token function">addPlugin</span><span class="token punctuation">(</span>img2picture<span class="token punctuation">,</span> <span class="token punctuation">{</span><br><span class="token prefix deleted">-</span>     <span class="token literal-property property">eleventyInputDir</span><span class="token operator">:</span> <span class="token string">"."</span><span class="token punctuation">,</span><br><span class="token prefix deleted">-</span>     <span class="token literal-property property">imagesOutputDir</span><span class="token operator">:</span> <span class="token string">"_site"</span><span class="token punctuation">,</span><br><span class="token prefix deleted">-</span>     <span class="token literal-property property">urlPath</span><span class="token operator">:</span> <span class="token string">"/images/"</span><span class="token punctuation">,</span><br><span class="token prefix deleted">-</span>   <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br></span><br><span class="token inserted-sign inserted language-js"><span class="token prefix inserted">+</span>   eleventyConfig<span class="token punctuation">.</span><span class="token function">addPlugin</span><span class="token punctuation">(</span>eleventyImageTransformPlugin<span class="token punctuation">,</span> <span class="token punctuation">{</span><br><span class="token prefix inserted">+</span>     <span class="token literal-property property">urlPath</span><span class="token operator">:</span> <span class="token string">"/images"</span><span class="token punctuation">,</span><br><span class="token prefix inserted">+</span>   <span class="token punctuation">}</span><span class="token punctuation">)</span><br></span><span class="token unchanged language-js"><span class="token prefix unchanged"> </span> <span class="token punctuation">}</span><span class="token punctuation">;</span><br></span></code></pre> <p>You can find more Eleventy Image transform <a href="https://www.11ty.dev/docs/plugins/image/#more-configuration-options">options in the docs</a>.</p> <h3 id="2.-update-%3Cimg%3E-instance-overrides" tabindex="-1">2. Update <code>&lt;img&gt;</code> instance overrides<a class="link link--anchor" href="https://saneef.com/blog/sunsets-eleventy-plugin-img2picture/#2.-update-%3Cimg%3E-instance-overrides" aria-hidden="true" tabindex="-1"></a></h3> <h4>Ignore</h4> <p>Replace <code>&lt;img data-img2picture-ignore=&quot;true&quot;&gt;</code> with <code>&lt;img eleventy:ignore&gt;</code>.</p> <h4>Widths</h4> <p>Replace <code>&lt;img data-img2picture-widths=&quot;200,400,600,800&quot;&gt;</code> with <code>&lt;img eleventy:widths=&quot;200,400,600,800&quot;&gt;</code>.</p> <p><strong>Warning:</strong> If <code>width</code> attribute is provided (like <code>&lt;img width&gt;</code>), it will be used to generate the image (only one image with mentioned width) and <em>values in <code>eleventy:widths</code> will be ignored.</em> You should remove <code>width</code> if you plan to use <code>eleventy:widths</code>. In the final generated tag <code>width</code> and <code>height</code> attributes will be populated based on the generated image size.</p> <h4><code>&lt;picture&gt;</code> classname</h4> <p>Replace <code>&lt;img data-img2picture-picture-class=&quot;w-full&quot; /&gt;</code> with <code>&lt;img eleventy:pictureattr:class=&quot;w-full&quot;&gt;</code>.</p> <p>Eleventy Image Transform plugin provides <a href="https://www.11ty.dev/docs/plugins/image/#attribute-overrides">more instance-specific overrides</a>.</p> 
          


          ]]></content
        >
      </entry><entry>
        <title>Learning notes 2025-W50</title>
        <link href="https://saneef.com/blog/learning-notes-2025-w50/" />
        <published>2025-12-12T03:30:00Z</published>
        <updated>2026-03-31T05:18:42Z</updated>
        <id>https://saneef.com/blog/learning-notes-2025-w50/</id>
        <content type="html"
          ><![CDATA[<h2 id="video%3A-a-real-world-case-study-of-shape-up-by-ryan-singer" tabindex="-1"><a href="https://www.youtube.com/watch?v=Holk0GsGYfY">Video: A real-world case study of Shape Up by Ryan Singer</a><a class="link link--anchor" href="https://saneef.com/blog/learning-notes-2025-w50/#video%3A-a-real-world-case-study-of-shape-up-by-ryan-singer" aria-hidden="true" tabindex="-1"></a></h2> <p>I have used many good parts from the Shape Up in my work. In this video, the Ryan demonstrates how he uses the process in a conventionally large company. <em>Disclaimer: I don’t endorse any bad people at or previously at 37 Signals. However, for what it is worth, I encourage you to use their good ideas.</em></p> <h2 id="book%3A-ways-to-connect---on-interface-and-product-design" tabindex="-1"><a href="https://www.amazon.in/Ways-Connect-Interface-Product-Design-ebook/dp/B00DUEF14S">Book: Ways to Connect - On Interface and Product Design</a><a class="link link--anchor" href="https://saneef.com/blog/learning-notes-2025-w50/#book%3A-ways-to-connect---on-interface-and-product-design" aria-hidden="true" tabindex="-1"></a></h2> <p>Came across this unpopular short book (about 22 pages) from 2013 containing an interview of Ryan Singer. It was a refresher on how important it is now to not to forget about the fundamentals like mental model of the customers, aspects (functional, emotional, social or something else) that matter for the project in hand.</p> <h2 id="learn-to-leverage-a-crisis" tabindex="-1"><a href="https://www.todepond.com/sky/crisis/">Learn to leverage a crisis</a><a class="link link--anchor" href="https://saneef.com/blog/learning-notes-2025-w50/#learn-to-leverage-a-crisis" aria-hidden="true" tabindex="-1"></a></h2> <p>Once in a while we face a crisis, at home or at work. Almost always they affect human relationships. Lu Wilson shares wisdom on how to gain from a crisis.</p> <h2 id="question%3A-what-is-a-principal-designer%3F" tabindex="-1">Question: What is a Principal Designer?<a class="link link--anchor" href="https://saneef.com/blog/learning-notes-2025-w50/#question%3A-what-is-a-principal-designer%3F" aria-hidden="true" tabindex="-1"></a></h2> <p>It was a question asked to me recently. I didn’t know the answer at that time. I read some articles and found out that there is no strict template for such a role. Here is my answer:</p> <p>A Principal Designer is an expert in their craft. They will be working in an Individual Contributor capacity either in a single team or multiple teams. They can be influential in long-term outcomes of the organisation. They don’t have any managerial duties, but will be mentoring other designers.</p> 
          


          ]]></content
        >
      </entry><entry>
        <title>Underlines</title>
        <link href="https://saneef.com/blog/underlines/" />
        <published>2025-11-10T03:30:00Z</published>
        <updated>2025-11-10T16:18:57Z</updated>
        <id>https://saneef.com/blog/underlines/</id>
        <content type="html"
          ><![CDATA[<blockquote> <p><span class="c-text">DSU George Stark:</span> [opening a book in a suspect’s flat] He underlines.</p> <p><span class="c-text">DCI Erin Gray:</span> So?</p> <p><span class="c-text">DSU George Stark:</span> We tend to underline observations that confirm our view of the world. Give me a day with those books, and I’ll serve him to you on a plate.</p> </blockquote> <p><a href="https://m.imdb.com/title/tt2808666/characters/nm0641244/?item=qt2064515&amp;ref_=ext_shr_lnk">Those are lines</a> by two police personnel in an episode from the series, Luther.</p> <p>We do cherish lines, ideas, concepts, and stories that agree with us. Should we neglect all the ones that don’t agree with us?</p> <blockquote> <p>When you only read authors and books you agree with, you aren’t going to be challenged. Defending an elegantly crafted argument from the opposing side will teach you far more about an issue than simply nodding your head along to your favorite writer.</p> <p>—<cite>Scott H. Young, <a href="https://www.scotthyoung.com/blog/2008/12/18/how-to-read-books-you-disagree-with/">How to Read Books You Disagree With</a></cite></p> </blockquote> <p>Seek out ideas that challenge our world view. The understanding and humility from such adventures are going to <a href="https://www.joanwestenberg.com/p/how-to-stay-sane-in-a-world-that-rewards-insanity">keep us sane</a> in these insane times.</p> 
          


          ]]></content
        >
      </entry><entry>
        <title>Disable built-in DNS clients in Chromium based apps</title>
        <link href="https://saneef.com/blog/disable-built-in-dns-clients-in-chromium-based-apps/" />
        <published>2024-02-16T15:30:00Z</published>
        <updated>2024-03-24T12:03:03Z</updated>
        <id>https://saneef.com/blog/disable-built-in-dns-clients-in-chromium-based-apps/</id>
        <content type="html"
          ><![CDATA[<p>All Chromium-based apps such a Google Chrome, Obsidian have a built-in DNS client. I have set up <a href="https://nextdns.io/">NextDNS</a> on my computer to block ads and trackers. The built-in DNS clients by pass the NextDNS, which I don’t want.</p> <p>On top of built-in DNS is switched on by default, there is no way to switch it off using the UI. <em>In macOS, I found a way to switch it off using the command line<sup class="footnote-ref"><a href="https://saneef.com/blog/disable-built-in-dns-clients-in-chromium-based-apps/#fn1" id="fnref1">[1]</a></sup>.</em></p> <p>First, you need the bundle identifier of the Chromium-based app. I have listed bundle identifiers of popular apps towards <a href="https://saneef.com/blog/disable-built-in-dns-clients-in-chromium-based-apps/#popular-chromium-apps">the end of the page</a>. Otherwise, use the <code>mdls</code> command to get the bundle identifier.</p> <pre class="language-sh"><code class="language-sh"><span class="token comment"># Run this command in Terminal.app</span><br>mdls <span class="token parameter variable">-name</span> kMDItemCFBundleIdentifier <span class="token parameter variable">-r</span> <span class="token operator">&lt;</span>path/to/chromium-app.app<span class="token operator">></span><br><br><span class="token comment"># Example:</span><br><span class="token comment"># $ mdls -name kMDItemCFBundleIdentifier \</span><br><span class="token comment">#        -r /Applications/Google\ Chrome.app/</span><br><span class="token comment"># com.google.Chrome</span></code></pre> <p>Once you have the bundle identifier, use the <code>defaults</code> command to set <code>BuiltInDnsClientEnabled</code> to <code>false</code>.</p> <pre class="language-sh"><code class="language-sh"><span class="token comment"># Run this command in Terminal.app</span><br>defaults <span class="token function">write</span> <span class="token operator">&lt;</span>bundle-identifier<span class="token operator">></span> BuiltInDnsClientEnabled <span class="token parameter variable">-boolean</span> <span class="token boolean">false</span><br><br><span class="token comment"># Example:</span><br><span class="token comment"># defaults write org.chromium.Chromium \</span><br><span class="token comment">#          BuiltInDnsClientEnabled -boolean false</span></code></pre> <p>Make sure to restart the app after you run the <code>defaults</code> command. You can use <a href="https://www.dnsleaktest.com">dnsleaktest.com</a> to check which DNS server is used by the Chromium browser.</p> <p>You can revert to using the built-in DNS client by deleting the <code>BuiltInDnsClientEnabled</code> preference.</p> <pre class="language-sh"><code class="language-sh"><span class="token comment"># Run this command in Terminal.app</span><br>defaults delete <span class="token operator">&lt;</span>bundle-identifier<span class="token operator">></span> BuiltInDnsClientEnabled<br><br><span class="token comment"># Example:</span><br><span class="token comment"># defaults delete org.chromium.Chromium \</span><br><span class="token comment">#          BuiltInDnsClientEnabled</span></code></pre> <h2 id="popular-chromium-apps" tabindex="-1">Popular Chromium Apps<a class="link link--anchor" href="https://saneef.com/blog/disable-built-in-dns-clients-in-chromium-based-apps/#popular-chromium-apps" aria-hidden="true" tabindex="-1"></a></h2> <table> <thead> <tr> <th style="text-align:left">Application</th> <th style="text-align:left">Bundle Identifier</th> </tr> </thead> <tbody> <tr> <td style="text-align:left">Chromium</td> <td style="text-align:left"><code>org.chromium.Chromium</code></td> </tr> <tr> <td style="text-align:left">Google Chrome</td> <td style="text-align:left"><code>com.google.Chrome</code></td> </tr> <tr> <td style="text-align:left">Obsidian</td> <td style="text-align:left"><code>md.obsidian</code></td> </tr> <tr> <td style="text-align:left">Visual Studio Code</td> <td style="text-align:left"><code>com.microsoft.VSCode</code></td> </tr> <tr> <td style="text-align:left">Vivaldi Browser</td> <td style="text-align:left"><code>com.vivaldi.Vivaldi</code></td> </tr> </tbody> </table> <hr class="footnotes-sep"> <section class="footnotes"> <ol class="footnotes-list"> <li id="fn1" class="footnote-item"><p>I learned about this preference from <a href="https://discourse.pi-hole.net/t/disable-async-dns-resolver-in-google-chrome/9500/8">this comment</a> on <a href="https://discourse.pi-hole.net">discourse.pi-hole.net</a> <a href="https://saneef.com/blog/disable-built-in-dns-clients-in-chromium-based-apps/#fnref1" class="footnote-backref">↩︎</a></p> </li> </ol> </section> 
          


          ]]></content
        >
      </entry><entry>
        <title>Website for my 7-year-old kid’s drawings</title>
        <link href="https://saneef.com/blog/website-for-my-7-year-old-kids-drawings/" />
        <published>2024-02-09T10:18:02Z</published>
        <updated>2024-02-09T11:35:45Z</updated>
        <id>https://saneef.com/blog/website-for-my-7-year-old-kids-drawings/</id>
        <content type="html"
          ><![CDATA[<p>Last week, I made <a href="https://shiro.ws/">a website</a> for my 7-year-old kid to put up his drawing online. I was amazed at how my kid convinced me to build one. I thought the website will be a medium for my kid to share drawings with cousins and grandparents. Later, I posted our conversation with a link to the website on Mastodon.</p> <blockquote> <p>7-year-old: Can I put my drawing videos on YouTube?<br> Me: No.</p> <p>7-year-old: Can I put my drawings on Instagram?<br> Me: No way.</p> <p>7-year-old: Can you make me a website for my drawings?<br> Me: (after thinking for a moment) Okay. That I can do!</p> <p>…</p> <p>After a day <a href="https://shiro.ws/">shiro.ws</a>!</p> <p>It’s a bunch of HTML pages generated by <a href="https://front-end.social/@eleventy@fosstodon.org">@eleventy</a>. The content is fetched from a Notion Table. Notion allows me or my spouse to add images and text. I have created an iOS Shortcut to publish – rebuild – on Netlify.</p> <p>—<cite>Saneef Ansari (<a href="https://front-end.social/@saneef">@saneef@front-end.social</a>) on <a href="https://front-end.social/@saneef/111868783885697884">3<sup>rd</sup> February, 2024</a></cite></p> </blockquote> <p>After posting on Mastodon, it was full of surprises for us. Many folks sent emails, long ones, to my kid. Those were the very first emails my kid got. It was fun for me to explain what are emails, and to type out the replies.</p> <p><em>Thank you to all who took out time to write those emails to our kid.</em></p> 
          


          ]]></content
        >
      </entry>
</feed>

