Pick a variant and size — see the cva() call resolve to a class string, exactly how a
shadcn Button works. Then watch tailwind-merge kill conflicting classes.
cva maps a variant + size prop to the right utility classes.
One component, many looks, fully type-safe.
A consumer passes className to override a default. With plain string join, both
px-* survive and the cascade is unpredictable. cn() merges them so the
last conflicting utility wins. Edit the override:
cn = twMerge(clsx(inputs)). clsx handles
conditional classes; tailwind-merge resolves Tailwind conflicts so overrides actually win.