docs(портал-мобилка): спека адаптива основного портала под телефон и планшет + аудит реальных экранов

Брейншторм с владельцем 07.07. Рамки: основной портал 9 экранов, телефон+планшет,
премиум-уровень, мобилка урезанная / десктоп полный. Подход А — сначала каркас, потом экраны.
Меню на телефоне: Поле, Проекты, Сделки, Биллинг, Канбан. База — ветка с «Полем» вне main.
Аудит: 4 реальных архетипа поломки сняты локально на 390px [findings/2026-07-07-portal-mobile-audit].

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Дмитрий
2026-07-07 16:49:54 +03:00
parent 590849391d
commit 29660698b1
6 changed files with 138 additions and 0 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

@@ -0,0 +1,138 @@
# Дизайн: адаптив основного портала под телефон и планшет
**Дата:** 07.07.2026
**Автор:** сессия Claude (брейншторм с владельцем)
**Статус:** черновик на утверждение
**Экраны-аудит (реальные, сняты локально на 390px):** [findings/2026-07-07-portal-mobile-audit/](../findings/2026-07-07-portal-mobile-audit/)
---
## 0. Одной фразой
Сделать основной клиентский портал (layout `app`, ~9 экранов) удобным на телефоне и планшете
на **премиум-уровне**, не сломав десктоп. Мобильная версия — намеренно **урезанная**
(только главное под палец); полная функциональность остаётся на компьютере.
## 1. Рамки (утверждено владельцем 07.07)
| Вопрос | Решение |
|---|---|
| Что адаптируем | **Только основной портал** (layout `app`). Кабинет продаж и админка — отдельно, позже. |
| Устройства | **Телефон (главное) + планшет заодно.** |
| Глубина | **Премиум** — карточки вместо таблиц, нижнее меню-вкладки, крупные тач-цели. |
| Подход | **А — сначала общий каркас, потом экраны по одному** (катим по частям). |
| Принцип | **Мобилка = урезанная, десктоп = полная.** На каждом экране явно решаем, что показываем на телефоне. |
### Не в этой работе (out of scope)
- Кабинет продаж (`/sales/*`), админка (`/admin/*`) — отдельные проекты.
- Изменения бэкенда/API/схемы БД — **только фронт (Vue/Vuetify + CSS)**.
- Новые фичи — нет; только адаптация существующих экранов.
## 2. Реальность «как есть» (по локальному прогону, не по памяти)
Портал сейчас **100% «настольный»** — во всём фронте `useDisplay`/breakpoints **не используются
нигде** (0 файлов). Корневая поломка на телефоне (см. снимки-аудит):
- **Меню слева не сворачивается.** `AppLayout.vue`: `.app-main { padding-left: 232px }` — жёстко,
без условий. `AppSidebar.vue`: кастомный `<aside class="ld-sidebar">` `position:fixed; width:232px;
z-index:1006`, `drawerOpen` по умолчанию `true`. На 390px тёмное меню занимает ~40% ширины,
контент втиснут в остаток и **обрезан по правому краю** (аватар, кнопка «Период», «пополнить» — за экраном).
- **Гамбургер-обрубок.** `AppTopbar.vue` имеет `<v-app-bar-nav-icon class="d-md-none">` (появляется на
телефоне), но меню под телефон не переделано и `padding-left` не снимается.
- **Тяжёлые места (реальные):**
- **Широкие таблицы `v-data-table`** — в основном портале: `DealsTable.vue` (колонки: Телефон,
Источник, Город, Статус, Комментарий, Поставлен), `TransactionsTable.vue`, `ChargesTab.vue`.
На телефоне уезжают в горизонтальный скролл, колонки обрезаются.
- **Канбан** (`KanbanView.vue`) — колонки-этапы с перетаскиванием; на телефоне влезает 1 колонка,
остальное — горизонтальным скроллом; drag пальцем неудобен.
- **Дашборд** — KPI-плитки + графики; стекается вертикально, но зажат меню и обрезан.
- **Конкурентное поле** (`/autopodbor`) — уже карточками (деградирует лучше), но так же зажато меню.
- **Плюс:** меню и топбар — **общие компоненты** (`components/layout/AppSidebar.vue`,
`AppTopbar.vue`). Починка каркаса чинит сразу все экраны.
## 3. Каркас размеров (breakpoints)
Три яруса (на базе Vuetify `useDisplay`):
| Ярус | Ширина | Меню | Контент |
|---|---|---|---|
| **Телефон** | `< 600px` (xs) | **Нижняя панель-вкладки** (5 шт.) + топбар с «Ещё» | 1 колонка, карточки, `padding-left:0` |
| **Планшет** | `6001279px` (smmd) | **Узкая колонка-иконки (rail)**, сворачиваемая | 1–2 колонки |
| **Десктоп** | `≥ 1280px` (lg+) | **Как сейчас** (полный `ld-sidebar` 232px) | без изменений |
`.app-main { padding-left }` привязать к ярусу: 232px только на десктопе, rail-ширина на планшете, 0 на телефоне.
## 4. Мобильная навигация
### 4.1. Нижняя панель-вкладки (телефон)
5 вкладок (утверждено владельцем): **Поле · Проекты · Сделки · Биллинг · Канбан**.
Иконки Lucide, активная — тил (`--liderra-teal`), тап-цель ≥ 56px высотой, `safe-area-inset-bottom`.
### 4.2. Остальные экраны (Дашборд, Отчёты, Настройки, Импорт, Помощь)
Нижняя панель вмещает только 5 — остальное доступно через **топбар**: кнопка-меню (или аватар)
открывает выезжающий список (`v-navigation-drawer temporary`) со всеми разделами и профилем/выходом.
Дашборд остаётся стартовой при заходе (редирект `/``/dashboard` не трогаем).
> ⚠️ **Открытый пункт на согласование:** Дашборд — очень частый экран, но в 5 вкладок владелец его
> не включил. Вариант: оставить как в списке (Дашборд — в «Ещё»/топбаре), либо заменить одну из
> вкладок. Решаем на этапе каркаса, увидев вживую.
### 4.3. Планшет
`ld-sidebar` в режиме **rail** (только иконки, ~64px), тап по иконке — разворот/переход. Тот же
`navGroups`, что и на десктопе.
## 5. Один приём на все таблицы
Переиспользуемая обёртка (напр. `ResponsiveTable.vue` / composable): на десктопе+планшете — обычный
`v-data-table`; на телефоне (`xs`) — **список карточек** из тех же данных. Одна карточка = строка:
крупное главное поле (Телефон), статус-плашка, вторичные поля, действия под палец. Чинит `DealsTable`,
`TransactionsTable`, `ChargesTab` и таблицы админки (когда дойдём) единым инструментом.
## 6. План по экранам (этапы)
**Этап 1 — каркас + самое ходовое:**
1. Breakpoint-каркас + мобильное меню (нижние вкладки + rail + топбар-drawer) + снятие `padding-left`.
2. **Дашборд** — плитки/графики в один столбик, графики на всю ширину.
3. **Сделки** — таблица → карточки (обёртка из §5); фильтры/экспорт компактно.
4. **Биллинг** — карточки баланса/тарифа; транзакции → карточки.
**Этап 2 — остальное простое:**
5. **Проекты**, **Настройки**, **Помощь** — списки/формы в столбик, крупные поля.
6. **Отчёты** — графики на всю ширину, горизонтальный скролл только внутри своего блока.
**Этап 3 — сложное:**
7. **Канбан** — на телефоне: одна колонка-этап с переключателем этапов (вкладки/свайп), карточки
сделок; drag заменить на «переместить в этап» через меню (перетаскивание пальцем — не основной путь).
8. **Импорт** — мастер по шагам вертикально.
9. **Конкурентное поле** (`/autopodbor`) — карточки уже есть; доводим отступы/тап-цели/ширины.
На **каждом** экране решаем «мобилка = урезанная»: тяжёлое (напр. массовый экспорт, широкие
таблицы-простыни, batch-действия) — оставляем полноценно на десктопе, на телефоне даём главное.
## 7. Как проверяем (критерии готовности)
Каждый экран считается готовым, когда:
- Реальный прогон (Playwright) на **390px (телефон)** и **~820px (планшет)**: ничего не вылезает за
экран, нет горизонтального скролла страницы, меню работает.
- **Десктоп ≥1280px** — проверен, что не сломан (снимок до/после).
- Тап-цели ≥ 44px; текст читаемый без зума.
- Pa11y без новых нарушений (единственный источник a11y — п.3 CLAUDE.md §5).
- Регрессия: `npm run type-check`, `npm run test:vue`, сборка Vite — зелёные.
## 8. Изоляция и база кода
- **База — ветка с «Полем».** «Конкурентное поле» есть только в `worktree-avtopodbor` (и на проде),
в `main`/текущей ветке его нет. Заводим **отдельную ветку от `worktree-avtopodbor`** в **новом
worktree** (не трогаем `main` — им пользуются другие сессии при выкатах; не трогаем сам
`worktree-avtopodbor` — там идёт работа по автоподбору).
- **Стек-фильтр (обязателен):** Vue 3 + Vuetify 3 (не Tailwind/React), палитра/шрифты/иконки —
Forest brandbook. UI-решения — через paired-stack Superpowers + Frontend Design (PSR_v1 R6).
- Ничего на боевой без отдельного разрешения владельца.
## 9. Риски
- **Раздробленность веток** — «Поле» вне main; при слиянии автоподбора в main мобильную ветку
придётся ребейзить. Приемлемо (обычное ветвление).
- **Канбан на телефоне** — перетаскивание пальцем сложно; решение — заменить на «переместить в этап»
через меню. Согласовать вживую на этапе 3.
- **«Урезанность»** — риск убрать нужное; поэтому на каждом экране показываем результат владельцу.