The in-app launcher, grouped by what it takes to reach each state.
The most consequential finding is not a missing state — it is that empty is currently expressed three different ways, and only one of them is a component:
| Treatment | Where | Shape |
|---|---|---|
<EmptyState> component | 11 screens — KCM, favorites, jumpseat saved/recent/saved-searches, documents, notifications, policy detail | Icon + title + subtitle, centred |
.alpa-form-empty | Flight Finder results | A single line of text, no icon |
.ftdt-empty | FTDT duty period list | A single line of text, no icon |
The two bespoke ones are not obviously wrong — the Flight Finder one deliberately distinguishes signed out and service failure from genuinely no flights (AB#2319), which the shared component has no vocabulary for. But three treatments means a member meets three different visual languages for the same idea.
| Surface | State | Reachable how |
|---|---|---|
| KCM · airport not found | EmptyState | Route — /kcm/airport/ZZZZ |
| KCM · airlines search no match | EmptyState | Type a non-matching term |
| KCM · home with no menu items | EmptyState | Only if the CMS returns no children |
| Notifications · no flight alerts | EmptyState | Device with no subscriptions and sample fallback off |
| Notifications · flight update not found | EmptyState | Route — stale deep link |
| Notifications · Comms inbox | EmptyState (added) | Member with no Comms items |
| Notifications · Comms filter matches nothing | EmptyState (added) | Filter to an audience with no items |
| Favorites · nothing saved | EmptyState | Signed in, nothing favourited |
| Favorites · failed to load | EmptyState | Favorites service unreachable |
| Jumpseat · saved flights / saved searches / recent | EmptyState ×3 | Device with none |
| Jumpseat · airline policy not found | EmptyState | Route — ?airline=999999 |
| Documents · empty scope / empty category | EmptyState ×2 | Scope or category with nothing published |
| Flight Finder · no results | bespoke | Search matching nothing |
| FTDT · no duty periods | bespoke | Device with none |
Each of these will render a blank area rather than say anything:
| Surface | When it goes blank |
|---|---|
| KCM · airports list | Airports feed returns nothing |
| KCM · policies search | Search matches no airline |
| Jumpseat · airline policies list | Policy list empty |
| My MEC · committees | Any of these four MEC feeds returns nothing — likely for a member whose MEC has not populated that section |
| My MEC · events | |
| My MEC · hotels | |
| My MEC · reps | |
| Member Resources | Resource list empty |
| Notification Settings · subscriptions | Member has no audience subscriptions |
| Search results | Query matches nothing |
EmptyState, or do their extra distinctions (signed
out / service failure / genuinely none) justify staying bespoke? If they should converge,
EmptyState needs a vocabulary for why it is empty.