Working prototype · commercial real estate search

What Happens When Search Doesn't Go as Planned

Every search box has a happy path — you type something, you get good results, everyone's happy. This is a working prototype of commercial real estate search built around the other path: the one where results come back empty, a listing you're looking at goes under contract mid-scroll, or a filter stops making sense because you switched from buying to leasing. Real apps hit dozens of these moments. Here are eight of them, built as functioning interface — not described in a deck, but actually clickable, keyboard-navigable, and readable by a screen reader. All listings are invented sample data.

Search / prototype
/ to search · ↓ into results
Property type
Price ceiling
Up to$40.0M
Minimum cap rate
At least0.0%
Map area

Search results

Sorted by relevance

This list works from the keyboard. Press ↓ to step through the results — the console at the bottom of the page shows what a screen reader hears as you go.

The eight states

Four of these you can reach by using the filters above the way a broker would. Four cannot be triggered on demand in a prototype — a listing does not go under contract because you asked it to — so they are here as switches. Each one is designed, not defaulted.

What a screen reader hears

You cannot evaluate a keyboard and screen-reader experience by looking at it. So this logs it: every live-region announcement and every programmatic focus move, as it happens. Tab into the results and use the arrow keys.

  1. Nothing announced yet. Use the filters, or press Tab then the arrow keys inside the results list.

Design decisions

Why the empty state names the constraint

“No results” tells a broker nothing they did not already know. The prototype computes which single filter is responsible for the emptiness, says so, and offers the relaxation with the resulting count attached — so the next click is a decision rather than a guess.

Why nothing here disappears

A listing that goes under contract mid-session is not removed. Removal makes a person doubt their own memory. It stays, marked, in position, and the count explains the change.

Why gated fields keep their shape

Hiding a restricted rent roll behind a blank space asks the user to guess whether data exists. Showing the field names, the row count, and a redacted value shape tells them exactly what verification buys.

Why the cap-rate filter switches itself off

Cap rate is a sale metric. Switch to For Lease and it has nothing to describe, so the control disables itself and says why. A filter that stays enabled while it can never match anything is a trap dressed as an option.

Why the map failing is not the page failing

Tile failure degrades to a list that still filters, sorts and opens. The retry restores the map without discarding a single filter — losing a broker’s query to a network blip is a design decision, not an accident.

Type floor, and what has actually been tested

Nothing on this page is set below 0.875 rem. WCAG specifies no minimum type size at all, so that is a house standard sitting above the spec: hierarchy here comes from weight, case, tracking and colour rather than from shrinking the secondary text until it is deniable. axe-core, WCAG 2.1 A and AA rule sets, run against all eight states: zero violations. Reflow holds at a 320 px viewport, and the 1.4.12 text-spacing override introduces no horizontal scroll. That is a floor, not a certificate — automated tooling catches perhaps a third of real accessibility problems, and no manual screen-reader pass has been run on this prototype. The one remaining “incomplete” is axe declining to judge the contrast of a glyph-only key hint. Treating an automated pass as conformance is the habit this page exists to argue against.

Sample data is invented; addresses, prices and cap rates are not real listings and no Crexi data was used. Built as an independent prototype by Kayhan Atamyildiz to demonstrate edge-case and accessibility practice — keyboard model, ARIA roles, live regions, focus management and reduced-motion support are implemented, not simulated.