Темизация
Тему виджета можно полностью перекрасить с хост-страницы без пересборки бандла. Все параметры темы проходят через единый пайплайн конфига (см. Конфигурацию): задавайте их через window.MZBOT_CONFIG, атрибутом data-mz-* или вживую через MZBOT.setTheme({...}).
Цветовая схема
Четыре режима: light · white · dark · auto.
Через атрибут data-mz-theme на <html> (рекомендуется)
Виджет вживую отслеживает data-mz-theme на <html> и реагирует немедленно:
document.documentElement.setAttribute('data-mz-theme', 'dark'); // тёмная
document.documentElement.setAttribute('data-mz-theme', 'light'); // светлая
document.documentElement.setAttribute('data-mz-theme', 'white'); // намного светлее light
document.documentElement.setAttribute('data-mz-theme', 'auto'); // следовать за ОСМожно задать статически в разметке — применится на загрузке:
<html data-mz-theme="dark">Невалидные значения игнорируются; удаление атрибута оставляет текущую тему. Обратной петли нет: виджет пишет собственное состояние на хост <mz-bot>, но никогда обратно в <html>.
Через JS-API
MZBOT.setTheme('dark'); // короткая форма
MZBOT.setTheme({ theme: 'dark' }); // объектная форма
MZBOT.getTheme(); // → { theme, resolvedTheme, accent, ... }
MZBOT.subscribe((t) => console.log(t)); // подписка на изменения; возвращает unsubscribeНачальный конфиг (до загрузки бандла)
<script src="bundle.min.js" data-mz-theme="dark" data-mz-accent="#0dbb52" defer></script>
<!-- или -->
<script>window.MZBOT_CONFIG = { theme: 'dark' };</script>Акцент и паттерн
MZBOT.setTheme({
accent: '#0dbb52', // любой CSS-цвет — красит всё тематическое
pattern: 'mesh', // none | whisper | mesh | scales | bloom | cipher | prism
patternOpacity: 0.08, // 0..1
patternScale: 1.5, // 0.25..4
});Доступные паттерны: MZBOT.patterns. Анимации: MZBOT.animations. Темы: MZBOT.themes.
Язык оформления (design)
Скин поверх темы, а не вместо неё: theme, accent, pattern, msgAnimation и glow продолжают работать в обоих вариантах.
// widget.config.js
theme: {
design: 'glass', // 'default' (или не указано) | 'glass'
}default— обычные плотные поверхности. Штатный вид виджета.glass— гласморфизм. Карточка становится полупрозрачным матовым стеклом с оттенком accent и размывает страницу под собой; поле ввода, пузыри сообщений, подсказки и кнопка-лаунчер — слои того же стекла над ней. Основа стекла берётся из темы: вlight/whiteстекло светлое, вdark— тёмное, accent тонирует оба.Шапки как панели в этом дизайне нет: её содержимое лежит прямо на стекле — без заливки, без края, без тени, — а текст берёт цвета темы (8–15:1 в светлой, 6–13:1 в тёмной, на любой подложке страницы). Accent из шапки не уходит, но перестаёт быть заливкой и становится объектом: тонкое кольцо присутствия вокруг аватара, с зазором, — светится акцентом, когда оператор на связи, и гаснет в нейтральный, когда нет. Пока онлайн, кольцо медленно «дышит» — это единственная фоновая анимация дизайна;
prefers-reduced-motion: reduceеё выключает. Кольцо заменяет зелёную точку статуса, а не дополняет её.Бюджет цвета. Accent тратится точечно, а не размазывается: еле уловимый тон в самой панели (настолько слабый, что читается как «тёплый серый»), пузыри сообщений посетителя и то, что сигналит — кнопка отправки, кольцо присутствия, ховер и нажатие, ссылки, галочки прочтения, кнопка-лаунчер. Все остальные поверхности нейтральные: бело-серые в светлой теме, серо-графитовые в тёмной. Сила тона панели — токен
--mz-glass-tint-a. Панели, висящие над перепиской — меню опций и карточка прикреплённого файла над полем ввода — намеренно непрозрачные: сквозь них не должны читаться сообщения. Стеклом они остаются за счёт размытия, блика и подсвеченной кромки.
Приоритеты — как у остальных ключей темы:
<script src="bundle.min.js" data-mz-design="glass" defer></script>MZBOT_CONFIG = { design: 'glass' };
MZBOT.setTheme({ design: 'glass' }); // живьём; список значений — MZBOT.designsЧто glass меняет в остальном конфиге
| Ключ | Поведение в glass |
|---|---|
accent | тонирует все поверхности, а не только кнопки |
bgColors / bgAngle | игнорируются — сплошная заливка чата легла бы поверх стекла и закрыла его |
pattern, patternImage | работают; текстура читается как взвешенная внутри стекла |
mode, msgAnimation, glow | без изменений |
Деградация
Движки без backdrop-filter (и посетители с включённым «уменьшить прозрачность») получают тот же скин на почти непрозрачных альфах — теряется матовость, но не читаемость. Сам оттенок собран из rgba() поверх триплета --mz-accent-rgb, который theme.js пишет рядом с --mz-accent, так что color-mix() не нужен и всё рисуется на старых Safari/iPadOS и Android WebView.
Акцентное свечение (glow)
Свечение (halo из box-shadow) вокруг открытого виджета, переключаемое по разрешённой теме.
// window.MZBOT_CONFIG
theme: {
glow: {
dark: true, // свечение, когда активна тёмная тема
light: false, // без свечения на светлой
intensity: 1, // множитель силы (1 = дефолт; ~0.1..5)
},
}Рантайм:
MZBOT.setGlow({ dark: true, light: true, intensity: 2 });
MZBOT_CONFIG = { glow: { dark: true, intensity: 1.5 } };intensity масштабирует размытие halo и прозрачность акцента (clamp ~0.1–5). Свечение следует за активной темой автоматически (включая auto и живые переключения data-mz-theme): theme.js ставит data-mz-glow на хост, что переключает --mz-widget-shadow. Видно только при открытом виджете.
Фон чата
Две независимых ручки кастомизируют область сообщений.
Градиент / заливка (bgColors / bgAngle)
Перекрывает дефолтную поверхность темы своим цветом или градиентом:
MZBOT.setTheme({ bgColors: ['#1b2735', '#283e51', '#0a1622'], bgAngle: 160 }); // 3-цветный градиент
MZBOT.setTheme({ bgColors: ['#0d4f2b'] }); // один цвет = заливка
MZBOT.setTheme({ bgColors: 'radial-gradient(circle at 30% 0%, #2a5298, #0a1622)' }); // сырой CSS
MZBOT.setTheme({ bgColors: 'none' }); // вернуть поверхность темыbgColors— массив из 1..n CSS-цветов (1 = заливка; 2+ =linear-gradient), строка через запятую (удобно дляdata-mz-bg-colors), или полная CSS-background-строка (любой*-gradient(...)) — используется как есть.'none'очищает.bgAngle— направление градиента в градусах (дефолт160). Игнорируется для одного цвета и сырой строки.
Одиночное значение заменяет поверхность во всех темах (это явный оверрайд) — либо задайте два фона, по одному на тему (ниже).
Два фона: светлая и тёмная тема
Любой ключ фона — bgColors, bgAngle, pattern, patternOpacity, patternScale, patternImage, patternImageOpacity, patternImageSize — принимает либо одно значение (общее для обеих тем), либо карту { light, dark }:
theme: {
mode: 'auto',
bgColors: {
light: ['#e9eeea', '#dfe8e0', '#d6e0d4'], // пока активна светлая тема
dark: ['#1b2735', '#283e51', '#0a1622'], // …а это под тёмную
},
bgAngle: 160, // одно значение = обе темы
pattern: { light: 'whisper', dark: 'scales' },
}- Ветка выбирается по активной теме и переприменяется при каждом переключении:
MZBOT.setTheme('dark'),mode: 'auto'(следит за системной темой),<html data-mz-theme>. Пересборка и перезагрузка не нужны. whiteберёт веткуlight, если своей нет.- Тема, для которой ветки нет, остаётся на своей штатной поверхности — то есть
bgColors: { dark: [...] }кастомизирует только тёмную, светлая идёт как из коробки. - Работает из любого источника:
widget.config.js,window.MZBOT_CONFIG,MZBOT.setTheme({...})и атрибутов скрипта (data-mz-bg-colors-light/data-mz-bg-colors-dark).
Подписи на фоне подстраиваются сами
Время сообщения пользователя и разделитель дат («сегодня») рисуются прямо на фоне, поэтому их цвет не фиксирован, а подбирается под фон: виджет берёт все стопы bgColors (или поверхность темы), выбирает направление — чёрный или белый, смотря что лучше держится на худшем стопе — и отходит от этого края обратно к фону настолько, насколько позволяет целевой контраст ~4:1 (учитывая opacity: .85, с которой эти подписи рисуются). Получается самый тихий цвет, который ещё уверенно читается: подпись видно на любом фоне, но она не спорит с текстом сообщений.
Ничего настраивать не нужно — пересчёт идёт при каждой смене темы и фона. Если фон в принципе не покрывается одним цветом (градиент от почти белого к почти чёрному), подписи дополнительно получают мягкий ореол (text-shadow) в противоположном цвете.
Бесшовное изображение-оверлей (patternImage)
Тайлит прозрачное изображение-паттерн поверх фона. Либо/либо со встроенными pattern: когда задан patternImage, он заменяет SVG-паттерн (изображение побеждает); patternImage: 'none' возвращает SVG.
MZBOT.setTheme({
patternImage: 'https://cdn.morze.tech/patterns/topography.png',
patternImageOpacity: 0.5, // 0..1 (своя альфа PNG тоже применяется)
patternImageSize: 280, // px-тайл или любой CSS background-size
});
MZBOT.setTheme({ patternImage: 'none' }); // убрать оверлейpatternImage— URL. Принимаютсяhttp(s)://, протокол-относительные (//), корневые/относительные (/…,./…) иdata:image/…; остальное (или URL с небезопасными символами) отклоняется.'none'/''— выкл.patternImageSize— число (px-ширина тайла, высота авто) или любой CSSbackground-size.
Через атрибуты загружающего скрипта
<script src="bundle.min.js"
data-mz-bg-colors="#1b2735,#283e51,#0a1622"
data-mz-bg-angle="160"
data-mz-pattern-image="https://cdn.morze.tech/patterns/topography.png"
data-mz-pattern-image-opacity="0.5"
data-mz-pattern-image-size="280"
defer></script>Свой фон на каждую тему — суффиксы -light / -dark у любого из этих атрибутов (базовый атрибут без суффикса остаётся значением для темы, которую не задали явно):
<script src="bundle.min.js"
data-mz-theme="auto"
data-mz-bg-colors-light="#e9eeea,#dfe8e0,#d6e0d4"
data-mz-bg-colors-dark="#1b2735,#283e51,#0a1622"
data-mz-bg-angle="160"
defer></script>Анимация сообщений
MZBOT.setTheme({ msgAnimation: 'unfurl' }); // bubble | unfurl | cascade | pop | breatheВсе методы темы — на странице JavaScript API.