feat: светлая тема как основная + переключатель тем
- CSS-переменные --bg, --surface, --ink, --mute, --accent для обеих тем - darkMode: 'class' в Tailwind config - ThemeToggle компонент с Sun/Moon, сохраняет выбор в localStorage - Inline-скрипт в layout.js защищает от FOUC (FlashOfUnstyledContent) - Авто-определение по prefers-color-scheme как fallback - not-found.js: красивая 404 страница вместо дефолтной Next - Обновлены все компоненты и страницы — Header, Footer, ArticleCard, page.js, blog, tag, about
This commit is contained in:
+81
-7
@@ -2,18 +2,92 @@
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
/* === Theme tokens === */
|
||||
:root {
|
||||
--bg: 250 250 249; /* почти белый, тёплый */
|
||||
--surface: 255 255 255; /* карточки */
|
||||
--surface-2: 245 245 244; /* приглушённый фон */
|
||||
--border: 231 229 228;
|
||||
--ink: 28 25 23; /* основной текст */
|
||||
--mute: 120 113 108; /* приглушённый текст */
|
||||
--accent: 16 185 129; /* emerald-500 */
|
||||
--accent-2: 5 150 105; /* emerald-600 */
|
||||
--accent-soft: 209 250 229; /* emerald-100 */
|
||||
}
|
||||
|
||||
.dark {
|
||||
--bg: 10 10 10;
|
||||
--surface: 20 20 20;
|
||||
--surface-2: 28 28 28;
|
||||
--border: 42 42 42;
|
||||
--ink: 229 231 235;
|
||||
--mute: 156 163 175;
|
||||
--accent: 16 185 129;
|
||||
--accent-2: 52 211 153;
|
||||
--accent-soft: 6 78 59;
|
||||
}
|
||||
|
||||
@layer base {
|
||||
html { @apply bg-bg text-ink; }
|
||||
html {
|
||||
background: rgb(var(--bg));
|
||||
color: rgb(var(--ink));
|
||||
}
|
||||
body { @apply font-sans antialiased; }
|
||||
::selection { @apply bg-accent/30; }
|
||||
::selection { background: rgb(var(--accent) / 0.25); }
|
||||
}
|
||||
|
||||
@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-mute hover:bg-surface hover:text-white; }
|
||||
.btn {
|
||||
@apply inline-flex items-center justify-center gap-2 px-4 py-2 rounded-lg font-medium transition-all disabled:opacity-50 disabled:cursor-not-allowed;
|
||||
}
|
||||
.btn-primary {
|
||||
background: rgb(var(--accent));
|
||||
color: white;
|
||||
}
|
||||
.btn-primary:hover { background: rgb(var(--accent-2)); }
|
||||
|
||||
.btn-ghost {
|
||||
color: rgb(var(--mute));
|
||||
}
|
||||
.btn-ghost:hover {
|
||||
background: rgb(var(--surface-2));
|
||||
color: rgb(var(--ink));
|
||||
}
|
||||
|
||||
.container-narrow { @apply max-w-3xl mx-auto px-4; }
|
||||
.container-wide { @apply max-w-6xl mx-auto px-4; }
|
||||
.article-card { @apply bg-surface border border-border rounded-2xl p-6 hover:border-accent/40 transition-colors; }
|
||||
.tag { @apply inline-block text-xs px-2.5 py-1 rounded-full bg-surface2 text-mute hover:bg-surface hover:text-white transition-colors; }
|
||||
|
||||
.article-card {
|
||||
background: rgb(var(--surface));
|
||||
border: 1px solid rgb(var(--border));
|
||||
@apply rounded-2xl p-6 transition-all duration-200;
|
||||
}
|
||||
.article-card:hover {
|
||||
border-color: rgb(var(--accent) / 0.4);
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 10px 25px -10px rgb(0 0 0 / 0.08);
|
||||
}
|
||||
.dark .article-card:hover {
|
||||
box-shadow: 0 10px 25px -10px rgb(0 0 0 / 0.5);
|
||||
}
|
||||
|
||||
.tag {
|
||||
display: inline-block;
|
||||
@apply text-xs px-2.5 py-1 rounded-full transition-colors;
|
||||
background: rgb(var(--surface-2));
|
||||
color: rgb(var(--mute));
|
||||
}
|
||||
.tag:hover {
|
||||
background: rgb(var(--accent-soft));
|
||||
color: rgb(var(--accent-2));
|
||||
}
|
||||
|
||||
.surface { background: rgb(var(--surface)); }
|
||||
.surface-2 { background: rgb(var(--surface-2)); }
|
||||
.ink { color: rgb(var(--ink)); }
|
||||
.mute { color: rgb(var(--mute)); }
|
||||
.accent { color: rgb(var(--accent)); }
|
||||
.border-soft { border-color: rgb(var(--border)); }
|
||||
.border-b-soft { border-bottom: 1px solid rgb(var(--border)); }
|
||||
.border-t-soft { border-top: 1px solid rgb(var(--border)); }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user