bf48a1561c
Side-by-side kicked in at sm (640px), squeezing the text column hard on tablet widths. Moved the breakpoint to lg (1024px), matching the secondary posts' grid below, which already used lg for the same reason.
146 lines
6.4 KiB
TypeScript
146 lines
6.4 KiB
TypeScript
import Link from "next/link";
|
|
import Image from "next/image";
|
|
import { getBlogPosts } from "../lib/payload";
|
|
import { Reveal, RevealGroup, RevealItem } from "./Reveal";
|
|
import { ArrowRightIcon } from "./ArrowRightIcon";
|
|
|
|
export async function Blog() {
|
|
const posts = await getBlogPosts(3);
|
|
if (posts.length === 0) return null;
|
|
|
|
const featured = { ...posts[0], href: `/blog/${posts[0].slug}` };
|
|
const secondary = posts
|
|
.slice(1, 3)
|
|
.map((post) => ({ ...post, href: `/blog/${post.slug}` }));
|
|
|
|
return (
|
|
<div id="blog" className="flex flex-col gap-12 items-start pb-16 w-full bg-bg-base">
|
|
|
|
{/* Section header */}
|
|
<Reveal className="flex flex-col gap-2 items-start px-[var(--layout-padding-x)] w-full">
|
|
<p className="font-bold text-brand text-h-small">
|
|
Neue Impulse
|
|
</p>
|
|
<p
|
|
className="font-semibold text-text-primary text-h-section leading-normal"
|
|
style={{ fontFamily: "var(--font-lora)" }}
|
|
>
|
|
Gedanken, Methoden & Impulse
|
|
</p>
|
|
</Reveal>
|
|
|
|
{/* Posts grid */}
|
|
<RevealGroup className="flex flex-col gap-10 items-start px-[var(--layout-padding-x)] w-full">
|
|
|
|
{/* Featured post — image on top through lg (1024px), side-by-side
|
|
only from lg+ (was sm+, but that squeezed the text column too
|
|
hard on tablet widths — same reasoning as the secondary posts'
|
|
grid below, which already used this lg breakpoint).
|
|
lg:min-h stretches the row taller on large screens (the image's
|
|
lg:h-full and the text column's justify-between both follow) —
|
|
without it the card's height was purely driven by the text
|
|
column's content, which stays short regardless of viewport
|
|
width. */}
|
|
<RevealItem className="w-full border border-border rounded-xl overflow-hidden grid grid-cols-1 lg:grid-cols-12 lg:min-h-[26rem] transition-transform duration-300 hover:-translate-y-1">
|
|
<div className="relative w-full aspect-video lg:aspect-auto lg:col-span-7 lg:h-full bg-bg-muted">
|
|
{featured.thumbnail && (
|
|
<Image
|
|
alt=""
|
|
src={featured.thumbnail}
|
|
fill
|
|
sizes="(min-width: 1024px) 58vw, 100vw"
|
|
className="object-cover pointer-events-none"
|
|
/>
|
|
)}
|
|
</div>
|
|
<div className="flex flex-col justify-between gap-4 py-4 px-4 lg:pr-4 lg:pl-4 lg:col-span-5 min-w-0">
|
|
<div className="flex flex-col gap-3">
|
|
<div className="flex gap-2 items-center font-semibold text-text-muted text-body uppercase whitespace-nowrap">
|
|
<span>{featured.categories.join(", ")}</span>
|
|
<span>•</span>
|
|
<span>{featured.readTime} Min</span>
|
|
</div>
|
|
<div className="flex flex-col gap-4 text-text-primary">
|
|
<p
|
|
className="font-semibold text-h-section leading-normal"
|
|
style={{ fontFamily: "var(--font-lora)" }}
|
|
>
|
|
{featured.title}
|
|
</p>
|
|
<p className="font-normal text-body leading-6 line-clamp-2 lg:line-clamp-none">
|
|
{featured.excerpt}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
{/* flex + arrow as its own span — see Tools.tsx's comment on
|
|
this same fix (→'s glyph baseline sits low next to text). */}
|
|
<Link
|
|
href={featured.href}
|
|
className="flex items-center gap-1 font-bold text-body text-text-primary whitespace-nowrap hover:text-brand transition-colors"
|
|
>
|
|
<ArrowRightIcon />
|
|
<span>Zum Beitrag</span>
|
|
</Link>
|
|
</div>
|
|
</RevealItem>
|
|
|
|
{/* Secondary posts — image on top through lg (1024px), side-by-side
|
|
only from lg+. These sit 2-up (sm:grid-cols-2 below) well
|
|
before lg, so each card's own available width through the
|
|
640-1023px tablet range is too narrow for image+text side by
|
|
side — was sm:grid-cols-5, squeezing the text column. */}
|
|
<div className="grid grid-cols-1 sm:grid-cols-2 gap-6 w-full">
|
|
{secondary.map((post) => (
|
|
<RevealItem
|
|
key={post.id}
|
|
className="border border-border rounded-xl overflow-hidden grid grid-cols-1 lg:grid-cols-5 transition-transform duration-300 hover:-translate-y-1"
|
|
>
|
|
<div className="relative w-full aspect-video lg:aspect-auto lg:col-span-2 lg:h-[230px] bg-bg-muted">
|
|
{post.thumbnail && (
|
|
<Image
|
|
alt=""
|
|
src={post.thumbnail}
|
|
fill
|
|
sizes="(min-width: 1024px) 29vw, 100vw"
|
|
className="object-cover pointer-events-none"
|
|
/>
|
|
)}
|
|
</div>
|
|
<div className="flex flex-col justify-between gap-4 py-3 px-4 lg:col-span-3 min-w-0 text-text-primary">
|
|
<div className="flex flex-col gap-3">
|
|
<div className="flex gap-2 items-center font-semibold text-text-muted text-body uppercase whitespace-nowrap">
|
|
<span>{post.categories.join(", ")}</span>
|
|
<span>•</span>
|
|
<span>{post.readTime} Min</span>
|
|
</div>
|
|
<div className="flex flex-col gap-4">
|
|
<p
|
|
className="font-semibold text-h-small leading-normal"
|
|
style={{ fontFamily: "var(--font-lora)" }}
|
|
>
|
|
{post.title}
|
|
</p>
|
|
<p className="font-normal text-body leading-6 line-clamp-1 lg:line-clamp-none">
|
|
{post.excerpt}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
{/* flex + arrow as its own span — see the featured post's
|
|
own Link above / Tools.tsx's comment on this same fix. */}
|
|
<Link
|
|
href={post.href}
|
|
className="flex items-center gap-1 font-bold text-body whitespace-nowrap hover:text-brand transition-colors"
|
|
>
|
|
<ArrowRightIcon />
|
|
<span>Zum Beitrag</span>
|
|
</Link>
|
|
</div>
|
|
</RevealItem>
|
|
))}
|
|
</div>
|
|
|
|
</RevealGroup>
|
|
</div>
|
|
);
|
|
}
|