Styling
The primitive gives you root-level state selectors. Your own slot classes stay responsible for the visible surface, spacing, and active-slot treatment.
CSS contract table
Headless state selectors
css
[data-slot='input-otp'] { }
[data-empty] { }
[data-partial] { }
[data-complete] { }
[data-active='2'] { }
[data-focused] { }
[data-focus-visible] { }
[data-invalid] { }
[data-disabled] { }State selectors
[data-empty],[data-partial], and[data-complete]tell you how much of the OTP is filled.[data-active]gives you the currently active slot index from the root.[data-focused]and[data-focus-visible]let you differentiate focus ring treatments from plain hover or active states.
Styling variants
Both variants style the same primitive state contract while keeping the slot markup fully owned.