diff --git a/src/app/home-page/page.tsx b/src/app/home-page/page.tsx
index 5c0d830..b179687 100644
--- a/src/app/home-page/page.tsx
+++ b/src/app/home-page/page.tsx
@@ -4,7 +4,7 @@ import Header from "@/components/Header";
import Footer from "@/components/Footer";
import FeaturedBentoFromDb from '@/components/FeaturedBentoFromDb';
import FeaturedCarouselServer from '@/components/FeaturedCarouselServer';
-import DoubleTicker from '@/components/DoubleTicker';
+import LiveWireTicker from '@/components/LiveWireTicker';
import NewsTicker from "./components/NewsTicker";
import FeaturedBento from "./components/FeaturedBento";
import SpotlightCarousel from "./components/SpotlightCarousel";
@@ -147,10 +147,10 @@ export default function HomePage() {
Broadcast Beat — Broadcast Engineering News & Insights
- {/* Scrolling news + forum tickers */}
+ {/* Scrolling news ticker */}
}>
-
+
diff --git a/src/components/DoubleTicker.tsx b/src/components/DoubleTicker.tsx
deleted file mode 100644
index a76a06f..0000000
--- a/src/components/DoubleTicker.tsx
+++ /dev/null
@@ -1,93 +0,0 @@
-import Link from "next/link";
-import { createClient } from "@supabase/supabase-js";
-
-export const dynamic = "force-dynamic";
-
-interface TickerItem {
- href: string;
- title: string;
-}
-
-export default async function DoubleTicker() {
- const sb = createClient(
- process.env.NEXT_PUBLIC_SUPABASE_URL!,
- process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
- {
- db: { schema: (process.env.NEXT_PUBLIC_SUPABASE_SCHEMA || "bb") as "public" },
- auth: { persistSession: false },
- }
- );
-
- const [wireRes, forumRes] = await Promise.all([
- sb
- .from("wp_imported_posts")
- .select("wp_slug, title")
- .eq("status", "published")
- .order("wp_published_at", { ascending: false, nullsFirst: false })
- .limit(14),
- sb
- .from("forum_threads")
- .select("id, title")
- .order("last_reply_at", { ascending: false, nullsFirst: false })
- .limit(14),
- ]);
-
- const wire: TickerItem[] = (wireRes.data || []).map((r: any) => ({
- href: `/news/${r.wp_slug}`,
- title: r.title,
- }));
- const forum: TickerItem[] = (forumRes.data || []).map((r: any) => ({
- href: `/forum/thread/${r.id}`,
- title: r.title,
- }));
-
- // Fallback to keep layout sensible if either feed is empty
- const wireItems = wire.length > 0 ? wire : [{ href: "/news", title: "Latest broadcast industry news loading…" }];
- const forumItems = forum.length > 0 ? forum : [{ href: "/forum", title: "Join the conversation in the forum" }];
-
- return (
-
- {/* LANE 1 — LIVE WIRE (red) */}
-
-
-
- LIVE WIRE
-
-
-
- {[...wireItems, ...wireItems].map((item, i) => (
-
- ›
- {item.title}
-
- ))}
-
-
-
-
- {/* LANE 2 — RECENT FORUM POSTS (teal-green) */}
-
-
-
- RECENT FORUM POSTS
-
-
-
- {[...forumItems, ...forumItems].map((item, i) => (
-
- ›
- {item.title}
-
- ))}
-
-
-
-
- );
-}
diff --git a/src/components/LiveWireTicker.tsx b/src/components/LiveWireTicker.tsx
new file mode 100644
index 0000000..11d2235
--- /dev/null
+++ b/src/components/LiveWireTicker.tsx
@@ -0,0 +1,118 @@
+import Link from "next/link";
+import { createClient } from "@supabase/supabase-js";
+
+export const dynamic = "force-dynamic";
+
+interface Item {
+ slug: string;
+ title: string;
+ published_at: string;
+ source_code: string;
+}
+
+const SOURCE_CODES: { match: RegExp; code: string }[] = [
+ { match: /blackmagic|davinci/i, code: "BMD" },
+ { match: /magewell/i, code: "MGW" },
+ { match: /aja/i, code: "AJA" },
+ { match: /sony/i, code: "SONY" },
+ { match: /matrox/i, code: "MTRX" },
+ { match: /telestream/i, code: "TLST" },
+ { match: /grass valley/i, code: "GV" },
+ { match: /lawo/i, code: "LAWO" },
+ { match: /calrec/i, code: "CLRC" },
+ { match: /zixi/i, code: "ZIXI" },
+ { match: /liveu/i, code: "LVU" },
+ { match: /netflix/i, code: "NFLX" },
+ { match: /youtube/i, code: "YT" },
+ { match: /amazon|aws/i, code: "AWS" },
+];
+
+function codeFor(title: string): string {
+ for (const { match, code } of SOURCE_CODES) if (match.test(title)) return code;
+ return "WIRE";
+}
+
+function hhmm(iso: string): string {
+ const d = new Date(iso);
+ const h = String(d.getUTCHours()).padStart(2, "0");
+ const m = String(d.getUTCMinutes()).padStart(2, "0");
+ return `${h}:${m}`;
+}
+
+export default async function LiveWireTicker() {
+ const sb = createClient(
+ process.env.NEXT_PUBLIC_SUPABASE_URL!,
+ process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
+ {
+ db: { schema: (process.env.NEXT_PUBLIC_SUPABASE_SCHEMA || "bb") as "public" },
+ auth: { persistSession: false },
+ }
+ );
+
+ const [wp, ai] = await Promise.all([
+ sb
+ .from("wp_imported_posts")
+ .select("wp_slug, title, wp_published_at")
+ .eq("status", "published")
+ .order("wp_published_at", { ascending: false })
+ .limit(12),
+ sb
+ .from("ai_rewritten_articles")
+ .select("slug, title, published_at")
+ .eq("status", "published")
+ .order("published_at", { ascending: false, nullsFirst: false })
+ .limit(6),
+ ]);
+
+ const items: Item[] = [];
+ for (const r of (wp.data || []) as any[]) {
+ items.push({
+ slug: r.wp_slug,
+ title: r.title,
+ published_at: r.wp_published_at,
+ source_code: codeFor(r.title || ""),
+ });
+ }
+ for (const r of (ai.data || []) as any[]) {
+ items.push({
+ slug: r.slug,
+ title: r.title,
+ published_at: r.published_at,
+ source_code: codeFor(r.title || ""),
+ });
+ }
+ items.sort(
+ (a, b) => new Date(b.published_at).getTime() - new Date(a.published_at).getTime()
+ );
+
+ const display = items.slice(0, 14);
+
+ return (
+
+
+
+ Live wire
+
+
+
+ {[...display, ...display].map((it, i) => (
+
+ [{hhmm(it.published_at)}]
+ [{it.source_code}]
+ {it.title}
+
+ ))}
+
+
+
+
+ );
+}
diff --git a/src/styles/tailwind.css b/src/styles/tailwind.css
index a07e74f..15f4bde 100644
--- a/src/styles/tailwind.css
+++ b/src/styles/tailwind.css
@@ -807,197 +807,4 @@ h1, h2, h3 {
.ProseMirror strong { font-weight: 700; color: #fff; }
.ProseMirror em { font-style: italic; }
.ProseMirror u { text-decoration: underline; }
-.ProseMirror s { text-decoration: line-through; }
-
-/* =====================
- DOUBLE TICKER (LIVE WIRE + RECENT FORUM POSTS)
- ===================== */
-.bb-ticker-stack {
- width: 100%;
- border-bottom: 1px solid #1a1a1a;
-}
-
-.bb-ticker {
- display: flex;
- align-items: stretch;
- height: 34px;
- width: 100%;
- overflow: hidden;
- position: relative;
-}
-
-.bb-ticker--wire {
- background: linear-gradient(90deg, #0a0a0a 0%, #161616 50%, #0a0a0a 100%);
- border-bottom: 1px solid #1f1212;
-}
-
-.bb-ticker--forum {
- background: linear-gradient(90deg, #08120e 0%, #0f1d18 50%, #08120e 100%);
-}
-
-.bb-ticker-label {
- flex-shrink: 0;
- display: inline-flex;
- align-items: center;
- gap: 8px;
- padding: 0 16px;
- font-family: var(--font-body);
- font-size: 11px;
- font-weight: 800;
- letter-spacing: 0.22em;
- color: #ffffff;
- white-space: nowrap;
- position: relative;
- z-index: 2;
-}
-
-.bb-ticker-label--red {
- background: linear-gradient(90deg, #d40000 0%, #a30000 100%);
- box-shadow: 0 0 18px rgba(212, 0, 0, 0.45), inset 0 -1px 0 rgba(255, 255, 255, 0.05);
- clip-path: polygon(0 0, 100% 0, calc(100% - 10px) 100%, 0 100%);
- padding-right: 24px;
-}
-
-.bb-ticker-label--green {
- background: linear-gradient(90deg, #0c8a63 0%, #086149 100%);
- box-shadow: 0 0 18px rgba(12, 138, 99, 0.40), inset 0 -1px 0 rgba(255, 255, 255, 0.05);
- clip-path: polygon(0 0, 100% 0, calc(100% - 10px) 100%, 0 100%);
- padding-right: 24px;
-}
-
-.bb-ticker-pulse {
- display: inline-block;
- width: 7px;
- height: 7px;
- border-radius: 999px;
- background: #ffffff;
- box-shadow: 0 0 8px rgba(255, 255, 255, 0.9);
- animation: bb-ticker-pulse-anim 1.4s ease-in-out infinite;
-}
-
-.bb-ticker-pulse--green {
- animation-duration: 1.8s;
-}
-
-@keyframes bb-ticker-pulse-anim {
- 0%, 100% { opacity: 1; transform: scale(1); }
- 50% { opacity: 0.4; transform: scale(1.25); }
-}
-
-.bb-ticker-mask {
- flex: 1;
- min-width: 0;
- overflow: hidden;
- position: relative;
- -webkit-mask-image: linear-gradient(to right, transparent 0, #000 28px, #000 calc(100% - 28px), transparent 100%);
- mask-image: linear-gradient(to right, transparent 0, #000 28px, #000 calc(100% - 28px), transparent 100%);
-}
-
-.bb-ticker-track {
- display: inline-flex;
- align-items: center;
- width: max-content;
- white-space: nowrap;
- animation-name: bb-ticker-scroll;
- animation-timing-function: linear;
- animation-iteration-count: infinite;
- will-change: transform;
-}
-
-/* Different speeds so the two lanes never sync up — feels alive */
-.bb-ticker-track--wire { animation-duration: 65s; }
-.bb-ticker-track--forum { animation-duration: 82s; }
-
-.bb-ticker-track:hover,
-.bb-ticker-track:focus-within {
- animation-play-state: paused;
-}
-
-@keyframes bb-ticker-scroll {
- 0% { transform: translate3d(0, 0, 0); }
- 100% { transform: translate3d(-50%, 0, 0); }
-}
-
-.bb-ticker-item {
- display: inline-flex;
- align-items: center;
- gap: 10px;
- padding: 0 22px;
- height: 34px;
- text-decoration: none;
- font-family: var(--font-body);
- font-size: 13px;
- font-weight: 500;
- letter-spacing: 0.005em;
- color: #d8d8d8;
- transition: color 0.18s ease;
- border-right: 1px solid rgba(255, 255, 255, 0.05);
-}
-
-.bb-ticker-item--wire:hover { color: #ff6b6b; }
-.bb-ticker-item--forum:hover { color: #5eead4; }
-
-.bb-ticker-bullet {
- flex-shrink: 0;
- font-weight: 700;
- color: rgba(255, 255, 255, 0.35);
-}
-
-.bb-ticker-item--wire:hover .bb-ticker-bullet { color: #ff6b6b; }
-.bb-ticker-item--forum:hover .bb-ticker-bullet { color: #5eead4; }
-
-/* =====================
- BROWSE NAV BAR (sits below the 728x90 header banner)
- ===================== */
-.bb-browse-bar {
- background: linear-gradient(180deg, #0b0b0b 0%, #0e0e0e 100%);
- border-top: 1px solid #1a1a1a;
- border-bottom: 1px solid #1a1a1a;
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
-}
-
-.bb-browse-row {
- display: flex;
- align-items: stretch;
- gap: 0;
- height: 44px;
-}
-
-.bb-browse-item {
- position: relative;
- display: inline-flex;
- align-items: center;
- padding: 0 16px;
- font-family: var(--font-body);
- font-size: 12px;
- font-weight: 700;
- letter-spacing: 0.06em;
- text-transform: uppercase;
- color: #cccccc;
- text-decoration: none;
- border-right: 1px solid #1a1a1a;
- transition: background 0.15s ease, color 0.15s ease;
-}
-
-.bb-browse-item:first-of-type {
- border-left: 1px solid #1a1a1a;
-}
-
-.bb-browse-item:hover,
-.bb-browse-item[aria-expanded="true"] {
- background: #161616;
- color: var(--color-accent);
-}
-
-.bb-browse-item .bb-browse-caret {
- display: inline-block;
- margin-left: 6px;
- font-size: 8px;
- opacity: 0.7;
- transform: translateY(-1px);
- transition: transform 0.15s ease;
-}
-
-.bb-browse-item[aria-expanded="true"] .bb-browse-caret {
- transform: rotate(180deg) translateY(1px);
-}
\ No newline at end of file
+.ProseMirror s { text-decoration: line-through; }
\ No newline at end of file