feat: add blog with archives, pagination, search, sharing and RSS

- Content collection (one folder per post) with zod schema
- /blog, category and tag archives with /sayfa/<n>/ pagination
- Post page: breadcrumbs, date badges, share bar, TOC, DIY notice,
  code copy, license line, prev/next, BlogPosting + BreadcrumbList JSON-LD
- Sidebar: Pagefind search, categories, featured fallback, tag cloud
- Sätteri HAST plugins for figure/figcaption and external links
- Dual-theme Shiki, themed prose, RSS feed, latest posts on home
- Three sample posts marked as examples

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-16 01:06:07 +03:00
parent f2d943c31b
commit 809f89af08
27 changed files with 1599 additions and 27 deletions
+97
View File
@@ -120,3 +120,100 @@
scroll-behavior: auto !important;
}
}
/* ---------- Article typography (unlayered: overrides the typography plugin) ---------- */
.article-prose {
--tw-prose-body: var(--fg);
--tw-prose-headings: var(--fg);
--tw-prose-lead: var(--fg-muted);
--tw-prose-links: var(--accent-strong);
--tw-prose-bold: var(--fg);
--tw-prose-counters: var(--fg-muted);
--tw-prose-bullets: var(--accent);
--tw-prose-hr: var(--line);
--tw-prose-quotes: var(--fg);
--tw-prose-quote-borders: var(--accent);
--tw-prose-captions: var(--fg-muted);
--tw-prose-kbd: var(--fg);
--tw-prose-code: var(--fg);
--tw-prose-pre-code: var(--fg);
--tw-prose-pre-bg: var(--surface);
--tw-prose-th-borders: var(--fg);
--tw-prose-td-borders: var(--line);
}
.article-prose :where(h2, h3, h4) {
font-family: var(--font-display);
font-weight: 800;
scroll-margin-top: 2rem;
}
.article-prose :where(a) {
text-decoration-thickness: 2px;
text-underline-offset: 0.2em;
}
.article-prose :where(:not(pre) > code) {
background: var(--bg-alt);
padding: 0.1em 0.35em;
border-radius: 2px;
font-weight: 500;
}
.article-prose :where(:not(pre) > code)::before,
.article-prose :where(:not(pre) > code)::after {
content: none;
}
.article-prose :where(blockquote) {
font-style: normal;
background: var(--surface);
padding-block: 0.25em;
}
.article-prose :where(blockquote p)::before,
.article-prose :where(blockquote p)::after {
content: none;
}
.article-prose :where(figure) {
margin-inline: 0;
}
.article-prose :where(figcaption) {
border-left: 3px solid var(--accent);
padding-left: 0.75em;
}
/* Shiki dual theme (defaultColor: false) */
.astro-code {
color: var(--shiki-light);
background-color: var(--surface) !important;
border: 1px solid var(--line);
border-radius: 2px;
}
.astro-code span {
color: var(--shiki-light);
}
[data-theme='dark'] .astro-code,
[data-theme='dark'] .astro-code span {
color: var(--shiki-dark);
}
.code-block {
position: relative;
}
.code-copy {
position: absolute;
top: 0.5rem;
right: 0.5rem;
padding: 0.15rem 0.6rem;
font: 700 0.75rem/1.5 var(--font-display);
text-transform: uppercase;
letter-spacing: 0.04em;
color: var(--bg);
background: var(--fg);
border-radius: 2px;
cursor: pointer;
}
.code-copy:hover {
background: var(--accent-fill);
color: var(--on-accent-fill);
}