# Дашборд: топ услуг B2C по регионам
Веб-дашборд «Топ услуг B2C по регионам»: топ услуг Казахтелекома по количеству покупок с разбивкой по всем регионам. В шапке слева — логотип Казахтелекома: файл kt-logo.svg в корне проекта (его содержимое — в разделе «Логотип» ниже, сохрани без изменений), подключи как , справа от него заголовок «Топ услуг B2C по регионам». Экран собирай ТОЛЬКО из компонентов дизайн-системы KT AI (design-system/COMPONENTS.md), своих классов, стилей и цветов не выдумывай. Шапка — .kt-ai-pagehead с логотипом и заголовком. Под ней полоса показателей .kt-ai-kpi-strip из четырёх плашек .kt-ai-kpi (в каждой .value — число, .label — подпись, .hint — уточнение): всего покупок, всего регионов, услуга-лидер (название целиком, без обрезания), регион-лидер; на широком экране четыре в один ряд, на телефоне — в две колонки. Ниже два столбчатых графика в карточках .kt-ai-card — «Топ регионов по покупкам» и «Топ услуг по количеству»: чистый SVG или div-столбцы высотой 190–220px, столбцы 20–28px с радиусом 2px, подписи значений 11px mono muted, цвет столбцов — один токен var(--kt-ai-chart-blue) (второй график — var(--kt-ai-chart-green)), без радуги; подсказка значения при наведении — атрибут data-kt-tip и скрипт ./design-system/kt-ai-chart-tip.js. Ниже таблица топ-услуг по правилам ДС: frameless в .kt-ai-table-wrap, колонки «Услуга», «Регион», «Покупок», «Сумма, ₸», числа вправо с tabular-nums, лёгкие горизонтальные разделители, поиск по услуге и фильтр по региону над таблицей. Цвета, отступы, радиусы, шрифт — только токены var(--kt-ai-…) из ДС в светлой теме (); ни одного своего hex-цвета, кроме файла логотипа. Перед публикацией проверь: в index.html не меньше десятка классов kt-ai-*. Только фронтенд — один статичный index.html с данными внутри, без серверной части (никаких package.json, server.js, node-зависимостей). Источник данных — таблица в разделе «Данные» ниже, используй её целиком и ничего не выдумывай. Все пути к CSS, скриптам, шрифтам и другим ресурсам — строго относительные (./...): сайт публикуется в подпапке, абсолютные пути с корня сломаются. Работай без уточняющих вопросов. Когда дашборд готов — опубликуй сайт.
## Основа — готовая страница
Прототип уже свёрстан и проверен, его код — в этом файле между строками `<<>>`. Не перепечатывай и не переписывай его — вырежи в index.html командой:
```sh
awk '/^<<>>$/{f=0} f' brief.md > index.html
sed -i 's#\.\./\.\./ds/#./design-system/#g; s#\.\./\.\./kt-logo\.svg#./kt-logo.svg#g' index.html
```
Сохрани kt-logo.svg из раздела «Логотип». После этого внеси ТОЛЬКО правку владельца: Дешборд по службе поддержки по регионам. Больше ничего не меняй и опубликуй сайт.
## Логотип
Сохрани этот SVG как файл kt-logo.svg в корне проекта, не меняя содержимое:
```svg
```
<<Топ услуг B2C по регионам
Топ услуг B2C по регионам
Июль 2026 · покупки и выручка по регионам
—
Покупок
за июль 2026
—
Выручка
по 50 позициям
—
Регионов
в выборке
—
Услуга-лидер
по покупкам
Регионыпо покупкам · нажмите, чтобы отфильтровать
Услугипо покупкам · топ-8
Позиции
услуга × регион
Услуга
Регион
Покупок
Сумма, ₸
Ничего не найдено
Измените запрос или снимите фильтр по региону
BASE_HTML>>>
## Объём работы
Собирай ровно то, что написано в задании. Не добавляй лишние разделы, журналы и настройки. Для статичной страницы достаточно index.html. Если запрошен статичный макет, не добавляй серверную часть на этом этапе.
Если задача требует общего хранения, настоящей регистрации или рабочего приложения, реализуй серверную часть и базу данных средствами Vibe AI. Создай необходимые файлы, таблицы и обработчики, даже если владелец не перечислил их отдельно. Не подменяй общее хранение localStorage или демонстрационным списком. Собственная база приложения не требует интеграции с системами КТ и отдельного утверждения дизайна в экспрессе. При доработке существующего проекта это правило заменяет прежнее ограничение одним HTML-файлом.
Проверь сохранение записи, чтение из другой сессии, обработку ошибок и ограничения доступа. Личные данные доступны только уполномоченному пользователю, секреты не попадают в браузерный код. Демонстрационные записи отделены от настоящих. Не придумывай доступы или готовые интеграции. Если публикация серверной части недоступна, укажи конкретную причину и не объявляй функцию работающей. Закончив, опубликуй приложение и сообщи фактический адрес и результаты проверки; сохраняй прежний адрес, если платформа это позволяет.
## Состояние данных
Примеры помечай «Демо-данные». Это не запрет базы данных: настоящие записи сохраняй в базе приложения отдельно от примеров. Пустую базу показывай пустой.
1. Управление и сообщение пустого состояния не прячутся никогда: скрывай только блок результата. Скрывать его предка (`parentElement`, `parentNode`, `closest(...)`) ЗАПРЕЩЕНО. Фильтры и надпись «Недостаточно данных» остаются видимыми.
2. Фильтр обязан менять ВСЕ представления, которые задевает: таблицу, показатели, график и текст объяснения. Объяви реестр `const FILTERS = [{id, label, affects}]` со всеми видимыми фильтрами. Не меняет чего-то в демо — скажи честно: `demoOnly: true` и видимая подпись рядом с контролом `в демо не меняет график`.
3. Молчаливая подмена набора запрещена: `DATA_SET[x] || DATA_SET["7d"]` показывает выбранный период вместе с данными другого. Нет данных под выбранные фильтры — покажи пустое состояние с явной причиной («за выбранный период данных нет»), а не чужой набор. Демо-набор наполни так, чтобы под каждым значением каждого фильтра числа были РАЗНЫЕ, и один срез оставь пустым.
4. Для демонстрационных наборов: `data-kt-data-mode="demo"` на `` и видимый чип `Демо-данные` в шапке. Для записей, действительно сохраняемых в собственной базе приложения, допустим `live` и подпись «Данные приложения». Чип «Данные из системы» используй только для реально подключённой системы, когда в задании названы источник и точка доступа. Не представляй собственную базу как интеграцию с КТ.
5. Объявленный запрет обязан быть запретом, а не надписью. Если строка помечена как непроходная (конфликт данных, пустой обязательный срок, незаполненное поле), действие по ней НЕ ВЫПОЛНЯЕТСЯ: ни поштучно, ни массовой кнопкой «принять всё». Кнопку в такой строке ставь `disabled`, а рядом одной фразой скажи, ЧТО именно мешает и что сделать («срок не заполнен — укажите дату»). Массовое действие пропускает непроходные строки и честно пишет, сколько пропустило.