<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Posts on Retro Dispatch</title><link>https://phantompixeldev.github.io/hugo-theme-retrocss/posts/</link><description>Recent content in Posts on Retro Dispatch</description><generator>Hugo</generator><language>en-us</language><copyright>© 2026 Retro Dispatch</copyright><lastBuildDate>Wed, 02 Sep 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://phantompixeldev.github.io/hugo-theme-retrocss/posts/index.xml" rel="self" type="application/rss+xml"/><item><title>Designing a token system that survives dark mode</title><link>https://phantompixeldev.github.io/hugo-theme-retrocss/posts/hello-retro/</link><pubDate>Wed, 02 Sep 2026 00:00:00 +0000</pubDate><guid>https://phantompixeldev.github.io/hugo-theme-retrocss/posts/hello-retro/</guid><description>&lt;h2 id="why-tiers"&gt;
 Why tiers
 &lt;a class="heading-anchor" href="#why-tiers" aria-label="Link to Why tiers"&gt;&lt;span aria-hidden="true"&gt;#&lt;/span&gt;&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;A colour is not one value. The blue that fills a button is not the blue that
reads as text on grey, and using either in the other&amp;rsquo;s place is how a design
system ships something illegible.&lt;/p&gt;
&lt;h2 id="the-four-tiers"&gt;
 The four tiers
 &lt;a class="heading-anchor" href="#the-four-tiers" aria-label="Link to The four tiers"&gt;&lt;span aria-hidden="true"&gt;#&lt;/span&gt;&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Fill, on-fill, on-surface, and states. Every hue carries all four.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma retro-code"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nd"&gt;root&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;--retro-primary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mh"&gt;#0000aa&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;--retro-primary-fg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mh"&gt;#ffffff&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;--retro-primary-text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mh"&gt;#000080&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="what-it-buys-you"&gt;
 What it buys you
 &lt;a class="heading-anchor" href="#what-it-buys-you" aria-label="Link to What it buys you"&gt;&lt;span aria-hidden="true"&gt;#&lt;/span&gt;&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;One class sets both a fill and the text colour that survives on it.&lt;/p&gt;</description></item><item><title>Building a component that is square on purpose</title><link>https://phantompixeldev.github.io/hugo-theme-retrocss/posts/square-on-purpose/</link><pubDate>Fri, 28 Aug 2026 00:00:00 +0000</pubDate><guid>https://phantompixeldev.github.io/hugo-theme-retrocss/posts/square-on-purpose/</guid><description>&lt;h2 id="one-token"&gt;
 One token
 &lt;a class="heading-anchor" href="#one-token" aria-label="Link to One token"&gt;&lt;span aria-hidden="true"&gt;#&lt;/span&gt;&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Every component routes its corners through &lt;code&gt;--retro-border-radius&lt;/code&gt;, so one
declaration rounds the whole framework.&lt;/p&gt;
&lt;h2 id="the-exceptions"&gt;
 The exceptions
 &lt;a class="heading-anchor" href="#the-exceptions" aria-label="Link to The exceptions"&gt;&lt;span aria-hidden="true"&gt;#&lt;/span&gt;&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Pills are named for their shape, and tables ignore &lt;code&gt;border-radius&lt;/code&gt; outright
because &lt;code&gt;border-collapse: collapse&lt;/code&gt; merges their cell borders.&lt;/p&gt;</description></item><item><title>Why your div is not a button</title><link>https://phantompixeldev.github.io/hugo-theme-retrocss/posts/why-your-div-is-not-a-button/</link><pubDate>Fri, 21 Aug 2026 00:00:00 +0000</pubDate><guid>https://phantompixeldev.github.io/hugo-theme-retrocss/posts/why-your-div-is-not-a-button/</guid><description>&lt;p&gt;A &lt;code&gt;div&lt;/code&gt; with a click handler looks like a button and behaves like nothing.&lt;/p&gt;
&lt;h2 id="what-you-lose"&gt;
 What you lose
 &lt;a class="heading-anchor" href="#what-you-lose" aria-label="Link to What you lose"&gt;&lt;span aria-hidden="true"&gt;#&lt;/span&gt;&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Tab order. Enter and Space. The implicit &lt;code&gt;button&lt;/code&gt; role. The disabled state.
Form submission. Focus visibility. Every one of those is a line of code you now
own, and a line you will forget on the next component.&lt;/p&gt;
&lt;h2 id="what-it-costs-to-get-back"&gt;
 What it costs to get back
 &lt;a class="heading-anchor" href="#what-it-costs-to-get-back" aria-label="Link to What it costs to get back"&gt;&lt;span aria-hidden="true"&gt;#&lt;/span&gt;&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma retro-code"&gt;&lt;code class="language-html" data-lang="html"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;button&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;tabindex&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;0&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;onkeydown&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;if (event.key === &amp;#39;Enter&amp;#39; || event.key === &amp;#39; &amp;#39;) this.click()&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Save
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;That is the &lt;em&gt;minimum&lt;/em&gt;, and it still does not report a disabled state, still does
not submit a form, and still needs &lt;code&gt;event.preventDefault()&lt;/code&gt; so Space does not
scroll the page.&lt;/p&gt;</description></item><item><title>Painting the right theme before the first frame</title><link>https://phantompixeldev.github.io/hugo-theme-retrocss/posts/painting-the-right-theme/</link><pubDate>Fri, 14 Aug 2026 00:00:00 +0000</pubDate><guid>https://phantompixeldev.github.io/hugo-theme-retrocss/posts/painting-the-right-theme/</guid><description>&lt;p&gt;A theme flash is not a rendering quirk. It is a page admitting that it decided
what colour to be after it had already been drawn.&lt;/p&gt;
&lt;h2 id="do-it-in-css"&gt;
 Do it in CSS
 &lt;a class="heading-anchor" href="#do-it-in-css" aria-label="Link to Do it in CSS"&gt;&lt;span aria-hidden="true"&gt;#&lt;/span&gt;&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;The dark palette is emitted twice: once for &lt;code&gt;[data-theme=&amp;quot;dark&amp;quot;]&lt;/code&gt;, and once
under &lt;code&gt;@media (prefers-color-scheme: dark)&lt;/code&gt; for &lt;code&gt;:root:not([data-theme=&amp;quot;light&amp;quot;])&lt;/code&gt;.
A visitor whose system is dark gets dark on the first paint, before any script
has run — before the bundle has even been requested.&lt;/p&gt;</description></item><item><title>A type scale for interfaces that shout</title><link>https://phantompixeldev.github.io/hugo-theme-retrocss/posts/a-type-scale-that-shouts/</link><pubDate>Fri, 07 Aug 2026 00:00:00 +0000</pubDate><guid>https://phantompixeldev.github.io/hugo-theme-retrocss/posts/a-type-scale-that-shouts/</guid><description>&lt;p&gt;Windows 95 shipped at 96 DPI with an 8pt UI font. Reproducing that number today
produces text nobody can read on a phone, which is the difference between an
homage and a re-enactment.&lt;/p&gt;
&lt;h2 id="steps-not-sizes"&gt;
 Steps, not sizes
 &lt;a class="heading-anchor" href="#steps-not-sizes" aria-label="Link to Steps, not sizes"&gt;&lt;span aria-hidden="true"&gt;#&lt;/span&gt;&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;--retro-font-size-xs&lt;/code&gt; through &lt;code&gt;-3xl&lt;/code&gt;, all in &lt;code&gt;rem&lt;/code&gt;, all derived from one body
size. A component asks for a step, never a pixel value, so a site that raises
the base size moves everything with it.&lt;/p&gt;</description></item><item><title>What we removed in 3.0, and why</title><link>https://phantompixeldev.github.io/hugo-theme-retrocss/posts/what-we-removed/</link><pubDate>Thu, 30 Jul 2026 00:00:00 +0000</pubDate><guid>https://phantompixeldev.github.io/hugo-theme-retrocss/posts/what-we-removed/</guid><description>&lt;h2 id="the-important-on-the-radius-reset"&gt;
 The &lt;code&gt;!important&lt;/code&gt; on the radius reset
 &lt;a class="heading-anchor" href="#the-important-on-the-radius-reset" aria-label="Link to The !important on the radius reset"&gt;&lt;span aria-hidden="true"&gt;#&lt;/span&gt;&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;It was load-bearing by accident. Dropping it woke thirty-one dormant radius
declarations and rounded eleven components — which is why 3.0.0 was followed by
3.0.1 the same week.&lt;/p&gt;
&lt;h2 id="a-documentation-renderer"&gt;
 A documentation renderer
 &lt;a class="heading-anchor" href="#a-documentation-renderer" aria-label="Link to A documentation renderer"&gt;&lt;span aria-hidden="true"&gt;#&lt;/span&gt;&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Unmaintained since 2022, its output was never published, and it accounted for
every security advisory in the dependency tree. The SassDoc comments stayed;
only the renderer left.&lt;/p&gt;</description></item><item><title>Sign-in forms that behave when the network does not</title><link>https://phantompixeldev.github.io/hugo-theme-retrocss/posts/auth-forms-that-behave/</link><pubDate>Sat, 18 Jul 2026 00:00:00 +0000</pubDate><guid>https://phantompixeldev.github.io/hugo-theme-retrocss/posts/auth-forms-that-behave/</guid><description>&lt;p&gt;The happy path of a sign-in form is four elements. Everything else is the
interesting part.&lt;/p&gt;
&lt;h2 id="the-states-worth-building"&gt;
 The states worth building
 &lt;a class="heading-anchor" href="#the-states-worth-building" aria-label="Link to The states worth building"&gt;&lt;span aria-hidden="true"&gt;#&lt;/span&gt;&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Pending&lt;/strong&gt; — the button is busy, not disabled-and-silent.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rejected&lt;/strong&gt; — the message is next to the field, not in a toast that vanished.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rate-limited&lt;/strong&gt; — say how long, not &amp;ldquo;try again later&amp;rdquo;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Offline&lt;/strong&gt; — the form should still hold what was typed.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="the-password-toggle"&gt;
 The password toggle
 &lt;a class="heading-anchor" href="#the-password-toggle" aria-label="Link to The password toggle"&gt;&lt;span aria-hidden="true"&gt;#&lt;/span&gt;&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Make it a real &lt;code&gt;button&lt;/code&gt; with &lt;code&gt;aria-pressed&lt;/code&gt;, keep the field type in sync, and
never place it where it covers the text it reveals.&lt;/p&gt;</description></item></channel></rss>