docs GitHub

Design systemDraft

Authenticator code

Shows a login's one-time code so a code about to roll over is never a guess: the current code large, the next one small under it, and a ring counting down. Appears on a vault login's detail (desktop), in the phone's Codes list, and in the pairing code of Add your phone (the same mono style, no ring). Drawn on "Vault" and "Add your phone".

SurfaceImplementing fileStatus
Deckdeck/views/vault-item.js, deck/css/views/vault.css (main)partial
Appnone in apps/app (work/mobile)not built
Lumennone ("code northwind" is a typed command, not drawn)not built

Anatomy

  1. Label (desktop card only): "Authenticator", 12/16 600 --label.
  2. Current code. JetBrains Mono, hero size 28/34, 600, --text, letter-spacing: 0.04em, font-variant-numeric: normal. Six digits as two groups of three with one space: "482 913".
  3. Next code. Mono 12/16 --label: "next 031 775".
  4. Ring. SVG, viewBox 22, radius 9, stroke 2.5: track --rule-strong, arc --focus with a round cap, starting at 12 o'clock and emptying clockwise over the period (30 s). Drawn 32 on desktop, 28 on the phone. Under it, the seconds left at 12/16 --text-2: "18 s".
  5. Copy. Desktop: a secondary button "Copy code" with the copy icon. Phone: the whole row copies on tap.

Desktop layout: label, current and next stacked on the left; ring and seconds centred in a column (gap 4); Copy code at the right. Phone row (padding 12 14): account tile 32, then a column of the account name (13 --text-2, truncating), the current code and the next line; the ring column at the right (gap 2).

States

StateLook
Countingring arc shrinks; seconds tick; nothing changes colour, ever, even under 5 s
Rolloverthe next code moves up to current in place; the next line shows the new next; no layout shift (mono, fixed width)
Copiedrow fill --signal-wash; the next line becomes a 12 px check and "Copied · clears in 30 s" at --text-2
Lockedcode and ring replaced by the lock pill "Locked · Face ID to open" (proposed; the board draws only unlocked)
Unlockedthe vault's pill reads "Unlocked · 24 min left"; use does not extend it
Offlinestill counts: codes are computed on the device from the secret cached while unlocked

Keyboard and touch

  • Desktop: the Copy code button, or ⌘C with the code focused.
  • Phone: tap anywhere on the row copies; the whole row is the target (min 44 tall, 72 as drawn).
  • The clipboard clears itself after 30 s and the row says so.

Motion

The ring animates on the compositor: one linear stroke-dashoffset transition across the seconds left, restarted at each period, never a per-second redraw. The copied wash fades out over --motion-reveal (150) when it clears. Reduced motion: the ring steps once a second.

Copy

  • "Authenticator", "next 031 775", "18 s", "Copy code", "Copied · clears in 30 s", "Tap a code to copy", "Locked · Face ID to open", "Unlocked · 24 min left".
  • Seconds always with a space: "18 s", never "18s". Never "OTP", "TOTP" or "2FA code" in the UI.
  • Pairing code (Add your phone) uses the same current-code style, but 8 characters in two groups of four joined by a hyphen ("7KQM-4P2X", alphabet ABCDEFGHJKMNPQRSTUVWXYZ23456789, no 0, O, 1, I or L), never wrapping, with its own status: "Used 14:31", and "Single use, valid 10 min. Treat this code like a password."

Accessibility

  • The code has aria-label reading digit by digit: "Code 4 8 2 9 1 3". The ring is aria-hidden; the seconds are available but not live (no announcement every second).
  • "Copied" is announced once through a polite live region.
  • Mono 28/600 --text on --panel passes easily; --label next code passes 4.5:1 at 12.

Gaps

Deck (main)

  • No next code; the code sits in a field row labelled "Code", not "Authenticator".
  • Ring is 20 px, and seconds render "18s" without the space.
  • Codes come from the box each period, not computed on the device, so offline shows nothing.
  • Copy is an icon button with the tooltip "This vyred has no vault.copy yet" when missing.
  • No phone Codes list with tap-to-copy rows.

App (work/mobile)

  • No vault codes.