OtpField
A one-time-code field: length cells backed by a single real text field.
Built as a BasicTextField with a decorationBox that paints the cells, rather than the usual trick of an invisible alpha(0f) field stacked behind a clickable Row. That matters for more than tidiness — with a real field, focus, the caret, IME actions, select-all, paste and the platform's own SMS-code suggestion all work by default, where the stacked-overlay version has to re-implement each one by hand and typically ships without them.
onComplete fires when the code first reaches length; re-editing the last digit to the same value will not re-fire it, so it is safe to hang a network call off.
var code by remember { mutableStateOf("") }
OtpField(code, { code = it }, onComplete = { viewModel.verify(it) }, isError = state.rejected)ponytail: no enabled = false styling beyond what the text field already does, and no built-in resend timer — a timer is screen state, not field state, and belongs in the caller's ViewModel.