Changelog UI with Three Design Variants
State-of-the-art changelog UI with timeline, card grid, and GitHub releases variants plus structured frontmatter schema.
Changelog - 2025-12-18 (#4)
Dark Matter Site: Changelog UI with Three Design Variants
Overview
Created a comprehensive changelog UI system with three distinct design approaches, allowing stakeholders to compare styles and choose the best fit. Each variant offers a unique way to browse development history.
Key deliverables:
Timeline Variant (
/changelog): Linear/Stripe-inspired vertical timeline with month groupingsCard Grid Variant (
/changelog/variant-1): Notion/Tailwind UI-inspired filterable card layoutReleases Variant (
/changelog/variant-3): GitHub releases-style collapsible sections with version tagsIndividual Entry Pages (
/changelog/[id]): Full markdown rendering with prose stylingFrontmatter Schema: Structured YAML metadata for all changelog entries
Changes by Area
1. Timeline Variant (src/pages/changelog/index.astro)
Linear/Stripe-inspired design with vertical timeline:
Features:
Month-grouped entries with sticky headers
Vertical timeline line with animated entry dots
Category badges with distinct color coding
Tags, author attribution, and AI badges
Smooth hover states on timeline dots
Visual Design:
Purple gradient header with "Development Timeline" badge
Entry dots that glow and scale on hover
Month dots with box-shadow glow effect
Subtle background gradients
2. Card Grid Variant (src/pages/changelog/variant-1.astro)
Notion/Tailwind UI-inspired card layout:
Features:
Category filter buttons with emoji icons
Colorful gradient headers per category
"New" badges on recent entries (first 3)
Hover lift animation with shadow
Tag cloud with overflow count
Category Gradients:
Feature: Emerald → Teal
Component: Violet → Purple
Refactor: Amber → Orange
Fix: Rose → Pink
Documentation: Sky → Blue
Infrastructure: Slate → Gray
Design-System: Fuchsia → Pink
Interactive Filtering:
// JavaScript filter functionality
filterBtns.forEach(btn => {
btn.addEventListener('click', () => {
const category = btn.dataset.category;
cards.forEach(card => {
if (category === 'all' || card.dataset.category === category) {
card.style.display = '';
} else {
card.style.display = 'none';
}
});
});
});3. Releases Variant (src/pages/changelog/variant-3.astro)
GitHub releases-inspired design:
Features:
Auto-generated version tags (v2025.12.18.3 format)
"Latest" badge on newest release
Collapsible
<details>sectionsMarkdown preview extraction
Category labels matching GitHub's style
Version Tag Generation:
function getVersionTag(entry, index) {
const date = new Date(entry.data.date);
const dateStr = date.toISOString().split('T')[0].replace(/-/g, '.');
return `v${dateStr}.${sortedEntries.length - index}`;
}Preview Extraction:
Finds content after "### Overview" heading
Extracts first 5 non-empty lines
Renders as markdown HTML
4. Individual Entry Page (src/pages/changelog/[id].astro)
Full markdown rendering for single entries:
Features:
Breadcrumb navigation
Full header with title, date, category, summary
Author and AI attribution
Tags display
Complete prose styling for markdown content
Back to changelog link
SSR Handling:
Since the site uses output: 'server', the page fetches entries dynamically:
const { id } = Astro.params;
const allEntries = await getCollection('changelog');
const entry = allEntries.find((e) => {
const entryId = e.id.replace(/\.md$/, '');
return entryId === id || e.id === id;
});5. Changelog Schema (src/content/changelog/changelog.config.ts)
Updated Zod schema for structured frontmatter:
export const changelogSchema = z.object({
// Required fields
title: z.string(),
date: z.coerce.date(),
// Optional metadata
authors: z.array(z.string()).optional(),
augmented_with: z.string().optional(),
category: z.enum([
'Feature', 'Component', 'Refactor', 'Fix',
'Documentation', 'Infrastructure', 'Design-System',
]).optional(),
tags: z.array(z.string()).optional(),
// Summary fields
summary: z.string().optional(),
why_care: z.string().optional(),
// Files changed
files_added: z.array(z.string()).optional(),
files_modified: z.array(z.string()).optional(),
}).passthrough();6. Frontmatter Migration
Added structured frontmatter to all 8 existing changelog files:
| File | Category | Tags |
| 2025-12-04_01 | Infrastructure | Theming, Layout, Mode-Toggle |
| 2025-12-04_02 | Feature | Hero-Section, Three.js, WebGL |
| 2025-12-04_03 | Fix | CSS-Scoping, Astro |
| 2025-12-09_01 | Feature | Team-Page, Social-Icons |
| 2025-12-13_01 | Feature | GitHub-API, Memo-System |
| 2025-12-18_01 | Feature | Narrative-Sections, Zod |
| 2025-12-18_02 | Component | Team-Cards, Design-System |
| 2025-12-18_03 | Component | Deal-Cards, Pipeline |
Files Changed Summary
New
Pages:
src/pages/changelog/index.astro— Timeline variantsrc/pages/changelog/variant-1.astro— Card grid variantsrc/pages/changelog/variant-3.astro— GitHub releases variantsrc/pages/changelog/[id].astro— Individual entry page
Modified
src/content/changelog/changelog.config.ts— Added Zod schemachangelog/*.md(8 files) — Added YAML frontmatter
Technical Details
Variant Switcher
All three variants include a consistent header with tabs for switching:
<div class="flex gap-2">
<a href="/changelog" class="variant-tab active">Timeline</a>
<a href="/changelog/variant-1" class="variant-tab">Cards</a>
<a href="/changelog/variant-3" class="variant-tab">Releases</a>
</div>Category Color System
Consistent color mapping across all variants:
| Category | Color | Use Case |
| Feature | Emerald | New functionality |
| Component | Violet | UI components |
| Refactor | Amber | Code improvements |
| Fix | Rose | Bug fixes |
| Documentation | Sky | Docs updates |
| Infrastructure | Slate | Build/config |
| Design-System | Fuchsia | Design tokens/patterns |
Dark/Light Mode Support
All components use :global([data-mode="..."]) selectors:
/* Dark mode (default) */
.entry-link:hover { color: #a78bfa; }
/* Light mode */
:global([data-mode="light"]) .entry-link:hover { color: #6c63ff; }Markdown Processing
Uses unified/remark/rehype pipeline:
const processor = unified()
.use(remarkParse)
.use(remarkGfm)
.use(remarkRehype, { allowDangerousHtml: true })
.use(rehypeStringify, { allowDangerousHtml: true });Notes / Follow-Ups
Syntax Highlighting: Currently using basic
<pre><code>styling. Could add Shiki or Prism for language-aware highlighting.Mermaid Diagrams: Schema mentions potential mermaid support. Would require
rehype-mermaidor client-side rendering.Search: Could add full-text search across changelog entries using Pagefind or similar.
RSS Feed: Could generate
/changelog/feed.xmlfor subscribers.Pagination: Currently loads all entries. For larger changelogs, consider pagination or infinite scroll.
Access URLs:
Timeline:
/changelogCards:
/changelog/variant-1Releases:
/changelog/variant-3Entry:
/changelog/2025-12-18_04