Four ways to break six digits into groups, each valid or invalid, plus the single slot on its own with the five states that belong to one box rather than to...
Two components, thirteen variants
InputOTP - Variant × State: Digits Only · With Separator · Simple · With Spacing × Default · Invalid - 192, 242, 217 and 232 wide
Because butted boxes each carrying their own 1px outline would draw two lines at every seam. Three of the four layouts put a single base.input outline on the group and drop 1px dividers between the slots as absolute children, so every seam is exactly one line wide.
What makes With Spacing different?
It is the only layout where a slot is a whole shape: six separate 32 × 32 boxes, 8 apart, each with its own outline and radius.sm corners. No group, no dividers. It is also the widest at 232 against Digits Only's 192.
What does Invalid actually repaint?
Everything structural. The group outline, the dividers between slots and the dashes between groups all go to base.destructive. Leaving the seams grey would make a wrong code look partly valid, which is worse than not flagging it at all.
Why is the slot published separately?
Because its states belong to one digit, not to the code. One slot is focused while the others wait, one is filled while the rest are empty. Those five states could not be an axis on InputOTP without multiplying eight variants by five for combinations nobody needs.
What is in the usage frame?
Three sections at 1000 wide. A verify-your-login card carrying the source's own copy, a code that did not match with the message under it, and a six-digit code filled in with a Verify button. The last one is the only place in the file where the Slot component's Filled state is used six times over, because the joined layouts cannot take digits without detaching.