ADR 0181 — Тёмная тема становится нейтрально-чёрной, и долг контраста заканчивается
Статус
Accepted. 2026-09-30 (AT-283 и AT-284, история HS-073, эпик EP-031,
раунд 29). Поверх ADR 0074
(достижимая тема, измерение в обеих темах, восемь синтаксических ролей) и
ADR 0036 (мерило "handoff устанавливает
намерение, измерение устанавливает число"). Не редактирует их: МЕХАНИЗМ 0074
остаётся целиком — boot файлом, две измеряемые темы, выведенный паритет,
восемь --syntax-*; меняется ЧИСЛО почти каждого цветового токена, а с
ним три вещи, которые 0074 утверждал о тёмной теме.
Контекст
Тёмная тема была насыщенной сине-бирюзовой (--surface-0 #061b24, тон 198°,
насыщенность ~71%) с кремовым текстом и ярким терракотовым акцентом (#d6633a). Решение
владельца от 2026-09-30: продукт получает рыночную нейтрально-чёрную тёмную тему,
спокойную, со смягчённым терракотовым акцентом (идентичность остаётся в акценте, а не в
поверхности), а светлая становится нейтральной из того же семейства вместо песочной
бумаги.
Перед заменой весили три измеренных факта:
- Тёмная тема несла долг контраста с FASE 16. Пять используемых пар
были ниже 4,5:1 —
--text-mutedна--surface-1(3,89) и--surface-2(3,10),--accentи--dangerна--surface-1(3,88), и--successна--surface-2(4,41). 0074 зафиксировал их числом, и четыре экрана сменили токен, чтобы обойти это (.hint,.link, блок состояния окружения, навигация ошибки Shell). - У основной кнопки было "известное исключение".
--on-accent(крем) на--accentдавал 3,20:1 в тёмной; ADR 0036 отказался это чинить, потому что "меняет марку во всём UI". Тот же крем на--successвButtonдавал 2,07:1. - Цвет вне токенов. Три места, рисующие runtime-библиотекой
(Mermaid, xterm, canvas миникарты), имели 27 hex-fallback, написанных
вручную, в прежнем бирюзовом, а "person" C4 использовал СЫРУЮ палитру
--teal-400/600. Три цвета агентов были отдельными hex вlib/agents.ts, откалиброванными только по тёмной. OverlayModalбыл бирюзовым вrgba. И два используемых токена не существовали:--surface-3и--radius-pill.
Решение
1. Семантические значения меняются; имена — нет. Ни одному модулю не нужно
менять ссылку: --surface-*, --text-*, --accent*, --on-accent,
состояния, --violet, границы, --code-bg, --diff-* и восемь --syntax-*
сохраняют прежние имена. Вводится сырая шкала --neutro-*
(000…950, цинк без тона), на которую ссылаются поверхности, вторичный текст и
границы обеих тем; четыре старые сырые матрицы остаются
(никто не использует их в UI, а их удаление ничего бы не дало).
2. Число берётся из измерения, а не из черновика. Черновик владельца был отправной точкой; где он не проходил, число корректировалось, пока порог не проходил:
| токен (тёмная) | черновик | итог | почему |
|---|---|---|---|
--text-muted | #71717a | #86868f | черновик повторял долг (3,80 / 3,51 на карточке и заголовке); итог даёт 5,38 / 5,10 / 4,70 и остаётся ниже --text-secondary |
--on-accent | (светлый) | --neutro-900 | белый на #c8744f дал бы 3,46 и 2,68 при hover; нейтральный чёрный даёт 5,61 / 7,25, и 7,65 на --success, 5,24 на --danger |
| токен (светлая) | черновик | итог | почему |
|---|---|---|---|
--text-muted | #71717a | #696972 | черновик давал 4,40 на --surface-2, а светлая закрывает текст на 4,5 со времён 0074 |
Остальной черновик прошёл как был: поверхности #0d0d0f/#141417/#1c1c21,
границы #2a2a30/#3a3a42, текст #ececef/#a1a1aa, акцент #c8744f, состояния
#3fb68b/#d4a13a/#e5534b, --code-bg #0a0a0c; в светлой #ffffff/#fafafa/ #f4f4f5, текст #18181b/#52525b и затемнённая терракота #a4502c (5,08
против --code-bg, 5,58 с белым кнопки). Восемь --syntax-* были
пересчитаны против двух новых --code-bg и проходят 4,5:1 в обеих темах
(наименьший — --syntax-type светлой, 4,85). Акцент остаётся терракотовым:
тон держится около ~18° в обеих темах, и это проверяется тестом.
3. Долг тёмной темы заканчивается, а то, что было зафиксированным числом, становится ПОРОГОМ. Пять
пар долга проходят 4,5:1 в обеих темах, и тест теперь требует порог
вместо "continua em 3,89". Два ИНВЕРТИРОВАННЫХ утверждения
design-contraste.test.ts ("muted reprova sobre card", "accent reprova sobre
card") переписаны как порог, а потребители пересмотрены: .link
(AuthLayout) возвращается к --accent, которого всегда требовал макет; .hint (Input) остаётся
на --text-secondary, теперь по иерархии, а не по контрасту. Исключение
основной кнопки перестаёт существовать, и исправление не изменило марку — изменило
ТЕКСТ на ней.
4. Цвет вне токенов входит в токены (AT-284).
apps/web/src/lib/tokens-padrao.tsхранит ОДНУ копию значений основной темы для Mermaid, xterm и миникарты, аtokens-padrao.test.tsпроваливается, когда она расходится с:root. "person" C4 переходит на--accentна--surface-1.--agent-leve,--agent-frontendи--agent-secopsрождаются со значением для каждой темы и измеряются на 3:1 на трёх поверхностях; вlib/agents.tsостаётся толькоvar(--token), и тест проваливает hex.--overlay— вуальModal, для каждой темы.--surface-3и--radius-pillНЕ рождаются: оба использования переходят на то, что уже отрисовывали (--surface-1/--surface-2и--r-pill), аdesign-tokens-existentes.test.tsпроваливает следующийvar(--x)без объявления в CSS и без записи в runtime.
Последствия
- Пробел "dívida de contraste do tema ESCURO travada por número (ADR 0074)"
в
CLAUDE.mdзакрывается. Правило никогда не ослаблять порог сохраняется, теперь без зарегистрированного исключения. - 111
color-mix()модулей (AT-285) здесь НЕ пересматривались: они смешивают токены и остаются валидными, но визуальный результат каждого меняется с новой базой, и пересмотр — дело отдельной lane. - Несколько комментариев CSS-модулей цитируют старые числа долга
(
Shell.module.css,SinaisDoAmbiente.module.css,ProjectCard.module.css,ProjectRail.module.css,TurnActivityStrip.module.css,Input.module.cssв placeholder). Обосновываемые ими выборы остаются валидными; цитируемое число историческое. Их обновление — дело пересмотра модулей. - Сайт документации (
website/src/css/custom.css) имеет собственную палитру и не затрагивался. - Превью
.design-sync, зависящие от контраста, остаются невалидными до следующей визуальной валидации (об этом говорит сам тамошний NOTES.md).