18 KiB
VidConf — тёмные варианты оболочки
Обязательный референс для разработки.
Тёмная тема для экранов «оболочки» (auth/лобби/календарь/join/«мои
конференции»/админка), реализована поверх дизайн-системы, а не взамен
неё. design/tokens.css и design/DESIGN_SYSTEM.md — единственный
источник истины по значениям (см. §0 DESIGN_SYSTEM.md: «светлая тема —
оболочка (со светлым/тёмным вариантом), тёмная — комната конференции
всегда»). Реализация во frontend — frontend/src/hooks/useTheme.ts и
frontend/src/components/ui/ThemeToggle.tsx (см. frontend/README.md,
раздел «Темы оболочки»).
Что здесь
Разметка, контент и русские данные каждого файла — 1:1 копия
соответствующего светлого макета из design/mockups/. Меняется только
цветовая схема: вместо индиго-на-белом (referens.png) — графит-мята-роза-
янтарь той же гаммы, что уже утверждена для комнаты конференции
(collor_ico.png, токены [data-theme="room"] в tokens.css).
| Файл | Светлый прообраз | Экран |
|---|---|---|
login.html |
../auth.html |
Вход / регистрация / подтверждение email |
lobby.html |
../lobby.html |
Лобби — хаб действий 2×2 |
calendar.html |
../calendar.html |
Календарь-менеджер конференций (+ создание/редактирование/отмена) |
join.html |
../join.html |
Подключение по ссылке/номеру → представиться (гость) → пароль |
my-conferences.html |
../my-conferences.html |
Мои конференции |
admin.html |
../admin.html |
Админка (конференции, пользователи, рассылка приглашений) |
room.html и email-summary.html в комплект не входят: комната уже тёмная
(эталон гаммы), а письмо-саммари по правилам проекта всегда светлое
(почтовые клиенты не гарантируют поддержку тёмной темы/CSS-переменных).
Ссылки на «Войти»/«Создать» из lobby.html/my-conferences.html ведут на
уже существующий ../room.html; ссылка «Открыть саммари» — на
../email-summary.html.
Каждый файл самодостаточен: встроенный <style>, инлайн-SVG-иконки
(lucide-совместимые контуры), без CDN и внешних сетевых зависимостей —
открывается двойным кликом. Единственная локальная зависимость —
<link rel="stylesheet" href="../../tokens.css"> (тот же приём, что и в
светлых макетах: используются базовые не-цветовые токены — spacing, радиусы,
типографика, тени-заготовки, шрифты).
Переключатель темы
В шапке каждого макета — сегментированный переключатель ☀ / 🌙 (иконки
Sun/Moon, lucide-стиль), «Тёмная» — активный сегмент. Элемент
статичный (демонстрирует точку входа в реальный toggle, не переключает
тему по клику в макете) и размещён:
login.html— плавающей плашкой в правом верхнем углу (у экрана нет общего топбара, панель бренда/форма — раздельные колонки);lobby.html,calendar.html,my-conferences.html— внутри правой группы топбара, рядом с меню пользователя;join.html— в топбаре, справа от логотипа;admin.html— в шапке сайдбара, рядом с логотипом.
Как получена палитра
Принцип
Тёмная схема не изобретает новых цветов, а переиспользует уже
утверждённые токены комнаты конференции (tokens.css, блок
[data-theme='room'], см. DESIGN_SYSTEM.md §1.2) в новых ролях — так
оболочка и комната читаются как одна система, когда пользователь входит
из тёмного лобби в тёмную комнату. Все переопределения делаются одним
блоком :root { … } в начале <style> каждого файла — он перекрывает
одноимённые переменные :root из tokens.css (та же специфичность,
позже в источнике — выигрывает), поэтому весь остальной CSS ниже —
дословная копия светлого макета и автоматически перекрашивается.
Токены, переиспользованные из комнаты 1:1 (без изменения hex)
| Токен оболочки (dark) | = токен комнаты | Hex | Новая роль в оболочке |
|---|---|---|---|
--color-bg |
--color-room-bg |
#1E1E1E |
фон страницы |
--color-surface |
--color-room-surface |
#2A2A2A |
карточки, топбар, поля |
--color-border |
--color-room-tile-border |
#3F3F3F |
базовая обводка |
--color-ink-900 |
--color-room-text-primary |
#E8E8E8 |
основной текст |
--color-ink-500 |
--color-room-text-secondary |
#B0B0B0 |
вторичный текст |
--color-ink-300 |
--color-room-text-tertiary |
#7A7A7A |
плейсхолдеры/disabled |
--color-ink-700, --color-accent, --color-border-pill, --color-success, --color-success-dot |
--color-room-mic-on |
#7FDDA8 |
мята: бренд/заголовки/ссылки/CTA/«успех» — единый пастельно-зелёный вектор (см. ниже) |
--color-danger, --color-danger-dot |
--color-room-mic-off |
#EB93A1 |
розово-красный: текст/иконки/обводка статуса «отменена»/ошибки |
--color-warning, --color-warning-dot |
--color-room-speaker-ring |
#D6A83D |
янтарь: статус «запланирована» |
--color-focus-ring |
--color-room-focus-ring |
#D6A83D |
кольцо :focus-visible — то же значение, что и в комнате |
--color-danger-solid |
--color-room-danger-bg |
#B85468 |
заливка сплошных danger-кнопок (см. ниже, почему это отдельный токен) |
--color-danger-solid-hover |
--color-room-danger-bg-hover |
#B9495F |
hover сплошной danger-кнопки |
Одна мята — три роли. В светлой оболочке бренд-индиго (--color-ink-700,
заголовки/ссылки/обводка pill-кнопок) и мятный CTA (--color-accent) — два
разных токена с разными hex. В комнате пастельная мята уже одна на всё
«позитивное» (--color-room-mic-on = «микрофон включён» + активная
демонстрация экрана + счётчик участников + кнопка отправки в чате). Чтобы
не завозить в тёмную оболочку новый, ничем не подкреплённый в комнате
оттенок, --color-ink-700 и --color-accent в тёмной оболочке сведены
к одному и тому же #7FDDA8 — бренд, заголовки, ссылки, обводка
secondary-кнопок и заливка CTA используют один и тот же «фирменный» зелёный.
Различие ролей (бренд-текст vs интерактивная заливка) остаётся читаемым за
счёт контекста (текст vs заливка с тёмным текстом поверх), а не за счёт
второго оттенка — это соответствует прецеденту самой комнаты.
Почему заливка danger-кнопок — отдельный токен, а не --color-danger.
В светлой теме один hex (#C7364F) одинаково хорошо работает и как текст на
белом, и как заливка кнопки с белым текстом (тёмный, насыщенный тон). В
тёмной теме эти две роли расходятся: --color-room-mic-off (#EB93A1) —
светлый пастельный тон, читаемый как текст на тёмном фоне (6.30:1 на
#2A2A2A), но слишком светлый, чтобы на нём читался белый текст кнопки
(≈1.9:1, провал). Поэтому для сплошных danger-кнопок (.btn-danger —
«Отменить все повторения» в календаре, «Удалить» в админке) заведена
отдельная пара --color-danger-solid / --color-danger-solid-hover,
переиспользующая уже готовые --color-room-danger-bg(-hover) (#B85468 /
#B9495F, задокументированы в DESIGN_SYSTEM.md §1.2 с контрастом
4.66:1/5.02:1 для белого текста).
Новые токены (введены только там, где у комнаты нет готового аналога)
Комната — экран без брендинга, форм и многошаговых карточек, поэтому под
нужды оболочки понадобилось несколько новых значений. Все получены
подмешиванием уже утверждённых цветов комнаты к графитовому фону/друг к
другу (не независимо придуманные тона), проверены по WCAG 2.1 (см. расчёт
ниже, тот же метод, что в design/tools/contrast.py):
| Токен | Hex | Как получен | Контраст | Роль |
|---|---|---|---|---|
--color-bg-alt |
#242424 |
между --color-room-bg (#1E1E1E) и --color-room-surface (#2A2A2A) |
— | альт-фон секций, инпуты, disabled-поля |
--color-border-strong |
#585858 |
осветление --color-border |
2.02:1 на surface (нетекст, декоративный hover-акцент — дублируется тенью/курсором, не единственный носитель состояния) | обводка при hover |
--color-ink-400 |
#5D9A78 |
мята #7FDDA8 × фон #1E1E1E, смешение 35% |
5.05:1 на bg / 4.35:1 на surface | эйбрау-подписи [ В СКОБКАХ ], крупные подписи (аналог ⚠︎ large-text-only из светлой темы, но с запасом) |
--color-accent-hover |
#75CA9A |
мята × фон, смешение 10% | текст #10331F на заливке: 7.04:1 |
hover CTA |
--color-accent-active |
#6CB78C |
мята × фон, смешение 20% | текст #10331F на заливке: 5.80:1 |
active/pressed CTA |
--color-accent-text |
#10331F |
не новый — переиспользован буквальный hex, уже встречающийся инлайн в room.html (.chat-input-row button, .tb-btn.is-positive-active, .badge-count) как цвет текста на заливке --color-room-mic-on |
8.45:1 на мяте | текст на CTA/бренд-заливках мятой |
--color-success-bg |
rgba(127,221,168,.14) |
мята с низкой непрозрачностью поверх тёмной поверхности | — | подложка бейджей «идёт сейчас»/«свободна»/«активен» |
--color-danger-bg |
rgba(235,147,161,.14) |
розовый (mic-off) с низкой непрозрачностью | — | подложка бейджей «отменена» |
--color-warning-bg |
rgba(214,168,61,.16) |
янтарь (speaker-ring) с низкой непрозрачностью | — | подложка бейджей «запланирована» |
--shadow-sm/md/lg/glass |
rgba(0,0,0,.35–.5) |
по образцу --shadow-room-panel комнаты (тёмные тени вместо индиго-тонированных) |
— | тени карточек/модалок/glass-панелей |
Контраст всех текстовых пар проверен по формуле WCAG 2.1 — пары, использованные
в макетах (основной текст, вторичный текст, мята/роза/янтарь как текст на
bg/surface/tile, белый текст на --color-danger-solid), все дают
≥ 4.5:1 (текст) либо ≥ 3:1 (декоративные элементы, статус которых также
задублирован иконкой/текстом — см. правило §5 DESIGN_SYSTEM.md). Регрессия
этих пар — в design/tools/contrast.py.
Точечные правки поверх скопированного CSS
Для каждого файла CSS светлого макета скопирован дословно (все .class
правила без изменений) — перекраска идёт только через блок :root. Ручных
точечных правок пять видов, во всех случаях — потому что исходное правило
использовало литеральный hex/rgba, а не var(), и не могло
перекраситься автоматически:
- Аватары и
.weekday-chip.is-selected/.badge-role-admin— в светлой теме заливкаvar(--color-ink-700)(тёмный индиго) сочеталась с жёсткимcolor: #fff. Так как--color-ink-700теперь = мята (светлый тон), белый текст перестаёт читаться (≈1.9:1) — заменено наvar(--color-accent-text)(#10331F, 8.45:1 на мяте). .btn-danger(calendar.html,admin.html) — добавлена отдельная заливкаvar(--color-danger-solid)вместоvar(--color-danger)(см. таблицу выше); белый текст кнопки не менялся..copy-toast(my-conferences.html) — фон былvar(--color-ink-900)(тёмный в светлой теме → стал бы светло-серым в тёмной, ломая тёмный тултип); заменён на буквальный#333333(=--color-room-surface-raised), текст остаётсяvar(--color-ink-900)(теперь светлый) — тултип снова тёмный чип со светлым текстом.- Декоративные градиенты/rgba-подложки (
login.html.brand-panel/.brand-panel::after,lobby.htmlфонbody,calendar.html.day-col.is-today/.cancel-alert,login.html/join.html/calendar.htmlbox-shadow фокуса и ошибки, glass-обводкаrgba(255,255,255,.7)вlogin.html/admin.html, disabled-заливка кнопок) — старые rgba были построены на индиго/старом danger-hex; заменены на тональные аналоги новой палитры (мятное свечение вместо индигового/мятного на белом, янтарный focus-glow вместо индигового, розовый error-glow,rgba(255,255,255,.08)вместо.7для тёмного стекла). color-scheme: darkдобавлен в блок:root, чтобы нативные элементы форм (скроллбар, чекбоксы без кастомной стилизации) тоже рендерились в тёмной палитре браузера.
Доступность (проверено при подборе палитры)
- Текст ≥ 4.5:1 везде, кроме крупных/декоративных элементов (аналогично
правилу §5
DESIGN_SYSTEM.mdдля светлой темы, порог 3:1). - Статус не передаётся только цветом: бейджи конференций — иконка + текст
(как в светлой теме), «скопировано» — смена иконки
Copy → Check+ текстовый тултип, ошибки полей — иконкаAlertCircle+ текст под полем,:focus-visible— везде видимое кольцо (--color-focus-ring, тот же янтарь, что и в комнате). - Палитра пастельная (мята/роза/янтарь той же светлоты, что уже утверждена для комнаты), неоновых/кислотных акцентов не вводилось.