- Hero на главной: большой заголовок в градиенте, мистический тэглайн, мета-плашка «N миров / N публикаций / N лет онлайн» - Декоративный фон: звёздная россыпь + радиальные градиенты акцента (CSS-only, без картинок) - Карточки постов с цветовой полосой по категории + hover-эффект - Цветные теги категорий с glow-точкой - «Миры и проекты» вместо «Форумы»: 8 карточек с тэгом, названием, описанием каждой вселенной и цветовой кодировкой - Single post: буквица в первом абзаце, центрированный заголовок в градиенте, тег категории сверху - BrandMark SVG (две зеркальные арки) + липкая шапка с blur - Cormorant Garamond вместо Lora — больше серифной выразительности - CATEGORY_COLORS в consts.ts (расширяемая палитра) - Mobile-адаптация (clamp заголовки, перенос меты, уменьшенные паддинги)
84 lines
2.9 KiB
Plaintext
84 lines
2.9 KiB
Plaintext
---
|
||
import { getCollection } from 'astro:content';
|
||
import BaseLayout from '../layouts/BaseLayout.astro';
|
||
import { WORLDS, CATEGORY_COLORS, HERO_TAGLINE, SITE_FOUNDED } from '../consts';
|
||
|
||
const posts = (await getCollection('posts'))
|
||
.sort((a, b) => b.data.pubDate.valueOf() - a.data.pubDate.valueOf());
|
||
|
||
const totalPosts = posts.length;
|
||
const totalWorlds = WORLDS.length;
|
||
const oldestYear = posts.length ? posts[posts.length - 1].data.pubDate.getFullYear() : SITE_FOUNDED;
|
||
|
||
const fmtDate = (d: Date) =>
|
||
d.toLocaleDateString('ru-RU', { year: 'numeric', month: 'long', day: 'numeric' });
|
||
---
|
||
<BaseLayout>
|
||
<section class="hero">
|
||
<span class="hero-eyebrow">Ролевой проект · с {SITE_FOUNDED} года</span>
|
||
<h1>Иные<br/>Отражения</h1>
|
||
<p class="hero-tagline">{HERO_TAGLINE}</p>
|
||
<div class="hero-meta">
|
||
<span><strong>{totalWorlds}</strong> мира</span>
|
||
<span><strong>{totalPosts}</strong> публикаций</span>
|
||
<span><strong>{new Date().getFullYear() - SITE_FOUNDED}</strong> лет онлайн</span>
|
||
</div>
|
||
</section>
|
||
|
||
<section id="news">
|
||
<div class="section-head">
|
||
<h2>Хроника проекта</h2>
|
||
<span class="section-meta"><a href="/feed.xml">RSS-фид</a></span>
|
||
</div>
|
||
<ul class="post-list">
|
||
{posts.map((post) => {
|
||
const catColor = post.data.categorySlugs[0]
|
||
? CATEGORY_COLORS[post.data.categorySlugs[0]] ?? 'var(--accent)'
|
||
: 'var(--accent)';
|
||
return (
|
||
<li class="post-card" style={`--cat-color: ${catColor}`}>
|
||
<div class="post-meta">
|
||
<time datetime={post.data.pubDate.toISOString()}>{fmtDate(post.data.pubDate)}</time>
|
||
{post.data.categories.length > 0 && (
|
||
<a
|
||
href={`/category/${post.data.categorySlugs[0]}/`}
|
||
class="cat-tag"
|
||
style={`--cat-color: ${catColor}`}
|
||
>
|
||
{post.data.categories[0]}
|
||
</a>
|
||
)}
|
||
</div>
|
||
<h3><a href={`/${post.data.slug}/`}>{post.data.title}</a></h3>
|
||
{post.data.description && <p class="post-excerpt">{post.data.description}…</p>}
|
||
</li>
|
||
);
|
||
})}
|
||
</ul>
|
||
</section>
|
||
|
||
<section id="worlds" style="margin-top: 4rem;">
|
||
<div class="section-head">
|
||
<h2>Миры и проекты</h2>
|
||
<span class="section-meta">{WORLDS.length} вселенных</span>
|
||
</div>
|
||
<ul class="worlds-grid">
|
||
{WORLDS.map((w) => (
|
||
<li>
|
||
<a
|
||
class="world-card"
|
||
href={w.url}
|
||
target="_blank"
|
||
rel="noopener"
|
||
style={`--cat-color: ${w.color}`}
|
||
>
|
||
<span class="world-tag">{w.tag}</span>
|
||
<span class="world-name">{w.name}</span>
|
||
<span class="world-desc">{w.desc}</span>
|
||
</a>
|
||
</li>
|
||
))}
|
||
</ul>
|
||
</section>
|
||
</BaseLayout>
|