The whole avatar flow in one control — pick or drop, refuse with a spoken reason, crop square, upload with a progress ring and cancel, and keep the crop when the transfer fails.
npx shadcn@latest add @zyeon/avatar-uploadZyeon UI limits how often it can be asked, and Avatar Upload hasn't had its turn. Its source will show here once it has.