Every other action in that menu dismisses it; the swatches did not. They do now, the way the calendar's colour menu already did.
The live-updates indicator
It was an 8px flat speck in --fg-faint — near invisible in either theme — and it showed two states where the lifecycle has three.
There was no third state to colour, so I added one. The push client only ever reported connected or not, which cannot tell "retrying with a backoff" from "stopped". It now reports connecting | connected | disconnected, and the retry path reports connecting instead of going dark, so a flaky link shows amber rather than looking dead. pushConnected stays for the callers that only want the boolean.
The dot is now 12px and raised — a white highlight over a solid colour with a soft halo. That is one bead that reads on light and dark alike, with no per-theme variant to keep in sync:
state
colour
means
connected
green
EventSource open
connecting
amber, slow pulse
first attempt, or a backoff retry
disconnected
red
not trying — push stopped
Two details worth keeping: the pulse respects prefers-reduced-motion, and the indicator is now labelled for a screen reader rather than aria-hidden, since it carries real information about whether mail is arriving live.
Verified
In the running app: picking a colour closes the menu and applies the colour (fill: rgb(37, 99, 235)); the dot renders at 12×12 with the right label; and all three states were photographed in the dark theme plus connected in light, to check the bead reads against both backgrounds rather than trusting that it would.
npm run typecheck, npm test — 224 web + 88 server passing.
Two cosmetics.
## The colour menu stays open after a pick
Every other action in that menu dismisses it; the swatches did not. They do now, the way the calendar's colour menu already did.
## The live-updates indicator
It was an **8px flat speck** in `--fg-faint` — near invisible in either theme — and it showed two states where the lifecycle has three.
**There was no third state to colour, so I added one.** The push client only ever reported `connected` or not, which cannot tell *"retrying with a backoff"* from *"stopped"*. It now reports `connecting | connected | disconnected`, and the retry path reports `connecting` instead of going dark, so a flaky link shows amber rather than looking dead. `pushConnected` stays for the callers that only want the boolean.
The dot is now 12px and raised — a white highlight over a solid colour with a soft halo. That is one bead that reads on light and dark alike, with no per-theme variant to keep in sync:
| state | colour | means |
| --- | --- | --- |
| connected | green | EventSource open |
| connecting | amber, slow pulse | first attempt, or a backoff retry |
| disconnected | red | not trying — push stopped |
Two details worth keeping: the pulse respects `prefers-reduced-motion`, and the indicator is now **labelled for a screen reader** rather than `aria-hidden`, since it carries real information about whether mail is arriving live.
## Verified
In the running app: picking a colour closes the menu and applies the colour (`fill: rgb(37, 99, 235)`); the dot renders at 12×12 with the right label; and all three states were photographed in the dark theme plus connected in light, to check the bead reads against both backgrounds rather than trusting that it would.
`npm run typecheck`, `npm test` — 224 web + 88 server passing.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
**Merged** 2026-08-25 as coffey-labs/ihasmail@acc9df299e40
<sub>Rebuilt from: git history, session transcript.</sub>
This repo is archived. You cannot comment on issues.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Two cosmetics.
The colour menu stays open after a pick
Every other action in that menu dismisses it; the swatches did not. They do now, the way the calendar's colour menu already did.
The live-updates indicator
It was an 8px flat speck in
--fg-faint— near invisible in either theme — and it showed two states where the lifecycle has three.There was no third state to colour, so I added one. The push client only ever reported
connectedor not, which cannot tell "retrying with a backoff" from "stopped". It now reportsconnecting | connected | disconnected, and the retry path reportsconnectinginstead of going dark, so a flaky link shows amber rather than looking dead.pushConnectedstays for the callers that only want the boolean.The dot is now 12px and raised — a white highlight over a solid colour with a soft halo. That is one bead that reads on light and dark alike, with no per-theme variant to keep in sync:
Two details worth keeping: the pulse respects
prefers-reduced-motion, and the indicator is now labelled for a screen reader rather thanaria-hidden, since it carries real information about whether mail is arriving live.Verified
In the running app: picking a colour closes the menu and applies the colour (
fill: rgb(37, 99, 235)); the dot renders at 12×12 with the right label; and all three states were photographed in the dark theme plus connected in light, to check the bead reads against both backgrounds rather than trusting that it would.npm run typecheck,npm test— 224 web + 88 server passing.🤖 Generated with Claude Code
Merged 2026-08-25 as coffey-labs/ihasmail@acc9df299e
Rebuilt from: git history, session transcript.