Part 2 of 2 · Design engineering

A tap is only safe if the state survives

I turned the mobile design into a working React prototype where every attempted action can explain what was allowed, what was blocked, and what information remained intact.

Typed transition functions hold the product rules. React renders their results. The interface makes recovery, recipient order, focus, status, and destructive confirmation visible through the same controls a person would use.

The prototype uses fictional local data and no external service. It demonstrates client behavior, not production authorization, persistence, or signature delivery.

45 second summary

What I implemented and what this story proves

Problem
A connected prototype needed executable rules, not convenient screen links.
Ownership
I designed the transition model, interface states, recovery behavior, accessibility mechanics, and tests.
Stack
Next.js, React, TypeScript, semantic HTML, CSS, Vitest, and Playwright.
Evidence
Reachable browser states, exact transition logic, preserved input, and automated checks.
Status
A local browser prototype with fictional fixtures and deterministic scenarios.
Limit
No backend authorization, account sync, signature delivery, or production write is claimed.
Editorial composition of mobile creation and approval states with design tokens and state diagram
Editorial system view. Live proof below comes from the working prototype and transition inspector.

Episode 1 · Transition contract

I turned the prototype path into a contract

Each journey accepts a typed action and returns either a next state or a guard error. Unsupported actions preserve the current data. A screen cannot skip responsibility, required information, recipient validation, or a valid prior state.

Approvalreviewing
responsibilityrequired contextnetwork
  • approved
  • failed
  • changes requested
  • cancelled
Creationselecting template
valid fieldsstakeholdertemplate version
  • created
  • failed
  • draft restored
Signatureconfiguring
valid identityunique recipientexplicit order
  • waiting
  • completed
  • declined
  • expired
  • voided
Branching transition contractGenerated from journeyContracts in domain.ts. Guards can preserve the current state, produce a recoverable failure, or permit a terminal result.
01
Previous state
approval:ready
02
Attempted action
SUBMIT
03
Guard result
accepted failure branch
04
Changed fields
stage
05
Next state
approval:failed
06
Announcement
Approval was not sent. Reconnect and retry.
One transition, fully exposedThe live inspector uses this same evidence shape after every attempted action. A rejected action reports the guard without hiding or replacing existing data.
if (action.type === "SUBMIT" || action.type === "RETRY") {
  if ((action.type === "SUBMIT" && state.stage !== "ready") || (action.type === "RETRY" && state.stage !== "failed")) {
    return rejected(state, action.type, approvalStageKey, "Submission is not available from the current state.")
  }
  if (!state.responsible) {
    return rejected(state, action.type, approvalStageKey, "Assume responsibility before approving.")
  }
  if (state.network === "offline") {
    const next = { ...state, stage: "failed" as const, message: "Approval was not sent. Reconnect and retry." }
    return accepted(state, action.type, next, approvalStageKey, ["stage"], next.message)
  }
  const next = { ...state, stage: "submitting" as const, message: "Approval is ready to confirm." }
  return accepted(state, action.type, next, approvalStageKey, ["stage"], next.message)
}

Episode 2 · Recovery

Failure does not get to erase intent

Approval answers survive an offline attempt. Creation keeps its title, purpose, and stakeholders through validation and a retryable failure. A saved creation draft can restore after reload on the same device, while the story remains explicit that this is not account or server persistence.

Approval

Preserve
Risk answer and budget confirmation
Interrupt
Offline submission
Recover
Reconnect and retry

Creation

Preserve
Title, purpose, and stakeholders
Interrupt
Retryable submission failure
Recover
Restore and submit

Local draft

Preserve
Editing state and entered values
Interrupt
Reload on the same device
Recover
Resume from saved data
Preservation is part of the transitionFailure changes status without discarding intent. Local restoration is explicit and remains separate from any claim of account or server persistence.

Approval after an offline attempt

Creation after a retryable failure

Episode 3 · Explicit order

I made hidden order operable

Signature recipients are validated before review, stored as an ordered array, and moved through named controls. The same array drives review and progress. After send, visible controls can reach waiting, reminder, complete, declined, expired, and voided states.

Before action

  1. 1Mara Reed
  2. 2Casey Morgan
  3. 3Jon Bell
MOVE Casey Morgan upaccepted

After action

  1. 1Casey Morgan
  2. 2Mara Reed
  3. 3Jon Bell
Order is data, not decorationNamed movement controls update the same ordered recipient array used by review and progress states. Drag is not required.

Episode 4 · Perception

I made state changes perceivable

Journey changes move focus to the new heading. Validation focuses a summary and connects errors to fields. Accepted and rejected actions update one polite live region. Recipient movement uses named buttons. Destructive actions require confirmation. Reduced motion removes movement without removing feedback.

These are implemented behaviors. I do not call them accessibility compliance because no recorded audit establishes that claim.

  1. 01Journey change

    Move focus to the new screen heading

  2. 02Validation failure

    Focus the summary and associate each invalid field

  3. 03Accepted action

    Announce the concise result through one polite region

  4. 04Recipient movement

    Use a named button and preserve a logical order

  5. 05Destructive request

    Require a second explicit confirmation

  6. 06Reduced motion

    Remove movement without removing state feedback

State must be perceivableAccessibility changes the mechanics of each control. The behavior remains visible, operable, and announced without claiming a completed compliance audit.
RuleImplementation proofBrowser proof
Approval guardUnit transitionRendered disabled and ready states
Offline recoveryUnit preservationBrowser retry through controls
Draft restorationSerialized local draftReload and resume
Recipient validationInvalid and duplicate rulesForm error association
Recipient orderArray movementNamed keyboard action
Focus and statusBrowser focus checksLive region output
Responsive layoutPublished width loopNo page overflow
Rule to proof mapEach published engineering claim connects to an implementation rule and a rendered browser check. Counts are secondary to traceability.

Production boundary

The prototype stops at the browser

The client can demonstrate rules, persistence on one device, focus, and recovery. Production still needs trusted authorization, account synchronization, server confirmed writes, signature provider callbacks, idempotency, and conflict resolution.

Implemented here

  • Fictional fixtures
  • Typed transitions
  • Local draft restoration
  • Validation and recovery
  • Focus and announcements

Required in production

  • Trusted authorization
  • Account synchronization
  • Server confirmed writes
  • Signature provider callbacks
  • Conflict resolution
The browser boundaryThe prototype proves client behavior. It does not authorize a reviewer, deliver a signature request, or confirm a production write.

Every action returns to the record

The design defined the return. The implementation protected it.

This prototype does not prove production readiness. It proves that complex mobile workflow behavior can remain explicit, recoverable, perceivable, and testable.

Hiring a design engineer for stateful product work? Send me the role, stack, and interaction challenge.