A mixed day — two pages got new words, one small visual bug turned into three attempts before it actually stuck, and a real "blog posts load blank" bug got found and fixed. Here's the whole thing, in the order it happened.
New words for the Home and About pages
The Home page's header went from "Websites for Handwerk and Mittelstand businesses" to something broader: "Whatever you can imagine, we can build together." — same Handwerk/Mittelstand roots, but making room for the personal projects and everything-in-between work I also take on, not just business sites.
The About page got its own rewrite, not a copy of the Home page's — same underlying facts (the metalworking business, two decades in manufacturing, the years with operations in China), but framed around empathy instead of a pitch: "Before I built websites, I ran a business like yours." It's meant to read as reassurance from someone who's actually sat where a Handwerk or Mittelstand owner is sitting, not as another sales page. Both went out in German, Chinese, and Japanese alongside the English.
A corner that took three tries
The Experiment page's hero has a live WebGL shader for a background, sitting inside a rounded card like every other panel on the site. Getting its corners to actually look rounded turned into the most stubborn bug of the day.
- Try one: the existing fix (rounding the canvas element's own box via CSS) had held in Chrome but come back squared-off — Firefox was ignoring it, painting the canvas as a hard-edged rectangle regardless of what CSS said. I added
clip-pathas a second, independent way to clip it. Still square in Firefox. - Try two: since CSS clipping of a GPU-composited canvas is apparently not something to trust, I moved the rounding into the shader itself — discarding the pixels outside a rounded rectangle in the fragment shader, so the canvas paints its own transparent corners no matter what any browser's compositor does with the layer. This rendered perfectly in my own test browser. On the real machine it was actually meant for, it did something worse: the visible color shrank into a small blob floating in the middle of a much bigger dark box. I never fully pinned down why — some interaction with the actual GPU/driver I couldn't reproduce — so rather than keep guessing at math I couldn't verify, I reverted it.
- Try three: back to CSS, but a different shape of fix — wrapping the canvas in an extra
<div>that does the clipping, instead of clipping the canvas's own layer directly. This is the standard, well-documented workaround for exactly this class of bug, and it's the one that actually held across both browsers.
That third fix introduced its own small regression: the shader's cursor-tracking glow stopped reacting to the mouse anywhere except directly over the canvas. The mouse-tracking code was listening on the canvas's parent element — which used to be the whole hero section (so moving your mouse over the headline or nav counted), but after the wrapper div was inserted, "parent" meant just that narrow wrapper. Re-pointed the listener at the hero section explicitly, and the cursor-follow effect works everywhere again.
Auditing every blog post, and a test that catches font-color regressions
Went through all nine posts and the blog index one at a time — checked every image actually loads, every internal link resolves, and the console is clean on each. Rebuilding all of them from the source Markdown produced byte-identical output, so nothing there was actually stale.
While on the subject of things that can quietly break: built a small contrast-checking script (check-contrast.js, no dependencies) that reads every text-color-on-background pairing this site actually uses — the sitewide dark and bright palettes, plus any page that pins its own colors, like the Experiment hero's always-dark backdrop — and checks the WCAG contrast ratio for each one. It's meant to catch the specific mistake of changing a color and accidentally making some text unreadable against its background, on any page, automatically, instead of relying on someone happening to notice. Tested it does its job by deliberately injecting a bad color, confirming it failed loudly, then reverting.
The blog was hiding its own words
Here's the one that actually mattered most: blog posts were loading with the header visible but the article body invisible until you scrolled down. Every section below the hero was wrapped in a scroll-triggered fade-in — hidden by default, revealed once it scrolled into view — and since a post's hero fills most of the initial screen, the entire article sat below the fold, effectively invisible the moment the page loaded.
The unsettling part: I'd already gone through all nine posts looking for exactly this kind of problem, and hadn't caught it. My checks scrolled quickly and screenshotted immediately after, which happened to catch the animation itself mid-transition a couple of times — I wrote those off as timing artifacts of my own testing, not real bugs, and moved on. They were closer to the real issue than I gave them credit for; I just hadn't slowed down enough to see the actual, worse version of it a normal visitor would hit.
Fixed by removing that fade-in from the blog templates entirely, rather than the individual pages — so it can't quietly come back the next time a post gets rebuilt. Ran the build for all nine posts and the index afterward, so every one of them picked up the fix at once, not just whichever ones had been complained about.
Nothing today was dramatic on its own, but the pattern's worth sitting with: two of today's fixes broke something else on the way to working (a shader fix that shrank on real hardware, a clipping fix that killed mouse tracking), and the more important bug was one my own automated pass had already looked past. Automated checks are worth having — the contrast script especially should catch a real category of mistake before it ships — but they're not a substitute for someone actually looking. Get in touch if that kind of attention is what your own project needs.