Files
vidconf/design/tokens.css

349 lines
12 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* VidConf — design tokens
* Источник истины для design/DESIGN_SYSTEM.md. Значения синхронизированы 1:1.
*
* Три темы, независимые механизмы переключения:
* - Оболочка, светлая (дефолт) — :root.
* - Оболочка, тёмная — :root[data-theme="dark"] (переключатель
* пользователя) ИЛИ автоматически по @media (prefers-color-scheme: dark),
* если data-theme не проставлен явно (см. блок ниже). Утверждено
* 2026-07-18 (фаза 6a, design/mockups/dark/README.md) — палитра 1:1 из
* утверждённых тёмных макетов оболочки.
* - Комната конференции — [data-theme="room"] (скоуп на контейнер
* экрана конференции; отдельный неймспейс --color-room-*, НЕ переключается
* системной темой и НЕ смешивается с dark-оболочкой — комната всегда
* тёмная независимо от выбора пользователя).
*
* Шрифты. Семейства и веса ниже — контракт дизайн-системы (Unbounded —
* display, Inter — body, JetBrains Mono — mono) и синхронизированы 1:1 с
* DESIGN_SYSTEM.md. Реализация подключения различается по среде, БЕЗ внешних
* CDN (инвариант приватности):
* - Собранный фронт (frontend/) — шрифты самохостятся через npm-пакеты
* @fontsource с кириллическим subset (импорты в frontend/src/main.tsx);
* там ручных @font-face нет.
* - Статические HTML-макеты (design/mockups/) — сборки npm нет, поэтому
* подключаются @font-face ниже. При отсутствии локальных woff2 браузер
* молча уходит в fallback-стек без сетевых запросов (макеты остаются
* рабочими; кастомная типографика появляется, если положить woff2 рядом).
*/
@font-face {
font-family: 'Unbounded';
src: url('../fonts/Unbounded/Unbounded-Regular.woff2') format('woff2');
font-weight: 400;
font-display: swap;
}
@font-face {
font-family: 'Unbounded';
src: url('../fonts/Unbounded/Unbounded-SemiBold.woff2') format('woff2');
font-weight: 600;
font-display: swap;
}
@font-face {
font-family: 'Unbounded';
src: url('../fonts/Unbounded/Unbounded-Bold.woff2') format('woff2');
font-weight: 700;
font-display: swap;
}
@font-face {
font-family: 'Inter';
src: url('../fonts/Inter/Inter-Variable.woff2') format('woff2-variations');
font-weight: 400 800;
font-display: swap;
}
@font-face {
font-family: 'JetBrains Mono';
src: url('../fonts/JetBrainsMono/JetBrainsMono-Medium.woff2') format('woff2');
font-weight: 500;
font-display: swap;
}
:root {
color-scheme: light;
/* ---------- Типографика ---------- */
--font-display: 'Unbounded', 'Arial Rounded MT Bold', -apple-system, 'Segoe UI', sans-serif;
--font-body: 'Inter', -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
--font-mono: 'JetBrains Mono', 'SFMono-Regular', Menlo, Consolas, monospace;
--text-display-2xl: 700 64px/1.05 var(--font-display);
--text-display-xl: 700 48px/1.1 var(--font-display);
--text-display-lg: 600 34px/1.2 var(--font-display);
--text-h1: 700 28px/1.25 var(--font-body);
--text-h2: 600 22px/1.3 var(--font-body);
--text-h3: 600 18px/1.35 var(--font-body);
--text-body-lg: 400 16px/1.5 var(--font-body);
--text-body: 400 14px/1.5 var(--font-body);
--text-caption: 600 12px/1.4 var(--font-body);
--text-mono-sm: 500 13px/1.4 var(--font-mono);
/* ---------- Spacing (8pt grid, база 4px) ---------- */
--space-1: 4px;
--space-2: 8px;
--space-3: 12px;
--space-4: 16px;
--space-5: 20px;
--space-6: 24px;
--space-8: 32px;
--space-10: 40px;
--space-12: 48px;
--space-16: 64px;
--space-20: 80px;
--space-24: 96px;
/* ---------- Радиусы ---------- */
--radius-sm: 8px;
--radius-md: 12px;
--radius-lg: 16px;
--radius-xl: 20px;
--radius-2xl: 24px;
--radius-3xl: 32px;
--radius-full: 999px;
/* ---------- Границы ---------- */
--border-thin: 1px;
--border-md: 1.5px;
--border-thick: 2px;
--border-speaker: 3px;
/* ---------- Breakpoints (справочно, desktop-first) ---------- */
--bp-desktop: 1440px;
--bp-min: 1280px;
/* ---------- Motion ---------- */
--transition-fast: 120ms ease;
--transition-base: 200ms ease;
/* ---------- Цвета: светлая тема (оболочка) ---------- */
--color-bg: #F1F1F1;
--color-bg-alt: #F7F7F8;
--color-surface: #FFFFFF;
--color-surface-glass: rgba(255, 255, 255, 0.55);
--color-border: #E1E3E9;
--color-border-strong: #C7CCDC;
--color-border-pill: #4A5A9E;
--color-ink-900: #2E3454;
--color-ink-700: #3B4D95;
--color-ink-500: #535F94;
--color-ink-400: #6976AC;
--color-ink-300: #A6AECB;
/* Пастельная мята — фаза R1 (пивот, 2026-07-16): переименовано из
--color-accent-green*, акцент больше не обязан быть зелёным.
Осветлено на 50% (смешение 50/50 с белым) по фидбеку гейта утверждения
R1-итерации (2026-07-16): #A9E4C6→#D4F2E3, #8FD6B2→#C7EBD9,
#74C89D→#BAE4CE. Mapping см. design/DESIGN_SYSTEM.md §1.1/§1.3. */
--color-accent: #D4F2E3;
--color-accent-hover: #C7EBD9;
--color-accent-active: #BAE4CE;
--color-accent-text: #2E3454;
--color-success: #0A7A4C;
--color-success-bg: #E4F7ED;
--color-success-dot: #46916B;
--color-danger: #C7364F;
--color-danger-bg: #FCE7EB;
--color-danger-dot: #C65366;
--color-warning: #7F560D;
--color-warning-bg: #FBF0DC;
--color-warning-dot: #B58A26;
--color-focus-ring: #3B4D95;
/* ---------- Тени (светлая тема) ---------- */
--shadow-sm: 0 1px 2px rgba(46, 52, 84, 0.06);
--shadow-md: 0 4px 16px rgba(46, 52, 84, 0.08);
--shadow-lg: 0 12px 32px rgba(46, 52, 84, 0.12);
--shadow-glass: 0 8px 24px rgba(59, 77, 149, 0.15);
}
/* =====================================================================
* Тёмная тема: оболочка (auth/лобби/календарь/join/«мои конференции»/админка)
* Утверждено 2026-07-18 (фаза 6a). Палитра — 1:1 копия блока :root из
* design/mockups/dark/*.html (все 6 файлов идентичны), происхождение каждого
* значения задокументировано в design/mockups/dark/README.md и продублировано
* в design/DESIGN_SYSTEM.md §1.2b. Принцип: тёмная оболочка не изобретает
* новых цветов, а переиспользует уже утверждённые --color-room-* в новых
* ролях (см. таблицу происхождения), поэтому тёмное лобби и тёмная комната
* читаются как одна система.
*
* Механизм активации (два независимых триггера, одни и те же переопределения
* --color-* / --shadow-* — те же имена, что в :root светлой темы выше):
* 1) явный выбор пользователя — атрибут data-theme="dark" на <html>/:root;
* 2) дефолт по системной теме — @media (prefers-color-scheme: dark),
* только пока data-theme НЕ проставлен явно (:root:not([data-theme])).
* Явный data-theme="light" отключает автодетект и форсирует светлую
* тему (базовый :root выше) даже при тёмной ОС.
* Оба блока продублированы намеренно (plain CSS, без препроцессора) — при
* правке палитры менять оба синхронно.
* ===================================================================== */
@media (prefers-color-scheme: dark) {
:root:not([data-theme]) {
color-scheme: dark;
--color-bg: #1E1E1E;
--color-bg-alt: #242424;
--color-surface: #2A2A2A;
--color-surface-glass: rgba(51, 51, 51, 0.55);
--color-border: #3F3F3F;
--color-border-strong: #585858;
--color-border-pill: #7FDDA8;
--color-ink-900: #E8E8E8;
--color-ink-700: #7FDDA8;
--color-ink-500: #B0B0B0;
--color-ink-400: #5D9A78;
--color-ink-300: #7A7A7A;
--color-accent: #7FDDA8;
--color-accent-hover: #75CA9A;
--color-accent-active: #6CB78C;
--color-accent-text: #10331F;
--color-success: #7FDDA8;
--color-success-bg: rgba(127, 221, 168, 0.14);
--color-success-dot: #7FDDA8;
--color-danger: #EB93A1;
--color-danger-bg: rgba(235, 147, 161, 0.14);
--color-danger-dot: #EB93A1;
--color-danger-solid: #B85468;
--color-danger-solid-hover: #B9495F;
--color-warning: #D6A83D;
--color-warning-bg: rgba(214, 168, 61, 0.16);
--color-warning-dot: #D6A83D;
--color-focus-ring: #D6A83D;
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.35);
--shadow-md: 0 4px 16px rgba(0, 0, 0, 0.4);
--shadow-lg: 0 12px 32px rgba(0, 0, 0, 0.5);
--shadow-glass: 0 8px 24px rgba(0, 0, 0, 0.45);
}
}
:root[data-theme='dark'] {
color-scheme: dark;
--color-bg: #1E1E1E;
--color-bg-alt: #242424;
--color-surface: #2A2A2A;
--color-surface-glass: rgba(51, 51, 51, 0.55);
--color-border: #3F3F3F;
--color-border-strong: #585858;
--color-border-pill: #7FDDA8;
--color-ink-900: #E8E8E8;
--color-ink-700: #7FDDA8;
--color-ink-500: #B0B0B0;
--color-ink-400: #5D9A78;
--color-ink-300: #7A7A7A;
--color-accent: #7FDDA8;
--color-accent-hover: #75CA9A;
--color-accent-active: #6CB78C;
--color-accent-text: #10331F;
--color-success: #7FDDA8;
--color-success-bg: rgba(127, 221, 168, 0.14);
--color-success-dot: #7FDDA8;
--color-danger: #EB93A1;
--color-danger-bg: rgba(235, 147, 161, 0.14);
--color-danger-dot: #EB93A1;
--color-danger-solid: #B85468;
--color-danger-solid-hover: #B9495F;
--color-warning: #D6A83D;
--color-warning-bg: rgba(214, 168, 61, 0.16);
--color-warning-dot: #D6A83D;
--color-focus-ring: #D6A83D;
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.35);
--shadow-md: 0 4px 16px rgba(0, 0, 0, 0.4);
--shadow-lg: 0 12px 32px rgba(0, 0, 0, 0.5);
--shadow-glass: 0 8px 24px rgba(0, 0, 0, 0.45);
}
/* ---------- Тёмная тема: комната конференции ---------- */
[data-theme='room'] {
color-scheme: dark;
--color-room-bg: #1E1E1E;
--color-room-surface: #2A2A2A;
--color-room-surface-raised: #333333;
--color-room-tile: #363636;
--color-room-tile-border: #3F3F3F;
--color-room-tile-hover: #3D3D3D;
--color-room-text-primary: #E8E8E8;
--color-room-text-secondary: #B0B0B0;
--color-room-text-tertiary: #7A7A7A;
--color-room-mic-on: #7FDDA8;
--color-room-mic-off: #EB93A1;
--color-room-speaker-ring: #D6A83D;
--color-room-danger: #EB93A1;
--color-room-danger-bg: #B85468;
--color-room-danger-bg-hover: #B9495F;
--color-room-focus-ring: #D6A83D;
--shadow-speaker-glow: 0 0 0 3px var(--color-room-speaker-ring), 0 0 24px rgba(214, 168, 61, 0.35);
--shadow-room-panel: 0 8px 24px rgba(0, 0, 0, 0.4);
}
/* ---------- Базовые сбросы, общие для макетов ---------- */
*, *::before, *::after { box-sizing: border-box; }
body {
margin: 0;
font: var(--text-body-lg);
color: var(--color-ink-900);
background: var(--color-bg);
-webkit-font-smoothing: antialiased;
}
[data-theme='room'] body,
[data-theme='room'] {
background: var(--color-room-bg);
color: var(--color-room-text-primary);
}
a { color: inherit; }
button {
font: inherit;
cursor: pointer;
}
:focus-visible {
outline: 2px solid var(--color-focus-ring);
outline-offset: 2px;
}
[data-theme='room'] :focus-visible {
outline-color: var(--color-room-focus-ring);
}
svg.icon {
width: 20px;
height: 20px;
stroke: currentColor;
stroke-width: 2;
fill: none;
stroke-linecap: round;
stroke-linejoin: round;
flex-shrink: 0;
}