Nobody tells you an interface feels cheap.
They just leave.

A visitor doesn't run through a checklist. They land, move the cursor, click something — and somewhere in that first half-minute they've already decided whether this is worth trusting with the next ten.

Nobody writes that verdict down. They just act on it, usually before they've read a single word.

What “cheap” actually means

It's rarely one broken thing. It's a handful of decisions nobody made on purpose — each too small to file as a bug — that add up to a feeling anyway.

  1. 1

    The layout jumps

    A card finishes loading and the paragraph underneath drops to make room for it. The button you were about to hit is now hovering over something else entirely. Every state an element can reach needs its space reserved before it gets there — not the moment after.

  2. 2

    The hover answers late

    You put the cursor on a button and, for a beat, nothing happens — then the color catches up once you've already moved on. Feedback under a tenth of a second reads as instant. Anything slower reads as absence, even once it arrives.

  3. 3

    Nothing was actually measured

    Twenty pixels here, eighteen there, a heading sized at whatever the framework shipped with. No single gap is wrong enough to flag on its own. The page just feels slightly off, in a way nobody can point to — because it was never built from one scale to begin with.

  4. 4

    The motion doesn't explain anything

    Elements fade and slide because a UI kit defaults to it, not because the movement tells you what changed. You can tell — close the panel a half-second after opening it, and it snaps back to start instead of reversing from wherever it actually was.

What we're doing about it

trove/cn studies the interfaces that get this right — the ones people call “expensive” without being able to say why — and rebuilds the actual mechanism behind each one: a spring that answers in under a tenth of a second and adapts if you interrupt it instead of snapping back to start, a type and spacing scale where every size traces back to one system instead of whatever felt close enough, surfaces that visibly step up off the page instead of a border nobody notices. None of it is supposed to read as an effect. That restraint is the craft, not the absence of it.

Then it ships as source, the same distribution model as shadcn/ui: code that lands directly in your project and becomes yours to maintain, not a package you install once and never open again.

Browse components