Post Archive v1: a first pass at a functional post-archive
This commit is contained in:
parent
1b66fc8a90
commit
960f7ff4d0
@ -1,4 +1,5 @@
|
|||||||
// Import the database connection
|
// Import the database connection
|
||||||
|
import { db } from './db';
|
||||||
export { db } from './db';
|
export { db } from './db';
|
||||||
|
|
||||||
// Export all functions related to database operations
|
// Export all functions related to database operations
|
||||||
|
|||||||
@ -1,6 +1,22 @@
|
|||||||
import { db } from './db';
|
import { db } from './db';
|
||||||
import { parseTags } from './tags';
|
import { parseTags } from './tags';
|
||||||
|
|
||||||
|
// Interface for archive data structure
|
||||||
|
export interface ArchiveMonth {
|
||||||
|
name: string;
|
||||||
|
count: string;
|
||||||
|
posts: Array<{
|
||||||
|
title: string;
|
||||||
|
href: string;
|
||||||
|
}>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ArchiveYear {
|
||||||
|
year: string;
|
||||||
|
count: string;
|
||||||
|
months: ArchiveMonth[];
|
||||||
|
}
|
||||||
|
|
||||||
// Interface for blog post
|
// Interface for blog post
|
||||||
export interface BlogPost {
|
export interface BlogPost {
|
||||||
id: number;
|
id: number;
|
||||||
@ -107,3 +123,69 @@ export function getPostsByDateRange(startDate: string, endDate: string): BlogPos
|
|||||||
|
|
||||||
return dateQuery.all(startDate, endDate) as BlogPost[];
|
return dateQuery.all(startDate, endDate) as BlogPost[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Function to get posts organized by year and month for the archive
|
||||||
|
export function getPostsByYearAndMonth(): ArchiveYear[] {
|
||||||
|
const query = db.query(`
|
||||||
|
SELECT * FROM posts
|
||||||
|
WHERE path NOT LIKE '%.md'
|
||||||
|
ORDER BY date DESC
|
||||||
|
`);
|
||||||
|
|
||||||
|
const posts = query.all() as any[];
|
||||||
|
|
||||||
|
// Group posts by year and month
|
||||||
|
const yearMap = new Map<string, ArchiveYear>();
|
||||||
|
|
||||||
|
const monthNames = [
|
||||||
|
"January", "February", "March", "April", "May", "June",
|
||||||
|
"July", "August", "September", "October", "November", "December"
|
||||||
|
];
|
||||||
|
|
||||||
|
// Process each post
|
||||||
|
posts.forEach(post => {
|
||||||
|
const date = new Date(post.date);
|
||||||
|
const year = String(date.getFullYear());
|
||||||
|
const monthName = monthNames[date.getMonth()];
|
||||||
|
|
||||||
|
// Create clean post href from path
|
||||||
|
const href = post.path.replace(/^.*\/content\//, '/').replace(/\.md$/, '');
|
||||||
|
|
||||||
|
// Initialize year if it doesn't exist
|
||||||
|
if (!yearMap.has(year)) {
|
||||||
|
yearMap.set(year, {
|
||||||
|
year,
|
||||||
|
count: "(0)",
|
||||||
|
months: []
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const yearData = yearMap.get(year)!;
|
||||||
|
|
||||||
|
// Find or create month data
|
||||||
|
let monthData = yearData.months.find(m => m.name === monthName);
|
||||||
|
if (!monthData) {
|
||||||
|
monthData = {
|
||||||
|
name: monthName,
|
||||||
|
count: "(0)",
|
||||||
|
posts: []
|
||||||
|
};
|
||||||
|
yearData.months.push(monthData);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add post to the month
|
||||||
|
monthData.posts.push({
|
||||||
|
title: post.title,
|
||||||
|
href
|
||||||
|
});
|
||||||
|
|
||||||
|
// Update counts
|
||||||
|
monthData.count = `(${monthData.posts.length})`;
|
||||||
|
yearData.count = `(${yearData.months.reduce((total, m) => total + m.posts.length, 0)})`;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Convert map to array and sort
|
||||||
|
return Array.from(yearMap.values()).sort((a, b) =>
|
||||||
|
parseInt(b.year) - parseInt(a.year)
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -10,15 +10,238 @@ function setupArchiveToggles() {
|
|||||||
// Toggle expanded state
|
// Toggle expanded state
|
||||||
if (toggleIcon) toggleIcon.classList.toggle('expanded');
|
if (toggleIcon) toggleIcon.classList.toggle('expanded');
|
||||||
if (content) content.classList.toggle('expanded');
|
if (content) content.classList.toggle('expanded');
|
||||||
|
|
||||||
|
// Update aria-expanded
|
||||||
|
const isExpanded = content.classList.contains('expanded');
|
||||||
|
this.setAttribute('aria-expanded', String(isExpanded));
|
||||||
|
|
||||||
|
// Update tabIndex for nested elements
|
||||||
|
updateTabIndex(content, isExpanded);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Remove active class from all post links
|
||||||
|
document.querySelectorAll('.archive-post a').forEach(link => {
|
||||||
|
link.classList.remove('active');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add click handlers for post links to toggle active class
|
||||||
|
document.querySelectorAll('.archive-post a').forEach(link => {
|
||||||
|
link.addEventListener('click', function() {
|
||||||
|
// Remove active class from all post links
|
||||||
|
document.querySelectorAll('.archive-post a').forEach(postLink => {
|
||||||
|
postLink.classList.remove('active');
|
||||||
|
});
|
||||||
|
// Add active class to clicked link
|
||||||
|
this.classList.add('active');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Initialize the archive state with a slight delay to ensure DOM is ready
|
||||||
|
setTimeout(() => {
|
||||||
|
initializeArchiveState();
|
||||||
|
// Update the active post indicator after initializing the archive state
|
||||||
|
updateActivePost();
|
||||||
|
}, 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateTabIndex(content: Element, isExpanded: boolean) {
|
||||||
|
if (!content) return;
|
||||||
|
|
||||||
|
const tabIndex = isExpanded ? '0' : '-1';
|
||||||
|
|
||||||
|
// Update focusable elements based on visibility
|
||||||
|
content.querySelectorAll('a, button, [tabindex="0"], [tabindex="-1"]').forEach(el => {
|
||||||
|
el.setAttribute('tabindex', tabIndex);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function initializeArchiveState() {
|
||||||
|
// Get the current path
|
||||||
|
const currentPath = window.location.pathname;
|
||||||
|
|
||||||
|
// Check if we're currently viewing a blog post (pattern: /YYYY/MM/slug)
|
||||||
|
const pathParts = currentPath.split('/').filter(part => part);
|
||||||
|
const isPostView = pathParts.length >= 3 &&
|
||||||
|
/^\d{4}$/.test(pathParts[0]) &&
|
||||||
|
/^\d{1,2}$/.test(pathParts[1]);
|
||||||
|
|
||||||
|
// Get all year and month elements
|
||||||
|
const years = Array.from(document.querySelectorAll('.archive-year')) as HTMLElement[];
|
||||||
|
const months = Array.from(document.querySelectorAll('.archive-month')) as HTMLElement[];
|
||||||
|
|
||||||
|
// Find the target year and month to keep expanded
|
||||||
|
let targetYear: HTMLElement | null = null;
|
||||||
|
let targetMonth: HTMLElement | null = null;
|
||||||
|
|
||||||
|
if (isPostView) {
|
||||||
|
// Try to find the post link in multiple ways
|
||||||
|
let postLink: HTMLAnchorElement | null = null;
|
||||||
|
|
||||||
|
// Try to find the post link with exact path or with/without trailing slash
|
||||||
|
postLink = document.querySelector(`a[href="${currentPath}"]`) as HTMLAnchorElement;
|
||||||
|
|
||||||
|
if (!postLink) {
|
||||||
|
const altPath = currentPath.endsWith('/') ?
|
||||||
|
currentPath.slice(0, -1) : currentPath + '/';
|
||||||
|
postLink = document.querySelector(`a[href="${altPath}"]`) as HTMLAnchorElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If still not found, try a partial match using the slug
|
||||||
|
if (!postLink && pathParts.length >= 3) {
|
||||||
|
const slug = pathParts[pathParts.length - 1];
|
||||||
|
|
||||||
|
document.querySelectorAll('.archive-post a').forEach((link) => {
|
||||||
|
const href = link.getAttribute('href');
|
||||||
|
if (href && href.endsWith(slug)) {
|
||||||
|
postLink = link as HTMLAnchorElement;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we found the post link, get its parent month and year
|
||||||
|
if (postLink) {
|
||||||
|
const postLi = postLink.parentElement; // li.archive-post
|
||||||
|
const postsUl = postLi?.parentElement; // ul.archive-posts
|
||||||
|
const contentDiv = postsUl?.parentElement; // div.archive-content
|
||||||
|
const monthLi = contentDiv?.parentElement; // li containing the month
|
||||||
|
|
||||||
|
// Get the month toggle element
|
||||||
|
const monthElement = monthLi?.querySelector('.archive-month') as HTMLElement;
|
||||||
|
|
||||||
|
if (monthElement) {
|
||||||
|
targetMonth = monthElement;
|
||||||
|
|
||||||
|
// Get the parent year
|
||||||
|
const yearLi = monthLi?.parentElement; // ul containing the month
|
||||||
|
const yearContentDiv = yearLi?.parentElement; // div.archive-content
|
||||||
|
const yearMainLi = yearContentDiv?.parentElement; // li containing the year
|
||||||
|
const yearElement = yearMainLi?.querySelector('.archive-year') as HTMLElement;
|
||||||
|
|
||||||
|
targetYear = yearElement;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we didn't find a specific target year, fall back to the most recent year
|
||||||
|
if (!targetYear && years.length > 0) {
|
||||||
|
targetYear = years[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we didn't find a specific target month, fall back to the most recent month in that year
|
||||||
|
if (!targetMonth && targetYear) {
|
||||||
|
const yearContent = targetYear.nextElementSibling as HTMLElement;
|
||||||
|
if (yearContent) {
|
||||||
|
const yearMonths = yearContent.querySelectorAll('.archive-month') as NodeListOf<HTMLElement>;
|
||||||
|
if (yearMonths.length > 0) {
|
||||||
|
targetMonth = yearMonths[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper function to collapse an element
|
||||||
|
function collapse(element: HTMLElement) {
|
||||||
|
const toggleIcon = element.querySelector('.archive-toggle');
|
||||||
|
const content = element.nextElementSibling;
|
||||||
|
|
||||||
|
if (toggleIcon) toggleIcon.classList.remove('expanded');
|
||||||
|
if (content) {
|
||||||
|
content.classList.remove('expanded');
|
||||||
|
updateTabIndex(content, false);
|
||||||
|
}
|
||||||
|
element.setAttribute('aria-expanded', 'false');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper function to expand an element
|
||||||
|
function expand(element: HTMLElement) {
|
||||||
|
const toggleIcon = element.querySelector('.archive-toggle');
|
||||||
|
const content = element.nextElementSibling;
|
||||||
|
|
||||||
|
if (toggleIcon) toggleIcon.classList.add('expanded');
|
||||||
|
if (content) {
|
||||||
|
content.classList.add('expanded');
|
||||||
|
updateTabIndex(content, true);
|
||||||
|
}
|
||||||
|
element.setAttribute('aria-expanded', 'true');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Collapse all years except our target
|
||||||
|
years.forEach(year => {
|
||||||
|
if (year !== targetYear) {
|
||||||
|
collapse(year);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Collapse all months except our target
|
||||||
|
months.forEach(month => {
|
||||||
|
if (month !== targetMonth) {
|
||||||
|
collapse(month);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Expand the target year if we have one
|
||||||
|
if (targetYear) {
|
||||||
|
expand(targetYear);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Expand the target month if we have one
|
||||||
|
if (targetMonth) {
|
||||||
|
expand(targetMonth);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to update the active post link based on the current URL
|
||||||
|
function updateActivePost() {
|
||||||
|
// Remove active class from all post links
|
||||||
|
document.querySelectorAll('.archive-post a').forEach(link => {
|
||||||
|
link.classList.remove('active');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Get the current path
|
||||||
|
const currentPath = window.location.pathname;
|
||||||
|
|
||||||
|
// Find the post link matching the current path
|
||||||
|
let postLink = document.querySelector(`a[href="${currentPath}"]`) as HTMLAnchorElement;
|
||||||
|
|
||||||
|
// Try with/without trailing slash if not found
|
||||||
|
if (!postLink) {
|
||||||
|
const altPath = currentPath.endsWith('/') ?
|
||||||
|
currentPath.slice(0, -1) : currentPath + '/';
|
||||||
|
postLink = document.querySelector(`a[href="${altPath}"]`) as HTMLAnchorElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If found, add active class
|
||||||
|
if (postLink) {
|
||||||
|
postLink.classList.add('active');
|
||||||
|
} else {
|
||||||
|
// Try partial match using the slug
|
||||||
|
const pathParts = currentPath.split('/').filter(part => part);
|
||||||
|
if (pathParts.length >= 3) {
|
||||||
|
const slug = pathParts[pathParts.length - 1];
|
||||||
|
document.querySelectorAll('.archive-post a').forEach((link) => {
|
||||||
|
const href = link.getAttribute('href');
|
||||||
|
if (href && href.endsWith(slug)) {
|
||||||
|
link.classList.add('active');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize on page load
|
// Initialize on page load
|
||||||
if (document.readyState === 'loading') {
|
if (document.readyState === 'loading') {
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
setupArchiveToggles();
|
setupArchiveToggles();
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
setupArchiveToggles();
|
setupArchiveToggles();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Listen for browser navigation events (back/forward buttons)
|
||||||
|
window.addEventListener('popstate', () => {
|
||||||
|
// Re-initialize the archive state for the new URL
|
||||||
|
initializeArchiveState();
|
||||||
|
// Update the active post indicator after initializing the archive state
|
||||||
|
setTimeout(updateActivePost, 10); // Small delay to ensure DOM is updated
|
||||||
|
});
|
||||||
@ -1,66 +1,23 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import postArchiveScript from '../clientJS/post-archive' with { type: "text" };
|
import postArchiveScript from '../clientJS/post-archive' with { type: "text" };
|
||||||
|
import { getPostsByYearAndMonth } from '../../db';
|
||||||
import { minifyJS } from '../utils';
|
import { minifyJS } from '../utils';
|
||||||
|
|
||||||
export function PostArchive() {
|
// Read posts from database once and store in a closure
|
||||||
const archiveData = [
|
const getArchiveData = (() => {
|
||||||
{
|
let cachedData: ReturnType<typeof getPostsByYearAndMonth> | null = null;
|
||||||
year: "2025",
|
|
||||||
count: "(8)",
|
return () => {
|
||||||
months: [
|
if (!cachedData) {
|
||||||
{
|
cachedData = getPostsByYearAndMonth();
|
||||||
name: "October",
|
|
||||||
count: "(3)",
|
|
||||||
posts: [
|
|
||||||
{ title: "Building a Modern Blog", href: "/blog/post-1" },
|
|
||||||
{ title: "TypeScript Tips & Tricks", href: "/blog/post-2" },
|
|
||||||
{ title: "Designing Better UIs", href: "/blog/post-3" }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "September",
|
|
||||||
count: "(5)",
|
|
||||||
posts: [
|
|
||||||
{ title: "Getting Started with Bun", href: "/blog/post-4" },
|
|
||||||
{ title: "Web Performance Optimization", href: "/blog/post-5" },
|
|
||||||
{ title: "CSS Grid vs Flexbox", href: "/blog/post-6" },
|
|
||||||
{ title: "JavaScript Best Practices", href: "/blog/post-7" },
|
|
||||||
{ title: "Accessibility Matters", href: "/blog/post-8" }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
year: "2024",
|
|
||||||
count: "(12)",
|
|
||||||
months: [
|
|
||||||
{
|
|
||||||
name: "December",
|
|
||||||
count: "(4)",
|
|
||||||
posts: [
|
|
||||||
{ title: "Year in Review 2024", href: "/blog/post-9" },
|
|
||||||
{ title: "Holiday Coding Projects", href: "/blog/post-10" },
|
|
||||||
{ title: "New Year Resolutions", href: "/blog/post-11" },
|
|
||||||
{ title: "Reflecting on Growth", href: "/blog/post-12" }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "June",
|
|
||||||
count: "(8)",
|
|
||||||
posts: [
|
|
||||||
{ title: "Summer Tech Trends", href: "/blog/post-13" },
|
|
||||||
{ title: "Remote Work Tips", href: "/blog/post-14" },
|
|
||||||
{ title: "Learning Resources", href: "/blog/post-15" },
|
|
||||||
{ title: "Code Review Best Practices", href: "/blog/post-16" },
|
|
||||||
{ title: "Git Workflow Tips", href: "/blog/post-17" },
|
|
||||||
{ title: "Docker for Beginners", href: "/blog/post-18" },
|
|
||||||
{ title: "API Design Patterns", href: "/blog/post-19" },
|
|
||||||
{ title: "Testing Strategies", href: "/blog/post-20" }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
];
|
return cachedData;
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
|
||||||
|
|
||||||
|
export function PostArchive() {
|
||||||
|
const archiveData = getArchiveData();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="postList sheet-background">
|
<div className="postList sheet-background">
|
||||||
@ -68,25 +25,25 @@ export function PostArchive() {
|
|||||||
<ul className="post-archive">
|
<ul className="post-archive">
|
||||||
{archiveData.map((yearData) => (
|
{archiveData.map((yearData) => (
|
||||||
<li key={yearData.year}>
|
<li key={yearData.year}>
|
||||||
<div className="archive-year">
|
<div className="archive-year" tabIndex={0} role="button" aria-expanded="true">
|
||||||
<span className="archive-toggle">▶</span>
|
<span className="archive-toggle expanded">▼</span>
|
||||||
<span>{yearData.year}</span>
|
<span>{yearData.year}</span>
|
||||||
<span className="post-count">{yearData.count}</span>
|
<span className="post-count">{yearData.count}</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="archive-content">
|
<div className="archive-content expanded">
|
||||||
<ul className="archive-months">
|
<ul className="archive-months">
|
||||||
{yearData.months.map((monthData) => (
|
{yearData.months.map((monthData) => (
|
||||||
<li key={monthData.name}>
|
<li key={monthData.name}>
|
||||||
<div className="archive-month">
|
<div className="archive-month" tabIndex={0} role="button" aria-expanded="true">
|
||||||
<span className="archive-toggle">▶</span>
|
<span className="archive-toggle expanded">▼</span>
|
||||||
<span>{monthData.name}</span>
|
<span>{monthData.name}</span>
|
||||||
<span className="post-count">{monthData.count}</span>
|
<span className="post-count">{monthData.count}</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="archive-content">
|
<div className="archive-content expanded">
|
||||||
<ul className="archive-posts">
|
<ul className="archive-posts">
|
||||||
{monthData.posts.map((post) => (
|
{monthData.posts.map((post) => (
|
||||||
<li key={post.href} className="archive-post">
|
<li key={post.href} className="archive-post">
|
||||||
<a href={post.href}>{post.title}</a>
|
<a href={post.href} tabIndex={-1}>{post.title}</a>
|
||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
|
|||||||
@ -5,8 +5,10 @@ import { type BlogPost } from '../../db/queries';
|
|||||||
|
|
||||||
export function Home({ searchParams }: { searchParams: Record<string, string> }) {
|
export function Home({ searchParams }: { searchParams: Record<string, string> }) {
|
||||||
const currentPage = parseInt(searchParams.page || "1", 10);
|
const currentPage = parseInt(searchParams.page || "1", 10);
|
||||||
const totalPages = Math.ceil(getNumOfPosts() / 10);
|
const postsPerPage = 10;
|
||||||
const posts = getRecentPosts(10, ); // Get the 10 most recent posts
|
const totalPages = Math.ceil(getNumOfPosts() / postsPerPage);
|
||||||
|
const offset = (currentPage - 1) * postsPerPage;
|
||||||
|
const posts = getRecentPosts(postsPerPage, offset); // Get posts for the current page
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<main>
|
<main>
|
||||||
|
|||||||
@ -628,11 +628,23 @@ h1 {
|
|||||||
user-select: none;
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.archive-year.expanded,
|
||||||
|
.archive-month.expanded {
|
||||||
|
background-color: var(--bg-primary);
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
.archive-year:hover,
|
.archive-year:hover,
|
||||||
.archive-month:hover {
|
.archive-month:hover {
|
||||||
background-color: var(--bg-primary);
|
background-color: var(--bg-primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.archive-year:focus,
|
||||||
|
.archive-month:focus {
|
||||||
|
outline: 2px solid var(--accent-color);
|
||||||
|
outline-offset: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
.archive-year {
|
.archive-year {
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
@ -652,6 +664,7 @@ h1 {
|
|||||||
|
|
||||||
.archive-toggle.expanded {
|
.archive-toggle.expanded {
|
||||||
transform: rotate(90deg);
|
transform: rotate(90deg);
|
||||||
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
.archive-content {
|
.archive-content {
|
||||||
@ -691,6 +704,11 @@ h1 {
|
|||||||
color: var(--text-primary);
|
color: var(--text-primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.archive-post a.active {
|
||||||
|
color: var(--text-primary);
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
.post-count {
|
.post-count {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
color: var(--text-secondary);
|
color: var(--text-secondary);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user