THEMES.md: несколько тем, цвета только из схемы (не числом в коде)

This commit is contained in:
Porfiry
2026-09-19 13:49:49 +03:00
parent b2f77d2ed9
commit 6f83766048
5 changed files with 225 additions and 2 deletions
+141
View File
@@ -0,0 +1,141 @@
# Цветовые темы: цвета не пишем в коде
**Правило:** в коде **не должно быть цветов числами**. Цвет берётся из текущей
цветовой схемы по смыслу. Тем будет **несколько** (тёмная, светлая и другие),
и одна и та же деталь интерфейса должна выглядеть правильно в каждой.
**Почему так:** если цвет вписан числом, при смене темы он останется прежним —
и на светлом фоне окажется тёмно-серый текст, тёмная тень или невидимая граница.
Такие места обычно находят уже у пользователя.
---
## Как это выглядит в коде
### Неправильно
```kotlin
Text(
text = "Диалоги",
color = Color(0xFFEBEBEB), // цвет вписан числом
modifier = Modifier.background(Color(0xFF17212B)) // и здесь тоже
)
```
При смене темы этот текст останется белым, а панель — тёмно-синей. В светлой
теме получится белое на белом.
### Правильно
```kotlin
Text(
text = "Диалоги",
color = MaterialTheme.colorScheme.onSurface,
modifier = Modifier.background(MaterialTheme.colorScheme.surface)
)
```
Здесь сказано **что это по смыслу**: текст «на поверхности» и сама «поверхность».
Какие именно цвета — решает схема, а не код.
---
## Имена по смыслу, а не по виду
| Хорошо (по смыслу) | Плохо (по виду) |
|---|---|
| `surface` — поверхность | `darkBlue` — тёмно-синий |
| `onSurface` — текст на поверхности | `almostWhite` — почти белый |
| `primary` — главный акцент | `blue` — синий |
| `error` — ошибка | `red` — красный |
| `outline` — границы | `greyLine` — серая линия |
Смысл от смены темы не меняется, а название цвета — меняется. `darkBlue`
в светлой теме станет ложью в самом названии.
---
## Что именно берётся из схемы
Проверять надо **все** цвета, а не только текст с фоном. Чаще всего забывают:
- **границы** — `outline`, `outlineVariant`;
- **фон «наведения» курсора** и **выбранной строки**;
- **тени** вокруг окон;
- **затемнение** под окном (полупрозрачное чёрное — тоже цвет);
- **цвет неактивного текста** — подписи, время, пояснения;
- **цвет состояния** — «на связи» зелёным, «не отвечает» красным;
- **фон поля ввода** и его рамку при фокусе;
- **цвет значков** и кружка непрочитанных;
- **фон блока кода** и **цвет ссылок** в ответах ассистента;
- **полосы прокрутки**;
- **выделение текста мышью**.
Если деталь где-то не переключилась — она выбивается и её видно сразу.
---
## Особый случай: цвета для различения ассистентов
**Эти цвета из схемы не берутся.** Пользователь задаёт их сам в настройках, чтобы
отличать ассистентов друг от друга. Они заданы сознательно и в другой теме
остаются собой — иначе различие пропадёт.
То есть в клиенте **два разных типа цвета**, и путать их нельзя:
| Тип | Откуда | Меняется ли с темой |
|---|---|---|
| Цвета интерфейса | Из цветовой схемы | **Да** |
| Цвет или картинка ассистента | Заданы пользователем | **Нет** |
**Практический вывод:** там, где подставляется цвет ассистента, нельзя брать
`MaterialTheme.colorScheme.*` — нужен именно пользовательский цвет. И наоборот:
фон строки диалога берётся из схемы, даже если рядом стоит цветная полоска агента.
**Ещё следствие:** пользовательский цвет должен **читаться** на фоне любой темы.
Пять предложенных цветов подобраны под тёмную тему; в светлой какие-то могут
оказаться бледными. Это надо проверить отдельно — либо ограничить набор
безопасными цветами, либо подстраивать яркость под тему.
---
## Что писать в макетах
В `sketches/` и `approved/` цвета стоят числами — **так и надо**, иначе макет
не будет выглядеть задуманным. Это не код.
Правило простое:
- **макеты** — числа, чтобы было видно замысел;
- **код** — имена из схемы, чтобы переключалось.
Проверка при реализации: **поиск по коду на цвета числами и на «#»**. Что нашлось —
то и надо заменить на схему. Исключение — цвета ассистентов из настроек
(см. выше) и, возможно, значения внутри самой схемы, где цвета как раз и задаются.
---
## Готовый образец у нас уже есть
В `ai/assistent`, файл `client-shared/.../ui/FolderTheme.kt` — тема описана
отдельным объектом, с именем, и в комментарии сказано: «Сейчас — одна тёмная тема;
в будущем — переключатель тем (светлая/тёмная)». Идею **берём**, детали —
**Чего в образце нет:** он соблюдается не везде. В том же клиенте **36 цветов
вписаны числами** прямо в экранах (`Color(0xFF4CAF50)` и подобные). Тема есть,
а половина цветов идёт мимо неё. Поэтому наш подход строже:
- **ни одного цвета числом вне самой схемы** — все цвета живут в одном месте;
- **именованные значения для смыслов** — тоже в теме, а не в экране;
- **проверяем на второй теме** — пока не переключили тему и не посмотрели, считать
готовым нельзя.
Разбор — `BORROW-FROM-ASSISTENT.md`, п. 3.10.
## Что осталось решить
- **Какие темы будут кроме тёмной.** Пока известно только: тёмная есть, светлая
предполагается.
- **Переключается ли тема в клиенте или берётся системная** (как в системе —
тёмная/светлая). От этого зависит, нужен ли в настройках отдельный переключатель.
- **Что делать с цветами ассистентов в светлой теме** (см. выше) — проверять
читаемость или ограничить набор.