uchill/front_material/styles/livekit-theme.css

430 lines
13 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.

/**
* Кастомизация 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;
}