feat(avbeat): brand-blue nav, navy card text, tagline rename, hide Industry News dates + Topics row, force-dynamic homepage
- Main nav background → brand-blue #1D4ED8 (sampled from logo emblem). - Nav link text → white with darker-blue hover bg so contrast holds. - Article card title fixed from #e0e0e0 to navy #0F172A (was unreadable on the new white surface). - Industry News card date row removed. - /news Topics filter chip row removed. - /news article hover from stark #111 to light-blue #EFF6FF tint matching the brand. - Tagline 'News & Intelligence for Pro AV, Live Production & Display Tech' renamed to 'Pro AV, Display and Live Production Tech' across Header, RSS feed, newsletter welcome template, root layout title, page title, OG/Twitter tags. - Homepage page.tsx now has `export const dynamic = 'force-dynamic'` + `revalidate = 0` so the hero (FeaturedBentoFromDb) actually re-renders against the live supabase row (previously the page was being statically prerendered which masked DB-driven hero swaps).
This commit is contained in:
@@ -141,7 +141,7 @@ export async function POST(req: NextRequest) {
|
|||||||
<!-- Header -->
|
<!-- Header -->
|
||||||
<div style="background:#111;border-bottom:2px solid #1D4ED8;padding:24px 32px;">
|
<div style="background:#111;border-bottom:2px solid #1D4ED8;padding:24px 32px;">
|
||||||
<h1 style="color:#1D4ED8;font-size:22px;margin:0;font-weight:bold;">AV Beat</h1>
|
<h1 style="color:#1D4ED8;font-size:22px;margin:0;font-weight:bold;">AV Beat</h1>
|
||||||
<p style="color:#555;font-size:12px;margin:4px 0 0;">News & Intelligence for Pro AV, Live Production & Display Tech</p>
|
<p style="color:#555;font-size:12px;margin:4px 0 0;">Pro AV, Display and Live Production Tech</p>
|
||||||
</div>
|
</div>
|
||||||
<!-- Body -->
|
<!-- Body -->
|
||||||
<div style="padding:32px;">
|
<div style="padding:32px;">
|
||||||
|
|||||||
@@ -624,7 +624,7 @@ export default function ArticleFeed() {
|
|||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<h3 className="font-heading text-[#e0e0e0] font-bold text-[0.875rem] md:text-[1rem] leading-snug mb-1 md:mb-1.5 group-hover:text-[#1D4ED8] transition-colors duration-200 line-clamp-2">
|
<h3 className="font-heading text-[#0F172A] font-bold text-[0.875rem] md:text-[1rem] leading-snug mb-1 md:mb-1.5 group-hover:text-[#1D4ED8] transition-colors duration-200 line-clamp-2">
|
||||||
<Link
|
<Link
|
||||||
href={articleHref}
|
href={articleHref}
|
||||||
{...linkProps}
|
{...linkProps}
|
||||||
@@ -644,14 +644,7 @@ export default function ArticleFeed() {
|
|||||||
<span className="font-body truncate">
|
<span className="font-body truncate">
|
||||||
By {article?.author}
|
By {article?.author}
|
||||||
</span>
|
</span>
|
||||||
{article?.date && (
|
{/* Date intentionally hidden on Industry News cards per current design direction. */}
|
||||||
<>
|
|
||||||
<span aria-hidden="true" className="text-[#333]">·</span>
|
|
||||||
<time className="font-body whitespace-nowrap" dateTime={article.date}>
|
|
||||||
{article.date}
|
|
||||||
</time>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
<Link
|
<Link
|
||||||
href={articleHref}
|
href={articleHref}
|
||||||
|
|||||||
@@ -12,8 +12,14 @@ import NewsletterSignup from "./components/NewsletterSignup";
|
|||||||
import SponsorLogoStrip from "@/components/SponsorLogoStrip";
|
import SponsorLogoStrip from "@/components/SponsorLogoStrip";
|
||||||
import CompanyMentionsHover from "@/components/CompanyMentionsHover";
|
import CompanyMentionsHover from "@/components/CompanyMentionsHover";
|
||||||
|
|
||||||
|
// force-dynamic so the homepage re-renders on every request — the hero
|
||||||
|
// component (FeaturedBentoFromDb) reads from supabase live and breaks
|
||||||
|
// when the parent page is statically prerendered.
|
||||||
|
export const dynamic = 'force-dynamic';
|
||||||
|
export const revalidate = 0;
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
title: 'AV Beat — Pro AV, Live Production & Display Tech News',
|
title: 'AV Beat — Pro AV, Display and Live Production Tech',
|
||||||
description: 'The digital platform for pro AV, live production, and display tech professionals. Breaking news, deep-dive features, and industry spotlights from InfoComm to ISE and beyond.',
|
description: 'The digital platform for pro AV, live production, and display tech professionals. Breaking news, deep-dive features, and industry spotlights from InfoComm to ISE and beyond.',
|
||||||
alternates: {
|
alternates: {
|
||||||
canonical: '/',
|
canonical: '/',
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ export const viewport: Viewport = {
|
|||||||
|
|
||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
metadataBase: new URL(process.env.NEXT_PUBLIC_SITE_URL || 'http://localhost:3000'),
|
metadataBase: new URL(process.env.NEXT_PUBLIC_SITE_URL || 'http://localhost:3000'),
|
||||||
title: 'AV Beat — Pro AV, Live Production & Display Tech News',
|
title: 'AV Beat — Pro AV, Display and Live Production Tech',
|
||||||
description: 'The digital platform for pro AV, live production, and display tech professionals. Breaking news, deep-dive features, and industry spotlights from InfoComm to ISE and beyond.',
|
description: 'The digital platform for pro AV, live production, and display tech professionals. Breaking news, deep-dive features, and industry spotlights from InfoComm to ISE and beyond.',
|
||||||
icons: {
|
icons: {
|
||||||
icon: [
|
icon: [
|
||||||
@@ -59,14 +59,14 @@ export const metadata: Metadata = {
|
|||||||
locale: 'en_US',
|
locale: 'en_US',
|
||||||
url: '/',
|
url: '/',
|
||||||
siteName: 'AV Beat',
|
siteName: 'AV Beat',
|
||||||
title: 'AV Beat — Pro AV, Live Production & Display Tech',
|
title: 'AV Beat — Pro AV, Display and Live Production Tech',
|
||||||
description: 'Breaking news and insights for pro AV, live production, and display tech professionals.',
|
description: 'Breaking news and insights for pro AV, live production, and display tech professionals.',
|
||||||
images: [
|
images: [
|
||||||
{
|
{
|
||||||
url: '/assets/images/og-image.png',
|
url: '/assets/images/og-image.png',
|
||||||
width: 1200,
|
width: 1200,
|
||||||
height: 630,
|
height: 630,
|
||||||
alt: 'AV Beat — Pro AV, Live Production & Display Tech News',
|
alt: 'AV Beat — Pro AV, Display and Live Production Tech',
|
||||||
type: 'image/png'
|
type: 'image/png'
|
||||||
}]
|
}]
|
||||||
|
|
||||||
@@ -75,7 +75,7 @@ export const metadata: Metadata = {
|
|||||||
card: 'summary_large_image',
|
card: 'summary_large_image',
|
||||||
site: '@AV Beat',
|
site: '@AV Beat',
|
||||||
creator: '@AV Beat',
|
creator: '@AV Beat',
|
||||||
title: 'AV Beat — Pro AV, Live Production & Display Tech',
|
title: 'AV Beat — Pro AV, Display and Live Production Tech',
|
||||||
description: 'Breaking news and insights for pro AV, live production, and display tech professionals.',
|
description: 'Breaking news and insights for pro AV, live production, and display tech professionals.',
|
||||||
images: ['/assets/images/og-image.png']
|
images: ['/assets/images/og-image.png']
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -226,33 +226,7 @@ export default function NewsPage({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Row 2: Category chips */}
|
{/* Topics chip row hidden per current design direction (2026-06-03). */}
|
||||||
<div className="flex items-center gap-2 flex-wrap">
|
|
||||||
<span className="text-[#555] text-[10px] font-body uppercase tracking-wider shrink-0">Topics:</span>
|
|
||||||
<div className="flex gap-1.5 flex-wrap">
|
|
||||||
{CATEGORIES.map((cat) => (
|
|
||||||
<button
|
|
||||||
key={cat}
|
|
||||||
onClick={() => setActiveCategory(cat)}
|
|
||||||
className={`px-2.5 py-1 text-[11px] font-body rounded-sm border transition-colors ${
|
|
||||||
activeCategory === cat
|
|
||||||
? "bg-[#1D4ED8] border-[#1D4ED8] text-white"
|
|
||||||
: "bg-[#FFFFFF] border-[#DCE6F2] text-[#888] hover:border-[#1D4ED8] hover:text-[#1D4ED8]"
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
{cat}
|
|
||||||
</button>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
{hasActiveFilters && (
|
|
||||||
<button
|
|
||||||
onClick={clearFilters}
|
|
||||||
className="ml-auto text-[11px] font-body text-[#555] hover:text-[#e0e0e0] underline transition-colors shrink-0"
|
|
||||||
>
|
|
||||||
Clear all
|
|
||||||
</button>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -285,7 +259,7 @@ export default function NewsPage({
|
|||||||
<Link
|
<Link
|
||||||
key={article.slug}
|
key={article.slug}
|
||||||
href={`/news/${article.slug}`}
|
href={`/news/${article.slug}`}
|
||||||
className="flex gap-4 py-5 border-b border-[#222] group hover:bg-[#111] transition-colors px-2 -mx-2">
|
className="flex gap-4 py-5 border-b border-[#DCE6F2] group hover:bg-[#EFF6FF] transition-colors px-2 -mx-2 rounded-sm">
|
||||||
<div className="flex-shrink-0 w-[160px] h-[105px] relative overflow-hidden rounded-sm">
|
<div className="flex-shrink-0 w-[160px] h-[105px] relative overflow-hidden rounded-sm">
|
||||||
<AppImage
|
<AppImage
|
||||||
src={article.image || "/assets/images/article-placeholder.jpg"}
|
src={article.image || "/assets/images/article-placeholder.jpg"}
|
||||||
@@ -299,7 +273,7 @@ export default function NewsPage({
|
|||||||
<div className="flex items-center gap-2 mb-1.5">
|
<div className="flex items-center gap-2 mb-1.5">
|
||||||
<span className="text-[#1D4ED8] font-body text-[10px] font-bold uppercase tracking-wider">{article.category || "NEWS"}</span>
|
<span className="text-[#1D4ED8] font-body text-[10px] font-bold uppercase tracking-wider">{article.category || "NEWS"}</span>
|
||||||
</div>
|
</div>
|
||||||
<h2 className="font-heading text-[#e0e0e0] text-base font-bold leading-snug mb-2 group-hover:text-[#1D4ED8] transition-colors line-clamp-2">
|
<h2 className="font-heading text-[#0F172A] text-base font-bold leading-snug mb-2 group-hover:text-[#1D4ED8] transition-colors line-clamp-2">
|
||||||
{article.title || "Untitled"}
|
{article.title || "Untitled"}
|
||||||
</h2>
|
</h2>
|
||||||
<p className="text-[#777] font-body text-sm leading-relaxed line-clamp-2">{article.excerpt || ""}</p>
|
<p className="text-[#777] font-body text-sm leading-relaxed line-clamp-2">{article.excerpt || ""}</p>
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ export async function GET() {
|
|||||||
<title>AV Beat</title>
|
<title>AV Beat</title>
|
||||||
<link>${SITE_URL}</link>
|
<link>${SITE_URL}</link>
|
||||||
<atom:link href="${SITE_URL}/rss" rel="self" type="application/rss+xml" />
|
<atom:link href="${SITE_URL}/rss" rel="self" type="application/rss+xml" />
|
||||||
<description>News & Intelligence for Pro AV, Live Production & Display Tech</description>
|
<description>Pro AV, Display and Live Production Tech</description>
|
||||||
<language>en-us</language>
|
<language>en-us</language>
|
||||||
<lastBuildDate>${new Date().toUTCString()}</lastBuildDate>
|
<lastBuildDate>${new Date().toUTCString()}</lastBuildDate>
|
||||||
${items}
|
${items}
|
||||||
|
|||||||
@@ -257,7 +257,7 @@ export default function Header() {
|
|||||||
<div className="relative">
|
<div className="relative">
|
||||||
{/* MAIN NAV */}
|
{/* MAIN NAV */}
|
||||||
<div className={`sticky top-0 z-50 transition-shadow duration-200 ${scrolled ? "shadow-nav" : ""}`}>
|
<div className={`sticky top-0 z-50 transition-shadow duration-200 ${scrolled ? "shadow-nav" : ""}`}>
|
||||||
<nav className="bg-[#F8FAFC] border-b border-[#DCE6F2]" role="navigation" aria-label="Main navigation">
|
<nav className="bg-[#1D4ED8] border-b border-[#1E3A8A] text-white" role="navigation" aria-label="Main navigation">
|
||||||
<div className="max-w-container mx-auto px-4">
|
<div className="max-w-container mx-auto px-4">
|
||||||
<div className="flex items-center justify-between h-[96px] gap-4">
|
<div className="flex items-center justify-between h-[96px] gap-4">
|
||||||
{/* Logo — links to homepage. Responsive lockup:
|
{/* Logo — links to homepage. Responsive lockup:
|
||||||
@@ -321,7 +321,7 @@ export default function Header() {
|
|||||||
key={link?.label}
|
key={link?.label}
|
||||||
href={link?.href}
|
href={link?.href}
|
||||||
ref={(el) => { navLinksRef.current[i] = el; }}
|
ref={(el) => { navLinksRef.current[i] = el; }}
|
||||||
className="px-2 py-2.5 text-sm font-body font-bold uppercase tracking-wide text-[#cccccc] hover:text-accent hover:bg-[#FFFFFF] border-b border-[#222] transition-colors focus:outline-none focus-visible:ring-1 focus-visible:ring-inset focus-visible:ring-[#1D4ED8]"
|
className="px-2 py-2.5 text-sm font-body font-bold uppercase tracking-wide text-white hover:text-white/80 hover:bg-[#1E3A8A] border-b border-[#222] transition-colors focus:outline-none focus-visible:ring-1 focus-visible:ring-inset focus-visible:ring-[#1D4ED8]"
|
||||||
onClick={() => setMobileOpen(false)}>
|
onClick={() => setMobileOpen(false)}>
|
||||||
{link?.label}
|
{link?.label}
|
||||||
</Link>
|
</Link>
|
||||||
@@ -329,7 +329,7 @@ export default function Header() {
|
|||||||
{/* Reading List mobile link */}
|
{/* Reading List mobile link */}
|
||||||
<Link
|
<Link
|
||||||
href="/reading-list"
|
href="/reading-list"
|
||||||
className="px-2 py-2.5 text-sm font-body font-bold uppercase tracking-wide text-[#cccccc] hover:text-accent hover:bg-[#FFFFFF] border-b border-[#222] transition-colors focus:outline-none focus-visible:ring-1 focus-visible:ring-inset focus-visible:ring-[#1D4ED8] flex items-center gap-2"
|
className="px-2 py-2.5 text-sm font-body font-bold uppercase tracking-wide text-white hover:text-white/80 hover:bg-[#1E3A8A] border-b border-[#222] transition-colors focus:outline-none focus-visible:ring-1 focus-visible:ring-inset focus-visible:ring-[#1D4ED8] flex items-center gap-2"
|
||||||
onClick={() => setMobileOpen(false)}>
|
onClick={() => setMobileOpen(false)}>
|
||||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" aria-hidden="true">
|
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" aria-hidden="true">
|
||||||
<path d="M19 21l-7-5-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z" />
|
<path d="M19 21l-7-5-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z" />
|
||||||
@@ -420,7 +420,7 @@ export default function Header() {
|
|||||||
<div className="max-w-container mx-auto px-4">
|
<div className="max-w-container mx-auto px-4">
|
||||||
<div className="bg-[#FFFFFF] border-b border-[#2a3a50] h-8 flex items-center justify-between px-4">
|
<div className="bg-[#FFFFFF] border-b border-[#2a3a50] h-8 flex items-center justify-between px-4">
|
||||||
<p className="text-[#999999] text-xs font-body hidden sm:block">
|
<p className="text-[#999999] text-xs font-body hidden sm:block">
|
||||||
News & Intelligence for Pro AV, Live Production & Display Tech
|
Pro AV, Display and Live Production Tech
|
||||||
</p>
|
</p>
|
||||||
<div className="flex items-center gap-3 ml-auto">
|
<div className="flex items-center gap-3 ml-auto">
|
||||||
<a href="https://linkedin.com/company/avbeat" target="_blank" rel="noopener noreferrer" aria-label="AV Beat on LinkedIn"
|
<a href="https://linkedin.com/company/avbeat" target="_blank" rel="noopener noreferrer" aria-label="AV Beat on LinkedIn"
|
||||||
|
|||||||
Reference in New Issue
Block a user