Brand cleanup: swap remaining user-facing BB strings + accent blue → AV orange

Hit pages we didn't get the first pass: rss, gear, show-coverage,
articles/[slug], contributor, manufacturers, login, client-login, terms,
dashboard/show-calendar, and team-page derive helpers (domain + comment).
This commit is contained in:
Ryan Salazar
2026-06-01 15:39:09 +00:00
parent c9b85b79b7
commit dd93a74bdf
14 changed files with 97 additions and 97 deletions

View File

@@ -8,8 +8,8 @@ export const dynamic = "force-dynamic";
export const revalidate = 600; export const revalidate = 600;
export const metadata = { export const metadata = {
title: "Our team — Broadcast Beat", title: "Our team — AV Beat",
description: "Meet the Broadcast Beat team — editorial staff plus accounts and support, covering broadcast, streaming, and post-production.", description: "Meet the AV Beat team — editorial staff plus accounts and support, covering the convergence of pro AV and IT.",
}; };
interface Persona { interface Persona {
@@ -77,11 +77,11 @@ export default async function TeamPage() {
.map((w) => w.charAt(0).toUpperCase()) .map((w) => w.charAt(0).toUpperCase())
.join(""); .join("");
// Derive @broadcastbeat.com email from the persona slug. Real mailboxes // Derive @avbeat.com email from the persona slug. Real mailboxes
// are set up centrally; this is the authoring address surfaced to readers. // are set up centrally; this is the authoring address surfaced to readers.
const editorialEmail = (p: Persona): { user: string; domain: string } | null => { const editorialEmail = (p: Persona): { user: string; domain: string } | null => {
if (!p.slug) return null; if (!p.slug) return null;
return { user: p.slug.replace(/-/g, "."), domain: "broadcastbeat.com" }; return { user: p.slug.replace(/-/g, "."), domain: "avbeat.com" };
}; };
const splitEmail = (email: string): { user: string; domain: string } | null => { const splitEmail = (email: string): { user: string; domain: string } | null => {

View File

@@ -229,9 +229,9 @@ export default function ArticleDetailClient({ article, relatedArticles, relatedF
{/* DO NOT OVERRIDE — article breadcrumb and back navigation */} {/* DO NOT OVERRIDE — article breadcrumb and back navigation */}
<div className="bg-[#0d0d0d] border-b border-[#1a1a1a]"> <div className="bg-[#0d0d0d] border-b border-[#1a1a1a]">
<div className="max-w-container mx-auto px-4 py-2.5 flex items-center gap-2 text-xs font-body text-[#555]"> <div className="max-w-container mx-auto px-4 py-2.5 flex items-center gap-2 text-xs font-body text-[#555]">
<Link href="/home-page" className="hover:text-[#3b82f6] transition-colors">Home</Link> <Link href="/home-page" className="hover:text-[#E67E22] transition-colors">Home</Link>
<span>/</span> <span>/</span>
<Link href={sectionHref} className="hover:text-[#3b82f6] transition-colors">{sectionLabel}</Link> <Link href={sectionHref} className="hover:text-[#E67E22] transition-colors">{sectionLabel}</Link>
<span>/</span> <span>/</span>
<span className="text-[#888] truncate max-w-[300px]">{article.title}</span> <span className="text-[#888] truncate max-w-[300px]">{article.title}</span>
</div> </div>
@@ -245,7 +245,7 @@ export default function ArticleDetailClient({ article, relatedArticles, relatedF
{/* Article Header */} {/* Article Header */}
<div className="mb-8"> <div className="mb-8">
<div className="flex items-center gap-3 mb-4"> <div className="flex items-center gap-3 mb-4">
<Link href={sectionHref} className="text-xs font-bold uppercase tracking-widest text-[#3b82f6] hover:underline"> <Link href={sectionHref} className="text-xs font-bold uppercase tracking-widest text-[#E67E22] hover:underline">
{article.category} {article.category}
</Link> </Link>
<span className="text-xs text-[#777]">{article.date}</span> <span className="text-xs text-[#777]">{article.date}</span>
@@ -271,7 +271,7 @@ export default function ArticleDetailClient({ article, relatedArticles, relatedF
<div> <div>
<Link <Link
href={`/authors/${article.authorSlug}`} href={`/authors/${article.authorSlug}`}
className="font-heading font-bold text-sm hover:text-[#3b82f6] transition-colors text-[#e0e0e0]"> className="font-heading font-bold text-sm hover:text-[#E67E22] transition-colors text-[#e0e0e0]">
{article.author} {article.author}
</Link> </Link>
<p className="font-body text-xs text-[#777]">{article.authorTitle}</p> <p className="font-body text-xs text-[#777]">{article.authorTitle}</p>
@@ -281,12 +281,12 @@ export default function ArticleDetailClient({ article, relatedArticles, relatedF
{(() => { {(() => {
const articleUrl = typeof window !== "undefined" const articleUrl = typeof window !== "undefined"
? window.location.href ? window.location.href
: `https://broadcastbeat.com/articles/${article.slug}`; : `https://avbeat.com/articles/${article.slug}`;
return ( return (
<> <>
<a href={`mailto:?subject=${encodeURIComponent(article.title)}&body=${encodeURIComponent(articleUrl)}`} <a href={`mailto:?subject=${encodeURIComponent(article.title)}&body=${encodeURIComponent(articleUrl)}`}
aria-label="Share via email" title="Email" aria-label="Share via email" title="Email"
className="flex items-center justify-center w-8 h-8 rounded-sm text-[#888] hover:text-[#3b82f6] hover:bg-[#1a1a1a] transition-colors focus:outline-none focus-visible:ring-1 focus-visible:ring-[#3b82f6]"> className="flex items-center justify-center w-8 h-8 rounded-sm text-[#888] hover:text-[#E67E22] hover:bg-[#1a1a1a] transition-colors focus:outline-none focus-visible:ring-1 focus-visible:ring-[#E67E22]">
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" aria-hidden="true"> <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" aria-hidden="true">
<rect x="2" y="4" width="20" height="16" rx="2" /> <rect x="2" y="4" width="20" height="16" rx="2" />
<path d="m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7" /> <path d="m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7" />
@@ -297,7 +297,7 @@ export default function ArticleDetailClient({ article, relatedArticles, relatedF
className="flex items-center justify-center w-8 h-8 rounded-sm text-[#888] hover:text-[#0a66c2] hover:bg-[#1a1a1a] transition-colors"> className="flex items-center justify-center w-8 h-8 rounded-sm text-[#888] hover:text-[#0a66c2] hover:bg-[#1a1a1a] transition-colors">
<svg width="15" height="15" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M19 0h-14C2.24 0 0 2.24 0 5v14c0 2.76 2.24 5 5 5h14c2.76 0 5-2.24 5-5V5c0-2.76-2.24-5-5-5zM8 19H5V8h3v11zM6.5 6.73a1.75 1.75 0 1 1 0-3.5 1.75 1.75 0 0 1 0 3.5zM20 19h-3v-5.6c0-3.37-4-3.12-4 0V19h-3V8h3v1.77c1.4-2.59 7-2.78 7 2.48V19z"/></svg> <svg width="15" height="15" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M19 0h-14C2.24 0 0 2.24 0 5v14c0 2.76 2.24 5 5 5h14c2.76 0 5-2.24 5-5V5c0-2.76-2.24-5-5-5zM8 19H5V8h3v11zM6.5 6.73a1.75 1.75 0 1 1 0-3.5 1.75 1.75 0 0 1 0 3.5zM20 19h-3v-5.6c0-3.37-4-3.12-4 0V19h-3V8h3v1.77c1.4-2.59 7-2.78 7 2.48V19z"/></svg>
</a> </a>
<a href={`https://twitter.com/intent/tweet?url=${encodeURIComponent(articleUrl)}&text=${encodeURIComponent(article.title)}&via=BroadcastBeat`} <a href={`https://twitter.com/intent/tweet?url=${encodeURIComponent(articleUrl)}&text=${encodeURIComponent(article.title)}&via=AVBeat`}
target="_blank" rel="noopener noreferrer" aria-label="Share on X" title="X (Twitter)" target="_blank" rel="noopener noreferrer" aria-label="Share on X" title="X (Twitter)"
className="flex items-center justify-center w-8 h-8 rounded-sm text-[#888] hover:text-white hover:bg-[#1a1a1a] transition-colors"> className="flex items-center justify-center w-8 h-8 rounded-sm text-[#888] hover:text-white hover:bg-[#1a1a1a] transition-colors">
<svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"/></svg> <svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"/></svg>
@@ -320,7 +320,7 @@ export default function ArticleDetailClient({ article, relatedArticles, relatedF
<button type="button" <button type="button"
onClick={async () => { try { await navigator.clipboard.writeText(articleUrl); } catch {} }} onClick={async () => { try { await navigator.clipboard.writeText(articleUrl); } catch {} }}
aria-label="Copy article link" title="Copy link" aria-label="Copy article link" title="Copy link"
className="flex items-center justify-center w-8 h-8 rounded-sm text-[#888] hover:text-[#3b82f6] hover:bg-[#1a1a1a] transition-colors"> className="flex items-center justify-center w-8 h-8 rounded-sm text-[#888] hover:text-[#E67E22] hover:bg-[#1a1a1a] transition-colors">
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" aria-hidden="true"> <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" aria-hidden="true">
<path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/> <path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/>
<path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/> <path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/>
@@ -334,7 +334,7 @@ export default function ArticleDetailClient({ article, relatedArticles, relatedF
onClick={handleSaveToReadingList} onClick={handleSaveToReadingList}
disabled={savingState !== "idle"} disabled={savingState !== "idle"}
aria-label={isSaved ? "Remove from reading list" : "Save to reading list"} aria-label={isSaved ? "Remove from reading list" : "Save to reading list"}
className="text-xs font-bold uppercase tracking-widest text-[#3b82f6] hover:text-blue-300 disabled:opacity-50 transition-colors focus:outline-none focus-visible:ring-1 focus-visible:ring-[#3b82f6]"> className="text-xs font-bold uppercase tracking-widest text-[#E67E22] hover:text-blue-300 disabled:opacity-50 transition-colors focus:outline-none focus-visible:ring-1 focus-visible:ring-[#E67E22]">
{savingState === "saving" ? "Saving..." : savingState === "removing" ? "Removing..." : isSaved ? "✓ Saved" : "Save"} {savingState === "saving" ? "Saving..." : savingState === "removing" ? "Removing..." : isSaved ? "✓ Saved" : "Save"}
</button> </button>
</div> </div>
@@ -368,7 +368,7 @@ export default function ArticleDetailClient({ article, relatedArticles, relatedF
{article.tags.map((tag) => ( {article.tags.map((tag) => (
<span <span
key={tag} key={tag}
className="px-3 py-1 text-xs font-body bg-[#1a1a1a] border border-[#2a2a2a] text-[#888] hover:border-[#3b82f6] hover:text-[#3b82f6] transition-colors rounded-sm cursor-default"> className="px-3 py-1 text-xs font-body bg-[#1a1a1a] border border-[#2a2a2a] text-[#888] hover:border-[#E67E22] hover:text-[#E67E22] transition-colors rounded-sm cursor-default">
{tag} {tag}
</span> </span>
))} ))}
@@ -380,7 +380,7 @@ export default function ArticleDetailClient({ article, relatedArticles, relatedF
<div className="pt-6 border-t border-[#222]"> <div className="pt-6 border-t border-[#222]">
<Link <Link
href={sectionHref} href={sectionHref}
className="inline-flex items-center gap-2 text-[#3b82f6] font-body text-sm hover:underline focus:outline-none focus-visible:ring-1 focus-visible:ring-[#3b82f6]"> className="inline-flex items-center gap-2 text-[#E67E22] font-body text-sm hover:underline focus:outline-none focus-visible:ring-1 focus-visible:ring-[#E67E22]">
<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">
<polyline points="15 18 9 12 15 6" /> <polyline points="15 18 9 12 15 6" />
</svg> </svg>
@@ -398,7 +398,7 @@ export default function ArticleDetailClient({ article, relatedArticles, relatedF
{/* Related Articles */} {/* Related Articles */}
{/* DO NOT OVERRIDE — related articles sidebar */} {/* DO NOT OVERRIDE — related articles sidebar */}
<div className="bg-[#111] border border-[#222] p-5"> <div className="bg-[#111] border border-[#222] p-5">
<h3 className="font-body font-bold text-xs text-[#3b82f6] uppercase tracking-widest mb-4 pb-2 border-b border-[#222]"> <h3 className="font-body font-bold text-xs text-[#E67E22] uppercase tracking-widest mb-4 pb-2 border-b border-[#222]">
Related Articles Related Articles
</h3> </h3>
<div className="space-y-4"> <div className="space-y-4">
@@ -417,10 +417,10 @@ export default function ArticleDetailClient({ article, relatedArticles, relatedF
/> />
</div> </div>
<div className="flex-1 min-w-0"> <div className="flex-1 min-w-0">
<p className="text-[#3b82f6] font-body text-[9px] font-bold uppercase tracking-wider mb-0.5"> <p className="text-[#E67E22] font-body text-[9px] font-bold uppercase tracking-wider mb-0.5">
{related.category} {related.category}
</p> </p>
<p className="font-heading text-[#e0e0e0] text-xs font-bold group-hover:text-[#3b82f6] transition-colors line-clamp-2 leading-snug"> <p className="font-heading text-[#e0e0e0] text-xs font-bold group-hover:text-[#E67E22] transition-colors line-clamp-2 leading-snug">
{related.title} {related.title}
</p> </p>
</div> </div>
@@ -435,19 +435,19 @@ export default function ArticleDetailClient({ article, relatedArticles, relatedF
recently-active threads so the box is never empty. */} recently-active threads so the box is never empty. */}
{relatedForumThreads.length > 0 && ( {relatedForumThreads.length > 0 && (
<div className="bg-[#111] border border-[#222] p-5"> <div className="bg-[#111] border border-[#222] p-5">
<h3 className="font-body font-bold text-xs text-[#3b82f6] uppercase tracking-widest mb-4 pb-2 border-b border-[#222]"> <h3 className="font-body font-bold text-xs text-[#E67E22] uppercase tracking-widest mb-4 pb-2 border-b border-[#222]">
Related Forum Posts Related Forum Posts
</h3> </h3>
<ul className="space-y-3.5"> <ul className="space-y-3.5">
{relatedForumThreads.map((t) => ( {relatedForumThreads.map((t) => (
<li key={t.id}> <li key={t.id}>
<Link href={`/forum/thread/${t.id}`} className="group block"> <Link href={`/forum/thread/${t.id}`} className="group block">
<p className="font-heading text-[#e0e0e0] text-xs font-bold group-hover:text-[#3b82f6] transition-colors line-clamp-2 leading-snug"> <p className="font-heading text-[#e0e0e0] text-xs font-bold group-hover:text-[#E67E22] transition-colors line-clamp-2 leading-snug">
{t.title} {t.title}
</p> </p>
<p className="flex items-center gap-2 mt-1 text-[10px] text-[#666]"> <p className="flex items-center gap-2 mt-1 text-[10px] text-[#666]">
{t.category_name && ( {t.category_name && (
<span className="text-[#3b82f6] font-body font-bold uppercase tracking-wider"> <span className="text-[#E67E22] font-body font-bold uppercase tracking-wider">
{t.category_name} {t.category_name}
</span> </span>
)} )}
@@ -461,7 +461,7 @@ export default function ArticleDetailClient({ article, relatedArticles, relatedF
</ul> </ul>
<Link <Link
href="/forum" href="/forum"
className="block mt-4 pt-3 border-t border-[#222] text-[11px] text-[#3b82f6] hover:underline font-body font-semibold uppercase tracking-wider" className="block mt-4 pt-3 border-t border-[#222] text-[11px] text-[#E67E22] hover:underline font-body font-semibold uppercase tracking-wider"
> >
Browse all forum threads Browse all forum threads
</Link> </Link>
@@ -479,7 +479,7 @@ export default function ArticleDetailClient({ article, relatedArticles, relatedF
<div <div
role="status" role="status"
aria-live="polite" aria-live="polite"
className="fixed bottom-4 right-4 bg-[#1a1a1a] border border-[#3b82f6] text-white px-4 py-3 rounded-sm text-sm font-body shadow-lg z-50"> className="fixed bottom-4 right-4 bg-[#1a1a1a] border border-[#E67E22] text-white px-4 py-3 rounded-sm text-sm font-body shadow-lg z-50">
{saveToast} {saveToast}
</div> </div>
)} )}

View File

@@ -17,7 +17,7 @@ interface PageProps {
} }
const SITE_URL = const SITE_URL =
process.env.NEXT_PUBLIC_SITE_URL || "https://broadcastbeat.com"; process.env.NEXT_PUBLIC_SITE_URL || "https://avbeat.com";
function toIso(d: string | null | undefined): string { function toIso(d: string | null | undefined): string {
if (!d) return new Date().toISOString(); if (!d) return new Date().toISOString();
@@ -70,7 +70,7 @@ export async function generateMetadata({ params }: PageProps): Promise<Metadata>
title: article.title, title: article.title,
description: article.excerpt, description: article.excerpt,
images: [article.image], images: [article.image],
creator: "@Broadcast Beat", creator: "@AV Beat",
}, },
}; };
} }
@@ -98,7 +98,7 @@ export default async function ArticlePage({ params }: PageProps) {
author: { "@type": "Person", name: article.author }, author: { "@type": "Person", name: article.author },
publisher: { publisher: {
"@type": "Organization", "@type": "Organization",
name: "Broadcast Beat", name: "AV Beat",
logo: { "@type": "ImageObject", url: `${SITE_URL}/assets/images/logo.png` }, logo: { "@type": "ImageObject", url: `${SITE_URL}/assets/images/logo.png` },
}, },
datePublished: toIso(article.date), datePublished: toIso(article.date),

View File

@@ -62,7 +62,7 @@ export default function ClientLoginPage() {
<div className="min-h-screen bg-gradient-to-br from-blue-50 to-indigo-100 flex items-center justify-center p-4"> <div className="min-h-screen bg-gradient-to-br from-blue-50 to-indigo-100 flex items-center justify-center p-4">
<div className="bg-white rounded-lg shadow-xl p-8 w-full max-w-md"> <div className="bg-white rounded-lg shadow-xl p-8 w-full max-w-md">
<div className="mb-8"> <div className="mb-8">
<h1 className="text-3xl font-bold text-gray-900 mb-2">Broadcast Beat</h1> <h1 className="text-3xl font-bold text-gray-900 mb-2">AV Beat</h1>
<p className="text-gray-600">Contributor Portal</p> <p className="text-gray-600">Contributor Portal</p>
</div> </div>

View File

@@ -62,7 +62,7 @@ const AV_CATEGORIES = [
]; ];
const SITE_CONFIG = { const SITE_CONFIG = {
1: { name: 'Broadcast Beat', badge: 'BB', color: '#0ea5e9', bgClass: 'bg-[#0ea5e9]/10', textClass: 'text-[#0ea5e9]', borderClass: 'border-[#0ea5e9]/30' }, 1: { name: 'AV Beat', badge: 'BB', color: '#0ea5e9', bgClass: 'bg-[#0ea5e9]/10', textClass: 'text-[#0ea5e9]', borderClass: 'border-[#0ea5e9]/30' },
2: { name: 'AV Beat', badge: 'AV', color: '#f97316', bgClass: 'bg-[#f97316]/10', textClass: 'text-[#f97316]', borderClass: 'border-[#f97316]/30' }, 2: { name: 'AV Beat', badge: 'AV', color: '#f97316', bgClass: 'bg-[#f97316]/10', textClass: 'text-[#f97316]', borderClass: 'border-[#f97316]/30' },
}; };
@@ -162,7 +162,7 @@ export default function ContributorDashboard() {
}); });
const data = await res.json(); const data = await res.json();
if (data.scope === 'broadcast' && data.confidence > 0.75) { if (data.scope === 'broadcast' && data.confidence > 0.75) {
setScopeWarning('This content may be better suited for Broadcast Beat. AV Beat covers professional AV integration. Your post has been flagged for editorial review.'); setScopeWarning('This content may be better suited for AV Beat. AV Beat covers professional AV integration. Your post has been flagged for editorial review.');
} else { } else {
setScopeWarning(null); setScopeWarning(null);
} }
@@ -194,7 +194,7 @@ export default function ContributorDashboard() {
const data = await res.json(); const data = await res.json();
if (!res.ok) { if (!res.ok) {
if (data.blocked) { if (data.blocked) {
showNotification('error', 'This post could not be submitted. Please contact the editorial team at editor@broadcastbeat.com for assistance.'); showNotification('error', 'This post could not be submitted. Please contact the editorial team at editor@avbeat.com for assistance.');
} else { } else {
showNotification('error', data.error || 'Failed to submit post.'); showNotification('error', data.error || 'Failed to submit post.');
} }
@@ -361,7 +361,7 @@ export default function ContributorDashboard() {
<div className="text-sm font-semibold text-white mb-3">Publish To</div> <div className="text-sm font-semibold text-white mb-3">Publish To</div>
<div className="flex gap-3"> <div className="flex gap-3">
{[ {[
{ id: 1, name: 'Broadcast Beat', badge: 'BB', color: '#0ea5e9' }, { id: 1, name: 'AV Beat', badge: 'BB', color: '#0ea5e9' },
{ id: 2, name: 'AV Beat', badge: 'AV', color: '#f97316' }, { id: 2, name: 'AV Beat', badge: 'AV', color: '#f97316' },
].map(site => ( ].map(site => (
<button <button

View File

@@ -67,7 +67,7 @@ type TabType = 'calendar' | 'queue' | 'exhibitors' | 'style-profiles' | 'setting
type SiteFilter = '' | '1' | '2'; type SiteFilter = '' | '1' | '2';
const SITE_CONFIG = { const SITE_CONFIG = {
1: { name: 'Broadcast Beat', badge: 'BB', color: '#0ea5e9', bgClass: 'bg-[#0ea5e9]/10', textClass: 'text-[#0ea5e9]' }, 1: { name: 'AV Beat', badge: 'BB', color: '#0ea5e9', bgClass: 'bg-[#0ea5e9]/10', textClass: 'text-[#0ea5e9]' },
2: { name: 'AV Beat', badge: 'AV', color: '#f97316', bgClass: 'bg-[#f97316]/10', textClass: 'text-[#f97316]' }, 2: { name: 'AV Beat', badge: 'AV', color: '#f97316', bgClass: 'bg-[#f97316]/10', textClass: 'text-[#f97316]' },
}; };
@@ -256,7 +256,7 @@ export default function ShowCalendarPage() {
if (loading) { if (loading) {
return ( return (
<div className="min-h-screen bg-[#0a0a0a] flex items-center justify-center"> <div className="min-h-screen bg-[#0a0a0a] flex items-center justify-center">
<div className="w-8 h-8 border-2 border-[#3b82f6] border-t-transparent rounded-full animate-spin" /> <div className="w-8 h-8 border-2 border-[#E67E22] border-t-transparent rounded-full animate-spin" />
</div> </div>
); );
} }
@@ -289,12 +289,12 @@ export default function ShowCalendarPage() {
<Link href="/admin" className="text-[#555] hover:text-white text-sm transition-colors"> Dashboard</Link> <Link href="/admin" className="text-[#555] hover:text-white text-sm transition-colors"> Dashboard</Link>
</div> </div>
<h1 className="text-xl font-bold text-white">Show Calendar Engine</h1> <h1 className="text-xl font-bold text-white">Show Calendar Engine</h1>
<p className="text-[#555] text-sm mt-0.5">Broadcast Beat + AV Beat Global Show Coverage</p> <p className="text-[#555] text-sm mt-0.5">AV Beat + AV Beat Global Show Coverage</p>
</div> </div>
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
<button <button
onClick={() => { setEditingEvent({ site_id: 1, year: new Date().getFullYear(), seo_tier: 3, event_type: 'trade_show' }); setShowEventModal(true); }} onClick={() => { setEditingEvent({ site_id: 1, year: new Date().getFullYear(), seo_tier: 3, event_type: 'trade_show' }); setShowEventModal(true); }}
className="px-3 py-1.5 bg-[#3b82f6] hover:bg-blue-500 text-white text-sm rounded-lg transition-colors" className="px-3 py-1.5 bg-[#E67E22] hover:bg-blue-500 text-white text-sm rounded-lg transition-colors"
> >
+ Add Event + Add Event
</button> </button>
@@ -316,11 +316,11 @@ export default function ShowCalendarPage() {
onClick={() => setSiteFilter(s)} onClick={() => setSiteFilter(s)}
className={`px-3 py-1 rounded text-xs font-medium transition-colors ${ className={`px-3 py-1 rounded text-xs font-medium transition-colors ${
siteFilter === s siteFilter === s
? 'bg-[#3b82f6] text-white' ? 'bg-[#E67E22] text-white'
: 'bg-[#1a1a1a] text-[#888] hover:text-white border border-[#333]' : 'bg-[#1a1a1a] text-[#888] hover:text-white border border-[#333]'
}`} }`}
> >
{s === '' ? 'All Sites' : s === '1' ? '🔵 Broadcast Beat' : '🟠 AV Beat'} {s === '' ? 'All Sites' : s === '1' ? '🔵 AV Beat' : '🟠 AV Beat'}
</button> </button>
))} ))}
</div> </div>
@@ -333,7 +333,7 @@ export default function ShowCalendarPage() {
onClick={() => setActiveTab(tab.id)} onClick={() => setActiveTab(tab.id)}
className={`px-4 py-2 text-sm font-medium transition-colors border-b-2 -mb-px ${ className={`px-4 py-2 text-sm font-medium transition-colors border-b-2 -mb-px ${
activeTab === tab.id activeTab === tab.id
? 'border-[#3b82f6] text-white' ? 'border-[#E67E22] text-white'
: 'border-transparent text-[#666] hover:text-white' : 'border-transparent text-[#666] hover:text-white'
}`} }`}
> >
@@ -347,7 +347,7 @@ export default function ShowCalendarPage() {
<div className="max-w-7xl mx-auto px-4 py-6"> <div className="max-w-7xl mx-auto px-4 py-6">
{loadingData ? ( {loadingData ? (
<div className="flex items-center justify-center py-20"> <div className="flex items-center justify-center py-20">
<div className="w-8 h-8 border-2 border-[#3b82f6] border-t-transparent rounded-full animate-spin" /> <div className="w-8 h-8 border-2 border-[#E67E22] border-t-transparent rounded-full animate-spin" />
</div> </div>
) : ( ) : (
<> <>
@@ -383,7 +383,7 @@ export default function ShowCalendarPage() {
<span>Engine: {formatDate(event.story_engine_start_date)} {formatDate(event.story_engine_end_date)}</span> <span>Engine: {formatDate(event.story_engine_start_date)} {formatDate(event.story_engine_end_date)}</span>
{event.official_site && ( {event.official_site && (
<a href={`https://${event.official_site}`} target="_blank" rel="noopener noreferrer" <a href={`https://${event.official_site}`} target="_blank" rel="noopener noreferrer"
className="text-[#3b82f6] hover:underline">{event.official_site}</a> className="text-[#E67E22] hover:underline">{event.official_site}</a>
)} )}
</div> </div>
<div className="flex items-center gap-3 mt-2 text-xs text-[#555]"> <div className="flex items-center gap-3 mt-2 text-xs text-[#555]">
@@ -440,7 +440,7 @@ export default function ShowCalendarPage() {
onClick={() => setQueueStatus(s)} onClick={() => setQueueStatus(s)}
className={`px-3 py-1 rounded text-xs font-medium transition-colors ${ className={`px-3 py-1 rounded text-xs font-medium transition-colors ${
queueStatus === s queueStatus === s
? 'bg-[#3b82f6] text-white' ? 'bg-[#E67E22] text-white'
: 'bg-[#1a1a1a] text-[#888] hover:text-white border border-[#333]' : 'bg-[#1a1a1a] text-[#888] hover:text-white border border-[#333]'
}`} }`}
> >
@@ -643,7 +643,7 @@ export default function ShowCalendarPage() {
</div> </div>
<div className="p-3 bg-[#0a0a0a] rounded-lg border border-[#1a1a1a]"> <div className="p-3 bg-[#0a0a0a] rounded-lg border border-[#1a1a1a]">
<p className="text-white font-medium mb-1">Pen Name Rosters</p> <p className="text-white font-medium mb-1">Pen Name Rosters</p>
<p className="mb-2"><strong className="text-[#aaa]">Broadcast Beat (12 writers):</strong> Michael Strand, David Harlow, Karen Fielding, James Mercer (primary NAB), Peter Calloway, Sandra Voss, Brian Kowalski, Laura Pennington, Thomas Reeves, Christine Vale, Marcus Webb, Ellen Forsythe</p> <p className="mb-2"><strong className="text-[#aaa]">AV Beat (12 writers):</strong> Michael Strand, David Harlow, Karen Fielding, James Mercer (primary NAB), Peter Calloway, Sandra Voss, Brian Kowalski, Laura Pennington, Thomas Reeves, Christine Vale, Marcus Webb, Ellen Forsythe</p>
<p><strong className="text-[#aaa]">AV Beat (7 writers):</strong> Rex Chandler, Dana Flux, Derek Wainwright, Sloane Rigging, Chip Crosspoint, Blair Presenter, Jordan Lumen</p> <p><strong className="text-[#aaa]">AV Beat (7 writers):</strong> Rex Chandler, Dana Flux, Derek Wainwright, Sloane Rigging, Chip Crosspoint, Blair Presenter, Jordan Lumen</p>
</div> </div>
<div className="p-3 bg-[#0a0a0a] rounded-lg border border-[#1a1a1a]"> <div className="p-3 bg-[#0a0a0a] rounded-lg border border-[#1a1a1a]">
@@ -689,7 +689,7 @@ export default function ShowCalendarPage() {
onChange={e => setEditingEvent(prev => ({ ...prev, site_id: parseInt(e.target.value) }))} onChange={e => setEditingEvent(prev => ({ ...prev, site_id: parseInt(e.target.value) }))}
className="w-full bg-[#0a0a0a] border border-[#333] text-white text-sm rounded px-3 py-2" className="w-full bg-[#0a0a0a] border border-[#333] text-white text-sm rounded px-3 py-2"
> >
<option value={1}>Broadcast Beat</option> <option value={1}>AV Beat</option>
<option value={2}>AV Beat</option> <option value={2}>AV Beat</option>
</select> </select>
</div> </div>
@@ -779,7 +779,7 @@ export default function ShowCalendarPage() {
<button <button
type="submit" type="submit"
disabled={actionLoading === 'save-event'} disabled={actionLoading === 'save-event'}
className="flex-1 py-2 bg-[#3b82f6] hover:bg-blue-500 text-white text-sm rounded-lg transition-colors disabled:opacity-50" className="flex-1 py-2 bg-[#E67E22] hover:bg-blue-500 text-white text-sm rounded-lg transition-colors disabled:opacity-50"
> >
{actionLoading === 'save-event' ? 'Saving...' : 'Save Event'} {actionLoading === 'save-event' ? 'Saving...' : 'Save Event'}
</button> </button>
@@ -857,7 +857,7 @@ export default function ShowCalendarPage() {
<button <button
type="submit" type="submit"
disabled={actionLoading === 'generate'} disabled={actionLoading === 'generate'}
className="flex-1 py-2 bg-[#3b82f6] hover:bg-blue-500 text-white text-sm rounded-lg transition-colors disabled:opacity-50" className="flex-1 py-2 bg-[#E67E22] hover:bg-blue-500 text-white text-sm rounded-lg transition-colors disabled:opacity-50"
> >
{actionLoading === 'generate' ? 'Generating...' : 'Generate Story'} {actionLoading === 'generate' ? 'Generating...' : 'Generate Story'}
</button> </button>

View File

@@ -12,11 +12,11 @@ import SidebarAdStack from "@/components/SidebarAdStack";
export const revalidate = 1800; export const revalidate = 1800;
export const metadata: Metadata = { export const metadata: Metadata = {
title: "Production Gear & Reviews — Broadcast Beat", title: "Production Gear & Reviews — AV Beat",
description: "In-depth reviews and coverage of broadcast cameras, audio gear, production equipment, and professional media technology.", description: "In-depth reviews and coverage of broadcast cameras, audio gear, production equipment, and professional media technology.",
alternates: { canonical: "/gear" }, alternates: { canonical: "/gear" },
openGraph: { openGraph: {
title: "Production Gear & Reviews — Broadcast Beat", title: "Production Gear & Reviews — AV Beat",
description: "In-depth reviews and coverage of broadcast cameras, audio gear, production equipment, and professional media technology.", description: "In-depth reviews and coverage of broadcast cameras, audio gear, production equipment, and professional media technology.",
url: "/gear", url: "/gear",
type: "website", type: "website",
@@ -49,7 +49,7 @@ export default async function GearPage() {
<Link <Link
key={article.slug} key={article.slug}
href={`/articles/${article.slug}`} href={`/articles/${article.slug}`}
className="bg-[#111] border border-[#222] overflow-hidden group hover:border-[#3b82f6] transition-colors"> className="bg-[#111] border border-[#222] overflow-hidden group hover:border-[#E67E22] transition-colors">
<div className="relative h-[200px] overflow-hidden"> <div className="relative h-[200px] overflow-hidden">
<AppImage <AppImage
src={article.image} src={article.image}
@@ -59,7 +59,7 @@ export default async function GearPage() {
sizes="(max-width: 768px) 100vw, (max-width: 1024px) 50vw, 33vw" sizes="(max-width: 768px) 100vw, (max-width: 1024px) 50vw, 33vw"
/> />
<div className="absolute top-2 left-2"> <div className="absolute top-2 left-2">
<span className="bg-[#3b82f6] text-white font-body text-[9px] font-bold px-2 py-0.5 tracking-wider uppercase"> <span className="bg-[#E67E22] text-white font-body text-[9px] font-bold px-2 py-0.5 tracking-wider uppercase">
{article.category} {article.category}
</span> </span>
</div> </div>
@@ -74,7 +74,7 @@ export default async function GearPage() {
)} )}
<span className="text-[#555] font-body text-[11px]">{article.readTime}</span> <span className="text-[#555] font-body text-[11px]">{article.readTime}</span>
</div> </div>
<h2 className="font-heading text-[#e0e0e0] text-sm font-bold leading-snug mb-2 group-hover:text-[#3b82f6] transition-colors line-clamp-3"> <h2 className="font-heading text-[#e0e0e0] text-sm font-bold leading-snug mb-2 group-hover:text-[#E67E22] transition-colors line-clamp-3">
{article.title} {article.title}
</h2> </h2>
<p className="text-[#666] font-body text-xs leading-relaxed line-clamp-2">{article.excerpt}</p> <p className="text-[#666] font-body text-xs leading-relaxed line-clamp-2">{article.excerpt}</p>

View File

@@ -53,7 +53,7 @@ function LoginInner() {
<main className="min-h-screen bg-[#111111]"> <main className="min-h-screen bg-[#111111]">
<div className="max-w-md mx-auto px-4 py-12"> <div className="max-w-md mx-auto px-4 py-12">
<div className="text-center mb-6"> <div className="text-center mb-6">
<h1 className="text-2xl font-heading font-bold text-white">Sign in to Broadcast Beat</h1> <h1 className="text-2xl font-heading font-bold text-white">Sign in to AV Beat</h1>
<p className="text-[#888] font-body text-sm mt-1"> <p className="text-[#888] font-body text-sm mt-1">
Editor and admin access. Forum members can also sign in here. Editor and admin access. Forum members can also sign in here.
</p> </p>
@@ -77,7 +77,7 @@ function LoginInner() {
onChange={(e) => setEmail(e.target.value)} onChange={(e) => setEmail(e.target.value)}
autoComplete="email" autoComplete="email"
required required
className="w-full bg-[#0d0d0d] border border-[#2a2a2a] rounded-lg px-3 py-2 text-white font-body text-sm focus:outline-none focus:border-[#3b82f6]" className="w-full bg-[#0d0d0d] border border-[#2a2a2a] rounded-lg px-3 py-2 text-white font-body text-sm focus:outline-none focus:border-[#E67E22]"
/> />
</div> </div>
<div> <div>
@@ -90,19 +90,19 @@ function LoginInner() {
onChange={(e) => setPassword(e.target.value)} onChange={(e) => setPassword(e.target.value)}
autoComplete="current-password" autoComplete="current-password"
required required
className="w-full bg-[#0d0d0d] border border-[#2a2a2a] rounded-lg px-3 py-2 text-white font-body text-sm focus:outline-none focus:border-[#3b82f6]" className="w-full bg-[#0d0d0d] border border-[#2a2a2a] rounded-lg px-3 py-2 text-white font-body text-sm focus:outline-none focus:border-[#E67E22]"
/> />
</div> </div>
<button <button
type="submit" type="submit"
disabled={loading} disabled={loading}
className="w-full bg-[#3b82f6] hover:bg-[#2563eb] disabled:opacity-50 text-white font-body font-semibold py-2 rounded-lg transition-colors" className="w-full bg-[#E67E22] hover:bg-[#C8651B] disabled:opacity-50 text-white font-body font-semibold py-2 rounded-lg transition-colors"
> >
{loading ? 'Signing in…' : 'Sign in'} {loading ? 'Signing in…' : 'Sign in'}
</button> </button>
<p className="text-xs text-[#666] font-body text-center pt-2"> <p className="text-xs text-[#666] font-body text-center pt-2">
PR firm / contributor?{' '} PR firm / contributor?{' '}
<Link href="/client-login" className="text-[#3b82f6] hover:underline"> <Link href="/client-login" className="text-[#E67E22] hover:underline">
Use the contributor portal Use the contributor portal
</Link> </Link>
</p> </p>

View File

@@ -105,13 +105,13 @@ export async function generateMetadata({
const { slug } = await params; const { slug } = await params;
const result = await loadManufacturer(slug); const result = await loadManufacturer(slug);
if (!result) { if (!result) {
return { title: "Manufacturer not found — Broadcast Beat" }; return { title: "Manufacturer not found — AV Beat" };
} }
const { company } = result; const { company } = result;
const title = `${company.company_name} — Manufacturer Profile | Broadcast Beat`; const title = `${company.company_name} — Manufacturer Profile | AV Beat`;
const description = const description =
(company.bio || "").slice(0, 200) || (company.bio || "").slice(0, 200) ||
`${company.company_name} is a broadcast industry manufacturer covered by Broadcast Beat.`; `${company.company_name} is a broadcast industry manufacturer covered by AV Beat.`;
return { return {
title, title,
description, description,
@@ -119,7 +119,7 @@ export async function generateMetadata({
openGraph: { openGraph: {
title, title,
description, description,
url: `https://broadcastbeat.com/manufacturers/${slug}`, url: `https://avbeat.com/manufacturers/${slug}`,
type: "profile", type: "profile",
...(company.logo_url ? { images: [{ url: company.logo_url }] } : {}), ...(company.logo_url ? { images: [{ url: company.logo_url }] } : {}),
}, },
@@ -206,7 +206,7 @@ export default async function ManufacturerProfile({
</span> </span>
)} )}
{company.phone && ( {company.phone && (
<a href={`tel:${company.phone.replace(/[^\d+]/g, '')}`} className="text-[#888] hover:text-[#3b82f6]"> <a href={`tel:${company.phone.replace(/[^\d+]/g, '')}`} className="text-[#888] hover:text-[#E67E22]">
{company.phone} {company.phone}
</a> </a>
)} )}
@@ -217,7 +217,7 @@ export default async function ManufacturerProfile({
href={company.company_website} href={company.company_website}
target="_blank" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"
className="text-[#3b82f6] hover:underline" className="text-[#E67E22] hover:underline"
> >
Website Website
</a> </a>
@@ -227,7 +227,7 @@ export default async function ManufacturerProfile({
href={company.press_url} href={company.press_url}
target="_blank" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"
className="text-[#3b82f6] hover:underline" className="text-[#E67E22] hover:underline"
> >
Newsroom Newsroom
</a> </a>
@@ -237,7 +237,7 @@ export default async function ManufacturerProfile({
href={company.contact_url} href={company.contact_url}
target="_blank" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"
className="text-[#3b82f6] hover:underline" className="text-[#E67E22] hover:underline"
> >
Contact Contact
</a> </a>
@@ -247,7 +247,7 @@ export default async function ManufacturerProfile({
href={company.linkedin_url} href={company.linkedin_url}
target="_blank" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"
className="text-[#888] hover:text-[#3b82f6]" className="text-[#888] hover:text-[#E67E22]"
> >
LinkedIn LinkedIn
</a> </a>
@@ -257,7 +257,7 @@ export default async function ManufacturerProfile({
href={`https://twitter.com/${company.twitter_handle}`} href={`https://twitter.com/${company.twitter_handle}`}
target="_blank" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"
className="text-[#888] hover:text-[#3b82f6]" className="text-[#888] hover:text-[#E67E22]"
> >
X / Twitter X / Twitter
</a> </a>
@@ -306,7 +306,7 @@ export default async function ManufacturerProfile({
href={e.linkedin_url} href={e.linkedin_url}
target="_blank" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"
className="text-[11px] text-[#3b82f6] hover:underline" className="text-[11px] text-[#E67E22] hover:underline"
> >
LinkedIn LinkedIn
</a> </a>
@@ -328,14 +328,14 @@ export default async function ManufacturerProfile({
)} )}
{company.phone && ( {company.phone && (
<div className="mt-1"> <div className="mt-1">
<a href={`tel:${company.phone.replace(/[^\d+]/g, '')}`} className="text-[#3b82f6] hover:underline"> <a href={`tel:${company.phone.replace(/[^\d+]/g, '')}`} className="text-[#E67E22] hover:underline">
{company.phone} {company.phone}
</a> </a>
</div> </div>
)} )}
{company.contact_email && ( {company.contact_email && (
<div> <div>
<a href={`mailto:${company.contact_email}`} className="text-[#3b82f6] hover:underline"> <a href={`mailto:${company.contact_email}`} className="text-[#E67E22] hover:underline">
{company.contact_email} {company.contact_email}
</a> </a>
</div> </div>
@@ -401,7 +401,7 @@ export default async function ManufacturerProfile({
<section className="mb-10"> <section className="mb-10">
<header className="flex items-baseline justify-between mb-3"> <header className="flex items-baseline justify-between mb-3">
<h2 className="text-lg font-display font-bold text-[#e0e0e0]">Recent coverage</h2> <h2 className="text-lg font-display font-bold text-[#e0e0e0]">Recent coverage</h2>
<Link href={`/news?search=${encodeURIComponent(company.company_name)}`} className="text-xs text-[#3b82f6] hover:underline"> <Link href={`/news?search=${encodeURIComponent(company.company_name)}`} className="text-xs text-[#E67E22] hover:underline">
All stories All stories
</Link> </Link>
</header> </header>
@@ -410,7 +410,7 @@ export default async function ManufacturerProfile({
<Link <Link
key={r.wp_slug} key={r.wp_slug}
href={`/news/${r.wp_slug}`} href={`/news/${r.wp_slug}`}
className="group bg-[#0d0d0d] border border-[#252525] rounded-md p-3 hover:border-[#3b82f6] hover:shadow-sm transition-all flex gap-3" className="group bg-[#0d0d0d] border border-[#252525] rounded-md p-3 hover:border-[#E67E22] hover:shadow-sm transition-all flex gap-3"
> >
{/* Image fallback cascade — Ryan rule: never show an empty {/* Image fallback cascade — Ryan rule: never show an empty
gray box on a coverage card. Falls through: gray box on a coverage card. Falls through:
@@ -423,7 +423,7 @@ export default async function ManufacturerProfile({
loading="lazy" loading="lazy"
/> />
<div className="min-w-0"> <div className="min-w-0">
<h3 className="text-xs font-semibold text-[#e0e0e0] leading-snug group-hover:text-[#3b82f6] line-clamp-3"> <h3 className="text-xs font-semibold text-[#e0e0e0] leading-snug group-hover:text-[#E67E22] line-clamp-3">
{r.title} {r.title}
</h3> </h3>
{r.wp_published_at && ( {r.wp_published_at && (
@@ -447,7 +447,7 @@ export default async function ManufacturerProfile({
{p.slug ? ( {p.slug ? (
<Link <Link
href={`/news/${p.slug}`} href={`/news/${p.slug}`}
className="text-[#3b82f6] hover:underline" className="text-[#E67E22] hover:underline"
> >
{p.title} {p.title}
</Link> </Link>
@@ -466,7 +466,7 @@ export default async function ManufacturerProfile({
)} )}
<footer className="text-xs text-[#666] mt-12 pt-6 border-t border-[#252525]"> <footer className="text-xs text-[#666] mt-12 pt-6 border-t border-[#252525]">
Listing maintained by Broadcast Beat editorial. Listing maintained by AV Beat editorial.
{company.last_mentioned && ( {company.last_mentioned && (
<> Last mentioned in coverage on {new Date(company.last_mentioned).toISOString().slice(0, 10)}.</> <> Last mentioned in coverage on {new Date(company.last_mentioned).toISOString().slice(0, 10)}.</>
)} )}

View File

@@ -8,16 +8,16 @@ import ManufacturerDirectoryClient from "./DirectoryClient";
export const revalidate = 1800; export const revalidate = 1800;
export const metadata: Metadata = { export const metadata: Metadata = {
title: "Production Industry Manufacturers — Broadcast Beat", title: "Production Industry Manufacturers — AV Beat",
description: description:
"Browse 1,000+ broadcast, post-production, and live-production manufacturers exhibiting at NAB Show and IBC. Find vendor profiles, booth numbers, product categories, and the latest news from each company.", "Browse 1,000+ broadcast, post-production, and live-production manufacturers exhibiting at NAB Show and IBC. Find vendor profiles, booth numbers, product categories, and the latest news from each company.",
alternates: { canonical: "/manufacturers" }, alternates: { canonical: "/manufacturers" },
openGraph: { openGraph: {
title: "Production Industry Manufacturers — Broadcast Beat", title: "Production Industry Manufacturers — AV Beat",
description: description:
"Comprehensive directory of broadcast industry manufacturers, exhibitors, and vendors.", "Comprehensive directory of broadcast industry manufacturers, exhibitors, and vendors.",
type: "website", type: "website",
url: "https://broadcastbeat.com/manufacturers", url: "https://avbeat.com/manufacturers",
}, },
}; };
@@ -97,12 +97,12 @@ export default async function ManufacturersIndex() {
<section className="mt-16 border-t border-[#252525] pt-8 text-sm text-[#888] leading-relaxed"> <section className="mt-16 border-t border-[#252525] pt-8 text-sm text-[#888] leading-relaxed">
<p> <p>
Sources: 2026 NAB Show exhibitor list (Map Your Show), IBC exhibitor list, Sources: 2026 NAB Show exhibitor list (Map Your Show), IBC exhibitor list,
manufacturer-direct press releases, and reporting tracked on Broadcast Beat. manufacturer-direct press releases, and reporting tracked on AV Beat.
New manufacturers and updates land here as our crawlers detect them. New manufacturers and updates land here as our crawlers detect them.
</p> </p>
<p className="mt-2"> <p className="mt-2">
Are you a manufacturer and want to update your listing?{" "} Are you a manufacturer and want to update your listing?{" "}
<a href="mailto:editors@broadcastbeat.com?subject=Manufacturer%20Directory%20Update" className="text-[#3b82f6] hover:underline"> <a href="mailto:editors@avbeat.com?subject=Manufacturer%20Directory%20Update" className="text-[#E67E22] hover:underline">
Contact our editors Contact our editors
</a> </a>
. .

View File

@@ -3,7 +3,7 @@ import { getLegacyArticlesBySection } from "@/lib/articles/legacy-source";
export const dynamic = "force-dynamic"; export const dynamic = "force-dynamic";
export const revalidate = 1800; export const revalidate = 1800;
const SITE_URL = process.env.NEXT_PUBLIC_SITE_URL || "https://broadcastbeat.com"; const SITE_URL = process.env.NEXT_PUBLIC_SITE_URL || "https://avbeat.com";
function escapeXml(s: string): string { function escapeXml(s: string): string {
return s return s
@@ -41,7 +41,7 @@ export async function GET() {
const body = `<?xml version="1.0" encoding="UTF-8"?> const body = `<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"> <rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel> <channel>
<title>Broadcast 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 &amp; Intelligence for Broadcast, Post-Production &amp; Streaming Technology</description> <description>News &amp; Intelligence for Broadcast, Post-Production &amp; Streaming Technology</description>

View File

@@ -83,7 +83,7 @@ async function fetchArticles(refs: ArticleRef[]): Promise<UnifiedArticle[]> {
excerpt: r.excerpt || "", excerpt: r.excerpt || "",
image: null, image: null,
date: r.published_at || r.created_at, date: r.published_at || r.created_at,
author: Array.isArray(r.persona) ? r.persona[0]?.name || "Broadcast Beat" : r.persona?.name || "Broadcast Beat", author: Array.isArray(r.persona) ? r.persona[0]?.name || "AV Beat" : r.persona?.name || "AV Beat",
source_table: "ai_rewritten", source_table: "ai_rewritten",
}); });
} }
@@ -101,7 +101,7 @@ async function fetchArticles(refs: ArticleRef[]): Promise<UnifiedArticle[]> {
excerpt: r.excerpt || "", excerpt: r.excerpt || "",
image: r.featured_image, image: r.featured_image,
date: r.wp_published_at, date: r.wp_published_at,
author: r.author_name || "Broadcast Beat", author: r.author_name || "AV Beat",
source_table: "wp_imported", source_table: "wp_imported",
}); });
} }
@@ -157,7 +157,7 @@ export default async function EventCoveragePage({
name: event.venue || event.city || event.country || "TBC", name: event.venue || event.city || event.country || "TBC",
address: [event.venue, event.city, event.country].filter(Boolean).join(", "), address: [event.venue, event.city, event.country].filter(Boolean).join(", "),
}, },
url: event.url || `https://broadcastbeat.com/show-coverage/${event.slug}`, url: event.url || `https://avbeat.com/show-coverage/${event.slug}`,
}; };
return ( return (
@@ -170,7 +170,7 @@ export default async function EventCoveragePage({
/> />
<div className="lg:grid lg:grid-cols-[1fr,300px] lg:gap-8"> <div className="lg:grid lg:grid-cols-[1fr,300px] lg:gap-8">
<main> <main>
<Link href="/show-coverage" className="text-sm text-[var(--color-text-info,#60a5fa)] hover:underline"> <Link href="/show-coverage" className="text-sm text-[var(--color-text-info,#E67E22)] hover:underline">
All events All events
</Link> </Link>
@@ -182,7 +182,7 @@ export default async function EventCoveragePage({
</span> </span>
)} )}
{!isLive && !isPast && ( {!isLive && !isPast && (
<span className="inline-flex items-center gap-1.5 text-[11px] font-mono uppercase tracking-wider text-[var(--color-text-info,#60a5fa)]"> <span className="inline-flex items-center gap-1.5 text-[11px] font-mono uppercase tracking-wider text-[var(--color-text-info,#E67E22)]">
T-{daysUntil}d T-{daysUntil}d
</span> </span>
)} )}
@@ -203,7 +203,7 @@ export default async function EventCoveragePage({
{[event.venue, event.city, event.country].filter(Boolean).join(" · ")} {[event.venue, event.city, event.country].filter(Boolean).join(" · ")}
</div> </div>
{event.url && ( {event.url && (
<div className="text-xs font-mono text-[var(--color-text-info,#60a5fa)] mt-2"> <div className="text-xs font-mono text-[var(--color-text-info,#E67E22)] mt-2">
<a href={event.url} target="_blank" rel="noopener noreferrer"> <a href={event.url} target="_blank" rel="noopener noreferrer">
{new URL(event.url).hostname.replace(/^www\./, "")} {new URL(event.url).hostname.replace(/^www\./, "")}
</a> </a>

View File

@@ -123,7 +123,7 @@ function EventCard({ e }: { e: Row }) {
<li> <li>
<Link <Link
href={`/show-coverage/${e.slug}`} href={`/show-coverage/${e.slug}`}
className="block p-5 rounded border border-[#252525] hover:border-[var(--color-text-info,#60a5fa)] bg-[#0b0f17] transition-colors" className="block p-5 rounded border border-[#252525] hover:border-[var(--color-text-info,#E67E22)] bg-[#0b0f17] transition-colors"
> >
<div className="flex items-start justify-between gap-3"> <div className="flex items-start justify-between gap-3">
<h3 className="font-serif text-xl font-semibold">{e.name}</h3> <h3 className="font-serif text-xl font-semibold">{e.name}</h3>
@@ -137,7 +137,7 @@ function EventCard({ e }: { e: Row }) {
{e.url && ( {e.url && (
<> <>
{" · "} {" · "}
<span className="text-[var(--color-text-info,#60a5fa)]">{new URL(e.url).hostname.replace(/^www\./, "")}</span> <span className="text-[var(--color-text-info,#E67E22)]">{new URL(e.url).hostname.replace(/^www\./, "")}</span>
</> </>
)} )}
</div> </div>
@@ -147,6 +147,6 @@ function EventCard({ e }: { e: Row }) {
} }
export const metadata = { export const metadata = {
title: "Industry Show Coverage — events tracked by Broadcast Beat", title: "Industry Show Coverage — events tracked by AV Beat",
description: "All upcoming and past broadcast / production industry events tracked by Broadcast Beat, with linked coverage.", description: "All upcoming and past broadcast / production industry events tracked by AV Beat, with linked coverage.",
}; };

View File

@@ -4,8 +4,8 @@ import Header from "@/components/Header";
import Footer from "@/components/Footer"; import Footer from "@/components/Footer";
export const metadata: Metadata = { export const metadata: Metadata = {
title: "Terms of Service — Broadcast Beat", title: "Terms of Service — AV Beat",
description: "Broadcast Beat Terms of Service — the rules governing use of our platform.", description: "AV Beat Terms of Service — the rules governing use of our platform.",
}; };
export default function TermsPage() { export default function TermsPage() {
@@ -22,15 +22,15 @@ export default function TermsPage() {
<div className="max-w-3xl space-y-8 font-body text-[#aaa] leading-relaxed"> <div className="max-w-3xl space-y-8 font-body text-[#aaa] leading-relaxed">
<section> <section>
<h2 className="font-heading text-[#e0e0e0] text-xl font-bold mb-3">1. Acceptance of Terms</h2> <h2 className="font-heading text-[#e0e0e0] text-xl font-bold mb-3">1. Acceptance of Terms</h2>
<p>By accessing and using Broadcast Beat, you accept and agree to be bound by the terms and provisions of this agreement. If you do not agree to these terms, please do not use our service.</p> <p>By accessing and using AV Beat, you accept and agree to be bound by the terms and provisions of this agreement. If you do not agree to these terms, please do not use our service.</p>
</section> </section>
<section> <section>
<h2 className="font-heading text-[#e0e0e0] text-xl font-bold mb-3">2. Use of Content</h2> <h2 className="font-heading text-[#e0e0e0] text-xl font-bold mb-3">2. Use of Content</h2>
<p>All content on Broadcast Beat is the property of Relevant Media Properties or its content suppliers and is protected by applicable intellectual property laws. You may not reproduce, distribute, or create derivative works from our content without express written permission.</p> <p>All content on AV Beat is the property of Relevant Media Properties or its content suppliers and is protected by applicable intellectual property laws. You may not reproduce, distribute, or create derivative works from our content without express written permission.</p>
</section> </section>
<section> <section>
<h2 className="font-heading text-[#e0e0e0] text-xl font-bold mb-3">3. User Accounts</h2> <h2 className="font-heading text-[#e0e0e0] text-xl font-bold mb-3">3. User Accounts</h2>
<p>If you create an account on Broadcast Beat, you are responsible for maintaining the confidentiality of your account credentials and for all activities that occur under your account. You agree to notify us immediately of any unauthorized use of your account.</p> <p>If you create an account on AV Beat, you are responsible for maintaining the confidentiality of your account credentials and for all activities that occur under your account. You agree to notify us immediately of any unauthorized use of your account.</p>
</section> </section>
<section> <section>
<h2 className="font-heading text-[#e0e0e0] text-xl font-bold mb-3">4. Community Standards</h2> <h2 className="font-heading text-[#e0e0e0] text-xl font-bold mb-3">4. Community Standards</h2>
@@ -38,7 +38,7 @@ export default function TermsPage() {
</section> </section>
<section> <section>
<h2 className="font-heading text-[#e0e0e0] text-xl font-bold mb-3">5. Disclaimer of Warranties</h2> <h2 className="font-heading text-[#e0e0e0] text-xl font-bold mb-3">5. Disclaimer of Warranties</h2>
<p>Broadcast Beat is provided "as is" without warranty of any kind. We do not warrant that the service will be uninterrupted or error-free. We make no warranties regarding the accuracy or completeness of any content on the site.</p> <p>AV Beat is provided "as is" without warranty of any kind. We do not warrant that the service will be uninterrupted or error-free. We make no warranties regarding the accuracy or completeness of any content on the site.</p>
</section> </section>
<section> <section>
<h2 className="font-heading text-[#e0e0e0] text-xl font-bold mb-3">6. Limitation of Liability</h2> <h2 className="font-heading text-[#e0e0e0] text-xl font-bold mb-3">6. Limitation of Liability</h2>
@@ -46,7 +46,7 @@ export default function TermsPage() {
</section> </section>
<section> <section>
<h2 className="font-heading text-[#e0e0f0] text-xl font-bold mb-3">7. Contact</h2> <h2 className="font-heading text-[#e0e0f0] text-xl font-bold mb-3">7. Contact</h2>
<p>Questions about these Terms? Contact us at <a href="mailto:legal@broadcastbeat.com" className="text-[#3b82f6] hover:underline">legal@broadcastbeat.com</a>.</p> <p>Questions about these Terms? Contact us at <a href="mailto:legal@avbeat.com" className="text-[#E67E22] hover:underline">legal@avbeat.com</a>.</p>
</section> </section>
</div> </div>
</main> </main>