# UX Design
Visual Package: **v2** (2026-10-30), локальные SVG в `../visuals/`, хеши в разделе «Materials». v1 (четыре макета без центральной суммы, предупреждения и без разрезов с одной валютой) заменён.
Базис существующих паттернов (код, не визуальные материалы): `frontend` @ `71126c91f0b30f4d65a313ddc7d7f86963340455`, Mantine / `@mantine/charts` 9.7.3, `docs/design/overview.md`. Storybook не запускался, истории прочитаны как исходники.
Поведение определяют Delta Specs `portfolio-concentration` (28 Requirements, с учётом решений владельца [#48, 3081](https://git.personal.ksv741.ru/WealthLedger/main/issues/48#issuecomment-3081)) и `portfolio-view`. Документ ссылается на Requirements и не вводит нового поведения; всё, чего в Specs нет, вынесено в «Design-level items».
## User Goals
Единственный пользователь — владелец, который отвечает на вопрос «где сконцентрированы мои деньги» и сравнивает вклад бумаг, секторов и эмитентов. Цель владельца: «сделать что-то классное и красивое» без выхода за пределы дизайн-системы.
| Цель | Что должно быть видно за один взгляд |
| --- | --- |
| Понять степень концентрации | «Топ-5 · N %» и сумма разреза в центре кольца |
| Узнать, кто в топе | Ранжированный список с названием, суммой, долей и длиной полосы |
| Не потерять остальное | Строка «Прочее» с числом элементов и раскрытием |
| Доверять цифрам | Одна валюта, предупреждение «Данные неполные», сноска «Не учтено позиций: N», одинаковые значения в кольце и списке |
## User Flows
Требования: `portfolio-concentration` — `Вкладка «Концентрация» страницы счёта`, `Вкладка в состояниях страницы`, `Переключение разрезов`, `Начальное состояние вкладки`, `Одна валюта за раз`, `Доступные валюты вкладки`, `Раскрытие строки «Прочее»`, `Строки без переходов`, `Сноска о не учтённых позициях`, `Предупреждение о неполных данных`.
```mermaid
flowchart TD
A[Страница счёта, вкладка «Позиции»] -->|Клик / Enter на «Концентрация»| B[Разрез «Акции», первая валюта по ISO]
B --> C{Что делает User}
C -->|Выбирает другой разрез| D[Разрез заменён, валюта сохранена, «Прочее» свёрнуто]
C -->|Выбирает валюту, если валют две и больше| E[Пересчёт по позициям валюты, «Прочее» свёрнуто]
C -->|Нажимает «Прочее»| F[Остальные элементы раскрыты, топ-5 и кольцо без изменений]
F -->|Повторное нажатие| C
C -->|Читает предупреждение и сноску| G[«Данные неполные» над разрезом; «Не учтено позиций: N» под списком]
C -->|Переключает другую вкладку страницы| H[Разрез и валюта сохраняются]
H -->|Возврат на «Концентрация»| C
C -->|Уходит со страницы или переключает счёт| I[Состояние сброшено]
I -->|Новый заход| B
J[Режим «Все счета»] -.->|Вкладки нет| X((выход))
```
1. **Открыть вкладку.** Вход: «Концентрация» в `Tabs.List` справа от «Позиции». Выход: разрез «Акции», первая валюта, кольцо с центром, список.
2. **Переключить разрез.** Один шаг на `SegmentedControl`. Валюта остаётся, «Прочее» сворачивается.
3. **Переключить валюту.** `Select`; пересчитывается текущий разрез, «Прочее» сворачивается. При одной валюте выбора нет, шаг пропускается.
4. **Раскрыть «Прочее».** Нажатие на строку (мышь, касание, Enter/Space), повторное нажатие сворачивает.
5. **Прочитать предупреждение и сноску.** Оба — текст без действий.
6. **Вернуться с другой вкладки страницы.** Разрез и валюта прежние; **новый заход** (уход со страницы, смена счёта, перезагрузка) — снова «Акции» и первая валюта.
7. **Пустой разрез.** User остаётся на вкладке и переключает разрез или валюту (если выбор показан).
## Information Architecture and Screen Structure
Положение: `Tabs.Tab value="concentration"` между «Позиции» и «Деньги». Вкладка не меняет `defaultValue` (`positions`); панель с `keepMounted={false}`, как у остальных. Требование сохранять разрез и валюту при переключении вкладок означает, что выбор живёт выше панели; способ — в `design.md`.
Порядок внутри панели:
1. **Предупреждение «Данные неполные»** — только при неполноте Portfolio, над карточкой (M5, M6). Один блок для всех разрезов: остаётся на месте при переключении разреза.
2. **Карточка** (`Paper withBorder radius="lg"`): шапка, затем две колонки на десктопе / одна на мобильном.
3. **Шапка.** `SegmentedControl` «Акции / Облигации / Секторы / Эмитенты» (aria-label «Разрез концентрации»). Справа подпись «Валюта» и `Select` — **только если валют две и больше**; иначе шапка содержит один переключатель (M5, M6).
4. **Hero-блок** (подложка `blue.0`, градиент в белый, радиус `lg`): кольцо 220 px, толщина 32. **Центр:** вверху «Топ-5 · N %» (muted, только если элементов шесть и больше), под ним сумма разреза (bold). Без метрики — только сумма (M6). Под кольцом подпись «<Разрез> · <валюта>».
5. **Ранжированный список** (`
`): номер, маркер, [логотип], название и подпись, справа сумма и доля, полоса доли.
6. **Строка «Прочее»** (при семи и более элементах): кнопка-disclosure с «N элементов», суммой, долей и шевроном. Раскрытие показывает остальные элементы вложенным списком (M2).
7. **Сноска** «Не учтено позиций: N» (только при N > 0).
Содержимое строки по разрезам:
| Разрез | Логотип | Подпись под названием |
| --- | --- | --- |
| Акции | `PositionLogo` 40 px, без ссылки | тикер или идентификатор позиции |
| Облигации | `PositionLogo` 40 px, без ссылки | ISIN |
| Секторы | нет | нет |
| Эмитенты | **нет** (`Строки без переходов`) | нет |
Логотип в «Секторах» не нужен: элемент объединяет позиции. Строка «Прочее» логотипа не имеет. Ни одна строка не ведёт на другую страницу; `PositionLogo` и название не получают `to`.
**Кодирование без цвета** (`Доступность диаграммы без цвета`, `Группы «Сектор не указан» и «Эмитент не указан»`):
| Признак | Кодирование |
| --- | --- |
| Ранг 1–6 | Цифра в строке и у сегмента (для сегментов ≥ 4 %) + монохромная синяя шкала `blue.9 → blue.0` с обводкой `blue.9` |
| «Прочее» | Серая точечная штриховка в маркере, сегменте и полосе, серая обводка; слово «Прочее» |
| «Сектор не указан» / «Эмитент не указан» | Диагональная штриховка поверх цвета ранга; название в тексте |
| Значение | Всегда число в тексте строки; полоса и кольцо его дублируют |
Шкала однотонная, потому что `grape`, `orange` и `green` в «Структуре портфеля» означают классы активов (`portfolioCategoryPresentation`). Длина полосы — доля от 100 % суммы разреза, шкала совпадает с кольцом.
**Центр кольца.** Внутренний диаметр 156 px. «Топ-5 · N %» — 14 px / 600, сумма — 22 px / 700; сумма точная, без округления (`Центр диаграммы`), поэтому при длинной записи размер ступенчато уменьшается до 14 px (22 → 18 → 14), без переноса и обрезки. Обе строки входят в текстовый эквивалент.
## Interaction Behavior
| Элемент | Поведение |
| --- | --- |
| Переключение разреза | Fade + `translateY(4px)` 220 ms `ease-out`, как смена валюты в `PortfolioStructure`; при `prefers-reduced-motion: reduce` анимации нет. Вращения сегментов нет (`isAnimationActive: false`). Фокус остаётся на переключателе. |
| Смена валюты | Та же анимация; «Прочее» сворачивается. Если выбранная валюта пропала после обновления Portfolio, выбирается первая (`Независимый выбор валюты вкладки`), без уведомления. Если валюта осталась одна, `Select` исчезает. |
| Строка «Прочее» | `