diff --git a/app/globals.css b/app/globals.css index 9db0b9f..f1953fa 100644 --- a/app/globals.css +++ b/app/globals.css @@ -2,19 +2,62 @@ @tailwind components; @tailwind utilities; +/* ── Светлая тема (по умолчанию) ──────────────────────────────────────────── */ +:root { + --bg: 250 250 249; /* stone-50 — мягкий тёплый фон */ + --surface: 255 255 255; /* белые карточки */ + --surface2: 245 245 244; /* stone-100 — инпуты */ + --border: 231 229 228; /* stone-200 */ + --text: 23 23 23; /* neutral-900 */ + --text-soft: 82 82 91; /* zinc-600 */ + --text-mute: 161 161 170; /* zinc-400 */ + --accent: 16 185 129; /* emerald-500 */ + --accent2: 5 150 105; /* emerald-600 */ + --accent-text: 255 255 255; /* белый текст на акценте */ +} + +/* ── Тёмная тема ──────────────────────────────────────────────────────────── */ +:root[data-theme='dark'] { + --bg: 10 10 10; + --surface: 20 20 20; + --surface2: 28 28 28; + --border: 42 42 42; + --text: 243 244 246; /* gray-100 */ + --text-soft: 209 213 219; /* gray-300 */ + --text-mute: 107 114 128; /* gray-500 */ + --accent: 16 185 129; + --accent2: 52 211 153; + --accent-text: 0 0 0; +} + @layer base { - html { @apply bg-bg text-gray-100; } + html { @apply bg-bg text-text; } body { @apply font-sans antialiased; } - ::selection { @apply bg-accent/30; } + ::selection { background: rgb(var(--accent) / 0.3); } } @layer components { .btn { @apply inline-flex items-center justify-center gap-2 px-4 py-2 rounded-lg font-medium transition-colors disabled:opacity-50 disabled:cursor-not-allowed; } - .btn-primary { @apply btn bg-accent text-black hover:bg-accent2; } - .btn-ghost { @apply btn text-gray-300 hover:bg-surface2 hover:text-white; } - .btn-danger { @apply btn bg-red-600/10 text-red-400 hover:bg-red-600/20; } - .card { @apply bg-surface border border-border rounded-xl; } - .input { @apply w-full bg-surface2 border border-border rounded-lg px-3 py-2 text-gray-100 placeholder-gray-500 focus:outline-none focus:border-accent transition-colors; } - .label { @apply block text-sm font-medium text-gray-300 mb-1.5; } - .hint { @apply text-xs text-gray-500 mt-1; } + .btn-primary { @apply btn; background: rgb(var(--accent)); color: rgb(var(--accent-text)); } + .btn-primary:hover:not(:disabled) { background: rgb(var(--accent2)); } + .btn-ghost { @apply btn; color: rgb(var(--text-soft)); } + .btn-ghost:hover:not(:disabled) { background: rgb(var(--surface2)); color: rgb(var(--text)); } + .btn-danger { @apply btn; background: rgb(220 38 38 / 0.1); color: rgb(248 113 113); } + .btn-danger:hover:not(:disabled) { background: rgb(220 38 38 / 0.2); } + .card { @apply rounded-xl; background: rgb(var(--surface)); border: 1px solid rgb(var(--border)); } + .input { + @apply w-full rounded-lg px-3 py-2 focus:outline-none transition-colors; + background: rgb(var(--surface2)); + border: 1px solid rgb(var(--border)); + color: rgb(var(--text)); + } + .input::placeholder { color: rgb(var(--text-mute)); } + .input:focus { border-color: rgb(var(--accent)); } + .label { @apply block text-sm font-medium mb-1.5; color: rgb(var(--text-soft)); } + .hint { @apply text-xs mt-1; color: rgb(var(--text-mute)); } +} + +/* ── Theme switch animation ──────────────────────────────────────────────── */ +* { + transition: background-color 0.15s, border-color 0.15s, color 0.15s; } diff --git a/app/layout.js b/app/layout.js index 3d2a435..8744720 100644 --- a/app/layout.js +++ b/app/layout.js @@ -5,10 +5,24 @@ export const metadata = { description: 'Инструмент для ведения Telegram-каналов с помощью ИИ', }; +// Inline-скрипт чтобы установить тему ДО рендера и избежать вспышки +const themeInit = ` +(function() { + try { + var saved = localStorage.getItem('zp_theme'); + var theme = saved || 'light'; + document.documentElement.setAttribute('data-theme', theme); + } catch(e) { + document.documentElement.setAttribute('data-theme', 'light'); + } +})(); +`; + export default function RootLayout({ children }) { return ( - + +