<!DOCTYPE html><html lang="en"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><link rel="icon" type="image/svg+xml" href="/favicon.svg"><meta name="generator" content="Astro v5.17.3"><title>if(and)else | AI, code, leadership, and the occasional broader take</title><!-- Primary Meta Tags --><meta name="title" content="if(and)else | AI, code, leadership, and the occasional broader take"><meta name="description" content="AI, code, leadership, and the occasional broader take"><!-- Canonical --><link rel="canonical" href="https://ifandelse.com/"><!-- Open Graph / Facebook --><meta property="og:type" content="website"><meta property="og:url" content="https://ifandelse.com/"><meta property="og:title" content="if(and)else | AI, code, leadership, and the occasional broader take"><meta property="og:description" content="AI, code, leadership, and the occasional broader take"><meta property="og:image" content="https://ifandelse.com/og-default.png"><meta property="og:site_name" content="if(and)else"><!-- Twitter --><meta property="twitter:card" content="summary_large_image"><meta property="twitter:url" content="https://ifandelse.com/"><meta property="twitter:title" content="if(and)else | AI, code, leadership, and the occasional broader take"><meta property="twitter:description" content="AI, code, leadership, and the occasional broader take"><meta property="twitter:image" content="https://ifandelse.com/og-default.png"><meta property="twitter:site" content="@@ifandelse"><!-- RSS Feed Discovery --><link rel="alternate" type="application/rss+xml" title="if(and)else Blog" href="/rss.xml"><!-- Umami Analytics --><script defer src="https://cloud.umami.is/script.js" data-website-id="0c0d085e-0d62-459e-a267-409e1a8f7571"></script><!-- Apply theme before paint to prevent flash --><script data-default-theme="catppuccin-mocha">
      (function() {
        const defaultTheme = document.currentScript?.getAttribute('data-default-theme') || 'clean-white';
        const savedTheme = localStorage.getItem('theme') || defaultTheme;
        const lightThemes = ['clean-white', 'catppuccin-latte', 'rose-pine-dawn', 'nord-light', 'solarized-light', 'gruvbox-light', 'tokyo-night-light'];
        const isLight = lightThemes.includes(savedTheme);
        
        document.documentElement.setAttribute('data-theme', savedTheme);
        if (!isLight) {
          document.documentElement.classList.add('dark');
        }
      })();
    </script><link rel="stylesheet" href="/_astro/_slug_.CYUhfthz.css">
<style>.typing-text[data-astro-cid-dpb7jah2]:after{content:"▋";animation:blink 1s infinite;transition:opacity .5s ease}.typing-done[data-astro-cid-dpb7jah2]:after{opacity:0;animation:none}@keyframes blink{0%,50%{opacity:1}51%,to{opacity:0}}
.terminal-header[data-astro-cid-xps5lu52]{font-family:JetBrains Mono,Geist Mono,monospace;font-weight:600;display:flex;align-items:center;gap:.5rem}
</style></head> <body class="min-h-screen bg-background text-foreground antialiased flex flex-col"> <header class="sticky top-0 z-50 w-full border-b bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60"> <div class="container max-w-5xl mx-auto px-4 sm:px-6 flex h-14 items-center justify-between"> <!-- Terminal Prompt Logo --> <div class="flex items-center font-mono"> <a href="/" class="flex items-center gap-2 hover:text-primary transition-colors"> <span class="text-primary">~</span> <span class="font-semibold">/if(and)else</span> </a> </div> <!-- Desktop Navigation - Bracketed --> <nav class="hidden md:flex items-center gap-1 text-base font-mono"> <a href="/" class="px-2 py-1.5 rounded transition-all hover:bg-primary/10 hover:text-primary text-primary">
[home]
</a><a href="/blog" class="px-2 py-1.5 rounded transition-all hover:bg-primary/10 hover:text-primary text-muted-foreground">
[blog]
</a><a href="/about" class="px-2 py-1.5 rounded transition-all hover:bg-primary/10 hover:text-primary text-muted-foreground">
[about]
</a><a href="/search" class="px-2 py-1.5 rounded transition-all hover:bg-primary/10 hover:text-primary text-muted-foreground">
[search]
</a> </nav> <!-- Desktop Actions --> <div class="hidden md:flex items-center gap-2">  <div class="theme-switcher relative" data-default-theme="catppuccin-mocha"> <button id="theme-toggle" class="flex items-center gap-2 font-mono text-sm text-muted-foreground hover:text-primary transition-colors px-2 py-1 rounded hover:bg-secondary" aria-label="Change theme" aria-haspopup="true"> <svg id="theme-icon-light" class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z"></path> </svg> <svg id="theme-icon-dark" class="w-4 h-4 hidden" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z"></path> </svg> <span id="theme-label">Theme</span> </button> <div id="theme-menu" class="hidden absolute right-0 mt-2 py-2 bg-card border border-border rounded-lg shadow-lg z-50 min-w-[200px] max-h-[400px] overflow-y-auto" style="color: var(--color-card-foreground);"> <!-- Light Themes First --> <div class="px-3 py-1.5 text-xs font-mono uppercase tracking-wide opacity-60">
Light Themes
</div> <button class="theme-option w-full px-4 py-2 text-left font-mono text-sm transition-colors flex items-center gap-3 hover:opacity-80" data-theme="clean-white" data-type="light" style="background: transparent;"> <span class="w-3 h-3 rounded-full border border-border shrink-0" style="background: #0066cc"></span> <span class="truncate">Clean White</span> </button><button class="theme-option w-full px-4 py-2 text-left font-mono text-sm transition-colors flex items-center gap-3 hover:opacity-80" data-theme="catppuccin-latte" data-type="light" style="background: transparent;"> <span class="w-3 h-3 rounded-full border border-border shrink-0" style="background: #8839ef"></span> <span class="truncate">Catppuccin Latte</span> </button><button class="theme-option w-full px-4 py-2 text-left font-mono text-sm transition-colors flex items-center gap-3 hover:opacity-80" data-theme="rose-pine-dawn" data-type="light" style="background: transparent;"> <span class="w-3 h-3 rounded-full border border-border shrink-0" style="background: #907aa9"></span> <span class="truncate">Rosé Pine Dawn</span> </button><button class="theme-option w-full px-4 py-2 text-left font-mono text-sm transition-colors flex items-center gap-3 hover:opacity-80" data-theme="nord-light" data-type="light" style="background: transparent;"> <span class="w-3 h-3 rounded-full border border-border shrink-0" style="background: #5e81ac"></span> <span class="truncate">Nord Light</span> </button><button class="theme-option w-full px-4 py-2 text-left font-mono text-sm transition-colors flex items-center gap-3 hover:opacity-80" data-theme="solarized-light" data-type="light" style="background: transparent;"> <span class="w-3 h-3 rounded-full border border-border shrink-0" style="background: #268bd2"></span> <span class="truncate">Solarized Light</span> </button><button class="theme-option w-full px-4 py-2 text-left font-mono text-sm transition-colors flex items-center gap-3 hover:opacity-80" data-theme="gruvbox-light" data-type="light" style="background: transparent;"> <span class="w-3 h-3 rounded-full border border-border shrink-0" style="background: #b57614"></span> <span class="truncate">Gruvbox Light</span> </button><button class="theme-option w-full px-4 py-2 text-left font-mono text-sm transition-colors flex items-center gap-3 hover:opacity-80" data-theme="tokyo-night-light" data-type="light" style="background: transparent;"> <span class="w-3 h-3 rounded-full border border-border shrink-0" style="background: #34548a"></span> <span class="truncate">Tokyo Night Light</span> </button> <hr class="my-2 border-border"> <!-- Dark Themes --> <div class="px-3 py-1.5 text-xs font-mono uppercase tracking-wide opacity-60">
Dark Themes
</div> <button class="theme-option w-full px-4 py-2 text-left font-mono text-sm transition-colors flex items-center gap-3 hover:opacity-80" data-theme="catppuccin-mocha" data-type="dark" style="background: transparent;"> <span class="w-3 h-3 rounded-full border border-border shrink-0" style="background: #cba6f7"></span> <span class="truncate">Catppuccin Mocha</span> </button><button class="theme-option w-full px-4 py-2 text-left font-mono text-sm transition-colors flex items-center gap-3 hover:opacity-80" data-theme="rose-pine" data-type="dark" style="background: transparent;"> <span class="w-3 h-3 rounded-full border border-border shrink-0" style="background: #c4a7e7"></span> <span class="truncate">Rosé Pine</span> </button><button class="theme-option w-full px-4 py-2 text-left font-mono text-sm transition-colors flex items-center gap-3 hover:opacity-80" data-theme="nord" data-type="dark" style="background: transparent;"> <span class="w-3 h-3 rounded-full border border-border shrink-0" style="background: #88c0d0"></span> <span class="truncate">Nord</span> </button><button class="theme-option w-full px-4 py-2 text-left font-mono text-sm transition-colors flex items-center gap-3 hover:opacity-80" data-theme="dracula" data-type="dark" style="background: transparent;"> <span class="w-3 h-3 rounded-full border border-border shrink-0" style="background: #bd93f9"></span> <span class="truncate">Dracula</span> </button><button class="theme-option w-full px-4 py-2 text-left font-mono text-sm transition-colors flex items-center gap-3 hover:opacity-80" data-theme="solarized-dark" data-type="dark" style="background: transparent;"> <span class="w-3 h-3 rounded-full border border-border shrink-0" style="background: #268bd2"></span> <span class="truncate">Solarized Dark</span> </button><button class="theme-option w-full px-4 py-2 text-left font-mono text-sm transition-colors flex items-center gap-3 hover:opacity-80" data-theme="gruvbox-dark" data-type="dark" style="background: transparent;"> <span class="w-3 h-3 rounded-full border border-border shrink-0" style="background: #fabd2f"></span> <span class="truncate">Gruvbox Dark</span> </button><button class="theme-option w-full px-4 py-2 text-left font-mono text-sm transition-colors flex items-center gap-3 hover:opacity-80" data-theme="tokyo-night" data-type="dark" style="background: transparent;"> <span class="w-3 h-3 rounded-full border border-border shrink-0" style="background: #7aa2f7"></span> <span class="truncate">Tokyo Night</span> </button> </div> </div> <script type="module">function m(){const n=document.getElementById("theme-toggle"),t=document.getElementById("theme-menu"),d=document.querySelectorAll(".theme-option");document.getElementById("theme-icon-dark"),document.getElementById("theme-icon-light");const i=document.querySelector(".theme-switcher")?.dataset.defaultTheme||"clean-white",c=localStorage.getItem("theme")||i;a(c),n?.addEventListener("click",e=>{e.stopPropagation(),t?.classList.toggle("hidden")}),d.forEach(e=>{e.addEventListener("click",()=>{const o=e.dataset.theme||i;a(o),localStorage.setItem("theme",o),t?.classList.add("hidden")})}),document.addEventListener("click",e=>{n?.contains(e.target)||t?.classList.add("hidden")}),document.addEventListener("keydown",e=>{e.key==="Escape"&&t?.classList.add("hidden")})}function a(n){const t=document.documentElement,d=document.getElementById("theme-icon-dark"),s=document.getElementById("theme-icon-light"),c=["clean-white","catppuccin-latte","rose-pine-dawn","nord-light","solarized-light","gruvbox-light","tokyo-night-light"].includes(n);t.classList.remove("dark"),t.removeAttribute("data-theme"),t.setAttribute("data-theme",n),c||t.classList.add("dark"),d&&s&&(c?(d.classList.add("hidden"),s.classList.remove("hidden")):(d.classList.remove("hidden"),s.classList.add("hidden"))),document.querySelectorAll(".theme-option").forEach(e=>{e.dataset.theme===n?e.classList.add("text-primary","bg-secondary"):e.classList.remove("text-primary","bg-secondary")})}m();document.addEventListener("astro:after-swap",m);</script> </div> <!-- Mobile Menu Button --> <div class="flex md:hidden items-center gap-2"> <a href="/search" class="font-mono text-sm text-muted-foreground hover:text-primary transition-colors">
[🔍]
</a> <button id="mobile-menu-button" class="inline-flex items-center justify-center rounded-md p-2 hover:bg-card hover:text-primary focus:outline-none font-mono text-sm" aria-expanded="false" aria-label="Toggle menu">
[menu]
</button> </div> </div> <!-- Mobile Navigation --> <div id="mobile-menu" class="hidden md:hidden border-t bg-background"> <nav class="container max-w-5xl mx-auto px-4 py-4 flex flex-col gap-2 font-mono"> <a href="/" class="px-2 py-2 rounded transition-all hover:bg-primary/10 hover:text-primary text-primary">
[home]
</a><a href="/blog" class="px-2 py-2 rounded transition-all hover:bg-primary/10 hover:text-primary text-muted-foreground">
[blog]
</a><a href="/about" class="px-2 py-2 rounded transition-all hover:bg-primary/10 hover:text-primary text-muted-foreground">
[about]
</a><a href="/search" class="px-2 py-2 rounded transition-all hover:bg-primary/10 hover:text-primary text-muted-foreground">
[search]
</a> <hr class="my-2 border-border"> <a href="/archives" class="px-2 py-2 rounded transition-all hover:bg-primary/10 text-muted-foreground hover:text-primary">
[archives]
</a> <a href="/rss.xml" class="px-2 py-2 rounded transition-all hover:bg-primary/10 text-muted-foreground hover:text-primary">
[rss]
</a>  </nav> </div> </header> <script type="module">const e=document.getElementById("mobile-menu-button"),n=document.getElementById("mobile-menu");e?.addEventListener("click",()=>{const t=n?.classList.toggle("hidden");e.setAttribute("aria-expanded",String(!t))});</script> <main class="flex-1">   <section class="min-h-[50vh] flex items-center justify-center py-16"> <div class="container max-w-5xl mx-auto px-6 flex justify-center"> <!-- Terminal-styled card --> <div class="terminal-window max-w-3xl w-full"> <div class="terminal-titlebar"> <div class="terminal-buttons"> <span class="terminal-button terminal-button-red"></span> <span class="terminal-button terminal-button-yellow"></span> <span class="terminal-button terminal-button-green"></span> </div> <span class="text-sm text-muted-foreground font-mono">~/ifandelse</span> </div> <div class="terminal-content text-center"> <div class="space-y-4"> <div> <h1 class="text-3xl md:text-4xl font-bold font-mono"> if(and)else </h1> <!-- Typewriter Container --> <div class="typewriter-lines mt-4 space-y-1 min-h-[3rem]" id="typewriter-container" data-lines="[&#34;AI, code, leadership, and the occasional broader take&#34;,&#34;by Jim Cowart&#34;]"> <p class="text-muted-foreground font-mono" id="line-1"></p> <p class="text-muted-foreground font-mono" id="line-2"><span class="terminal-cursor" id="typewriter-cursor"></span></p> </div> </div> <p class="font-mono text-muted-foreground">A blog about <span class="text-primary">human agency</span>, <span class="text-primary">building products</span>, and <span class="text-primary">not surrendering your mental model</span>.</p> <!-- Social Links --> <div class="flex flex-wrap items-center justify-center gap-4 pt-2"> <a href="https://github.com/ifandelse" target="_blank" rel="noopener noreferrer" class="text-muted-foreground hover:text-primary transition-colors" aria-label="GitHub"> <svg class="w-5 h-5" fill="currentColor" viewBox="0 0 24 24"><path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"></path></svg> </a> <a href="https://twitter.com/ifandelse" target="_blank" rel="noopener noreferrer" class="text-muted-foreground hover:text-primary transition-colors" aria-label="Twitter"> <svg class="w-5 h-5" fill="currentColor" viewBox="0 0 24 24"><path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"></path></svg> </a> <a href="/rss.xml" class="text-muted-foreground hover:text-primary transition-colors" aria-label="RSS Feed"> <svg class="w-5 h-5" fill="currentColor" viewBox="0 0 24 24"><path d="M6.18 15.64a2.18 2.18 0 0 1 2.18 2.18C8.36 19 7.38 20 6.18 20C5 20 4 19 4 17.82a2.18 2.18 0 0 1 2.18-2.18M4 4.44A15.56 15.56 0 0 1 19.56 20h-2.83A12.73 12.73 0 0 0 4 7.27V4.44m0 5.66a9.9 9.9 0 0 1 9.9 9.9h-2.83A7.07 7.07 0 0 0 4 12.93V10.1Z"></path></svg> </a> </div> </div> <div class="flex flex-wrap gap-3 mt-8 justify-center"> <a href="/blog" class="inline-flex items-center gap-2 px-4 py-2 rounded font-mono text-sm transition-colors bg-primary text-primary-foreground hover:bg-primary/90"> [blog] </a><a href="/about" class="inline-flex items-center gap-2 px-4 py-2 rounded font-mono text-sm transition-colors border border-border hover:bg-card"> [about] </a> </div> </div> </div> </div> </section>  <section class="py-16 border-t border-border"> <div class="container max-w-4xl mx-auto px-6"> <div class="terminal-header text-3xl md:text-4xl" data-astro-cid-xps5lu52> <span class="terminal-prompt" data-astro-cid-xps5lu52>$</span> <span class="terminal-command" data-astro-cid-xps5lu52>ls -la ./posts | head -5</span>  </div>  <div class="space-y-1"> <a href="/blog/errors-deserve-better" class="blog-card group"> <time class="blog-card-date" datetime="Sat Apr 25 2026 00:00:00 GMT+0000 (Coordinated Universal Time)"> Apr 25, 2026 </time> <h3 class="blog-card-title font-mono"> Errors Deserve Better </h3> <p class="blog-card-description"> TypeScript treats `catch (e)` as `unknown`, so odds are your codebase has hidden and unhandled error paths. better-result puts every failure mode back in the function signature, and lets each one get the response it actually deserves. <span class="blog-card-arrow ml-2">→</span> </p> <div class="flex flex-wrap gap-2 mt-3"> <span class="text-xs font-mono px-2 py-0.5 bg-secondary rounded text-muted-foreground">
#typescript </span><span class="text-xs font-mono px-2 py-0.5 bg-secondary rounded text-muted-foreground">
#errors </span><span class="text-xs font-mono px-2 py-0.5 bg-secondary rounded text-muted-foreground">
#error-handling </span><span class="text-xs font-mono px-2 py-0.5 bg-secondary rounded text-muted-foreground">
#better-result </span><span class="text-xs font-mono px-2 py-0.5 bg-secondary rounded text-muted-foreground">
#effect </span> </div> </a><a href="/blog/how-random-walks-find-the-bugs-you-wont" class="blog-card group"> <time class="blog-card-date" datetime="Sun Mar 22 2026 00:00:00 GMT+0000 (Coordinated Universal Time)"> Mar 22, 2026 </time> <h3 class="blog-card-title font-mono"> How Random Walks Find the Bugs You Won&#39;t </h3> <p class="blog-card-description"> Traditional tests encode what you think the machine does. Random walks surface what it actually does under sequences you didn’t imagine. <span class="blog-card-arrow ml-2">→</span> </p> <div class="flex flex-wrap gap-2 mt-3"> <span class="text-xs font-mono px-2 py-0.5 bg-secondary rounded text-muted-foreground">
#testing </span><span class="text-xs font-mono px-2 py-0.5 bg-secondary rounded text-muted-foreground">
#fsm </span><span class="text-xs font-mono px-2 py-0.5 bg-secondary rounded text-muted-foreground">
#machina </span> </div> </a><a href="/blog/ai-made-my-expertise-economically-viable" class="blog-card group"> <time class="blog-card-date" datetime="Thu Mar 05 2026 00:00:00 GMT+0000 (Coordinated Universal Time)"> Mar 5, 2026 </time> <h3 class="blog-card-title font-mono"> AI Made My Expertise Economically Viable </h3> <p class="blog-card-description"> Vibe Coding works for throwaway apps. But what about the systems that accumulated 15 years of implicit decisions? AI didn&#39;t replace my domain expertise, it made it worth deploying again. <span class="blog-card-arrow ml-2">→</span> </p> <div class="flex flex-wrap gap-2 mt-3"> <span class="text-xs font-mono px-2 py-0.5 bg-secondary rounded text-muted-foreground">
#ai </span><span class="text-xs font-mono px-2 py-0.5 bg-secondary rounded text-muted-foreground">
#open-source </span><span class="text-xs font-mono px-2 py-0.5 bg-secondary rounded text-muted-foreground">
#typescript </span> </div> </a><a href="/blog/rewriting-a-12-year-old-javascript-library-in-typescript" class="blog-card group"> <time class="blog-card-date" datetime="Tue Feb 24 2026 00:00:00 GMT+0000 (Coordinated Universal Time)"> Feb 24, 2026 </time> <h3 class="blog-card-title font-mono"> Rewriting a 12-Year-Old JavaScript Library in TypeScript </h3> <p class="blog-card-description"> How Erlang&#39;s gen_fsm inspired a JavaScript state machine library, why I rebuilt it in TypeScript 12 years later, and why finite state machines still matter. <span class="blog-card-arrow ml-2">→</span> </p> <div class="flex flex-wrap gap-2 mt-3"> <span class="text-xs font-mono px-2 py-0.5 bg-secondary rounded text-muted-foreground">
#typescript </span><span class="text-xs font-mono px-2 py-0.5 bg-secondary rounded text-muted-foreground">
#javascript </span><span class="text-xs font-mono px-2 py-0.5 bg-secondary rounded text-muted-foreground">
#open-source </span><span class="text-xs font-mono px-2 py-0.5 bg-secondary rounded text-muted-foreground">
#FSM </span> </div> </a><a href="/blog/appreciation-awe" class="blog-card group"> <time class="blog-card-date" datetime="Fri Aug 02 2019 00:00:00 GMT+0000 (Coordinated Universal Time)"> Aug 2, 2019 </time> <h3 class="blog-card-title font-mono"> Appreciation &amp; Awe </h3> <p class="blog-card-description"> Reflections on five years of leading the LeanKit development team <span class="blog-card-arrow ml-2">→</span> </p> <div class="flex flex-wrap gap-2 mt-3"> <span class="text-xs font-mono px-2 py-0.5 bg-secondary rounded text-muted-foreground">
#leadership </span><span class="text-xs font-mono px-2 py-0.5 bg-secondary rounded text-muted-foreground">
#team-building </span> </div> </a> </div> <div class="mt-8 pt-6 border-t border-border"> <a href="/blog" class="font-mono text-sm text-muted-foreground hover:text-primary transition-colors">
View all posts →
</a> </div> </div> </section>  </main> <footer class="border-t bg-card/50"> <div class="container max-w-5xl mx-auto px-4 sm:px-6 py-8"> <div class="flex flex-col md:flex-row items-center justify-between gap-4 font-mono text-sm"> <div class="status-bar"> <span class="status-dot status-dot-green"></span> <span class="text-muted-foreground">all systems operational</span> </div> <div class="flex items-center gap-4 text-muted-foreground"> <a href="https://github.com/ifandelse" class="hover:text-primary transition-colors">[github]</a> <a href="https://twitter.com/ifandelse" class="hover:text-primary transition-colors">[twitter]</a>    <a href="/rss.xml" class="hover:text-primary transition-colors">[rss]</a> </div> <p class="text-muted-foreground"> © 2026 Jim Cowart </p> </div> </div> </footer> <div id="command-palette" class="hidden fixed inset-0 z-[100]" data-astro-cid-wozhyvwc> <!-- Backdrop --> <div id="palette-backdrop" class="absolute inset-0 bg-background/80 backdrop-blur-sm" data-astro-cid-wozhyvwc></div> <!-- Modal --> <div class="relative flex items-start justify-center pt-[20vh]" data-astro-cid-wozhyvwc> <div class="terminal-window w-full max-w-lg mx-4" data-astro-cid-wozhyvwc> <div class="terminal-titlebar" data-astro-cid-wozhyvwc> <div class="terminal-buttons" data-astro-cid-wozhyvwc> <span class="terminal-button terminal-button-red" data-astro-cid-wozhyvwc></span> <span class="terminal-button terminal-button-yellow" data-astro-cid-wozhyvwc></span> <span class="terminal-button terminal-button-green" data-astro-cid-wozhyvwc></span> </div> <span class="text-sm text-muted-foreground font-mono ml-4" data-astro-cid-wozhyvwc>command palette</span> <span class="text-xs text-muted-foreground font-mono ml-auto" data-astro-cid-wozhyvwc>esc to close</span> </div> <div class="terminal-content" data-astro-cid-wozhyvwc> <div class="flex items-center gap-2 font-mono mb-4 pb-4 border-b border-border" data-astro-cid-wozhyvwc> <span class="terminal-prompt" data-astro-cid-wozhyvwc>$</span> <input type="text" id="palette-input" placeholder="Type a command..." class="flex-1 bg-transparent border-none outline-none text-foreground placeholder:text-muted-foreground/50" autocomplete="off" data-astro-cid-wozhyvwc> </div> <ul id="palette-items" class="space-y-1" data-astro-cid-wozhyvwc> <li data-astro-cid-wozhyvwc> <a href="/" class="palette-item flex items-center justify-between px-3 py-2 rounded hover:bg-secondary transition-colors font-mono text-sm" data-label="home" data-astro-cid-wozhyvwc> <span class="text-foreground" data-astro-cid-wozhyvwc>Home</span> <kbd class="text-xs text-muted-foreground px-2 py-0.5 bg-secondary rounded" data-astro-cid-wozhyvwc> H </kbd> </a> </li><li data-astro-cid-wozhyvwc> <a href="/about" class="palette-item flex items-center justify-between px-3 py-2 rounded hover:bg-secondary transition-colors font-mono text-sm" data-label="about" data-astro-cid-wozhyvwc> <span class="text-foreground" data-astro-cid-wozhyvwc>About</span> <kbd class="text-xs text-muted-foreground px-2 py-0.5 bg-secondary rounded" data-astro-cid-wozhyvwc> A </kbd> </a> </li><li data-astro-cid-wozhyvwc> <a href="/blog" class="palette-item flex items-center justify-between px-3 py-2 rounded hover:bg-secondary transition-colors font-mono text-sm" data-label="blog" data-astro-cid-wozhyvwc> <span class="text-foreground" data-astro-cid-wozhyvwc>Blog</span> <kbd class="text-xs text-muted-foreground px-2 py-0.5 bg-secondary rounded" data-astro-cid-wozhyvwc> B </kbd> </a> </li><li data-astro-cid-wozhyvwc> <a href="/projects" class="palette-item flex items-center justify-between px-3 py-2 rounded hover:bg-secondary transition-colors font-mono text-sm" data-label="projects" data-astro-cid-wozhyvwc> <span class="text-foreground" data-astro-cid-wozhyvwc>Projects</span> <kbd class="text-xs text-muted-foreground px-2 py-0.5 bg-secondary rounded" data-astro-cid-wozhyvwc> P </kbd> </a> </li><li data-astro-cid-wozhyvwc> <a href="/search" class="palette-item flex items-center justify-between px-3 py-2 rounded hover:bg-secondary transition-colors font-mono text-sm" data-label="search" data-astro-cid-wozhyvwc> <span class="text-foreground" data-astro-cid-wozhyvwc>Search</span> <kbd class="text-xs text-muted-foreground px-2 py-0.5 bg-secondary rounded" data-astro-cid-wozhyvwc> S </kbd> </a> </li><li data-astro-cid-wozhyvwc> <a href="/archives" class="palette-item flex items-center justify-between px-3 py-2 rounded hover:bg-secondary transition-colors font-mono text-sm" data-label="archives" data-astro-cid-wozhyvwc> <span class="text-foreground" data-astro-cid-wozhyvwc>Archives</span> <kbd class="text-xs text-muted-foreground px-2 py-0.5 bg-secondary rounded" data-astro-cid-wozhyvwc> R </kbd> </a> </li><li data-astro-cid-wozhyvwc> <a href="/rss.xml" class="palette-item flex items-center justify-between px-3 py-2 rounded hover:bg-secondary transition-colors font-mono text-sm" data-label="rss feed" data-astro-cid-wozhyvwc> <span class="text-foreground" data-astro-cid-wozhyvwc>RSS Feed</span> <kbd class="text-xs text-muted-foreground px-2 py-0.5 bg-secondary rounded" data-astro-cid-wozhyvwc> F </kbd> </a> </li> </ul> </div> </div> </div> </div> <!-- Keyboard shortcut hint --> <div class="fixed bottom-4 right-4 hidden md:block" data-astro-cid-wozhyvwc> <button id="palette-trigger" class="font-mono text-xs text-muted-foreground hover:text-foreground transition-colors bg-card/80 backdrop-blur px-3 py-2 rounded-lg border border-border" data-astro-cid-wozhyvwc> <kbd data-astro-cid-wozhyvwc>⌘</kbd> + <kbd data-astro-cid-wozhyvwc>K</kbd> </button> </div> <script type="module">function c(){const n=document.getElementById("command-palette"),i=document.getElementById("palette-backdrop"),t=document.getElementById("palette-input"),r=document.querySelectorAll(".palette-item"),m=document.getElementById("palette-trigger");function o(){n?.classList.remove("hidden"),t?.focus(),document.body.style.overflow="hidden"}function d(){n?.classList.add("hidden"),t&&(t.value=""),s(""),document.body.style.overflow=""}function s(e){const u=e.toLowerCase();r.forEach(a=>{const f=a.dataset.label||"",l=a.parentElement;f.includes(u)?l?.classList.remove("hidden"):l?.classList.add("hidden")})}document.addEventListener("keydown",e=>{(e.metaKey||e.ctrlKey)&&e.key==="k"&&(e.preventDefault(),n?.classList.contains("hidden")?o():d()),e.key==="Escape"&&d()}),t?.addEventListener("input",e=>{s(e.target.value)}),i?.addEventListener("click",d),m?.addEventListener("click",o)}c();document.addEventListener("astro:after-swap",c);</script>  </body></html> <script type="module">function g(){const a=document.getElementById("typewriter-container");if(!a)return;const d=a.getAttribute("data-lines"),r=d?JSON.parse(d):["A minimal, terminal-inspired blog theme","Built with Astro 5.x and Tailwind CSS v4"],p=30,y=400;let t=0,n=0;const u=document.getElementById("line-1"),m=document.getElementById("line-2"),o=document.getElementById("typewriter-cursor");if(!u||!m||!o)return;const s=[u,m];s.forEach(i=>{i&&(i.textContent="")});function c(){if(t>=r.length)return;const i=s[t],f=r[t];i&&(s.forEach((e,l)=>{e&&o&&(l===t?(e.innerHTML=f.substring(0,n),e.appendChild(o)):l<t?e.textContent=r[l]:e.textContent="")}),n++,n<=f.length?setTimeout(c,p):(t++,n=0,setTimeout(c,y)))}c()}g();document.addEventListener("astro:page-load",g);</script>