<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet href="/feed/pretty-atom-feed.xsl" type="text/xsl"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>irvin.dev</title>
  <subtitle></subtitle>
  <link href="https://irvin.dev/" />
  <link href="https://irvin.dev/feed/feed.xml" rel="self" />
  <updated>2026-04-19T17:53:00Z</updated>
  <id>https://irvin.dev/</id>
  <author>
    <name>Joseph Irvin</name>
  </author>
  
  
  <entry>
    <title>Hugo Migration</title>
    <link href="https://irvin.dev/posts/hugo-migration/" />
    <id>https://irvin.dev/posts/hugo-migration/</id>
    <updated>2026-04-12T00:00:00Z</updated>
    <content type="html"><![CDATA[<p>In yet another contradiction of my <a href="/posts/start/">first post</a>, I have migrated this blog to <a href="https://gohugo.io" target="_blank">Hugo</a>. Previously, I was using 11ty (Eleventy) as my blog framework. I enjoyed 11ty and had no problems with it. However, with their recent <a href="https://www.11ty.dev/blog/build-awesome/" target="_blank">rebranding announcement</a>, I&rsquo;ve decided to move on.</p>
<p>11ty, which is changing its name to Build Awesome after joining up with Font Awesome, appears to be moving toward monetization. That&rsquo;s fine, no shade if they want to get paid, but it&rsquo;s not a ride I want to stay on for my blog framework. Additionally, changing the name from 11ty to Build Awesome feels like going from something unique and hip to something bland and corporate. A name change like that is the kind of decision that foreshadows future decisions.</p>
<p>I don&rsquo;t see Hugo making any similar alterations. Hugo is open-source with no monetization plans, has an active community, and has been around for a long time. I just want something lightweight that works, something open-source that I can depend on without thinking about it. Hugo feels like that.</p>
<p>Good luck, Build Awesome.</p>
]]></content>
  </entry>
  
  <entry>
    <title>Liminal Salt Theme</title>
    <link href="https://irvin.dev/posts/liminal-salt-theme/" />
    <id>https://irvin.dev/posts/liminal-salt-theme/</id>
    <updated>2026-03-07T00:00:00Z</updated>
    <content type="html"><![CDATA[<p><a href="https://github.com/irvj/liminal-salt" target="_blank">Liminal Salt</a> is an LLM frontend for OpenRouter that I built in Python and Django, but it also spawned a color theme that I&rsquo;ve been using for various projects. The overall aesthetic is inspired by greige, kind of a beige/sage/stone milieu. I&rsquo;ve tried to make it accessible and comfortable for reading.</p>
<p>Liminal Salt has an earthy vibe that I really enjoy. I&rsquo;m transitioning all my tools to use it. Check out the theme on GitHub: <a href="https://github.com/irvj/liminal-salt-theme" target="_blank">liminal-salt-theme</a></p>
<p>It&rsquo;s still evolving, but here&rsquo;s the current palette:</p>
<h2 id="dark-theme">
  Dark Theme
  <a class="ha" href="#dark-theme" aria-hidden="true">#</a>
</h2>
<h3 id="base">
  Base
  <a class="ha" href="#base" aria-hidden="true">#</a>
</h3>
<p>The default page background and primary text colors. Foreground Secondary is for supporting text like subtitles and metadata.</p>
<div class="swatch-row">
  <div class="swatch">
    <div class="swatch-color swatch-bordered" style="background:#1a1c1b"></div>
    <code>#1a1c1b</code>
    <div>Background</div>
  </div>

  <div class="swatch">
    <div class="swatch-color" style="background:#e8e4dc"></div>
    <code>#e8e4dc</code>
    <div>Foreground</div>
  </div>

  <div class="swatch">
    <div class="swatch-color" style="background:#c5c1b8"></div>
    <code>#c5c1b8</code>
    <div>Foreground Secondary</div>
  </div>

</div>
<h3 id="muted">
  Muted
  <a class="ha" href="#muted" aria-hidden="true">#</a>
</h3>
<p>A subdued surface for secondary UI like disabled states, chips, and sidebars. Muted Foreground is for placeholder text and de-emphasized labels.</p>
<div class="swatch-row">
  <div class="swatch">
    <div class="swatch-color swatch-bordered" style="background:#141615"></div>
    <code>#141615</code>
    <div>Muted</div>
  </div>

  <div class="swatch">
    <div class="swatch-color" style="background:#9e9b93"></div>
    <code>#9e9b93</code>
    <div>Muted Foreground</div>
  </div>

</div>
<h3 id="card">
  Card
  <a class="ha" href="#card" aria-hidden="true">#</a>
</h3>
<p>An elevated surface for cards, dialogs, popovers, and panels that sit above the background.</p>
<div class="swatch-row">
  <div class="swatch">
    <div class="swatch-color swatch-bordered" style="background:#242726"></div>
    <code>#242726</code>
    <div>Card</div>
  </div>

  <div class="swatch">
    <div class="swatch-color" style="background:#e8e4dc"></div>
    <code>#e8e4dc</code>
    <div>Card Foreground</div>
  </div>

</div>
<h3 id="accent">
  Accent
  <a class="ha" href="#accent" aria-hidden="true">#</a>
</h3>
<p>The primary action color for buttons, links, and interactive highlights. Accent Foreground is the text color on accent-colored surfaces.</p>
<div class="swatch-row">
  <div class="swatch">
    <div class="swatch-color" style="background:#8fac98"></div>
    <code>#8fac98</code>
    <div>Accent</div>
  </div>

  <div class="swatch">
    <div class="swatch-color" style="background:#a3bfac"></div>
    <code>#a3bfac</code>
    <div>Accent Hover</div>
  </div>

  <div class="swatch">
    <div class="swatch-color swatch-bordered" style="background:#1a1c1b"></div>
    <code>#1a1c1b</code>
    <div>Accent Foreground</div>
  </div>

</div>
<h3 id="destructive">
  Destructive
  <a class="ha" href="#destructive" aria-hidden="true">#</a>
</h3>
<p>For destructive actions and error states — delete buttons, form validation errors, error toasts, and danger alerts.</p>
<div class="swatch-row">
  <div class="swatch">
    <div class="swatch-color" style="background:#cc8585"></div>
    <code>#cc8585</code>
    <div>Destructive</div>
  </div>

  <div class="swatch">
    <div class="swatch-color" style="background:#d99292"></div>
    <code>#d99292</code>
    <div>Destructive Hover</div>
  </div>

  <div class="swatch">
    <div class="swatch-color swatch-bordered" style="background:#1a1c1b"></div>
    <code>#1a1c1b</code>
    <div>Destructive Foreground</div>
  </div>

</div>
<h3 id="success">
  Success
  <a class="ha" href="#success" aria-hidden="true">#</a>
</h3>
<p>For confirmations and positive states — saved indicators, valid form fields, success toasts, and completion badges.</p>
<div class="swatch-row">
  <div class="swatch">
    <div class="swatch-color" style="background:#7dba8a"></div>
    <code>#7dba8a</code>
    <div>Success</div>
  </div>

  <div class="swatch">
    <div class="swatch-color swatch-bordered" style="background:#1a1c1b"></div>
    <code>#1a1c1b</code>
    <div>Success Foreground</div>
  </div>

</div>
<h3 id="warning">
  Warning
  <a class="ha" href="#warning" aria-hidden="true">#</a>
</h3>
<p>For caution states — warnings, deprecation notices, and attention-needed indicators that aren&rsquo;t errors.</p>
<div class="swatch-row">
  <div class="swatch">
    <div class="swatch-color" style="background:#c9a86c"></div>
    <code>#c9a86c</code>
    <div>Warning</div>
  </div>

  <div class="swatch">
    <div class="swatch-color swatch-bordered" style="background:#1a1c1b"></div>
    <code>#1a1c1b</code>
    <div>Warning Foreground</div>
  </div>

</div>
<h3 id="borders--focus">
  Borders &amp; Focus
  <a class="ha" href="#borders--focus" aria-hidden="true">#</a>
</h3>
<p>Structural and interactive borders. Ring is the focus indicator for keyboard navigation. Input is the default border for form fields. Border is for layout dividers and container edges.</p>
<div class="swatch-row">
  <div class="swatch">
    <div class="swatch-color" style="background:#95bebe"></div>
    <code>#95bebe</code>
    <div>Ring</div>
  </div>

  <div class="swatch">
    <div class="swatch-color" style="background:#6b7369"></div>
    <code>#6b7369</code>
    <div>Input</div>
  </div>

  <div class="swatch">
    <div class="swatch-color swatch-bordered" style="background:#2e312f"></div>
    <code>#2e312f</code>
    <div>Border</div>
  </div>

</div>
<h3 id="syntax">
  Syntax
  <a class="ha" href="#syntax" aria-hidden="true">#</a>
</h3>
<p>Colors for code highlighting — keywords, strings, types, and other language constructs.</p>
<div class="swatch-row">
  <div class="swatch">
    <div class="swatch-color" style="background:#8fac98"></div>
    <code>#8fac98</code>
    <div>Keyword</div>
  </div>

  <div class="swatch">
    <div class="swatch-color" style="background:#a3bfac"></div>
    <code>#a3bfac</code>
    <div>Function</div>
  </div>

  <div class="swatch">
    <div class="swatch-color" style="background:#c9a86c"></div>
    <code>#c9a86c</code>
    <div>String</div>
  </div>

  <div class="swatch">
    <div class="swatch-color" style="background:#7eb8c9"></div>
    <code>#7eb8c9</code>
    <div>Number</div>
  </div>

  <div class="swatch">
    <div class="swatch-color" style="background:#8fb8ad"></div>
    <code>#8fb8ad</code>
    <div>Type</div>
  </div>

  <div class="swatch">
    <div class="swatch-color" style="background:#9e9b93"></div>
    <code>#9e9b93</code>
    <div>Comment</div>
  </div>

  <div class="swatch">
    <div class="swatch-color" style="background:#cc8585"></div>
    <code>#cc8585</code>
    <div>Tag</div>
  </div>

  <div class="swatch">
    <div class="swatch-color" style="background:#a9ad78"></div>
    <code>#a9ad78</code>
    <div>Regex</div>
  </div>

</div>
<h3 id="editor">
  Editor
  <a class="ha" href="#editor" aria-hidden="true">#</a>
</h3>
<p>Colors for editor chrome — cursor, selection, line highlighting, gutter, and diff backgrounds. These are the tinted surfaces used in code editors and IDEs.</p>
<div class="swatch-row">
  <div class="swatch">
    <div class="swatch-color" style="background:#8fac98"></div>
    <code>#8fac98</code>
    <div>Cursor</div>
  </div>

  <div class="swatch">
    <div class="swatch-color swatch-bordered" style="background:#3d4741"></div>
    <code>#3d4741</code>
    <div>Selection</div>
  </div>

  <div class="swatch">
    <div class="swatch-color swatch-bordered" style="background:#393a38"></div>
    <code>#393a38</code>
    <div>Line Highlight</div>
  </div>

  <div class="swatch">
    <div class="swatch-color swatch-bordered" style="background:#4f4633"></div>
    <code>#4f4633</code>
    <div>Find Match</div>
  </div>

</div>
<div class="swatch-row">
  <div class="swatch">
    <div class="swatch-color" style="background:#9e9b93"></div>
    <code>#9e9b93</code>
    <div>Gutter</div>
  </div>

  <div class="swatch">
    <div class="swatch-color" style="background:#c5c1b8"></div>
    <code>#c5c1b8</code>
    <div>Gutter Active</div>
  </div>

  <div class="swatch">
    <div class="swatch-color swatch-bordered" style="background:#2e312f"></div>
    <code>#2e312f</code>
    <div>Bracket Match</div>
  </div>

  <div class="swatch">
    <div class="swatch-color swatch-bordered" style="background:#2e312f"></div>
    <code>#2e312f</code>
    <div>Indent Guide</div>
  </div>

</div>
<div class="swatch-row">
  <div class="swatch">
    <div class="swatch-color swatch-bordered" style="background:#4f3c3b"></div>
    <code>#4f3c3b</code>
    <div>Diff Deleted</div>
  </div>

  <div class="swatch">
    <div class="swatch-color swatch-bordered" style="background:#384b3c"></div>
    <code>#384b3c</code>
    <div>Diff Inserted</div>
  </div>

</div>
<h2 id="light-theme">
  Light Theme
  <a class="ha" href="#light-theme" aria-hidden="true">#</a>
</h2>
<h3 id="base-1">
  Base
  <a class="ha" href="#base-1" aria-hidden="true">#</a>
</h3>
<div class="swatch-row">
  <div class="swatch">
    <div class="swatch-color swatch-bordered" style="background:#f5f2ed"></div>
    <code>#f5f2ed</code>
    <div>Background</div>
  </div>

  <div class="swatch">
    <div class="swatch-color" style="background:#2d2b28"></div>
    <code>#2d2b28</code>
    <div>Foreground</div>
  </div>

  <div class="swatch">
    <div class="swatch-color" style="background:#5a5753"></div>
    <code>#5a5753</code>
    <div>Foreground Secondary</div>
  </div>

</div>
<h3 id="muted-1">
  Muted
  <a class="ha" href="#muted-1" aria-hidden="true">#</a>
</h3>
<div class="swatch-row">
  <div class="swatch">
    <div class="swatch-color swatch-bordered" style="background:#ebe7e0"></div>
    <code>#ebe7e0</code>
    <div>Muted</div>
  </div>

  <div class="swatch">
    <div class="swatch-color" style="background:#6b6762"></div>
    <code>#6b6762</code>
    <div>Muted Foreground</div>
  </div>

</div>
<h3 id="card-1">
  Card
  <a class="ha" href="#card-1" aria-hidden="true">#</a>
</h3>
<div class="swatch-row">
  <div class="swatch">
    <div class="swatch-color swatch-bordered" style="background:#fdfcfa"></div>
    <code>#fdfcfa</code>
    <div>Card</div>
  </div>

  <div class="swatch">
    <div class="swatch-color" style="background:#2d2b28"></div>
    <code>#2d2b28</code>
    <div>Card Foreground</div>
  </div>

</div>
<h3 id="accent-1">
  Accent
  <a class="ha" href="#accent-1" aria-hidden="true">#</a>
</h3>
<div class="swatch-row">
  <div class="swatch">
    <div class="swatch-color" style="background:#506e58"></div>
    <code>#506e58</code>
    <div>Accent</div>
  </div>

  <div class="swatch">
    <div class="swatch-color" style="background:#425f4a"></div>
    <code>#425f4a</code>
    <div>Accent Hover</div>
  </div>

  <div class="swatch">
    <div class="swatch-color swatch-bordered" style="background:#f5f2ed"></div>
    <code>#f5f2ed</code>
    <div>Accent Foreground</div>
  </div>

</div>
<h3 id="destructive-1">
  Destructive
  <a class="ha" href="#destructive-1" aria-hidden="true">#</a>
</h3>
<div class="swatch-row">
  <div class="swatch">
    <div class="swatch-color" style="background:#a54d4d"></div>
    <code>#a54d4d</code>
    <div>Destructive</div>
  </div>

  <div class="swatch">
    <div class="swatch-color" style="background:#984242"></div>
    <code>#984242</code>
    <div>Destructive Hover</div>
  </div>

  <div class="swatch">
    <div class="swatch-color swatch-bordered" style="background:#f5f2ed"></div>
    <code>#f5f2ed</code>
    <div>Destructive Foreground</div>
  </div>

</div>
<h3 id="success-1">
  Success
  <a class="ha" href="#success-1" aria-hidden="true">#</a>
</h3>
<div class="swatch-row">
  <div class="swatch">
    <div class="swatch-color" style="background:#3a7346"></div>
    <code>#3a7346</code>
    <div>Success</div>
  </div>

  <div class="swatch">
    <div class="swatch-color swatch-bordered" style="background:#f5f2ed"></div>
    <code>#f5f2ed</code>
    <div>Success Foreground</div>
  </div>

</div>
<h3 id="warning-1">
  Warning
  <a class="ha" href="#warning-1" aria-hidden="true">#</a>
</h3>
<div class="swatch-row">
  <div class="swatch">
    <div class="swatch-color" style="background:#7d6325"></div>
    <code>#7d6325</code>
    <div>Warning</div>
  </div>

  <div class="swatch">
    <div class="swatch-color swatch-bordered" style="background:#f5f2ed"></div>
    <code>#f5f2ed</code>
    <div>Warning Foreground</div>
  </div>

</div>
<h3 id="borders--focus-1">
  Borders &amp; Focus
  <a class="ha" href="#borders--focus-1" aria-hidden="true">#</a>
</h3>
<div class="swatch-row">
  <div class="swatch">
    <div class="swatch-color" style="background:#3e5d5d"></div>
    <code>#3e5d5d</code>
    <div>Ring</div>
  </div>

  <div class="swatch">
    <div class="swatch-color" style="background:#888379"></div>
    <code>#888379</code>
    <div>Input</div>
  </div>

  <div class="swatch">
    <div class="swatch-color swatch-bordered" style="background:#ddd8d0"></div>
    <code>#ddd8d0</code>
    <div>Border</div>
  </div>

</div>
<h3 id="syntax-1">
  Syntax
  <a class="ha" href="#syntax-1" aria-hidden="true">#</a>
</h3>
<div class="swatch-row">
  <div class="swatch">
    <div class="swatch-color" style="background:#506e58"></div>
    <code>#506e58</code>
    <div>Keyword</div>
  </div>

  <div class="swatch">
    <div class="swatch-color" style="background:#425f4a"></div>
    <code>#425f4a</code>
    <div>Function</div>
  </div>

  <div class="swatch">
    <div class="swatch-color" style="background:#7d6325"></div>
    <code>#7d6325</code>
    <div>String</div>
  </div>

  <div class="swatch">
    <div class="swatch-color" style="background:#3a6f80"></div>
    <code>#3a6f80</code>
    <div>Number</div>
  </div>

  <div class="swatch">
    <div class="swatch-color" style="background:#3e6b5d"></div>
    <code>#3e6b5d</code>
    <div>Type</div>
  </div>

  <div class="swatch">
    <div class="swatch-color" style="background:#6b6762"></div>
    <code>#6b6762</code>
    <div>Comment</div>
  </div>

  <div class="swatch">
    <div class="swatch-color" style="background:#a54d4d"></div>
    <code>#a54d4d</code>
    <div>Tag</div>
  </div>

  <div class="swatch">
    <div class="swatch-color" style="background:#5c6135"></div>
    <code>#5c6135</code>
    <div>Regex</div>
  </div>

</div>
<h3 id="editor-1">
  Editor
  <a class="ha" href="#editor-1" aria-hidden="true">#</a>
</h3>
<div class="swatch-row">
  <div class="swatch">
    <div class="swatch-color" style="background:#506e58"></div>
    <code>#506e58</code>
    <div>Cursor</div>
  </div>

  <div class="swatch">
    <div class="swatch-color swatch-bordered" style="background:#c4cac0"></div>
    <code>#c4cac0</code>
    <div>Selection</div>
  </div>

  <div class="swatch">
    <div class="swatch-color swatch-bordered" style="background:#d7d4cf"></div>
    <code>#d7d4cf</code>
    <div>Line Highlight</div>
  </div>

  <div class="swatch">
    <div class="swatch-color swatch-bordered" style="background:#d1c7b1"></div>
    <code>#d1c7b1</code>
    <div>Find Match</div>
  </div>

</div>
<div class="swatch-row">
  <div class="swatch">
    <div class="swatch-color" style="background:#6b6762"></div>
    <code>#6b6762</code>
    <div>Gutter</div>
  </div>

  <div class="swatch">
    <div class="swatch-color" style="background:#5a5753"></div>
    <code>#5a5753</code>
    <div>Gutter Active</div>
  </div>

  <div class="swatch">
    <div class="swatch-color swatch-bordered" style="background:#ddd8d0"></div>
    <code>#ddd8d0</code>
    <div>Bracket Match</div>
  </div>

  <div class="swatch">
    <div class="swatch-color swatch-bordered" style="background:#ddd8d0"></div>
    <code>#ddd8d0</code>
    <div>Indent Guide</div>
  </div>

</div>
<div class="swatch-row">
  <div class="swatch">
    <div class="swatch-color swatch-bordered" style="background:#ddc1bd"></div>
    <code>#ddc1bd</code>
    <div>Diff Deleted</div>
  </div>

  <div class="swatch">
    <div class="swatch-color swatch-bordered" style="background:#bdccbb"></div>
    <code>#bdccbb</code>
    <div>Diff Inserted</div>
  </div>

</div>
<h2 id="accessibility">
  Accessibility
  <a class="ha" href="#accessibility" aria-hidden="true">#</a>
</h2>
<p>All foreground/background pairings meet WCAG 2.1 AA (4.5:1 for normal text, 3:1 for large text). Many primary pairings exceed AAA (7:1).</p>
<h3 id="dark-theme-1">
  Dark Theme
  <a class="ha" href="#dark-theme-1" aria-hidden="true">#</a>
</h3>
<h4 id="on-surfaces">
  On surfaces
  <a class="ha" href="#on-surfaces" aria-hidden="true">#</a>
</h4>
<p>Contrast ratios for text and UI elements on the three surface tokens.</p>
<table>
  <thead>
      <tr>
          <th>Token</th>
          <th>Background</th>
          <th>Card</th>
          <th>Muted</th>
          <th>Level</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Foreground</td>
          <td>13.5</td>
          <td>11.9</td>
          <td>14.3</td>
          <td>AAA</td>
      </tr>
      <tr>
          <td>Foreground Secondary</td>
          <td>9.5</td>
          <td>8.4</td>
          <td>10.1</td>
          <td>AAA</td>
      </tr>
      <tr>
          <td>Muted Foreground</td>
          <td>6.2</td>
          <td>5.4</td>
          <td>6.5</td>
          <td>AA</td>
      </tr>
      <tr>
          <td>Accent</td>
          <td>7.0</td>
          <td>6.1</td>
          <td>7.4</td>
          <td>AA-AAA</td>
      </tr>
      <tr>
          <td>Accent Hover</td>
          <td>8.7</td>
          <td>7.6</td>
          <td>9.2</td>
          <td>AAA</td>
      </tr>
      <tr>
          <td>Destructive</td>
          <td>5.9</td>
          <td>5.2</td>
          <td>6.3</td>
          <td>AA</td>
      </tr>
      <tr>
          <td>Destructive Hover</td>
          <td>6.9</td>
          <td>6.1</td>
          <td>7.3</td>
          <td>AA</td>
      </tr>
      <tr>
          <td>Success</td>
          <td>7.6</td>
          <td>6.6</td>
          <td>8.0</td>
          <td>AA-AAA</td>
      </tr>
      <tr>
          <td>Warning</td>
          <td>7.6</td>
          <td>6.7</td>
          <td>8.1</td>
          <td>AA-AAA</td>
      </tr>
      <tr>
          <td>Ring</td>
          <td>8.5</td>
          <td>7.5</td>
          <td>9.0</td>
          <td>AAA</td>
      </tr>
      <tr>
          <td>Input</td>
          <td>3.5</td>
          <td>3.1</td>
          <td>3.7</td>
          <td>AA (non-text)</td>
      </tr>
  </tbody>
</table>
<h4 id="paired-foregrounds">
  Paired foregrounds
  <a class="ha" href="#paired-foregrounds" aria-hidden="true">#</a>
</h4>
<p>Contrast ratios for foreground tokens measured against their own surface.</p>
<table>
  <thead>
      <tr>
          <th>Token</th>
          <th>Surface</th>
          <th>Contrast</th>
          <th>Level</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Card Foreground</td>
          <td>Card</td>
          <td>11.9</td>
          <td>AAA</td>
      </tr>
      <tr>
          <td>Accent Foreground</td>
          <td>Accent</td>
          <td>7.0</td>
          <td>AAA</td>
      </tr>
      <tr>
          <td>Destructive Foreground</td>
          <td>Destructive</td>
          <td>5.9</td>
          <td>AA</td>
      </tr>
      <tr>
          <td>Success Foreground</td>
          <td>Success</td>
          <td>7.6</td>
          <td>AAA</td>
      </tr>
      <tr>
          <td>Warning Foreground</td>
          <td>Warning</td>
          <td>7.6</td>
          <td>AAA</td>
      </tr>
  </tbody>
</table>
<h4 id="syntax-on-surfaces">
  Syntax on surfaces
  <a class="ha" href="#syntax-on-surfaces" aria-hidden="true">#</a>
</h4>
<p>Contrast ratios for syntax highlighting tokens on the three surface tokens.</p>
<table>
  <thead>
      <tr>
          <th>Token</th>
          <th>Background</th>
          <th>Card</th>
          <th>Muted</th>
          <th>Level</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Keyword</td>
          <td>7.0</td>
          <td>6.1</td>
          <td>7.4</td>
          <td>AA-AAA</td>
      </tr>
      <tr>
          <td>Function</td>
          <td>8.7</td>
          <td>7.6</td>
          <td>9.2</td>
          <td>AAA</td>
      </tr>
      <tr>
          <td>String</td>
          <td>7.6</td>
          <td>6.7</td>
          <td>8.1</td>
          <td>AA-AAA</td>
      </tr>
      <tr>
          <td>Number</td>
          <td>7.8</td>
          <td>6.9</td>
          <td>8.3</td>
          <td>AA-AAA</td>
      </tr>
      <tr>
          <td>Type</td>
          <td>7.9</td>
          <td>6.9</td>
          <td>8.3</td>
          <td>AA-AAA</td>
      </tr>
      <tr>
          <td>Comment</td>
          <td>6.2</td>
          <td>5.4</td>
          <td>6.5</td>
          <td>AA</td>
      </tr>
      <tr>
          <td>Tag</td>
          <td>5.9</td>
          <td>5.2</td>
          <td>6.3</td>
          <td>AA</td>
      </tr>
      <tr>
          <td>Regex</td>
          <td>7.3</td>
          <td>6.4</td>
          <td>7.7</td>
          <td>AA-AAA</td>
      </tr>
  </tbody>
</table>
<h4 id="editor-chrome">
  Editor chrome
  <a class="ha" href="#editor-chrome" aria-hidden="true">#</a>
</h4>
<p>Contrast ratios for editor text elements on background, and foreground text readability on tinted highlight surfaces.</p>
<table>
  <thead>
      <tr>
          <th>Token</th>
          <th>On Background</th>
          <th>Level</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Cursor</td>
          <td>7.0</td>
          <td>AAA</td>
      </tr>
      <tr>
          <td>Gutter</td>
          <td>6.2</td>
          <td>AA</td>
      </tr>
      <tr>
          <td>Gutter Active</td>
          <td>9.5</td>
          <td>AAA</td>
      </tr>
  </tbody>
</table>
<table>
  <thead>
      <tr>
          <th>Token</th>
          <th>Foreground on surface</th>
          <th>Level</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Selection</td>
          <td>7.6</td>
          <td>AAA</td>
      </tr>
      <tr>
          <td>Line Highlight</td>
          <td>9.0</td>
          <td>AAA</td>
      </tr>
      <tr>
          <td>Find Match</td>
          <td>7.3</td>
          <td>AAA</td>
      </tr>
      <tr>
          <td>Diff Deleted</td>
          <td>8.1</td>
          <td>AAA</td>
      </tr>
      <tr>
          <td>Diff Inserted</td>
          <td>7.4</td>
          <td>AAA</td>
      </tr>
  </tbody>
</table>
<h3 id="light-theme-1">
  Light Theme
  <a class="ha" href="#light-theme-1" aria-hidden="true">#</a>
</h3>
<h4 id="on-surfaces-1">
  On surfaces
  <a class="ha" href="#on-surfaces-1" aria-hidden="true">#</a>
</h4>
<table>
  <thead>
      <tr>
          <th>Token</th>
          <th>Background</th>
          <th>Card</th>
          <th>Muted</th>
          <th>Level</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Foreground</td>
          <td>12.6</td>
          <td>13.8</td>
          <td>11.5</td>
          <td>AAA</td>
      </tr>
      <tr>
          <td>Foreground Secondary</td>
          <td>6.4</td>
          <td>7.0</td>
          <td>5.8</td>
          <td>AA-AAA</td>
      </tr>
      <tr>
          <td>Muted Foreground</td>
          <td>5.0</td>
          <td>5.5</td>
          <td>4.6</td>
          <td>AA</td>
      </tr>
      <tr>
          <td>Accent</td>
          <td>5.1</td>
          <td>5.5</td>
          <td>4.6</td>
          <td>AA</td>
      </tr>
      <tr>
          <td>Accent Hover</td>
          <td>6.3</td>
          <td>6.9</td>
          <td>5.7</td>
          <td>AA</td>
      </tr>
      <tr>
          <td>Destructive</td>
          <td>5.0</td>
          <td>5.4</td>
          <td>4.5</td>
          <td>AA</td>
      </tr>
      <tr>
          <td>Destructive Hover</td>
          <td>5.9</td>
          <td>6.4</td>
          <td>5.3</td>
          <td>AA</td>
      </tr>
      <tr>
          <td>Success</td>
          <td>5.1</td>
          <td>5.5</td>
          <td>4.6</td>
          <td>AA</td>
      </tr>
      <tr>
          <td>Warning</td>
          <td>5.1</td>
          <td>5.6</td>
          <td>4.6</td>
          <td>AA</td>
      </tr>
      <tr>
          <td>Ring</td>
          <td>6.4</td>
          <td>7.0</td>
          <td>5.8</td>
          <td>AA-AAA</td>
      </tr>
      <tr>
          <td>Input</td>
          <td>3.4</td>
          <td>3.7</td>
          <td>3.1</td>
          <td>AA (non-text)</td>
      </tr>
  </tbody>
</table>
<h4 id="paired-foregrounds-1">
  Paired foregrounds
  <a class="ha" href="#paired-foregrounds-1" aria-hidden="true">#</a>
</h4>
<table>
  <thead>
      <tr>
          <th>Token</th>
          <th>Surface</th>
          <th>Contrast</th>
          <th>Level</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Card Foreground</td>
          <td>Card</td>
          <td>13.8</td>
          <td>AAA</td>
      </tr>
      <tr>
          <td>Accent Foreground</td>
          <td>Accent</td>
          <td>5.1</td>
          <td>AA</td>
      </tr>
      <tr>
          <td>Destructive Foreground</td>
          <td>Destructive</td>
          <td>5.0</td>
          <td>AA</td>
      </tr>
      <tr>
          <td>Success Foreground</td>
          <td>Success</td>
          <td>5.1</td>
          <td>AA</td>
      </tr>
      <tr>
          <td>Warning Foreground</td>
          <td>Warning</td>
          <td>5.1</td>
          <td>AA</td>
      </tr>
  </tbody>
</table>
<h4 id="syntax-on-surfaces-1">
  Syntax on surfaces
  <a class="ha" href="#syntax-on-surfaces-1" aria-hidden="true">#</a>
</h4>
<table>
  <thead>
      <tr>
          <th>Token</th>
          <th>Background</th>
          <th>Card</th>
          <th>Muted</th>
          <th>Level</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Keyword</td>
          <td>5.1</td>
          <td>5.5</td>
          <td>4.6</td>
          <td>AA</td>
      </tr>
      <tr>
          <td>Function</td>
          <td>6.3</td>
          <td>6.9</td>
          <td>5.7</td>
          <td>AA</td>
      </tr>
      <tr>
          <td>String</td>
          <td>5.1</td>
          <td>5.6</td>
          <td>4.6</td>
          <td>AA</td>
      </tr>
      <tr>
          <td>Number</td>
          <td>5.0</td>
          <td>5.4</td>
          <td>4.5</td>
          <td>AA</td>
      </tr>
      <tr>
          <td>Type</td>
          <td>5.4</td>
          <td>5.9</td>
          <td>4.9</td>
          <td>AA</td>
      </tr>
      <tr>
          <td>Comment</td>
          <td>5.0</td>
          <td>5.5</td>
          <td>4.6</td>
          <td>AA</td>
      </tr>
      <tr>
          <td>Tag</td>
          <td>5.0</td>
          <td>5.4</td>
          <td>4.5</td>
          <td>AA</td>
      </tr>
      <tr>
          <td>Regex</td>
          <td>5.8</td>
          <td>6.4</td>
          <td>5.3</td>
          <td>AA</td>
      </tr>
  </tbody>
</table>
<h4 id="editor-chrome-1">
  Editor chrome
  <a class="ha" href="#editor-chrome-1" aria-hidden="true">#</a>
</h4>
<table>
  <thead>
      <tr>
          <th>Token</th>
          <th>On Background</th>
          <th>Level</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Cursor</td>
          <td>5.1</td>
          <td>AA</td>
      </tr>
      <tr>
          <td>Gutter</td>
          <td>5.0</td>
          <td>AA</td>
      </tr>
      <tr>
          <td>Gutter Active</td>
          <td>6.4</td>
          <td>AA</td>
      </tr>
  </tbody>
</table>
<table>
  <thead>
      <tr>
          <th>Token</th>
          <th>Foreground on surface</th>
          <th>Level</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Selection</td>
          <td>8.4</td>
          <td>AAA</td>
      </tr>
      <tr>
          <td>Line Highlight</td>
          <td>9.5</td>
          <td>AAA</td>
      </tr>
      <tr>
          <td>Find Match</td>
          <td>8.4</td>
          <td>AAA</td>
      </tr>
      <tr>
          <td>Diff Deleted</td>
          <td>8.4</td>
          <td>AAA</td>
      </tr>
      <tr>
          <td>Diff Inserted</td>
          <td>8.4</td>
          <td>AAA</td>
      </tr>
  </tbody>
</table>
<h2 id="examples">
  Examples
  <a class="ha" href="#examples" aria-hidden="true">#</a>
</h2>
<p>Here&rsquo;s how the theme looks applied to common UI elements. <a href="javascript:void(0)" onclick="document.getElementById('theme-toggle').click()">Toggle light/dark mode</a> to see both variants.</p>
<h3 id="buttons">
  Buttons
  <a class="ha" href="#buttons" aria-hidden="true">#</a>
</h3>
<div class="btn-row">
  <button class="btn btn-primary">Primary</button>
  <button class="btn btn-outline">Outline</button>
  <button class="btn btn-danger">Destructive</button>
</div>
<h3 id="form-fields">
  Form Fields
  <a class="ha" href="#form-fields" aria-hidden="true">#</a>
</h3>
<div class="form-row" role="group" aria-label="Example form fields (non-functional)">
  <div class="form-field">
    <label for="demo-name">Name</label>
    <input id="demo-name" type="text" placeholder="Enter your name" aria-description="Demo field, not submitted">
  </div>
  <div class="form-field">
    <label for="demo-email">Email</label>
    <input id="demo-email" type="email" placeholder="you@example.com" aria-description="Demo field, not submitted">
  </div>
  <div class="form-field">
    <label for="demo-message">Message</label>
    <textarea id="demo-message" rows="3" placeholder="Write something..." aria-description="Demo field, not submitted"></textarea>
  </div>
</div>
<h3 id="code-blocks">
  Code Blocks
  <a class="ha" href="#code-blocks" aria-hidden="true">#</a>
</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">dataclasses</span> <span class="kn">import</span> <span class="n">dataclass</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Minimum contrast for WCAG AA compliance</span>
</span></span><span class="line"><span class="cl"><span class="n">CONTRAST_AA</span> <span class="o">=</span> <span class="mf">4.5</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nd">@dataclass</span>
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">Color</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;&#34;&#34;A named color primitive.&#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="n">name</span><span class="p">:</span> <span class="nb">str</span>
</span></span><span class="line"><span class="cl">    <span class="n">value</span><span class="p">:</span> <span class="nb">str</span>
</span></span><span class="line"><span class="cl">    <span class="n">luminance</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="mf">0.0</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">meets_aa</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">:</span> <span class="s2">&#34;Color&#34;</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">ratio</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">contrast</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">ratio</span> <span class="o">&gt;=</span> <span class="n">CONTRAST_AA</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">palette</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&#34;sage&#34;</span><span class="p">:</span> <span class="s2">&#34;#8fac98&#34;</span><span class="p">,</span> <span class="s2">&#34;amber&#34;</span><span class="p">:</span> <span class="s2">&#34;#c9a86c&#34;</span><span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="n">total</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">palette</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">is_valid</span> <span class="o">=</span> <span class="n">total</span> <span class="o">&gt;</span> <span class="mi">0</span> <span class="ow">and</span> <span class="kc">True</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;Colors: </span><span class="si">{</span><span class="n">total</span><span class="si">}</span><span class="s2">, valid=</span><span class="si">{</span><span class="n">is_valid</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">)</span>
</span></span></code></pre></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;swatch&#34;</span> <span class="na">data-color</span><span class="o">=</span><span class="s">&#34;#8fac98&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">span</span><span class="p">&gt;</span>Sage<span class="p">&lt;/</span><span class="nt">span</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">code</span><span class="p">&gt;</span>#8fac98<span class="p">&lt;/</span><span class="nt">code</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">HEX</span> <span class="o">=</span> <span class="sr">/^#([a-f\d]{2}){3}$/i</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">function</span> <span class="nx">parseHex</span><span class="p">(</span><span class="nx">value</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">HEX</span><span class="p">.</span><span class="nx">test</span><span class="p">(</span><span class="nx">value</span><span class="p">))</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">throw</span> <span class="k">new</span> <span class="nb">Error</span><span class="p">(</span><span class="sb">`Invalid: </span><span class="si">${</span><span class="nx">value</span><span class="si">}</span><span class="sb">`</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">5</span><span class="p">].</span><span class="nx">map</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="p">(</span><span class="nx">i</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="nb">parseInt</span><span class="p">(</span><span class="nx">value</span><span class="p">.</span><span class="nx">slice</span><span class="p">(</span><span class="nx">i</span><span class="p">,</span> <span class="nx">i</span> <span class="o">+</span> <span class="mi">2</span><span class="p">),</span> <span class="mi">16</span><span class="p">)</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><h3 id="blockquote">
  Blockquote
  <a class="ha" href="#blockquote" aria-hidden="true">#</a>
</h3>
<blockquote>
  The Liminal Salt palette draws from natural, earthy tones — muted sage greens and warm beiges that feel grounded without being heavy.
</blockquote>
<h3 id="inline-code--links">
  Inline Code &amp; Links
  <a class="ha" href="#inline-code--links" aria-hidden="true">#</a>
</h3>
<p>Here&rsquo;s some <code>inline code</code> alongside a <a href="https://github.com/irvj/liminal-salt-theme">link to the repository</a>. The theme&rsquo;s <code>--accent</code> variable drives both the link color and the code highlight, keeping everything visually cohesive across <code>light</code> and <code>dark</code> modes.</p>
]]></content>
  </entry>
  
  <entry>
    <title>Start</title>
    <link href="https://irvin.dev/posts/start/" />
    <id>https://irvin.dev/posts/start/</id>
    <updated>2025-12-13T00:00:00Z</updated>
    <content type="html"><![CDATA[<p>This site is built using <a href="https://www.11ty.dev/" target="_blank" rel="noopener noreferrer">11ty</a>. Repo at <a href="https://github.com/irvj/irvin-dev" target="_blank" rel="noopener noreferrer">GitHub</a>. Deployed using <a href="https://pages.cloudflare.com" target="_blank" rel="noopener noreferrer">Cloudflare Pages</a>. The theme is <a href="https://www.nordtheme.com" target="_blank" rel="noopener noreferrer">Nord</a>. I don&rsquo;t think any of these things will change. If they do, I won&rsquo;t update this post. I&rsquo;ll leave it as is for posterity.</p>
<p>If you want to know about me, check out the <a href="/about/">about page</a>. That page, on the other hand, will probably get updated on occasion.</p>
<p>I&rsquo;m not entirely sure what&rsquo;s next. But that&rsquo;s where I&rsquo;m headed anyway.</p>
<p>Let&rsquo;s begin.</p>
]]></content>
  </entry>
  
</feed>
