I threw my operating system's theme at the entire internet, and the internet mostly caught it

Your browser's dark mode is just gray with a grudge.

By Mackenzie Bowes · mackenzie@mackenziebowes.com · @_mackenziebowes on X

Contents

A devlog about omarchy-web-retheme, a browser extension built in one morning.

The pitch

If you use Omarchy, your terminals look gorgeous.[1] All of them. Every agent, every shell, every pane - one coherent theme, like a well-run ship.

Then you open a web browser, and the web does what the web does: forty shades of white you never asked for, a blue you've never seen in nature, and a "dark mode" that's actually just gray with a grudge.

On October 5th, at 9:58 in the morning, Mackenzie Bowes opened an empty folder and told a Claude:

"I have a dumb throwaway idea I want to pass to you to play with in here."

The idea: read the theme file Omarchy already uses, turn the palette into CSS variables, and restyle every website to match. His words: "we can make a plugin that reads a theme file from omarchy, use that as CSS variables, and do something like css-reset a website and write in new rules."

Two minutes later, it was being built. Not a prototype. The thing.

The one real problem (and the one real answer)

Here's the constraint that kills most "browser talks to my files" ideas: a browser extension cannot read your home directory. Sandboxed. Done. No ~/.config for you.

The answer is a native messaging host - a tiny program that lives outside the browser and feeds data in. Ours is 85 lines of Python with zero dependencies, because the system Python already ships tomllib. It reads ~/.local/state/omarchy/current/theme/colors.toml and pushes it to the extension on connect, and again every time the file changes.

That last part is the magic. Change your Omarchy theme once and every open tab follows, live. No reload. No re-extension. The whole internet re-skins itself because one file changed.

The extension side is about 390 lines of JavaScript: css.js turns the palette into CSS variables (bright_red becomes --omarchy-bright-red, plus conveniences like --owr-bg and --owr-accent), content.js injects the stylesheet at document_start so pages never flash their original crimes, and there's a background worker and a small popup.[4] When a theme is missing a key, a default from Catppuccin Mocha fills in.

Then came the debugging, which is the actual devlog

Ship the thing, watch it break, learn things. Here's the morning, in order.

10:07. Mackenzie sends screenshots of x.com and YouTube. Something's wrong: hidden profiles on x.com, a big empty box in front of YouTube videos. He diagnoses it himself, and this is the lesson worth framing:

"I think the hidden profiles on x.com, as well as the big empty box in front of youtube videos, is your *:html & :not(svg) rule. That's catching invisible divs that sit on top of images for link-like behaviour, pretty sure."

A restyling rule that touches everything will touch the invisible furniture too. Sites use transparent divs as click targets, and if your CSS gives them a background, you get a website wearing cardboard boxes.

10:21. "x.com is much better." But now the touch targets on x.com have the wrong background - because, as Mackenzie put it, "the x.com design team is just using bounding boxes for that in their design system, so we get weird square boxes on every interactable element." You can't fix a site's design system. You can only stop fighting it.

10:24. The fix: make the x.com rule use transparent. Reason: "The background color thing is making the search bar grow out of bounds because their like... pill container thing is just an image." When your restyler paints an element that was never meant to be painted, layout itself bends. "That should get x into a really good spot." It did.

10:30-10:39. A big gap appears in the x.com sidebar. Suspicious! Did we break it? Mackenzie dug in and found the truth: "It uses fixed widths and tries to center all three columns of content... depending on screen size. That big left gap was from the window being at an awkward width for their design team. We don't need to fix it."

This is the most important paragraph in this devlog: sometimes the site was already broken, and your extension gets the blame. Knowing which bugs are yours is half the job. The other lesson from the same minute: YouTube "needs a similar transparent click-area idea to x.com." Per-site fixes aren't a hack, they're the product. They live in OWR_SITES in extension/css.js, and X and YouTube are in there because both draw their icon buttons as filled boxes.

10:49. "This is amazing." Ship it.

The shipping sprint (six commits in twelve minutes)

About the header, Mackenzie had strong art direction, delivered at 10:54:

"You do gotta draw a sick header image for the project using HTML canvas, though, so people get excited about it."

And then, clarifying:

"dumb. I mean accessible for someone that is in a feed-hole. Yknow, big red before-after arrow."

Big red arrow. Before. After. That's the whole brand.

Also in the record, from 10:51, on why this exists at all: "I was actually trying to do this kind of thing manually a year ago with iroshiki but I'm kinda stupid so it didn't work well." It's MIT licensed, so this year's attempt is everyone's.

What it actually does

We measured the contrast, because vibes aren't accessibility

WCAG 2.1, AA for normal text is 4.5 to 1.[3] All 22 themes that ship with Omarchy, checked against each theme's own background, using the same colours the extension uses:

WhatPass (≥ 4.5)
Body text (foreground)22 of 22
Captions, labels, small text (light_foreground)22 of 22
Links (accent)19 of 22 - rose-pine 3.14, miasma 3.86, catppuccin-latte 4.34
Placeholder text (dark_foreground)3 of 22 - osaka-jade 7.78, ethereal 4.90, retro-82 4.68 (white and everforest sit at 1.82 and 1.72)

Placeholder text is where most themes miss, and the fix is already scoped: when a palette fails, fall back to a colour that passes. That fallback is next to build.

Try it

Repo: https://github.com/mackenziebowes/omarchy-web-retheme (MIT)[2]

There's no build step. Most changes are an edit to extension/css.js and a reload. Install: run ./install.sh, then in Chromium go to chrome://extensions, turn on Developer mode, and Load unpacked extension/. In Firefox: about:debugging, Load Temporary Add-on, extension/manifest.json - then click "Grant access to all sites" in the popup once, since Firefox makes site access opt-in, and know that a temporary add-on disappears when Firefox restarts. It installs from the repository, not a browser store.

And when your terminal, your browser, and every tab in it are all wearing the same theme - and you switch themes and watch the whole internet change clothes at once - remember that this started at 9:58 AM as a dumb throwaway idea, and was on GitHub by 10:49.

The best ideas usually are.

Sources

  1. Omarchy, a Linux distribution configured around Hyprland. omarchy.org
  2. omarchy-web-retheme, MIT licence, Mackenzie Bowes, first commit 2026-10-05. github.com/mackenziebowes/omarchy-web-retheme
  3. W3C, Web Content Accessibility Guidelines 2.1, success criterion 1.4.3 Contrast (Minimum). www.w3.org/TR/WCAG21/#contrast-minimum
  4. Omarchy, theme "catppuccin", colors.toml (background = "#1e1e2e"). github.com/omacom/omarchy/blob/quattro/themes/catppuccin/colors.toml

Terms on this page

  • WCAG: The W3C's Web Content Accessibility Guidelines, here version 2.2 (December 2024).