A felt sun for grey mornings
How a plush sun on the windowsill became the icon set for my smart-home dashboard, and why soft things make better buttons.
Continue readingNotes on code, small apps and things made by hand.
How a plush sun on the windowsill became the icon set for my smart-home dashboard, and why soft things make better buttons.
Continue readingReading
12 September 2026
A short book about doing one thing at a time, read one chapter per evening.
Projects
28 August 2026
Our flat's tiny shared-expenses app: three people, one list, zero arguments.
From the workbench
For years every little app I built looked like every other little app. This summer I tried something different: what if the buttons looked like they were cut from wool and sewn on by hand?
It started as a joke on a rainy Sunday. I had photographed a scrap of grey felt for a birthday card, and on a whim I dropped it into a stylesheet as a background on a primary button. It looked ridiculous. It also looked warm, and I couldn't stop smiling at it.
The trick that made it work was to stop treating every surface the same way. Real felt comes in two moods, and so does the stylesheet:
Keeping those apart is what stops the whole thing from turning into a craft-fair explosion.
The stitches around each card come from a single photo of a running stitch, cut into a nine-slice frame. A blend mode tints the thread to match whatever it is sewn onto, so it is always a shade lighter on colour and a shade darker on cream.
Make it soft enough that people want to touch it, and plain enough that they still know where to click.
My one hard rule: switching between the felt look and the clean look must not move a single pixel. Felt only changes colours, textures, shadows and seams, never padding or fonts. In practice that means every felt rule lives in its own cascade layer:
@layer felt {
:where([data-look="felt"]) .btn-primary {
background-image: var(--felt);
background-blend-mode: soft-light;
}
}
Because the selector is wrapped in :where(), it has no specificity at all, and anything you write yourself wins. Press Ctrl + R with ?look=clean in the address bar and the same page comes back in plain cotton.
19 August 2026
214 cycles, two firmware updates and one very confused cat.
2 August 2026
When rain is coming, the laundry reminder politely stays quiet.
14 July 2026
A gentle evening scene in eleven lines of Ruby.