Первоначальная версия VidConf
This commit is contained in:
210
frontend/src/styles/lobby.css
Normal file
210
frontend/src/styles/lobby.css
Normal file
@@ -0,0 +1,210 @@
|
||||
/*
|
||||
* VidConf — стили экрана лобби.
|
||||
*
|
||||
* `.page-shell`/`.page-main`/`.page-head` — общая разметка светлой оболочки,
|
||||
* переиспользуется и другими страницами (см. CalendarPage.tsx), поэтому эти
|
||||
* три класса общие и не привязаны к разметке лобби.
|
||||
*
|
||||
* Остальное — 1:1 воспроизводит хаб действий design/mockups/lobby.html
|
||||
* (мозаика из 4 действий + медальон логотипа в центре пересечения).
|
||||
*/
|
||||
|
||||
.page-shell { min-height: 100vh; background: var(--color-bg); }
|
||||
main.page-main { padding: var(--space-8); max-width: 1440px; margin: 0 auto; }
|
||||
|
||||
.page-head { display: flex; align-items: flex-end; justify-content: space-between; margin-bottom: var(--space-6); }
|
||||
.page-head h1 { font: var(--text-display-lg); font-family: var(--font-display); color: var(--color-ink-700); margin: 0 0 6px; }
|
||||
.page-head p { font: var(--text-body-lg); color: var(--color-ink-500); margin: 0; }
|
||||
|
||||
/* Общая адаптивная подстройка контейнера/шапки страниц оболочки (Calendar/
|
||||
MyConferences/Admin) — узкие экраны не должны получать горизонтальную
|
||||
прокрутку из-за фиксированных отступов space-8. Раскладка контента внутри
|
||||
каждой страницы (сетки/сайдбары) — зона соответствующих блоков. */
|
||||
@media (max-width: 640px) {
|
||||
main.page-main { padding: var(--space-5) var(--space-4); }
|
||||
.page-head { flex-direction: column; align-items: flex-start; gap: var(--space-3); }
|
||||
}
|
||||
|
||||
/* ---------- Лобби-хаб (мозаика действий) ---------- */
|
||||
.lobby-shell {
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background:
|
||||
radial-gradient(1100px 520px at 10% -10%, rgba(59, 77, 149, 0.06), transparent 60%),
|
||||
radial-gradient(900px 480px at 105% 110%, rgba(212, 242, 227, 0.28), transparent 55%),
|
||||
var(--color-bg);
|
||||
}
|
||||
|
||||
/* Тёмная тема: декоративные радиальные пятна фона построены на индиго/мятном
|
||||
светлой темы (литеральные rgba, не var()) — патч в тон новой палитры
|
||||
(янтарь/мята той же светлоты, что и в комнате конференции). */
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root:not([data-theme]) .lobby-shell {
|
||||
background:
|
||||
radial-gradient(1100px 520px at 10% -10%, rgba(214, 168, 61, 0.05), transparent 60%),
|
||||
radial-gradient(900px 480px at 105% 110%, rgba(127, 221, 168, 0.14), transparent 55%),
|
||||
var(--color-bg);
|
||||
}
|
||||
}
|
||||
:root[data-theme='dark'] .lobby-shell {
|
||||
background:
|
||||
radial-gradient(1100px 520px at 10% -10%, rgba(214, 168, 61, 0.05), transparent 60%),
|
||||
radial-gradient(900px 480px at 105% 110%, rgba(127, 221, 168, 0.14), transparent 55%),
|
||||
var(--color-bg);
|
||||
}
|
||||
|
||||
.hub-main {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: var(--space-6) var(--space-8) var(--space-12);
|
||||
}
|
||||
|
||||
.hub-wrap { display: flex; flex-direction: column; align-items: center; gap: var(--space-8); width: 100%; }
|
||||
.hub-intro { text-align: center; max-width: 560px; }
|
||||
.hub-intro .eyebrow { font: var(--text-caption); color: var(--color-ink-400); margin: 0 0 var(--space-2); }
|
||||
.hub-intro h1 { font: var(--text-display-lg); font-family: var(--font-display); color: var(--color-ink-700); margin: 0; }
|
||||
|
||||
.hub {
|
||||
position: relative;
|
||||
width: min(1420px, 100%);
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
grid-template-rows: repeat(2, 340px);
|
||||
gap: var(--space-8);
|
||||
}
|
||||
|
||||
/* Карточка-действие. Медальон с иконкой «сидит» на верхней кромке. */
|
||||
.action {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
gap: var(--space-3);
|
||||
padding: var(--space-10) var(--space-12) var(--space-8);
|
||||
margin-top: 34px;
|
||||
/* min-width:0 — иначе grid-элемент с 1fr-треком не сжимается уже своего
|
||||
min-content (длинные заглавные слова вроде «ПОДКЛЮЧИТЬСЯ» на Unbounded);
|
||||
без этого узкий вьюпорт даёт classic grid blowout — трек и вся сетка
|
||||
раздуваются шире контейнера, появляется горизонтальный скролл. */
|
||||
min-width: 0;
|
||||
background: var(--color-surface);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--radius-3xl);
|
||||
text-decoration: none;
|
||||
color: var(--color-ink-900);
|
||||
box-shadow: var(--shadow-sm);
|
||||
cursor: pointer;
|
||||
font-family: inherit;
|
||||
transition:
|
||||
transform var(--transition-base),
|
||||
box-shadow var(--transition-base),
|
||||
border-color var(--transition-base);
|
||||
}
|
||||
.action:hover { transform: translateY(-4px); box-shadow: var(--shadow-lg); border-color: var(--color-border-strong); }
|
||||
.action:active { transform: translateY(-1px); }
|
||||
.action:disabled { cursor: not-allowed; opacity: 0.7; transform: none; }
|
||||
|
||||
.action-icon {
|
||||
position: absolute;
|
||||
top: -34px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 68px; height: 68px;
|
||||
border-radius: 50%;
|
||||
background: var(--color-surface);
|
||||
border: var(--border-thick) solid var(--color-ink-700);
|
||||
color: var(--color-ink-700);
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
box-shadow: var(--shadow-md);
|
||||
}
|
||||
.action-icon .icon { width: 30px; height: 30px; }
|
||||
|
||||
.action-title {
|
||||
margin: 0;
|
||||
font: 600 40px/1.2 var(--font-display);
|
||||
letter-spacing: 0.01em;
|
||||
color: var(--color-ink-700);
|
||||
text-transform: uppercase;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
.action-object { margin: 0; font: 600 21px/1.35 var(--font-body); color: var(--color-ink-900); overflow-wrap: break-word; }
|
||||
.action-note { margin: 0; font: 400 17px/1.5 var(--font-body); color: var(--color-ink-500); overflow-wrap: break-word; }
|
||||
|
||||
/* Главное действие — CTA дизайн-системы (пастельная мята) */
|
||||
.action--create { background: var(--color-accent); border-color: transparent; }
|
||||
.action--create:hover:not(:disabled) { background: var(--color-accent-hover); border-color: transparent; }
|
||||
.action--create:active:not(:disabled) { background: var(--color-accent-active); }
|
||||
.action--create .action-title { font: 700 54px/1.1 var(--font-display); }
|
||||
.action--create .action-title, .action--create .action-object { color: var(--color-accent-text); }
|
||||
.action--create .action-note { color: var(--color-ink-700); }
|
||||
.action--create .action-icon { background: var(--color-accent); border-color: var(--color-accent-text); color: var(--color-accent-text); }
|
||||
|
||||
/* ---------- Медальон VidConf в центре мозаики ---------- */
|
||||
.hub-logo {
|
||||
position: absolute;
|
||||
top: 373px; left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 156px; height: 156px;
|
||||
border-radius: 50%;
|
||||
background: var(--color-surface);
|
||||
border: var(--border-thick) solid var(--color-ink-700);
|
||||
box-shadow: var(--shadow-lg);
|
||||
display: flex; flex-direction: column;
|
||||
align-items: center; justify-content: center;
|
||||
gap: 6px;
|
||||
z-index: 20;
|
||||
pointer-events: none;
|
||||
}
|
||||
.hub-logo .logo-mark { width: 56px; height: 56px; color: var(--color-ink-700); }
|
||||
.hub-logo .logo-word { font: 600 16px/1 var(--font-display); color: var(--color-ink-700); }
|
||||
|
||||
/* ---------- Появление ---------- */
|
||||
@media (prefers-reduced-motion: no-preference) {
|
||||
.action, .hub-logo { animation: vc-hub-rise 480ms cubic-bezier(0.22, 0.9, 0.3, 1) backwards; }
|
||||
.action--create { animation-delay: 60ms; }
|
||||
.action--calendar { animation-delay: 140ms; }
|
||||
.action--join { animation-delay: 220ms; }
|
||||
.action--mine { animation-delay: 300ms; }
|
||||
.hub-logo { animation-delay: 420ms; animation-name: vc-hub-rise-logo; }
|
||||
@keyframes vc-hub-rise {
|
||||
from { opacity: 0; transform: translateY(14px); }
|
||||
to { opacity: 1; transform: translateY(0); }
|
||||
}
|
||||
@keyframes vc-hub-rise-logo {
|
||||
from { opacity: 0; transform: translate(-50%, calc(-50% + 14px)); }
|
||||
to { opacity: 1; transform: translate(-50%, -50%); }
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------- Узкие экраны ---------- */
|
||||
/* ВАЖНО: этот блок должен идти строго ПОСЛЕДНИМ в файле. При равной
|
||||
специфичности селекторов (`.action-title` и т.п. — 0,1,0 что здесь, что в
|
||||
безусловных правилах выше) порядок в исходнике решает, какое правило
|
||||
применится, а не сам факт совпадения media query — если этот блок стоит
|
||||
раньше своих безусловных дублей, он будет молча перебит ими на любой
|
||||
ширине. Так уже ловили баг (правки гейта, гейт 3): грид расползался на
|
||||
375px, потому что этот блок раньше стоял сразу после базового `.hub {}`,
|
||||
до `.action-title`/`.action--create .action-title` и т.п. */
|
||||
@media (max-width: 960px) {
|
||||
/* Мозаика 2×2 → одна колонка; фиксированная высота 340px больше не нужна —
|
||||
тайлы подстраиваются под контент. Медальон-логотип в центре сетки на
|
||||
узких экранах убираем совсем: он был позиционирован под чёткую 2×2
|
||||
геометрию (см. .hub-logo выше) и на одну колонку не переносится. */
|
||||
.hub-wrap { gap: var(--space-6); }
|
||||
.hub { grid-template-columns: 1fr; grid-template-rows: repeat(4, auto); gap: var(--space-5); }
|
||||
.hub-logo { display: none; }
|
||||
.hub-main { padding: var(--space-5) var(--space-4) var(--space-8); }
|
||||
|
||||
.action { padding: var(--space-8) var(--space-5) var(--space-6); margin-top: 28px; }
|
||||
.action-icon { width: 56px; height: 56px; top: -28px; }
|
||||
.action-icon .icon { width: 26px; height: 26px; }
|
||||
.action-title { font-size: 28px; }
|
||||
.action--create .action-title { font-size: 34px; }
|
||||
.action-object { font-size: 17px; }
|
||||
.action-note { font-size: 15px; }
|
||||
}
|
||||
Reference in New Issue
Block a user