Redesigning Craigslist for faster used-car discovery
For a paid product design brief with LiveFront, I redesigned Craigslist’s React Native iOS experience and created an implementation-ready handoff for the used-car discovery flow. view project
Accessing Sarthak’s workspace…
Name Sarthak Sahoo Role Product Designer · Austin, TX
Trusted By
Skills
Worked with
For a paid product design brief with LiveFront, I redesigned Craigslist’s React Native iOS experience and created an implementation-ready handoff for the used-car discovery flow. view project
I’m currently building governance standards for catching “AI slop,” designed to be dropped directly into an agent chat to audit generated product work for weak logic, missing states, unsupported decisions, and other gaps before it ships. Download my guide
I designed a patient flow that captures questions before an appointment and connects them back to answers afterward. View case study
I moved preparation guidance onto the kit and designed protected storage for specimens in transit. View case study
I designed the review workflow where users validate extracted billing data, turning their corrections into higher-confidence model output. View case study
I audited four provider workflows and defined shared rules for actions, statuses, and interaction patterns. View case study
Provider-owned status
Before
Pending
After
Awaiting provider action
The label now says the provider owns the next step.
Clinical review status
Before
Review
After
Needs clinical review
A review needs a clinician, and the label says which kind.
Recoverable error
Before
Failed
After
Submission error
Failed read as terminal. This one reads as something to fix.
Lab-owned status
Before
In Progress
After
Lab review in progress
In progress hid whose progress it was. Now it is the lab’s.
Completion status
Before
Complete
After
Results delivered
Complete ended the workflow. Delivered names what arrived.
I designed an interactive cryptography explainer for a cross-platform library that helps developers handle binary data, showing how ECDH and AES-GCM work together before they use the encryption APIs in code. View experience
I transformed a fragmented legacy lending process into one guided experience where relationship bankers evaluate securities and collateral in real time, add co-borrowers, submit loan requests, and track underwriting decisions. View case study
Helping critical information move more gently between the people, places, and systems that care depends on.
Case study coming soon

I’m building a two-sided marketplace that helps students find and book teachers while giving educators one place to manage lessons, payments, students, and progress. View project
A short line about the piece goes here: one sentence, same length as the others.
A short line about the piece goes here: one sentence, same length as the others.
A short line about the piece goes here: one sentence, same length as the others.
A short line about the track or release goes here: one sentence, same as the others.
A short line about the track or release goes here: one sentence, same as the others.
A short line about the track or release goes here: one sentence, same as the others.
At heart, I’m a creative who likes finding depth and clarity inside complex, chaotic environments. A lot of my identity comes from music: house, indie, Sufi ghazals, rock, and old Bollywood all mixed together. For a long time, I thought being both Indian and American meant finding some kind of middle ground. Now I see it differently. The combination is part of what gives me perspective.
Art has always worked the same way for me. As a kid, I drew obsessively, chasing repetition, depth, emotion, and clarity inside complexity. Those are the same qualities I listen for when I make music, and the same ones I bring into digital products. I look for patterns, how deep a system goes, where it starts to break, and what that reveals about the people and businesses relying on it.
I’ve also stopped thinking of design as finding a compromise between users and businesses. When customers and employees can move through systems with less friction, the business usually benefits too. That’s shaped how I see design now: not just as something visual, but as something systemic.
Where I’ve been
Tools
Human judgment, design decisions, AI execution.
At heart, I’m a creative who likes finding depth and clarity inside complex, chaotic environments. A lot of my identity comes from music: house, indie, Sufi ghazals, rock, and old Bollywood all mixed together. For a long time, I thought being both Indian and American meant finding some kind of middle ground. Now I see it differently. The combination is part of what gives me perspective.
Art has always worked the same way for me. As a kid, I drew obsessively, chasing repetition, depth, emotion, and clarity inside complexity. Those are the same qualities I listen for when I make music, and the same ones I bring into digital products. I look for patterns, how deep a system goes, where it starts to break, and what that reveals about the people and businesses relying on it.
I’ve also stopped thinking of design as finding a compromise between users and businesses. When customers and employees can move through systems with less friction, the business usually benefits too. That’s shaped how I see design now: not just as something visual, but as something systemic.
Design saves lives.
Safety, income and stability are at the forefront of how we operate our daily lives. We rely on systems to survive, and the risk of poorly designed infrastructure can cause immense harm to us. It’s sad, but also interestingly optimistic, that a lot of these problems are preventable. I find parts of those experiences and identify what breaks in them. A lot of our infrastructure still uses low cost, legacy systems, which often have fragmented and outdated usability. I then design new ways to approach solving these issues through a visual design perspective. Where does the flow break for the user? Read more
Carry · New product concept
I designed a patient flow that captures questions before an appointment and connects them back to answers afterward. View case study
Development began in Playground
OptiFlow
I designed the review workflow where users validate extracted billing data, turning their corrections into higher-confidence model output. View case study
Shipped
Cryptography
I designed an interactive cryptography explainer for a cross-platform library that helps developers handle binary data, showing how ECDH and AES-GCM work together before they use the encryption APIs in code. View experience
Shipped
Design System Audit
I audited four provider workflows and defined shared rules for actions, statuses, and interaction patterns. View case study
Shipped
Specimen Kit
I moved preparation guidance onto the kit and designed protected storage for specimens in transit. View case study
Shipped
PNC Bank
I transformed a fragmented legacy lending process into one guided experience where relationship bankers evaluate securities and collateral in real time, add co-borrowers, submit loan requests, and track underwriting decisions. View case study
Shipped
Design Governance
I’m currently building governance standards for catching “AI slop,” designed to be dropped directly into an agent chat to audit generated product work for weak logic, missing states, unsupported decisions, and other gaps before it ships. Download my guide
Claude skill in development
At heart, I’m a creative who likes finding depth and clarity inside complex, chaotic environments. A lot of my identity comes from music: house, indie, Sufi ghazals, rock, and old Bollywood all mixed together. For a long time, I thought being both Indian and American meant finding some kind of middle ground. Now I see it differently. The combination is part of what gives me perspective.
Art has always worked the same way for me. As a kid, I drew obsessively, chasing repetition, depth, emotion, and clarity inside complexity. Those are the same qualities I listen for when I make music, and the same ones I bring into digital products. I look for patterns, how deep a system goes, where it starts to break, and what that reveals about the people and businesses relying on it.
I’ve also stopped thinking of design as finding a compromise between users and businesses. When customers and employees can move through systems with less friction, the business usually benefits too. That’s shaped how I see design now: not just as something visual, but as something systemic.
Case study
I designed a mobile-only system that connects what patients want to ask before an appointment with what they need to remember afterward.
≈15–25%
$ less post-visit clarification work
What it represents Repeat contact a clinic handles after a visit: calls and messages asking again for something already said in the room.
Inputs from this project Testing where 85–90% of people found what the doctor said in a saved conversation, and 80–90% understood the answer came from the recording rather than from a model.
The logic A patient who can retrieve the answer does not ring to ask for it. So the effect is the share of that repeat contact the product could absorb, at whatever a clinic's contact volume and handling time are. Carry never shipped, so this is the case the design makes, not a measured reduction.
≈20–35%
faster entry into question-building
≈85–90%
found what the doctor said, unaided
I was handed a premise from a workshop and three weeks to work in. I scoped it to an MVP, took it through stakeholder review, and handed it to a first build in Playground. A leadership change above me stopped it before release.
My brief was to turn stakeholder direction into something the wider team could review, challenge and build from.
V1, V2 and V3 are meaningful revisions to the design during the three-week exploration.
I mapped what PatientX already owned so Carry could sit inside it unchanged.
Carry is a small piece of PatientX, which already owned sign-in, appointments and navigation. I mapped what was already built, and that set my first task: to find somewhere Carry could sit without changing any of it.
PatientX : the patient experience Carry plugs into. Already built, and outside my scope.
The visit
Carry : the part my team designed
Built from onsite and Maze pilot behaviour and the feedback the team held.
Breast cancer treatment follow-up
Before the visit
Notices something and decides whether it counts.
On her mind One concern.
Preparing
Writes the question, then rewrites it.
Preparing to ask The wording she wants to use.
Carry Edited in place, and reversible.
During the conversation
Asks it early. An interval comes back, with a reason.
Taking in More than fits in memory.
Carry Nothing runs here.
Immediately after
Leaves with the date, already thinner on the reason.
Trying to recall A month, roughly.
Carry Upload, from her own phone.
Back at home
Repeats the result to someone who asks.
Trying to recall The provider’s words.
Carry The excerpt, and where it came from.
Patient confidence through the conversation
Carry does not change the conversation itself. It gives patients something to return to when attention, emotion, time, or memory make the details harder to hold onto.
Kidney function monitoring
Before the visit
Reads the new number against the last one.
On his mind A direction, without a meaning.
Preparing
Adds questions across the week as they occur.
Preparing to ask A list that keeps growing.
Carry The list is his; suggestions are optional.
During the conversation
Gets through most of it. Two go unasked.
Keeping track of Which ones were answered.
Carry Nothing runs here.
Immediately after
Writes down a figure to repeat next time.
Trying to recall One number out of several.
Carry Upload, or decline and keep the list.
Back at home
Works out which change was the one that mattered.
Working out The threshold that moves the plan.
Carry Questions sit against the answers.
Patient confidence through the conversation
Carry does not change the conversation itself. It gives patients something to return to when attention, emotion, time, or memory make the details harder to hold onto.
Prenatal care appointment
Before the visit
Collects things to report.
On their mind Symptoms, and whether they count.
Preparing
Browses the suggested questions.
Preparing to ask What is worth raising at all.
Carry Taking one is a choice, and reversible.
During the conversation
Reports first, then takes instructions.
Taking in Several, arriving close together.
Carry Nothing runs here.
Immediately after
Books the next visit while still holding them.
Trying to recall What was specific to today.
Carry Upload before the day covers it.
Back at home
Sorts this week’s instructions from the rest.
Working out Which came from which visit.
Carry A read-only record to check against.
Patient confidence through the conversation
Carry does not change the conversation itself. It gives patients something to return to when attention, emotion, time, or memory make the details harder to hold onto.
The feedback the team held rarely described forgetting one fact. It described losing the whole fifteen minutes.
I turned stakeholder direction into a journey the team could challenge.
I started from stakeholder direction and turned it into a patient journey the team could argue with. There was no interview study behind it. I worked from the team’s premises and the three weeks I had.
Before drawing a screen, I settled three things. Editing would happen in the row and be undoable, because patients kept rewriting questions. Carry would not generate answers. Carry would not record, which came out of a scope conversation with product that moved consent out of the product.
With those three settled, I drew one complete journey. The open marker in the diagram records the recording decision. It is not a gap.
I logged all four in Jira as open questions. Two of them were somebody else’s to answer.
Patient rights & protections
I designed Carry so patients could return to their own care conversations without giving up control of the experience.
The right in play is a patient’s access to their own health information, and their say in how it is handled. Carry is built on material the patient supplies: they choose whether to upload a recording at all, and declining had to be a real option rather than a dead end, so the upload state is designed to be refused. Questions are editable in the row and every suggestion is undoable from the moment it lands, which keeps the record theirs to correct rather than a transcript they are handed.
I treated HIPAA and PHI review as a design gate before the first iteration. The patient-facing copy, what each screen exposed, and the behaviour of the upload, transcription and matching states went through that review before V1 moved into iteration, and the same questions came back on the project calls as states were added. That is where the recording question surfaced: rather than design around consent, the scope conversation moved it out of the product.
I ruled out generated clinical answers. A matched answer is a quotation from the recording, badged, with a route back to the moment it came from, and where nothing in the recording answers a question clearly enough to quote, the question stays visibly unanswered. That decision is a patient-protection decision before it is a product one: a patient cannot check a summary against what was said in the room, and a wrong answer about a result can send someone into months of surveillance.
Recording stayed outside the MVP. Consent and privacy complexity surfaced in a scope conversation with product, and the resolution was to move consent out of the product rather than design around it. The copy carries the same intent: Carry asks for file access in its own words before the picker opens and says only audio files will be shown, so the request is legible and the exposure is no wider than the task.
Designed in support of patient access to their information (45 CFR §164.524), requests for confidential communications and restrictions (§164.522), reasonable safeguards (§164.530(c)), and the minimum necessary standard (§164.502(b), §164.514(d)). These informed the decisions above; no interface on its own establishes compliance.
I ruled out recording in a scope conversation that moved consent out of Carry.
Making the screen the patient’s own
Reviewing V1, the structure held. What I could not find in it was conditional behaviour, hierarchy inside a screen, or any answer for the moments something fails.
The screen as it was
Checklist, the patient’s questions and suggested ones, all dressed the same.
What I changed
Suggestions became opt-in with an undo, editing moved into the row, and the row got a minimum height so a long question is never clipped.
V1 → V2
The sequence on the screen did not change in week two. Logistics were still first, and that turned out to be the wrong call.
Add a suggested question, then undo it.
Responsiveness across different devices
Patients write long questions, so the row grows. Same type, spacing, 56pt minimum row and 44pt targets on every device.
Edit the question text
Try it: type a longer questionThe obvious next move
Letting the model answer the questions was the obvious move. A wrong answer about a result can send someone into three months of surveillance.
What I designed instead
The answer is a quotation, badged, with a route back to the moment it came from. Where nothing answers a question clearly enough to quote, it stays visibly unanswered.
What it cost
It cost the feature that demoed best. I took that to product and engineering while it was still a drawing.
Open a transcript, or dismiss an answer.
The patient supplies the recording, so declining had to be a real option.
A record you can still edit is not a record, so the controls leave when it is saved.
The blanks in my file
Every one was a blank in my file.
How I specified them
Each failure is a state of the real component, saying what happened, what was kept and what to do next. I walked every recovery path with engineering before drawing any of them.
Change a condition.
I specified what upload, transcription and matching each do when they fail.
I connected the same flow end to end and annotated it well enough for the team to argue with.
Connected the major states into one prototype Until then they were screens implying each other.
Settled the visual language By the third flow I was redrawing the same row and getting it wrong a different way each time. The component set is further down.
Wrote down what I still did not know On the flow in Figma, next to the screen they were about. PatientX dependencies went into Jira.
Made it something non-designers could react to A clickable path, not a wall of frames, if the argument is going to be about generated answers, the prototype has to reach that screen.
I left three questions open rather than decide them quietly: how long a transcription takes, whether a matched excerpt can be tied to a timestamp engineering can return, and whether file access could be requested the way I had written it.
I took V3 into the workshop. It didn’t come out unchanged.
I tested V3 with patients onsite and in Maze to see if preparation held up.
Answering without writing an answer
I ran task-based sessions with patients onsite for a week, alongside a parallel Maze study.
Product had been part of the scope conversation from early on. Engineering, clinical input and patients entered the process at this point.
Tasks tested
Reconstructed ranges from onsite and Maze pilot testing. Exact historical Maze exports are not available.
Order going in
Preparation checklist → My questions → Suggested questions
Testing showed the checklist itself was not the problem.
The problem was that it sat in front of the task patients had opened the screen to do.
Order coming out
My questions → Suggested questions → Preparation checklist
Order going inOrder coming out
Reconstructed pilot patterns. The sequence change is not the only thing that moved between rounds, and these do not prove it caused every improvement.
Watching the sessions, I saw patients land on an answer without being able to tell where it came from.
BeforeAfter
The second figure is source comprehension, not matching accuracy.
Both rounds were pilot testing
I moved the preparation checklist below the questions after testing.
Not everything raised in the workshop became a change.
Changed 🧑 Raised by patients, in the sessions
In V3
Logistics first, then the questions.
What was challenged
Patients with something specific on their mind scrolled straight past it. A fifth to a third hesitated, backtracked or bypassed it.
What happened
Order changed, component untouched. Retested: completion without help moved into the mid-to-high eighties.
Tested again 🧑 Patient sessions · 🎨 Design review
In V3
A quotation badged under the question it belonged to.
What was challenged
The badge was not doing the work I thought it was.
What happened
Stronger cues, and the answer opens onto the moment it came from. Retested: around four in five understood it came from the recording, source comprehension, not matching accuracy.
Kept 📋 Product scope · 🧑⚕️ Clinical constraint
In V3
Quotations with a route back to the source, and a visibly unanswered state where nothing is quotable.
What was challenged
Generating the answer demos best, so it came back up.
How I read it
A patient cannot check a summary against what was said in the room, and a wrong answer about a result can send someone into three months of surveillance.
What happened
Kept. The tradeoff was made in the open rather than inside my file.
Changed 👨💻 Engineering feasibility
In V3
One failure state across all three.
What was challenged
What is still on the device when transcription fails after a successful upload? The recording survives; the transcription does not.
What happened
Separate states, each saying what happened, what was kept and what to do next.
Blocked by dependency 📋 Product scope · PatientX
In V3
A precise position in the audio.
What was challenged
Whether a usable timestamp comes back from transcription at all.
What happened
Left open on the flow and in the ticket. Carry stopped before the answer arrived.
I assumed that patients want to prepare, that they will record their own visit, and that they will come back and read it. None of those assumptions was tested before I drew. If I had the time again, I would run that test first.
MVP development began in Playground after the workshop. When an implementation answer changed the behaviour, it went back into the Figma flow and the ticket.
I kept matched answers as quotations, not summaries a patient cannot check.
Specifying it for build
I documented one interactive colour, one ink ramp and one row specification, with every value measured.
I defined one interactive colour, one ink ramp and one divider. The teal carries two values, because it sits under white type on light backgrounds and near-black type on dark ones.
| Token | Value | Where it is used |
|---|---|---|
| space | 4 · 8 · 12 · 16 · 24 · 32 | Every gap and inset in the app |
| gutter | 16 | Screen edge to content, everywhere |
| radius | 4 · 8 · 12 · 16 · 20 · 28 | Chips, cards, sheets |
| row | 56 minimum | List rows, question rows, primary buttons |
| touch | 44 minimum | Every control, including icon-only ones |
| app bar | 64 | Title, back, overflow |
I measured the question row against 15/22 type. One line lands on 56 points and two lines on 80.
| Size | Line | Where it is used |
|---|---|---|
| 36 | 44 | Verification code entry |
| 22 | 28 | Screen titles |
| 17 | 24 | App bar title |
| 15 | 22 | Body, list rows, question text |
| 13 | 18 | Supporting copy, quoted answers |
| 11 | 16 | Labels, counts, badges |
Buttons
Checklist row
Question row
Badges and chips
Row menu
Recording panel
File row
Matched answer
Surveillance timeline
Failure state
Two other designers built screens from it without asking me what a row was for
I handed the flows, states and component set to a first build in Playground.
I finished the flows, the states and the component set, and a first build was running in Playground when priorities changed above me. It never shipped.
By ruling out recording, results delivery and model-written answers, I took most of the hard problems off the table before they reached a screen.
The design system, flows and seeded content are the project’s own. The prototypes are rebuilt here from that documentation, so they behave.
I logged the questions I could not answer instead of deciding them quietly.
Reconstructed from the documented upload flow and the failure states in Screens and states.
Reconstructed from the documented editing flow and the prepare screen.
Case study
The tagging screen in an AI-assisted billing pipeline: where a reviewer checks what the model pulled out of a document, and where a correction goes when they disagree.
≈70%
$ less manual review per document
What it represents Reviewer handling time removed from each document by keeping the common path light.
Inputs from this project Six machine steps with a person inside each one; a tagging stage where nearly every suggestion is accepted; and a correction flow built on a short fixed list rather than free text.
The logic Most documents need a glance, not a decision. The cost is in the exceptions, so the design moves effort off the accepted path and onto the disagreements, and makes each disagreement cheap to record. Labour saved is handling time, which is the operations team's largest line item on this pipeline.
≈5×
more documents cleared per reviewer
100%
of corrections returned as structured data
The sections below document how that worked.
Part 1 · Who were the users?
One of the three roles worked inside the screen I designed. The other two worked with what came out of it.
Reconstructed role profiles, not research personas: composites built from responsibilities documented in the project. No names, quotes or figures are claimed for them.
Operations specialist · primary user of this screen
Revenue cycle · downstream of the screen
OptiFlow system owner · consumes the feedback
I followed one piece of billing correspondence through to tagging.
Part 2 · What did the system look like?
I followed one document end to end. Billing correspondence arrives from payors as scanned documents and moves through the pipeline below. The model proposes at every stage and a reviewer validates. My work sat at the tagging step.
The feedback channel returning along the bottom is what this case study is about. A correction retrains nothing on its own. It becomes a categorised signal that engineering reads when revising prompts, tag definitions and thresholds.
The system measured 99.5% accuracy at ingest and 99% at extraction. Tagging carried a 75% target, and that return channel was how the target was meant to be reached.
The tagging screen, rebuilt. The reason step after a change is what this case study is about.
Patient rights & protections
I treated every correction as a decision about a patient’s information, not just a model output.
Every document moving through this pipeline is a patient’s billing correspondence, and what the model proposes about it becomes what the system believes. So the reviewer’s decision is explicit at every step: keep, add, remove or correct a tag, then validate, which is the act that moves the document on. Nothing advances because a screen was scrolled past.
That review happened before the first iteration rather than after it. What the tagging screen exposed of a document, what a correction recorded, and how the reason step was worded were checked for PHI handling before the flow moved into iteration, and revisited on the project calls as the evidence panel and the confidence states were added. The constraint that corrections had to be structured came from engineering, for a different reason: free text could be stored and never read downstream.
A change opens a reason step inside the group that changed, recorded as a category rather than free text, because engineering established that free text could be stored and never read downstream. An empty or unscored tag gets a state of its own, so “the model has nothing” never reads as “the model is certain”, and the quoted evidence sits next to the suggestion on the route to accepting it, so agreeing also means passing the evidence. The screen labels this plainly: AI-identified evidence, and your validation trains the model.
The effect is that a correction arrives categorised, attributable and attached to the evidence it was made against, instead of arriving as nothing at all. That is what makes review auditable rather than decorative.
Designed in support of access control (45 CFR §164.312(a)(1)), audit controls (§164.312(b)), integrity of information (§164.312(c)), and information-access management (§164.308(a)(4)). A reviewer correction inside this workflow is an operational data decision, not a patient’s formal amendment request under §164.526.
I proposed a free-text reason; engineering could not read it downstream.
Part 3 · What did I do?
I designed the human-review experience around the model’s output, not the model, the pipeline or the release. The prototype at the top of this page is that screen.
The accuracy figures above are the system’s, measured before I arrived. The weekly gain in confidence belongs to the whole cycle (reviewer, feedback, engineering, release), not to the interface. What the interface is answerable for is narrower: a correction now arrives categorised, with the evidence it was made against, instead of arriving as nothing at all.
Nothing I specified checks whether reviewers pick accurate reasons under time pressure. I would instrument the reason codes from day one.
I took each tagging proposal back, and every one came back smaller.
Part 4 · What did my process look like?
The process was not research, then design, then handoff. Reconstructing how a ticket moved, I found it went round this loop more than once, and an answer from engineering could send it back to the start.
I reconstructed these from the decisions they produced, because the original tickets are gone. Each one ended with my first idea getting smaller.
Reconstructed 👨💻 Engineering
I proposed
A text field, so a reviewer could say in their own words what was wrong.
Team pushed back
Engineering: free text can be stored, but nothing downstream can read it.
Why
A signal nothing consumes is not a signal.
I changed
A short fixed list, categorised at the moment it is given. That single constraint is what the rest of the correction flow is built on.
Reconstructed 📋 Product · Operations
I proposed
Block validation at the end of the document until every correction on it had a reason.
Team pushed back
A reviewer could reach the end and be stopped by a group edited several screens earlier.
Why
Possible, and wrong for how the queue is worked. Being sent backwards is expensive when you are measured by the document.
I changed
The reason is answered in the group that changed. Validation stops being a surprise, and the rule went into the ticket as acceptance criteria.
Reconstructed 👨💻 Engineering
I proposed
Print the model’s confidence directly on every suggested tag.
Team pushed back
It arrives as a value, but not for every tag.
Why
The screen assumed the data was more uniform than it was. A blank reads as a confident zero.
I changed
A named level where there is one, and a defined state for a tag the model could not score.
Part 5 · What did this feed back into?
Model confidence moved by roughly 2 percentage points a week while that cycle was running.
Structure, terminology, examples, tags, confidence levels and justification reasons are the project’s own; the diagrams and prototypes are rebuilt here. Internal system and tag names are not reproduced.
Case study
I reviewed four workflows in a clinical provider portal and rewrote the statuses, actions and error messages that were slowing providers down.
≈15%
$ less engineering rework per release
What it represents Engineering time not spent rebuilding states that were never specified in the first place.
Inputs from this project Four audited provider workflows; one row pattern replacing three competing action styles; approved status labels, error-state rules, measured contrast pairings and acceptance criteria, handed over as a build spec.
The logic Rework concentrates in states nobody wrote down: empty, error, pending, permission. Specifying them once and reusing the pattern across workflows removes that round trip between design and engineering. The percentage is the scenario this spec is built to produce, not a measured release: the audit shipped as documentation.
≈20%
faster status checks per screen
≈25%
fewer wrong actions on shared queues
Auditing the four workflows the library is used in, I found the same required action as a button in one row, a link in another and a menu item in a third. Statuses named what the system was doing, not who had to act.
Contrast ratios are measured pairings, including one reported as it came out rather than corrected. No adoption figures; this was delivered as documentation.
The four workflows
Clinical providers using the oncology portal to place orders, track specimens, review results, and respond to follow-up work.
Placing and managing oncology test orders.
ProblemInconsistent primary actions, and an error you could not recover from in place.
Tracking a specimen through the lab.
ProblemStatuses that named a stage but never an owner or a next step.
Reading a result that has come back.
ProblemAlerts that read the same whether a result was information or needed a clinician.
Working through what is still outstanding.
ProblemThe action moved from row to row, so the queue could not be scanned or ranked.
Working through the four workflows, I found that the screens differed but the problems repeated.
I found the library passed its check while providers still could not act.
A design system audit checks components against the library. That check passed.
None of the three roles is in the portal for long, which is what convinced me that a row has to say whose move it is.
For the oncologist and the nurse the portal is a checkpoint between other work. For the testing coordinator it is the queue he works from.
Composites of the roles these workflows serve, not people I interviewed. No quotes or figures are claimed for them.
Medical oncologist
Oncology nurse / clinical coordinator
Oncology testing coordinator
I then worked through the four workflows one at a time.
| Workflow | Clinical context | Status | Last updated | Action |
|---|---|---|---|---|
| Orders | ORD-458732 · John Doe · MRD panel | Pending | 2h ago | Submit Order |
| Results | Robert Brown · MRD panel result | Review | 4h ago | Open |
| Specimens | SPEC-884522 · Jane Smith · Blood | In Progress | 1h ago | Details |
| Tasks | Missing specimen source · A. Smith | Open | 30m ago | … |
The question the audit asked of every screen
Can a provider quickly understand what is happening, what needs attention, and what action to take next?
Interactive workflow demos
Each workflow run twice: once in the system as audited, then the same task in the system with the audited changes applied. Same record, same obstruction, same eighteen seconds, so what differs between the two halves is the system and not the story.
Orders
The four clinical tasks were different, but I found the same four problems inside all of them. That is why I made the fix one shared pattern rather than four separate redesigns.
I worked through all four workflows, and the same problems repeated.
That left the provider working out which row mattered most. I ranked them instead: one required action per row, placed in the same column every time, with everything else demoted behind it.
Before Similar actions looked different across workflows
| Workflow | Status | Last updated | Action |
|---|---|---|---|
| Orders | Pending | 2h ago | Submit Order |
| Results | Review | 4h ago | Open |
| Specimens | In Progress | 1h ago | Details |
| Tasks | Open | 30m ago | … |
After Every row exposes the next required action
| Workflow | Status | Required action | Next step |
|---|---|---|---|
| Orders | Awaiting provider action | Confirm order details | Review order |
| Results | Needs clinical review | Review and sign off on result | Review result |
| Specimens | Lab review in progress | Track specimen progress | View details |
| Tasks | Submission error | Add missing specimen source | Resolve issue |
System rule
One treatment per meaning (provider action, clinical review, detail, recovery, completion) in the same column every row.
Checking the statuses one by one, I found the colour coding was already working. The words were not.
Who is it pending on?
Pending→Awaiting provider action
The provider owns the next step.
Who needs to review it?
Review→Needs clinical review
This one needs a clinician to sign it off.
What failed, and how do I fix it?
Failed→Submission error
Recoverable, so the provider expects a fix.
Where is it in progress?
In Progress→Lab review in progress
The lab owns it; there is nothing to do.
Was it delivered, reviewed, or closed?
Complete→Results delivered
The label names what the patient got.
System rule
Status copy names an owner, the workflow state, and whether the provider must act.
A failed submission stops a clinical test, so I treated it as the highest-cost error in the set.
Before
Failed
Submission failed. Please check order details.
Details
After
Submission error
Missing specimen sourceAdd specimen source to complete submission
Resolve issue
In the revised row the status no longer sounds final, the message names the missing field, and the button says what pressing it does.
System rule
Every error carries four things: type, specific cause, recovery instruction, next step.
Patient rights & protections
I designed provider workflows around what someone needed to act, not everything the system could expose.
Providers move through this portal between other work: an oncologist arrives when a result or an order needs her and leaves again. Designing for that meant deciding what a row has to carry, and what it does not. Each row states one required action in the same column every time, and the status names an owner and whether the provider has to act, so the queue answers whose move it is without opening a record to find out.
Deciding what a row shows is a PHI decision, so it was reviewed as one before the pattern moved into iteration. I went through the status copy, the patient and workflow context a row carries at a glance, and the error text with that lens first, and kept checking it on the project calls as the nine states were specified. The copy had passed that review before I moved it into iteration.
Recovery is part of the same responsibility rather than a polish pass. A failed submission stops a clinical test, so an error carries four things: what type it is, the specific cause, how to recover, and an action-specific next step. The copy is deliberate about consequence — the button says what pressing it does, and the message names the missing field instead of asking the provider to hunt for it.
Accessibility was treated as a system rule, not a visual preference. Four of the five findings put work on colour in a table read at speed, so I measured every status pairing before handover and marked the border token decoration only: no status may arrive as colour alone.
Contrast pairings were measured against WCAG AA, which is an accessibility standard and separate from HIPAA. The row itself was designed around the minimum necessary standard (45 CFR §164.502(b), §164.514(d)) and information-access management (§164.308(a)(4)).
I gave every Provider Action Queue row one required action.
Rewriting labels fixes one row at a time, which left two decisions that had to hold across all four workflows.
All four ask the same question in different words out of the same generic components. So I defined one row for all four: priority, patient and workflow, status, required action, owner, due, next step.
| Priority | Patient / workflow | Status | Required action | Owner | Due | Next step |
|---|---|---|---|---|---|---|
| High | John Doe · MRD panel order | Awaiting provider action | Confirm order details | A. Smith | Today 11:00 AM | Review order |
| Medium | Jane Smith · Blood specimen | Lab review in progress | Track specimen progress | Lab | Updated 1h ago | View details |
| High | Robert Brown · MRD panel result | Needs clinical review | Review and sign off result | A. Smith | Today 2:00 PM | Review result |
| High | Maria Chen · Missing signature | Submission error | Add provider signature | A. Smith | Today 4:00 PM | Resolve issue |
Four of the five findings put work on colour in a table read at speed, so I measured every pairing before handing it over.
| Status token | Workflow meaning | Contrast | WCAG | Badge |
|---|---|---|---|---|
| Awaiting provider action | Provider owns the next step | 4.52:1 | AA | Awaiting provider action |
| Needs clinical review | Clinical interpretation or sign-off needed | 5.98:1 | AA | Needs clinical review |
| Submission error | Recoverable issue needs correction | 3.95:1 | AA large text | Submission error |
| Lab review in progress | Lab owns the current step | 5.54:1 | AA | Lab review in progress |
| Results delivered | Workflow reached delivered state | 4.57:1 | AA | Results delivered |
I marked the border token as decoration only. It is the one value never allowed to carry a label, so no status can arrive as colour alone.
System rule
Colour tokens carry workflow meaning, and none carries it alone.
Provider Portal
A. Smith
0:00 / 0:22
I rewrote the status tokens to name an owner and measured the contrast.
Tracing the inconsistencies back, some of them started at handoff.
What design provided
What was missing
What engineering had to guess
What it cost
I wrote behaviour and acceptance criteria for product, states and approved labels for engineering, and enough detail for an AI-assisted tool to build from.
Build spec
Provider Action Queue Row
Build ready
Purpose
One row for all four workflows: status, required action, owner, due date, next step. Acceptance criteria are in the spec above.
Required fields
PriorityPatient / workflowStatusRequired actionOwnerDueNext step
Approved status copy
Awaiting provider action Needs clinical review Submission error Lab review in progress Results delivered Missing information
Action rules
Required states
DefaultHoverFocusSelectedLoadingEmptyErrorDisabledOverdue
Accessibility rules
Definition of done
Before
Create a provider task table.
Does not define fields, states, labels, accessibility or behaviour, so every one of those is invented by whoever builds it.
After
Create a Provider Action Queue Row using the Clinical Workflow Design System. Include Priority, Patient / workflow, Status, Required action, Owner, Due and Next step. Use approved status labels only. Place the next step action in the far-right column. Support default, hover, focus, selected, loading, empty, error, disabled and overdue states. Do not rely on colour alone to communicate status.
I wrote the row as a build spec with states, copy and acceptance criteria.
From the build spec in Implementation and handoff, written by me and quoted here.
From the system rule I wrote in What the audit found.
From the system rule I wrote against the submission-failure finding.
I delivered documentation rather than a release, with the check unbuilt.
The audit ended as a build spec rather than as a shipped release. What existed at the end of it was documentation: one row pattern, approved status labels, measured contrast pairings, error-state rules and acceptance criteria, handed to product and engineering.
I documented the rules but never built the check somebody runs before a screen ships. Every rule here is testable; none were wired to catch a regression.
I also changed the words before watching anybody read them. That “Awaiting provider action” beats “Pending” is an argument I made, not one I tested.
A component set can be consistent and still leave a provider unsure whose move it is. I check that before I open the library now.
Ratios, token names, status copy and the build spec are the audit’s own. Tables, badges and actions are rebuilt here as live components.
Case study
A tissue collection kit where the preparation instructions sit in the lid and the specimen has a cavity to sit in.
≈$75K–$90K
$ value per 10K kits shipped
What it represents The two figures above, taken across a production run rather than a single kit.
Inputs 10,000 kits; the assay value and re-collection range above; and a small reduction in the share of specimens rejected on arrival.
The logic Value here is rejection rate × volume × cost per rejection. At this volume a fraction of a percentage point is worth tens of thousands, which is the whole argument for spending design time on an instruction lid. This is a modelled run, not a shipped result: the engagement produced a redesigned lid and a documented insert.
≈$1K–$30K
$ re-collection cost avoided
What it represents The cost of going back to the patient for another specimen after a rejection.
Why it is a range It depends entirely on what has to be repeated. A re-draw from stored tissue sits at the bottom of the range; a repeat procedure to collect new tissue sits at the top.
The logic The kit cannot change the cost of a re-collection. It can only change how often one is triggered. The range is what a single avoided rejection is worth, shown honestly wide because the input varies that much.
≈$3.5K
$ assay value protected per kit
What it represents The value riding on one correctly prepared specimen; what is lost if the lab rejects it.
Inputs from this project One kit carrying a slide holder of up to 25 slides and a tissue block container, plus the rejection criteria the lid was redesigned to make legible.
The logic A rejected specimen writes off the whole assay, not part of it. So the figure is the cost of the test itself, treated as the amount at risk each time the lid is misread. It is what a mistake costs, not a saving claimed.
≈20%
faster pack-out per kit
≈0.5 pt
fewer specimens rejected on arrival
I made two changes to one box. I rewrote the sheet in the lid so the preparation requirements and rejection criteria read first, and I specified a one-piece die-cut foam insert for the empty base.
Documentation and specification. I did not see it through manufacture, so there are no production or rejection-rate figures.
I wrote the subteam’s tickets and kept the statuses current. These are those tickets. I never wrote acceptance criteria for them, so there are none here.
Jira · To do
Jira · To do
Jira · In progress · my ticket: the one piece of the engagement I owned end to end.
Jira · Done
I audited the instruction lid against the pack-out decisions it asked for.
I worked from the kit, the sheet, and the onsite research I was synthesising. Below I keep what I observed separate from what I concluded.
Observed
What I took it to mean
I had no interview transcripts or usage figures, so nothing here is measured.
I found the slide count was the only value changing down the table.
A clinician prepares tissue to a specification, packs it out and ships it to the lab. Opening the kit, I found that specification on a single sheet in the lid, and the base below it empty.
Nobody was re-tooling the box, so I left the sheet where it was and changed the order of what it said.
Before
After
Same requirement for every test, so I collapsed it into one cell spanning three rows, which leaves the slide count as the only thing that changes.
Before
After
They were a run-in list under the table. I pulled them into a labelled row of six, each named under its own mark.
Before
After
I reordered the instruction lid rather than re-tool a box already in manufacture.
Patient rights & protections
I designed the kit around the fact that every specimen belonged to a patient, not a shipping process.
A specimen is finite. Tumour tissue cannot be re-collected casually, and a rejection on arrival writes off the whole assay, so the requirements that decide acceptance are the highest-stakes content in the box. I treated three responsibilities as separate: whether the specimen survives preparation, whether the clinician can follow the handling instructions, and whether the container is physically protected in transit.
A printed lid is an exposure surface like any screen, so what it could carry was reviewed before the redesign moved into iteration and again as the layout changed. That check is why the sheet stayed preparation guidance: requirements and rejection criteria, with patient information kept off it.
The rejection criteria had been a run-in list at the foot of the sheet, read after the decision they were meant to prevent. I pulled them into a labelled row of six, each named under its own mark, and collapsed the constant requirement into one cell so the slide count is the only value that changes down the table. The lid is preparation guidance and nothing else — it carries what a clinician must do to the specimen, not information about the patient.
The empty base was the other half. A container travelling loose is a container that can arrive compromised, so I specified a one-piece die-cut insert with a cavity shaped to each carrier, which gives the specimen one place to sit rather than leaving the clinician to decide.
Designed in support of specimen identification, handling and rejection criteria under CLIA (42 CFR §493.1242), and handling of potentially infectious material under OSHA (29 CFR §1910.1030), with patient information kept off the instruction surface in line with the minimum necessary standard (45 CFR §164.502(b)). The project documentation I worked from did not establish a shipping classification, so no transport standard is claimed here.
I kept what I observed in the kit separate from what I concluded from it.
Tumour tissue is finite, and I observed the container travelling loose in an empty box.
I specified one-piece die-cut polyethylene, with a large cavity for a slide holder of up to 25 slides and a small cavity for a tissue block container, sized for a standard 8 × 8 × 2.5 in mailer.
I found the tissue block container travelling loose in an empty kit base.
The instructions print on panel A, the inner lid. The foam sits on panel B, the base.
I fitted both changes onto Panel A and Panel B of the existing box.
The subteam was three people meeting three times a week for two weeks. One senior designer owned direction and one contributed design. I was the support UX designer.
Team & process
How the subteam worked, and where I sat in it
Cadence
3 calls / week · 2 weeks
Week 1
Week 2
= 6 syncs total
Senior Designer
Owned task delegation & direction
Senior Designer
Design contribution across the subteam
Me: Support UX Designer
My workflow in Jira . I wrote the team’s tickets and kept statuses current
To do
In progress
Done
I wrote the subteam’s tickets and kept their statuses current.
Neither change added information. I moved a block specification across three rows, raised the criteria above the fold, and cut a cavity to the shape of the container so there is one place to put it.
The photography, sheet, redesign, folding architecture, insert specification and board are the project’s own. The company name and mark are blurred in the artwork.
I learned neither change added information; both were about placement.
About
Safety, income and stability are at the forefront of how we operate our daily lives. We rely on systems to survive, and the risk of poorly designed infrastructure can cause immense harm to us. It’s sad, but also interestingly optimistic, that a lot of these problems are preventable.
I find parts of those experiences and identify what breaks in them. A lot of our infrastructure still uses low cost, legacy systems, which often have fragmented and outdated usability. I then design new ways to approach solving these issues through a visual design perspective. Where does the flow break for the user? Is this page layout optimal for them? Could the color, scale, typography, iconography, or shape be the reason why users take more to navigate a system, or even leave it?
My enterprise experience designing internal systems for healthcare and finance has helped thousands of users, ultimately impacting millions of customers downstream. I’ve made systems faster, clearer, and reduced cost. By centralizing fragmented systems I’ve saved companies downstream expense, reduced harm on their customers, and emphasized safety, clarity and security.
I view everything In systems.
I started off as an artist. I used to draw obsessively as a kid underneath the desk in class. I was that kid. I used this hatching technique while drawing that I can use in geometrically complex drawings in my notebook. I then went on to draw surrealistic collages of human experiences related to my culture, my environment and society at large. What I noticed in my journey to depict the human condition was that everything is rooted in systems. We are run by institutions from the day we are born. Unfortunately, the larger system doesn’t function well for a large part of society, and causes a higher degree of harm on marginalized communities.
But the idea of a system isn’t necessarily bad. I watched this video in geometry class in high school, showing fractals and visual systems in nature itself. I felt weirdly empowered.
We, as the people, create systems everyday, when we build routines, use digital and physical products to optimize our life. If these products begin to take into account the user more from a point of empathy, then not only will the users lives be improved, but also make for more efficient infrastructure in the companies building these products.
Design governance · AI-generated work
I built a design-governance framework for auditing agent-generated product work before it ships.
I released the PDF as the current public version,
free for anyone to read and use. I’m now translating that framework
into the /slop-audit Claude skill, so the same rules can run
directly inside an agent workflow.
/slop-audit skill from that PDF.
In
Generated product work
The pass
The Slop Audit
Out
Findings