Личный кабинет в правом верхнем углу top-bar (gendsgn.ru + /trade-in/).
Компонент:
- Avatar 32×32 (первая буква username в круге, `var(--accent-soft)` фон,
`var(--accent)` text)
- Dropdown по клику: username, role badge («Админ» / «Пилот»),
кнопка «Выйти» (text-only, `var(--danger)`)
- Закрытие по Escape, click-outside; focus возвращается на avatar
- `aria-label="Личный кабинет"`, `role="menu"`, `role="menuitem"`
Logout flow (basic_auth quirk):
1. Fetch `/api/v1/me` (через `API_BASE_URL` чтобы single source of truth
с `apiFetchWithStatus`) с явно invalid Basic creds `logout:logout`
→ 401 от Caddy → браузер очищает cached basic_auth для origin
2. `window.location.href = "/"` — hard reload, новый basic_auth prompt
Integration:
- Main `frontend/`: `<UserMenu />` в `<TopNav rightSlot>`. Pricing CTA
(`PilotRequestModal` trigger) на странице остался — не дублировался
в TopNav.
- Tradein `frontend/`: `<UserMenu />` в конце `.top-nav` в `Topbar.tsx`
(после tabs). MIRROR с inline LogOut SVG (нет lucide-react dep) +
`API_BASE_URL` import для logout fetch (consistency с rest of tradein).
Manual smoke план (post-deploy):
- Safari incognito → admintest → авitar «A» + role «Админ»
- Click «Выйти» → basic_auth prompt появляется снова
- Same в Chrome / Firefox (cross-browser logout reliability см. PR review)
Code-reviewer LGTM (1 critical fixed inline — tradein logout fetch
теперь использует `API_BASE_URL` вместо `process.env.NEXT_PUBLIC_BASE_PATH`).