/** * Кастомизация LiveKit через CSS переменные. * Все стили и скрипты LiveKit отдаются с нашего сервера (бандл + этот файл). */ @keyframes lk-spin { to { transform: rotate(360deg); } } :root { /* Цвета фона */ --lk-bg: #1a1a1a; --lk-bg2: #2a2a2a; --lk-bg3: #3a3a3a; /* Цвета текста */ --lk-fg: #ffffff; --lk-fg2: rgba(255, 255, 255, 0.7); /* Основные цвета */ --lk-control-bg: var(--md-sys-color-primary); --lk-control-hover-bg: var(--md-sys-color-primary-container); --lk-button-bg: rgba(255, 255, 255, 0.15); --lk-button-hover-bg: rgba(255, 255, 255, 0.25); /* Границы */ --lk-border-color: rgba(255, 255, 255, 0.1); --lk-border-radius: 12px; /* Фокус */ --lk-focus-ring: var(--md-sys-color-primary); /* Ошибки */ --lk-danger: var(--md-sys-color-error); /* Размеры */ --lk-control-bar-height: 80px; --lk-participant-tile-gap: 12px; } /* Панель управления — без ограничения по ширине */ .lk-control-bar { background: rgba(0, 0, 0, 0.8) !important; backdrop-filter: blur(20px) !important; border-radius: 16px !important; padding: 12px 16px !important; margin: 16px !important; box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4) !important; max-width: none !important; width: auto !important; } .lk-control-bar .lk-button-group, .lk-control-bar .lk-button-group-menu { max-width: none !important; width: auto !important; } /* Кнопки управления — ширина по контенту, без жёсткого ограничения */ .lk-control-bar .lk-button { min-width: 48px !important; width: auto !important; height: 48px !important; border-radius: 12px !important; transition: all 0.2s ease !important; padding-left: 12px !important; padding-right: 12px !important; } /* Русские подписи: скрываем английский текст, показываем свой */ .lk-control-bar .lk-button[data-lk-source="microphone"], .lk-control-bar .lk-button[data-lk-source="camera"], .lk-control-bar .lk-button[data-lk-source="screen_share"], .lk-control-bar .lk-chat-toggle, .lk-control-bar .lk-disconnect-button, .lk-control-bar .lk-start-audio-button { font-size: 0 !important; } .lk-control-bar .lk-button[data-lk-source="microphone"] > svg, .lk-control-bar .lk-button[data-lk-source="camera"] > svg, .lk-control-bar .lk-button[data-lk-source="screen_share"] > svg, .lk-control-bar .lk-chat-toggle > svg, .lk-control-bar .lk-disconnect-button > svg { width: 16px !important; height: 16px !important; flex-shrink: 0 !important; } .lk-control-bar .lk-button[data-lk-source="microphone"]::after { content: "Микрофон"; font-size: 1rem; } .lk-control-bar .lk-button[data-lk-source="camera"]::after { content: "Камера"; font-size: 1rem; } .lk-control-bar .lk-button[data-lk-source="screen_share"]::after { content: "Поделиться экраном"; font-size: 1rem; } .lk-control-bar .lk-button[data-lk-source="screen_share"][data-lk-enabled="true"]::after { content: "Остановить демонстрацию"; } .lk-control-bar .lk-chat-toggle::after { content: "Чат"; font-size: 1rem; } /* Кнопка бургер слева от микрофона — в панели LiveKit */ .lk-burger-button { background: rgba(255, 255, 255, 0.15) !important; color: #fff !important; } /* Скрываем стандартную кнопку «Выйти» — используем свою внутри панели (модалка: Выйти / Выйти и завершить занятие) */ .lk-control-bar .lk-disconnect-button { display: none !important; } .lk-control-bar .lk-disconnect-button::after { content: "Выйти"; font-size: 1rem; } /* Наша кнопка «Выйти» — внутри панели, рядом с «Поделиться экраном» */ .lk-control-bar .lk-custom-exit-button { font-size: 0 !important; background: var(--md-sys-color-error) !important; color: #fff !important; border: none; cursor: pointer; display: inline-flex !important; align-items: center; justify-content: center; } .lk-control-bar .lk-custom-exit-button::after { content: "Выйти"; font-size: 1rem; } .lk-control-bar .lk-custom-exit-button > .material-symbols-outlined { color: #fff !important; } /* Скрываем кнопку «Начать видео» — у нас свой StartAudioOverlay */ .lk-control-bar .lk-start-audio-button { display: none !important; } /* Кнопки без текста (только иконка) — минимальный размер */ .lk-button { min-width: 48px !important; width: auto !important; height: 48px !important; border-radius: 12px !important; transition: all 0.2s ease !important; } .lk-button:hover { transform: scale(1.05); } .lk-button:active { transform: scale(0.95); } /* Активная кнопка */ .lk-button[data-lk-enabled="true"] { background: var(--md-sys-color-primary) !important; } /* Кнопка отключения — белые иконка и текст */ .lk-disconnect-button { background: var(--md-sys-color-error) !important; color: #fff !important; } .lk-disconnect-button > svg { color: #fff !important; fill: currentColor; } /* Плитки участников */ .lk-participant-tile { border-radius: 12px !important; overflow: hidden !important; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2) !important; } /* Плейсхолдер без камеры: скрываем дефолтную SVG, показываем аватар из API */ .lk-participant-tile .lk-participant-placeholder svg { display: none !important; } /* Контейнер для аватара — нужен для container queries */ .lk-participant-tile .lk-participant-placeholder { container-type: size; } .lk-participant-tile .lk-participant-placeholder img.lk-participant-avatar-img { /* Квадрат: меньшая сторона контейнера, максимум 400px */ --avatar-size: min(min(80cqw, 80cqh), 400px); width: var(--avatar-size); height: var(--avatar-size); aspect-ratio: 1 / 1; object-fit: cover; object-position: center; border-radius: 50%; } /* Fallback для браузеров без container queries */ @supports not (width: 1cqw) { .lk-participant-tile .lk-participant-placeholder img.lk-participant-avatar-img { width: 200px; height: 200px; } } /* Имя участника — белый текст (Камера, PiP) */ .lk-participant-name { background: rgba(0, 0, 0, 0.7) !important; backdrop-filter: blur(10px) !important; border-radius: 8px !important; padding: 6px 12px !important; font-weight: 600 !important; color: #fff !important; } /* Чат LiveKit скрыт — используем чат сервиса (платформы) */ .lk-video-conference .lk-chat { display: none !important; } .lk-control-bar .lk-chat-toggle { display: none !important; } /* Стили чата платформы оставляем для других страниц */ .lk-chat { background: var(--md-sys-color-surface) !important; border-left: 1px solid var(--md-sys-color-outline) !important; } .lk-chat-entry { background: var(--md-sys-color-surface-container) !important; border-radius: 12px !important; padding: 12px !important; margin-bottom: 12px !important; } /* Сетка участников */ .lk-grid-layout { gap: 12px !important; padding: 12px !important; } /* Меню выбора устройств — без ограничения по ширине */ .lk-device-menu, .lk-media-device-select { max-width: none !important; width: max-content !important; min-width: 0 !important; } .lk-media-device-select { background: rgba(0, 0, 0, 0.95) !important; backdrop-filter: blur(20px) !important; border-radius: 12px !important; padding: 8px !important; box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4) !important; border: 1px solid rgba(255, 255, 255, 0.1) !important; } .lk-media-device-select button { border-radius: 8px !important; padding: 10px 14px !important; transition: background 0.2s ease !important; width: 100% !important; min-width: 0 !important; white-space: normal !important; text-align: left !important; } .lk-media-device-select button:hover { background: rgba(255, 255, 255, 0.1) !important; } .lk-media-device-select button[data-lk-active="true"] { background: var(--md-sys-color-primary) !important; } /* Индикатор говорящего */ .lk-participant-tile[data-lk-speaking="true"] { box-shadow: 0 0 0 3px var(--md-sys-color-primary) !important; } /* Layout для 1-на-1: собеседник на весь экран, своя камера в углу */ /* Карусель position:absolute выходит из flow — остаётся только основной контент. */ /* Сетка 5fr 1fr: единственный grid-ребёнок (основное видео) получает 5fr (расширяется). */ .lk-focus-layout { position: relative !important; grid-template-columns: 5fr 1fr !important; } /* Основное видео (собеседник) на весь экран */ .lk-focus-layout .lk-focus-layout-wrapper { width: 100% !important; height: 100% !important; } .lk-focus-layout .lk-focus-layout-wrapper .lk-participant-tile { width: 100% !important; height: 100% !important; border-radius: 0 !important; } /* Демонстрация экрана — на весь экран только в режиме фокуса (после клика на раскрытие) */ /* Структура: .lk-focus-layout-wrapper > .lk-focus-layout > .lk-participant-tile */ .lk-focus-layout > .lk-participant-tile[data-lk-source="screen_share"] { position: absolute !important; width: 100% !important; height: 100% !important; top: 0 !important; left: 0 !important; border-radius: 0 !important; z-index: 50 !important; } /* Карусель с локальным видео (своя камера) */ .lk-focus-layout .lk-carousel { position: absolute !important; bottom: 80px !important; right: 16px !important; width: 280px !important; height: auto !important; z-index: 100 !important; pointer-events: auto !important; } .lk-focus-layout .lk-carousel .lk-participant-tile { width: 280px !important; height: 158px !important; border-radius: 12px !important; box-shadow: 0 8px 32px rgba(0, 0, 0, 0.6) !important; border: 2px solid rgba(255, 255, 255, 0.2) !important; } /* Скрыть стрелки карусели (они не нужны для 1 участника) */ .lk-focus-layout .lk-carousel button[aria-label*="Previous"], .lk-focus-layout .lk-carousel button[aria-label*="Next"] { display: none !important; } /* Если используется grid layout (фоллбэк) */ .lk-grid-layout { position: relative !important; } /* Для 2 участников: первый на весь экран, второй в углу */ .lk-grid-layout[data-lk-participants="2"] { display: block !important; position: relative !important; } .lk-grid-layout[data-lk-participants="2"] .lk-participant-tile:first-child { position: absolute !important; top: 0 !important; left: 0 !important; width: 100% !important; height: 100% !important; border-radius: 0 !important; } .lk-grid-layout[data-lk-participants="2"] .lk-participant-tile:last-child { position: absolute !important; bottom: 80px !important; right: 16px !important; width: 280px !important; height: 158px !important; border-radius: 12px !important; box-shadow: 0 8px 32px rgba(0, 0, 0, 0.6) !important; border: 2px solid rgba(255, 255, 255, 0.2) !important; z-index: 100 !important; } /* Адаптивность */ @media (max-width: 768px) { .lk-control-bar { border-radius: 12px !important; padding: 8px 12px !important; } .lk-control-bar .lk-button, .lk-button { min-width: 44px !important; width: auto !important; height: 44px !important; } /* Уменьшаем размер локального видео на мобильных */ .lk-focus-layout .lk-carousel, .lk-grid-layout[data-lk-participants="2"] .lk-participant-tile:last-child { width: 160px !important; height: 90px !important; bottom: 70px !important; right: 12px !important; } } /* Качество отображения видео в контейнере LiveKit */ .lk-participant-media-video { background: #000 !important; } /* Демонстрация экрана: contain чтобы не обрезать, чёткое отображение */ .lk-participant-media-video[data-lk-source="screen_share"] { object-fit: contain !important; object-position: center !important; image-rendering: -webkit-optimize-contrast; image-rendering: crisp-edges; } /* Сетка: минимальная высота плиток для крупного видео */ .lk-grid-layout { min-height: 0; } .lk-grid-layout .lk-participant-tile { min-height: 240px; }