Files
claudetools/projects/radio-show/website/src/components/home/BlogHighlights.astro
Mike Swanson 1b45921493 Radio show website: Full Astro build with 194 episodes imported
Complete website for The Computer Guru Show (radio.azcomputerguru.com):
- Astro 6.0.4 static site with React islands
- 194 episodes imported from gurushow.com RSS feed
- Dark/light mode HSL design system
- Persistent audio player with session persistence
- Episode archive with search and season filtering
- Home page with animated hero, stats, latest episodes
- All pages: About, Subscribe, Community, Live, Contact, Blog, 404
- Podcast RSS feed with iTunes namespace
- Session log updated

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-14 20:44:42 -07:00

186 lines
4.8 KiB
Plaintext

---
import { getCollection } from 'astro:content';
const allPosts = await getCollection('blog');
const publishedPosts = allPosts
.filter((post) => !post.data.draft)
.sort((a, b) => b.data.pubDate.getTime() - a.data.pubDate.getTime())
.slice(0, 3);
const isSingle = publishedPosts.length === 1;
---
{publishedPosts.length > 0 && (
<section class="section blog-highlights fade-in">
<div class="container">
<div class="section-header">
<h2 class="section__title">From the Blog</h2>
<a href="/blog" class="section-header__link">
All Posts
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<polyline points="9 18 15 12 9 6"></polyline>
</svg>
</a>
</div>
<div class:list={['blog-grid', { 'blog-grid--single': isSingle }]}>
{publishedPosts.map((post) => {
const formattedDate = new Date(post.data.pubDate).toLocaleDateString('en-US', {
year: 'numeric',
month: 'long',
day: 'numeric',
});
return (
<article class="blog-card card">
<div class="blog-card__meta">
<time datetime={post.data.pubDate.toISOString()}>{formattedDate}</time>
{post.data.tags.length > 0 && (
<div class="blog-card__tags">
{post.data.tags.slice(0, 2).map((tag: string) => (
<span class="blog-card__tag">{tag}</span>
))}
</div>
)}
</div>
<a href={`/blog/${post.id}`} class="blog-card__title-link">
<h3 class="blog-card__title">{post.data.title}</h3>
</a>
<p class="blog-card__description">{post.data.description}</p>
<div class="blog-card__footer">
<span class="blog-card__author">By {post.data.author}</span>
<a href={`/blog/${post.id}`} class="blog-card__read-more">
Read More
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<line x1="5" y1="12" x2="19" y2="12"></line>
<polyline points="12 5 19 12 12 19"></polyline>
</svg>
</a>
</div>
</article>
);
})}
</div>
</div>
</section>
)}
<style>
.section-header {
display: flex;
align-items: baseline;
justify-content: space-between;
gap: var(--space-4);
flex-wrap: wrap;
}
.section-header__link {
display: inline-flex;
align-items: center;
gap: var(--space-1);
font-size: var(--text-sm);
font-weight: 600;
color: var(--color-accent);
transition: gap var(--transition-fast);
}
.section-header__link:hover {
gap: var(--space-2);
}
.blog-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: var(--space-6);
}
.blog-grid--single {
max-width: 600px;
margin-inline: auto;
}
.blog-card {
display: flex;
flex-direction: column;
gap: var(--space-3);
}
.blog-card__meta {
display: flex;
align-items: center;
justify-content: space-between;
gap: var(--space-3);
flex-wrap: wrap;
}
.blog-card__meta time {
font-size: var(--text-sm);
color: var(--color-text-muted);
}
.blog-card__tags {
display: flex;
gap: var(--space-1);
}
.blog-card__tag {
font-size: 0.65rem;
padding: 2px var(--space-2);
border-radius: 9999px;
background: var(--color-accent-glow);
color: var(--color-accent);
}
.blog-card__title-link {
color: inherit;
text-decoration: none;
}
.blog-card__title-link:hover {
color: var(--color-accent);
}
.blog-card__title {
font-size: var(--text-xl);
font-weight: 700;
line-height: 1.3;
}
.blog-card__description {
font-size: var(--text-sm);
color: var(--color-text-secondary);
line-height: 1.6;
}
.blog-card__footer {
display: flex;
align-items: center;
justify-content: space-between;
margin-top: auto;
padding-top: var(--space-3);
border-top: 1px solid var(--color-border);
}
.blog-card__author {
font-size: var(--text-xs);
color: var(--color-text-muted);
}
.blog-card__read-more {
display: inline-flex;
align-items: center;
gap: var(--space-1);
font-size: var(--text-sm);
font-weight: 600;
color: var(--color-accent);
transition: gap var(--transition-fast);
}
.blog-card__read-more:hover {
gap: var(--space-2);
}
</style>