Mobile App · iOS · Android · Healthcare Operations

Clinician App

A mobile companion for shifts, time tracking, and on-the-go scheduling

Clinician App — Hi Julia home screen

A pocket tool for the people who keep the clinic running

Dental practice staff — assistants, hygienists, front-desk, and rotating clinicians — were tracking shifts, hours, and check-ins on paper or via the desktop practice management software. Neither worked on the move. The Clinician App was designed as a mobile-first companion: open it before a shift, glance at the week, check in, log overtime, get back to work.

Core surfaces

One-tap actions, calm visuals, no clinical clutter.

My calendars — tracked vs. planned hours

My calendars · hours tracked

Check-in — daily working time, status, timer

Check-in · daily timer

My shifts — weekly schedule with shift codes

My shifts · week view

Auth flow

Forgot password — three taps, no friction.

Forgot password — email entered

Email entered

Forgot password — sent confirmation

Confirmation sent · live

Accessibility · WCAG 2.2 AA

Accessibility is a step in the process, not a retrofit — every screen gets a WCAG 2.2 AA pass before it ships.

The pass runs across the app's core surfaces — calendar, check-in and check-out, day logs, shifts — as a structured screen review with contrast ratios measured pixel by pixel against the WCAG relative-luminance formula rather than judged by eye. Working with Claude makes that measurement fast enough to do on every screen instead of spot-checking a few. It catches what static review can catch: colour, labelling, text alternatives, target sizes, reflow. What it cannot reach — real VoiceOver and TalkBack behaviour, focus order, hit areas as built in code, Dynamic Type on device — is a separate pass on hardware, and naming that boundary is part of the method rather than a footnote to it.

9

Issues caught pre-launch

2

Critical

4

Major

3

Minor

3

Patterns already right

Measured

Every colour pair measured, not eyeballed.

Element Colours Ratio AA Verdict
White text on dark-green chips and buttons #FFFFFF#00624F 7.3:1 4.5:1 Pass
Blue text on pale blue — info banner, “Planned” chip #00588F#E3EFF5 6.4:1 4.5:1 Pass
Green “Checked-in” status on white #007E3C#FFFFFF 5.2:1 4.5:1 Pass
Bottom-nav labels and icons #00624F#FFFFFF 7.3:1 4.5:1 Pass
Shift cards — purple on pink, blue on lavender
#7B2D8E#F6E7F8
#3D4FA0#E8EAF8
6.3:1
8.3:1
4.5:1 Pass
Orange “Checked-out” status
#B45309#FFFFFF
#B45309#F5F5F5
4.6–4.9:1
4.3–4.5:1
4.5:1 Borderline
Out-of-month and future dates
#9E9E9E#FFFFFF
#D6D6D6#FFFFFF
2.7:1
1.5:1
4.5:1 Fail

WCAG exempts genuinely disabled controls from contrast requirements — but these date cells are bordered and shaped exactly like the active ones, so they read as tappable. An exemption you have to explain to the user is not an exemption. Either the cell stops looking interactive, or it meets contrast.

Findings

Ranked by who they lock out, not by how hard they are to fix.

Critical

Log-source icons carry meaning with no text alternativePerson, phone and gear icons are the only thing distinguishing manual, mobile and automatic entries — invisible to a screen reader. The 23:59 gear marks an automatic check-out, which is payroll-relevant.

1.1.1 · 4.1.2
Critical

Cancelled entries are conveyed by strikethrough aloneScreen readers do not announce strikethrough. A cancelled 11:30 check-in is read out as an ordinary one — the record sounds different from how it looks.

1.3.1
Major

Status orange is borderline on tinted rowsIt clears 4.5:1 on white but drops to roughly 4.3:1 on the grey alternating rows, where it is used most.

1.4.3
Major

Untracked dates fail contrast while looking interactiveAt 1.5:1 the numerals are barely visible, and the card border invites a tap that does nothing.

1.4.3 · 1.4.11
Major

Shift labels truncate at default text size“10.30-12:00 (1h30” and “13:00-17:30 (4h 3” are clipped before anyone changes a setting. At 200% Dynamic Type the card has nothing left to give.

1.4.4 · 1.4.10
Major

Notification dots carry state through colour aloneThe red dots on Tasks and Profile have no count and no accessible label — nothing announces that anything is waiting.

1.4.1 · 1.1.1
Minor

Touch targets under 44 ptThe month chevrons and the bottom-sheet drag handle are sized to their glyphs rather than to a thumb.

2.5.8
Minor

The live timer ticks every secondExposed as a live region it would interrupt VoiceOver once a second, which makes the rest of the screen unusable.

4.1.3 · 2.2.2
Minor

Copy that contradicts itself“Working time left: −7h 59m” is a negative amount of something remaining. Vacation is marked with a bare 🏝 emoji, and the same day appears as both “10.30” and “10:30”, “Checked-In” and “Checked-in”.

3.1.5

Confirmed

Three patterns the review confirmed were already right.

Colour is never alone on the calendarThe legend pairs every colour with a symbol — plus, minus, tick, warning — so status survives without colour vision.
The donut states its own value“89%” is written in the centre, so the chart is not the only way to read the number.
Status is written, not just tinted“Checked-in” and “Checked-out” appear as words, not as green and orange alone.

Before / after

Each screen reworked against the findings — first pass on the left, corrected design on the right.

01

Day logs — source, cancellation, plain totals

Day logs, first pass — source shown only by icon, cancelled entry shown only by strikethrough
Before · first pass
Day logs after — each row names its source in text and cancelled entries carry a Cancelled tag
After · corrected
The source is written downIcons keep their place but no longer carry the meaning alone — every row names itself: “Manual entry”, “Mobile app”, “Automatic — by system”.1.1.1 · 4.1.2
Cancelled becomes a tagThe strikethrough stays as a visual cue, but the meaning now lives in a “Cancelled” tag that a screen reader can announce.1.3.1
A darker status orange#B45309 becomes #9A4207 — about 6:1, which holds on white and on the tinted rows alike.1.4.3
Totals in plain language“Working time left +40m” becomes “Balance — 40m over target”, and time formats are unified to hh:mm throughout.3.1.5
02

Calendar — inert dates, real badges, thumb-sized controls

Calendar, first pass — pale untracked dates that still look tappable, colour-only notification dots
Before · first pass
Calendar after — untracked dates styled as inert, numeric badges on the tab bar
After · corrected
Untracked dates read as inertThe card border and fill come off and the numeral lifts from #D6D6D6 to #6B675F, about 5.6:1. A card now means there is something to open.1.4.3 · 1.4.11
Badges carry a countThe bare red dots become numbers with labels — “Tasks, 2 new” — and disappear entirely at zero.1.4.1 · 1.1.1
44 pt month controlsThe chevrons keep their small glyph inside a 44×44 target, and the month label becomes a button in its own right.2.5.8
Vacation gets a nameThe 🏝 emoji is replaced by “Paid vac.”, read out in full as “Paid vacation”, with a legend line explaining the greyed dates.1.1.1
03

Shifts — truncation, and what happens at 200%

Shifts, first pass — shift times clipped mid-label at default text size
Before · clipped
Shifts after — time, duration and site stacked on separate lines
After · default size
Shifts after at 200% Dynamic Type — week collapses to a single day column with paging
After · Dynamic Type 200%
Nothing truncatesTime, duration and site stack on three lines instead of one clipped line — “10.30-12:00 (1h30” becomes “10:30–12:00 / 1h 30m / BHZ1”.1.4.4 · 1.4.10
Reflow instead of shrinkAbove about 150% the three-column week collapses to a single day column with paging, so cards grow rather than squeeze to nothing.1.4.10
Site colour is never aloneA swatch plus the code — BHZ1, BHZ7 — and the card border repeats the hue for low-vision users.1.4.1
Empty days say why“⊘ No Shifts” becomes a dashed, clearly non-interactive “No shifts planned” panel, so nobody taps a dead end.1.3.1
04

Check-in — a quiet timer and honest copy

Check-in, first pass — Working time left minus 7h 59m, icon-only play button
Before · first pass
Check-in after — Remaining today 7h 49m, labelled check-in button, status explained in text
After · corrected
No negative time remaining“Working time left −7h 59m” becomes “Remaining today 7h 49m”, and days over target read “40m over target”.3.1.5
A timer that stops talkingThe seconds counter renders with aria-live="off" and a static summary — “Checked in since 08:00” — that VoiceOver reads once.4.1.3 · 2.2.2
The button says what it doesThe play and stop glyphs get a permanent visible label, so state is not carried by shape and colour alone.1.4.1 · 4.1.2
One date format“02.02.2022 - Wednesday” becomes “Wed 2 Feb 2022”, which cannot be misread between locales.3.1.5

Other projects.

All projects ↗