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>
This commit is contained in:
@@ -5,69 +5,56 @@ export default function BlogFooter() {
|
||||
return (
|
||||
<footer className="bg-white/80 dark:bg-carbon-950/80 backdrop-blur-md border-t border-carbon-200/50 dark:border-carbon-800/50 mt-24">
|
||||
<div className="blog-container py-12">
|
||||
<div className="grid grid-cols-1 md:grid-cols-4 gap-8">
|
||||
<div className="col-span-1 md:col-span-2">
|
||||
<div className="flex items-center space-x-3 mb-4">
|
||||
<div className="w-10 h-10">
|
||||
<ThreeLogo className="w-full h-full" />
|
||||
</div>
|
||||
<div className="flex flex-col">
|
||||
<span className="font-logo font-semibold text-lg leading-none text-carbon-900 dark:text-carbon-100">CHORUS</span>
|
||||
<span className="text-carbon-600 dark:text-carbon-500 text-xs font-medium">PING!</span>
|
||||
</div>
|
||||
{/* Centered Masthead Footer */}
|
||||
<div className="flex flex-col items-center text-center space-y-8">
|
||||
{/* Logo Group - Centered */}
|
||||
<div className="flex items-center space-x-4">
|
||||
<div className="w-12 h-12">
|
||||
<ThreeLogo className="w-full h-full" />
|
||||
</div>
|
||||
<p className="text-carbon-600 dark:text-carbon-400 text-sm leading-relaxed mb-6 max-w-md">
|
||||
Insights and deep dives into Context Engineering for Agentic AI and Orchestration, Agent Collaboration,
|
||||
and the future of intelligent systems.
|
||||
</p>
|
||||
<div className="flex space-x-4">
|
||||
<Link
|
||||
href="https://www.linkedin.com/in/anthonylewisrawlins"
|
||||
className="text-carbon-600 dark:text-carbon-500 hover:text-carbon-800 dark:hover:text-carbon-300 transition-colors"
|
||||
>
|
||||
<span className="sr-only">LinkedIn</span>
|
||||
<svg className="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fillRule="evenodd" d="M16.338 16.338H13.67V12.16c0-.995-.017-2.277-1.387-2.277-1.39 0-1.601 1.086-1.601 2.207v4.248H8.014v-8.59h2.559v1.174h.037c.356-.675 1.227-1.387 2.526-1.387 2.703 0 3.203 1.778 3.203 4.092v4.711zM5.005 6.575a1.548 1.548 0 11-.003-3.096 1.548 1.548 0 01.003 3.096zm-1.337 9.763H6.34v-8.59H3.667v8.59zM17.668 1H2.328C1.595 1 1 1.581 1 2.298v15.403C1 18.418 1.595 19 2.328 19h15.34c.734 0 1.332-.582 1.332-1.299V2.298C19 1.581 18.402 1 17.668 1z" clipRule="evenodd"/>
|
||||
</svg>
|
||||
</Link>
|
||||
<div className="flex flex-col">
|
||||
<span className="font-logo font-thin text-2xl leading-none text-carbon-900 dark:text-carbon-100 text-center">CHORUS</span>
|
||||
<span className="text-carbon-600 dark:text-carbon-500 text-sm font-bold tracking-wider text-left">PING!</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 className="text-carbon-900 dark:text-carbon-100 font-semibold mb-4">Blog</h3>
|
||||
<ul className="space-y-2 text-sm">
|
||||
<li>
|
||||
<Link href="/" className="text-carbon-600 dark:text-carbon-400 hover:text-carbon-800 dark:hover:text-carbon-200 transition-colors">
|
||||
All Posts
|
||||
</Link>
|
||||
</li>
|
||||
<li>
|
||||
<Link href="/tags" className="text-carbon-600 dark:text-carbon-400 hover:text-carbon-800 dark:hover:text-carbon-200 transition-colors">
|
||||
Topics
|
||||
</Link>
|
||||
</li>
|
||||
<li>
|
||||
<Link href="/rss.xml" className="text-carbon-600 dark:text-carbon-400 hover:text-carbon-800 dark:hover:text-carbon-200 transition-colors">
|
||||
RSS Feed
|
||||
</Link>
|
||||
</li>
|
||||
</ul>
|
||||
{/* Description */}
|
||||
<p className="text-carbon-600 dark:text-carbon-400 text-sm leading-relaxed max-w-2xl">
|
||||
Insights and deep dives into Context Engineering for Agentic AI and Orchestration, Agent Collaboration,
|
||||
and the future of intelligent systems.
|
||||
</p>
|
||||
|
||||
{/* Navigation Links */}
|
||||
<div className="flex items-center justify-center space-x-6 border-t border-b border-carbon-200 dark:border-carbon-800 py-4 w-full max-w-xl">
|
||||
<Link href="/" className="text-carbon-600 dark:text-carbon-400 hover:text-carbon-800 dark:hover:text-carbon-200 transition-colors text-sm font-medium uppercase tracking-wide">
|
||||
All Posts
|
||||
</Link>
|
||||
<span className="text-carbon-300 dark:text-carbon-700">•</span>
|
||||
<Link href="https://chorus.services" className="text-carbon-600 dark:text-carbon-400 hover:text-carbon-800 dark:hover:text-carbon-200 transition-colors text-sm font-medium uppercase tracking-wide">
|
||||
Platform
|
||||
</Link>
|
||||
<span className="text-carbon-300 dark:text-carbon-700">•</span>
|
||||
<Link href="/rss.xml" className="text-carbon-600 dark:text-carbon-400 hover:text-carbon-800 dark:hover:text-carbon-200 transition-colors text-sm font-medium uppercase tracking-wide">
|
||||
RSS
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 className="text-carbon-900 dark:text-carbon-100 font-semibold mb-4">CHORUS</h3>
|
||||
<ul className="space-y-2 text-sm">
|
||||
<li>
|
||||
<Link href="https://chorus.services" className="text-carbon-600 dark:text-carbon-400 hover:text-carbon-800 dark:hover:text-carbon-200 transition-colors">
|
||||
Platform
|
||||
</Link>
|
||||
</li>
|
||||
</ul>
|
||||
{/* Social Links */}
|
||||
<div className="flex space-x-4">
|
||||
<Link
|
||||
href="https://www.linkedin.com/in/anthonylewisrawlins"
|
||||
className="text-carbon-600 dark:text-carbon-500 hover:text-carbon-800 dark:hover:text-carbon-300 transition-colors"
|
||||
>
|
||||
<span className="sr-only">LinkedIn</span>
|
||||
<svg className="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fillRule="evenodd" d="M16.338 16.338H13.67V12.16c0-.995-.017-2.277-1.387-2.277-1.39 0-1.601 1.086-1.601 2.207v4.248H8.014v-8.59h2.559v1.174h.037c.356-.675 1.227-1.387 2.526-1.387 2.703 0 3.203 1.778 3.203 4.092v4.711zM5.005 6.575a1.548 1.548 0 11-.003-3.096 1.548 1.548 0 01.003 3.096zm-1.337 9.763H6.34v-8.59H3.667v8.59zM17.668 1H2.328C1.595 1 1 1.581 1 2.298v15.403C1 18.418 1.595 19 2.328 19h15.34c.734 0 1.332-.582 1.332-1.299V2.298C19 1.581 18.402 1 17.668 1z" clipRule="evenodd"/>
|
||||
</svg>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="border-t border-carbon-200 dark:border-carbon-800 mt-8 pt-8 text-center">
|
||||
<p className="text-carbon-600 dark:text-carbon-500 text-sm">
|
||||
<p className="text-carbon-600 dark:text-carbon-500 text-xxs">
|
||||
© {new Date().getFullYear()} CHORUS Services. Built with care by{' '}
|
||||
<Link href="https://deepblack.cloud" className="text-carbon-700 dark:text-carbon-400 hover:text-carbon-900 dark:hover:text-carbon-200 transition-colors">
|
||||
Deep Black Cloud
|
||||
|
||||
@@ -20,54 +20,49 @@ export default function BlogHeader() {
|
||||
return (
|
||||
<header className={`sticky top-0 z-50 transition-all duration-300 ${
|
||||
isScrolled
|
||||
? 'bg-white/80 dark:bg-carbon-950/80 backdrop-blur-md border-b border-carbon-200/50 dark:border-carbon-800/50'
|
||||
: 'bg-white/20 dark:bg-carbon-950/20 backdrop-blur-sm'
|
||||
? 'bg-white/80 dark:bg-mulberry-950/80 backdrop-blur-md border-b border-carbon-200/50 dark:border-carbon-800/50'
|
||||
: 'bg-white/20 dark:bg-mulberry-950/20 backdrop-blur-sm'
|
||||
}`}>
|
||||
<nav className="blog-container py-chorus-lg">
|
||||
<div className="flex items-center justify-between">
|
||||
<Link href="/" className="flex items-center space-x-3 group">
|
||||
<div className="w-14 h-14 group-hover:scale-110 transition-transform">
|
||||
{/* Traditional Newspaper Masthead Layout */}
|
||||
<div className="flex flex-col items-center space-y-4">
|
||||
{/* Logo Group - Centered */}
|
||||
<Link href="/" className="flex items-center space-x-4 group">
|
||||
<div className="w-16 h-16 group-hover:scale-110 transition-transform">
|
||||
<ThreeLogo className="w-full h-full" />
|
||||
</div>
|
||||
<div className="flex flex-col">
|
||||
<span className="font-logo font-semibold text-lg leading-none text-carbon-900 dark:text-carbon-100">CHORUS</span>
|
||||
<span className="text-carbon-600 dark:text-carbon-500 text-xs font-medium">PING!</span>
|
||||
<span className="font-logo font-thin text-3xl leading-none text-carbon-900 dark:text-carbon-100 text-center">CHORUS</span>
|
||||
<span className="text-carbon-600 dark:text-carbon-500 text-sm font-bold tracking-wider text-left">PING!</span>
|
||||
</div>
|
||||
</Link>
|
||||
|
||||
|
||||
|
||||
|
||||
<div className="hidden md:flex items-center space-x-8">
|
||||
{/* Navigation Bar - Below Logo */}
|
||||
<div className="flex items-center justify-center space-x-8 border-t border-b border-carbon-200 dark:border-carbon-800 py-3 w-full max-w-2xl">
|
||||
<Link
|
||||
href="https://chorus.services"
|
||||
className="text-carbon-600 dark:text-carbon-300 hover:text-carbon-900 dark:hover:text-carbon-100 transition-colors font-semibold"
|
||||
className="text-carbon-600 dark:text-carbon-300 hover:text-carbon-900 dark:hover:text-carbon-100 transition-colors font-medium text-sm uppercase tracking-wide"
|
||||
>
|
||||
Home
|
||||
</Link>
|
||||
<span className="text-carbon-300 dark:text-carbon-700">•</span>
|
||||
<Link
|
||||
href="/"
|
||||
className="text-carbon-600 dark:text-carbon-300 hover:text-carbon-900 dark:hover:text-carbon-100 transition-colors font-semibold"
|
||||
className="text-carbon-600 dark:text-carbon-300 hover:text-carbon-900 dark:hover:text-carbon-100 transition-colors font-medium text-sm uppercase tracking-wide"
|
||||
>
|
||||
All Posts
|
||||
</Link>
|
||||
{/* <Link
|
||||
href="/tags"
|
||||
className="text-carbon-600 dark:text-carbon-300 hover:text-carbon-900 dark:hover:text-carbon-100 transition-colors font-semibold"
|
||||
>
|
||||
Topics
|
||||
</Link> */}
|
||||
|
||||
</div>
|
||||
|
||||
<div className="flex items-center space-x-4">
|
||||
<ThemeToggle />
|
||||
<Link
|
||||
href="https://chorus.services"
|
||||
className="px-4 py-2 bg-carbon-900 dark:bg-mulberry-700 hover:bg-carbon-800 dark:hover:bg-mulberry-600 text-white dark:text-mulberry-100 rounded-lg font-medium transition-colors text-sm"
|
||||
>
|
||||
Join Waitlist
|
||||
</Link>
|
||||
<span className="text-carbon-300 dark:text-carbon-700">•</span>
|
||||
<div className="flex items-center space-x-4">
|
||||
|
||||
<Link
|
||||
href="https://chorus.services"
|
||||
className="px-3 py-1 bg-carbon-900 dark:bg-mulberry-700 hover:bg-carbon-800 dark:hover:bg-mulberry-600 text-white dark:text-mulberry-100 rounded font-medium transition-colors text-xs uppercase tracking-wide"
|
||||
>
|
||||
Join Waitlist
|
||||
</Link>
|
||||
<ThemeToggle />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
121
components/FeaturedPostHero.tsx
Normal file
121
components/FeaturedPostHero.tsx
Normal file
@@ -0,0 +1,121 @@
|
||||
import Link from 'next/link'
|
||||
import { BlogPost } from '@/types/blog'
|
||||
|
||||
interface FeaturedPostHeroProps {
|
||||
post: BlogPost
|
||||
}
|
||||
|
||||
export default function FeaturedPostHero({ post }: FeaturedPostHeroProps) {
|
||||
const formattedDate = new Date(post.date).toLocaleDateString('en-US', {
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
day: 'numeric'
|
||||
})
|
||||
|
||||
return (
|
||||
<article className="group border-y-2 border-carbon-300 dark:border-carbon-700 bg-gradient-to-r from-white via-sand-50 to-white dark:from-carbon-950 dark:via-mulberry-950/30 dark:to-carbon-950 transition-all duration-300">
|
||||
<Link href={`/posts/${post.slug}`} className="block">
|
||||
<div className="max-w-6xl mx-auto px-8 py-12">
|
||||
{/* Newspaper-style header */}
|
||||
<div className="flex items-center space-x-4 mb-6">
|
||||
<div className="h-px bg-carbon-400 dark:bg-carbon-600 flex-1"></div>
|
||||
<div className="bg-carbon-900 dark:bg-mulberry-700 text-white dark:text-mulberry-100 px-4 py-1 text-xs font-bold uppercase tracking-wider">
|
||||
Featured Article
|
||||
</div>
|
||||
<div className="h-px bg-carbon-400 dark:bg-carbon-600 flex-1"></div>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 lg:grid-cols-3 gap-8 items-center">
|
||||
{/* Main content - spans 2 columns on large screens */}
|
||||
<div className="lg:col-span-2">
|
||||
{/* Newspaper-style kicker */}
|
||||
<div className="mb-4">
|
||||
<span className="text-mulberry-700 dark:text-mulberry-400 text-sm font-bold uppercase tracking-wide">
|
||||
{post.tags?.[0] || 'Contextual AI'}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/* Large headline */}
|
||||
<h1 className="text-3xl md:text-4xl lg:text-5xl font-bold text-carbon-950 dark:text-carbon-100 leading-tight mb-6 group-hover:text-carbon-700 dark:group-hover:text-mulberry-200 transition-colors">
|
||||
{post.title}
|
||||
</h1>
|
||||
|
||||
{/* Subhead/description */}
|
||||
<p className="text-xl md:text-2xl text-carbon-700 dark:text-carbon-300 leading-relaxed mb-6 font-light">
|
||||
{post.description}
|
||||
</p>
|
||||
|
||||
{/* Byline and meta */}
|
||||
<div className="flex items-center space-x-6 text-sm">
|
||||
<div className="flex items-center space-x-3">
|
||||
<div className="w-10 h-10 bg-gradient-to-br from-mulberry-400 to-ocean-500 rounded-full flex items-center justify-center">
|
||||
<span className="text-carbon-950 font-bold text-sm">
|
||||
{post.author?.name?.charAt(0) || 'C'}
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-carbon-950 dark:text-carbon-100 font-semibold">
|
||||
By {post.author?.name || 'CHORUS Team'}
|
||||
</p>
|
||||
{post.author?.role && (
|
||||
<p className="text-carbon-600 dark:text-carbon-500 text-xs">
|
||||
{post.author.role}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="h-4 w-px bg-carbon-400 dark:bg-carbon-600"></div>
|
||||
|
||||
<div className="text-carbon-600 dark:text-carbon-500">
|
||||
<time dateTime={post.date} className="font-medium">
|
||||
{formattedDate}
|
||||
</time>
|
||||
<span className="mx-2">•</span>
|
||||
<span>{post.readingTime} min read</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Sidebar - article highlights */}
|
||||
<div className="lg:col-span-1">
|
||||
<div className="bg-sand-100/50 dark:bg-carbon-900/50 border border-carbon-200 dark:border-carbon-800 p-6 rounded-lg">
|
||||
<h3 className="font-bold text-carbon-950 dark:text-carbon-100 mb-4 text-lg border-b border-carbon-300 dark:border-carbon-700 pb-2">
|
||||
In This Article
|
||||
</h3>
|
||||
<ul className="space-y-2 text-sm text-carbon-700 dark:text-carbon-300">
|
||||
<li className="flex items-start space-x-2">
|
||||
<span className="text-mulberry-600 dark:text-mulberry-400 mt-1">•</span>
|
||||
<span>Key insights into AI orchestration</span>
|
||||
</li>
|
||||
<li className="flex items-start space-x-2">
|
||||
<span className="text-mulberry-600 dark:text-mulberry-400 mt-1">•</span>
|
||||
<span>Real-world implementation strategies</span>
|
||||
</li>
|
||||
<li className="flex items-start space-x-2">
|
||||
<span className="text-mulberry-600 dark:text-mulberry-400 mt-1">•</span>
|
||||
<span>Future implications for the industry</span>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
{/* Tags */}
|
||||
<div className="mt-6 pt-4 border-t border-carbon-300 dark:border-carbon-700">
|
||||
<p className="text-xs text-carbon-600 dark:text-carbon-500 mb-2 font-medium uppercase tracking-wide">
|
||||
Topics
|
||||
</p>
|
||||
<div className="flex flex-wrap gap-1">
|
||||
{post.tags?.slice(0, 4).map((tag) => (
|
||||
<span key={tag} className="bg-carbon-200 dark:bg-carbon-800 text-carbon-700 dark:text-carbon-300 px-2 py-1 text-xs rounded font-medium">
|
||||
{tag}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
</article>
|
||||
)
|
||||
}
|
||||
@@ -9,77 +9,53 @@ interface PostCardProps {
|
||||
export default function PostCard({ post, featured = false }: PostCardProps) {
|
||||
const formattedDate = new Date(post.date).toLocaleDateString('en-US', {
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
month: 'short',
|
||||
day: 'numeric'
|
||||
})
|
||||
|
||||
// Newspaper-style card - clean, minimal, text-focused
|
||||
return (
|
||||
<article className={`group ${
|
||||
featured
|
||||
? 'bg-gradient-to-b from-sand-200 to-sand-100 dark:from-mulberry-900 to-mulberry-700 border border-carbon-200 dark:border-carbon-800 p-chorus-lg hover:border-carbon-400 dark:hover:border-mulberry-700 transition-all duration-300'
|
||||
: 'bg-gradient-to-b from-sand-100 to-sand-50 dark:from-mulberry-800 to-mulberry-800 border border-carbon-200/50 dark:border-carbon-800/50 p-chorus-lg hover:bg-carbon-50 dark:hover:bg-carbon-900 hover:border-carbon-300 dark:hover:border-carbon-700 transition-all duration-300'
|
||||
}`}>
|
||||
<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">
|
||||
<div className="mb-chorus-md">
|
||||
<div className="flex items-center justify-between mb-chorus-sm">
|
||||
<div className="blog-meta">
|
||||
<time dateTime={post.date} className="text-carbon-600 dark:text-carbon-500">
|
||||
{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>
|
||||
{post.featured && (
|
||||
<span className="blog-tag bg-mulberry-700 text-mulberry-200">
|
||||
Featured
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<h2 className={`${
|
||||
featured ? 'text-h3' : 'text-h4'
|
||||
} font-logo text-carbon-950 dark:text-carbon-100 group-hover:text-carbon-700 dark:group-hover:text-mulberry-200 transition-colors mb-chorus-lg`}>
|
||||
{post.title}
|
||||
</h2>
|
||||
|
||||
<p className="text-carbon-700 dark:text-carbon-300 leading-relaxed mb-4 line-clamp-3">
|
||||
{post.description}
|
||||
</p>
|
||||
{/* 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>
|
||||
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center space-x-2">
|
||||
<div className="w-8 h-8 bg-gradient-to-br from-mulberry-400 to-ocean-500 rounded-full flex items-center justify-center">
|
||||
<span className="text-carbon-950 font-semibold text-xs">
|
||||
{post.author?.name?.charAt(0) || 'C'}
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-carbon-950 dark:text-carbon-200 font-medium text-sm">
|
||||
{post.author?.name || 'CHORUS Team'}
|
||||
</p>
|
||||
{post.author?.role && (
|
||||
<p className="text-carbon-600 dark:text-carbon-500 text-xs">
|
||||
{post.author.role}
|
||||
</p>
|
||||
)}
|
||||
</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>
|
||||
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{post.tags?.slice(0, 3).map((tag) => (
|
||||
<span key={tag} className="blog-tag">
|
||||
{tag}
|
||||
</span>
|
||||
)) || []}
|
||||
{(post.tags?.length || 0) > 3 && (
|
||||
<span className="text-carbon-600 dark:text-carbon-500 text-xs">
|
||||
+{(post.tags?.length || 0) - 3} more
|
||||
</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>
|
||||
|
||||
@@ -229,7 +229,8 @@ export default function ThreeLogo({ className = "" }: ThreeLogoProps) {
|
||||
aspectRatio: '1 / 1',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center'
|
||||
justifyContent: 'center',
|
||||
opacity: 0.5
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user