Files
vidconf/design/mockups/dark/login.html
Max Ronzhin 8757bec8ac
Some checks failed
CI / backend (push) Has been cancelled
CI / frontend (push) Has been cancelled
first commit
2026-07-23 02:38:05 +03:00

402 lines
21 KiB
HTML
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.
<!doctype html>
<html lang="ru" data-theme="shell-dark">
<head>
<meta charset="UTF-8">
<title>VidConf — Вход / Регистрация / Подтверждение email (тёмная тема, НА СОГЛАСОВАНИИ)</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="../../tokens.css">
<style>
/* =====================================================================
* ТЁМНЫЙ ВАРИАНТ ОБОЛОЧКИ — ПРЕДЛОЖЕНИЕ, НЕ УТВЕРЖДЕНО.
* Разметка и контент идентичны design/mockups/auth.html 1:1, меняется
* только цветовая схема. Палитра переиспользует токены комнаты
* конференции (tokens.css, [data-theme="room"]) — единая тёмная гамма:
* графит + пастельная мята/розово-красный/жёлто-оранжевый.
* Происхождение цветов и обоснование — design/mockups/dark/README.md.
* Технически: блок :root ниже переопределяет одноимённые переменные
* оболочки из tokens.css (та же специфичность :root, но позже в
* источнике — выигрывает), поэтому весь остальной CSS ниже скопирован
* из auth.html БЕЗ ИЗМЕНЕНИЙ и автоматически перекрашивается.
* ===================================================================== */
:root {
color-scheme: dark;
--color-bg: #1E1E1E; /* = --color-room-bg */
--color-bg-alt: #242424; /* новый: между bg и surface */
--color-surface: #2A2A2A; /* = --color-room-surface */
--color-surface-glass: rgba(51, 51, 51, .55); /* на основе --color-room-surface-raised */
--color-border: #3F3F3F; /* = --color-room-tile-border */
--color-border-strong: #585858; /* новый, hover-обводка */
--color-border-pill: #7FDDA8; /* = --color-room-mic-on */
--color-ink-900: #E8E8E8; /* = --color-room-text-primary */
--color-ink-700: #7FDDA8; /* = --color-room-mic-on — бренд/заголовки/ссылки */
--color-ink-500: #B0B0B0; /* = --color-room-text-secondary */
--color-ink-400: #5D9A78; /* новый, приглушённая мята, крупный текст ⚠︎ */
--color-ink-300: #7A7A7A; /* = --color-room-text-tertiary */
--color-accent: #7FDDA8; /* = --color-room-mic-on */
--color-accent-hover: #75CA9A; /* новый */
--color-accent-active: #6CB78C; /* новый */
--color-accent-text: #10331F; /* новый, тёмный ink (прецедент room.html) */
--color-success: #7FDDA8;
--color-success-bg: rgba(127, 221, 168, .14);
--color-success-dot: #7FDDA8;
--color-danger: #EB93A1; /* = --color-room-mic-off */
--color-danger-bg: rgba(235, 147, 161, .14);
--color-danger-dot: #EB93A1;
--color-danger-solid: #B85468; /* = --color-room-danger-bg, заливка danger-кнопок */
--color-danger-solid-hover: #B9495F;
--color-warning: #D6A83D; /* = --color-room-speaker-ring */
--color-warning-bg: rgba(214, 168, 61, .16);
--color-warning-dot: #D6A83D;
--color-focus-ring: #D6A83D; /* = --color-room-focus-ring */
--shadow-sm: 0 1px 2px rgba(0, 0, 0, .35);
--shadow-md: 0 4px 16px rgba(0, 0, 0, .4);
--shadow-lg: 0 12px 32px rgba(0, 0, 0, .5);
--shadow-glass: 0 8px 24px rgba(0, 0, 0, .45);
}
/* Переключатель темы (солнце/луна) — статичная демонстрация, не функциональна в макете */
.theme-toggle { position: fixed; top: 24px; right: 32px; z-index: 50; display: inline-flex; gap: 2px; background: var(--color-bg-alt); padding: 4px; border-radius: var(--radius-full); border: 1px solid var(--color-border); box-shadow: var(--shadow-md); }
.theme-toggle-btn { width: 32px; height: 32px; border-radius: 50%; border: none; background: transparent; color: var(--color-ink-500); display: flex; align-items: center; justify-content: center; }
.theme-toggle-btn .icon { width: 16px; height: 16px; }
.theme-toggle-btn:hover { color: var(--color-ink-900); }
.theme-toggle-btn.is-active { background: var(--color-surface); color: var(--color-ink-700); box-shadow: var(--shadow-sm); }
html { min-width: 1280px; }
body { min-height: 100vh; }
.layout { display: flex; min-height: 100vh; }
/* ---------- Брендовая панель ---------- */
.brand-panel {
width: 42%;
background: linear-gradient(160deg, #242424 0%, #1E1E1E 55%, #1A1A1A 100%);
padding: var(--space-12) var(--space-12);
display: flex;
flex-direction: column;
justify-content: space-between;
position: relative;
overflow: hidden;
border-right: 1px solid var(--color-border);
}
.brand-panel::after {
content: "";
position: absolute;
right: -120px; bottom: -120px;
width: 380px; height: 380px;
border-radius: 50%;
background: radial-gradient(circle at 30% 30%, rgba(127,221,168,.16), rgba(127,221,168,0) 70%);
}
.brand-mark {
display: inline-flex;
align-items: center;
gap: var(--space-2);
font: var(--text-h3);
color: var(--color-ink-700);
z-index: 1;
}
.brand-mark .logo-mark { width: 22px; height: 22px; flex-shrink: 0; }
.brand-copy { z-index: 1; }
.eyebrow {
font: var(--text-caption);
letter-spacing: .08em;
color: var(--color-ink-400);
margin: 0 0 var(--space-4);
}
.brand-headline {
font: var(--text-display-lg);
font-family: var(--font-display);
color: var(--color-ink-700);
margin: 0 0 var(--space-4);
max-width: 460px;
}
.brand-sub {
font: var(--text-body-lg);
color: var(--color-ink-500);
max-width: 420px;
margin: 0;
}
.brand-stats { display: flex; gap: var(--space-4); z-index: 1; margin-top: var(--space-8); }
.stat-glass {
background: var(--color-surface-glass);
backdrop-filter: blur(16px);
-webkit-backdrop-filter: blur(16px);
border: 1px solid rgba(255,255,255,.08);
box-shadow: var(--shadow-glass);
border-radius: var(--radius-xl);
padding: var(--space-4) var(--space-5);
min-width: 140px;
}
.stat-glass strong { display: block; font: var(--text-h1); font-family: var(--font-display); color: var(--color-ink-700); }
.stat-glass span { font: var(--text-caption); color: var(--color-ink-500); text-transform: none; letter-spacing: normal; }
/* ---------- Форма-панель ---------- */
.form-panel {
width: 58%;
padding: var(--space-12) var(--space-16);
display: flex;
flex-direction: column;
gap: var(--space-16);
}
.screen-block { max-width: 440px; }
.screen-label {
font: var(--text-caption);
color: var(--color-ink-400);
margin: 0 0 var(--space-3);
}
.screen-label b { color: var(--color-ink-700); }
.screen-title { font: var(--text-h1); color: var(--color-ink-900); margin: 0 0 var(--space-8); }
.divider { border: none; border-top: 1px solid var(--color-border); max-width: 720px; margin: 0; }
.tabs { display: flex; gap: var(--space-2); margin-bottom: var(--space-6); background: var(--color-bg-alt); padding: 4px; border-radius: var(--radius-full); width: fit-content; }
.tab { padding: 8px 20px; border-radius: var(--radius-full); border: none; background: transparent; font: var(--text-body); color: var(--color-ink-500); }
.tab.is-active { background: var(--color-surface); color: var(--color-ink-700); font-weight: 600; box-shadow: var(--shadow-sm); }
.field { margin-bottom: var(--space-5); }
.field label { display: block; font: var(--text-body); font-weight: 600; color: var(--color-ink-900); margin-bottom: var(--space-2); }
.input-wrap { position: relative; }
.input-wrap .icon { position: absolute; left: 14px; top: 50%; transform: translateY(-50%); color: var(--color-ink-400); }
.input-wrap input {
width: 100%;
font: var(--text-body-lg);
color: var(--color-ink-900);
padding: 11px 14px 11px 42px;
border-radius: var(--radius-md);
border: 1px solid var(--color-border);
background: var(--color-surface);
outline: none;
}
.input-wrap input::placeholder { color: var(--color-ink-300); }
.input-wrap input:hover { border-color: var(--color-border-strong); }
.input-wrap input:focus { border-color: var(--color-focus-ring); box-shadow: 0 0 0 3px rgba(214,168,61,.18); }
.input-wrap .toggle-eye { left: auto; right: 14px; background: none; border: none; padding: 0; cursor: pointer; }
.field.has-error input { border-color: var(--color-danger); box-shadow: 0 0 0 3px rgba(235,147,161,.18); }
.error-msg { display: flex; align-items: center; gap: 6px; margin-top: var(--space-2); font: var(--text-body); color: var(--color-danger); }
.hint-msg { margin-top: var(--space-2); font: var(--text-body); color: var(--color-ink-500); }
.field-disabled input { background: var(--color-bg-alt); color: var(--color-ink-300); cursor: not-allowed; }
.row-between { display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--space-6); }
.checkbox-row { display: flex; align-items: center; gap: 8px; font: var(--text-body); color: var(--color-ink-500); }
.link { color: var(--color-ink-700); font-weight: 600; text-decoration: none; }
.link:hover { text-decoration: underline; }
.btn { display: inline-flex; align-items: center; justify-content: center; gap: 8px; border: none; cursor: pointer; font-family: var(--font-body); transition: background var(--transition-fast), box-shadow var(--transition-fast); }
.btn-primary {
width: 100%;
background: var(--color-accent);
color: var(--color-accent-text);
font: var(--text-body-lg);
font-weight: 700;
padding: 13px 24px;
border-radius: var(--radius-full);
}
.btn-primary:hover { background: var(--color-accent-hover); box-shadow: var(--shadow-md); }
.btn-primary:active { background: var(--color-accent-active); }
.btn-primary[disabled] { background: rgba(122,122,122,.35); color: var(--color-ink-300); cursor: not-allowed; }
.btn-secondary {
width: 100%;
background: transparent;
color: var(--color-ink-700);
border: 1.5px solid var(--color-border-pill);
font: var(--text-body-lg);
font-weight: 600;
padding: 12px 24px;
border-radius: var(--radius-full);
}
.btn-secondary:hover { background: var(--color-bg-alt); border-color: var(--color-ink-700); }
.oauth-row { display: flex; gap: var(--space-3); margin-top: var(--space-5); }
.oauth-row .btn-secondary { flex: 1; }
.separator { display: flex; align-items: center; gap: 12px; color: var(--color-ink-400); font: var(--text-caption); margin: var(--space-6) 0; text-transform: none; letter-spacing: normal; }
.separator::before, .separator::after { content: ""; flex: 1; height: 1px; background: var(--color-border); }
/* ---------- Подтверждение email ---------- */
.confirm-card {
max-width: 440px;
background: var(--color-surface);
border: 1px solid var(--color-border);
border-radius: var(--radius-2xl);
padding: var(--space-8);
text-align: left;
}
.confirm-icon {
width: 56px; height: 56px; border-radius: var(--radius-full);
background: var(--color-success-bg); color: var(--color-success);
display: flex; align-items: center; justify-content: center;
margin-bottom: var(--space-5);
}
.confirm-icon .icon { width: 28px; height: 28px; }
.confirm-card h3 { font: var(--text-h2); color: var(--color-ink-900); margin: 0 0 var(--space-2); }
.confirm-card p { font: var(--text-body-lg); color: var(--color-ink-500); margin: 0 0 var(--space-6); }
.confirm-card .mail-chip {
display: inline-flex; align-items: center; gap: 8px;
background: var(--color-bg-alt); border-radius: var(--radius-full);
padding: 6px 14px; font: var(--text-mono-sm); color: var(--color-ink-700);
margin-bottom: var(--space-6);
}
/* pending confirmation state variant */
.confirm-card.pending .confirm-icon { background: var(--color-warning-bg); color: var(--color-warning); }
</style>
</head>
<body>
<svg style="display:none">
<symbol id="i-mail" viewBox="0 0 24 24"><rect x="2" y="4" width="20" height="16" rx="2"/><path d="m2 6 10 7 10-7"/></symbol>
<symbol id="i-lock" viewBox="0 0 24 24"><rect x="3" y="11" width="18" height="11" rx="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></symbol>
<symbol id="i-user" viewBox="0 0 24 24"><circle cx="12" cy="8" r="4"/><path d="M6 21v-2a6 6 0 0 1 12 0v2"/></symbol>
<symbol id="i-eye" viewBox="0 0 24 24"><path d="M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7-10-7-10-7Z"/><circle cx="12" cy="12" r="3"/></symbol>
<symbol id="i-eye-off" viewBox="0 0 24 24"><path d="M3 3l18 18"/><path d="M10.58 10.58a2 2 0 0 0 2.83 2.83"/><path d="M9.88 5.09A9.77 9.77 0 0 1 12 5c6.5 0 10 7 10 7a13.16 13.16 0 0 1-3.06 4.06M6.1 6.1A13.16 13.16 0 0 0 2 12s3.5 7 10 7a9.77 9.77 0 0 0 4.9-1.3"/></symbol>
<symbol id="i-check-circle" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><path d="m9 12 2 2 4-4"/></symbol>
<symbol id="i-arrow-right" viewBox="0 0 24 24"><line x1="5" y1="12" x2="19" y2="12"/><polyline points="12 5 19 12 12 19"/></symbol>
<symbol id="i-alert" viewBox="0 0 24 24"><path d="M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0Z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></symbol>
<symbol id="i-clock" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></symbol>
<symbol id="i-sun" viewBox="0 0 24 24"><circle cx="12" cy="12" r="5"/><line x1="12" y1="1" x2="12" y2="3"/><line x1="12" y1="21" x2="12" y2="23"/><line x1="4.22" y1="4.22" x2="5.64" y2="5.64"/><line x1="18.36" y1="18.36" x2="19.78" y2="19.78"/><line x1="1" y1="12" x2="3" y2="12"/><line x1="21" y1="12" x2="23" y2="12"/><line x1="4.22" y1="19.78" x2="5.64" y2="18.36"/><line x1="18.36" y1="5.64" x2="19.78" y2="4.22"/></symbol>
<symbol id="i-moon" viewBox="0 0 24 24"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79Z"/></symbol>
</svg>
<div class="theme-toggle" role="group" aria-label="Переключить тему оформления">
<button class="theme-toggle-btn" type="button" aria-pressed="false" aria-label="Светлая тема"><svg class="icon"><use href="#i-sun"/></svg></button>
<button class="theme-toggle-btn is-active" type="button" aria-pressed="true" aria-label="Тёмная тема"><svg class="icon"><use href="#i-moon"/></svg></button>
</div>
<div class="layout">
<!-- ===================== БРЕНД-ПАНЕЛЬ ===================== -->
<aside class="brand-panel">
<div class="brand-mark"><svg class="logo-mark" viewBox="0 0 32 32" fill="none" aria-hidden="true"><polygon points="21,16 18.5,20.3 13.5,20.3 11,16 13.5,11.7 18.5,11.7" fill="currentColor"/><circle cx="16" cy="16" r="13" stroke="currentColor" stroke-width="2.6" stroke-dasharray="12 6"/></svg> VidConf</div>
<div class="brand-copy">
<p class="eyebrow">[ SELF-HOSTED ВИДЕОКОНФЕРЕНЦИИ ]</p>
<h1 class="brand-headline">Ваши встречи.<br>Ваша инфраструктура.</h1>
<p class="brand-sub">Видео, записи и AI-саммари обрабатываются на ваших серверах - данные не уходят
за пределы вашей инфраструктуры. Гости подключаются по ссылке или номеру, без регистрации.</p>
<div class="brand-stats">
<div class="stat-glass"><strong>100%</strong><span>данных - в вашем контуре</span></div>
<div class="stat-glass"><strong>AI-саммари</strong><span>на почту после встречи</span></div>
</div>
</div>
<p class="hint-msg" style="z-index:1">© 2026 VidConf · self-hosted</p>
</aside>
<!-- ===================== ФОРМА: ВХОД / РЕГИСТРАЦИЯ ===================== -->
<main class="form-panel">
<section class="screen-block">
<p class="screen-label">Экран: <b>вход в аккаунт</b></p>
<div class="tabs" role="tablist" aria-label="Способ авторизации">
<button class="tab is-active" role="tab" aria-selected="true">Вход</button>
<button class="tab" role="tab" aria-selected="false">Регистрация</button>
</div>
<form>
<div class="field">
<label for="login-email">Рабочая почта</label>
<div class="input-wrap">
<svg class="icon"><use href="#i-mail"/></svg>
<input id="login-email" type="email" placeholder="you@company.ru" value="a.ivanova@vidconf.dev">
</div>
</div>
<div class="field has-error">
<label for="login-pass">Пароль</label>
<div class="input-wrap">
<svg class="icon"><use href="#i-lock"/></svg>
<input id="login-pass" type="password" placeholder="••••••••" value="wrongpass">
<button type="button" class="toggle-eye" aria-label="Показать пароль">
<svg class="icon"><use href="#i-eye"/></svg>
</button>
</div>
<p class="error-msg"><svg class="icon" style="width:16px;height:16px"><use href="#i-alert"/></svg> Неверный email или пароль</p>
</div>
<div class="row-between">
<label class="checkbox-row"><input type="checkbox" checked> Запомнить меня</label>
<a href="#" class="link">Забыли пароль?</a>
</div>
<button type="submit" class="btn btn-primary">Войти <svg class="icon"><use href="#i-arrow-right"/></svg></button>
</form>
</section>
<hr class="divider">
<section class="screen-block">
<p class="screen-label">Экран: <b>регистрация</b></p>
<h2 class="screen-title">Создать аккаунт</h2>
<form>
<div class="field">
<label for="reg-name">Имя и фамилия</label>
<div class="input-wrap">
<svg class="icon"><use href="#i-user"/></svg>
<input id="reg-name" type="text" placeholder="Мария Кузнецова">
</div>
</div>
<div class="field">
<label for="reg-email">Рабочая почта</label>
<div class="input-wrap">
<svg class="icon"><use href="#i-mail"/></svg>
<input id="reg-email" type="email" placeholder="you@company.ru">
</div>
</div>
<div class="field">
<label for="reg-pass">Пароль</label>
<div class="input-wrap">
<svg class="icon"><use href="#i-lock"/></svg>
<input id="reg-pass" type="password" placeholder="Минимум 8 символов">
<button type="button" class="toggle-eye" aria-label="Скрыть пароль">
<svg class="icon"><use href="#i-eye-off"/></svg>
</button>
</div>
<p class="hint-msg">Минимум 8 символов, буквы и цифры</p>
</div>
<button type="submit" class="btn btn-primary" style="margin-top:8px">Зарегистрироваться</button>
<div class="separator">или</div>
<div class="field field-disabled" style="margin-bottom:0">
<label for="reg-invite">Код приглашения (недоступно без администратора)</label>
<div class="input-wrap">
<input id="reg-invite" type="text" placeholder="INVITE-XXXX-XXXX" disabled>
</div>
</div>
</form>
</section>
<hr class="divider">
<section class="screen-block">
<p class="screen-label">Экран: <b>подтверждение email</b></p>
<div class="confirm-card" style="margin-bottom: var(--space-6);">
<div class="confirm-icon"><svg class="icon"><use href="#i-check-circle"/></svg></div>
<h3>Почта подтверждена</h3>
<p>Аккаунт <strong>a.ivanova@vidconf.dev</strong> активирован. Теперь
доступно бронирование переговорных и вход в конференции.</p>
<button class="btn btn-primary">Перейти в лобби <svg class="icon"><use href="#i-arrow-right"/></svg></button>
</div>
<div class="confirm-card pending">
<div class="confirm-icon"><svg class="icon"><use href="#i-clock"/></svg></div>
<h3>Подтвердите почту</h3>
<p>Мы отправили письмо со ссылкой на <span class="mail-chip"><svg class="icon" style="width:14px;height:14px"><use href="#i-mail"/></svg>m.kuznetsova@company.ru</span></p>
<button class="btn btn-secondary">Отправить письмо повторно</button>
</div>
</section>
</main>
</div>
</body>
</html>