лендинг: 32 нарушения контраста WCAG AA — затемнены токены, поставлен сторож #3277

Merged
bot-backend merged 2 commits from fix/mera-public-contrast into main 2026-08-30 10:15:15 +00:00
Collaborator

Из отчёта тестировщика 30.08.2026, пункт 4: 32 нарушения color-contrast, все severity=serious. Одно правило, 32 узла — поэтому Lighthouse показывал 97 и занижал масштаб.

Замеры подтвердились

Пересчитал пары прямо из кода:

узел было норма
.heroSubmitBtn (главная кнопка) 4,41 4,5
.artSoon 2,25 4,5
метки тикера 2,85 / 3,68 4,5

Отдельно: шапка b2c-tokens.ts утверждала про accentDeep контраст «4.6:1». Это было не замером, а числом из головы — фактически 4,41. Переписана честными цифрами.

Правка

Затемнены четыре токена до запаса на худшем светлом фоне (surfaceSoft, он темнее pageBg), оттенок сохранён:

accentDeep#0C7B8B (4,97) · muted#5B686C (5,19) · success#177A50 (4,80) · danger#B33D28 (5,23)

Второй класс — светлый текст на тёмной плашке, где шкала перевёрнута: метки тикера и стрелка (1,50 → 6,20).

Плюс убраны сырые hex мимо палитры: 11 вхождений #9fb0b4 разведены на muted для светлых узлов и muted-dark для тёмных. Разводить пришлось поимённо — muted-dark на белом даёт 2,84, то есть механическая замена одним значением сделала бы хуже.

Не тронуты после проверки: .heroListIcon (aria-hidden, axe его не считает), .gameRowLabelAccent и .pathEyebrow — лежат на светлых рядах, сверено по TSX.

Сторож

contrast-tokens.test.ts: функция яркости WCAG + ассерты на значениях токенов для обоих фонов страницы, плюс проверка на новые сырые hex в color:/fill: с явным allowlist.

Фальсификация автором и ревьюером независимо, дважды: возврат muted к #667579 даёт красное с точным числом («muted на pageBg: 4,4478 >= 4,5»), возврат сырого #9fb0b4 — красное со списком вхождений.

Честный потолок

axe заново не гоняли — «32 → 0» не подтверждено. Утверждается только расчёт по значениям: все найденные в коде пары ≥ 4,5. Прогнать axe после деплоя.

Allowlist сканера — снимок, а не расчёт: подложку CSS-правила по тексту не вывести. Помечено ponytail: прямо в коде.

Проверки

vitest 11 файлов / 130 passed · tsc --noEmit rc=0 · eslint --max-warnings 0 rc=0. Всё перепрогнано ревьюером независимо в отдельном worktree.

Замечания ревьюера (не блокеры, беру в следующий заход)

  1. .artLead красит текст токеном границы --b2c-line-dark. Значение сейчас совпадает (11,8:1), но тюнинг рамки молча перекрасит абзац статьи.
  2. Докстринг mutedDark ссылается на старое значение muted — тот же дефект, который эта же правка чинила в шапке файла.
Из отчёта тестировщика 30.08.2026, пункт 4: 32 нарушения `color-contrast`, все severity=serious. Одно правило, 32 узла — поэтому Lighthouse показывал 97 и занижал масштаб. ## Замеры подтвердились Пересчитал пары прямо из кода: | узел | было | норма | |---|---|---| | `.heroSubmitBtn` (главная кнопка) | 4,41 | 4,5 | | `.artSoon` | 2,25 | 4,5 | | метки тикера | 2,85 / 3,68 | 4,5 | Отдельно: шапка `b2c-tokens.ts` утверждала про `accentDeep` контраст «4.6:1». Это было **не замером, а числом из головы** — фактически 4,41. Переписана честными цифрами. ## Правка Затемнены четыре токена до запаса на **худшем** светлом фоне (`surfaceSoft`, он темнее `pageBg`), оттенок сохранён: `accentDeep` → `#0C7B8B` (4,97) · `muted` → `#5B686C` (5,19) · `success` → `#177A50` (4,80) · `danger` → `#B33D28` (5,23) Второй класс — светлый текст на тёмной плашке, где шкала перевёрнута: метки тикера и стрелка (1,50 → 6,20). Плюс убраны сырые hex мимо палитры: 11 вхождений `#9fb0b4` разведены на `muted` для светлых узлов и `muted-dark` для тёмных. Разводить пришлось поимённо — `muted-dark` на белом даёт 2,84, то есть механическая замена одним значением сделала бы хуже. Не тронуты после проверки: `.heroListIcon` (`aria-hidden`, axe его не считает), `.gameRowLabelAccent` и `.pathEyebrow` — лежат на светлых рядах, сверено по TSX. ## Сторож `contrast-tokens.test.ts`: функция яркости WCAG + ассерты на **значениях токенов** для обоих фонов страницы, плюс проверка на новые сырые hex в `color:`/`fill:` с явным allowlist. Фальсификация автором и ревьюером независимо, дважды: возврат `muted` к `#667579` даёт красное с точным числом («muted на pageBg: 4,4478 >= 4,5»), возврат сырого `#9fb0b4` — красное со списком вхождений. ## Честный потолок **axe заново не гоняли — «32 → 0» не подтверждено.** Утверждается только расчёт по значениям: все найденные в коде пары ≥ 4,5. Прогнать axe после деплоя. Allowlist сканера — снимок, а не расчёт: подложку CSS-правила по тексту не вывести. Помечено `ponytail:` прямо в коде. ## Проверки `vitest` 11 файлов / 130 passed · `tsc --noEmit` rc=0 · `eslint --max-warnings 0` rc=0. Всё перепрогнано ревьюером независимо в отдельном worktree. ## Замечания ревьюера (не блокеры, беру в следующий заход) 1. `.artLead` красит **текст** токеном границы `--b2c-line-dark`. Значение сейчас совпадает (11,8:1), но тюнинг рамки молча перекрасит абзац статьи. 2. Докстринг `mutedDark` ссылается на старое значение `muted` — тот же дефект, который эта же правка чинила в шапке файла.
bot-backend added 1 commit 2026-08-30 10:05:13 +00:00
fix(mera-public): контраст WCAG AA на публичном лендинге
All checks were successful
CI Trade-In / changes (pull_request) Successful in 14s
CI / changes (pull_request) Successful in 17s
CI Trade-In / backend-tests (pull_request) Has been skipped
CI Trade-In / browser-tests (pull_request) Has been skipped
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
CI Trade-In / frontend-checks (pull_request) Successful in 2m3s
8aac93ee9b
axe 30.08 нашёл 32 узла color-contrast (все serious). Причина одна на все:
пары «цвет × фон» подбирались глазами, а числа в комментариях писались по
памяти — шапка b2c-tokens.ts утверждала «onAccent на accentDeep 4.6:1», тогда
как реальный замер 4.41, то есть главная кнопка призыва не проходила норму, а
документация уверяла, что проходит.

Затемнены четыре токена до запаса на худшем светлом фоне (surfaceSoft, он
темнее pageBg): accentDeep 4.41→4.97, muted 4.45→5.36, success 4.04→4.96,
danger 4.60→5.23. Оттенок сохранён, фирменный вид не меняется.

Отдельный класс — светлый токен на тёмной плашке surfaceDark, где шкала
перевёрнута: метки тикера красились muted (2.7) и accentText (2.85), стрелка
между прогнозом и фактом — линейным #2c3a3f (1.50). Переведены на mutedDark
(6.2) и accent (6.24). Заодно убраны сырые hex #9fb0b4 (2.24 на светлом —
.artSoon, .gameScale, .repPaidFine, .artFootnote; 7.84 на тёмном) — палитра
запрещает hex в CSS именно потому, что мимо токена величина не считается
никаким аудитом.

Регресс ловится без браузера: contrast-tokens.test.ts считает яркость по
формуле WCAG прямо на значениях токенов и проверяет ОБА фона страницы, плюс
сторож на новые сырые hex в CSS. Проверен фальсификацией: возврат muted к
#667579 красит тест.
bot-backend added 1 commit 2026-08-30 10:13:28 +00:00
Merge branch 'main' into fix/mera-public-contrast
All checks were successful
CI Trade-In / changes (pull_request) Successful in 12s
CI Trade-In / backend-tests (pull_request) Has been skipped
CI Trade-In / browser-tests (pull_request) Has been skipped
CI / changes (pull_request) Successful in 14s
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
CI Trade-In / frontend-checks (pull_request) Successful in 1m20s
be59ca4452
bot-backend merged commit 53a1b9ba89 into main 2026-08-30 10:15:15 +00:00
bot-backend deleted branch fix/mera-public-contrast 2026-08-30 10:15:16 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: lekss361/gendesign#3277
No description provided.