Решили: экраны, открытые поверх главного меню (режим, дом, профиль, настройки), кладутся как ScreenKind.Page, а цепочку целиком снимает тот, кто её растил; сеанс владельца открывается перед входом в ЛЮБОЙ режим, а не только в Кампанию.

Почему: прежний путь клал их модалками и прятал панель меню руками — menuPanel.style.display = None перед PushScreen. Отвергнут потому, что не работает по устройству: UiNavigator.SyncVisibility пересчитывает видимость всего стека на каждый Push и Modal «не прячет ничего структурно» — значит следующей же строкой возвращает меню в Flex. Меню воскресало под новым экраном, и оба читались одним слипшимся листом (скриншот Макса 04.08.2026). Page скрывает под собой всё сам, и ручная синхронизация уходит вместе с классом задачи, а не чинится ещё одним флагом.

Второе — сеанс. GameFlow.PlayAsync открывал его только для Кампании, потому что открывал его RequireRun(), а площадке забег не нужен. Но мероприятие рождается ВНУТРИ сеанса: вход в Ристалище и в PvP упирался в SessionHost.CreateChild → null и синий экран. Открывать сеанс на буте (как обещал текст ошибки) нельзя — роль выбирается входом в режим, поэтому сеанс открывает вход, просто теперь всякий.

Сказано: «Когда пытаюсь зайти в ристилище - “[SessionHost] - сеанс не открыт → дочернему скоупу рождаться не от кого.” и синий экран. Наверное с PVP также?» (04.08.2026, сессия 60e7fc08).

Грабли: резолв главного меню снимает ТОЛЬКО экран меню — всё, что лежит выше, переживает его и осталось бы висеть поверх мира весь забег. Прежний код обходился одним Pop(), потому что экран поверх меню был ровно один; с цепочкой «режим → дом» этого хватать перестало. Отсюда список overMenu и CloseOverMenu() в ShowMainMenuAsync: снимает всю цепочку разом, а не верхний лист.

Владелец правды: MenuRouter.ShowMainMenuAsync, MenuRouter.BuildNewGameScreen, GameFlow.PlayAsync, тест SceneWiringTests (разводка UXML новых экранов).