SYSTEM

One-time code

One short ink rule per character.

Forms shadcn: Input OTP

Code

We sent six digits to your email.

States

  • Empty

    nothing set

    Six short ink rules.

  • Typing

    :focus on a slot

    The focused slot’s rule develops in --state; the filled ones keep their ink.

  • Filled

    every slot set

    Six characters in the clean cut.

  • Invalid

    aria-invalid="true"

    Every rule stays --state.

Anatomy

Slot 32px wide (--control-sm), 40px tall, one 1px --ink rule
Character Redaction, the clean cut, at 22/24, centred
Gap half a module between slots
Focus each slot’s own rule develops in --state in 140ms
Keys typing moves on; Backspace on an empty slot steps back; a paste spreads across the slots
Invalid every slot’s rule stays --state, with the message under them

The develop time is read from the engine at build time (rule.ts).

Decisions

  • A rule per character

    The code is a row of short fields rather than one box with dividers: each slot is its own input, so focus develops each slot’s rule in turn and the reader sees where they are.

  • The clean cut

    Characters are display text under 24px, so they are set in Redaction’s clean cut; the eroded cuts read as a rendering bug at that size.

  • Invalid is a state

    A wrong code is a state, so its rules turn --state and a “Check this” label leads the message.