feat: мобильная версия + поиск + SEO-инфраструктура
Мобилка: - Header: hide-on-scroll, мобильный burger-menu, тонкая адаптация - Hero: текст и кнопки оптимизированы под узкие экраны (full-width buttons) - ArticleCard featured: на мобилке в столбик, картинка сверху - Stats: компактная сетка 2x2 с уменьшенным шрифтом - Глобально: scroll-behavior smooth, safe-area-inset, tap targets 40px+ - prefers-reduced-motion respected Страница статьи: - ReadingProgress: прогресс-бар сверху при скролле - ScrollToTop: круглая кнопка наверху после 800px скролла - ShareButton: Web Share API на мобилках, копирование URL на десктопе - Related articles: подбираем по пересечению тегов (max 3) - Мобильная типографика: prose-base sm:prose-lg, leading-relaxed SEO/инфра: - /api/search: простой поиск по title/excerpt/tags с подсветкой и скорингом - SearchBox: оверлей с / хоткеем, дебаунс 250ms, мобиле-friendly - /rss.xml: полноценный RSS-фид - sitemap.xml: динамический через next sitemap() - robots.txt: динамический - viewport metadata + theme-color для светлой/тёмной темы - alternates rel=alternate type=application/rss+xml
This commit is contained in:
+47
-21
@@ -4,15 +4,15 @@
|
||||
|
||||
/* === Theme tokens === */
|
||||
:root {
|
||||
--bg: 250 250 249; /* почти белый, тёплый */
|
||||
--surface: 255 255 255; /* карточки */
|
||||
--surface-2: 245 245 244; /* приглушённый фон */
|
||||
--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 */
|
||||
--ink: 28 25 23;
|
||||
--mute: 120 113 108;
|
||||
--accent: 16 185 129;
|
||||
--accent-2: 5 150 105;
|
||||
--accent-soft: 209 250 229;
|
||||
}
|
||||
|
||||
.dark {
|
||||
@@ -31,28 +31,39 @@
|
||||
html {
|
||||
background: rgb(var(--bg));
|
||||
color: rgb(var(--ink));
|
||||
scroll-behavior: smooth;
|
||||
/* лучше для мобильных WebKit */
|
||||
-webkit-text-size-adjust: 100%;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
}
|
||||
body {
|
||||
@apply font-sans antialiased;
|
||||
/* safe areas на iOS */
|
||||
padding-left: env(safe-area-inset-left);
|
||||
padding-right: env(safe-area-inset-right);
|
||||
}
|
||||
body { @apply font-sans antialiased; }
|
||||
::selection { background: rgb(var(--accent) / 0.25); }
|
||||
|
||||
/* tap target минимум 44px для кнопок и ссылок в навигации/действиях */
|
||||
button, a.btn {
|
||||
min-height: 40px;
|
||||
}
|
||||
|
||||
/* плавный скролл к якорям с учётом sticky header */
|
||||
:where(h1, h2, h3, h4, [id]) {
|
||||
scroll-margin-top: 80px;
|
||||
}
|
||||
}
|
||||
|
||||
@layer components {
|
||||
.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 { 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));
|
||||
}
|
||||
.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; }
|
||||
@@ -70,10 +81,15 @@
|
||||
.dark .article-card:hover {
|
||||
box-shadow: 0 10px 25px -10px rgb(0 0 0 / 0.5);
|
||||
}
|
||||
/* на мобилке hover-эффект transform не нужен (тач) */
|
||||
@media (hover: none) {
|
||||
.article-card:hover { transform: none; box-shadow: none; }
|
||||
.article-card:active { transform: scale(0.99); }
|
||||
}
|
||||
|
||||
.tag {
|
||||
display: inline-block;
|
||||
@apply text-xs px-2.5 py-1 rounded-full transition-colors;
|
||||
@apply text-xs px-2.5 py-1 rounded-full transition-colors whitespace-nowrap;
|
||||
background: rgb(var(--surface-2));
|
||||
color: rgb(var(--mute));
|
||||
}
|
||||
@@ -91,3 +107,13 @@
|
||||
.border-b-soft { border-bottom: 1px solid rgb(var(--border)); }
|
||||
.border-t-soft { border-top: 1px solid rgb(var(--border)); }
|
||||
}
|
||||
|
||||
/* Уважаем системную настройку "меньше анимаций" */
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
html { scroll-behavior: auto; }
|
||||
*, *::before, *::after {
|
||||
animation-duration: 0.01ms !important;
|
||||
animation-iteration-count: 1 !important;
|
||||
transition-duration: 0.01ms !important;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user