homepage: bento 3-up + 300x600 inline; word-safe excerpt; bigger sponsor logos

- FeaturedBentoFromDb: row below the hero is now a 3-up rail on the left
  with the Blackmagic 300x600 on the right, aligned with the hero's right
  edge. SidebarAdStack skips that 300x600 so the article-feed sidebar
  starts with the 300x250 stack instead.
- cleanExcerpt: render-time word-snap for excerpts that were hard-cut at a
  byte count (Matrox 50-years showed "Since 1976, the co" mid-word). Used
  on the bento hero subhead and the article-feed cards.
- SponsorLogoStrip: now also pulls every tracked_companies.featured=true
  brand (Rode, TBC Consoles, Plura, Autocue, Autoscript, Filmcraft,
  Lectrosonics, Prompter People, SanDisk, Sennheiser), and logos go from
  h-10/h-12 max-w-140 → h-14/h-16 max-w-180 with thicker padding.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Ryan Salazar
2026-05-29 10:56:38 +00:00
parent 0541103c89
commit 3b74f610a2
5 changed files with 110 additions and 48 deletions

View File

@@ -2,6 +2,9 @@ import Link from "next/link";
import { createClient } from "@supabase/supabase-js";
import { rewriteLegacyImageUrl } from "@/lib/legacy-image";
import StarRating from "@/components/StarRating";
import AdImage from "@/components/AdImage";
import { pickAds } from "@/lib/ads";
import { cleanExcerpt } from "@/lib/articles/excerpt";
export const dynamic = "force-dynamic";
@@ -53,7 +56,11 @@ export default async function FeaturedBento() {
if (rows.length === 0) return null;
const hero = rows[0];
const rail = rows.slice(1, 5);
// 3-up rail: room is reserved on the right of the same row for the
// Blackmagic 300x600 banner — see grid below. Dropped the 4th card so
// the banner can sit baseline-aligned with the hero's right edge.
const rail = rows.slice(1, 4);
const heroAd = pickAds("300x600", 1)[0] || null;
function img(r: Row): string {
return r.featured_image ? rewriteLegacyImageUrl(r.featured_image) : "/assets/images/article-placeholder.svg";
@@ -102,7 +109,7 @@ export default async function FeaturedBento() {
</h3>
{hero.excerpt && (
<p className="font-serif text-base md:text-lg text-[#cbd5e1] mt-3 max-w-2xl line-clamp-2">
{hero.excerpt}
{cleanExcerpt(hero.excerpt)}
</p>
)}
<div className="mt-4 flex flex-wrap items-center gap-3 text-[11px] font-mono text-[#9ca3af]">
@@ -114,34 +121,48 @@ export default async function FeaturedBento() {
</div>
</Link>
{/* 4-up rail BELOW the hero, vertical cards */}
<div className="grid grid-cols-2 md:grid-cols-4 gap-4 mt-4">
{rail.map((r) => (
<Link
key={r.wp_slug}
href={`/news/${r.wp_slug}`}
className="group block rounded border border-[#252525] bg-[#0b0f17] overflow-hidden hover:border-[var(--color-text-info,#60a5fa)] transition-colors"
>
<div className="aspect-[16/10] bg-[#111] relative">
<img
src={img(r)}
alt={r.featured_image_alt || r.title}
className="w-full h-full object-cover"
/>
</div>
<div className="p-3">
<div className="text-[9px] font-mono uppercase tracking-wider text-[var(--color-text-info,#60a5fa)] mb-1">
{r.category || "News"}
{/* Row below the hero — 3-up rail (left) + Blackmagic 300x600 (right).
Right column is locked to 300px so its edge aligns with the right
edge of the 21:9 hero above; SidebarAdStack downstream skips this
banner so it doesn't double-render. */}
<div className="grid grid-cols-1 lg:grid-cols-[minmax(0,1fr)_300px] gap-4 mt-4 items-start">
<div className="grid grid-cols-3 gap-3">
{rail.map((r) => (
<Link
key={r.wp_slug}
href={`/news/${r.wp_slug}`}
className="group block rounded border border-[#252525] bg-[#0b0f17] overflow-hidden hover:border-[var(--color-text-info,#60a5fa)] transition-colors"
>
<div className="aspect-[16/10] bg-[#111] relative">
<img
src={img(r)}
alt={r.featured_image_alt || r.title}
className="w-full h-full object-cover"
/>
</div>
<h4 className="font-serif text-sm leading-tight text-[#e5e7eb] group-hover:text-[var(--color-text-info,#60a5fa)] line-clamp-3">
{r.title}
</h4>
<div className="mt-2">
<StarRating seed={r.wp_slug} publishedAt={r.wp_published_at} size="sm" showCount={false} />
<div className="p-3">
<div className="text-[9px] font-mono uppercase tracking-wider text-[var(--color-text-info,#60a5fa)] mb-1">
{r.category || "News"}
</div>
<h4 className="font-serif text-sm leading-tight text-[#e5e7eb] group-hover:text-[var(--color-text-info,#60a5fa)] line-clamp-3">
{r.title}
</h4>
<div className="mt-2">
<StarRating seed={r.wp_slug} publishedAt={r.wp_published_at} size="sm" showCount={false} />
</div>
</div>
</Link>
))}
</div>
<aside className="hidden lg:block" aria-label="Premium sponsor">
{heroAd ? (
<AdImage ad={heroAd} priority />
) : (
<div className="w-[300px] h-[600px] bg-[#0d1520] border border-[#1e3a5f] rounded flex items-center justify-center text-[#888] text-xs uppercase tracking-widest">
Premium Sponsorship
</div>
</Link>
))}
)}
</aside>
</div>
</section>
);