My daughter has an IKEA cloud lamp on her wall. The problem was never that it was boring: it was too bright, one shade of white, and the only way to change anything was to reach up and touch it. I opened it, and inside were 24 V and IKEA's own proprietary connector — there to discourage exactly this, I assume. That one detail decided the whole project: I was never going to dim it, I was going to replace everything behind the diffuser.

The actual board, front and back. The back is not printed: the moon, the cloud and the stars are openings in the soldermask, and what shows through them is the copper.
The why, the how, what did not work, and the part I did not expect to enjoy: making it a proper board.
It did exactly one thing, and at bedtime it went straight into her face. To change anything you had to reach up and touch it.
She watches us change the colour of a lamp from a phone, and to her that is not technology: it is simply what lamps do. So she should have one she can change herself — and find out, while she is at it, that the inside of a thing is not sealed. You are allowed to open it.
Inside: 24 V and a connector shaped so that nothing else fits. Adapting to it made no sense, so I took out everything behind the diffuser and put in a microcontroller and a ring of 24 pixels.
She picks the colour. No account, no app, no cloud. And the lamp also answers to Home Assistant, because it speaks a protocol the house already understands.
It answers like a Yeelight bulb on the local network, so the house already knows what it is. Committing to that shape on day one meant the light's behaviour was already decided: I never had to invent it.
One file holds state, fades, gamma and what survives a power cut — and it does not know what a Yeelight is. That separation is the only architectural decision worth making here.
The control page is served by the lamp itself: under 4 KB, gzipped into the firmware. I put the URL on her iPad and that was it. Nothing to install, nothing to keep alive.
The diffuser is the hard part and it already existed. Keeping the case turned something headed for a donation box — or worse, a bin — into the one part I did not have to make.



The loose wires outgrew the masking tape, so I made it a board. I did not draw it: I described it, and three scripts wrote it. In 2026 that is no longer the wall it used to be — KiCad is free, the factory is a website, and the part that used to stop people, knowing where everything actually goes, you can now talk your way through.
One script places the parts, one lays the tracks, one draws the artwork. All three would rather tell me something sits two tenths of a millimetre too close than write the file. I never dragged a single footprint.
The module footprint comes from the manufacturer's own dimensioned DXF, not from an image search. Every part is measured against the others before anything is written.
So the board never costs you the microcontroller. And the pinout is printed inside the socket, which is exactly where you need it: with the module out.
The moon, the cloud and the fourteen stars are openings in the soldermask. What shows through is the copper with an ENIG finish. Three colours, and only one of them is ink.
What the exercise actually taught me is not that the automated checks are enough. KiCad's DRC passed clean with 49 stacked shapes in the soldermask, because the DRC does not check the mask. What found the mistakes was looking.
Everything is on GitHub: the firmware, the web UI, the KiCad scripts that generate and check the board, and the fabrication files.
Built with Claude Code and the KiCad MCP. The idea, the taste and every decision are mine; the firmware, the board scripts and the video were produced together with the AI tools. The video's narration is Gemini TTS, and the video itself is made with HyperFrames.