CloseKnit

thoughtbot · 2021–22

The questions weren’t ours to write, so everything around them was.

Rails, Hotwire and Tailwind · the intake flow for virtual urgent care

Industry: Healthcare Role: Product Designer and Front-End Developer, thoughtbot Duration: 6 months Tools Used: Ruby on Rails, React Native, Hotwire, Figma, HTML, CSS (TailwindCSS), JavaScript Website: closeknithealth.com

Project Brief

Nearly forty per cent of CareFirst’s members had no primary care doctor at all, which is the gap the plan named publicly when it launched CloseKnit. That is not background detail. It describes the person filling out the intake form: no relationship to fall back on, no habit, and nothing to compare the experience against.

I came in through thoughtbot for the web product, after the service had launched on mobile only. What existed was a logo and a set of colors; nearly everything else had been decided one screen at a time. The first surface to build was intake: the one that decides whether somebody becomes a patient or closes the tab.

What we could not change

The clinical questions were not ours to write. They belonged to an external clinician network and could not be altered. The consent, eligibility, and payment gates around them were fixed by law and by contract.

So almost none of the flow’s length was mine to delete. That is the whole constraint, and it is more common than case studies admit: the interesting work in regulated software is rarely the part you are allowed to remove.

Research told us the other half. People wanted a bigger screen for a consultation and would use a desktop if it were offered: seeing the person you are talking to is most of what builds trust in a medical setting, and trust is the thing the whole product is actually selling.

Collage of CloseKnit mobile app screens: home dashboard, urgent care waiting room, and virtual visit summary

The one instrument left

When you cannot change what is asked, you change the conditions under which it is asked. And the one instrument the constraint left completely untouched was order.

Sign-up moved from the first thing you did to something you did only after seeing providers and choosing a time. Providers moved to the front, with faces and names, so you could see who you would be talking to before being asked to hand anything over. The hardest gate, eligibility, was split in two: a cheap question early, the full confirmation late.

None of that changes a single word of the intake. All of it changes who is still there to answer, and how much they have already decided by the time the questions arrive.

Sign-up moved behind the providers and the time slot

Two versions of the same intake flow. In the first, you create an account, agree to terms and prove insurance before you are allowed to see a single provider, and a dashboard sits in the middle with nothing in it. In the second, the landing page collects care type, location and insurer, providers with bios come next, then a time slot, and only then sign-up, terms and a confirmation of the insurance you already gave — with the dashboard at the end, showing the visit you just booked. No gate is removed. Only the order changes.

BeforeAfterLandingTermsInsuranceDashboardemptyServiceProvidersLanding+ insurerProviderswith biosTime slotTermsConfirminsuranceDashboardthe receipt“Users won’t find value in a dashboard at this stage”“New flow benefits both returning and new users”Sign upSign upsign-up moves

No gate is removed. Only the order changes — a face before a form, the hardest gate demoted to a confirmation of something already given, and the dashboard moved to the end, where it becomes the receipt. Drawn as a proposal, not an outcome.

Conditions are components

The rest of the answer was a design system, built in Tailwind, with data capture as its center of gravity. The form primitives are elaborated far more than anything else, because on this product the form is the product. Progress is stated explicitly rather than implied. Label placement was treated as a real decision with named strategies rather than a default, because on a long clinical form, a label’s position is the difference between scanning and re-reading.

Accessibility was part of the same argument, not a pass at the end. I built an extended palette to hold WCAG contrast at every step, because a form somebody must complete to see a doctor is not a place to be relaxed about legibility.

A practice, not an insurer

The identity was drawn deliberately apart from its parent. A humanist serif runs across all six heading levels, with a full serif scale in the body, set against a neutral sans for the working text — an unusual amount of serif for a health product, and the point of it was tone.

An insurer signals contracts. A practice has to signal a person. Those are different promises, and they should not look the same.

Collage of CloseKnit web and mobile screens showing video consultation, mental health intake form, and landing page

We had to deliver it fast, with a small team, against a set of integrations nobody controlled. Prototypes carried most of that weight: they let the people paying for the work use it before it existed, which is the cheapest way to find out an ordering decision is wrong.

Impact and Results

The web product extended CloseKnit past its mobile-only launch: members could now see their providers on a desktop, and work with more than one of them. Because we built the front-end on Hotwire, the Android and iOS teams inherited most of those features without rewriting them.

CloseKnit’s own product manager has said publicly that release speed improved eight to ten times over the first year.

Today you can still browse providers before handing over an email address. That ordering is the product’s front door years later, which I offer as continuity rather than as cause — it also rode a business decision to acquire an in-person practice, which gave the in-person half of the offer something real to point at. Design decisions rarely survive on their own merits alone, and pretending otherwise is how case studies stop being useful.

The identity eventually aged, and I designed its replacement. That is the argument for keeping the brand layer separable from the product in the first place: you should be able to replace one without rebuilding the other.

Most design-system work is repair — arriving after the drift and reconciling what is already there. This was the other half of that skill: being present when the conventions get set, and building the system that prevents the mess instead of the one that cleans it up.