The Well-Tempered Notebook

a notebook kept in public

Counterpoint for interfaces

Every interface I have worked on has had the same kind of bug, and it is never the kind that shows up in a component library. Each piece is fine. The button is fine. The toast is fine. The loading state is fine. Then someone triggers a save while a toast is already up and a sheet is half-dismissed, and the result is something nobody designed and nobody can quite name.

This is a counterpoint problem. In counterpoint the rules are almost entirely about pairs: two voices moving in parallel fifths, two voices crossing so you cannot tell which is which, two voices arriving at the same note from the same direction. No voice is wrong. The relationship is wrong.

Most of our tools are built to check single voices. A design system checks that a button is a button. A type checker checks that a prop is a string. Neither has an opinion about what happens when the sheet and the toast both decide they own the bottom of the screen.

What the rule actually protects

The parallel-fifths rule is not arbitrary aesthetics. Two voices a fifth apart, moving in the same direction, fuse — the ear stops hearing two things and starts hearing one thing with a strange timbre. The rule exists to preserve independence: you wrote two voices, so the listener should be able to hear two voices.

That is the interface version too. When a spinner and a skeleton and a progress bar all appear together, the user does not perceive three accurate status signals. They perceive one confusing event. The information did not add up; it fused.

Writing the pairs down

The practical move is unglamorous: enumerate the pairs. Not all of them — the combinatorics are hostile — but the ones that share a resource. Two things that own the same corner of the screen. Two things that can both take focus. Two things that both speak to a screen reader. Two things that both animate on the same trigger.

That list is usually short, and it is usually not written down anywhere, and it is usually where the bugs are.


All posts