about/show-coverage: redesign with sidebar (300x600 + rotating 300x250s)
Switch the bare single-column layouts on these pages to a two-column
grid that pulls in <SidebarAdStack /> on the right (pinned 300x600 +
every 300x250 rotated). Header keeps the leaderboard above. The
in-content 728x90 banners added earlier are removed since the sidebar
now carries the ad load (avoids stacking two of the same unit on the
page).
Pages updated:
- /show-coverage/[slug] event detail
- /about
- /about/contact
- /about/team
- /about/advertise (also gets a real-banner grid in "Available units":
the actual 728x90, 300x600, and 300x250 sample creatives are
rendered next to each unit's description, so advertisers see what
the inventory looks like in production rather than just a label).
The /about pages also got a small refresh: serif H1 + accent-blue
"Broadcast Beat" eyebrow line + bordered content blocks, bringing the
look closer to the cinematic homepage.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,60 +1,113 @@
|
|||||||
import Header from "@/components/Header";
|
import Header from "@/components/Header";
|
||||||
import Footer from "@/components/Footer";
|
import Footer from "@/components/Footer";
|
||||||
import AdImage from "@/components/AdImage";
|
import AdImage from "@/components/AdImage";
|
||||||
import { ADS_728X90, shuffle } from "@/lib/ads";
|
import SidebarAdStack from "@/components/SidebarAdStack";
|
||||||
|
import { ADS_728X90, ADS_300X250, FIXED_300X600, shuffle } from "@/lib/ads";
|
||||||
|
|
||||||
export const metadata = { title: "Advertise — Broadcast Beat" };
|
export const metadata = { title: "Advertise — Broadcast Beat" };
|
||||||
|
|
||||||
export default function AdvertisePage() {
|
export default function AdvertisePage() {
|
||||||
|
const example728 = ADS_728X90[0];
|
||||||
|
const example300x250 = ADS_300X250[0];
|
||||||
|
const example300x600 = FIXED_300X600;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen bg-background">
|
<div className="min-h-screen bg-background">
|
||||||
<Header />
|
<Header />
|
||||||
<main className="mx-auto max-w-3xl px-6 py-12 text-[#e5e7eb]">
|
<div className="mx-auto max-w-6xl px-6 py-12 text-[#e5e7eb]">
|
||||||
<h1 className="font-serif text-4xl font-bold tracking-tight mb-2">Advertise on Broadcast Beat</h1>
|
<div className="lg:grid lg:grid-cols-[1fr,300px] lg:gap-10">
|
||||||
<p className="text-sm text-[#9ca3af] mb-10">
|
<main>
|
||||||
Broadcast Beat reaches broadcast engineers, post supervisors, streaming
|
<header className="mb-8 border-b border-[#252525] pb-6">
|
||||||
architects, and live-event professionals across the industry.
|
<div className="text-[10px] font-mono uppercase tracking-[0.22em] text-[var(--color-text-info,#60a5fa)] mb-2">
|
||||||
</p>
|
Broadcast Beat
|
||||||
|
</div>
|
||||||
|
<h1 className="font-serif text-4xl md:text-5xl font-bold tracking-tight">Advertise</h1>
|
||||||
|
<p className="mt-3 text-[#9ca3af] text-base max-w-2xl">
|
||||||
|
Broadcast Beat reaches broadcast engineers, post supervisors,
|
||||||
|
streaming architects, and live-event professionals across the
|
||||||
|
industry — daily.
|
||||||
|
</p>
|
||||||
|
</header>
|
||||||
|
|
||||||
<section className="mb-10">
|
<section className="mb-12">
|
||||||
<h2 className="font-mono text-xs uppercase tracking-wider text-[#6b7280] mb-3">Available units</h2>
|
<h2 className="font-mono text-xs uppercase tracking-[0.18em] text-[var(--color-text-info,#60a5fa)] mb-5">
|
||||||
<ul className="space-y-3 text-[15px]">
|
Available units
|
||||||
<li>
|
</h2>
|
||||||
<strong>728×90 leaderboard</strong> — between main nav and headline ticker, sitewide.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<strong>300×600 sidebar premium</strong> — pinned top of every sidebar, sitewide.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<strong>300×250 sidebar rotation</strong> — rotates across every page, multiple slots.
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
{/* In-content 728x90 banner (live example of the leaderboard unit) */}
|
<div className="grid grid-cols-1 gap-5">
|
||||||
{ADS_728X90.length > 0 && (
|
{/* 728x90 */}
|
||||||
<div className="my-10 hidden md:flex justify-center" aria-label="Advertisement">
|
<div className="rounded border border-[#252525] bg-[#0b0f17] p-5 flex flex-col md:flex-row md:items-center gap-5">
|
||||||
<AdImage ad={shuffle(ADS_728X90)[0]} page="advertise" />
|
<div className="md:flex-1 min-w-0">
|
||||||
</div>
|
<h3 className="font-serif text-xl font-semibold">728 × 90 leaderboard</h3>
|
||||||
)}
|
<div className="mt-1 text-[10px] font-mono uppercase tracking-wider text-[#6b7280]">Site-wide · top of every page</div>
|
||||||
|
<p className="mt-3 text-sm text-[#d1d5db]">
|
||||||
|
Sits between the main nav and the headline ticker on
|
||||||
|
every page. The premium first-impression unit.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className="flex-shrink-0 flex items-center justify-center rounded border border-[#1e1e1e] bg-[#0a0a0a] p-3" style={{ minWidth: 250 }}>
|
||||||
|
{example728 ? <AdImage ad={example728} page="advertise-example" /> : <div className="w-[728px] max-w-full h-[90px] flex items-center justify-center text-xs text-[#555]">728 × 90</div>}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<section className="mb-10">
|
{/* 300x600 */}
|
||||||
<h2 className="font-mono text-xs uppercase tracking-wider text-[#6b7280] mb-3">Reporting</h2>
|
<div className="rounded border border-[#252525] bg-[#0b0f17] p-5 flex flex-col md:flex-row md:items-center gap-5">
|
||||||
<p className="text-[15px] text-[#d1d5db]">
|
<div className="md:flex-1 min-w-0">
|
||||||
Every banner is tracked for gross impressions and clicks. Advertisers
|
<h3 className="font-serif text-xl font-semibold">300 × 600 sidebar premium</h3>
|
||||||
receive a monthly report with totals and CTR. Click links route through
|
<div className="mt-1 text-[10px] font-mono uppercase tracking-wider text-[#6b7280]">Pinned · every sidebar · sitewide</div>
|
||||||
/r/{"{campaign}"} for accurate counting independent of analytics
|
<p className="mt-3 text-sm text-[#d1d5db]">
|
||||||
blockers.
|
Pinned at the top of every sidebar, sitewide. Stays
|
||||||
</p>
|
visible while readers scroll the article body.
|
||||||
</section>
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className="flex-shrink-0 flex items-center justify-center rounded border border-[#1e1e1e] bg-[#0a0a0a] p-3">
|
||||||
|
{example300x600 ? <AdImage ad={example300x600} page="advertise-example" /> : <div className="w-[300px] h-[600px] flex items-center justify-center text-xs text-[#555]">300 × 600</div>}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<section>
|
{/* 300x250 */}
|
||||||
<h2 className="font-mono text-xs uppercase tracking-wider text-[#6b7280] mb-3">Get in touch</h2>
|
<div className="rounded border border-[#252525] bg-[#0b0f17] p-5 flex flex-col md:flex-row md:items-center gap-5">
|
||||||
<p className="text-[15px]">
|
<div className="md:flex-1 min-w-0">
|
||||||
<a className="text-[var(--color-text-info,#60a5fa)] hover:underline" href="mailto:advertising@broadcastbeat.com">advertising@broadcastbeat.com</a>
|
<h3 className="font-serif text-xl font-semibold">300 × 250 sidebar rotation</h3>
|
||||||
</p>
|
<div className="mt-1 text-[10px] font-mono uppercase tracking-wider text-[#6b7280]">Rotating · multiple slots · every page</div>
|
||||||
</section>
|
<p className="mt-3 text-sm text-[#d1d5db]">
|
||||||
</main>
|
Rotates across every page, multiple slots per page.
|
||||||
|
Highest-volume inventory — best for awareness campaigns
|
||||||
|
and seasonal pushes (NAB, IBC, BroadcastAsia).
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className="flex-shrink-0 flex items-center justify-center rounded border border-[#1e1e1e] bg-[#0a0a0a] p-3">
|
||||||
|
{example300x250 ? <AdImage ad={example300x250} page="advertise-example" /> : <div className="w-[300px] h-[250px] flex items-center justify-center text-xs text-[#555]">300 × 250</div>}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="mb-10">
|
||||||
|
<h2 className="font-mono text-xs uppercase tracking-[0.18em] text-[var(--color-text-info,#60a5fa)] mb-3">Reporting</h2>
|
||||||
|
<p className="text-[15px] text-[#d1d5db] leading-relaxed">
|
||||||
|
Every banner is tracked for gross impressions and clicks.
|
||||||
|
Advertisers receive a monthly report with totals and CTR. Click
|
||||||
|
links route through <code className="text-[#60a5fa]">/r/{`{campaign}`}</code> for accurate counting independent of
|
||||||
|
analytics blockers.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h2 className="font-mono text-xs uppercase tracking-[0.18em] text-[var(--color-text-info,#60a5fa)] mb-3">Get in touch</h2>
|
||||||
|
<p className="text-[15px]">
|
||||||
|
<a className="text-[var(--color-text-info,#60a5fa)] hover:underline" href="mailto:advertising@broadcastbeat.com">advertising@broadcastbeat.com</a>
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<aside className="mt-10 lg:mt-0" aria-label="Advertisements">
|
||||||
|
<div className="lg:sticky lg:top-24">
|
||||||
|
<SidebarAdStack />
|
||||||
|
</div>
|
||||||
|
</aside>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<Footer />
|
<Footer />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,45 +1,86 @@
|
|||||||
import Header from "@/components/Header";
|
import Header from "@/components/Header";
|
||||||
import Footer from "@/components/Footer";
|
import Footer from "@/components/Footer";
|
||||||
import AdImage from "@/components/AdImage";
|
import SidebarAdStack from "@/components/SidebarAdStack";
|
||||||
import { ADS_728X90, shuffle } from "@/lib/ads";
|
|
||||||
|
|
||||||
export const metadata = { title: "Contact — Broadcast Beat" };
|
export const metadata = { title: "Contact — Broadcast Beat" };
|
||||||
|
|
||||||
|
const CONTACTS = [
|
||||||
|
{
|
||||||
|
title: "Editorial",
|
||||||
|
body: (
|
||||||
|
<a className="text-[var(--color-text-info,#60a5fa)] hover:underline" href="mailto:editor@broadcastbeat.com">editor@broadcastbeat.com</a>
|
||||||
|
),
|
||||||
|
hint: "Story tips, corrections, interview requests.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Press releases",
|
||||||
|
body: (
|
||||||
|
<>
|
||||||
|
Route PR-firm submissions through{" "}
|
||||||
|
<a className="text-[var(--color-text-info,#60a5fa)] hover:underline" href="https://distribution.relevantmediaproperties.com">distribution.relevantmediaproperties.com</a>.
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
hint: "Routed submissions land in our editorial queue with provenance.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Advertising",
|
||||||
|
body: (
|
||||||
|
<>
|
||||||
|
<a className="text-[var(--color-text-info,#60a5fa)] hover:underline" href="mailto:advertising@broadcastbeat.com">advertising@broadcastbeat.com</a> — see the{" "}
|
||||||
|
<a className="text-[var(--color-text-info,#60a5fa)] hover:underline" href="/about/advertise">media kit</a>.
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
hint: "728×90, 300×600, 300×250 inventory; CTR + impression reports monthly.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Publisher",
|
||||||
|
body: (
|
||||||
|
<>
|
||||||
|
Ryan Salazar ·{" "}
|
||||||
|
<a className="text-[var(--color-text-info,#60a5fa)] hover:underline" href="mailto:ryan.salazar@relevantmediaproperties.com">ryan.salazar@relevantmediaproperties.com</a>
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
hint: "Partnerships, M&A, syndication, network membership.",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
export default function ContactPage() {
|
export default function ContactPage() {
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen bg-background">
|
<div className="min-h-screen bg-background">
|
||||||
<Header />
|
<Header />
|
||||||
<main className="mx-auto max-w-2xl px-6 py-12 text-[#e5e7eb]">
|
<div className="mx-auto max-w-6xl px-6 py-12 text-[#e5e7eb]">
|
||||||
<h1 className="font-serif text-4xl font-bold tracking-tight mb-6">Contact</h1>
|
<div className="lg:grid lg:grid-cols-[1fr,300px] lg:gap-10">
|
||||||
<dl className="space-y-5 text-[15px]">
|
<main>
|
||||||
<div>
|
<header className="mb-8 border-b border-[#252525] pb-6">
|
||||||
<dt className="text-xs font-mono uppercase tracking-wider text-[#6b7280] mb-1">Editorial</dt>
|
<div className="text-[10px] font-mono uppercase tracking-[0.22em] text-[var(--color-text-info,#60a5fa)] mb-2">
|
||||||
<dd><a className="text-[var(--color-text-info,#60a5fa)] hover:underline" href="mailto:editor@broadcastbeat.com">editor@broadcastbeat.com</a></dd>
|
Broadcast Beat
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<h1 className="font-serif text-4xl md:text-5xl font-bold tracking-tight">Contact</h1>
|
||||||
<dt className="text-xs font-mono uppercase tracking-wider text-[#6b7280] mb-1">Press releases (PR firms)</dt>
|
<p className="mt-3 text-[#9ca3af] text-base">
|
||||||
<dd>
|
Pitches, press, partnerships — pick the right desk and we'll get back fast.
|
||||||
Route submissions through{" "}
|
</p>
|
||||||
<a className="text-[var(--color-text-info,#60a5fa)] hover:underline" href="https://distribution.relevantmediaproperties.com">distribution.relevantmediaproperties.com</a>.
|
</header>
|
||||||
</dd>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<dt className="text-xs font-mono uppercase tracking-wider text-[#6b7280] mb-1">Advertising</dt>
|
|
||||||
<dd><a className="text-[var(--color-text-info,#60a5fa)] hover:underline" href="mailto:advertising@broadcastbeat.com">advertising@broadcastbeat.com</a> — see <a className="text-[var(--color-text-info,#60a5fa)] hover:underline" href="/about/advertise">media kit</a>.</dd>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<dt className="text-xs font-mono uppercase tracking-wider text-[#6b7280] mb-1">Publisher</dt>
|
|
||||||
<dd>Ryan Salazar · <a className="text-[var(--color-text-info,#60a5fa)] hover:underline" href="mailto:ryan.salazar@relevantmediaproperties.com">ryan.salazar@relevantmediaproperties.com</a></dd>
|
|
||||||
</div>
|
|
||||||
</dl>
|
|
||||||
|
|
||||||
{/* In-content 728x90 banner */}
|
<ul className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||||
{ADS_728X90.length > 0 && (
|
{CONTACTS.map((c) => (
|
||||||
<div className="mt-12 hidden md:flex justify-center" aria-label="Advertisement">
|
<li key={c.title} className="rounded border border-[#252525] bg-[#0b0f17] p-5 hover:border-[var(--color-text-info,#60a5fa)]/60 transition-colors">
|
||||||
<AdImage ad={shuffle(ADS_728X90)[0]} page="contact" />
|
<div className="text-[10px] font-mono uppercase tracking-[0.18em] text-[var(--color-text-info,#60a5fa)] mb-2">
|
||||||
</div>
|
{c.title}
|
||||||
)}
|
</div>
|
||||||
</main>
|
<div className="text-[15px] leading-relaxed">{c.body}</div>
|
||||||
|
<div className="mt-3 text-xs text-[#6b7280]">{c.hint}</div>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<aside className="mt-10 lg:mt-0" aria-label="Advertisements">
|
||||||
|
<div className="lg:sticky lg:top-24">
|
||||||
|
<SidebarAdStack />
|
||||||
|
</div>
|
||||||
|
</aside>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<Footer />
|
<Footer />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import Header from "@/components/Header";
|
import Header from "@/components/Header";
|
||||||
import Footer from "@/components/Footer";
|
import Footer from "@/components/Footer";
|
||||||
|
import SidebarAdStack from "@/components/SidebarAdStack";
|
||||||
|
|
||||||
export const metadata = {
|
export const metadata = {
|
||||||
title: "About Broadcast Beat",
|
title: "About Broadcast Beat",
|
||||||
@@ -10,31 +11,90 @@ export default function AboutPage() {
|
|||||||
return (
|
return (
|
||||||
<div className="min-h-screen bg-background">
|
<div className="min-h-screen bg-background">
|
||||||
<Header />
|
<Header />
|
||||||
<main className="mx-auto max-w-3xl px-6 py-12 text-[#e5e7eb]">
|
<div className="mx-auto max-w-6xl px-6 py-12 text-[#e5e7eb]">
|
||||||
<h1 className="font-serif text-4xl font-bold tracking-tight mb-6">About Broadcast Beat</h1>
|
<div className="lg:grid lg:grid-cols-[1fr,300px] lg:gap-10">
|
||||||
<div className="space-y-5 text-[#d1d5db] text-[15px] leading-relaxed">
|
<main>
|
||||||
<p>
|
<header className="mb-8 border-b border-[#252525] pb-6">
|
||||||
Broadcast Beat is an independent trade publication covering broadcast,
|
<div className="text-[10px] font-mono uppercase tracking-[0.22em] text-[var(--color-text-info,#60a5fa)] mb-2">
|
||||||
live production, streaming, and post-production technology. We
|
Broadcast Beat
|
||||||
report on the equipment, services, and people that move the
|
</div>
|
||||||
professional video industry forward.
|
<h1 className="font-serif text-4xl md:text-5xl font-bold tracking-tight">About</h1>
|
||||||
</p>
|
<p className="mt-3 text-[#9ca3af] text-base max-w-2xl">
|
||||||
<p>
|
An independent trade publication covering broadcast, live production, streaming, and post-production technology.
|
||||||
We cover the major industry shows — NAB, IBC, BroadcastAsia, MPTS,
|
</p>
|
||||||
and others — track product launches and acquisitions, and publish
|
</header>
|
||||||
interviews with the engineers, post supervisors, and executives
|
|
||||||
building the next generation of workflows.
|
<div className="grid grid-cols-1 md:grid-cols-3 gap-4 mb-10">
|
||||||
</p>
|
<Stat label="Years covering the industry" value="20+" />
|
||||||
<p>
|
<Stat label="Shows tracked annually" value="14+" />
|
||||||
Editorial decisions are made independently of advertising. We do
|
<Stat label="Stories archived" value="29k+" />
|
||||||
not accept payment for editorial coverage. Vendor-supplied press
|
</div>
|
||||||
releases routed through our distribution platform are rewritten
|
|
||||||
by our staff or AI assistants according to our editorial style
|
<section className="space-y-6 text-[#d1d5db] text-[15px] leading-relaxed">
|
||||||
guide; the original submission is preserved on file.
|
<Block title="What we cover">
|
||||||
</p>
|
Broadcast Beat reports on the equipment, services, and people
|
||||||
|
that move the professional video industry forward. We follow
|
||||||
|
product launches, executive moves, acquisitions, and the live
|
||||||
|
production / IP / cloud workflows reshaping how content gets
|
||||||
|
made and delivered.
|
||||||
|
</Block>
|
||||||
|
|
||||||
|
<Block title="Where we go">
|
||||||
|
We cover the major industry shows in person and remotely — NAB
|
||||||
|
Show, IBC, BroadcastAsia, MPTS, InfoComm, and more — track
|
||||||
|
product launches and acquisitions year-round, and publish
|
||||||
|
interviews with the engineers, post supervisors, and executives
|
||||||
|
building the next generation of workflows.
|
||||||
|
</Block>
|
||||||
|
|
||||||
|
<Block title="How we work">
|
||||||
|
Editorial decisions are made independently of advertising. We
|
||||||
|
do not accept payment for editorial coverage. Vendor-supplied
|
||||||
|
press releases routed through our distribution platform are
|
||||||
|
rewritten by our staff or AI assistants according to our
|
||||||
|
editorial style guide; the original submission is preserved on
|
||||||
|
file. Our AI personas are clearly labeled wherever they appear.
|
||||||
|
</Block>
|
||||||
|
|
||||||
|
<Block title="Get involved">
|
||||||
|
For editorial pitches: <a className="text-[var(--color-text-info,#60a5fa)] hover:underline" href="mailto:editor@broadcastbeat.com">editor@broadcastbeat.com</a>.
|
||||||
|
{" "}For advertising: <a className="text-[var(--color-text-info,#60a5fa)] hover:underline" href="/about/advertise">see the media kit</a>.
|
||||||
|
{" "}For our team: <a className="text-[var(--color-text-info,#60a5fa)] hover:underline" href="/about/team">meet the editorial team</a>.
|
||||||
|
</Block>
|
||||||
|
</section>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
{/* Sidebar: 300x600 + rotating 300x250s */}
|
||||||
|
<aside className="mt-10 lg:mt-0" aria-label="Advertisements">
|
||||||
|
<div className="lg:sticky lg:top-24">
|
||||||
|
<SidebarAdStack />
|
||||||
|
</div>
|
||||||
|
</aside>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</div>
|
||||||
<Footer />
|
<Footer />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function Stat({ label, value }: { label: string; value: string }) {
|
||||||
|
return (
|
||||||
|
<div className="rounded border border-[#252525] bg-[#0b0f17] p-4">
|
||||||
|
<div className="font-serif text-3xl text-white">{value}</div>
|
||||||
|
<div className="mt-1 text-[10px] font-mono uppercase tracking-[0.16em] text-[#6b7280]">
|
||||||
|
{label}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function Block({ title, children }: { title: string; children: React.ReactNode }) {
|
||||||
|
return (
|
||||||
|
<div className="rounded border border-[#1e1e1e] bg-[#0b0f17]/70 p-5">
|
||||||
|
<h2 className="font-mono text-xs uppercase tracking-[0.18em] text-[var(--color-text-info,#60a5fa)] mb-2">
|
||||||
|
{title}
|
||||||
|
</h2>
|
||||||
|
<p className="text-[15px] leading-relaxed">{children}</p>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
import { createClient } from "@supabase/supabase-js";
|
import { createClient } from "@supabase/supabase-js";
|
||||||
import Header from "@/components/Header";
|
import Header from "@/components/Header";
|
||||||
import Footer from "@/components/Footer";
|
import Footer from "@/components/Footer";
|
||||||
import AdImage from "@/components/AdImage";
|
import SidebarAdStack from "@/components/SidebarAdStack";
|
||||||
import { ADS_728X90, shuffle } from "@/lib/ads";
|
|
||||||
|
|
||||||
export const dynamic = "force-dynamic";
|
export const dynamic = "force-dynamic";
|
||||||
export const revalidate = 600;
|
export const revalidate = 600;
|
||||||
@@ -38,44 +37,52 @@ export default async function TeamPage() {
|
|||||||
return (
|
return (
|
||||||
<div className="min-h-screen bg-background">
|
<div className="min-h-screen bg-background">
|
||||||
<Header />
|
<Header />
|
||||||
<main className="mx-auto max-w-5xl px-6 py-12 text-[#e5e7eb]">
|
<div className="mx-auto max-w-6xl px-6 py-12 text-[#e5e7eb]">
|
||||||
<h1 className="font-serif text-4xl font-bold tracking-tight mb-2">Editorial team</h1>
|
<div className="lg:grid lg:grid-cols-[1fr,300px] lg:gap-10">
|
||||||
<p className="text-sm text-[#9ca3af] mb-10">
|
<main>
|
||||||
Staff journalists by beat. We are a mix of human reporters and trained
|
<header className="mb-8 border-b border-[#252525] pb-6">
|
||||||
AI personas operating under house style.
|
<div className="text-[10px] font-mono uppercase tracking-[0.22em] text-[var(--color-text-info,#60a5fa)] mb-2">
|
||||||
</p>
|
Broadcast Beat
|
||||||
<ul className="grid grid-cols-1 md:grid-cols-2 gap-5">
|
|
||||||
{team.map((p) => (
|
|
||||||
<li key={p.slug} className="rounded border border-[#252525] bg-[#0b0f17] p-5 flex gap-4">
|
|
||||||
{p.avatar_url && (
|
|
||||||
<img
|
|
||||||
src={p.avatar_url}
|
|
||||||
alt={p.name}
|
|
||||||
width={64}
|
|
||||||
height={64}
|
|
||||||
className="rounded-full border border-[#252525]"
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
<div className="flex-1">
|
|
||||||
<h2 className="font-serif text-lg font-semibold">{p.name}</h2>
|
|
||||||
{p.beat && (
|
|
||||||
<div className="text-[10px] font-mono uppercase tracking-wider text-[var(--color-text-info,#60a5fa)] mt-0.5">
|
|
||||||
{p.beat.replace(/-/g, " ")}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{p.bio && <p className="text-sm text-[#9ca3af] mt-2 leading-relaxed">{p.bio}</p>}
|
|
||||||
</div>
|
</div>
|
||||||
</li>
|
<h1 className="font-serif text-4xl md:text-5xl font-bold tracking-tight">Editorial team</h1>
|
||||||
))}
|
<p className="mt-3 text-[#9ca3af] text-base">
|
||||||
</ul>
|
Staff journalists by beat — a mix of human reporters and trained AI personas operating under house style.
|
||||||
|
</p>
|
||||||
|
</header>
|
||||||
|
|
||||||
{/* In-content 728x90 banner */}
|
<ul className="grid grid-cols-1 md:grid-cols-2 gap-5">
|
||||||
{ADS_728X90.length > 0 && (
|
{team.map((p) => (
|
||||||
<div className="mt-12 hidden md:flex justify-center" aria-label="Advertisement">
|
<li key={p.slug} className="rounded border border-[#252525] bg-[#0b0f17] p-5 flex gap-4 hover:border-[var(--color-text-info,#60a5fa)]/60 transition-colors">
|
||||||
<AdImage ad={shuffle(ADS_728X90)[0]} page="team" />
|
{p.avatar_url && (
|
||||||
</div>
|
<img
|
||||||
)}
|
src={p.avatar_url}
|
||||||
</main>
|
alt={p.name}
|
||||||
|
width={64}
|
||||||
|
height={64}
|
||||||
|
className="rounded-full border border-[#252525] flex-shrink-0"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<div className="flex-1 min-w-0">
|
||||||
|
<h2 className="font-serif text-lg font-semibold">{p.name}</h2>
|
||||||
|
{p.beat && (
|
||||||
|
<div className="text-[10px] font-mono uppercase tracking-wider text-[var(--color-text-info,#60a5fa)] mt-0.5">
|
||||||
|
{p.beat.replace(/-/g, " ")}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{p.bio && <p className="text-sm text-[#9ca3af] mt-2 leading-relaxed">{p.bio}</p>}
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<aside className="mt-10 lg:mt-0" aria-label="Advertisements">
|
||||||
|
<div className="lg:sticky lg:top-24">
|
||||||
|
<SidebarAdStack />
|
||||||
|
</div>
|
||||||
|
</aside>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<Footer />
|
<Footer />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { createClient } from "@supabase/supabase-js";
|
|||||||
import Header from "@/components/Header";
|
import Header from "@/components/Header";
|
||||||
import Footer from "@/components/Footer";
|
import Footer from "@/components/Footer";
|
||||||
import AdImage from "@/components/AdImage";
|
import AdImage from "@/components/AdImage";
|
||||||
|
import SidebarAdStack from "@/components/SidebarAdStack";
|
||||||
import { ADS_728X90, shuffle } from "@/lib/ads";
|
import { ADS_728X90, shuffle } from "@/lib/ads";
|
||||||
|
|
||||||
export const dynamic = "force-dynamic";
|
export const dynamic = "force-dynamic";
|
||||||
@@ -162,11 +163,13 @@ export default async function EventCoveragePage({
|
|||||||
return (
|
return (
|
||||||
<div className="min-h-screen bg-background">
|
<div className="min-h-screen bg-background">
|
||||||
<Header />
|
<Header />
|
||||||
<main className="mx-auto max-w-5xl px-6 py-10 text-[#e5e7eb]">
|
<div className="mx-auto max-w-6xl px-6 py-10 text-[#e5e7eb]">
|
||||||
<script
|
<script
|
||||||
type="application/ld+json"
|
type="application/ld+json"
|
||||||
dangerouslySetInnerHTML={{ __html: JSON.stringify(eventJsonLd) }}
|
dangerouslySetInnerHTML={{ __html: JSON.stringify(eventJsonLd) }}
|
||||||
/>
|
/>
|
||||||
|
<div className="lg:grid lg:grid-cols-[1fr,300px] lg:gap-8">
|
||||||
|
<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,#60a5fa)] hover:underline">
|
||||||
← All events
|
← All events
|
||||||
</Link>
|
</Link>
|
||||||
@@ -245,7 +248,16 @@ export default async function EventCoveragePage({
|
|||||||
</ul>
|
</ul>
|
||||||
)}
|
)}
|
||||||
</section>
|
</section>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
|
{/* Sidebar: 300x600 + rotating 300x250s */}
|
||||||
|
<aside className="mt-10 lg:mt-0" aria-label="Advertisements">
|
||||||
|
<div className="lg:sticky lg:top-24">
|
||||||
|
<SidebarAdStack />
|
||||||
|
</div>
|
||||||
|
</aside>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<Footer />
|
<Footer />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user