36 KiB
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) и portfolio-view. Документ ссылается на Requirements и не вводит нового поведения; всё, чего в Specs нет, вынесено в «Design-level items».
User Goals
Единственный пользователь — владелец, который отвечает на вопрос «где сконцентрированы мои деньги» и сравнивает вклад бумаг, секторов и эмитентов. Цель владельца: «сделать что-то классное и красивое» без выхода за пределы дизайн-системы.
| Цель | Что должно быть видно за один взгляд |
|---|---|
| Понять степень концентрации | «Топ-5 · N %» и сумма разреза в центре кольца |
| Узнать, кто в топе | Ранжированный список с названием, суммой, долей и длиной полосы |
| Не потерять остальное | Строка «Прочее» с числом элементов и раскрытием |
| Доверять цифрам | Одна валюта, предупреждение «Данные неполные», сноска «Не учтено позиций: N», одинаковые значения в кольце и списке |
User Flows
Требования: portfolio-concentration — Вкладка «Концентрация» страницы счёта, Вкладка в состояниях страницы, Переключение разрезов, Начальное состояние вкладки, Одна валюта за раз, Доступные валюты вкладки, Раскрытие строки «Прочее», Строки без переходов, Сноска о не учтённых позициях, Предупреждение о неполных данных.
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((выход))
- Открыть вкладку. Вход: «Концентрация» в
Tabs.Listсправа от «Позиции». Выход: разрез «Акции», первая валюта, кольцо с центром, список. - Переключить разрез. Один шаг на
SegmentedControl. Валюта остаётся, «Прочее» сворачивается. - Переключить валюту.
Select; пересчитывается текущий разрез, «Прочее» сворачивается. При одной валюте выбора нет, шаг пропускается. - Раскрыть «Прочее». Нажатие на строку (мышь, касание, Enter/Space), повторное нажатие сворачивает.
- Прочитать предупреждение и сноску. Оба — текст без действий.
- Вернуться с другой вкладки страницы. Разрез и валюта прежние; новый заход (уход со страницы, смена счёта, перезагрузка) — снова «Акции» и первая валюта.
- Пустой разрез. User остаётся на вкладке и переключает разрез или валюту (если выбор показан).
Information Architecture and Screen Structure
Положение: Tabs.Tab value="concentration" между «Позиции» и «Деньги». Вкладка не меняет defaultValue (positions); панель с keepMounted={false}, как у остальных. Требование сохранять разрез и валюту при переключении вкладок означает, что выбор живёт выше панели; способ — в design.md.
Порядок внутри панели:
- Предупреждение «Данные неполные» — только при неполноте Portfolio, над карточкой (M5, M6). Один блок для всех разрезов: остаётся на месте при переключении разреза.
- Карточка (
Paper withBorder radius="lg"): шапка, затем две колонки на десктопе / одна на мобильном. - Шапка.
SegmentedControl«Акции / Облигации / Секторы / Эмитенты» (aria-label «Разрез концентрации»). Справа подпись «Валюта» иSelect— только если валют две и больше; иначе шапка содержит один переключатель (M5, M6). - Hero-блок (подложка
blue.0, градиент в белый, радиусlg): кольцо 220 px, толщина 32. Центр: вверху «Топ-5 · N %» (muted, только если элементов шесть и больше), под ним сумма разреза (bold). Без метрики — только сумма (M6). Под кольцом подпись «<Разрез> · <валюта>». - Ранжированный список (
<ol>): номер, маркер, [логотип], название и подпись, справа сумма и доля, полоса доли. - Строка «Прочее» (при семи и более элементах): кнопка-disclosure с «N элементов», суммой, долей и шевроном. Раскрытие показывает остальные элементы вложенным списком (M2).
- Сноска «Не учтено позиций: 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 исчезает. |
| Строка «Прочее» | <button> с aria-expanded и aria-controls; зона — вся строка, высота ≥ 44 px. Шеврон поворачивается на 180°, список раскрывается ≤ 200 ms (при reduce-motion — мгновенно). Фокус остаётся на кнопке. Пять строк и кольцо не меняются. |
| Строки топ-5 и раскрытые элементы | Не интерактивны: курсор обычный, переходов нет (Строки без переходов). |
| Hover/focus | Hover на сегменте подсвечивает строку и показывает tooltip «название · сумма · доля» (вид PortfolioTooltip); hover на строке подсвечивает сегмент. Это подсветка, не действие; вся информация доступна в тексте. |
| Касание | Tooltip по касанию сегмента — дополнение; список читается без жестов. |
| Фокус | Стандартное кольцо Mantine, не скрывается (показан на «Прочее» в M2). |
| Предупреждение «Данные неполные» | Статический блок Alert role="status", без кнопок; ручного обновления нет (portfolio-view). |
UI States
Данные вкладки выводятся из уже загруженного Portfolio; собственных loading и error у вкладки нет. Состояния — только те, что есть в Specs: Вкладка в состояниях страницы, Пустое состояние разреза, Предупреждение о неполных данных, Сноска о не учтённых позициях, Доступные валюты вкладки, Состояния Portfolio на вкладке «Концентрация».
| Экран / область | Loading | Empty | Error | Success | Partial / stale |
|---|---|---|---|---|---|
| Страница счёта (Portfolio) | Skeleton страницы (AccountPageLoading); вкладки «Концентрация» нет |
Штатный пустой Portfolio: вкладки нет (AccountPageEmpty) |
StateView error (AccountPageError); вкладки нет |
— | Stale: SourceSyncStatus над вкладками, как для «Позиций»; разрезы по сохранённому снимку. Partial: вкладка есть, над разрезом «Данные неполные» (M5, M6), разрезы по доступным данным |
| Вкладка, разрез с данными | n/a | n/a | n/a | Центр, кольцо, список, сноска при N > 0 (M1–M3, M5, M6) | Сноска «Не учтено позиций: N». Позиции без оценки при полном Portfolio предупреждение «Данные неполные» не вызывают |
| Разрез без учитываемых элементов (в том числе у счёта только с денежными остатками) | n/a | Название разреза и валюта (если валюта есть) вместо кольца, списка, метрики; Select (если показывается) и сноска остаются (M4) |
n/a | n/a | Сноска при N > 0 |
| Выбор валюты | n/a | Скрыт при одной валюте и при отсутствии валют | n/a | Select при двух и более |
— |
| Метрика «Топ-5 · N %» | n/a | Скрыта при пяти и менее элементах (M6) | n/a | Показана при шести и более (M1, M2, M5) | — |
| «Прочее» | n/a | Строки нет при шести и менее элементах (M5) | n/a | Свёрнуто / раскрыто | — |
| Группы «не указан» | n/a | n/a | n/a | Обычный элемент с названием и штриховкой (M2, M5) | Не влияют на успешность и свежесть Portfolio |
Disabled, offline, «нет прав»: не применимо (действий записи нет); недоступный счёт обрабатывает страница, вкладка в этих состояниях не показывается.
Validation Feedback
Пользовательского ввода, кроме выбора из закрытых списков (разрез, валюта), нет; валидации и ошибок ввода нет. Обратная связь на выбор — мгновенная перерисовка (см. Design-level items про озвучивание).
Responsive Behavior
Опора на существующую границу 48em, уже применяемую в PortfolioStructure.module.css.
| Ширина | Раскладка |
|---|---|
| ≥ 48em, макеты M1, M2, M5 (1280) | Шапка в одну строку. Две колонки: hero 296 px + список, gap 32 (xl). Предупреждение (если есть) на всю ширину над карточкой. |
| < 48em, макеты M3, M4, M6 (390) | Одна колонка: переключатель разрезов во всю ширину; при двух и более валютах ниже строка «Валюта + Select» (в M6 её нет); hero во всю ширину, кольцо 220 по центру; ниже список. Строка: логотип 40 (если положен), название и подпись слева, сумма и доля справа, полоса под ними. |
| 320 px (минимум) | Переключатель разрезов — в контейнере с overflow-x: auto (паттерн positionFilter), подписи не сжимаются; страница не скроллится по горизонтали. |
| Вкладки страницы на мобильном | Существующая Tabs.List (flex-wrap: nowrap; overflow-x: auto, класс tabsList) прокручивается по горизонтали. В макетах (M3, M4, M6) это показано так: вкладка «Операции» обрезана краем экрана, а не вмещена целиком, и справа 40 px градиентное затухание. Обрезанная вкладка — основной признак прокрутки; затухание — необязательное усиление (см. Design-level items). «Концентрация» — вторая вкладка и на 320 px видна целиком. |
| Длинные названия | Название переносится до двух строк; суммы white-space: nowrap, font-variant-numeric: tabular-nums. Отсутствие названия — fallback из Названия элементов. |
| Много элементов в «Прочее» | Вложенный список без собственной прокрутки. |
| Масштаб текста 200 % | Колонки схлопываются в одну; числа не усекаются; сумма в центре кольца уменьшается ступенчато, но не обрезается. |
Целевые зоны переключателя, Select и «Прочее» ≥ 40–44 px (WCAG 2.2 AA 2.5.8: ≥ 24 px).
Accessibility
Ориентир: WCAG 2.2 AA. Основа — Доступность диаграммы без цвета и Центр диаграммы.
| Элемент | Роль / имя |
|---|---|
| Панель | Tabs.Panel, имя от вкладки; внутри <section aria-labelledby> с заголовком «Концентрация» (visually hidden или Title order={2}) |
| Предупреждение | Alert role="status" с текстом «Данные неполные», не alert (не прерывает) |
| Переключатель разрезов | SegmentedControl (radiogroup), aria-label «Разрез концентрации» |
| Валюта | Select, aria-label «Валюта концентрации» (отличается от «Валюта структуры портфеля»); при одной валюте элемента нет в DOM |
| Кольцо | role="img", имя «Распределение: <разрез>, <валюта>» + aria-describedby на скрытый текст: центр («Топ-5 · 86,5 %, 2 235 310 ₽» либо только сумма) и затем «1. Сбербанк, 612 480 ₽, 27,4 %; … Прочее, …» в порядке списка. Сегменты в порядок фокуса не входят |
| Список | <ol aria-label="<разрез>: топ элементов">; каждый элемент читается как «название, сумма, доля» |
| Полоса, маркер, штриховка | aria-hidden (дублируют текст) |
| «Прочее» | <button aria-expanded aria-controls>, имя «Прочее, N элементов, <сумма>, <доля>» |
| Сноска | Обычный текст, не alert |
Клавиатура. Порядок фокуса: вкладки страницы → разрез → валюта (если показана) → «Прочее» (если есть) → остальной контент. Строки не фокусируются, потому что на них нет действий. Enter/Space на «Прочее» переключает раскрытие; фокус при раскрытии не уходит. Прокручиваемый ряд вкладок на мобильном остаётся доступен с клавиатуры стрелками (поведение Tabs).
Не только цвет. Ранг — цифра + светлота + обводка; «Прочее» — точечная штриховка + слово; «не указан» — диагональная штриховка + слово; предупреждение — текст «Данные неполные».
Контраст (расчёт по токенам @wealthledger/tokens, светлая схема)
| Пара | Коэффициент | Требование |
|---|---|---|
text dark.7 на белом |
15,5 : 1 | 4,5 |
text dark.7 на blue.0 hero |
14,3 : 1 | 4,5 |
muted gray.7 на белом / на blue.0 hero |
8,2 : 1 / 7,5 : 1 | 4,5 |
Обводка сегмента blue.9 на белом |
10,4 : 1 | 3 (граница графики) |
Заливка blue.6 полосы на треке gray.1 |
4,7 : 1 | 3 |
Серый контур «Прочее» gray.6 на белом |
3,3 : 1 | 3 |
Светлые заливки рангов 4–6 (blue.3/1/0) на белом |
1,8 / 1,2 / 1,1 : 1 | Информации не несут: различимы обводкой blue.9 и цифрой |
gray.6 для мелкого текста |
3,3 : 1 | Не использовать; muted в теме — gray.7 |
Тёмная тема. docs/design/overview.md: «тёмная тема не заявлена», токены описывают только светлую схему; контраст для тёмной не рассчитывался. Цвета в реализации берутся из токенов / CSS-переменных; литералы в SVG нужны только для самодостаточности.
Движение. prefers-reduced-motion: reduce отключает fade, раскрытие и переходы подсветки.
Увеличение текста. До 200 % без потери информации.
Design System Reuse
| Часть | Решение | Обоснование |
|---|---|---|
| Вкладка | Reuse Tabs.Tab страницы счёта |
Консистентная навигация |
| Прокрутка вкладок на мобильном | Reuse tabsList (overflow-x: auto) |
Уже работает; затухание у правого края в макете — необязательное улучшение |
| Переключатель разрезов | Reuse SegmentedControl + обёртка с overflow-x, как у «Акции / Облигации / Прочее» |
Тот же паттерн внутри вкладки |
| Выбор валюты | Reuse Select (allowDeselect={false}, w=112, aria-label) из PortfolioStructure; скрывается при ≤ 1 валюте, как там |
Единое поведение и вид |
| Кольцо | Reuse DonutChart (size 220, thickness 32, startAngle 90 / endAngle -270, без анимации, tooltip по сегменту) |
Знакомая форма |
| Tooltip | Reuse PortfolioTooltip (Paper, Text fw=600) |
Тот же вид |
| Логотипы | Reuse PositionLogo (Avatar 40, radius md, fallback — первая буква) без to |
Совпадает с PositionCard; переходов по Specs нет |
| Предупреждение | Reuse Alert role="status" (как investment.partial страницы) |
Тот же вид неполных данных |
| Состояния страницы | Reuse StateView, SourceSyncStatus, LoadingSkeleton |
Наследуются без изменений |
| Анимация смены | Reuse keyframes currency-change |
Единый ритм |
| Центр кольца из двух строк | Новый («Топ-5 · N %» + сумма вместо одной chartLabel) |
Требует Центр диаграммы; реализация — в design.md |
| Строка рейтинга с полосой | Новый (номер, маркер, название, сумма/доля, полоса) | Нет компонента «строка доли»; EntryCard и PositionCard выражают карточку операции/позиции. Собирается из Group, Text и полосы |
| Шкала рангов | Новый (монохромные blue.9…0) |
Не смешивать с цветами классов активов; только палитра токенов |
| Штриховки | Новый вспомогательный признак | Доступность диаграммы без цвета; название остаётся главным признаком |
| Disclosure «Прочее» | Новый по структуре (UnstyledButton + Collapse) |
В @wealthledger/ui аналога нет; поведение задано Specs |
Видимая подпись «Валюта» рядом с Select |
Отклонение | В PortfolioStructure только aria-label; подпись поясняет значение на мобильном, aria-label сохраняется. Можно снять без последствий для Specs |
| Подпись «<Разрез> · <валюта>» под кольцом | Новый текст | Помогает при одной валюте, когда Select скрыт; значений не добавляет |
Новые токены не вводятся; в @wealthledger/ui ничего не добавляется, предметные компоненты остаются в приложении (docs/design/overview.md).
Materials
Относительные пути заданы от каталога этого файла. SVG самодостаточны (без scripts, handlers, внешних шрифтов и ресурсов; font-family: system-ui, sans-serif), содержат <title> и <desc> с текстовым эквивалентом, включая центр кольца. Данные синтетические; цвета в SVG — литералы токенов для самодостаточности.
PNG-превью не создавались: единственный доступный рендерер (qlmanage) выдаёт квадратные миниатюры с полями, непригодные как эталон.
| ID материала | Относительный путь / ссылка | Экран/состояние и назначение | SHA-256 |
|---|---|---|---|
| M1 | ../visuals/desktop-stocks.svg |
Desktop 1280: «Акции», RUB, две валюты (выбор виден), 8 элементов: центр «Топ-5 · 86,5 %» + сумма, топ-5 с логотипами, «Прочее» свёрнуто, сноска «Не учтено позиций: 2» | c4ef8f814f6b168d3d96b6b8288ee6c574b4cf361de451a2152b1e51c939dae5 |
| M2 | ../visuals/desktop-sectors-expanded.svg |
Desktop 1280: «Секторы», «Прочее» раскрыто и в фокусе, «Сектор не указан» со штриховкой на 5-м месте, без логотипов, центр «Топ-5 · 92,1 %» + сумма | b59256bbcca8a414af85b487966dbda314ca30bbe20c5a65cf313096b4305106 |
| M3 | ../visuals/mobile-stocks.svg |
Mobile 390: «Акции», одна колонка, выбор валюты в отдельной строке, прокручиваемый ряд вкладок (обрезанная «Операции» + затухание) | d0ed332a78bdf8c9646a3033db63fc45643b4f365b0fabf34f2433b815663dbd |
| M4 | ../visuals/mobile-empty-slice.svg |
Mobile 390: пустое состояние «Облигации» в RUB (валют две, выбор виден), сноска «Не учтено позиций: 1» | 04f8be877948c3a46f0cea64558c5da1a3577a3a4b947f32b7341f83eda0a377 |
| M5 | ../visuals/desktop-issuers-warning.svg |
Desktop 1280: «Эмитенты», одна валюта (выбора нет), предупреждение «Данные неполные», шесть элементов без «Прочее», метрика «Топ-5 · 94,2 %» + сумма, без логотипов, «Эмитент не указан» со штриховкой | ece4fa5499cd5c326569e3a3b3069546dc66964b9972cac65140449206fcb4ae |
| M6 | ../visuals/mobile-issuers-warning.svg |
Mobile 390: «Эмитенты», пять элементов: в центре только сумма (метрики нет), предупреждение «Данные неполные», без выбора валюты и без логотипов | 1380c45d3db93c9b778a77c210f4444a19fe6666dff8b32080312584b78719ae |
Что проверено: валидный XML (xmllint), отсутствие scripts, href, <image> и @font-face, оценка наложений текста, расчёт контраста по токенам. Макеты не просматривались на отрисованном изображении. Единственное «выходит за экран» по оценке — «Операции» в M3, M4, M6, и это намеренная обрезка clipPath. Макеты — иллюстрация компоновки, а не пиксельная спецификация.
Закрытые findings для Specs
Решения владельца (#48, 3081) внесены в Specs; UX-часть приведена в соответствие.
| ID | Решение | Requirement | Где отражено |
|---|---|---|---|
| S1 | Разрез и валюта сохраняются, пока User на странице, включая переключение вкладок; сбрасываются при новом заходе | Начальное состояние вкладки |
User Flows 6, IA |
| S2 | Select скрыт при одной валюте и без валют |
Доступные валюты вкладки |
IA 3, UI States, M5, M6 |
| S3 | Метрика «доля топ-5» скрыта при пяти и менее элементах | Суммарная доля топ-5 |
IA 4, UI States, M6 |
| S4 | Неполный Portfolio: вкладка есть, над разрезом «Данные неполные» | Предупреждение о неполных данных |
IA 1, UI States, M5, M6 |
| S5 | Вкладки нет при загрузке, ошибке и штатном пустом Portfolio | Вкладка в состояниях страницы |
UI States |
| S6 | Неизвестный сектор показывается как получено, без пояснений | Подписи секторов |
Без UX-обработки; текст читается скринридером как есть |
| S7 | «Прочее» показывает число остальных: «2 элемента», «5 элементов» | Топ-5 и строка «Прочее» |
IA 6, M1, M2 |
| S8 (часть) | Центр кольца: «Топ-5 · N %» и сумма разреза | Центр диаграммы |
IA 4, Accessibility |
| S9 | Без логотипов в «Эмитентах» и без переходов из строк | Строки без переходов |
IA, Interaction Behavior, Design System Reuse |
Ранее предложенные вопросы Q1 (сумма разреза), Q3 (логотип эмитента), Q4 (переход из строки) закрыты теми же Requirements; Q8 (масштаб полосы от 100 %) принят как дизайн-решение.
Design-level items
Поведения не меняют; остаются на уровне дизайна, подтверждаются в design.md / на ревью макетов. Пункты D1–D4 перенесены из прежних вопросов по просьбе владельца, D5–D7 найдены при обновлении.
| ID | Вопрос | Предложение по умолчанию |
|---|---|---|
| D1 | Тексты пустого состояния. Specs задают содержание (название разреза и валюта, если есть), но не формулировку | Заголовок «<Разрез> в <валюта>: нет позиций» (без валюты, если валют нет); пояснение «Нет позиций с положительной оценкой в этом разрезе и выбранной валюте.» |
| D2 | Озвучивание смены разреза и валюты (бывший S8) | Одна role="status" (polite) строка: «Разрез «Секторы», RUB: 8 элементов»; при первом показе не объявляется |
| D3 | Минимальная видимая дуга для очень малых долей | Минимума нет (доли честные); сегмент опознаётся по списку и обводке |
| D4 | Нумерация внутри раскрытого «Прочее» | Продолжение ранга (6, 7, …), как в M2 |
| D5 | Сообщения о неполноте: на вкладке «Концентрация» страничное «Период загружен не полностью» не показывается, остаётся только «Данные неполные» на вкладке | Закрыт: PC «Предупреждение о неполных данных», решение владельца 3082; реализация — design.md F4 |
| D6 | Затухание у правого края мобильных вкладок отсутствует в коде; ряд уже прокручивается и обрезанная вкладка сама показывает прокрутку | Затухание не обязательно; если принимается, оно общее для всех вкладок страницы, а не только для «Концентрации» |
| D7 | Реализация двухстрочного центра DonutChart (children либо наложенный Text) и ступенчатое уменьшение суммы |
Решает design.md; UX требует две строки, точную сумму без обрезки и текстовый эквивалент |