Components · Forms & selection
OTP input
A one-time-passcode field: a centred row of single-character slots in Geist Mono, with an optional hairline separator between groups. Each slot is a 32px square that rings on focus.
Preview
Light
Dark
Accessibility
Spec
Values and token references straight from the Zetta spec.
input-otp-container
- display
- flex
- flexDirection
- row
- gap
- 8px
- justifyContent
- center
- alignItems
- center
input-otp-slot
- backgroundColor
- {colors.surface-card}
- textColor
- {colors.ink}
- borderColor
- {colors.border-strong}
- borderWidth
- 1px
- borderRadius
- {rounded.base}
- fontFamily
- Geist Mono
- fontSize
- 16px
- fontWeight
- 500
- width
- 32px
- height
- 32px
- textAlign
- center
input-otp-slot-focus
- borderColor
- {colors.border-focus}
- outline
- 2px solid {colors.border-focus}
- outlineOffset
- 2px
input-otp-separator
- color
- {colors.hairline}
- width
- 8px
- height
- 2px
Build with the skill
No package to install — hand this to your AI to generate the OTP input in your stack.
Implement the Zetta "OTP input" component in this project's stack using the zetta-design-md skill.
- Apply the `input-otp` spec from the skill (variants: default).
- Use this project's own component conventions and framework idioms.
- Reference the Zetta design tokens (CSS variables) for every color, radius, and shadow — never hardcode values.
- Implement all states (hover, focus, active, disabled, and invalid where applicable) with a visible 2px focus ring.
- Honor the Zetta guardrails (brand never shifts hue, shadows for overlays only, etc.) and verify in Light, Dark, and Accessibility. Anatomy & rules
- 32px square slots, base radius, hairline-strong border, Geist Mono 16/500, centre-aligned. The separator is an 8×2 hairline bar.
- Mono digits keep every slot the same width. Auto-advance to the next slot on entry and step back on Backspace; allow paste to fill the whole code.
Accessibility
- Use
inputmode="numeric"andautocomplete="one-time-code"; give each slot a label (Digit 1…6). Announce validation on the group, not per slot.