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 entries
Changelog 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
```mermaidblocks - Loads Mermaid from CDN on-demand
- Custom theme variables matching emblem colors:
- primaryColor:
#B91C1C(crimson) - lineColor:
#DC2626(crimson-bright) - background:
#141531(haiti-blue)
- primaryColor:
ChangelogViewToggler.astro
- Three toggle buttons with icons
- Share button copies URL with
?view=param - LocalStorage 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.md
YYYY-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