Assumed
Audio is the primary output, not a fallback. Because a traveller who cannot see the screen gets everything through speech, and the reading is the interface, not a description of it.
Indoor navigation for people who will never look at the screen.

Indoor wayfinding apps are built around a floor plan. You look at a blue dot, you look at a corridor, and you close the gap between them with your eyes. For a blind traveller, the central element of the interface is the one element that carries no information.
The common workaround is to bolt a screen reader onto a visual product. That produces an interface that can be read aloud but was not designed to be heard. Controls are sized for sighted aiming, states are carried only in colour, and the reading order mirrors a layout rather than a task.
I wanted to find out what the product becomes if you start from the other end: assume the screen is never looked at, and treat it as the secondary channel from the first decision onward.
This was secondary research. I read orientation and mobility practice, WCAG 2.1, and the screen reader conventions on iOS and Android, and I audited how existing navigation apps behave with VoiceOver running.
I did not interview blind or low-vision users. That is a real limit and it shapes how much the result is worth. So rather than present assumptions as findings, I wrote them down as assumptions. Each one has the evidence behind it and the test that would prove it wrong. Validation with real users is the next step, not a footnote.
Audio is the primary output, not a fallback. Because a traveller who cannot see the screen gets everything through speech, and the reading is the interface, not a description of it.
Hands are busy. Because a white cane or guide dog occupies one hand, so anything needing two hands or precise aiming fails in the real context.
Emergencies are when the interface matters most. Because disorientation in an unfamiliar building is the failure state this product exists to prevent.


No state lives in colour alone. Every state carries in at least two senses: speech, haptic pattern, sound, and shape. Colour is the fourth copy, never the only one.
The screen is the secondary channel. If the design stops working with the display off, it is wrong. That test killed several layouts.
Help is never more than one action away. Emergency access is a permanent fixture, not a destination you navigate to.
I worked out structure and hierarchy in low fidelity first (390×844 frames, no colour or type decisions), and locked the information architecture before committing to the visual system.

The screens hang off one flow. Onboarding funnels into home, and navigation, look-around, and SOS all hang off the home hub. Help is never more than one action away because the structure says so, not because a button was added.

Onboarding asks two questions and gets out of the way: how you see, and how you want to be spoken to. Both are changeable later, and both can be skipped. A first run should not be a gate.



Home is one large microphone target and four routes into the product. Navigation carries one instruction at a time, large enough to be read by anyone with residual vision and spoken in full to anyone without.



Commands are matched by priority rather than by order. Filler words are stripped before matching, so “um, could you take me to gate twenty-two” and “gate 22” resolve to the same intent, with the destination pulled out as a slot rather than matched against a fixed menu.
Emergency phrases sit in their own tier. They outrank every other command, and they stay live even when the app is not actively listening. This is the one case where I let the product listen past the wake word, because the alternative is a person in trouble having to remember a magic phrase first.
I wrote a test harness of thirteen realistic phrasings. One failed: “what’s around me” broke, because stripping the apostrophe produced “what s around me” and the pattern no longer matched. Matching on “around me” fixed it. Thirteen of thirteen after that.
The grammar exists as a flow, not just as code. Utterances are normalised and matched by priority, and emergency phrases enter at priority 1000, outranking every other command, including active listening.


Destination extracted as a slot. No menu to navigate.
Hands over to scene description without leaving the route.
Outranks everything above it. Works whether or not the app is listening.

#FF8C42 appears in exactly one context across the whole product, and it stays orange whether its tab is selected or not. A colour that only ever means one thing becomes learnable by the people who can see it, and its position becomes learnable by the people who cannot.
Entry is one tap and renders instantly, with no entrance transition. Every other screen in the app animates in over 300ms, and this is the one place where that 300ms is a cost rather than a courtesy.
Exit asks for confirmation. That asymmetry is deliberate. Leaving by accident costs a disoriented person the help they were reaching for, so the way out is the only guarded action in the product.
I set a WCAG AAA target of 7:1 and audited the palette with a script rather than by eye.
| Pairing | Ratio | Rating |
|---|---|---|
| White on background | 18.13 | AAA |
| Success green on card | 8.82 | AAA |
| Accent blue on background | 6.91 | AA |
| Secondary text on card | 6.61 | AA |
The accent blue lands at 6.91 against a 7.00 target. I published the shortfall with a proposed correction rather than nudging the number and calling it AAA. A design system that hides one failure cannot be trusted about the others.
Touch targets are 56dp minimum. This sits above Apple’s 44pt and Material’s 48dp, because a target you cannot aim at by eye needs to be findable by thumb.
Phone haptics cannot vibrate one side of the device, so a left turn and a right turn share a vibration pattern and the direction is carried by speech. I kept the maneuver in the function signature anyway, so the day the hardware supports it, the fix is one implementation and no API change.
The camera, speech synthesis and speech recognition are documented seams rather than finished integrations. They are abstracted behind interfaces with the production swap written down, which is honest about what this is: a designed and built prototype, not a shipped app.
I would have tested with blind users before building the design system, not after. The token layer is sound, but I hardened decisions, the haptic vocabulary in particular, on reasoning rather than evidence. Reasoning is cheaper to change before it is encoded in twenty-six components.
The thing I would keep is the discipline of measuring. Every accessibility claim in this project has a number behind it, and the one number that fell short is stated as plainly as the ones that passed.