feat(brand): AV BEAT 2026 rebrand — blue/navy/white identity

- New AvBeatLogo inline-SVG component (rounded-square emblem with
  forward-leaning AV monogram + horizontal beam detail) at
  src/components/AvBeatLogo.tsx, three variants (full/wordmark/icon).
- Header.tsx now uses the responsive AV BEAT logo lockup in the
  top-left, links to /, full lockup on desktop (emblem+wordmark+tagline),
  emblem+wordmark on tablet, emblem-only on mobile.
- Removed DualSpeedTicker (the 'RECENT FORUM POSTS' ticker strip);
  the news ticker / glow chrome does not match the new aesthetic and the
  forum row was the explicit removal target.
- Tailwind theme + globals.css now expose the AV BEAT 2026 palette as
  semantic tokens: --brand-blue (#1D4ED8), --brand-blue-bright (#38BDF8),
  --brand-navy (#0F172A), --brand-bg (#F8FAFC), --brand-surface, --brand-border,
  --brand-text, --brand-text-muted. Legacy --color-* aliases re-point to the
  new tokens so any inline-styled component re-themes for free.
- Site-wide hex sweep migrates 2,769 hardcoded color literals across 144
  files from the old dark-broadcast palette to the new tokens (orange
  -> blue, dark-brown -> white surface / navy text, cream -> navy).
- Layout body class flipped from 'bb-neon' to 'bg-brand-bg text-brand-text'
  so the dark glow chrome no longer leaks through the new light theme.
This commit is contained in:
2026-06-03 12:07:18 +00:00
parent 39d2bf9073
commit 8042024c4a
146 changed files with 2219 additions and 2081 deletions

View File

@@ -252,7 +252,7 @@ export default function CampaignEditorPage() {
article_blocks: payload.article_blocks,
layout: 'featured',
style: 'dark',
accent_color: '#F0A623',
accent_color: '#1D4ED8',
is_preset: false,
}),
});
@@ -296,7 +296,7 @@ export default function CampaignEditorPage() {
)}
{/* ── Top Bar ── */}
<div className="sticky top-0 z-40 bg-[#0a0a0a]/95 backdrop-blur border-b border-[#231d18]">
<div className="sticky top-0 z-40 bg-[#0a0a0a]/95 backdrop-blur border-b border-[#FFFFFF]">
<div className="max-w-screen-xl mx-auto px-4 h-14 flex items-center justify-between gap-4">
<div className="flex items-center gap-3 min-w-0">
<Link href="/admin/newsletter" className="text-[#555] hover:text-white transition-colors flex-shrink-0">
@@ -313,7 +313,7 @@ export default function CampaignEditorPage() {
className="bg-transparent text-sm font-medium text-white placeholder-[#444] outline-none min-w-0 w-48"
/>
<span className={`text-xs px-2 py-0.5 rounded-full font-medium flex-shrink-0 ${
campaign.status === 'draft' ? 'bg-[#231d18] text-[#666]' :
campaign.status === 'draft' ? 'bg-[#FFFFFF] text-[#666]' :
campaign.status === 'scheduled'? 'bg-yellow-400/10 text-yellow-400' : 'bg-green-400/10 text-green-400'
}`}>
{campaign.status}
@@ -339,7 +339,7 @@ export default function CampaignEditorPage() {
<button
onClick={() => handleSave('draft')}
disabled={saving}
className="px-3 py-1.5 text-xs font-medium bg-[#231d18] hover:bg-[#222] border border-[#3a322b] text-[#aaa] rounded-lg transition-colors disabled:opacity-50"
className="px-3 py-1.5 text-xs font-medium bg-[#FFFFFF] hover:bg-[#222] border border-[#DCE6F2] text-[#aaa] rounded-lg transition-colors disabled:opacity-50"
>
{saving ? 'Saving…' : 'Save Draft'}
</button>
@@ -393,9 +393,9 @@ export default function CampaignEditorPage() {
<div className="space-y-2">
{loadingArticles ? (
Array.from({ length: 5 }).map((_, i) => (
<div key={i} className="bg-[#111] border border-[#231d18] rounded-xl p-4 animate-pulse">
<div key={i} className="bg-[#111] border border-[#FFFFFF] rounded-xl p-4 animate-pulse">
<div className="h-3 bg-[#1e1e1e] rounded w-3/4 mb-2" />
<div className="h-2.5 bg-[#231d18] rounded w-1/2" />
<div className="h-2.5 bg-[#FFFFFF] rounded w-1/2" />
</div>
))
) : articles.length === 0 ? (
@@ -409,7 +409,7 @@ export default function CampaignEditorPage() {
onClick={() => toggleArticle(article)}
className={`group relative bg-[#111] border rounded-xl p-4 cursor-pointer transition-all ${
selected
? 'border-white/20 bg-white/5' :'border-[#231d18] hover:border-[#3a322b]'
? 'border-white/20 bg-white/5' :'border-[#FFFFFF] hover:border-[#DCE6F2]'
}`}
>
<div className="flex items-start gap-3">
@@ -427,7 +427,7 @@ export default function CampaignEditorPage() {
<div className="flex-1 min-w-0">
<div className="flex items-center gap-2 mb-1">
{article.category && (
<span className="text-[10px] font-semibold uppercase tracking-wider text-[#555] bg-[#231d18] px-1.5 py-0.5 rounded">
<span className="text-[10px] font-semibold uppercase tracking-wider text-[#555] bg-[#FFFFFF] px-1.5 py-0.5 rounded">
{article.category}
</span>
)}
@@ -454,7 +454,7 @@ export default function CampaignEditorPage() {
{(activePanel === 'settings' || activePanel === 'articles') && (
<>
{/* Subject Line */}
<div className="bg-[#111] border border-[#231d18] rounded-xl p-4">
<div className="bg-[#111] border border-[#FFFFFF] rounded-xl p-4">
<div className="flex items-center justify-between mb-3">
<h3 className="text-xs font-semibold text-white uppercase tracking-wider">Subject Line</h3>
<span className={`text-[10px] font-mono ${subjectCharCount > 60 ? 'text-yellow-400' : 'text-[#444]'}`}>
@@ -477,7 +477,7 @@ export default function CampaignEditorPage() {
</div>
{/* Preview Text */}
<div className="bg-[#111] border border-[#231d18] rounded-xl p-4">
<div className="bg-[#111] border border-[#FFFFFF] rounded-xl p-4">
<div className="flex items-center justify-between mb-3">
<h3 className="text-xs font-semibold text-white uppercase tracking-wider">Preview Text</h3>
<span className={`text-[10px] font-mono ${previewCharCount > 90 ? 'text-yellow-400' : 'text-[#444]'}`}>
@@ -497,7 +497,7 @@ export default function CampaignEditorPage() {
</div>
{/* Recipient Segment */}
<div className="bg-[#111] border border-[#231d18] rounded-xl p-4">
<div className="bg-[#111] border border-[#FFFFFF] rounded-xl p-4">
<h3 className="text-xs font-semibold text-white uppercase tracking-wider mb-3">Recipient Segment</h3>
<div className="space-y-2">
{SEGMENTS.map((seg) => {
@@ -509,7 +509,7 @@ export default function CampaignEditorPage() {
onClick={() => setCampaign((p) => ({ ...p, segment: seg.id }))}
className={`w-full text-left px-3 py-2.5 rounded-lg border transition-all ${
active
? 'bg-white/5 border-white/20 text-white' :'bg-[#0a0a0a] border-[#231d18] text-[#888] hover:border-[#3a322b] hover:text-white'
? 'bg-white/5 border-white/20 text-white' :'bg-[#0a0a0a] border-[#FFFFFF] text-[#888] hover:border-[#DCE6F2] hover:text-white'
}`}
>
<div className="flex items-center justify-between">
@@ -529,7 +529,7 @@ export default function CampaignEditorPage() {
})}
</div>
{recipientCount > 0 && (
<div className="mt-3 pt-3 border-t border-[#231d18] flex items-center gap-2">
<div className="mt-3 pt-3 border-t border-[#FFFFFF] flex items-center gap-2">
<svg className="w-3.5 h-3.5 text-[#555]" fill="none" stroke="currentColor" strokeWidth="2" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0z" />
</svg>
@@ -543,7 +543,7 @@ export default function CampaignEditorPage() {
)}
{/* ── Selected Articles ── */}
<div className="bg-[#111] border border-[#231d18] rounded-xl p-4">
<div className="bg-[#111] border border-[#FFFFFF] rounded-xl p-4">
<div className="flex items-center justify-between mb-3">
<h3 className="text-xs font-semibold text-white uppercase tracking-wider">Selected Articles</h3>
<span className="text-[10px] text-[#555]">{campaign.articles.length} article{campaign.articles.length !== 1 ? 's' : ''}</span>
@@ -559,7 +559,7 @@ export default function CampaignEditorPage() {
) : (
<div className="space-y-2">
{campaign.articles.map((article, idx) => (
<div key={article.id} className="bg-[#0a0a0a] border border-[#231d18] rounded-lg p-3">
<div key={article.id} className="bg-[#0a0a0a] border border-[#FFFFFF] rounded-lg p-3">
<div className="flex items-start gap-2">
{/* Order controls */}
<div className="flex flex-col gap-0.5 flex-shrink-0 mt-0.5">
@@ -618,16 +618,16 @@ export default function CampaignEditorPage() {
{/* ── Preview Panel ── */}
{activePanel === 'preview' && (
<div className="bg-[#111] border border-[#231d18] rounded-xl overflow-hidden">
<div className="px-4 py-3 border-b border-[#231d18] flex items-center justify-between">
<div className="bg-[#111] border border-[#FFFFFF] rounded-xl overflow-hidden">
<div className="px-4 py-3 border-b border-[#FFFFFF] flex items-center justify-between">
<h3 className="text-xs font-semibold text-white uppercase tracking-wider">Email Preview</h3>
<span className="text-[10px] text-[#555]">Inbox view</span>
</div>
{/* Inbox row preview */}
<div className="px-4 py-3 border-b border-[#231d18] bg-[#1c1815]">
<div className="px-4 py-3 border-b border-[#FFFFFF] bg-[#F8FAFC]">
<div className="flex items-center gap-2 mb-1">
<div className="w-6 h-6 rounded-full bg-[#231d18] flex items-center justify-center flex-shrink-0">
<div className="w-6 h-6 rounded-full bg-[#FFFFFF] flex items-center justify-center flex-shrink-0">
<span className="text-[8px] font-bold text-[#666]">BB</span>
</div>
<div className="flex-1 min-w-0">
@@ -644,7 +644,7 @@ export default function CampaignEditorPage() {
{/* Email body preview */}
<div className="p-4 space-y-3 max-h-[400px] overflow-y-auto">
{/* Header */}
<div className="bg-[#0a0a0a] rounded-lg p-3 text-center border border-[#231d18]">
<div className="bg-[#0a0a0a] rounded-lg p-3 text-center border border-[#FFFFFF]">
<p className="text-xs font-bold text-white tracking-widest uppercase">AV Beat</p>
{campaign.previewText && (
<p className="text-[10px] text-[#555] mt-1">{campaign.previewText}</p>
@@ -657,7 +657,7 @@ export default function CampaignEditorPage() {
) : (
campaign.articles.map((article, idx) => (
<div key={article.id} className={`rounded-lg border p-3 ${
article.featured ? 'border-white/10 bg-white/3' : 'border-[#231d18] bg-[#0a0a0a]'
article.featured ? 'border-white/10 bg-white/3' : 'border-[#FFFFFF] bg-[#0a0a0a]'
}`}>
{article.featured && (
<span className="text-[9px] font-semibold uppercase tracking-wider text-yellow-400 mb-1 block">Featured Story</span>
@@ -679,7 +679,7 @@ export default function CampaignEditorPage() {
)}
{/* Footer */}
<div className="text-center pt-2 border-t border-[#231d18]">
<div className="text-center pt-2 border-t border-[#FFFFFF]">
<p className="text-[9px] text-[#333]">AV Beat · Unsubscribe · View in browser</p>
</div>
</div>
@@ -687,7 +687,7 @@ export default function CampaignEditorPage() {
)}
{/* ── Publish Summary ── */}
<div className="bg-[#111] border border-[#231d18] rounded-xl p-4">
<div className="bg-[#111] border border-[#FFFFFF] rounded-xl p-4">
<h3 className="text-xs font-semibold text-white uppercase tracking-wider mb-3">Campaign Summary</h3>
<div className="space-y-2">
{[
@@ -710,7 +710,7 @@ export default function CampaignEditorPage() {
<button
onClick={() => handleSave('draft')}
disabled={saving}
className="flex-1 py-2 text-xs font-medium bg-[#231d18] hover:bg-[#222] border border-[#3a322b] text-[#aaa] rounded-lg transition-colors disabled:opacity-50"
className="flex-1 py-2 text-xs font-medium bg-[#FFFFFF] hover:bg-[#222] border border-[#DCE6F2] text-[#aaa] rounded-lg transition-colors disabled:opacity-50"
>
{saving ? 'Saving…' : 'Save Draft'}
</button>