Agents love inventing skeleton screens. Ask for a loading state and you get a neat gray card with three lines… that is half the height of the real content. When data arrives, the layout jumps. CLS goes up. Reviewers shrug because “at least there is a skeleton.”

I’ve started treating height match as a hard constraint, not a nice-to-have. If the skeleton doesn’t reserve roughly the same vertical space as the loaded UI, send it back.

Why height mismatch slips through

AI drafts tend to:

  • Copy a generic “3 lines + avatar” pattern from training data
  • Ignore the real card’s padding, media block, or multi-row meta
  • Use fixed h-4 bars that look pretty in isolation and wrong in the page
  • Forget mobile denser layouts vs desktop taller cards

The PR still “has a loading state,” so it merges. Users feel the jump every time.

What I ask for instead

Paste the real component (or a Storybook story) and constrain the skeleton to geometry, not vibes:

Add a loading skeleton for `ProductCard`. Constraints: - Match the loaded card’s outer height ±8px at the default Storybook viewport - Preserve the same grid/flex structure (media block + title row + price row) - Use the same padding tokens / gap as the loaded card - No new skeleton library — reuse our existing `Skeleton` primitive - Show both states side-by-side in Storybook (`Loading` + `Loaded`) so the jump is obvious in review If you can’t match height without inventing fake content, stop and explain why. 

The ±8px line matters. Without a number, agents will claim “close enough” while the page still shifts a full media block.

Quick review checks

Reject / send back

  • Skeleton shorter than the loaded card by a media block or more
  • Different padding or gap than the real component
  • A brand-new shimmer library when the repo already has one
  • Skeleton only in one breakpoint while the card grows on desktop

Accept

  • Same outer box model as the loaded UI
  • Structural placeholders (media / title / meta) that mirror real rows
  • Story that toggles loading ↔ loaded without a visible jump
  • Token reuse — no one-off gray hexes

Tiny habit

Next time an agent drops a pretty skeleton into a PR, open the Storybook pair and watch the toggle. If the page jumps, don’t debate aesthetics — paste the height constraint and ask again. A skeleton that doesn’t hold space is just a prettier spinner.