Стеклянный люкс
Дизайн-система Maia. Полупрозрачные панели над живым цветным фоном: глубина строится материалом, а не рамками. Одна система на кабинет, лендинг и виджет.
Основание
Пять правил, из которых выводится всё остальное. Спор о конкретном элементе решается возвращением сюда, а не голосованием.
Фон живёт, панели плавают
Фон — три цветных пятна на градиенте. Он зафиксирован и не скроллится вместе с содержимым. Панели над ним размывают то, что под ними, и потому меняются на глазах при прокрутке.
Стекло — материал, не украшение
Панель, карточка, первичная кнопка, поле — стекло. Разделитель, текст, иконка — нет. Если светится каждый элемент, не светится ни один.
Иерархию держит цвет
Первичная кнопка — изумрудное стекло, вторичная — нейтральное стекло того же материала. Разница в цвете, а не в наличии материала.
Две темы равноправны
Ни одна не «основная».
Набор токенов один, значения разные. Тема ставится атрибутом
data-theme на <html>.
Материал отключаем
Пользователь просит систему убрать прозрачность — стекло становится плотной панелью, и дизайн не разваливается. Это работает сейчас, а не «заложено на будущее».
--solid-panel, а не на стекле.Знак
Буква M на изумрудном градиенте в квадрате со скруглением. Знак несёт тот же стеклянный объём, что и первичная кнопка: светлая верхняя кромка, глянец сверху, цветная тень снизу.
Размеры
Радиус скругления растёт вместе со знаком — примерно 30% стороны. Ниже 24px внутренний глянец не читается и убирается.
Блок бренда и охранное поле
Знак плюс название плюс необязательный подзаголовок. Отступ между знаком
и текстом — --s3. Свободное поле вокруг блока — половина
высоты знака с каждой стороны.
Так
- Буква набрана Inter 700. Начертание должно быть загружено — иначе браузер рисует поддельный жирный.
- Глиф опущен на 1px: наклонный глянец тянет оптический центр вверх.
- На чужом фоне знак кладётся на плашку
--brand-plate.
Не так
- Не перекрашивать градиент под контекст — он часть узнавания.
- Не растягивать: знак всегда квадратный.
- Не класть на фотографию без плашки — стеклянная тень пропадает.
- Не набирать «Maia» капсом и не разряжать трекингом.
Цвет
Клик по образцу копирует имя токена. Значения меняются вместе с темой —
переключите её в шапке и сравните. Цифра в углу — контрастность к той
базе, на которой токен реально лежит: текст меряется к фону,
--on-accent — к акценту. Красная означает, что порог не взят.
Где сравнение бессмысленно — градиент, полупрозрачная поверхность — цифры
нет.
Бренд
Акцент инвертируется по яркости: на тёмном фоне светлый изумруд, на светлом — глубокий. Поэтому текст на акценте тоже разный.
--on-accent почти чёрный. Брать #fff вслепую нельзя.Текст
--txt-3 для того, что
можно не прочитать. Всё, что несёт смысл, — минимум --txt-2.Поверхности
Полупрозрачные слои. Контрастность для них не считается — она зависит от того, что оказалось под панелью.
Статусы
Четыре семейства по четыре токена: фон, рамка, текст, точка. Цвет никогда не единственный носитель смысла — рядом всегда точка и слово. Ниже измерены текстовые токены: именно они несут смысл. Точка декоративна и порогом не связана.
Фон
Три радиальных пятна одинаковой геометрии в обеих темах, разной светлоты,
поверх диагонального градиента. При prefers-reduced-transparency
заменяется плотным --solid-bg.
Типографика
Inter — и заголовки, и текст. Один шрифт вместо пары: направление VisionOS требует нейтральной системной ясности, а контраст засечки против гротеска добавил бы характера там, где он мешает читать данные.
Начертания
@fontsource/inter
в кабинете, woff2 в бандле лендинга. Google Fonts не подключается — под РФ
внешний CDN может отдать таймаут, страница молча упадёт на системный стек,
и это будет другой дизайн, о котором никто не узнает.Шкала
Правила набора
Так
- Трекинг заголовков
-.02em: крупный Inter без сжатия выглядит рыхло. - Межстрочный 1.6 в тексте, 1.05–1.2 в заголовках.
- Строка текста 65–75 символов. Шире — глаз теряет начало следующей.
- Числа в таблицах и метриках — класс
.tnum, моноширинные цифры. Иначе колонка дёргается при обновлении. - Над заголовком воздуха больше, чем под ним.
Не так
- Не набирать заголовок градиентом. Выделение делают вес и размер.
- Не ставить надзаголовок-рубрику над заголовком: заголовок несёт себя сам.
- Не использовать моноширинный шрифт «для технологичности» — только для кода, данных и измерений.
- Не вводить размеры вне шкалы.
- Не набирать интерфейсный текст капсом длиннее двух слов.
Ритм и форма
Одна шкала отступов с шагом 4px на весь продукт. Значений вне шкалы в коде быть не должно — кроме оптических поправок в 1–2px, и каждая такая поправка объясняется комментарием на месте.
Отступы
Радиусы
Радиус растёт вместе с элементом. Маленький радиус на большой карточке читается как обрезанный угол, большой на кнопке — как капсула.
--radius-xs9px · чипы, ползунки
--radius-sm11px · поля, меню
--radius13px · кнопки
--radius-md16px · панели
--radius-lg20px · карточки
--radius-pill999px · статусы
Размеры
| Что | Кабинет | Лендинг | Почему |
|---|---|---|---|
| Высота кнопки и поля | 42px | 46px | плотность против пальца на телефоне |
| Ширина содержимого | во всю ширину | 1180px | таблицы шире экрана не бывают лишними |
| Боковая панель | 264 / 216 / 64px | — | полная, узкая, только иконки |
| Строка таблицы | 68px | — | помещается логотип клиента 36px с полями |
grid-auto-rows:1fr). Разнобой
читается как небрежность раньше, чем читается содержание.Материал
Стеклянная панель — четыре слоя, и все четыре обязательны. Убрать любой значит получить полупрозрачный прямоугольник вместо стекла.
1 · Размытие подложки
backdrop-filter: blur() saturate().
Насыщенность выше 100% обязательна — иначе размытый фон сереет и
стекло выглядит грязным.
2 · Заливка и рамка
Полупрозрачная
--panel-bg и рамка --panel-border в 1px.
Заливка нужна, чтобы текст поверх читался.
3 · Верхняя кромка
Внутренняя тень
inset 0 1px 0. Именно она даёт ощущение толщины —
свет ложится на верхнее ребро.
4 · Блик
Радиальный градиент из
правого верхнего угла в ::after. Один источник света на
всю страницу — блики не спорят между собой.
0 20px 50px — со смещением и
мягким размытием. Цветное свечение без смещения — декорация, а не
глубина.Два веса стекла
.glass
Размытие 22–26px, блик, внешняя тень. Верхнеуровневые поверхности: карточки, модальные окна, боковая панель, шапка.
.glass-lite
Размытие 16px, без блика и без внешней тени. Вложенное: поля ввода, вторичные кнопки, ячейки, сегментные переключатели.
Где стекло запрещено
Контекстное
меню и выпадающие списки — плотная подложка --solid-panel,
размытие выключено. Меню всплывает поверх произвольного содержимого:
под ним может оказаться таблица, картинка или другое меню, и стекло
сделает его нечитаемым.
Компоненты
Готовый набор. Новый экран собирается отсюда; компонента нет в брендбуке — сначала он появляется здесь, потом в коде.
Кнопки
Первичная — изумрудное стекло, на экране она одна. Вторичная — нейтральное стекло того же материала. Опасная — красное стекло, только для необратимого.
Поля ввода
Переключатели
prefers-reduced-motion скольжение выключается.Навигация
Активный пункт — нейтральный стеклянный чип со светлой кромкой, иконка перекрашивается в акцент. Активность не отмечается цветной полосой слева: она спорит с материалом.
Таблица
| Клиент | Статус | Диалогов | Лидов |
|---|---|---|---|
| ППекарня на Мясницкой | Работает | 1 284 | 96 |
| ААвтосервис «Ветер» | Пробный | 312 | 21 |
| ССтоматология «Дента» | На паузе | 0 | 0 |
.tnum. Логотип клиента несёт тот же стеклянный объём поверх
произвольного цвета: светлая кромка, глянец, мягкая тень.Состояния
Экран не готов, пока не нарисованы все шесть. Пустой список и ошибка сети встречаются пользователю чаще, чем идеальный сценарий, — и почти всегда остаются недорисованными.
| Состояние | Как выглядит | Правило |
|---|---|---|
| Обычное | материал по рецепту | — |
| Наведение | подложка --hover, кнопка поднимается на 1px | 0.2s, кривая проекта |
| Фокус | изумрудное кольцо 2px, отступ 2px | только с клавиатуры, от мыши не показывается |
| Нажатие | scale(.975) | без тени — элемент «уходит» вглубь |
| Отключено | прозрачность 0.5, тень снята | курсор обычный, не «запрещено» |
| Загрузка | кольцо в кнопке, серые полосы в списке | заглушка повторяет форму будущих данных |
Пусто, грузится, сломалось
Сервер не ответил за 30 секунд. Данные не потеряны — попробуйте ещё раз.
Иконки
Контурные SVG на сетке 24×24, толщина линии 1.6, скругления на концах. Заливок нет. Цвет наследуется от текста, поэтому иконка сама перекрашивается вместе с темой.
Так
- Размеры в интерфейсе: 20px в навигации, 18px в кнопках и полях, 17px в контекстном меню.
stroke="currentColor"— иконка следует за цветом текста.- Иконка сопровождает слово. В одиночку — только там, где действие общеизвестно.
- Одиночная иконка-кнопка получает
aria-label.
Не так
- Эмодзи вместо иконки — никогда. Они рисуются системным шрифтом, выглядят по-разному на Windows, Mac и Android и не подчиняются теме.
- Не смешивать толщины: сейчас в кабинете гуляет 1.5–2, это ошибка, а не вариативность.
- Не заливать контурную иконку цветом «для акцента».
Движение
Одна кривая на весь продукт: резкий старт, долгий выход. Так двигаются физические предметы, которые тормозятся сопротивлением.
| Токен | Значение | Для чего |
|---|---|---|
--ease | cubic-bezier(.22,1,.36,1) | всё без исключения |
--dur-fast | .12s | появление меню, подсветка пункта |
--dur | .2s | цвет, фон, рамка |
--dur-slow | .28s | сдвиг, тень, масштаб |
Что двигается
- Подъём кнопки на 1px при наведении и уход в
scale(.975)при нажатии. - Скольжение индикатора в сегментном фильтре и переключателе тем.
- Появление контекстного меню — 0.12s, сдвиг на 4px вверх.
- Проявление блоков лендинга при прокрутке — по одному разу, из уже видимого положения.
Что не двигается
- Смена экрана. Кабинет открывают ежедневно: анимация, милая на первом запуске, на сотом становится задержкой.
- Появление данных в таблице.
- Переключение темы — мгновенно, иначе видно, как перекрашиваются слои.
- Одинаковый въезд у каждой секции подряд. Один авторский момент, а не эффект на всём.
prefers-reduced-motion длительности
сокращаются до 0.01ms. Не до нуля — нулевая длительность ломает
переходы, завязанные на событие окончания анимации.Доступность
Стекло и прозрачность — самая рискованная часть системы. Поэтому контрастность посчитана, а не оценена на глаз, и всё лишнее отключается системными настройками пользователя.
Что уже сделано
| Механизм | Что происходит |
|---|---|
prefers-reduced-transparency | стекло становится плотным, блик убирается, фон — сплошной цвет |
prefers-reduced-motion | все переходы 0.01ms, скольжение индикаторов выключено |
color-scheme | системные попапы <select> и автозаполнение приходят в тон темы |
:focus-visible | кольцо только при навигации с клавиатуры; клик мышью рамку не рисует |
| Точка у статуса | смысл не кодируется одним цветом — рядом форма и слово |
Контрастность, измерено
Отношение к плотному фону темы. Порог WCAG AA: 4.5 для текста, 3.0 для крупного и для элементов управления.
| Токен | Тёмная | Светлая | Вердикт |
|---|---|---|---|
--txt | 17.63 | 15.97 | проходит |
--txt-2 | 8.02 | 8.30 | проходит |
--txt-3 | 4.58 | 4.52 | проходит |
--accent | 9.86 | 4.51 | проходит |
--on-accent на акценте | 9.89 | 5.08 | проходит |
| Текст на первичной кнопке | 5.49 | 5.49 | проходит |
| Текст на опасной кнопке | 5.53 | 5.53 | проходит |
--danger | 6.49 | 4.99 | проходит |
--txt-3 поднят с .42/.52 до .47/.60. Стопы обеих цветных
кнопок затемнены — тень под текстом контраст не заменяет. Светлый
--danger сдвинут с #C4443E на
#B93B35. Для кнопок взят худший случай: белый текст на самом
светлом стопе градиента поверх самой светлой подложки.Голос
Maia продаёт результат, а не технологию. Клиент агентства покупает отвеченные заявки, а не векторный поиск.
| Вместо | Пишем |
|---|---|
| Осуществите активацию бота | Включите бота |
| Данные успешно сохранены | Сохранили |
| Ошибка 500. Что-то пошло не так | Сервер не ответил. Данные не потеряны, попробуйте ещё раз |
| Инновационная AI-платформа нового поколения | Бот отвечает клиентам за секунды и приводит заявки круглосуточно |
| Нет данных | Клиентов пока нет. Добавьте первого — бот заработает через 10 минут |
| Неверный формат | Не хватает домена после @ |
pishi.Расхождения
Лендинг портирован из кабинета. Двенадцать мест разошлись — все сведены 3 августа 2026. Таблица оставлена как история решений: она объясняет, почему высота кнопки различается намеренно, а всё остальное нет.
| Что | Было в кабинете | Было на лендинге | Стало |
|---|---|---|---|
| Базовый размер текста | 15px | 16px | 16px везде, таблицы на --t-table |
| Шкала отступов | s1…s10 | s1…s20 с пропусками | полная сплошная в обоих |
| Токены радиусов | нет, литералы | частично | лестница xs…pill в обоих |
| Высота кнопки | 42px | 46px | оставлено намеренно: плотность против пальца |
Класс .pill | метка статуса | акцентная плашка | на лендинге это .tag |
--divider, тёмная | .07 | .09 | .09 |
| Статусные цвета | есть | нет | добавлены на лендинг |
--card-solid, --accent-2 | нет | есть | добавлены в кабинет |
| Inter 700 | не загружался | загружался | загружается в обоих |
| Толщина линии иконок | 1.5 – 2 | 1.8 – 2.5 | 1.6 везде, 30 иконок |
| Полоса прокрутки | стеклянная | системная плоская | стеклянная в обоих |
| Нажатая кнопка | translateY(1px) | scale(.975) | scale(.975) |
.btn мимо токена
--btn-grad: правка цвета из одного места не работала, хотя
токен существовал. Теперь кнопка красится токеном.Применение
Как этим пользоваться и что считается нарушением.
| Файл | Что в нём |
|---|---|
DESIGN.md | контракт системы, источник истины. Правка начинается здесь |
brand/tokens.json | все токены машиночитаемо, плюс рецепты и замеры контраста |
brand/brandbook.html | эта страница |
prototype/src/index.css | реализация в кабинете |
maia24-site/src/styles/theme.css | реализация на лендинге |
Четыре правила
Компонент берётся отсюда
Новый экран собирается из готового. Своего не изобретаем.
Значение — только токеном
Цвет, отступ, радиус вписанные числом в правило — ошибка, а не мелочь.
Нового компонента нет — сначала сюда
Он появляется в брендбуке, потом в коде. Обратный порядок даёт два набора кнопок.
Токен правится в трёх местах
tokens.json и
оба CSS-файла. Расхождение между ними означает, что продукт распался
на два.
Чек-лист перед сдачей экрана
| Обе темы проверены глазами, не рассуждением |
| Нарисованы шесть состояний, включая пустое и ошибку |
| Экран пройден клавиатурой — фокус видно везде |
Смысловой текст не набран --txt-3 |
| Карточки в ряду одной высоты |
| Реальный текст, не «Lorem ipsum» — на всех ширинах |
| Стекло не вложено глубже двух уровней |
| Всплывающие слои на плотной подложке |