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

@@ -91,7 +91,7 @@ export default function ClientsPage() {
setForm({ company_name: '', contact_name: '', contact_email: '', contact_phone: '', billing_address: '', notes: '' });
}
if (loading) return <div className="min-h-screen bg-[#0a0a0a] flex items-center justify-center"><div className="w-8 h-8 border-2 border-[#F0A623] border-t-transparent rounded-full animate-spin" /></div>;
if (loading) return <div className="min-h-screen bg-[#0a0a0a] flex items-center justify-center"><div className="w-8 h-8 border-2 border-[#1D4ED8] border-t-transparent rounded-full animate-spin" /></div>;
if (!user) return null;
return (
@@ -102,7 +102,7 @@ export default function ClientsPage() {
<h1 className="text-xl font-bold">Clients</h1>
<Link href="/admin/accounting" className="text-xs text-[#555] hover:text-[#888]"> Accounting</Link>
</div>
<button onClick={() => setShowForm(true)} className="px-3 py-1.5 bg-[#F0A623] rounded text-xs font-medium hover:bg-blue-500 transition-colors">+ New Client</button>
<button onClick={() => setShowForm(true)} className="px-3 py-1.5 bg-[#1D4ED8] rounded text-xs font-medium hover:bg-blue-500 transition-colors">+ New Client</button>
</div>
{/* Success Toast */}
@@ -116,14 +116,14 @@ export default function ClientsPage() {
{/* Filters */}
<div className="flex gap-2 flex-wrap">
{['active','inactive','all'].map(s => (
<button key={s} onClick={() => setFilter(s)} className={`px-3 py-1 rounded text-xs capitalize ${filter === s ? 'bg-[#F0A623] text-white' : 'bg-[#111] border border-[#3a322b] text-[#888] hover:text-white'}`}>{s}</button>
<button key={s} onClick={() => setFilter(s)} className={`px-3 py-1 rounded text-xs capitalize ${filter === s ? 'bg-[#1D4ED8] text-white' : 'bg-[#111] border border-[#DCE6F2] text-[#888] hover:text-white'}`}>{s}</button>
))}
<input value={search} onChange={e => setSearch(e.target.value)} placeholder="Search clients…" className="ml-auto px-3 py-1 bg-[#111] border border-[#3a322b] rounded text-xs text-white placeholder-[#555] focus:outline-none focus:border-[#F0A623]" />
<input value={search} onChange={e => setSearch(e.target.value)} placeholder="Search clients…" className="ml-auto px-3 py-1 bg-[#111] border border-[#DCE6F2] rounded text-xs text-white placeholder-[#555] focus:outline-none focus:border-[#1D4ED8]" />
</div>
{/* New Client Form */}
{showForm && (
<form onSubmit={handleCreate} noValidate className="bg-[#111] border border-[#3a322b] rounded-lg p-4 space-y-3">
<form onSubmit={handleCreate} noValidate className="bg-[#111] border border-[#DCE6F2] rounded-lg p-4 space-y-3">
<h3 className="text-sm font-semibold">New Client</h3>
{errors._form && (
@@ -148,7 +148,7 @@ export default function ClientsPage() {
type={f.key === 'contact_email' ? 'email' : 'text'}
value={(form as any)[f.key]}
onChange={e => handleChange(f.key, e.target.value)}
className={`w-full px-2 py-1.5 bg-[#0a0a0a] border rounded text-xs text-white focus:outline-none focus:border-[#F0A623] ${errors[f.key] ? 'border-red-500/60' : 'border-[#3a322b]'}`}
className={`w-full px-2 py-1.5 bg-[#0a0a0a] border rounded text-xs text-white focus:outline-none focus:border-[#1D4ED8] ${errors[f.key] ? 'border-red-500/60' : 'border-[#DCE6F2]'}`}
/>
{errors[f.key] && <p className="mt-1 text-xs text-red-400">{errors[f.key]}</p>}
</div>
@@ -156,26 +156,26 @@ export default function ClientsPage() {
<div className="col-span-2">
<label className="text-xs text-[#888] block mb-1">Billing Address</label>
<input value={form.billing_address} onChange={e => handleChange('billing_address', e.target.value)}
className="w-full px-2 py-1.5 bg-[#0a0a0a] border border-[#3a322b] rounded text-xs text-white focus:outline-none focus:border-[#F0A623]" />
className="w-full px-2 py-1.5 bg-[#0a0a0a] border border-[#DCE6F2] rounded text-xs text-white focus:outline-none focus:border-[#1D4ED8]" />
</div>
<div className="col-span-2">
<label className="text-xs text-[#888] block mb-1">Notes</label>
<textarea value={form.notes} onChange={e => handleChange('notes', e.target.value)} rows={2}
className="w-full px-2 py-1.5 bg-[#0a0a0a] border border-[#3a322b] rounded text-xs text-white focus:outline-none focus:border-[#F0A623]" />
className="w-full px-2 py-1.5 bg-[#0a0a0a] border border-[#DCE6F2] rounded text-xs text-white focus:outline-none focus:border-[#1D4ED8]" />
</div>
</div>
<div className="flex gap-2">
<button type="submit" disabled={saving} className="px-3 py-1.5 bg-[#F0A623] rounded text-xs font-medium hover:bg-blue-500 disabled:opacity-50">{saving ? 'Saving…' : 'Create Client'}</button>
<button type="button" onClick={handleCancel} className="px-3 py-1.5 bg-[#231d18] border border-[#3a322b] rounded text-xs text-[#888] hover:text-white">Cancel</button>
<button type="submit" disabled={saving} className="px-3 py-1.5 bg-[#1D4ED8] rounded text-xs font-medium hover:bg-blue-500 disabled:opacity-50">{saving ? 'Saving…' : 'Create Client'}</button>
<button type="button" onClick={handleCancel} className="px-3 py-1.5 bg-[#FFFFFF] border border-[#DCE6F2] rounded text-xs text-[#888] hover:text-white">Cancel</button>
</div>
</form>
)}
{/* Table */}
<div className="bg-[#111] border border-[#3a322b] rounded-lg overflow-hidden">
<div className="bg-[#111] border border-[#DCE6F2] rounded-lg overflow-hidden">
<table className="w-full text-sm">
<thead>
<tr className="border-b border-[#231d18]">
<tr className="border-b border-[#FFFFFF]">
{['Company','Contact','Email','Active Orders','Total Revenue','Status',''].map(h => (
<th key={h} className="px-4 py-2 text-left text-xs text-[#555] font-medium">{h}</th>
))}
@@ -187,17 +187,17 @@ export default function ClientsPage() {
) : clients.length === 0 ? (
<tr><td colSpan={7} className="px-4 py-8 text-center text-[#555] text-xs">No clients found</td></tr>
) : clients.map(c => (
<tr key={c.id} className="border-b border-[#231d18] hover:bg-[#231d18]">
<tr key={c.id} className="border-b border-[#FFFFFF] hover:bg-[#FFFFFF]">
<td className="px-4 py-2 text-white font-medium">{c.company_name}</td>
<td className="px-4 py-2 text-[#ccc]">{c.contact_name}</td>
<td className="px-4 py-2 text-[#888]">{c.contact_email}</td>
<td className="px-4 py-2 text-[#ccc]">{c.active_orders ?? 0}</td>
<td className="px-4 py-2 text-green-400">{fmt(c.total_revenue ?? 0)}</td>
<td className="px-4 py-2">
<span className={`px-2 py-0.5 rounded-full text-xs ${c.status === 'active' ? 'bg-green-400/10 text-green-400' : 'bg-[#231d18] text-[#555]'}`}>{c.status}</span>
<span className={`px-2 py-0.5 rounded-full text-xs ${c.status === 'active' ? 'bg-green-400/10 text-green-400' : 'bg-[#FFFFFF] text-[#555]'}`}>{c.status}</span>
</td>
<td className="px-4 py-2">
<Link href={`/admin/accounting/clients/${c.id}`} className="text-xs text-[#F0A623] hover:underline">View</Link>
<Link href={`/admin/accounting/clients/${c.id}`} className="text-xs text-[#1D4ED8] hover:underline">View</Link>
</td>
</tr>
))}