feat: premium UI redesign — glassmorphism, gradient accents, ambient background
All checks were successful
Deploy / deploy (push) Successful in 2m40s

This commit is contained in:
Cosmo
2026-04-22 18:38:31 +00:00
parent 4874466985
commit eb644ff341
8 changed files with 763 additions and 436 deletions

View File

@@ -5,22 +5,37 @@
}
:root {
--bg: #0a0a14;
--sidebar-bg: rgba(255, 255, 255, 0.02);
--card-bg: rgba(255, 255, 255, 0.05);
--card-border: rgba(255, 255, 255, 0.08);
--text-primary: rgba(255, 255, 255, 0.92);
--bg: #0c0c18;
--bg-secondary: #12121f;
--sidebar-bg: rgba(12, 12, 24, 0.8);
--card-bg: rgba(255, 255, 255, 0.04);
--card-bg-hover: rgba(255, 255, 255, 0.07);
--card-border: rgba(255, 255, 255, 0.07);
--card-border-hover: rgba(255, 255, 255, 0.12);
--text-primary: rgba(255, 255, 255, 0.95);
--text-secondary: rgba(255, 255, 255, 0.45);
--accent: #00d4ff;
--accent-glow: rgba(0, 212, 255, 0.15);
--on-color: #00d4ff;
--off-color: rgba(255, 255, 255, 0.2);
--text-tertiary: rgba(255, 255, 255, 0.25);
--accent: #818cf8;
--accent-secondary: #22d3ee;
--accent-glow: rgba(129, 140, 248, 0.15);
--glass: rgba(255, 255, 255, 0.03);
--glass-border: rgba(255, 255, 255, 0.06);
--gradient-primary: linear-gradient(135deg, #6366f1, #8b5cf6);
--gradient-warm: linear-gradient(135deg, #f59e0b, #ef4444);
--gradient-cool: linear-gradient(135deg, #06b6d4, #3b82f6);
--gradient-green: linear-gradient(135deg, #10b981, #34d399);
--on-color: #818cf8;
--off-color: rgba(255, 255, 255, 0.15);
--radius-sm: 12px;
--radius-md: 16px;
--radius-lg: 22px;
--radius-xl: 28px;
}
html, body {
background: var(--bg);
color: var(--text-primary);
font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Display', 'Segoe UI', system-ui, sans-serif;
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'SF Pro Display', 'Segoe UI', system-ui, sans-serif;
height: 100%;
overflow: hidden;
-webkit-font-smoothing: antialiased;
@@ -31,6 +46,70 @@ html, body {
height: 100%;
}
/* Ambient background orbs */
.bg-ambient {
position: fixed;
inset: 0;
z-index: 0;
overflow: hidden;
pointer-events: none;
}
.bg-ambient::before {
content: '';
position: absolute;
width: 600px;
height: 600px;
border-radius: 50%;
background: radial-gradient(circle, rgba(99, 102, 241, 0.08) 0%, transparent 70%);
top: -200px;
right: -100px;
animation: float1 20s ease-in-out infinite;
}
.bg-ambient::after {
content: '';
position: absolute;
width: 500px;
height: 500px;
border-radius: 50%;
background: radial-gradient(circle, rgba(139, 92, 246, 0.06) 0%, transparent 70%);
bottom: -150px;
left: -50px;
animation: float2 25s ease-in-out infinite;
}
@keyframes float1 {
0%, 100% { transform: translate(0, 0) scale(1); }
33% { transform: translate(30px, 40px) scale(1.05); }
66% { transform: translate(-20px, 20px) scale(0.95); }
}
@keyframes float2 {
0%, 100% { transform: translate(0, 0) scale(1); }
33% { transform: translate(-40px, -30px) scale(1.1); }
66% { transform: translate(20px, -10px) scale(0.9); }
}
/* Glass card base */
.glass-card {
background: var(--card-bg);
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
border: 1px solid var(--card-border);
border-radius: var(--radius-lg);
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
.glass-card:hover {
background: var(--card-bg-hover);
border-color: var(--card-border-hover);
}
/* Gradient text */
.gradient-text {
background: var(--gradient-primary);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
button {
cursor: pointer;
border: none;
@@ -46,20 +125,34 @@ button:focus-visible {
outline-offset: 2px;
}
/* Smooth scrollbar */
::-webkit-scrollbar {
width: 4px;
height: 4px;
}
::-webkit-scrollbar-track {
background: transparent;
}
::-webkit-scrollbar-thumb {
background: rgba(255, 255, 255, 0.1);
background: rgba(255, 255, 255, 0.08);
border-radius: 2px;
}
::-webkit-scrollbar-thumb:hover {
background: rgba(255, 255, 255, 0.2);
background: rgba(255, 255, 255, 0.15);
}
/* Pulse animation for active devices */
@keyframes pulse-glow {
0%, 100% { box-shadow: 0 0 20px rgba(129, 140, 248, 0.15); }
50% { box-shadow: 0 0 30px rgba(129, 140, 248, 0.25); }
}
/* Slide in animation */
@keyframes slideUp {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
.animate-slide-up {
animation: slideUp 0.4s cubic-bezier(0.4, 0, 0.2, 1) forwards;
}

View File

@@ -3,7 +3,7 @@ import "./globals.css";
export const metadata: Metadata = {
title: "Smart Home Dashboard",
description: "Smart Home Tablet Dashboard — управление умным домом",
description: "Smart Home Tablet Dashboard",
manifest: "/manifest.json",
};
@@ -26,6 +26,7 @@ export default function RootLayout({
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossOrigin="anonymous" />
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet" />
</head>
<body className="antialiased">{children}</body>
</html>

View File

@@ -1,6 +1,7 @@
'use client'
import { useState, useEffect, useCallback } from 'react'
import { Thermometer, Droplets, Wind, Calendar, Sun, CloudRain, Snowflake as SnowIcon, Cloud, CloudSun, Zap, Settings as SettingsIcon } from 'lucide-react'
import Sidebar from '@/components/Sidebar'
import TopBar from '@/components/TopBar'
import RoomTabs from '@/components/RoomTabs'
@@ -56,53 +57,19 @@ const DEVICES_BY_ROOM: Record<string, {
isMock?: boolean
}[]> = {
living: [
{
id: 'air_purifier',
name: 'Очиститель воздуха',
icon: '💨',
entityId: 'fan.zhimi_rmb1_9528_air_purifier',
domain: 'fan',
haKey: 'fan.air_purifier',
isMock: false,
},
{
id: 'light_living',
name: 'Свет',
icon: '💡',
entityId: 'light.living_room',
domain: 'light',
haKey: 'light.living_room',
isMock: true,
},
{
id: 'tv',
name: 'Телевизор',
icon: '📺',
isMock: true,
},
{ id: 'air_purifier', name: 'Очиститель воздуха', icon: '💨', entityId: 'fan.zhimi_rmb1_9528_air_purifier', domain: 'fan', haKey: 'fan.air_purifier', isMock: false },
{ id: 'light_living', name: 'Свет', icon: '💡', entityId: 'light.living_room', domain: 'light', haKey: 'light.living_room', isMock: true },
{ id: 'tv', name: 'Телевизор', icon: '📺', isMock: true },
],
bedroom: [
{
id: 'light_bedroom',
name: 'Свет',
icon: '💡',
entityId: 'light.bedroom',
domain: 'light',
haKey: 'light.bedroom',
isMock: true,
},
{
id: 'ac',
name: 'Кондиционер',
icon: '❄️',
isMock: true,
},
{ id: 'light_bedroom', name: 'Свет', icon: '💡', entityId: 'light.bedroom', domain: 'light', haKey: 'light.bedroom', isMock: true },
{ id: 'ac', name: 'Кондиционер', icon: '❄️', isMock: true },
],
kitchen: [],
bathroom: [],
}
function getWeatherEmoji(desc: string): string {
function getWeatherIcon(desc: string): string {
const d = desc?.toLowerCase() || ''
if (d.includes('ясно') || d.includes('солнеч')) return '☀️'
if (d.includes('облач')) return '⛅'
@@ -118,6 +85,13 @@ function formatEventTime(iso: string): string {
return d.toLocaleTimeString('ru-RU', { hour: '2-digit', minute: '2-digit' })
}
function getPm25Level(pm25: number): { label: string; color: string; bg: string } {
if (pm25 <= 12) return { label: 'Отлично', color: '#34d399', bg: 'rgba(52,211,153,0.12)' }
if (pm25 <= 35) return { label: 'Хорошо', color: '#a3e635', bg: 'rgba(163,230,53,0.12)' }
if (pm25 <= 55) return { label: 'Умеренно', color: '#fbbf24', bg: 'rgba(251,191,36,0.12)' }
return { label: 'Плохо', color: '#f87171', bg: 'rgba(248,113,113,0.12)' }
}
// ————— Home Tab —————
function HomeTab({ weather, sensors }: { weather: WeatherData | null; sensors: SensorData | null }) {
const [todayEvents, setTodayEvents] = useState<CalendarEvent[]>([])
@@ -131,38 +105,182 @@ function HomeTab({ weather, sensors }: { weather: WeatherData | null; sensors: S
.finally(() => setCalLoading(false))
}, [])
return (
<div style={{ flex: 1, overflowY: 'auto', WebkitOverflowScrolling: 'touch' as any, padding: '16px 20px 24px', display: 'flex', flexDirection: 'column', gap: 16 }}>
const pm25Info = sensors ? getPm25Level(sensors.pm25) : null
{/* Today Widget */}
return (
<div style={{ flex: 1, overflowY: 'auto', WebkitOverflowScrolling: 'touch' as any, padding: '20px 24px 28px', display: 'flex', flexDirection: 'column', gap: 16 }}>
{/* Top row: Weather + Sensors side by side */}
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 16 }}>
{/* Weather Card */}
{weather && (
<div style={{
background: 'linear-gradient(135deg, rgba(99,102,241,0.12), rgba(139,92,246,0.06))',
backdropFilter: 'blur(20px)',
border: '1px solid rgba(129,140,248,0.12)',
borderRadius: 22,
padding: '22px 24px',
position: 'relative',
overflow: 'hidden',
}}>
{/* Background decoration */}
<div style={{
position: 'absolute', top: -20, right: -10,
fontSize: 80, opacity: 0.12, pointerEvents: 'none',
}}>
{getWeatherIcon(weather.desc)}
</div>
<div style={{ fontSize: 11, color: 'var(--text-secondary)', textTransform: 'uppercase', letterSpacing: '0.1em', fontWeight: 600, marginBottom: 16 }}>
Погода
</div>
<div style={{ display: 'flex', alignItems: 'center', gap: 16, marginBottom: 18, position: 'relative', zIndex: 1 }}>
<span style={{ fontSize: 44 }}>{getWeatherIcon(weather.desc)}</span>
<div>
<div style={{ fontSize: 36, fontWeight: 800, color: 'var(--text-primary)', lineHeight: 1, letterSpacing: '-2px' }}>{weather.temp}°</div>
<div style={{ fontSize: 14, color: 'var(--text-secondary)', marginTop: 4, fontWeight: 500 }}>{weather.desc}</div>
</div>
</div>
{/* Forecast mini */}
{weather.forecast && weather.forecast.length > 0 && (
<div style={{ display: 'flex', gap: 8 }}>
{weather.forecast.slice(0, 3).map(day => {
const d = new Date(day.date)
const label = d.toLocaleDateString('ru-RU', { weekday: 'short' })
return (
<div key={day.date} style={{
flex: 1,
background: 'rgba(255,255,255,0.04)',
borderRadius: 14,
padding: '10px 8px',
textAlign: 'center',
border: '1px solid rgba(255,255,255,0.04)',
}}>
<div style={{ fontSize: 10, color: 'var(--text-secondary)', textTransform: 'capitalize', marginBottom: 4, fontWeight: 500 }}>{label}</div>
<div style={{ fontSize: 20, marginBottom: 4 }}>{getWeatherIcon(day.desc)}</div>
<div style={{ fontSize: 13, fontWeight: 700, color: 'var(--text-primary)' }}>{day.maxTemp}°</div>
<div style={{ fontSize: 11, color: 'var(--text-secondary)' }}>{day.minTemp}°</div>
</div>
)
})}
</div>
)}
</div>
)}
{/* Sensors Card */}
{sensors && (
<div style={{
background: 'rgba(255,255,255,0.03)',
backdropFilter: 'blur(20px)',
border: '1px solid rgba(255,255,255,0.06)',
borderRadius: 22,
padding: '22px 24px',
}}>
<div style={{ fontSize: 11, color: 'var(--text-secondary)', textTransform: 'uppercase', letterSpacing: '0.1em', fontWeight: 600, marginBottom: 16 }}>
Климат в квартире
</div>
<div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
{/* Temperature */}
<div style={{ display: 'flex', alignItems: 'center', gap: 14 }}>
<div style={{
width: 48, height: 48, borderRadius: 16,
background: 'linear-gradient(135deg, rgba(251,146,60,0.15), rgba(245,158,11,0.08))',
display: 'flex', alignItems: 'center', justifyContent: 'center',
}}>
<Thermometer size={22} color="#fb923c" />
</div>
<div>
<div style={{ fontSize: 24, fontWeight: 700, color: 'var(--text-primary)', lineHeight: 1 }}>{sensors.temperature}°C</div>
<div style={{ fontSize: 12, color: 'var(--text-secondary)', marginTop: 2 }}>Температура</div>
</div>
</div>
{/* Humidity */}
<div style={{ display: 'flex', alignItems: 'center', gap: 14 }}>
<div style={{
width: 48, height: 48, borderRadius: 16,
background: 'linear-gradient(135deg, rgba(59,130,246,0.15), rgba(99,102,241,0.08))',
display: 'flex', alignItems: 'center', justifyContent: 'center',
}}>
<Droplets size={22} color="#3b82f6" />
</div>
<div>
<div style={{ fontSize: 24, fontWeight: 700, color: 'var(--text-primary)', lineHeight: 1 }}>{sensors.humidity}%</div>
<div style={{ fontSize: 12, color: 'var(--text-secondary)', marginTop: 2 }}>Влажность</div>
</div>
</div>
{/* PM2.5 */}
<div style={{ display: 'flex', alignItems: 'center', gap: 14 }}>
<div style={{
width: 48, height: 48, borderRadius: 16,
background: pm25Info?.bg || 'rgba(255,255,255,0.05)',
display: 'flex', alignItems: 'center', justifyContent: 'center',
}}>
<Wind size={22} color={pm25Info?.color || '#999'} />
</div>
<div style={{ flex: 1 }}>
<div style={{ display: 'flex', alignItems: 'baseline', gap: 8 }}>
<span style={{ fontSize: 24, fontWeight: 700, color: 'var(--text-primary)', lineHeight: 1 }}>{sensors.pm25}</span>
<span style={{ fontSize: 12, color: 'var(--text-secondary)' }}>µg/m³</span>
</div>
<div style={{ fontSize: 12, color: pm25Info?.color, marginTop: 2, fontWeight: 500 }}>PM2.5 · {pm25Info?.label}</div>
</div>
</div>
</div>
</div>
)}
</div>
{/* Today Events */}
<div style={{
background: 'var(--card-bg)',
border: '1px solid var(--card-border)',
borderRadius: 20,
padding: '18px 20px',
background: 'rgba(255,255,255,0.03)',
backdropFilter: 'blur(20px)',
border: '1px solid rgba(255,255,255,0.06)',
borderRadius: 22,
padding: '22px 24px',
}}>
<div style={{ fontSize: 12, color: 'var(--text-secondary)', textTransform: 'uppercase', letterSpacing: '0.08em', fontWeight: 600, marginBottom: 14 }}>
📅 Сегодня
<div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 16 }}>
<Calendar size={15} color="var(--text-secondary)" />
<span style={{ fontSize: 11, color: 'var(--text-secondary)', textTransform: 'uppercase', letterSpacing: '0.1em', fontWeight: 600 }}>
Сегодня
</span>
</div>
{calLoading ? (
<div style={{ fontSize: 14, color: 'var(--text-secondary)' }}>Загрузка...</div>
) : todayEvents.length === 0 ? (
<div style={{ fontSize: 15, color: 'var(--text-secondary)', textAlign: 'center', padding: '8px 0' }}>
Свободный день 🎉
<div style={{ fontSize: 15, color: 'var(--text-secondary)', textAlign: 'center', padding: '12px 0' }}>
Нет событий на сегодня
</div>
) : (
<div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
{todayEvents.map(ev => (
<div key={ev.id} style={{ display: 'flex', alignItems: 'flex-start', gap: 10 }}>
<div style={{ width: 3, borderRadius: 2, background: ev.color, alignSelf: 'stretch', minHeight: 32, flexShrink: 0 }} />
<div key={ev.id} style={{
display: 'flex',
alignItems: 'center',
gap: 14,
padding: '12px 16px',
borderRadius: 14,
background: `${ev.color}0a`,
border: `1px solid ${ev.color}18`,
}}>
<div style={{
width: 4, borderRadius: 2,
background: ev.color,
alignSelf: 'stretch', minHeight: 36, flexShrink: 0,
}} />
<div style={{ flex: 1, minWidth: 0 }}>
<div style={{ fontSize: 14, fontWeight: 600, color: 'var(--text-primary)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
{ev.title}
</div>
<div style={{ fontSize: 12, color: 'var(--text-secondary)', marginTop: 2, display: 'flex', gap: 6 }}>
<div style={{ fontSize: 12, color: 'var(--text-secondary)', marginTop: 3, display: 'flex', gap: 8 }}>
<span>{ev.allDay ? 'Весь день' : `${formatEventTime(ev.start)}${formatEventTime(ev.end)}`}</span>
<span style={{ color: ev.color }}>{ev.ownerName}</span>
<span style={{ color: ev.color, fontWeight: 500 }}>{ev.ownerName}</span>
</div>
</div>
</div>
@@ -170,90 +288,6 @@ function HomeTab({ weather, sensors }: { weather: WeatherData | null; sensors: S
</div>
)}
</div>
{/* Weather Widget */}
{weather && (
<div style={{
background: 'var(--card-bg)',
border: '1px solid var(--card-border)',
borderRadius: 20,
padding: '18px 20px',
}}>
<div style={{ fontSize: 12, color: 'var(--text-secondary)', textTransform: 'uppercase', letterSpacing: '0.08em', fontWeight: 600, marginBottom: 14 }}>
🌤 Погода
</div>
{/* Current */}
<div style={{ display: 'flex', alignItems: 'center', gap: 14, marginBottom: 16 }}>
<span style={{ fontSize: 44 }}>{getWeatherEmoji(weather.desc)}</span>
<div>
<div style={{ fontSize: 32, fontWeight: 700, color: 'var(--text-primary)', lineHeight: 1 }}>{weather.temp}°C</div>
<div style={{ fontSize: 14, color: 'var(--text-secondary)', marginTop: 4 }}>{weather.desc}</div>
<div style={{ fontSize: 12, color: 'var(--text-secondary)', marginTop: 2 }}>
💧 {weather.humidity}% · 💨 {weather.windSpeed} км/ч · Ощущается {weather.feelsLike}°
</div>
</div>
</div>
{/* Forecast */}
{weather.forecast && weather.forecast.length > 0 && (
<div style={{ display: 'flex', gap: 8 }}>
{weather.forecast.slice(0, 3).map(day => {
const d = new Date(day.date)
const label = d.toLocaleDateString('ru-RU', { weekday: 'short' })
return (
<div key={day.date} style={{
flex: 1,
background: 'rgba(255,255,255,0.04)',
borderRadius: 12,
padding: '10px 8px',
textAlign: 'center',
border: '1px solid rgba(255,255,255,0.06)',
}}>
<div style={{ fontSize: 11, color: 'var(--text-secondary)', textTransform: 'capitalize', marginBottom: 4 }}>{label}</div>
<div style={{ fontSize: 20, marginBottom: 4 }}>{getWeatherEmoji(day.desc)}</div>
<div style={{ fontSize: 12, fontWeight: 600, color: 'var(--text-primary)' }}>{day.maxTemp}°</div>
<div style={{ fontSize: 11, color: 'var(--text-secondary)' }}>{day.minTemp}°</div>
</div>
)
})}
</div>
)}
</div>
)}
{/* Sensors Widget */}
{sensors && (
<div style={{
background: 'var(--card-bg)',
border: '1px solid var(--card-border)',
borderRadius: 20,
padding: '18px 20px',
}}>
<div style={{ fontSize: 12, color: 'var(--text-secondary)', textTransform: 'uppercase', letterSpacing: '0.08em', fontWeight: 600, marginBottom: 14 }}>
📊 Датчики квартиры
</div>
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 10 }}>
{[
{ label: 'Температура', value: `${sensors.temperature}°C`, icon: '🌡️' },
{ label: 'Влажность', value: `${sensors.humidity}%`, icon: '💧' },
{ label: 'PM2.5', value: `${sensors.pm25} μg`, icon: '💨' },
].map(s => (
<div key={s.label} style={{
background: 'rgba(255,255,255,0.04)',
border: '1px solid rgba(255,255,255,0.06)',
borderRadius: 14,
padding: '12px 10px',
textAlign: 'center',
}}>
<div style={{ fontSize: 24, marginBottom: 6 }}>{s.icon}</div>
<div style={{ fontSize: 18, fontWeight: 700, color: 'var(--text-primary)' }}>{s.value}</div>
<div style={{ fontSize: 11, color: 'var(--text-secondary)', marginTop: 2 }}>{s.label}</div>
</div>
))}
</div>
</div>
)}
</div>
)
}
@@ -301,9 +335,7 @@ export default function HomePage() {
}
const getDeviceExtra = (id: string): string | undefined => {
if (id === 'air_purifier' && sensors) {
return `PM2.5: ${sensors.pm25}`
}
if (id === 'air_purifier' && sensors) return `PM2.5: ${sensors.pm25}`
return undefined
}
@@ -314,7 +346,11 @@ export default function HomePage() {
width: '100%',
background: 'var(--bg)',
overflow: 'hidden',
position: 'relative',
}}>
{/* Ambient background */}
<div className="bg-ambient" />
<Sidebar active={tab} onChange={setTab} />
<main style={{
@@ -323,6 +359,8 @@ export default function HomePage() {
flexDirection: 'column',
overflow: 'hidden',
minWidth: 0,
position: 'relative',
zIndex: 1,
}}>
<TopBar weather={weather} sensors={sensors} />
@@ -335,7 +373,7 @@ export default function HomePage() {
flex: 1,
overflowY: 'auto',
WebkitOverflowScrolling: 'touch' as any,
padding: '16px 20px 24px',
padding: '16px 24px 28px',
}}>
{devicesInRoom.length === 0 ? (
<div style={{
@@ -343,15 +381,20 @@ export default function HomePage() {
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
height: 200,
height: 220,
color: 'var(--text-secondary)',
gap: 8,
gap: 12,
}}>
<span style={{ fontSize: 40 }}>🏠</span>
<span style={{ fontSize: 15 }}>Устройства не добавлены</span>
<div style={{
width: 64, height: 64, borderRadius: 20,
background: 'rgba(255,255,255,0.04)',
display: 'flex', alignItems: 'center', justifyContent: 'center',
fontSize: 28,
}}>🏠</div>
<span style={{ fontSize: 15, fontWeight: 500 }}>Устройства не добавлены</span>
</div>
) : (
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(2, 1fr)', gap: 12 }}>
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 14 }}>
{devicesInRoom.map(device => (
<DeviceCard
key={device.id}
@@ -380,11 +423,18 @@ export default function HomePage() {
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
gap: 12,
gap: 16,
color: 'var(--text-secondary)',
}}>
<span style={{ fontSize: 48 }}></span>
<span style={{ fontSize: 16 }}>Настройки</span>
<div style={{
width: 72, height: 72, borderRadius: 22,
background: 'linear-gradient(135deg, rgba(99,102,241,0.12), rgba(139,92,246,0.08))',
border: '1px solid rgba(129,140,248,0.15)',
display: 'flex', alignItems: 'center', justifyContent: 'center',
}}>
<SettingsIcon size={32} color="#818cf8" />
</div>
<span style={{ fontSize: 18, fontWeight: 600 }}>Настройки</span>
<span style={{ fontSize: 13 }}>Скоро</span>
</div>
)}