Дизайн-система MTRNTV

Единый набор цветов, размеров и готовых элементов, из которых собираются наши интерфейсы. Эта страница сделана самой системой: каждый пример здесь живой и нарисован теми же переменными, что рабочий продукт.

110переменных
17элементов
68иконок
2оформления
6брендов
01

Бренд

6 брендов

Бренд — это то немногое, что меняется от продукта к продукту: фирменный цвет и знак. Всё остальное в системе общее — размеры, элементы, правила. Сейчас брендов шесть, и различаются они ровно двумя вещами.

Знак

Чёрная плашка, внутри белый знак. Без надписей рядом. В тёмном оформлении плашка и знак меняются местами — знак остаётся читаемым на любом фоне. Сам знак берётся из фирменного логотипа бренда: если логотип текстовый, из него вырезается первая буква.

светлое
тёмное
Обычныйплашка 28, скругление 6, знак 15Крупныйплашка 44, скругление 8, знак 24

Фирменный цвет

Один цвет на весь интерфейс: им отмечают выбранное, подсвечивают активное поле и красят главную кнопку. Семь оттенков — один основной и шесть производных для состояний и подложек. У части брендов есть второй цвет — фон или подложка; он не заменяет основной и в интерфейсе работает как поверхность.

Основной#0099ff
Под курсором#007ed6
При нажатии#0066ad
Рамка#a8d7ff
Подложка#d6ecff
Лёгкая подложка#ebf6ff
В тёмном оформлениицвет светлее — на тёмном фоне исходный синий читается плохо. Это тот же цвет, поднятый по яркости

Бренды системы

Каждый бренд — это знак в чёрной плашке и один фирменный цвет. Плашка, её скругление, размер знака и всё остальное общие: меняются только эти две вещи.

Letteros редактор HTML-коммуникаций
#0099ff
#eceef1
Mailfit CRM-агентство и CRM-платформа
#f4512d
#f4f3ee
Finalyty управленческий учёт и финансовая аналитика
#acbf69
Selgram магазины в Telegram
#05c5f0
#14181c
Aiatos командная работа и база знаний
#00d0f0
База Роста сообщество growth-инженеров
#e9fb04
#0f133a
Плашкаодна на все бренды: 28 или 44, скругление 6 и 8Знаккрасится цветом текста — в тёмном оформлении меняется самВторой цветесть не у всех: это фон или подложка бренда, не замена основному

Как добавить бренд

Новому бренду нужны только два набора значений — семь оттенков фирменного цвета и свой знак. Размеры, отступы, скругления, элементы и правила остаются общими, поэтому интерфейс собирается тот же, а выглядит по-своему.

Что задаёт брендЧто остаётся общим
Семь оттенков фирменного цветаСерая шкала, сигнальные цвета, все назначения
Знак и его размеры в плашкеШрифт, размеры текста, начертания
При необходимости — своя пара цветов для тёмного оформленияОтступы, скругления, высоты, тени, порядок наложения
Все 17 элементов интерфейса и 68 иконок
02

Цвет

серая шкала, назначения, сигналы

Кроме фирменного цвета в системе есть серая шкала и три сигнальных цвета. Элементы не берут оттенок из шкалы напрямую: между ними стоит слой назначений, и именно он переключает светлое оформление на тёмное.

Серая шкала

Тринадцать ступеней от белого до почти чёрного. Из них строятся фоны, границы и текст. В тёмном оформлении шкала разворачивается целиком, поэтому все назначения переводятся сами.

Светлое оформление

Тёмное оформление

Исходники знаков

Все файлы бренда в одном месте: знак в плашке, как он стоит в интерфейсе; знак отдельно, чтобы вставить куда угодно; знак фирменным цветом и то, что отдаёт сам продукт. Формат SVG — масштабируется без потерь и красится прямо в коде.

Letteros4
В плашкекак в интерфейсе
Скачать
Знакчёрный, прозрачный фон
Скачать
Знак в цветефирменным цветом
Скачать
Исходник продуктакак отдаёт продукт
Скачать
Mailfit5
В плашкекак в интерфейсе
Скачать
Знакчёрный, прозрачный фон
Скачать
Знак в цветефирменным цветом
Скачать
Исходник продуктакак отдаёт продукт
Скачать
Со словомлоготип с надписью
Скачать
Finalyty4
В плашкекак в интерфейсе
Скачать
Знакчёрный, прозрачный фон
Скачать
Знак в цветефирменным цветом
Скачать
Исходник продуктакак отдаёт продукт
Скачать
Selgram4
В плашкекак в интерфейсе
Скачать
Знакчёрный, прозрачный фон
Скачать
Знак в цветефирменным цветом
Скачать
Исходник продуктакак отдаёт продукт
Скачать
Aiatos4
В плашкекак в интерфейсе
Скачать
Знакчёрный, прозрачный фон
Скачать
Знак в цветефирменным цветом
Скачать
Оригинал от брендарастр, с которого перерисован знак
База Роста5
В плашкекак в интерфейсе
Скачать
Знакчёрный, прозрачный фон
Скачать
Знак в цветефирменным цветом
Скачать
Вертикальныйдля тёмного фона
Скачать
Горизонтальныйдля тёмного фона
Скачать
Скачатьсохраняет файлКопироватькладёт разметку в буфер — работает и там, где скачивание запрещено
Как называютсяот --c-n-0 — белый, до --c-n-900 — почти чёрный

Назначения — то, что пишут в элементах

Элемент не знает про пятнадцатую ступень серого. Он знает, что рисует границу. Это единственный слой, который перенастраивают, если продукту нужен другой оттенок серого.

НазначениеСветлоеТёмноеГде встречается
--c-bg-app#eceef1#121215фон рабочей области под письмом и списками
--c-bg-surfaceбелый#17171aкарточки, боковая панель, окна
--c-bg-subtle#fafafb#1b1b1fнижняя полоса карточки с кнопками
--c-bg-hover#f4f4f5#26262cстрока списка и пункт меню под курсором
--c-border#ececef#2f2f36границы карточек и разделители
--c-border-strong#e4e4e7#3a3a43линейка над письмом, дорожка ползунка
--c-text#18181b#f5f5f8основной текст
--c-text-muted#71717a#a3a3b0подписи над полями, пояснения
--c-text-subtle#a1a1aa#8b8b98единицы измерения, счётчики, иконки в покое
--c-text-inverseбелый#17171aтекст поверх фирменного цвета
--c-focus-ringполупрозрачный синийполупрозрачный синийсвечение вокруг поля, на которое перешли клавишей Tab
--c-overlayзатемнение 45%затемнение 60%подложка под открытым окном
--c-inverse-surface#27272a#33333aтёмная плашка поверх содержимого

Поля и кнопки: заливка вместо рамки

Кнопки, поля и списки — это серые прямоугольники, а не белые в тонкой обводке. Под них выделены отдельные назначения, потому что цвет настоящих границ трогать нельзя: он же держит рамки окон, линейку над письмом и разделители панелей.

НазначениеЧто делает
--c-control-bgзаливка поля или кнопки в спокойном состоянии
--c-control-bg-hoverпод курсором
--c-control-bg-activeв момент нажатия
--c-control-borderпрозрачная рамка. Она не убрана, а именно прозрачна: её толщина по-прежнему занимает место, поэтому при переходе в поле или при ошибке рамка просто перекрашивается и ничего не сдвигается
--c-ghost-bg-hoverкнопка-иконка: в покое она без фона, заливка появляется только под курсором

Сигнальные цвета

Три набора по три оттенка: сам цвет, подложка и граница. Используются в уведомлениях, ошибках полей и опасных действиях — и больше нигде, чтобы красный всегда означал одно и то же.

Письмо опубликовано
Такой адрес уже занят
Черновик сохранён
Успех#16a34aОшибка#dc2626Предупреждение#b45309В тёмном оформлениисам цвет тот же, подложка и граница темнеют
03

Шрифт и размеры

Inter, свои файлы

Один шрифт на весь интерфейс — Inter. Он лежит своими файлами рядом с приложением, а не тянется из интернета: так текст не моргает чужим начертанием при первой загрузке. Взяты только латиница и кириллица.

Размеры текста

У каждого размера своя работа. Размера «просто побольше» в системе нет: если подходящий не нашёлся, значит элемент делает что-то новое.

--fs-2xsЕдиницы измерения и мелкие метки10
--fs-xsПодсказка под полем11
--fs-smПодписи над полями, фильтры12
--fs-baseОсновной текст интерфейса и надписи на кнопках13
--fs-mdЗаголовок карточки14
--fs-lgЗаголовок окна16
--fs-xlЗаголовок экрана20
--fs-2xlКрупный заголовок24
--fs-3xlЗаголовок раздела на странице32
--fs-4xlЗаголовок страницы42
13 — рабочий размер интерфейсадве верхние ступени нужны страницам и сайту, в самом редакторе они не используются

Насыщенность

ОбычныйТекст и значения полей400
СреднийПодписи, пункты меню500
ПолужирныйКнопки, заголовки блоков600
ЖирныйЗаголовки экранов700

Высота строки и общие заголовки

ПлотноДля заголовков1.25
ОбычноДля текста абзацем1.5
Заголовок экранажирный, 20 — общий стиль на всех экранахПояснение под нимобычный, 13, приглушённый
04

Отступы и формы

шаг 4 пикселя

Расстояния, скругления, высоты, тени, порядок наложения и скорость движения. Скруглений два набора: один отвечает на вопрос «насколько круглый», второй — «что именно скругляем». В работе пользуются вторым.

Расстояния

Все кратны четырём. Число не из этого списка — повод остановиться.

4самый мелкий зазор
8внутри кнопки, между иконкой и текстом
12между соседними кнопками и полями
16между блоками
20поля внутри карточки
24крупный отступ
32поля страницы
40вокруг сообщения «здесь пусто»

Скругления по назначению

12кнопки, поля, фильтры, пункты меню
16карточки, окна, выпадающие меню
8мелкие метки внутри кнопок
Вложенное скруглениеповторяет внешнее минус отступ — иначе внутренний прямоугольник выглядит квадратным в круглом

Высоты кнопок и полей

Четыре значения на весь продукт. Соседние элементы в одном ряду обязаны быть одной высоты.

28мелкая кнопка, переключатель
32панель свойств, фильтры, списки
38формы и обычные кнопки
44главная кнопка формы входа

Тени

лёгкая
средняя
глубокая
приподнятая
Лёгкаякружок тумблераСредняявыпадающее меню, уведомлениеГлубокаяокно поверх экранаПриподнятаявыбранный сегмент переключателя

Что поверх чего

Единственный список, откуда берут порядок наложения. Числа по месту не пишут.

Подсказки на письме5
Боковая панель20
Закреплённые элементы50
Выпадающие меню400
Окна600
Уведомления800

Скорость

Два значения. Быстрое — для смены цвета и фона, обычное — для перемещения.

0,12 сцвет, фон, рамка0,2 сперемещение

Ширина экрана

Две точки, в которых интерфейс перестраивается.

1024панели редактора выезжают поверх письма
900боковая панель уезжает в выезжающую и открывается кнопкой
560окно превращается в шторку снизу, кнопки под карточкой встают столбиком
05

Элементы интерфейса

17 готовых

Семнадцать готовых элементов, из которых собираются экраны. У каждого — живой образец, таблица состояний, разметка для копирования и адрес файла в коде.

Кнопка

Четыре вида: главная, обычная, контурная и опасная. Обычная держится на серой заливке, контурная — на рамке. Под курсором все четыре ведут себя одинаково: заливка становится контрастной — в светлом оформлении чёрной, в тёмном белой, — а у опасной красной.

ВидОбычноПод курсоромПри нажатииС клавиатурыНедоступнаИдёт работа
Главная фирменная контрастная на тон мягче рамка 2px полупрозрачна кнопка заблокирована
Обычная серая контрастная на тон мягче рамка 2px полупрозрачна кнопка заблокирована
Контурная рамка, без заливки контрастная на тон мягче рамка 2px полупрозрачна кнопка заблокирована
Опасная на поверхности красная красная, темнее рамка 2px полупрозрачна кнопка заблокирована
светлая
тёмная
Виды:главная, обычная, контурная, опаснаяВысоты:28, 38 и 44 пикселяУмеет:иконку слева, индикатор работы, блокировку, растягивание на всю ширину
Показать разметку
<!-- Vue -->
<UiButton variant="primary" icon="plus" @click="create">Создать</UiButton>
<UiButton variant="outline" size="sm" :loading="saving">Сохранить</UiButton>

<!-- Чистый HTML при переносе -->
<button class="ui-btn primary" type="button">
  <svg width="15" height="15">…</svg>
  <span>Создать</span>
</button>
Где в коде: src/components/ui/UiButton.vue129 строк

Поле ввода

Глазок для показа пароля встроен внутрь. Подпись, подсказка и текст ошибки связаны с полем по-настоящему: по клику на подпись курсор встаёт в поле, а программа чтения с экрана называет поле по имени.

СостояниеКак выглядитРамкаЗаливкаПодпись под полем
Обычно
прозрачнаясераяприглушённая
Курсор в поле
фирменный цветсераяприглушённая
Ошибка
краснаясераякрасная, зачитывается вслух
Недоступно
прозрачнаясветлее обычнойбледная

На него придёт подтверждение

От 8 символов

Принимает:текст, почту, пароль, телефон, адрес, число, поискДве высоты:32 — в панели свойств, 38 — в формах
Показать разметку
<UiFormField label="Email" :error="errors.email" required v-slot="{ id, describedBy, invalid }">
  <UiInput :id="id" v-model="email" type="email" icon="mail"
           :described-by="describedBy" :invalid="invalid" />
</UiFormField>
Где в коде: UiInput.vue · UiFormField.vue135 + 59 строк

Выпадающий список, число и строка свойства

Три элемента панели свойств. У списка своя стрелка, а не браузерная — иначе он остаётся светлым в тёмном оформлении. В числовом поле буква слева и единица справа стоят рядом с цифрами, а не поверх них, поэтому число не обрезается на узкой панели.

px
Шpx
Строка свойстваподпись, элемент и подсказка под ним — из этих строк собрана панель справа
Где в коде: UiSelect.vue · UiNumber.vue · UiField.vue62 + 113 + 43 строки

Отступы по сторонам

Отступы задаются крестом: сторону показывает положение поля, поэтому подписи не нужны и всё помещается на узкой панели. Скрепка в середине включает связывание — правишь левый отступ, правый меняется следом.

px
px
px
px
Раскладкатри на три, зазор 4Скрепкавысота 32, состояние видно по цвету
Где в коде: src/components/ui/UiSides.vue126 строк

Переключатель режимов

Один переключатель на весь продукт: и выравнивание текста, и вкладки панели, и режимы просмотра. Внутри настоящие радиокнопки, поэтому по группе можно ходить стрелками с клавиатуры.

светлая
тёмная
Ширинана всю строку или по содержимомуБез подписейкаждой кнопке нужна подсказка при наведении
Где в коде: src/components/ui/UiSegment.vue113 строк

Тумблер

Размер34 на 20, кружок 16Скорость0,2 секунды
Где в коде: UiSwitch.vue78 строк

Фильтры списка

Высота и скруглениете же, что у поиска и сортировки в том же ряду
Где в коде: src/styles/tokens.cssотдельного элемента нет — только стиль

Выпадающее меню

Закрывается клавишей Escape, щелчком мимо и уходом курсора с клавиатуры. Галочка «выбрано» — отдельное свойство пункта, а не картинка внутри подписи.

Три состояния отметкивыбран, не выбран и «отметки тут нет» — последнее для обычных пунктов вроде «Выйти»
Где в коде: UiDropdown.vue · UiMenuItem.vue55 + 96 строк

Карточка

Личные данные

Имя, аватар и пароль. Видны только вам.

Из чего состоитзаголовок, содержимое и полоса с кнопками внизуНа узком экранекнопки внизу встают столбиком
Где в коде: UiCard.vue58 строк

Окно поверх экрана

Закрывается по Escape, не выпускает курсор клавиатуры наружу, возвращает его на место при закрытии и не даёт странице прокручиваться под собой. Своих окон в продукте не заводят — берут это.

Удалить письмо?

«Промо −20%» уедет в корзину. Восстановить можно 30 дней.

Три ширины400, 560 и 860Можно запретить закрытиенапример, пока идёт сохранениеНа телефонепревращается в шторку снизу
Где в коде: UiModal.vue163 строки · самый крупный в наборе

Уведомления

Появляются в правом нижнем углу и не мешают работать. Программа чтения с экрана произносит текст, но не перебрасывает курсор.

Письмо опубликовано
Слаг занят другим письмом
Черновик сохранён
Где в коде: UiToaster.vue + composables/useToast123 строки

Сообщение «здесь пусто»

Показывается, когда показывать нечего: объясняет, что список пуст, и предлагает действие.

В медиатеке пусто

Загрузите картинки, чтобы вставлять их в письма без внешних ссылок.

Где в коде: UiEmptyState.vue51 строка

Раскрывающийся раздел

Фон
Типографика

Шрифт, размер, цвет текста и ссылок

Работает без скриптоввстроенная возможность браузера
Где в коде: components/panels/Acc.vue + класс в tokens.css

Индикатор загрузки и поле для ссылки

12 / 16 / 22

Голый домен получит протокол сам; «#» и example.com подсвечиваются как заглушка

Где в коде: UiSpinner.vue · UiLinkField.vue + lib/linkUrl.ts34 + 124 строки
06

Иконки

68 знаков

Один набор, разложенный по месту работы. Все нарисованы линией одной толщины и красятся цветом текста рядом, поэтому один и тот же знак работает в обоих оформлениях. Нажмите на знак, чтобы скопировать название.

68 из 68
Размеры по месту:13 в мелкой кнопке, 15 в обычной, 16 в окне, 22 в сообщении «здесь пусто»
07

Устройство экранов

без верхней полосы

Верхней полосы в интерфейсе нет. Знак, выбор проекта, разделы, счётчики и меню пользователя живут в боковой панели слева, а рабочая область начинается прямо от края окна. В редакторе к ней добавляется вторая панель справа — свойства выбранного блока, настройки самого редактора и AI-ассистент.

Общий каркас

Слева боковая панель фиксированной ширины, справа рабочая область. Панель прижата к верху и низу окна и прокручивается отдельно от содержимого.

Проект
Оплата
рабочая область
от края до края
Боковая панель280Поля рабочей области32Верхняя полосанет

Что в боковой панели

Сверху вниз, всегда в этом порядке.

Пункт менювысота 38, скругление 12Выбранныйподложка фирменного цвета, текст тоже фирменныйЗаголовок группымелкий, приглушённый, без фона
Панель слева на этой странице собрана по этому же описанию: знак и выбор бренда наверху, разделы группами, счётчики и карточка с переключением оформления внизу. На узком экране она уезжает и открывается кнопкой.

Список

280панель
карточки
не уже 236
панель 280поля 32зазор 12
Уже 900панель уезжает в выезжающую и открывается кнопкой

Страница раздела

280панель
колонка
не шире 720
панель 280колонка 720
Колонка 720формы в две колонки, на узком — в одну

Редактор письма

280блоки
письмо
600
280свойства,
настройки,
ассистент
обе панели 280письмо 600
Правая панель остаётсясвойства выбранного блока, настройки редактора и AI-ассистентУже 1024панели выезжают поверх письма

Ширина боковой панели

Одна на все экраны — 280 пикселей. Столько нужно картинкам раскладок в редакторе, и столько же хватает панели свойств, чтобы числа в полях не обрезались.

Панель280Колонка разделане шире 720Карточка в спискене уже 236Письмо в редакторе600
08

Правила

как пользоваться системой

Девять правил, которые держат систему целой. Их соблюдают во всех продуктах, где она применяется.

Цвета и размеры — только переменными

Число или цвет, вписанные прямо в элемент, не переключаются вместе с оформлением, не находятся поиском и не участвуют в общей правке.

Поля и кнопки держатся на заливке, а не на рамке

Это серый прямоугольник, а не белый в обводке. Рамка при этом не убрана, а прозрачна: её толщина занимает место, поэтому при переходе в поле или при ошибке она просто перекрашивается и ничего не сдвигается.

Под курсором кнопка становится контрастной

Не соседний оттенок серого, а противоположный конец шкалы: в светлом оформлении чёрная заливка с белой надписью, в тёмном — белая с тёмной. У опасной кнопки заливка красная, надпись белая в обоих оформлениях. Соседний оттенок сливается с фоном страницы, и человек не понимает, наведено или нет.

Кнопки без формы в системе нет

Третий вид — контурный: прозрачная заливка, но видимая рамка и надпись обычного цвета. Кнопка, у которой в покое нет ни заливки, ни рамки, не читается как кнопка: рядом с залитыми соседями её просто не находят.

Рамка берётся не из обычной границы — та на сером фоне рабочей области даёт контраст 1,0 и не видна вовсе. Для неё есть свой серый, который виден и на карточке, и на фоне.

Единственное исключение — квадратная кнопка-иконка

У неё рамки нет: рядом со знаком в шапке две обводки подряд читаются как две плашки. Форму ей даёт сама иконка, а под курсором она заливается так же, как все остальные.

Скругление выбирают по назначению

Три значения: для кнопок и полей, для карточек и окон, для мелких меток. Вложенное скругление повторяет внешнее минус отступ.

Соседние элементы — одной высоты

Высоту берут из четырёх значений системы, и весь ряд собирается из одного. Поиск, сортировка и фильтр рядом друг с другом — это одна высота и одно скругление.

Галочки и радиокнопки остаются настоящими

Их прячут прозрачностью, а не выключают совсем: иначе они выпадают из порядка обхода клавишей Tab, по группе перестают ходить стрелки и пропадает подсветка выбранного с клавиатуры.

Подпись связана с полем по-настоящему

Не текст рядом, а связка: клик по подписи ставит курсор в поле, программа чтения с экрана называет поле по имени, а текст ошибки читается вместе с ним.

Своих окон и выпадающих меню не заводят

Закрытие по Escape, удержание курсора клавиатуры внутри, возврат его на место и блокировка прокрутки уже сделаны в общих элементах — берут их.

Тёмное оформление интерфейса — это не тёмное письмо

Первое красит саму программу. Второе живёт в настройках письма и уезжает в почту получателю. Это разные вещи и разные переключатели.

09

Все переменные

готово к вставке

Светлое и тёмное оформление целиком, с пояснениями. Это всё, что нужно подключить продукту, чтобы говорить на языке системы.

110 переменных, оба оформления
/* Глобальные стили и дизайн-токены оболочки.
   Порт <style> из макета Claude Design (design/), значения сверены с design/README.md.
   ПРАВИЛО: новый код пишет var(--…), хардкод цветов и размеров не добавляем. */
:root {
  /* --- нейтральная шкала (zinc) --- */
  --c-n-0: #ffffff;
  --c-n-25: #fafafb;
  --c-n-50: #fafafa;
  --c-n-100: #f4f4f5;
  --c-n-150: #ececef;
  --c-n-200: #e4e4e7;
  --c-n-300: #d4d4d8;
  --c-n-400: #a1a1aa;
  --c-n-500: #71717a;
  --c-n-600: #52525b;
  --c-n-700: #3f3f46;
  --c-n-800: #27272a;
  --c-n-900: #18181b;

  /* --- акцент --- */
  --c-a-50: #ebf6ff;
  --c-a-100: #d6ecff;
  --c-a-200: #a8d7ff;
  --c-a-500: #33adff;
  --c-a-600: #0099ff;
  --c-a-700: #007ed6;
  --c-a-800: #0066ad; /* нажатие: на ступень темнее ховера */

  /* --- статусы --- */
  --c-danger: #dc2626;
  --c-danger-bg: #fef2f2;
  --c-danger-border: #fecaca;
  --c-warn: #b45309;
  --c-warn-bg: #fef3c7;
  --c-warn-border: #fde68a;
  --c-success: #16a34a;
  --c-success-bg: #f0fdf4;
  --c-success-border: #bbf7d0;

  /* --- семантические роли --- */
  --c-bg-app: #eceef1;
  --c-bg-surface: var(--c-n-0);
  --c-bg-subtle: var(--c-n-25);
  --c-bg-hover: var(--c-n-100);
  --c-border: var(--c-n-150);
  --c-border-strong: var(--c-n-200);
  --c-text: var(--c-n-900);
  --c-text-muted: var(--c-n-500);
  --c-text-subtle: var(--c-n-400);
  --c-text-inverse: var(--c-n-0);
  --c-focus-ring: rgba(0, 153, 255, 0.16);

  /* --- контролы: залитые, без рамки ---
     Кнопки, поля, селекты и чипы держатся на СЕРОЙ ЗАЛИВКЕ, а не на обводке
     белого прямоугольника. Роль отдельная, потому что `--c-border-strong`
     нужен и настоящим границам — рамкам модалок, линейке холста, разделителям
     панелей; если поменять его, поедут и они.

     Рамка не убирается, а становится прозрачной: 1px по-прежнему занимает
     место, поэтому фокус и состояние ошибки перекрашивают её, ничего не
     сдвигая. */
  --c-control-bg: var(--c-n-100);
  --c-control-bg-hover: var(--c-n-150);
  --c-control-bg-active: var(--c-n-200);
  --c-control-border: transparent;

  /* Кнопка-иконка живёт по другому правилу: в покое ПРОЗРАЧНАЯ, заливка
     появляется только под курсором. Постоянная заливка превращала её в плашку,
     и в шапке файл-менеджера рядом со знаком вставали два бокса подряд —
     серый и чёрный. Ховер берётся сразу с `-hover`, а не с `--c-control-bg`:
     из прозрачного в едва заметный #f4f4f5 переход не читается. */
  --c-ghost-bg-hover: var(--c-control-bg-hover);
  --c-ghost-bg-active: var(--c-control-bg-active);

  /* Рамка контурной кнопки. Обычная граница для неё слишком бледная: на сером
     фоне рабочей области даёт контраст 1.0, и кнопки просто не видно. Здесь
     нужен серый, который читается: в светлой теме n-500, в тёмной n-400 —
     та же ступень в тёмной выглядела бы ярче собственной надписи. */
  --c-control-outline: var(--c-n-500);

  /* Наведение на кнопку. Заливка контрастная, а не соседний оттенок серого:
     в светлой теме чёрная, в тёмной белая — обе из одной переменной, потому
     что нейтральная шкала уже развёрнута. Соседний оттенок сливается с фоном
     страницы, и человек не понимает, наведено или нет.
     У опасной кнопки заливка красная, надпись на ней белая в обеих темах. */
  --c-hover-fill: var(--c-n-900);
  --c-hover-fill-active: var(--c-n-800);
  --c-hover-ink: var(--c-text-inverse);
  --c-danger-ink: #ffffff;

  /* Выбранный сегмент переключателя. Всегда СВЕТЛЕЕ подложки контрола:
     в светлой теме это белый, в тёмной — серый на ступень выше подложки.
     Белая плашка на тёмном фоне бьёт по глазам и читается как ошибка. */
  --c-control-raised: var(--c-n-0);

  /* --- скругления по РОЛИ ---
     Шкала `--r-sm…--r-xl` осталась размерной и используется по месту; эти три
     говорят, ЧТО скругляется, и потому меняются осмысленно и разом. Раньше
     радиус выбирался у каждого контрола свой (9px, 11px, --r-md, --r-sm),
     и один ряд кнопок собирал три разных скругления. */
  --r-control: 12px; /* кнопки, поля, чипы, пункты навигации */
  --r-card: 16px; /* карточки, дропдауны, модалки, панели */
  --r-chip: 8px; /* мелкие бейджи внутри контролов */

  /* --- типографика --- */
  --font-sans: 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --fs-2xs: 10px;
  --fs-xs: 11px;
  --fs-sm: 12px;
  --fs-base: 13px;
  --fs-md: 14px;
  --fs-lg: 16px;
  --fs-xl: 20px;
  --fs-2xl: 24px;
  --fw-regular: 400;
  --fw-medium: 500;
  --fw-semibold: 600;
  --fw-bold: 700;
  --lh-tight: 1.25;
  --lh-normal: 1.5;

  /* --- ритм (шаг 4px) --- */
  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 12px;
  --sp-4: 16px;
  --sp-5: 20px;
  --sp-6: 24px;
  --sp-8: 32px;
  --sp-10: 40px;

  /* --- скругления --- */
  --r-xs: 4px;
  --r-sm: 6px;
  --r-md: 8px;
  --r-lg: 12px;
  --r-xl: 16px;
  --r-full: 999px;

  /* --- высоты контролов --- */
  --h-control-sm: 28px;
  --h-control: 32px;
  --h-control-md: 38px;
  --h-control-lg: 44px;

  /* --- тени --- */
  --shadow-sm: 0 1px 2px rgba(24, 24, 27, 0.06);
  --shadow-md: 0 4px 14px rgba(24, 24, 27, 0.1);
  --shadow-lg: 0 12px 40px rgba(24, 24, 27, 0.16);
  /* «приподнятый» сегмент/ручка тумблера — раньше литерал по месту в четырёх правилах */
  --shadow-raised: 0 1px 2px rgba(24, 24, 27, 0.12), 0 0 0 1px rgba(24, 24, 27, 0.04);

  /* --- анимация --- */
  --dur-fast: 0.12s;
  --dur-base: 0.2s;

  /* --- слои: единственный источник z-index, магические числа запрещены --- */
  --z-canvas-affordance: 5;
  --z-panel: 20;
  --z-topbar: 50;
  --z-dropdown: 400;
  --z-modal: 600;
  --z-toast: 800;

  /* --- брейкпоинты (справочно; @media их не читает, значения дублируются в правилах) --- */
  --bp-md: 900px;
  --bp-lg: 1024px;

  /* --- роли, которых не хватало: раньше эти цвета были литералами по месту --- */
  /* подложка модалок — было четыре копии rgba(24,24,27,.35…55) в разных файлах */
  --c-overlay: rgba(24, 24, 27, 0.45);
  /* штриховка зон отступов на холсте; зелёный вообще не имел токена */
  --c-hatch-margin: rgba(0, 153, 255, 0.5);
  --c-hatch-pad: rgba(59, 183, 132, 0.55);
  /* пунктирные рамки «добавить» и заглушки */
  --c-border-dashed: var(--c-n-300);
  /* тёмная плашка поверх контента (панель форматирования текста) */
  --c-inverse-surface: #27272a;
  --c-inverse-text: #e4e4e7;
  --c-inverse-hover: rgba(255, 255, 255, 0.13);

  /* обратная совместимость: раньше был единственный токен */
  --accent: var(--c-a-600);
}

/**
 * Тёмная тема ИНТЕРФЕЙСА. Не путать с тёмной темой письма — та живёт
 * в `settings.darkMode` документа и красит только холст.
 *
 * Переопределяется нейтральная шкала целиком: она используется как «0 — фон,
 * 900 — текст», поэтому её разворот сам переводит все производные роли.
 * Акцент осветляется: indigo-600 на тёмном фоне не набирает контраст.
 */
[data-ui-theme='dark'] {
  --c-n-0: #17171a;
  --c-n-25: #1b1b1f;
  --c-n-50: #1f1f24;
  --c-n-100: #26262c;
  --c-n-150: #2f2f36;
  --c-n-200: #3a3a43;
  --c-n-300: #4c4c57;
  --c-n-400: #8b8b98;
  --c-n-500: #a3a3b0;
  --c-n-600: #bcbcc7;
  --c-n-700: #d2d2da;
  --c-n-800: #e6e6eb;
  --c-n-900: #f5f5f8;

  /* На тёмном #0099ff читается плохо: контраст с фоном чуть выше 3:1, а на
     заливках подписи в нём тонут. Поэтому в тёмной теме акцент светлее — это
     тот же цвет, поднятый по яркости, а не другой. */
  --c-a-50: #0e2a3d;
  --c-a-100: #123b57;
  --c-a-200: #1b5580;
  --c-a-500: #4db6ff;
  --c-a-600: #4db6ff;
  --c-a-700: #7ccbff;
  --c-a-800: #a5dcff;

  --c-bg-app: #121215;
  --c-text-inverse: #17171a;
  --c-focus-ring: rgba(77, 182, 255, 0.25);

  --c-danger-bg: #2a1a1c;
  --c-danger-border: #4d2427;
  --c-success-bg: #16241b;
  --c-success-border: #234d33;
  --c-warn-bg: #2a2312;
  --c-warn-border: #4d4020;

  --c-overlay: rgba(0, 0, 0, 0.6);
  --c-inverse-surface: #33333a;
  --c-inverse-text: #f0f0f4;

  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.5);
  --shadow-md: 0 4px 14px rgba(0, 0, 0, 0.55);
  --shadow-lg: 0 12px 40px rgba(0, 0, 0, 0.6);
  --shadow-raised: 0 1px 2px rgba(0, 0, 0, 0.45), 0 0 0 1px rgba(255, 255, 255, 0.06);

  --c-control-raised: var(--c-n-200);
  --c-control-outline: var(--c-n-400);

  color-scheme: dark;
}