Files
chorus-ping-blog/components/PostCard.tsx
anthonyrawlins 5e0be60c30 Release v1.2.0: Newspaper-style layout with major UI refinements
This release transforms PING into a sophisticated newspaper-style digital
publication with enhanced readability and professional presentation.

Major Features:
- New FeaturedPostHero component with full-width newspaper design
- Completely redesigned homepage with responsive newspaper grid layout
- Enhanced PostCard component with refined typography and spacing
- Improved mobile-first responsive design (mobile → tablet → desktop → 2XL)
- Archive section with multi-column layout for deeper content discovery

Technical Improvements:
- Enhanced blog post validation and error handling in lib/blog.ts
- Better date handling and normalization for scheduled posts
- Improved Dockerfile with correct content volume mount paths
- Fixed port configuration (3025 throughout stack)
- Updated Tailwind config with refined typography and newspaper aesthetics
- Added getFeaturedPost() function for hero selection

UI/UX Enhancements:
- Professional newspaper-style borders and dividers
- Improved dark mode styling throughout
- Better content hierarchy and visual flow
- Enhanced author bylines and metadata presentation
- Refined color palette with newspaper sophistication

Documentation:
- Added DESIGN_BRIEF_NEWSPAPER_LAYOUT.md detailing design principles
- Added TESTING_RESULTS_25_POSTS.md with test scenarios

This release establishes PING as a premium publication platform for
AI orchestration and contextual intelligence thought leadership.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-19 00:23:51 +11:00

63 lines
2.3 KiB
TypeScript

import Link from 'next/link'
import { BlogPost } from '@/types/blog'
interface PostCardProps {
post: BlogPost
featured?: boolean
}
export default function PostCard({ post, featured = false }: PostCardProps) {
const formattedDate = new Date(post.date).toLocaleDateString('en-US', {
year: 'numeric',
month: 'short',
day: 'numeric'
})
// Newspaper-style card - clean, minimal, text-focused
return (
<article className="group border-b border-carbon-200 dark:border-carbon-700 pb-6 mb-6 hover:border-mulberry-400 dark:hover:border-mulberry-600 transition-colors duration-200">
<Link href={`/posts/${post.slug}`} className="block">
{/* Newspaper-style kicker */}
<div className="mb-2">
<span className="text-mulberry-600 dark:text-mulberry-400 text-xs font-bold uppercase tracking-wide">
{post.tags?.[0] || 'Analysis'}
</span>
</div>
{/* Headline */}
<h2 className="text-xl md:text-2xl font-bold text-carbon-950 dark:text-carbon-100 leading-tight mb-3 group-hover:text-carbon-700 dark:group-hover:text-mulberry-200 transition-colors">
{post.title}
</h2>
{/* Subhead */}
<p className="text-carbon-700 dark:text-carbon-300 leading-relaxed mb-4 text-base">
{post.description}
</p>
{/* Byline - newspaper style */}
<div className="flex items-center justify-between text-xxs">
<div className="flex items-center space-x-3">
<span className="text-carbon-950 dark:text-carbon-200 font-semibold">
{post.author?.name || 'CHORUS Team'}
</span>
<span className="text-carbon-500 dark:text-carbon-600">|</span>
<time dateTime={post.date} className="text-carbon-600 dark:text-carbon-500 font-medium">
{formattedDate}
</time>
<span className="text-carbon-500 dark:text-carbon-600">|</span>
<span className="text-carbon-600 dark:text-carbon-500">
{post.readingTime} min read
</span>
</div>
{/* Tag indicator */}
{(post.tags?.length || 0) > 1 && (
<span className="text-carbon-600 dark:text-carbon-500 text-xxs">
+{(post.tags?.length || 0) - 1} more topics
</span>
)}
</div>
</Link>
</article>
)
}