NexLotus Request a briefing

01 / Patient Experiences

Directions for the people who never registered.

A floor plan and turn-by-turn directions that open from one poster QR with no sign-in, in thirteen languages, and stay correct when part of the building stops working.

Entry

One waiting-room QR. No account, no token, no session, ever.

Languages

13, ordered by census prevalence in Ontario, three of them right-to-left.

Third-party requests

None. Self-hosted fonts, strict same-origin CSP, no CDN, no analytics.

The only thing standing between a visitor and the map is a code already printed on the wall next to them.

Scanning the poster opens the app. The link carries the facility join code, so nothing is typed and nothing is remembered. That code is the only gate in the reader experience, and what it gates is narrow: it stops the building's announcement feed becoming a public oracle for what is happening inside the hospital right now.

It is deliberately not a security boundary for anything else. It is printed on a poster, so anyone physically in the room already has it, and that is the point. The people most likely to be lost in a hospital are the ones who never registered anywhere, so wayfinding has to work before and without any registration at all.

The API refuses to boot publicly exposed without a join code and non-default secrets. This is enforced at start-up, not documented as a recommendation. A deployment that skipped it does not come up.

No sign-in

There is no account to create and nothing to remember. Readers have no identity in this system.

No reader tokens

No sessions, no cookies carrying identity, nothing to steal from a phone left on a chair.

One stable code

The poster QR resolves to a public URL that does not change, so the printed poster never goes stale.

Nothing summons anyone

No urgent button, no nurse call, no check-in. The consent screen says so before anything else loads.

Configurable identity

Facility name and site list drive the wordmark, the browser tab and announcement targeting. Renaming a deployment is configuration, not a code change.

Routing

The banner and the directions are not allowed to disagree.

The most damaging failure in hospital wayfinding is not a missing map. It is a map that confidently routes someone through a lift that a sign three metres away says is out of order. Staff publish the notice, and the same action removes the place from routing.

A graph, not a picture

The floor plan is backed by map nodes and edges with a server-side router, not an image with hotspots. Adding a corridor closure changes the route, because the route is computed rather than drawn.

Turn words, not translated sentences

Direction words come from each device's own shipped dictionary. A reader gets "straight ahead, then right" rendered locally. It is never a sentence that had to survive a round trip to a translation provider while somebody stands in a corridor.

Sensitive destinations

Destinations flagged as sensitive are unreachable for every reader in this configuration, because every reader is anonymous. That is the correct outcome, and it is pinned by a test rather than discovered during a pilot.

The same graph answers a second question

Asset Tracking asks it how far away a machine is, so nearest first on the equipment list is ranked on the distances this router computes, past the closures this router already knows about. A route to a defibrillator and a route to Medical Imaging are the same question about the same building, so there is no second router.

No map, no problem

Every other module degrades gracefully with no map data loaded. Directions are simply absent, distances are simply absent, and nothing else breaks.

A notice removing a place from routing A staff member publishes an out-of-service notice for a lift. The same action removes that lift from the routing graph, so the computed route changes to avoid it. Staff console Raise notice · SERVICE_INTERRUPTION Place: Lift B Routing graph Lift B edge suppressed Reader · banner Lift B is out of service Operational information only. This is not an emergency notification system. Reader · directions Take the stairs at the end of the corridor, then turn left. Route recomputed · Lift B avoided
One staff action, two consistent surfaces. The reader is never told to walk to something the building has already announced is closed.

Thirteen languages, ordered by who actually walks through the door.

The registry is ordered by StatsCan 2021 Census prevalence in Ontario, not by what was convenient to add. Arabic, Urdu and Persian get real right-to-left layout driven by the document direction and logical CSS, rather than a mirrored stylesheet.

EnglishEN · verified
FrançaisFR · verified
简体中文ZH-HANS
繁體中文ZH-HANT
हिन्दीHI
EspañolES
ਪੰਜਾਬੀPA
العربيةAR · RTL
ItalianoIT
اردوUR · RTL
தமிழ்TA
TagalogTL
فارسیFA · RTL

Every script self-hosted

Lexend subsets for Latin, plus seven subsetted Noto faces: Simplified and Traditional Han, Arabic, Urdu Nastaliq, Devanagari, Gurmukhi and Tamil. No CDN, strict CSP, font-src 'self'.

Subset to what is actually said

Faces are cut to exactly the codepoints present in the translations, so about 240 KB in total, against roughly 10 MB unsubsetted. A test fails the build if the translations drift from the committed font bytes.

The part unicode-range cannot do

Simplified and Traditional Han share codepoints, and so do Arabic and Urdu. :lang() rules disambiguate them, because a Unicode range alone would render Urdu in an Arabic face and quietly look wrong to everyone who reads it.

English and French are the human-verified source. Every other registered language carries a machine translation of the interface strings behind an explicit auto-translated disclaimer. External machine translation is off by default; the providers that would send text out of the country additionally refuse to boot without a written residency acknowledgement, because a staff-authored announcement is still the hospital's information leaving Canada.

Accessibility

Built for AODA. Not yet attested to it.

Ontario's binding standard for hospital web content is WCAG 2.0 Level AA under the AODA Integrated Accessibility Standards Regulation. 2.1 AA is the internal target: what the project aims at, not what the law requires.

Audited in a real browser, last re-run 7 September 2026. Twenty-one screens across all four apps clear WCAG 2.0 and 2.1 Level A and AA with zero violations, measured in real Chrome against the bundles a deployment actually serves. That change mattered more than it sounds. The suites had run under a renderer that does not lay out or paint, so roughly the most consequential third of the rules had never run at all, and the first real-browser pass found six failures, every one of them a contrast failure. A later pass found seventeen more that had made an earlier "zero violations" untrue.

It is still the project auditing itself. Fifteen results are recorded as needing a human decision rather than counted as passes, no audit with assistive-technology users has been carried out, and the screen-reader script has been walked by the author rather than by somebody who uses one daily. An independent audit is a pre-deployment gate, named as one so a facility plans for it rather than discovering it.

Larger-text toggle

A first-class control in the reader app, not a browser zoom the visitor has to know about.

Language picker

A fully labelled native <select>, chosen over a custom widget precisely because it already works with every assistive technology.

Live regions

ARIA live regions announce a new notice without stealing focus from whatever the reader is doing.

Focus handling

Skip link, visible focus, focus traps in dialogs, and focus restored to where it came from on close.

Direction and language

Per-language lang and dir on the document, so screen readers switch pronunciation and layout flips properly.

Motion and touch

Reduced-motion support, large touch targets, and no hover-only interaction anywhere in the reader app.


The wayfinding floor plan. Rooms are drawn as outlined blocks along corridors, three of them labelled Emergency, Diagnostic Imaging and Information Desk, with a vertical floor switcher down the right edge and level two selected.
The map. The building drawn from its own graph, with no sign-in behind any of it. The destination sheet slides up from the bottom edge.
The reader app with the larger-text setting turned on, showing the same content at an increased type size.
Larger text, on. A control in the app itself, not a browser zoom the visitor has to know about.
The reader app in Urdu, laid out right to left, with an auto-translation disclaimer above the content.
Urdu, right to left. Document direction, a Nastaliq face served from this server, and the disclaimer above the content.

Development build, seeded data, no deployment. These are the captures the accessibility harness took on 2026-08-25, cropped only.

A reader can send exactly one kind of thing, and it is about a place.

From a room or lift's card on the map, and from nowhere else in the app, a reader can report that it is not working, blocked, or wrongly signed. Three of the four choices carry no text at all. The fourth is a short note, capped at 240 characters, encrypted at rest, and refused outright if it contains emergency wording; the reader is shown directions to the desk instead, and nothing is stored.

There is no reply path, no acknowledgement, no severity, and no reader identity attached to it. The shape of the record is the argument: there is nowhere in that table to put a person.

NOT_WORKING

No text sent

BLOCKED

No text sent

WRONG_SIGN

No text sent

OTHER

240 characters, encrypted at rest

Next: what happens when the building has something to say.

Operational Communication is the other half of the reader experience: the closed set of notices a hospital can raise, why three notice kinds were deleted, and the latency the system admits to.