<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wc="https://wilhelm.codes/ns/feed/1.0"><channel><title>Wilhelm Codes · Design</title><link>https://wilhelm.codes/tags/design/</link><description>Coder and platform engineer. Slinger of nibbles, bits and bytes. Over 25 years of professional experience as a software engineer. Love making glowing rectangles go "beep-boop".</description><generator>Hugo</generator><language>en-US</language><managingEditor>0xdeadbeef@devilmayco.de (Wilhelm Murdoch)</managingEditor><webMaster>0xdeadbeef@devilmayco.de (Wilhelm Murdoch)</webMaster><lastBuildDate>Mon, 14 Sep 2026 17:15:00 +1000</lastBuildDate><atom:link href="https://wilhelm.codes/tags/design/index.xml" rel="self" type="application/rss+xml"/><item><title>I’ve been rebuilding the public landing page for the homelab this …</title><link>https://wilhelm.codes/bits/update-a-thin-layer-of-grime/</link><pubDate>Mon, 14 Sep 2026 17:15:00 +1000</pubDate><author>0xdeadbeef@devilmayco.de (Wilhelm Murdoch)</author><guid>https://wilhelm.codes/bits/update-a-thin-layer-of-grime/</guid><category>wilhelm.codes</category><category>homelab</category><category>css</category><category>design</category><wc:kind>bit</wc:kind><wc:bit>update</wc:bit><wc:untitled>true</wc:untitled><description>I&amp;rsquo;ve been rebuilding the public landing page for the homelab this weekend and somewhere in the middle of it I laid a scanline over the whole thing. It&amp;rsquo;s a single hairline that repeats itself every three pixels. It&amp;rsquo;s faint enough that the page stops looking quite so flat without you ever working out why. Then, obviously, I wanted it here too.
The lazy version is a white line at about 1.5% opacity, which is what the other page uses, because the other page is forty words of neon over black; legibility isn&amp;rsquo;t really the goal. However, this site is mostly prose, so a white line lightens the words as well as the background. I didn&amp;rsquo;t spend all that time on the reading column just to lay a haze over it.</description><content:encoded><![CDATA[<p>I&rsquo;ve been rebuilding the <a href="https://nightcity.network">public landing</a> page for the homelab this weekend and somewhere in the middle of it I laid a scanline over the whole thing. It&rsquo;s a single hairline that repeats itself every three pixels. It&rsquo;s faint enough that the page stops looking quite so flat without you ever working out why. Then, obviously, I wanted it here too.</p>
<p>The lazy version is a white line at about <code>1.5%</code> opacity, which is what the other page uses, because the other page is forty words of neon over black; legibility isn&rsquo;t really the goal. However, <em>this</em> site is mostly prose, so a white line lightens the words as well as the background. I didn&rsquo;t spend all that time on the reading column just to lay a haze over it.</p>
<p>So the grain mixes off <code>--text</code> instead of white:</p>
<div class="code-block">
  <div class="code-head">
    <span class="code-file"></span>
    <span class="code-lang">CSS</span>
  </div>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-css" data-lang="css"><span class="line"><span class="cl"><span class="nt">--grain</span><span class="o">:</span> <span class="nt">color-mix</span><span class="o">(</span><span class="nt">in</span> <span class="nt">srgb</span><span class="o">,</span> <span class="nt">var</span><span class="o">(</span><span class="nt">--text</span><span class="o">)</span> <span class="nt">1</span><span class="p">.</span><span class="nc">5</span><span class="o">%,</span> <span class="nt">transparent</span><span class="o">);</span></span></span></code></pre></div>
</div>
<p>This can be applied like so:</p>
<div class="code-block">
  <div class="code-head">
    <span class="code-file"></span>
    <span class="code-lang">CSS</span>
  </div>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-css" data-lang="css"><span class="line"><span class="cl"><span class="p">.</span><span class="nc">grain</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">position</span><span class="p">:</span> <span class="kc">fixed</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="k">inset</span><span class="p">:</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="n">pointer-events</span><span class="p">:</span> <span class="kc">none</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="k">z-index</span><span class="p">:</span> <span class="mi">10</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="k">background</span><span class="p">:</span> <span class="nb">repeating-linear-gradient</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="kc">to</span> <span class="kc">bottom</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nf">var</span><span class="p">(</span><span class="o">--</span><span class="n">grain</span><span class="p">)</span> <span class="mi">0</span> <span class="mi">1</span><span class="kt">px</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="kc">transparent</span> <span class="mi">1</span><span class="kt">px</span> <span class="mi">3</span><span class="kt">px</span>
</span></span><span class="line"><span class="cl">  <span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div>
</div>
<p>And finally referened like so just above the closing <code>&lt;/body&gt;</code> tag:</p>
<div class="code-block">
  <div class="code-head">
    <span class="code-file"></span>
    <span class="code-lang">HTML</span>
  </div>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;grain&#34;</span> <span class="na">aria-hidden</span><span class="o">=</span><span class="s">&#34;true&#34;</span><span class="p">&gt;&lt;/</span><span class="nt">div</span><span class="p">&gt;</span></span></span></code></pre></div>
</div>
<p>This works out great, because a colour mixed with itself gives that colour straight back. The grain physically <em>cannot</em> touch the body copy. I&rsquo;ve learned quite a few new things today!</p>
<p>As a bonus the lightbox is a <code>&lt;dialog&gt;</code> and the browser promotes a modal dialog into the top layer. This sits above every <code>z-index</code> on the page; including the one holding the grain. So a zoomed photograph comes up perfectly clean and I didn&rsquo;t have to write a rule to make that happen.</p>
<p>Whether you can see any of this depends entirely on your monitor, your colour settings and even your resolution. If you can&rsquo;t see it, it&rsquo;s working.</p>
]]></content:encoded></item><item><title>“Perfection is achieved, not when there is nothing more to add, but …</title><link>https://wilhelm.codes/bits/quote-antoine-de-saint-exup%C3%A9ry/</link><pubDate>Mon, 06 Apr 2026 05:00:00 +0000</pubDate><author>0xdeadbeef@devilmayco.de (Wilhelm Murdoch)</author><guid>https://wilhelm.codes/bits/quote-antoine-de-saint-exup%C3%A9ry/</guid><category>wisdom</category><category>design</category><wc:kind>bit</wc:kind><wc:bit>quote</wc:bit><wc:untitled>true</wc:untitled><wc:source>Antoine de Saint-Exupéry</wc:source><description>&amp;ldquo;Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away.&amp;rdquo;</description><content:encoded><![CDATA[<p>&ldquo;Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away.&rdquo;</p>
]]></content:encoded></item></channel></rss>