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:
Alexey Pavlov
2026-05-31 09:07:44 +03:00
parent d8d1affcc8
commit a16bf812e4
12 changed files with 231 additions and 75 deletions
+7 -8
View File
@@ -30,7 +30,6 @@ export default async function ArticlePage({ params }) {
const article = await getArticle(slug);
if (!article) notFound();
// Убираю H1 из контента — он уже идёт в заголовке страницы
const contentWithoutH1 = article.content.replace(/^#\s+.+$/m, '').trim();
const html = renderMarkdown(contentWithoutH1);
@@ -38,7 +37,7 @@ export default async function ArticlePage({ params }) {
<>
<Header />
<article className="container-narrow pt-10 pb-16">
<Link href="/" className="btn-ghost text-sm mb-6 -ml-2">
<Link href="/" className="btn btn-ghost text-sm mb-6 -ml-2">
<ArrowLeft className="w-4 h-4" /> Все статьи
</Link>
@@ -48,11 +47,11 @@ export default async function ArticlePage({ params }) {
))}
</div>
<h1 className="font-serif text-3xl sm:text-5xl font-bold leading-tight mb-5 tracking-tight">
<h1 className="font-serif text-3xl sm:text-5xl font-bold leading-tight mb-5 tracking-tight ink">
{article.title}
</h1>
<div className="flex items-center gap-4 text-sm text-mute pb-8 mb-8 border-b border-border/60">
<div className="flex items-center gap-4 text-sm mute pb-8 mb-8 border-b-soft">
<span>{article.author}</span>
<span>·</span>
<span>{formatDate(article.published_at)}</span>
@@ -67,13 +66,13 @@ export default async function ArticlePage({ params }) {
</div>
<div
className="prose prose-invert prose-lg max-w-none font-serif prose-headings:font-sans"
className="prose prose-lg max-w-none font-serif prose-headings:font-sans"
dangerouslySetInnerHTML={{ __html: html }}
/>
<div className="mt-16 pt-8 border-t border-border/60 text-center">
<p className="text-mute mb-4">Хочешь такой же блог или канал в Telegram?</p>
<a href="https://app.zeropost.ru" className="btn-primary">
<div className="mt-16 pt-8 border-t-soft text-center">
<p className="mute mb-4">Хочешь такой же блог или канал в Telegram?</p>
<a href="https://app.zeropost.ru" className="btn btn-primary">
Открыть ZeroPost
</a>
</div>