Changelog System Implementation
Implemented a complete changelog system following the dark-matter pattern with three view modes (Timeline, Cards, Releases), syntax-highlighted code blocks, Mermaid diagram support, and full emblem theme integration.
Changelog - 2026-01-19 (#2)
Changelog System Implementation
Overview
Implemented a full-featured changelog system for banner-site following the dark-matter pattern. The system supports three view modes, markdown rendering with syntax highlighting, Mermaid diagrams, and is fully integrated with the emblem theme.
Architecture
Content Collection Structure
src/
├── content.config.ts # Central collections registry
└── content/
└── changelog/
└── changelog.config.ts # Schema definition
changelog/ # Project root (outside src/)
└── YYYY-MM-DD_NN.md # Changelog entriesChangelog Schema
z.object({
title: z.string(),
date: z.coerce.date(),
authors: z.array(z.string()).optional(),
augmented_with: z.string().optional(),
category: z.enum([
'Feature', 'Component', 'Refactor', 'Fix',
'Documentation', 'Infrastructure', 'Design-System', 'Milestone',
]).optional(),
tags: z.array(z.string()).optional(),
summary: z.string().optional(),
files_added: z.array(z.string()).optional(),
files_modified: z.array(z.string()).optional(),
}).passthrough();View Modes
1. Timeline View (Default)
Linear/Stripe-inspired timeline with:
Grouped entries by month/year
Sticky month headers
Vertical line with animated dots
Category badges with theme-appropriate colors
Author attribution and Claude AI badge
2. Cards View
Notion/Tailwind UI-inspired card grid with:
Category filters (clickable pills)
Gradient headers per category
"New" badges for recent entries
Truncated summaries with "Read more"
Responsive 1/2/3 column grid
3. Releases View
GitHub releases-inspired layout with:
Version tags (auto-generated from date)
"Latest" badge for most recent
Collapsible release notes
Preview extracted from Overview section
Only shows entries from
releases/folder
Key Components
ContentEnhancer.astro
Wraps markdown content and enhances:
Code Blocks:
Adds header with language label
Copy-to-clipboard button
Syntax highlighting via Shiki (tokyo-night dark, github-light)
Scrollable with max-height
Mermaid Diagrams:
Detects
```mermaidblocksLoads Mermaid from CDN on-demand
Custom theme variables matching emblem colors:
primaryColor:
#B91C1C(crimson)lineColor:
#DC2626(crimson-bright)background:
#141531(haiti-blue)
ChangelogViewToggler.astro
Three toggle buttons with icons
Share button copies URL with
?view=paramLocalStorage not needed (URL-based state)
Smooth transitions between views
ClaudeTrademark.astro
Auto-switches between light/dark mode variants
Uses images from
/public/trademarks/Displays next to AI-augmented entries
Theme Integration
All colors adapted from dark-matter's violet to emblem's crimson/navy:
| Element | Dark-Matter | Emblem |
| Primary accent | #8b5cf6 (violet) | var(--color-primary) (crimson) |
| Timeline dot | violet gradient | crimson gradient |
| Links hover | #a78bfa | var(--color-primary) |
| Code inline | violet tint | crimson tint |
| Blockquote border | violet | crimson |
| Active filter | violet | crimson |
Uses color-mix() for consistent opacity variations:
background: color-mix(in srgb, var(--color-primary) 10%, transparent);
border-color: color-mix(in srgb, var(--color-primary) 30%, transparent);Dependencies Added
{
"@shikijs/rehype": "^3.6.0",
"rehype-stringify": "^10.0.0",
"remark-gfm": "^4.0.0",
"remark-parse": "^11.0.0",
"remark-rehype": "^11.1.0",
"unified": "^11.0.4",
"unist-util-visit": "^5.0.0"
}Path Aliases
Added to tsconfig.json:
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@components/*": ["src/components/*"],
"@layouts/*": ["src/layouts/*"],
"@styles/*": ["src/styles/*"],
"@utils/*": ["src/utils/*"],
"@content/*": ["src/content/*"]
}
}
}Usage
Creating a Changelog Entry
---
title: "My Feature"
date: 2026-01-20
authors:
- Your Name
category: Feature
tags:
- Tag1
- Tag2
summary: "Brief description for cards view"
---
# Changelog - 2026-01-20 (#1)
## My Feature
Content here with **markdown** support...File Naming Convention
changelog/YYYY-MM-DD_NN.mdYYYY-MM-DD- Date of the entryNN- Sequential number for same-day entries (01, 02, 03...)
Accessing the Changelog
/changelog- Main page with view toggle/changelog?view=cards- Direct link to cards view/changelog?view=releases- Direct link to releases view/changelog/2026-01-19_01- Individual entry page
Technical Notes
Static Generation
The [id].astro page uses getStaticPaths() to pre-render all changelog entries:
export async function getStaticPaths() {
const entries = await getCollection('changelog');
return entries.map((entry) => ({
params: { id: entry.id },
props: { entry },
}));
}Mermaid Pre-processing
Custom rehype plugin extracts mermaid blocks before Shiki processes them:
function rehypeMermaidPre() {
return (tree: any) => {
visit(tree, 'element', (node: any) => {
// Convert <pre><code class="language-mermaid">
// to <pre class="mermaid"> before Shiki runs
});
};
}Sorting Logic
Entries sorted by:
Date descending (newest first)
Same date: ID descending (
_04before_01)
Future Enhancements
RSS feed generation
Search/filter by tag
Pagination for large changelogs
Related entries linking
Export to PDF
