Six cells for the code in the email: a wrong one shakes and empties itself, a right one closes them into a single pill.
The prompt15,227 characters
Add the "One-time code" component from notboring to my project.
It is licensed for use in my projects — notboring.dev/license. Please:
1. Create the component at a sensible path for this
project, named OTP, from the source below.
2. Install what it needs: npm i framer-motion lucide-react
3. Add the CSS to the project's stylesheet.
4. THE PART THAT NEEDS YOUR JUDGMENT. The CSS reads
these custom properties and does not define them:
--card
--danger
--font-ui
--ink
--ink-3
--ink-4
--ink-rgb
They are notboring's design tokens. Map each one to
whatever this project already uses for the same
job — its own ink, ground, surface and UI font —
rather than defining them as new globals. If the
project has no equivalent, define it locally on
the component's own root so nothing leaks out.
Anything ending -rgb wants three bare numbers,
because the CSS builds rgba() from it.
5. IF YOU CHANGE IT, GO ALL THE WAY. This block is
built for every state its object can really be
in — empty, one, full, refused, undone, pressed
twice, interrupted halfway — and not only the one
the demo opens on. Adapt it and the same standard
holds: work out that list before you write, and
build the whole of it. Never settle for the
minimum that makes the screenshot right. A
component somebody has to come back and finish is
the thing this was written to replace.
Keep the comments. They say why the numbers are what
they are, and they are most of what makes this worth
copying rather than rewriting.
--- OTP.tsx ---
import { useEffect, useRef, useState } from "react";
import { AnimatePresence, motion } from "framer-motion";
import { Check } from "lucide-react";
/* ══ OTP ══════════════════════════════════════════════════
Six cells for the code in the email, and the one thing they
do when it is right: close up into a single pill.
THE SIX CELLS ARE ONE FIELD WEARING SIX BOXES. There is one
input under them holding the whole string — invisible, but
real — so a paste of "481523" spreads across all six, the
password manager fills it, the phone offers the code above
the keyboard, and Backspace walks back the way a person
expects. The version everybody builds first is six separate
inputs with focus handed between them, and it fails at
exactly the moment it matters: the paste.
A WRONG CODE EMPTIES ITSELF. The cells shake, and then the
digits leave right to left, one every 60ms, the way you
would have deleted them. A field that shakes and keeps the
six wrong digits is asking you to do six things before you
can try again.
AND A RIGHT ONE CLOSES UP. The gaps go to nothing, the
The rest — the source and its comments — is what the plan opens.