diff --git a/src/components/RecentPosts.astro b/src/components/RecentPosts.astro index 3e0d6d7..ed62956 100644 --- a/src/components/RecentPosts.astro +++ b/src/components/RecentPosts.astro @@ -5,6 +5,7 @@ const posts = (await getCollection('blog')) .sort((a, b) => b.data.pubDate.valueOf() - a.data.pubDate.valueOf()) .slice(0, 3); --- +
@@ -31,7 +32,7 @@ const posts = (await getCollection('blog'))
{(post.data.tags ?? []).slice(0,3).map((t: string) => ( - {t} + {t} ))}
@@ -51,9 +52,7 @@ const posts = (await getCollection('blog'))
+ \ No newline at end of file diff --git a/src/pages/tags/[tag].astro b/src/pages/tags/[tag].astro new file mode 100644 index 0000000..ca3dd86 --- /dev/null +++ b/src/pages/tags/[tag].astro @@ -0,0 +1,109 @@ +--- +import { getCollection } from 'astro:content'; +import BaseLayout from '../../layouts/BaseLayout.astro'; + +export async function getStaticPaths() { + const posts = await getCollection('blog', ({ data }) => !data.draft); + const tags = [...new Set(posts.flatMap(p => p.data.tags ?? []))]; + + return tags.map(tag => ({ + params: { tag }, + props: { + tag, + posts: posts + .filter(p => p.data.tags?.includes(tag)) + .sort((a, b) => b.data.pubDate.valueOf() - a.data.pubDate.valueOf()), + }, + })); +} + +const { tag, posts } = Astro.props; +--- + + +
+
+ ← all posts +
+

+ #{tag} +

+

+ {posts.length} {posts.length === 1 ? 'entry' : 'entries'} +

+
+ +
+ {posts.map(post => ( + + ))} +
+
+
+ + \ No newline at end of file diff --git a/src/styles/global.css b/src/styles/global.css index 9cd7242..8f638db 100644 --- a/src/styles/global.css +++ b/src/styles/global.css @@ -115,13 +115,23 @@ pre { } pre { - background: var(--bg-surface); - border: 1px solid var(--border-subtle); + background: #0d1918; + border: 1px solid rgba(0, 210, 190, 0.12); border-left: 3px solid var(--petronas-teal); padding: 1.25rem 1.5rem; border-radius: 0 8px 8px 0; overflow-x: auto; margin: 2rem 0; + color: #a8c8c6; /* single readable text colour — no syntax highlighting */ +} + +/* Kill any syntax highlighter span colours — keep it monochrome */ +pre span, +pre code span { + color: inherit !important; + background: transparent !important; + font-style: normal !important; + font-weight: normal !important; } /* ── Layout ────────────────────────────────────────────────── */ @@ -193,14 +203,24 @@ pre { /* ── Tag / Badge ───────────────────────────────────────────── */ .tag { display: inline-block; - padding: 0.2rem 0.65rem; + padding: 0.15rem 0.55rem; font-family: var(--font-mono); - font-size: 0.72rem; + font-size: 0.68rem; color: var(--petronas-teal); background: var(--petronas-glow); border: 1px solid rgba(0, 210, 190, 0.2); - border-radius: 3px; + border-radius: 20px; letter-spacing: 0.04em; + white-space: nowrap; + transition: + background var(--transition-fast), + border-color var(--transition-fast), + color var(--transition-fast); +} +a.tag:hover { + background: rgba(0, 210, 190, 0.2); + border-color: rgba(0, 210, 190, 0.5); + color: var(--text-primary); } /* ── Glow Divider ──────────────────────────────────────────── */ @@ -215,7 +235,6 @@ pre { ); margin: 4rem 0; opacity: 0.3; - margin: 4rem auto; } /* ── Noise texture overlay ─────────────────────────────────── */ @@ -246,7 +265,7 @@ body::after { /* ── Prose (blog posts) ────────────────────────────────────── */ .prose { max-width: 72ch; - color: var(--text-secondary); + color: #9bbfbd; /* brighter than text-secondary for long-form readability */ } .prose h2, .prose h3 { @@ -255,6 +274,7 @@ body::after { } .prose p { margin-bottom: 1.4rem; + line-height: 1.8; } .prose ul, .prose ol { @@ -285,8 +305,9 @@ body::after { font-weight: 500; } .prose code { - background: var(--bg-surface); - padding: 0.15em 0.4em; + background: #0d1918; + padding: 0.15em 0.45em; border-radius: 3px; - color: var(--petronas-teal); + color: #7dcfca; /* slightly muted teal — readable but distinct from body text */ + font-size: 0.85em; }