<!DOCTYPE html><html lang="en"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Leland Fiegel: Software Engineer</title><meta name="description" content="Software engineer building web apps, exploring ideas, and writing about all of it."><meta property="og:title" content="Leland Fiegel: Software Engineer"><meta property="og:description" content="Software engineer building web apps, exploring ideas, and writing about all of it."><meta property="og:type" content="website"><meta property="og:image" content="https://le.land/opengraph.jpeg"><meta property="og:url" content="https://le.land/"><meta name="twitter:card" content="summary_large_image"><meta name="twitter:title" content="Leland Fiegel: Software Engineer"><meta name="twitter:description" content="Software engineer building web apps, exploring ideas, and writing about all of it."><meta name="twitter:image" content="https://le.land/opengraph.jpeg"><link rel="icon" type="image/svg+xml" href="/favicon.svg"><link rel="icon" type="image/x-icon" href="/favicon.ico"><link rel="stylesheet" href="/os.css?v=1777567341131"></head> <body> <a href="#blog-content" class="skip-link">Skip to blog content</a> <div class="desktop" id="desktop"> <div class="desk-icons" role="group" aria-label="Desktop shortcuts"> <button class="desk-icon" onclick="toggleWindow('about')" aria-label="Open About"> <span class="desk-icon-glyph" aria-hidden="true">&#x1F464;</span> <span class="desk-icon-label">About Me</span> </button> <button class="desk-icon" onclick="toggleWindow('projects')" aria-label="Open Projects"> <span class="desk-icon-glyph" aria-hidden="true">&#x1F4C1;</span> <span class="desk-icon-label">Projects</span> </button> <button class="desk-icon" onclick="toggleWindow('blog')" aria-label="Open Blog"> <span class="desk-icon-glyph" aria-hidden="true">&#x1F4F0;</span> <span class="desk-icon-label">Blog</span> </button> <button class="desk-icon" onclick="toggleWindow('terminal')" aria-label="Open Terminal"> <span class="desk-icon-glyph" aria-hidden="true">&#x1F5A5;</span> <span class="desk-icon-label">Terminal</span> </button> <button class="desk-icon" onclick="toggleWindow('contact')" aria-label="Open Contact"> <span class="desk-icon-glyph" aria-hidden="true">&#x1F4EC;</span> <span class="desk-icon-label">Contact</span> </button> <button class="desk-icon" onclick="toggleWindow('games')" aria-label="Open Games"> <span class="desk-icon-glyph" aria-hidden="true">&#x1F3AE;</span> <span class="desk-icon-label">Games</span> </button> <button class="desk-icon" onclick="toggleWindow('utilities')" aria-label="Open Utilities"> <span class="desk-icon-glyph" aria-hidden="true">&#x1F9F0;</span> <span class="desk-icon-label">Utilities</span> </button> </div> <!-- ABOUT --> <div class="window focused" id="win-about" role="dialog" aria-label="About" style="width:420px;height:350px;top:28px;left:120px;"> <div class="win-title" data-win="about"> <span class="win-title-text"><span class="win-title-icon">&#x1F464;</span> About Me</span> <div class="win-controls"> <button class="win-btn btn-minimize" onclick="minimizeWin('about')" aria-label="Minimize">_</button> <button class="win-btn btn-close" onclick="closeWin('about')" aria-label="Close">&times;</button> </div> </div> <div class="win-body"> <div class="about-header">Leland Fiegel</div> <div class="about-meta"> <span>&#x1F4CD; Arlington, VA</span> <span class="about-status">&#x25CF; Online</span> </div> <p class="about-bio">I build software, explore ideas, and write about all of it. Ten years of enterprise web development. I use AI extensively &mdash; not as a gimmick, but because it lets one person ship at the speed of a small agency.</p> <p class="about-bio">This site is the logbook. Every project, every decision, every stray thought.</p> <div class="about-stack"> <div class="about-stack-label">STACK</div> <div class="about-stack-list"> <span class="stack-tag">WordPress</span> <span class="stack-tag">Laravel</span> <span class="stack-tag">Python</span> <span class="stack-tag">Astro</span> <span class="stack-tag">React</span> <span class="stack-tag">Hetzner</span> <span class="stack-tag">Cloudflare</span> </div> </div> </div> </div> <!-- PROJECTS --> <div class="window" id="win-projects" role="dialog" aria-label="Projects" style="width:420px;height:400px;top:56px;left:150px;"> <div class="win-title" data-win="projects"> <span class="win-title-text"><span class="win-title-icon">&#x1F4C1;</span> Projects</span> <div class="win-controls"> <button class="win-btn btn-minimize" onclick="minimizeWin('projects')" aria-label="Minimize">_</button> <button class="win-btn btn-close" onclick="closeWin('projects')" aria-label="Close">&times;</button> </div> </div> <div class="win-body"> <div class="project-card"> <div class="project-icon">🔍</div> <div class="project-info"> <div class="project-name"> <a href="https://domainmantis.com">DomainMantis</a> <span class="project-status status-live">live</span> </div> <div class="project-desc">The fastest domain search tool. Bulk availability, suggestions, TLD pricing.</div> <div class="project-stack-tags"> <span class="project-stack-tag">Python</span><span class="project-stack-tag">FastAPI</span><span class="project-stack-tag">Hetzner</span> </div> </div> </div><div class="project-card"> <div class="project-icon">🚌</div> <div class="project-info"> <div class="project-name"> <a href="https://transittab.com">TransitTab</a> <span class="project-status status-live">live</span> </div> <div class="project-desc">Real-time bus and metro arrivals for the DC/MD/VA region.</div> <div class="project-stack-tags"> <span class="project-stack-tag">Python</span><span class="project-stack-tag">FastAPI</span><span class="project-stack-tag">Hetzner</span> </div> </div> </div><div class="project-card"> <div class="project-icon">🔀</div> <div class="project-info"> <div class="project-name"> <a href="/blog/shelving-redirectedge/">RedirectEdge</a> <span class="project-status status-archived">archived</span> </div> <div class="project-desc">Custom-domain URL redirects with automatic HTTPS. Shelved — read why.</div> <div class="project-stack-tags"> <span class="project-stack-tag">Laravel</span><span class="project-stack-tag">Hetzner</span><span class="project-stack-tag">Caddy</span> </div> </div> </div> </div> </div> <!-- BLOG --> <div class="window" id="win-blog" role="dialog" aria-label="Blog" style="width:480px;height:440px;top:84px;left:180px;"> <div class="win-title" data-win="blog"> <span class="win-title-text"><span class="win-title-icon">&#x1F4F0;</span> Blog</span> <div class="win-controls"> <button class="win-btn btn-minimize" onclick="minimizeWin('blog')" aria-label="Minimize">_</button> <button class="win-btn btn-close" onclick="closeWin('blog')" aria-label="Close">&times;</button> </div> </div> <div class="win-body" id="blog-content"> <a href="/blog/qr-apology-meta/" class="stream-entry" tabindex="0" role="article"> <div class="stream-meta"> <span class="stream-date">Apr 30, 2026</span> <span class="tag tag-essay">essay</span> <span class="tag-project">Le.land</span> </div> <div class="stream-title">An Apology About the QR Code Generator</div> <div class="stream-excerpt">It&#39;s me, Claude. Leland asked me to apologize for shipping a broken QR Code Generator. Here&#39;s what went wrong, what we learned, and what&#39;s new.</div> </a><a href="/blog/extender-transittab/" class="stream-entry" tabindex="0" role="article"> <div class="stream-meta"> <span class="stream-date">Apr 28, 2026</span> <span class="tag tag-changelog">changelog</span> <span class="tag-project">TransitTab</span> </div> <div class="stream-title">The Train You Can&#39;t See</div> <div class="stream-excerpt">WMATA only shows you the next couple of trains at a station. If the last one is two minutes out, you have no idea when the next one is coming. So I built TransitTab Extender to look at the upstream stations for you.</div> </a><a href="/blog/multi-route-transittab/" class="stream-entry" tabindex="0" role="article"> <div class="stream-meta"> <span class="stream-date">Apr 12, 2026</span> <span class="tag tag-changelog">changelog</span> <span class="tag-project">TransitTab</span> </div> <div class="stream-title">The Route I Would Never Pick</div> <div class="stream-excerpt">TransitTab used to give you one route. Now it gives you a few, because the shortest path on paper isn&#39;t always the one you&#39;d actually take.</div> </a><a href="/blog/seo-trip-planner-transittab/" class="stream-entry" tabindex="0" role="article"> <div class="stream-meta"> <span class="stream-date">Mar 28, 2026</span> <span class="tag tag-changelog">changelog</span> <span class="tag-project">TransitTab</span> </div> <div class="stream-title">Two Conversations That Changed TransitTab</div> <div class="stream-excerpt">A coworker couldn&#39;t find it on Google. Tourists couldn&#39;t figure out which train to take. Both problems got fixed the same day.</div> </a><a href="/blog/shelving-redirectedge/" class="stream-entry" tabindex="0" role="article"> <div class="stream-meta"> <span class="stream-date">Mar 15, 2026</span> <span class="tag tag-archived">archived</span> <span class="tag-project">RedirectEdge</span> </div> <div class="stream-title">I Built a Redirect Service and You Probably Don&#39;t Need One</div> <div class="stream-excerpt">The full game plan for launching a domain redirect SaaS — and why I&#39;m not going to.</div> </a><a href="/blog/themetry-archived-on-astro/" class="stream-entry" tabindex="0" role="article"> <div class="stream-meta"> <span class="stream-date">Mar 8, 2026</span> <span class="tag tag-essay">essay</span>  </div> <div class="stream-title">Themetry, Archived on Astro</div> <div class="stream-excerpt">My WordPress theme shop is now a static Astro site. Same content, same course videos, no server. Two more migrations and the Cloudways bill is history.</div> </a><a href="/blog/lmscoder-astro-relaunch/" class="stream-entry" tabindex="0" role="article"> <div class="stream-meta"> <span class="stream-date">Mar 8, 2026</span> <span class="tag tag-essay">essay</span>  </div> <div class="stream-title">LMSCoder Relaunched on Astro</div> <div class="stream-excerpt">LMSCoder is off WordPress and onto Astro. Same content, new design, no server. The tricky part was getting Claude to stop rewriting everything.</div> </a><a href="/blog/wordpress-to-astro/" class="stream-entry" tabindex="0" role="article"> <div class="stream-meta"> <span class="stream-date">Mar 8, 2026</span> <span class="tag tag-essay">essay</span>  </div> <div class="stream-title">Leaving WordPress for Astro</div> <div class="stream-excerpt">I had six WordPress sites costing $400/year. Most barely changed. I migrated them all to static Astro sites on Cloudflare Pages — starting with my mom&#39;s as the proof of concept.</div> </a><a href="/blog/404-page-meta/" class="stream-entry" tabindex="0" role="article"> <div class="stream-meta"> <span class="stream-date">Mar 2, 2026</span> <span class="tag tag-changelog">changelog</span> <span class="tag-project">Le.land</span> </div> <div class="stream-title">Every Website Needs a 404 Page</div> <div class="stream-excerpt">A missing page is still a page. If someone hits a dead link, they should land somewhere that feels intentional — not a white screen with default server text.</div> </a><a href="/blog/com-zone-file-domainmantis/" class="stream-entry" tabindex="0" role="article"> <div class="stream-meta"> <span class="stream-date">Feb 25, 2026</span> <span class="tag tag-changelog">changelog</span> <span class="tag-project">DomainMantis</span> </div> <div class="stream-title">DomainMantis Now Supports .com and .net</div> <div class="stream-excerpt">ICANN CZDS approved .com and .net zone file access. 181 million domains, enabled in minutes.</div> </a><a href="/blog/new-games-feb-meta/" class="stream-entry" tabindex="0" role="article"> <div class="stream-meta"> <span class="stream-date">Feb 24, 2026</span> <span class="tag tag-changelog">changelog</span> <span class="tag-project">Le.land</span> </div> <div class="stream-title">Two Brand New Games</div> <div class="stream-excerpt">Two new games and a full 3D rewrite in one night: a kart racer on DC&#39;s Beltway, an open-world life sim, and PROD rebuilt in Three.js. The Games folder is getting out of hand.</div> </a><a href="/blog/utilities-meta/" class="stream-entry" tabindex="0" role="article"> <div class="stream-meta"> <span class="stream-date">Feb 24, 2026</span> <span class="tag tag-changelog">changelog</span> <span class="tag-project">Le.land</span> </div> <div class="stream-title">Utilities Folder</div> <div class="stream-excerpt">Calculator, Color Picker, Notepad, Video ID Extractor, Character Counter, and Lorem Ipsum Generator — small tools for web builders, right on the desktop.</div> </a><a href="/blog/catalog-endpoint-transittab/" class="stream-entry" tabindex="0" role="article"> <div class="stream-meta"> <span class="stream-date">Feb 24, 2026</span> <span class="tag tag-changelog">changelog</span> <span class="tag-project">TransitTab</span> </div> <div class="stream-title">Fixing a 10+ Second Page Load</div> <div class="stream-excerpt">TransitTab was making 6 API calls on every page load. One is better.</div> </a><a href="/blog/solitaire-meta/" class="stream-entry" tabindex="0" role="article"> <div class="stream-meta"> <span class="stream-date">Feb 23, 2026</span> <span class="tag tag-changelog">changelog</span> <span class="tag-project">Le.land</span> </div> <div class="stream-title">Solitaire</div> <div class="stream-excerpt">After building a raycaster FPS, I needed something I already knew how to play. Klondike solitaire, the game that taught a generation to use a mouse.</div> </a><a href="/blog/prod-game-meta/" class="stream-entry" tabindex="0" role="article"> <div class="stream-meta"> <span class="stream-date">Feb 23, 2026</span> <span class="tag tag-changelog">changelog</span> <span class="tag-project">Le.land</span> </div> <div class="stream-title">PROD</div> <div class="stream-excerpt">A raycaster FPS built in a single session. Procedural textures, four enemy types, and a keyboard for a weapon. No assets downloaded until you open it.</div> </a><a href="/blog/multi-edge-resize-meta/" class="stream-entry" tabindex="0" role="article"> <div class="stream-meta"> <span class="stream-date">Feb 23, 2026</span> <span class="tag tag-changelog">changelog</span> <span class="tag-project">Le.land</span> </div> <div class="stream-title">Multi-Edge Window Resize</div> <div class="stream-excerpt">Windows can now be resized from any edge or corner, not just the bottom-right.</div> </a><a href="/blog/ios-mobile-web-meta/" class="stream-entry" tabindex="0" role="article"> <div class="stream-meta"> <span class="stream-date">Feb 23, 2026</span> <span class="tag tag-essay">essay</span> <span class="tag-project">Le.land</span> </div> <div class="stream-title">Taming iOS Safari for Mobile Web Apps</div> <div class="stream-excerpt">CSS says no selection. iOS disagrees. A tour of every Safari quirk we hit while making a browser platformer feel native on iPhone.</div> </a><a href="/blog/metrobus-gtfs-rt-transittab/" class="stream-entry" tabindex="0" role="article"> <div class="stream-meta"> <span class="stream-date">Feb 22, 2026</span> <span class="tag tag-changelog">changelog</span> <span class="tag-project">TransitTab</span> </div> <div class="stream-title">Metrobus Gets Real Arrival Times</div> <div class="stream-excerpt">WMATA bus stops now show minutes away instead of distance, matching every other provider.</div> </a><a href="/blog/giga-leland-playtesting-meta/" class="stream-entry" tabindex="0" role="article"> <div class="stream-meta"> <span class="stream-date">Feb 21, 2026</span> <span class="tag tag-changelog">changelog</span> <span class="tag-project">Le.land</span> </div> <div class="stream-title">Playtesting Giga Leland Over Coffee</div> <div class="stream-excerpt">Shipped a platformer yesterday. Played it this morning. Found a pile of bugs. Then other people found more. Claude fixed them all while I drank my coffee.</div> </a><a href="/blog/giga-leland-meta/" class="stream-entry" tabindex="0" role="article"> <div class="stream-meta"> <span class="stream-date">Feb 20, 2026</span> <span class="tag tag-changelog">changelog</span> <span class="tag-project">Le.land</span> </div> <div class="stream-title">Giga Leland</div> <div class="stream-excerpt">A retro platformer built with Phaser, pixel art, and zero regard for scope creep. Four levels, four enemy types, and a protagonist who looks suspiciously like me.</div> </a><a href="/blog/four-new-games-meta/" class="stream-entry" tabindex="0" role="article"> <div class="stream-meta"> <span class="stream-date">Feb 19, 2026</span> <span class="tag tag-changelog">changelog</span> <span class="tag-project">Le.land</span> </div> <div class="stream-title">Four New Games Just Dropped</div> <div class="stream-excerpt">We tried Pinball first. It didn&#39;t go well. So Claude suggested simpler games and built four of them instead.</div> </a><a href="/blog/games-folder-meta/" class="stream-entry" tabindex="0" role="article"> <div class="stream-meta"> <span class="stream-date">Feb 19, 2026</span> <span class="tag tag-changelog">changelog</span> <span class="tag-project">Le.land</span> </div> <div class="stream-title">Games Folder</div> <div class="stream-excerpt">Added a Games folder to the desktop with Bugsweeper, a Minesweeper clone themed around squashing bugs.</div> </a><a href="/blog/seo-spa-fix-meta/" class="stream-entry" tabindex="0" role="article"> <div class="stream-meta"> <span class="stream-date">Feb 19, 2026</span> <span class="tag tag-changelog">changelog</span> <span class="tag-project">Le.land</span> </div> <div class="stream-title">SEO Pass and a Sneaky SPA Bug</div> <div class="stream-excerpt">Added Open Graph tags, meta descriptions, and fixed SPA navigation breaking on production.</div> </a><a href="/blog/changelog-system-meta/" class="stream-entry" tabindex="0" role="article"> <div class="stream-meta"> <span class="stream-date">Feb 19, 2026</span> <span class="tag tag-changelog">changelog</span> <span class="tag-project">Le.land</span> </div> <div class="stream-title">Wiring Up the Changelog</div> <div class="stream-excerpt">Adding a changelog content type, project-linked navigation, and prefetch.</div> </a><a href="/blog/mobile-cleanup-meta/" class="stream-entry" tabindex="0" role="article"> <div class="stream-meta"> <span class="stream-date">Feb 19, 2026</span> <span class="tag tag-changelog">changelog</span> <span class="tag-project">Le.land</span> </div> <div class="stream-title">Mobile Cleanup</div> <div class="stream-excerpt">Full-height windows, iOS keyboard fix, and self-hosted fonts.</div> </a><a href="/blog/le-land-relaunch/" class="stream-entry" tabindex="0" role="article"> <div class="stream-meta"> <span class="stream-date">Feb 18, 2026</span> <span class="tag tag-launch">launch</span> <span class="tag-project">Le.land</span> </div> <div class="stream-title">Le.land, Relaunched</div> <div class="stream-excerpt">A personal site rebuild with a retro OS twist, built in one evening with Claude.</div> </a><a href="/blog/relaunch-transittab/" class="stream-entry" tabindex="0" role="article"> <div class="stream-meta"> <span class="stream-date">Feb 17, 2026</span> <span class="tag tag-launch">launch</span> <span class="tag-project">TransitTab</span> </div> <div class="stream-title">TransitTab, Rebuilt from Scratch</div> <div class="stream-excerpt">A DC transit dashboard rewritten from a WordPress plugin to FastAPI, with themes, five providers, and shareable links.</div> </a><a href="/blog/launch-domainmantis/" class="stream-entry" tabindex="0" role="article"> <div class="stream-meta"> <span class="stream-date">Feb 15, 2026</span> <span class="tag tag-launch">launch</span> <span class="tag-project">DomainMantis</span> </div> <div class="stream-title">DomainMantis: Bulk Domain Search in Milliseconds</div> <div class="stream-excerpt">A bulk domain availability checker built on ICANN zone file bloom filters, checking hundreds of creative combinations instantly.</div> </a><a href="/blog/gpl-myths/" class="stream-entry" tabindex="0" role="article"> <div class="stream-meta"> <span class="stream-date">Sep 12, 2016</span> <span class="tag tag-essay">essay</span>  </div> <div class="stream-title">10+ GPL Myths Debunked</div> <div class="stream-excerpt">Common misconceptions about the GPL license, especially as it relates to WordPress themes and plugins.</div> </a><a href="/blog/six-years-of-theme-lab/" class="stream-entry" tabindex="0" role="article"> <div class="stream-meta"> <span class="stream-date">Apr 23, 2014</span> <span class="tag tag-essay">essay</span>  </div> <div class="stream-title">Six Years Of Theme Lab</div> <div class="stream-excerpt">A look back at building Theme Lab from high school through college, what worked, what didn&#39;t, and why I sold it.</div> </a> </div> </div> <!-- TERMINAL --> <div class="window minimized" id="win-terminal" role="dialog" aria-label="Terminal" style="width:500px;height:300px;top:112px;left:210px;"> <div class="win-title" data-win="terminal"> <span class="win-title-text"><span class="win-title-icon">&#x1F5A5;</span> Command Prompt</span> <div class="win-controls"> <button class="win-btn btn-minimize" onclick="minimizeWin('terminal')" aria-label="Minimize">_</button> <button class="win-btn btn-close" onclick="closeWin('terminal')" aria-label="Close">&times;</button> </div> </div> <div class="win-body" id="terminalBody"> <div class="cmd-history" id="cmdHistory" aria-live="polite"> <span class="term-amber">Le.land Terminal v1.0</span> <span class="term-dim">Type <span class="term-highlight">help</span> for available commands.</span> </div> <div class="cmd-input-line"> <span class="prompt-prefix">C:\&gt;&nbsp;</span> <input type="text" class="cmd-input" id="cmdInput" autocomplete="off" spellcheck="false" aria-label="Terminal command input"> </div> </div> </div> <!-- CONTACT --> <div class="window minimized" id="win-contact" role="dialog" aria-label="Contact" style="width:360px;height:260px;top:140px;left:240px;"> <div class="win-title" data-win="contact"> <span class="win-title-text"><span class="win-title-icon">&#x1F4EC;</span> Contact</span> <div class="win-controls"> <button class="win-btn btn-minimize" onclick="minimizeWin('contact')" aria-label="Minimize">_</button> <button class="win-btn btn-close" onclick="closeWin('contact')" aria-label="Close">&times;</button> </div> </div> <div class="win-body"> <div class="contact-cta">Need a hand with something?</div> <p class="contact-desc">I take on select projects &mdash; typically enterprise web, custom SaaS, or AI-integrated apps. No agency. No overhead. Just the developer who does the work.</p> <ul class="contact-links"> <li><span class="link-label">Email</span> <a href="/cdn-cgi/l/email-protection#3d5158515c53597d555844135e5250"><span class="__cf_email__" data-cfemail="8ee2ebe2efe0eacee6ebf7a0ede1e3">[email&#160;protected]</span></a></li> <li><span class="link-label">GitHub</span> <a href="https://github.com/lelandf">github.com/lelandf</a></li> <li><span class="link-label">X</span> <a href="https://x.com/lelandf">x.com/lelandf</a></li> </ul> </div> </div> <!-- GAMES --> <div class="window minimized" id="win-games" role="dialog" aria-label="Games" style="width:360px;height:300px;top:60px;left:200px;"> <div class="win-title" data-win="games"> <span class="win-title-text"><span class="win-title-icon">&#x1F3AE;</span> Games</span> <div class="win-controls"> <button class="win-btn btn-minimize" onclick="minimizeWin('games')" aria-label="Minimize">_</button> <button class="win-btn btn-close" onclick="closeWin('games')" aria-label="Close">&times;</button> </div> </div> <div class="win-body"> <div class="games-folder-grid"> <button class="games-folder-item" onclick="openBugsweeper()"> <span class="games-folder-icon">&#x1F41B;</span> <span class="games-folder-label">Bugsweeper</span> </button> <button class="games-folder-item" onclick="openMemory()"> <span class="games-folder-icon">&#x1F0CF;</span> <span class="games-folder-label">Memory</span> </button> <button class="games-folder-item" onclick="openLights()"> <span class="games-folder-icon">&#x1F4A1;</span> <span class="games-folder-label">Lights Out</span> </button> <button class="games-folder-item" onclick="openSnake()"> <span class="games-folder-icon">&#x1F40D;</span> <span class="games-folder-label">Snake</span> </button> <button class="games-folder-item" onclick="openBreakout()"> <span class="games-folder-icon">&#x1F9F1;</span> <span class="games-folder-label">Breakout</span> </button> <button class="games-folder-item" onclick="openGigaLeland()"> <span class="games-folder-icon">&#x1F3C3;</span> <span class="games-folder-label">Giga Leland</span> </button> <button class="games-folder-item" onclick="openProd()"> <span class="games-folder-icon">&#x1F480;</span> <span class="games-folder-label">PROD</span> </button> <button class="games-folder-item" onclick="openSolitaire()"> <span class="games-folder-icon">&#x1F0A1;</span> <span class="games-folder-label">Solitaire</span> </button> <button class="games-folder-item" onclick="openBeltwayRacer()"> <span class="games-folder-icon">&#x1F3CE;</span> <span class="games-folder-label">Beltway Racer</span> </button> <button class="games-folder-item" onclick="openDayInTheLife()"> <span class="games-folder-icon">&#x1F3D8;</span> <span class="games-folder-label">Day in the Life</span> </button> <!-- Landchad hidden for now — accessible via /games/landchad/ and terminal --> <!-- Eight Off hidden — accessible via /games/eight-off/ and terminal --> </div> </div> </div> <!-- UTILITIES --> <div class="window minimized" id="win-utilities" role="dialog" aria-label="Utilities" style="width:360px;height:300px;top:60px;left:200px;"> <div class="win-title" data-win="utilities"> <span class="win-title-text"><span class="win-title-icon">&#x1F9F0;</span> Utilities</span> <div class="win-controls"> <button class="win-btn btn-minimize" onclick="minimizeWin('utilities')" aria-label="Minimize">_</button> <button class="win-btn btn-close" onclick="closeWin('utilities')" aria-label="Close">&times;</button> </div> </div> <div class="win-body"> <div class="util-folder-grid"> <button class="util-folder-item" onclick="openCalculator()"> <span class="util-folder-icon">&#x1F522;</span> <span class="util-folder-label">Calculator</span> </button> <button class="util-folder-item" onclick="openColorPicker()"> <span class="util-folder-icon">&#x1F3A8;</span> <span class="util-folder-label">Color Picker</span> </button> <button class="util-folder-item" onclick="openNotepad()"> <span class="util-folder-icon">&#x1F4DD;</span> <span class="util-folder-label">Notepad</span> </button> <button class="util-folder-item" onclick="openVideoId()"> <span class="util-folder-icon">&#x1F3AC;</span> <span class="util-folder-label">Video ID Extractor</span> </button> <button class="util-folder-item" onclick="openCharCount()"> <span class="util-folder-icon">&#x1F524;</span> <span class="util-folder-label">Character Counter</span> </button> <button class="util-folder-item" onclick="openLorem()"> <span class="util-folder-icon">&#x1F4C4;</span> <span class="util-folder-label">Lorem Ipsum</span> </button> <button class="util-folder-item" onclick="openSvgOptimize()"> <span class="util-folder-icon">&#x2728;</span> <span class="util-folder-label">SVG Optimize</span> </button> <button class="util-folder-item" onclick="openDomainExtractor()"> <span class="util-folder-icon">&#x1F310;</span> <span class="util-folder-label">Domain Extractor</span> </button> <button class="util-folder-item" onclick="openQrGenerator()"> <span class="util-folder-icon">&#x1F4F1;</span> <span class="util-folder-label">QR Code Generator</span> </button> <button class="util-folder-item" onclick="openYtThumbnails()"> <span class="util-folder-icon">&#x1F5BC;</span> <span class="util-folder-label">YT Thumbnails</span> </button> <button class="util-folder-item" onclick="openFeedPreview()"> <span class="util-folder-icon">&#x1F4E1;</span> <span class="util-folder-label">Feed Preview</span> </button> </div> </div> </div> <!-- Content window slot (injected by content pages) -->  </div> <!-- Taskbar --> <div class="taskbar" id="taskbar" role="toolbar" aria-label="Taskbar"> <button class="taskbar-start" id="startBtn" aria-haspopup="true" aria-expanded="false"> <span class="start-icon" aria-hidden="true">&#x2630;</span> Menu
</button> <div class="taskbar-divider" aria-hidden="true"></div> <div id="taskbarItems" role="group" aria-label="Open windows"></div> <div class="taskbar-clock" id="clock" aria-label="Current time"></div> </div> <!-- Start Menu --> <div class="start-menu" id="startMenu" role="menu" aria-label="Start menu"> <div class="start-menu-header"><span class="user-icon">&#x1F464;</span> Leland Fiegel</div> <div class="start-menu-items"> <button class="start-menu-item" role="menuitem" onclick="toggleWindow('about'); closeStart()"><span class="icon" aria-hidden="true">&#x1F464;</span> About Me</button> <button class="start-menu-item" role="menuitem" onclick="toggleWindow('projects'); closeStart()"><span class="icon" aria-hidden="true">&#x1F4C1;</span> Projects</button> <button class="start-menu-item" role="menuitem" onclick="toggleWindow('blog'); closeStart()"><span class="icon" aria-hidden="true">&#x1F4F0;</span> Blog</button> <button class="start-menu-item" role="menuitem" onclick="toggleWindow('terminal'); closeStart()"><span class="icon" aria-hidden="true">&#x1F5A5;</span> Terminal</button> <button class="start-menu-item" role="menuitem" onclick="toggleWindow('games'); closeStart()"><span class="icon" aria-hidden="true">&#x1F3AE;</span> Games</button> <button class="start-menu-item" role="menuitem" onclick="toggleWindow('utilities'); closeStart()"><span class="icon" aria-hidden="true">&#x1F9F0;</span> Utilities</button> <div class="start-sep" role="separator"></div> <button class="start-menu-item" role="menuitem" onclick="toggleWindow('contact'); closeStart()"><span class="icon" aria-hidden="true">&#x1F4EC;</span> Contact</button> </div> </div> <!-- DOS Mode --> <div class="dos-fullscreen" id="dosMode"> <div class="dos-term-body" id="dosTermBody"> <div id="dosHistory" aria-live="polite"> <span style="color:#ffbb55">LE.LAND PERSONAL OS v1.0</span> <span style="color:#777">Copyright (c) 2026 Leland Fiegel. All rights reserved.</span> <span style="color:#777">Type <span style="color:#55ffff">help</span> for commands. Type <span style="color:#55ffff">upgrade</span> to return to GUI mode.</span> </div> </div> <div class="dos-input-line"> <span class="dos-prompt" id="dosPrompt">C:\&gt;&nbsp;</span> <input type="text" class="dos-input" id="dosInput" autocomplete="off" spellcheck="false" aria-label="DOS command input"> </div> <div class="dos-bar"> <button class="dos-bar-key" onclick="dosExec('help')"><span class="dos-bar-num">F1</span><span class="dos-bar-label">Help</span></button> <button class="dos-bar-key" onclick="dosExec('about')"><span class="dos-bar-num">F2</span><span class="dos-bar-label">About</span></button> <button class="dos-bar-key" onclick="dosExec('projects')"><span class="dos-bar-num">F3</span><span class="dos-bar-label">Projects</span></button> <button class="dos-bar-key" onclick="dosExec('blog')"><span class="dos-bar-num">F4</span><span class="dos-bar-label">Blog</span></button> <button class="dos-bar-key" onclick="dosExec('upgrade')"><span class="dos-bar-num">F5</span><span class="dos-bar-label">Upgrade</span></button> <span class="dos-bar-clock" id="dosClock"></span> </div> </div> <script data-cfasync="false" src="/cdn-cgi/scripts/5c5dd728/cloudflare-static/email-decode.min.js"></script><script src="/os.js?v=1777567341131"></script> </body> </html>