refactor: update web-client files - replace old HTML/JS/CSS with new droidAssist implementation
- Remove old: assist.html, index.html, script.js, styles.css, AI robot.lottie - Add new: droidAssist.html, droidAssist.css, droidAssist.js, animation.lottie - Restructure web-client files into html/ directory
This commit is contained in:
@@ -0,0 +1,396 @@
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
/* ===== СЛОЙ 1: BODY — общий фон страницы ===== */
|
||||
body {
|
||||
background: radial-gradient(circle at 30% 20%, #0a0f1e, #03060c);
|
||||
font-family: 'Segoe UI', 'Inter', system-ui, sans-serif;
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* ===== Частицы ===== */
|
||||
.particles {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
pointer-events: none;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.particle {
|
||||
position: absolute;
|
||||
width: 2px;
|
||||
height: 2px;
|
||||
background: rgba(0, 255, 255, 0.3);
|
||||
border-radius: 50%;
|
||||
animation: float 20s infinite;
|
||||
}
|
||||
|
||||
@keyframes float {
|
||||
0%, 100% { transform: translateY(0) translateX(0); opacity: 0; }
|
||||
10% { opacity: 1; }
|
||||
90% { opacity: 1; }
|
||||
100% { transform: translateY(-100vh) translateX(50px); opacity: 0; }
|
||||
}
|
||||
|
||||
/* ===== Контейнер ассистента ===== */
|
||||
.assistant-container {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 40px;
|
||||
padding: 40px;
|
||||
max-width: 600px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* ===== Бейдж подключения ===== */
|
||||
.connection-badge {
|
||||
position: absolute;
|
||||
top: 30px;
|
||||
right: 30px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
backdrop-filter: blur(10px);
|
||||
padding: 12px 20px;
|
||||
border-radius: 50px;
|
||||
border: 1px solid rgba(0, 255, 255, 0.3);
|
||||
font-size: 14px;
|
||||
color: #b0e0ff;
|
||||
font-weight: 500;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.status-dot {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
border-radius: 50%;
|
||||
background: #ff4d4d;
|
||||
box-shadow: 0 0 10px #ff4d4d;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.status-dot.connected {
|
||||
background: #0ff;
|
||||
box-shadow: 0 0 20px #0ff;
|
||||
animation: pulse-dot 2s infinite;
|
||||
}
|
||||
|
||||
@keyframes pulse-dot {
|
||||
0%, 100% { transform: scale(1); opacity: 1; }
|
||||
50% { transform: scale(1.2); opacity: 0.8; }
|
||||
}
|
||||
|
||||
/* ===== СЛОЙ 3: ANIMATION-WRAPPER — непрозрачный тёмный круг =====
|
||||
isolation: isolate создаёт локальный stacking context,
|
||||
чтобы ::before с z-index: -1 был ПОД wrapper, но НАД body
|
||||
*/
|
||||
.animation-wrapper {
|
||||
position: relative;
|
||||
width: 420px;
|
||||
height: 420px;
|
||||
border-radius: 50%;
|
||||
isolation: isolate;
|
||||
|
||||
/* CSS-переменные для фона круга и ореола */
|
||||
--bg-light: #1a2540;
|
||||
--bg-dark: #03060c;
|
||||
--glow-color: rgba(59, 130, 246, 0.55);
|
||||
|
||||
/* Непрозрачный тёмный фон — свой для каждого состояния */
|
||||
background: radial-gradient(
|
||||
circle at 30% 30%,
|
||||
var(--bg-light) 0%,
|
||||
#0a0f1e 50%,
|
||||
var(--bg-dark) 100%
|
||||
);
|
||||
|
||||
/* Лёгкая внутренняя подсветка (inset) */
|
||||
box-shadow: inset 0 0 40px rgba(0, 0, 0, 0.5);
|
||||
|
||||
transition: background 0.8s ease;
|
||||
}
|
||||
|
||||
/* ===== СЛОЙ 2: ::BEFORE — свечение-ореол, выходит за границы ===== */
|
||||
.animation-wrapper::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
/* Выходим за границы круга на 70px с каждой стороны */
|
||||
inset: -70px;
|
||||
border-radius: 50%;
|
||||
|
||||
/* Светящийся ореол */
|
||||
background: radial-gradient(
|
||||
circle at center,
|
||||
var(--glow-color) 0%,
|
||||
var(--glow-color) 30%,
|
||||
rgba(0, 0, 0, 0) 70%
|
||||
);
|
||||
|
||||
filter: blur(25px);
|
||||
opacity: 0.85;
|
||||
|
||||
/* ПОД wrapper, но НАД body благодаря isolation: isolate */
|
||||
z-index: -1;
|
||||
pointer-events: none;
|
||||
|
||||
transition: background 0.8s ease, opacity 0.8s ease;
|
||||
animation: halo-pulse 3s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes halo-pulse {
|
||||
0%, 100% {
|
||||
transform: scale(1);
|
||||
opacity: 0.7;
|
||||
}
|
||||
50% {
|
||||
transform: scale(1.08);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* ===== СЛОЙ 4: LOTTIE-CANVAS — анимация с прозрачным фоном ===== */
|
||||
#lottie-canvas {
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
display: block;
|
||||
transform: scale(2);
|
||||
transform-origin: center center;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
|
||||
/* Обрезаем canvas по кругу, чтобы не вылезал за wrapper */
|
||||
clip-path: circle(50% at center);
|
||||
|
||||
/* Фон прозрачный — видно непрозрачный фон wrapper под ним */
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
/* ===== ЦВЕТА ДЛЯ КАЖДОГО СОСТОЯНИЯ ===== */
|
||||
.animation-wrapper.idle {
|
||||
--bg-light: #1a2540;
|
||||
--bg-dark: #03060c;
|
||||
--glow-color: rgba(59, 130, 246, 0.55);
|
||||
}
|
||||
|
||||
.animation-wrapper.yes {
|
||||
--bg-light: #0f2818;
|
||||
--bg-dark: #030a06;
|
||||
--glow-color: rgba(34, 197, 94, 0.65);
|
||||
}
|
||||
|
||||
.animation-wrapper.no {
|
||||
--bg-light: #2a1010;
|
||||
--bg-dark: #0a0303;
|
||||
--glow-color: rgba(239, 68, 68, 0.7);
|
||||
}
|
||||
.animation-wrapper.no::before {
|
||||
animation: halo-pulse 1s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.animation-wrapper.alert {
|
||||
--bg-light: #2a1f08;
|
||||
--bg-dark: #0a0803;
|
||||
--glow-color: rgba(245, 158, 11, 0.7);
|
||||
}
|
||||
.animation-wrapper.alert::before {
|
||||
animation: halo-pulse 0.5s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.animation-wrapper.thinking {
|
||||
--bg-light: #1a0f2a;
|
||||
--bg-dark: #06030a;
|
||||
--glow-color: rgba(168, 85, 247, 0.65);
|
||||
}
|
||||
.animation-wrapper.thinking::before {
|
||||
animation: halo-pulse 1.5s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.animation-wrapper.jump {
|
||||
--bg-light: #2a0f1f;
|
||||
--bg-dark: #0a0306;
|
||||
--glow-color: rgba(236, 72, 153, 0.75);
|
||||
}
|
||||
.animation-wrapper.jump::before {
|
||||
animation: halo-pulse 0.3s ease-in-out infinite;
|
||||
}
|
||||
|
||||
/* ===== Оверлей загрузки ===== */
|
||||
.loading-overlay {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: rgba(3, 6, 12, 0.95);
|
||||
z-index: 10;
|
||||
border-radius: 50%;
|
||||
transition: opacity 0.5s;
|
||||
}
|
||||
.loading-overlay.hidden { opacity: 0; pointer-events: none; }
|
||||
|
||||
/* ===== Текст статуса ===== */
|
||||
.status-text {
|
||||
font-size: 24px;
|
||||
font-weight: 600;
|
||||
color: #00ffff;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 4px;
|
||||
text-shadow: 0 0 20px rgba(0, 255, 255, 0.5);
|
||||
animation: text-glow 2s ease-in-out infinite;
|
||||
min-height: 30px;
|
||||
}
|
||||
|
||||
@keyframes text-glow {
|
||||
0%, 100% { text-shadow: 0 0 20px rgba(0, 255, 255, 0.5); }
|
||||
50% { text-shadow: 0 0 40px rgba(0, 255, 255, 0.8); }
|
||||
}
|
||||
|
||||
/* ===== Контейнер громкости ===== */
|
||||
.volume-container {
|
||||
width: 100%;
|
||||
max-width: 400px;
|
||||
background: rgba(0, 0, 0, 0.4);
|
||||
backdrop-filter: blur(20px);
|
||||
border: 1px solid rgba(0, 255, 255, 0.3);
|
||||
border-radius: 30px;
|
||||
padding: 30px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.volume-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
color: #b0e0ff;
|
||||
font-size: 14px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 2px;
|
||||
}
|
||||
|
||||
.volume-value {
|
||||
font-size: 24px;
|
||||
font-weight: 700;
|
||||
color: #00ffff;
|
||||
font-family: 'Courier New', monospace;
|
||||
}
|
||||
|
||||
.volume-slider {
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
width: 100%;
|
||||
height: 8px;
|
||||
background: rgba(0, 255, 255, 0.2);
|
||||
border-radius: 10px;
|
||||
outline: none;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.volume-slider::-webkit-slider-thumb {
|
||||
-webkit-appearance: none;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
background: #00ffff;
|
||||
border-radius: 50%;
|
||||
cursor: pointer;
|
||||
box-shadow: 0 0 20px rgba(0, 255, 255, 0.8);
|
||||
}
|
||||
|
||||
/* ===== Кнопки громкости ===== */
|
||||
.vol-btn {
|
||||
background: rgba(0, 255, 255, 0.1);
|
||||
border: 1px solid rgba(0, 255, 255, 0.5);
|
||||
color: #00ffff;
|
||||
padding: 12px 24px;
|
||||
border-radius: 50px;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.vol-btn:hover {
|
||||
background: rgba(0, 255, 255, 0.3);
|
||||
border-color: #00ffff;
|
||||
box-shadow: 0 0 20px rgba(0, 255, 255, 0.5);
|
||||
}
|
||||
|
||||
/* ===== Debug-кнопки ===== */
|
||||
.debug-buttons {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
gap: 12px;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
.debug-btn {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
border: 1px solid rgba(0, 255, 255, 0.4);
|
||||
color: #0ff;
|
||||
padding: 8px 16px;
|
||||
border-radius: 40px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
transition: 0.2s;
|
||||
}
|
||||
|
||||
.debug-btn:hover {
|
||||
background: rgba(0, 255, 255, 0.2);
|
||||
border-color: #0ff;
|
||||
box-shadow: 0 0 10px rgba(0, 255, 255, 0.4);
|
||||
}
|
||||
|
||||
/* ===== Transcript box ===== */
|
||||
.transcript-box {
|
||||
width: 100%;
|
||||
max-width: 500px;
|
||||
background: rgba(0, 0, 0, 0.3);
|
||||
backdrop-filter: blur(15px);
|
||||
border: 1px solid rgba(0, 255, 255, 0.2);
|
||||
border-radius: 20px;
|
||||
padding: 20px;
|
||||
min-height: 80px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.transcript-label {
|
||||
font-size: 12px;
|
||||
color: #7f9fcf;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 2px;
|
||||
}
|
||||
|
||||
.transcript-text {
|
||||
font-size: 18px;
|
||||
color: #eef5ff;
|
||||
font-style: italic;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
/* ===== Адаптив ===== */
|
||||
@media (max-width: 768px) {
|
||||
.animation-wrapper { width: 280px; height: 280px; }
|
||||
.status-text { font-size: 20px; }
|
||||
}
|
||||
Reference in New Issue
Block a user