Темы и внешний вид Web App

Обновление темы по умолчанию. Встроенная
darkтеперь является канонической темой по умолчанию и содержит два варианта:darkиlight. Старый ключlightсохранён как скрытый alias совместимости, поэтому существующие ссылкиWEBAPP_DEFAULT_THEME=lightи/home?theme_preview=lightпо-прежнему открывают светлый вариант, но админы настраивают его через единую карточку Default theme. Карточка поддерживает удобную no-code настройку: пресеты, переключатель dark/light, токены палитры, радиус, масштаб логотипа для десктопа/мобильного, отдельную палитру админки и выпадающие списки шрифтов для UI, бренда и моноширинного текста.
Темы и внешний вид Web App
Заголовок раздела «Темы и внешний вид Web App»Web App поддерживает файловые темы, предпросмотр и базовую настройку внешнего вида из админ-панели. Тема может быть простой цветовой схемой на JSON-токенах или полноценным скином с собственным CSS, шрифтами, иконками и графикой.
Что можно поменять
Заголовок раздела «Что можно поменять»Через раздел Админка -> Внешний вид можно:
- выбрать глобальную тему Web App;
- изменить accent-цвет конкретной темы;
- включить или выключить применение темы в админ-панели;
- настроить масштаб логотипа на главной и экране входа;
- загрузить логотип файлом или по HTTPS-ссылке;
- открыть предпросмотр темы через
/home?theme_preview=<key>.
Через файлы темы можно менять намного больше:
- базовые цвета Mini App и админки;
- радиусы, семейства шрифтов и размер главного логотипа;
- любые компоненты через CSS: карточки, навигацию, таблицы, модалки, кнопки, скелетоны, прогресс-бары, состояния hover/active и мобильную/desktop-верстку;
- экран инструкций установки (
/installи/s/<token>): topbar, выбор платформы, карточки приложений, шаги инструкции и QR-блок личной страницы; - иконки и изображения, если CSS ссылается на ассеты темы;
- стили только пользовательской части, только админки или обеих частей сразу.
Готовые темы лежат в backend/bot/app/web/themes: dark, windows95, ascii. Светлый режим живет как вариант темы dark; ключ light оставлен только как скрытый алиас для старых настроек. При первом запуске темы копируются в WEBAPP_THEMES_DIR, по умолчанию data/themes.
Где живут темы
Заголовок раздела «Где живут темы»Каждая тема - отдельная папка:
Путь настраивается переменной:
WEBAPP_DEFAULT_THEME опционален. Если он задан и совпадает с ключом темы, он переопределяет default: true в theme.json. Если переменная пустая, дефолт выбирается из дескрипторов тем.
В compose-примерах data/themes - это локальная папка рядом с выбранным docker-compose.yml; она монтируется в контейнер как /app/data/themes. Правки в backend/bot/app/web/themes попадают в прод только при сборке собственного образа; опубликованный образ их не видит.
Важно: WEBAPP_PRIMARY_COLOR и WEBAPP_LOGO_URL больше не являются рабочим способом первичной настройки через .env. Эти значения редактируются в админке и сохраняются как overrides в базе. Тема при этом может использовать сохраненный primary color как fallback accent.
Email-шаблоны берут тот же бренд из настроек внешнего вида. Загруженный логотип добавляется в письма как inline image (cid:webapp-logo), а публичный HTTPS-логотип остается внешней картинкой, которую почтовый клиент может скрыть до разрешения загрузки изображений.
Контракт theme.json
Заголовок раздела «Контракт theme.json»Минимальная тема:
Тема с CSS:
Поля верхнего уровня:
| Поле | Назначение |
|---|---|
key |
Уникальный ключ темы, 1-64 символа: латиница, цифры, _ и -. Если ключ не указан, берется имя папки. |
names |
Локализованные названия, например ru и en. |
enabled |
Показывать тему пользователям. Отключенная тема не попадает в публичный каталог. |
default |
Делает тему выбранной по умолчанию, если WEBAPP_DEFAULT_THEME не задан. |
use_primary_accent |
Если true, тема может получить accent из настройки внешнего вида, когда в tokens.accent ничего нет. |
use_in_admin |
Если false, пользовательская часть использует тему, но админка откатывается на dark. |
css_file |
CSS-файл внутри папки темы. Может быть style.css или вложенный путь вроде css/theme.css. |
assets_version |
Версия ассетов. Для встроенных тем используется для обновления старых файлов в data/themes. |
tokens |
Дизайн-токены, которые превращаются в CSS-переменные на .app-shell. |
Поддерживаемые токены:
| Токен | CSS-переменная | Что меняет |
|---|---|---|
color_scheme |
color-scheme |
Нативная светлая/темная схема браузера: dark или light. |
style_preset |
CSS-класс пресета | Сейчас win95/windows95 добавляет theme-preset-win95; остальные значения не дают специального класса. |
accent |
--accent |
Главный акцент: активные элементы, кнопки, прогресс, фокус. Только hex #RGB или #RRGGBB. |
bg |
--bg |
Основной фон приложения. |
panel |
--panel |
Основные карточки и поверхности. |
panel_2 |
--panel-2 |
Вторичные поверхности. |
panel_3 |
--panel-3 |
Поверхности повышенной вложенности, dropdown/popover. |
border |
--border |
Обычные границы. |
border_strong |
--border-strong |
Усиленные границы и hover-состояния. |
text |
--text |
Основной текст. |
muted |
--muted |
Вторичный текст. |
dim |
--dim |
Еще более тихий текст и служебные подписи. |
danger |
--danger |
Ошибки и опасные действия. |
blue |
--blue |
Синий вспомогательный цвет. |
radius |
--radius |
Базовый радиус карточек, кнопок и контролов. |
font_sans |
--font-sans |
Основной шрифт интерфейса. |
font_logo |
--font-logo |
Шрифт бренда и заголовка. |
font_mono |
--font-mono |
Моноширинный шрифт. |
home_logo_scale_desktop |
--home-logo-scale-desktop |
Масштаб логотипа на desktop layout, от 50 до 300 процентов. |
home_logo_scale_mobile |
--home-logo-scale-mobile |
Масштаб логотипа на mobile layout, от 50 до 300 процентов. |
home_logo_scale |
--home-logo-scale |
Legacy fallback для старых тем; используется, если desktop/mobile token не задан. |
admin_bg |
--admin-bg |
Фон админ-панели. |
admin_surface |
--admin-surface |
Основные карточки админки. |
admin_surface_2 |
--admin-surface-2 |
Вторичные поверхности админки. |
admin_elev |
--admin-elev |
Elevated-поверхности админки. |
admin_border |
--admin-border |
Границы админки. |
admin_border_strong |
--admin-border-strong |
Усиленные границы админки. |
admin_text |
--admin-text |
Основной текст админки. |
admin_muted |
--admin-muted |
Вторичный текст админки. |
admin_dim |
--admin-dim |
Тихие подписи админки. |
Если css_file не задан, интерфейс полностью строится на токенах и общих стилях. Если css_file задан, токены все равно применяются первыми, а CSS темы может уточнить или полностью переопределить внешний вид.
CSS-слой темы
Заголовок раздела «CSS-слой темы»CSS темы подключается как:
Например data/themes/neon/style.css будет доступен как /webapp-theme-css/neon/style.css.
Корневой контейнер получает классы:
Для светлой схемы будет theme-light. Класс theme-key-<key> - основной якорь для CSS темы. Всегда начинайте селекторы с него, чтобы тема не задевала другие режимы:
CSS можно писать для пользовательской части и админки одновременно:
Ограничения:
- CSS-файл должен быть внутри папки темы;
- размер CSS - до 512 KiB;
- путь не может содержать
..; - удаленные CSS,
data:и protocol-relative URL вcss_fileне подключаются.
Ассеты темы
Заголовок раздела «Ассеты темы»Картинки темы кладутся рядом с theme.json и отдаются через:
Пример:
Разрешены png, jpg, jpeg, gif, webp, svg, ico. Один asset - до 1 MiB. Для шрифтов лучше использовать внешние источники, уже разрешенные CSP (fonts.googleapis.com, fonts.gstatic.com, cdn.jsdelivr.net) или системные fallback-цепочки в font_* токенах.
Пайплайн создания новой темы
Заголовок раздела «Пайплайн создания новой темы»-
Выберите ключ темы.
Ключ должен быть стабильным: по нему сохраняется выбранная тема и строятся URL ассетов. Используйте короткий slug:
neon,brand_dark,terminal-blue. Не переименовывайте ключ после публикации без миграции файлов и сохраненных настроек. -
Создайте папку в
WEBAPP_THEMES_DIR.В Docker это
data/themesрядом с выбраннымdocker-compose.yml, внутри контейнера путь будет/app/data/themes. Убедитесь, что контейнер может писать вdata. -
Скопируйте ближайшую базовую тему.
Для обычной брендовой темы чаще всего удобнее начать с
darkи при необходимости переключить/настроить его светлый variant. Для глубокого CSS-скина можно взятьasciiилиwindows95как пример того, насколько далеко можно уйти от стандартного вида. -
Отредактируйте
theme.json.Сначала поменяйте
key,names,default,use_primary_accentи базовые токены. На этом этапе можно вообще не создавать CSS: приложение уже увидит тему как новый набор токенов. -
Запустите приложение и откройте админку.
Раздел Внешний вид загружает
/api/admin/themes, backend читаетWEBAPP_THEMES_DIR, добавляет обязательные базовые темы и возвращает каталог. Нажмите Обновить, если папка была создана во время работы приложения. -
Проверьте тему через предпросмотр.
В карточке темы нажмите Предпросмотр или откройте:
Предпросмотр не меняет глобальную тему и удобен для проверки CSS до публикации.
-
Подберите accent и масштаб логотипа.
В админке можно менять accent,
home_logo_scale_desktopиhome_logo_scale_mobileбез ручного редактирования JSON. При сохранении backend перепишетtheme.jsonвWEBAPP_THEMES_DIR, выставит ровно одинdefaultи сбросит кеш публичных настроек. Старыйhome_logo_scaleсохраняется как fallback для уже существующих тем. -
Добавьте
style.css, если токенов мало.Создайте файл, укажите его в
theme.json:Начинайте с переопределения CSS-переменных на
.theme-key-neon.app-shell, затем переходите к конкретным компонентам. Проверяйте минимум: главная,/install, публичная/s/<token>, оплата, настройки, модалки, админский дашборд, таблица пользователей, редактор тарифов.После ручного изменения CSS поднимите
assets_versionвtheme.jsonили сделайте жесткую перезагрузку страницы: тема подключается с?v=<assets_version>, и браузер может держать старую версию. -
Добавьте ассеты при необходимости.
Положите картинки в подпапку темы и ссылайтесь на них через
/webapp-theme-assets/<key>/.... Не используйте относительные пути вродеurl("icons/x.png"), если CSS может быть подключен с другого URL-уровня; явный/webapp-theme-assets/neon/icons/x.pngнадежнее. -
Настройте поведение админки.
Если тема сильно декоративная и мешает рабочей админке, выставьте
use_in_admin: false. Пользователи увидят тему, а администраторы в разделе админки получатdarkкак fallback. -
Сделайте тему дефолтной.
Есть два способа:
- в админке выбрать тему и сохранить;
- указать
WEBAPP_DEFAULT_THEME=neonв.env, если нужен жесткий override на уровне окружения.
-
Зафиксируйте тему.
Для темы, которая должна ехать вместе с проектом, добавьте ее в репозиторий в
backend/bot/app/web/themesи при необходимости расширьтеDEFAULT_THEME_KEYSвbackend/config/webapp_themes_config.py. Для приватной инсталляции достаточно хранить ее вdata/themes.
Насколько глубоко можно менять вид
Заголовок раздела «Насколько глубоко можно менять вид»Уровни кастомизации:
- Быстрый бренд - токены
accent,bg,panel,text,radius, логотип в админке. Код не нужен. - Полная палитра - все пользовательские и admin-токены, отдельные шрифты, масштаб логотипа.
- CSS-скин - переопределение карточек, навигации, таблиц, модалок, progress/skeleton/toast, desktop/mobile раскладок.
- Почти новый UI - тема вроде
windows95илиascii: можно менять форму контролов, иконки, эффекты, таблицы и визуальный язык целиком, пока сохраняется DOM и интерактивные состояния.
Не стоит менять через CSS смысловые состояния: скрывать ошибки, отключать фокус, перекрывать кнопки невидимыми слоями или делать display: none для обязательных действий оплаты и авторизации. Тема должна менять внешний вид, а не бизнес-логику.
Диагностика
Заголовок раздела «Диагностика»Если тема не появилась:
- проверьте, что
theme.jsonлежит ровно вWEBAPP_THEMES_DIR/<key>/theme.json; - ключ состоит только из латиницы, цифр,
_и-; - JSON валиден;
- тема не отключена через
enabled: false; - в логах нет предупреждения
Ignoring theme descriptor.
Если CSS не применился:
- проверьте
css_fileи URL/webapp-theme-css/<key>/<css_file>; - если CSS уже был открыт в браузере, увеличьте
assets_versionвtheme.jsonили очистите кеш; - убедитесь, что файл меньше 512 KiB;
- начинайте селекторы с
.theme-key-<key>; - откройте
/home?theme_preview=<key>в новом окне, чтобы исключить сохраненный старый выбор.
Если ассеты не грузятся:
- используйте путь
/webapp-theme-assets/<key>/<path>; - проверьте расширение:
png,jpg,jpeg,gif,webp,svg,ico; - размер каждого файла должен быть до 1 MiB;
- путь не должен содержать пробелы, кириллицу или
...