Case studies / Tigg · Jul 2025 – Jun 2026
Sign-in as a sequence of recoverable states
Two arcs: the 2025 verification flow (designed in Figma first), and the 2026 sign-in redesign that made the Citizens Bank integration visible to every user.
Role
Timeline
Team
Platform
Not mine
Measured outcome
the key decision
Every step of sign-in has a way back, and the front door carries one message at a time.
how deep do you want to go?
A password form that learned to ask a second question
Until mid-2025, signing in to Tigg meant an email, a password and a button. Then the backend started deciding, device by device, whether to ask for a second step: a 6-digit code sent by email. That one change added states the old page had never had:
- the device isn't identified yet;
- a code is needed, but hasn't arrived;
- the code is half typed, or wrong;
- trust this device, or not;
- and where do I manage the devices I trusted?
Each of these is a moment when someone can get stuck at the only door into the product. I treated sign-in as a sequence of states, and gave each one a visible way forward or back.
A year later the same page had a different job. Tigg had integrated with Citizens Bank, and the login is the one screen every user sees. In 2026 I redesigned it so the integration was the first thing people saw, without slowing down anyone who just wanted to sign in.
Two arcs, three front doors
Tigg is several apps sharing one account system. The accounting app and the POS each have their own login page, and a companion account web app handles sign-up, password recovery and security settings. There is no single sign-on and no shared component library between the codebases. So a change to how sign-in behaves has to be designed once and then built three times.
| 2025: device verification | 2026: the Citizens Bank login | |
|---|---|---|
| Question | How do people get through a conditional second step? | How does everyone see a major bank integration? |
| Design | In Figma first, then built | A visual redesign of the login page |
| My part | Design and frontend in all three apps | Design and frontend in both web apps |
| Not mine | Sending the codes, the device-trust policy, the sessions backend | The bank integration itself |
The inputs came through Tigg's usual channels: the CEO's priorities, and problems reported by QA and support. No usability test was run for either arc.
Every wait gets a state
I started by mapping sign-in as a state machine. The backend can say "verification needed" in two ways: as a flag in a successful response, or as a message in an error. Both had to lead to the same code-entry screen. After the code, the person had to follow exactly the same route as someone who didn't need one. A bank-report user still lands in their report view, and an expired password still leads to the change-password screen.
Two waits are invisible to the person signing in, so I gave each one a state:
- The device isn't ready. The browser needs a moment to identify the device. Until it has, the button reads "Preparing..." and can't be pressed, so an early click doesn't fail with a confusing error.
- The email is on its way. The code screen says where the code was sent and shows a countdown: "Didn't receive a code? Resend in 00:45". In the last five seconds the digits turn red and blink, then the countdown becomes "Resend now". The number stays next to the colour, so the cue doesn't depend on colour alone.
The trust choice appears at the moment it matters, on the code screen: "Trust this Device for 60 days?", checked by default. A teammate wrote that wording and the first placeholder screen. I designed and built the flow around it.
Failures became recoverable too. A wrong code shows the server's message, clears all six boxes and puts the cursor back in the first one. After a failed sign-in, the email and password stay filled in. In September 2025 I also removed validation messages that pointed to the wrong field.
Asset to add
Figma export: '🟢 New Login' page — the 2FA frame (carried over from the 2025 design), 2x PNG
Six boxes that behave like one field
The code input looks trivial: six boxes, one digit each. On phones it broke. Android and iOS keyboards offer the whole emailed code as a single suggestion, and one tap put all six digits into the first box. The rest were lost.
I fixed it in August 2025. Then I wrote down what the input has to do, however the code arrives:
| Input | Result |
|---|---|
| A digit | Fill the box, move to the next |
| Anything that isn't a digit | Ignored |
| A full code, typed, pasted or autofilled into any box | Spread across all six |
| Backspace in an empty box | Clear the previous box and move there |
| Arrow keys | Move between boxes |
| Six digits present | Submit once, and never while a request is running |
Doing this once wasn't enough: all three apps had to follow the same rules, in two different code styles. Keeping them in step turned out to be a design task as much as an engineering one.
2026: putting the bank at the front door
The Citizens Bank integration was a major feature, and it needed to be in front of every user. The existing login showed "What's New with Tigg" as a pale side column with two small post cards. In that layout, a bank partnership looked as important as a routine monthly update.
The redesign was mainly visual. The sign-in form stayed where it was, on the right. On the left, the list became one featured post at hero scale: a dark, image-led panel with the date, title, excerpt, a "Learn More" button and previous/next controls. At launch in late May 2026, that post was "Citizens Bank International Now Integrated with Tigg".
Signing in still had to come first. On a phone the form appears first and the announcement follows below, with its call to action pinned while the excerpt scrolls. If the posts fail to load, the panel shows "Unable to load the update." with a reload button, and the form beside it keeps working. I didn't redraw the verification, forgot-password and sign-up screens in 2026; only the login page changed. I also applied the same visual change to the companion account app.
Asset to add
Screenshot: 2026 accounting login on desktop with the Citizens Bank featured post, and the same page on a phone before and after scrolling
Results and what I learned
The 2025 verification flow was in Tigg's first tagged releases in February 2026. The 2026 redesign was merged to production on 27 May 2026 and included in a tagged release on 3 June.
It looked more modern.Reported to me by the CEO
Measured outcome: none. I have no data on sign-in success, resend rates, time to sign in, or clicks on the featured post. If I were measuring it, I'd log one event for each state change, including how the code was entered (typed, pasted or autofilled). I'd also track clicks on the featured post during a campaign.
The security feature is the recovery path. Most of the work was in the states after something goes wrong: a wrong code, a late email, a lost field.
A small component can carry a contract. Six boxes had to behave like one field for paste and autofill, in three codebases.
A visual redesign can do business work. Making the bank integration the first thing every user sees didn't need a single flow change.
States, edge cases and the first sign-in on a new device
| State | What the person sees |
|---|---|
| Device not ready | "Preparing..." on a disabled button |
| Required fields empty | Field messages under email and password |
| Sign-in refused | The server's message under the form; typed values kept |
| Code incomplete | "Please enter a complete 6-digit verification code" |
| Code wrong or expired | The server's message; all boxes cleared; cursor in box 1 |
| Resend cooling down | "Resend in 00:ss", red and blinking in the last five seconds |
| Resend failed | "Failed to resend verification code" |
| Unknown company address | "The company url … doesn't exist", with a way to claim it |
| Subscription not verified | A message with the support contact |
| Posts loading or failed | A spinner, or "Unable to load the update." with reload |
Other edge cases I designed for:
- surrounding spaces are trimmed from emails, and emails are lowercased so capitals don't cause a failed sign-in;
- a deep link brings people back to where they were going after sign-in, and an unsafe link falls back to the home page;
- after verification, an expired or first-time password still goes to the change-password screen.
Built, then removed
Several pieces of the 2025 work didn't survive in their first form. I count these removals as part of the design.
| What | What happened | My reading, looking back |
|---|---|---|
| "Remember me" checkbox | Removed in August 2025 | Device trust replaced it with a decision the server enforces |
| A trusted-devices page inside accounting settings | Built in August 2025, removed a month later, before any tagged release | Devices belong to the account, not to one app, so device management went to the companion account app. On the same day I extended the device list there |
| "Remove all devices" | I hid it in August 2025; another engineer later brought it back with a loading state and disabled it when there's nothing to remove | |
| A port of the accounting sign-in code into the POS | Abandoned after two exploratory attempts; a flow written in the POS's own style shipped instead | Fitting the POS codebase beat importing a second way of doing things |
| A news column on the POS login | Built but never switched on, which saves a request on every sign-in |
In the account app, turning two-step verification on or off asks for the current password first. Trusted and untrusted devices are listed separately, and each can be removed after confirming.
Notes on sources
The dates come from the tickets and version history. The reasons in the right-hand column are my reading in hindsight, not notes from the time. The diagrams are redrawn from the shipped code and the Figma layer names, with fictional data.