# Navigation and menu audit

Scope:
- **Today (live product).** Every navigation element seen in the thinkrun walkthrough, checked against the page source on `signal-analyst` `origin/main`.
- **Proposed (wireframes).** The four shells (`wireframes/_SHELL-*.md`) and the page-level navigation inside the wireframes.

Checked against:
- NN/g's [17 menu-design guidelines](https://www.nngroup.com/articles/menu-design/), [hidden navigation](https://www.nngroup.com/articles/hamburger-menus/), [mobile discoverability](https://www.nngroup.com/articles/find-navigation-mobile-even-hamburger/), [vertical nav](https://www.nngroup.com/articles/vertical-nav/), [tabs](https://www.nngroup.com/articles/tabs-used-right/), [information scent](https://www.nngroup.com/articles/information-scent/), [footers](https://www.nngroup.com/articles/footers/) and [wizards](https://www.nngroup.com/articles/wizards/).
- Baymard on [enclosed checkout](https://baymard.com/blog/checkout-flow-ux-optimization).
- WCAG 2.4.1, 2.4.5, 3.2.3 and 2.5.8.
- WAI-ARIA [disclosure navigation](https://w3.org/WAI/ARIA/apg/patterns/disclosure/examples/disclosure-navigation).

## Scorecard

✅ meets · 🟡 partly · 🔴 fails · — not applicable

| # | Guideline | Today | Proposed | Notes |
|---|---|---|---|---|
| 1 | Navigation visible on larger screens (NN/g #1) | 🔴 | ✅ | Today only the home page has a nav. Signed-in and operator pages have none. |
| 2 | Menus in expected locations (NN/g #2) | 🟡 | 🟡 | Proposed mobile menus sit top-right and have no label (N-3). |
| 3 | Show the current location (NN/g #5, `aria-current`) | 🔴 | 🟡 | No `aria-current` anywhere today. Wireframes show `▸` but don't specify a non-glyph indicator or `aria-current` (N-1). |
| 4 | Local navigation for related content (NN/g #6) | 🔴 | ✅ | Account and operator areas get shared nav. |
| 5 | Clear, familiar labels, no jargon (NN/g #7, information scent) | 🔴 | 🟡 | Today: "Magic link", "Status", `↗` on internal links. Proposed: "Usage & plan" (N-6) and `›` on links that leave the site (N-5). |
| 6 | Labels easy to scan, key word first (NN/g #8) | 🟡 | ✅ | |
| 7 | Targets big enough (NN/g #11, WCAG 2.5.8 24px min) | 🟡 | 🟡 | Mobile footer and stepper targets aren't sized in the wireframes (N-10). |
| 8 | Click-activated submenus with a caret (NN/g #12, #13) | — | ✅ | Shop switcher and operator menu use `▾`; they must open on click. |
| 9 | No gimmicky patterns (NN/g #17) | ✅ | 🟡 | A `<select>` as the operator mobile nav is non-standard (N-4). |
| 10 | Don't hide main nav when there's room; label hidden menus (NN/g hamburger research) | 🔴 | 🟡 | Today the stepper is removed below 980px. Proposed hamburgers have no label (N-3). |
| 11 | Tabs only for views of the same thing (NN/g tabs) | 🔴 | 🟡 | Today: auth tabs switch between different tasks (fixed in P02/P03). Proposed operator "tabs" are site navigation (N-4). |
| 12 | Enclosed flow with a logo escape hatch (Baymard) | 🟡 | 🟡 | Enclosure ✅ in both. The logo isn't a link today, and the wireframes don't specify where it goes (N-2). |
| 13 | Wizard: steps visible, current shown, order enforced (NN/g wizards) | 🔴 | ✅ | See T-3. |
| 14 | Consistent navigation across a set of pages (WCAG 3.2.3) | 🔴 | 🟡 | Today five operator header labels. Proposed: the account shell has no footer, so Privacy/Terms/Help disappear after setup (N-7). |
| 15 | More than one way to reach a page (WCAG 2.4.5) | 🔴 | ✅ | Today `/mcp/install` can't be reached from any signed-in page. |
| 16 | Skip link and nav landmarks (WCAG 2.4.1) | 🔴 | 🔴 | Today only the home page has a skip link and `<nav>`. The wireframes don't specify either (N-1). |
| 17 | Consistent, discoverable footer (NN/g footers) | 🔴 | 🟡 | See N-7. |
| 18 | Site nav built as links/disclosure, not `role="menu"` (WAI-ARIA) | — | 🔴 | Not specified; add to conventions (N-1). |

## Today: what's wrong

**T-1. Almost no page has navigation, landmarks or a skip link.**
- On `origin/main`, only the home page (`ops/domain-front-door/worker.js`) has a `<nav>` and a "Skip to content" link. The pipeline page also has a `<nav>`.
- Onboarding, Connect Claude, the Claude shop picker, the Slack pages and four of the five operator pages have neither.
- No page sets `aria-current`.

WCAG 2.4.1, NN/g #5.

**T-2. The logo goes nowhere except on the home page.**
In onboarding, `/mcp/install` and every operator page, the logo is plain text, so there's no way home and no escape hatch. NN/g #2, Baymard.

**T-3. The wizard stepper misleads, and disappears on small screens.**
- All four steps are `<button>` elements even when they can't be used (`flow.tsx:278–281`). Signed out, clicking one does nothing (`05_click_plan_signedout.png`).
- `.stepper { display: none }` below **980px** (`flow.tsx:261`) hides progress on phones *and* tablets.
- There's no `aria-current="step"`.

NN/g wizards, NN/g #1 and #5.

**T-4. The public header is missing key destinations, and the arrows mislead.**
- The header has only `How it works` and `Sign in ↗`. There's no Pricing and no Help.
- `↗` on internal links (`Sign in ↗`, `Connect Claude ↗`, `Your account ↗`) signals an external site.

NN/g #7, information scent.

**T-5. There's no navigation after sign-in.**
- The Status page's only controls are Refresh, Manage billing and a **Log out button styled as the primary action**.
- Nothing links to Connect Claude, sources or help.

WCAG 2.4.5, NN/g #1, #6.

**T-6. The operator pages aren't connected to each other.**
- There's no shared nav and `/operations` returns a browser 404.
- The pages use five different header labels: "INTERNAL OPERATIONS", "DATA OPERATIONS", "SLACK THREAD REPLAY", "INTERNAL SOURCE TESTS", or none.

WCAG 3.2.3, NN/g #6.

**T-7. Privacy, Terms and Help can't be reached after the home page.**
No setup, account or operator page has a footer. NN/g footers.

**T-8. The auth "tabs" are really three different tasks.**
- `Sign up · Log in · Magic link` are tabs, but tabs are for alternative views of the same thing.
- "Magic link" is jargon.
- The Claude-return variant hides Sign up, so new users are stuck (`flow.tsx:299`).

NN/g tabs, #7. P02/P03 already fix this.

**T-9. Mobile public navigation is untested.**
The home page blocks framing (`frame-ancestors`), so it couldn't be checked at 390px.

## Proposed wireframes: what still needs fixing

These are gaps in our own shells. They're cheap to fix now, before anyone builds from them.

**N-1. Accessibility rules for navigation are missing from the conventions.** Add to `_CONVENTIONS.md`:
- `<nav aria-label="…">` for every nav block. Use distinct labels when a page has two navs, for example "Main" and "Footer".
- A "Skip to content" link as the first element in every shell.
- `aria-current="page"` on the current nav item, and `aria-current="step"` on the current wizard step.
- The current item must be shown with more than a glyph, for example weight plus a bar. `▸` alone isn't enough.
- Site nav uses links and the disclosure pattern, never `role="menu"` or `menubar`.

(WCAG 2.4.1, WAI-ARIA)

**N-2. Where the logo goes isn't defined.** Proposed rule:
| Shell | Logo links to |
|---|---|
| Public | `/` |
| Setup, signed out | `/` |
| Setup, signed in | Nowhere during steps ①–③ (enclosure). `/account` once setup is complete. |
| Account | `/account` |
| Operator | `/operations` |
| OAuth and Slack minimal frames (E14–E20) | **Not a link.** Leaving mid-consent strands the Claude or Slack flow. |

(Baymard escape hatch, NN/g #2)

**N-3. Mobile hamburgers have no label and sit top-right.**
- NN/g found that hiding navigation roughly halves discoverability. Their fix is to label the icon, and users look top-left for hidden navigation.
- Change `☰` to `☰ Menu` in the public, account and operator mobile headers.
- Public: keep `Sign in` visible outside the menu, next to `[ Connect Claude ]`. There are only four items, so hiding all of them isn't worth it.

**N-4. Operator "tabs" are site navigation, and the mobile version is a `<select>`.**
- Render the six operator destinations as a horizontal nav bar: links, current item underlined, `aria-current`. Don't use a tab look or `role="tablist"` (NN/g tabs).
- A `<select>` that navigates when changed is fragile for keyboard and screen-reader users (WCAG 3.2.2 On Input). Use a disclosure button `Sources ▾` that opens a list of links.
- Tools not enabled on a host are shown greyed with a tooltip, but tooltips don't work on touch. Keep the tab active and let the page explain "Not enabled on this host", or hide the tab.

**N-5. The `›` vs `↗` rule contradicts itself.**
The public shell says "use `›` for internal links, keep `↗` for links that leave the site". But the account shell's `Open Claude ›`, C01's `Open Claude`, and the Slack and Shopify links all leave the site.
- **Rule:** `↗` and a new tab for links that leave signalanalyst.ai (Claude, Slack, Shopify admin, Stripe portal). `›` for everything internal.
- Fix in `_SHELL-account.md`, `C01`, `C07`, `C11` and `P07`.

**N-6. Account nav labels need stronger information scent.**
- `Usage & plan` → **`Plan & billing`**. People look for "billing" to find invoices and payment methods, which live in the Stripe portal behind this page (NN/g information scent). Keep usage as the first section on the page.
- `Team` is P2 and doesn't exist yet. Hide it from the nav until C09 ships, so no nav item leads to an empty page.
- Add `Operations ↗` or `Operations ›` for Signal staff only, mirroring the operator shell's `Customer view ›` (WCAG 2.4.5).

**N-7. The account shell has no footer.**
- Privacy, Terms and support vanish after setup. That breaks consistent navigation across the product (WCAG 3.2.3) and the "help is easy to find" expectation (BFS 4.2.2).
- Add the same one-line footer the setup shell uses: `Help · Privacy · Terms · support address`.
- Apply it to the operator shell too.

**N-8. The setup header doesn't show who is signed in.**
- `Log out ›` with no identity is a problem when password and Google accounts can share an address (E05).
- Show `{email} · Log out ›`. On mobile, show the email inside a small account disclosure.

**N-9. Finished users can land back in the wizard.**
- Specify that `/onboarding` redirects to `/account` once setup is complete.
- The setup shell never shows for a finished account, except to reopen a step from Account › Home.

**N-10. Target sizes aren't specified.**
- The mobile footer (`Help › · Privacy › · Terms ›` on one line) and the desktop stepper labels risk falling under the 24×24px minimum (WCAG 2.5.8).
- Rule: nav targets ≥ 44px tall on touch, footer links stacked or spaced ≥ 24px apart.

**N-11. Shopify embedded app navigation isn't specified.**
- C13 draws only the App Bridge title bar.
- If the embedded app has more than one page, it should use Shopify's app navigation menu (App Bridge nav menu) rather than its own sidebar, so it matches the admin (BFS 3.1.1, Shopify design guidelines).
- If it stays a single page, state that explicitly.

## What's already right in the proposed shells
- The setup shell is **enclosed**: no site nav, only done steps clickable, future steps plain text, mobile `Step n of 4` with a bar (Baymard, NN/g wizards).
- Account uses **left vertical nav**: visible, left-aligned, familiar labels, with a context switcher (shop) at the top and search for more than 7 shops (NN/g vertical nav).
- **One persistent primary action per shell**: `Connect Claude` (public) and `Open Claude` (account).
- **The operator area has a loud environment badge**, and production looks different (environment-indicator practice).
- **Auth tabs are replaced** with a single sign-up view plus links (P02/P03).
- **The public footer** carries Pricing, Help, Privacy and Terms, and shows the contact address as text (NN/g footers).
- **Nested operator pages** (E21) get a back link. The account area is flat, so it doesn't need breadcrumbs.

## Status: N-1 to N-11 applied to the wireframes (2026-09-24)
| Fix | Where it landed |
|---|---|
| N-1 accessibility rules | `_CONVENTIONS.md` › Navigation rules, plus a "Navigation and accessibility" section in all four shells |
| N-2 logo destinations | `_CONVENTIONS.md` table; each shell states its own rule |
| N-3 labelled mobile menus | `☰ Menu` in every mobile header (public, account and operator pages); public mobile keeps `Sign in` and `[ Connect Claude ]` outside the menu; sheets have `✕ Close` |
| N-4 operator nav | `_SHELL-operator.md`: link bar (not tabs) with current-page bar; mobile `<select>` rows removed from all operator pages; disabled tools open a page that explains why |
| N-5 `↗` vs `›` | Rule in `_CONVENTIONS.md`; `Open Claude ↗`, `[ Open Claude ↗ ]`, `( Open Slack ↗ )` across shells and pages (C01, C05–C10, C13, E07, P06, P07) |
| N-6 account labels | `Plan & billing` everywhere (C05 retitled; file name kept so links don't break); `Team` shown only once C09 ships; staff-only `Operations ›` |
| N-7 footers | One-line footer added to the account and operator shells |
| N-8 who's signed in | Setup header `{email} · Log out ›` (shell, P04, P05, C01); mobile `Account ▾` disclosure |
| N-9 finished setup | `/onboarding` → `/account` redirect in conventions and the setup shell |
| N-10 targets | 44px nav targets rule; mobile footers stacked (setup shell, P02, P03, public shell) |
| N-11 Shopify embed | `C13` › Navigation: title bar only while single-page; App Bridge nav menu if it grows |

All wireframe blocks still fit their width limits, box edges line up, and cross-links resolve.

## Fix list (in order)
1. **N-1:** add navigation accessibility rules to `_CONVENTIONS.md`.
2. **N-2:** add the logo-destination table to `_CONVENTIONS.md`.
3. **N-5:** apply the `↗` / `›` rule in `_SHELL-account.md`, C01, C07, C11, P07.
4. **N-7:** add a footer to `_SHELL-account.md` and `_SHELL-operator.md`.
5. **N-4:** redraw operator nav as links, with a disclosure menu on mobile.
6. **N-3:** label the mobile menus `☰ Menu`, and keep `Sign in` visible on public mobile.
7. **N-6:** rename to `Plan & billing`, hide Team until built, add staff-only Operations link.
8. **N-8:** show the signed-in email in the setup header.
9. **N-9:** redirect finished accounts from `/onboarding` to `/account`.
10. **N-10:** add target-size rules.
11. **N-11:** specify Shopify embedded nav in C13.

When the product is built, T-1 to T-8 are fixed by building from the corrected shells. T-3 (stepper hidden below 980px) and T-4 (arrows, missing Pricing/Help) are also quick fixes in today's code.
