style: format code biome
Local Build and Deploy / deploy (push) Failing after 46s

This commit is contained in:
openhands committed 2026-07-13 21:57:41 +02:00
1 parent 8efd032cc6
commit df38dccbf1
735 files changed
+128321 -120870

No files matched your search

+230 -199
View File
@@ -1,212 +1,243 @@
import { getTranslations } from "next-intl/server";
import Link from "next/link";
import Image from "next/image";
import Link from "next/link";
import { getTranslations } from "next-intl/server";
import { HomeLoginForm } from "@/components/auth/home-login-form";
import { avatarImageUrl, excerpt } from "@/lib/format";
import { prisma } from "@/lib/prisma";
import { siteSettings } from "@/lib/services/site-settings";
import { HomeLoginForm } from "@/components/auth/home-login-form";
export default async function GuestView() {
const t = await getTranslations("pages.home");
const _hotelName = await siteSettings.get("hotel_name", "Atom");
const imager =
(await siteSettings.get("habbo_imaging_url", "https://www.habbo.com/habbo-imaging/avatarimage")) ?? "";
const t = await getTranslations("pages.home");
const _hotelName = await siteSettings.get("hotel_name", "Atom");
const imager =
(await siteSettings.get(
"habbo_imaging_url",
"https://www.habbo.com/habbo-imaging/avatarimage",
)) ?? "";
let articles: Array<{ slug: string; title: string; shortStory: string; image: string }> = [];
try {
articles = await prisma.websiteArticles.findMany({
orderBy: { createdAt: "desc" },
take: 8,
select: { slug: true, title: true, shortStory: true, image: true },
});
} catch {}
let articles: Array<{
slug: string;
title: string;
shortStory: string;
image: string;
}> = [];
try {
articles = await prisma.websiteArticles.findMany({
orderBy: { createdAt: "desc" },
take: 8,
select: { slug: true, title: true, shortStory: true, image: true },
});
} catch {}
let recentUsers: Array<{ username: string; look: string }> = [];
try {
recentUsers = await prisma.user.findMany({
orderBy: { lastOnline: "desc" },
take: 12,
select: { username: true, look: true },
});
} catch {}
let recentUsers: Array<{ username: string; look: string }> = [];
try {
recentUsers = await prisma.user.findMany({
orderBy: { lastOnline: "desc" },
take: 12,
select: { username: true, look: true },
});
} catch {}
return (
<div className="flex flex-col gap-4 md:flex-row">
<div className="flex w-full flex-col gap-4 md:w-1/3 md:flex-shrink-0">
<div
className="overflow-hidden rounded-lg border"
style={{ borderColor: "color-mix(in srgb, var(--color-text-muted) 22%, transparent)" }}
>
<div className="relative h-[120px] overflow-hidden md:h-[150px]">
<div
className="absolute inset-0"
style={{
backgroundImage: "url(/assets/images/kasja_mepage_header.png)",
backgroundSize: "cover",
backgroundPosition: "center 30%",
backgroundRepeat: "no-repeat",
}}
/>
<div
className="absolute inset-0"
style={{
background:
"linear-gradient(135deg, rgba(0,0,0,0.65) 0%, rgba(0,0,0,0.15) 50%, rgba(0,0,0,0.5) 100%)",
}}
/>
<div
className="absolute -bottom-8 right-4 w-32 h-32 rounded-full opacity-[0.12] blur-[60px]"
style={{ background: "var(--color-primary)" }}
/>
</div>
<div className="p-3" style={{ backgroundColor: "var(--color-surface)" }}>
<HomeLoginForm />
</div>
</div>
return (
<div className="flex flex-col gap-4 md:flex-row">
<div className="flex w-full flex-col gap-4 md:w-1/3 md:flex-shrink-0">
<div
className="overflow-hidden rounded-lg border"
style={{
borderColor:
"color-mix(in srgb, var(--color-text-muted) 22%, transparent)",
}}
>
<div className="relative h-[120px] overflow-hidden md:h-[150px]">
<div
className="absolute inset-0"
style={{
backgroundImage: "url(/assets/images/kasja_mepage_header.png)",
backgroundSize: "cover",
backgroundPosition: "center 30%",
backgroundRepeat: "no-repeat",
}}
/>
<div
className="absolute inset-0"
style={{
background:
"linear-gradient(135deg, rgba(0,0,0,0.65) 0%, rgba(0,0,0,0.15) 50%, rgba(0,0,0,0.5) 100%)",
}}
/>
<div
className="absolute -bottom-8 right-4 w-32 h-32 rounded-full opacity-[0.12] blur-[60px]"
style={{ background: "var(--color-primary)" }}
/>
</div>
<div
className="p-3"
style={{ backgroundColor: "var(--color-surface)" }}
>
<HomeLoginForm />
</div>
</div>
<a href="/register" className="relative block">
<div
className="inline-block overflow-hidden rounded-lg border"
style={{ borderColor: "color-mix(in srgb, var(--color-text-muted) 22%, transparent)" }}
>
<Image
src="/assets/images/EnterHubbly.png"
alt="Register"
width={300}
height={100}
className="block"
unoptimized
/>
</div>
<span
className="pointer-events-none absolute inset-0 flex items-center text-4xl font-extrabold text-white text-shadow"
style={{ marginLeft: "15px" }}
>
REGISTER NOW
</span>
</a>
<a href="/register" className="relative block">
<div
className="inline-block overflow-hidden rounded-lg border"
style={{
borderColor:
"color-mix(in srgb, var(--color-text-muted) 22%, transparent)",
}}
>
<Image
src="/assets/images/EnterHubbly.png"
alt="Register"
width={300}
height={100}
className="block"
unoptimized
/>
</div>
<span
className="pointer-events-none absolute inset-0 flex items-center text-4xl font-extrabold text-white text-shadow"
style={{ marginLeft: "15px" }}
>
REGISTER NOW
</span>
</a>
{recentUsers.length > 0 && (
<div
className="overflow-hidden rounded-lg border"
style={{
borderColor: "color-mix(in srgb, var(--color-text-muted) 22%, transparent)",
backgroundColor: "var(--color-surface)",
}}
>
<div
className="flex h-12 w-full items-center justify-center bg-repeat"
style={{
background:
"linear-gradient(140deg, #0A1F0A 0%, #0F2D0F 20%, #153C15 40%, #1B4A1B 60%, #205820 75%, #1A4A1A 90%, #143814 100%)",
}}
>
<h2 className="px-3 text-xl font-bold text-white">Recent Users</h2>
</div>
<div className="grid grid-cols-4 sm:grid-cols-6 gap-3 p-3">
{recentUsers.map((u) => (
<div
key={u.username}
className="relative overflow-visible rounded-md p-0 shadow-lg"
style={{
width: "50px",
height: "50px",
justifySelf: "center",
backgroundColor: "var(--color-surface)",
}}
>
<Image
src={avatarImageUrl(imager, u.look, { headOnly: true, direction: 3 })}
alt={u.username}
width={50}
height={62}
style={{
position: "absolute",
top: "-12px",
left: "50%",
transform: "translateX(-50%)",
maxWidth: "none",
maxHeight: "none",
}}
unoptimized
/>
</div>
))}
</div>
</div>
)}
</div>
{recentUsers.length > 0 && (
<div
className="overflow-hidden rounded-lg border"
style={{
borderColor:
"color-mix(in srgb, var(--color-text-muted) 22%, transparent)",
backgroundColor: "var(--color-surface)",
}}
>
<div
className="flex h-12 w-full items-center justify-center bg-repeat"
style={{
background:
"linear-gradient(140deg, #0A1F0A 0%, #0F2D0F 20%, #153C15 40%, #1B4A1B 60%, #205820 75%, #1A4A1A 90%, #143814 100%)",
}}
>
<h2 className="px-3 text-xl font-bold text-white">
Recent Users
</h2>
</div>
<div className="grid grid-cols-4 sm:grid-cols-6 gap-3 p-3">
{recentUsers.map((u) => (
<div
key={u.username}
className="relative overflow-visible rounded-md p-0 shadow-lg"
style={{
width: "50px",
height: "50px",
justifySelf: "center",
backgroundColor: "var(--color-surface)",
}}
>
<Image
src={avatarImageUrl(imager, u.look, {
headOnly: true,
direction: 3,
})}
alt={u.username}
width={50}
height={62}
style={{
position: "absolute",
top: "-12px",
left: "50%",
transform: "translateX(-50%)",
maxWidth: "none",
maxHeight: "none",
}}
unoptimized
/>
</div>
))}
</div>
</div>
)}
</div>
<div className="flex w-full flex-col gap-4 md:w-2/3">
<div
className="overflow-hidden rounded-lg border"
style={{
borderColor: "color-mix(in srgb, var(--color-text-muted) 22%, transparent)",
backgroundColor: "var(--color-surface)",
}}
>
<div
className="flex h-12 w-full items-center justify-center"
style={{
background:
"linear-gradient(140deg, #1a3a5c 0%, #1e4a6e 20%, #2a5a80 40%, #3a6a90 60%, #4a7aa0 75%, #3a6a90 90%, #2a5a80 100%)",
}}
>
<h2 className="text-xl font-bold text-white">{t("latestNews") || "Latest News"}</h2>
</div>
<div className="p-4">
{articles.length === 0 ? (
<p
className="py-8 text-center"
style={{ color: "var(--color-text-muted-readable, var(--color-text-muted))" }}
>
{t("noArticles")}
</p>
) : (
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2">
{articles.map((a) => (
<Link
key={a.slug}
href={`/news/${a.slug}`}
className="group relative w-full overflow-hidden rounded-lg transition-all duration-200"
style={{
height: "215px",
backgroundColor: "var(--color-surface)",
border: "1px solid color-mix(in srgb, var(--color-text-muted) 15%, transparent)",
}}
>
<div className="relative h-full w-full overflow-hidden rounded-lg">
<Image
src={a.image}
alt={a.title}
fill
className="rounded-lg object-cover transition-all duration-300 group-hover:scale-105"
unoptimized
/>
<div
className="absolute left-0 w-full p-2"
style={{
bottom: "-2px",
background: "linear-gradient(to top, rgba(0,0,0,0.85) 0%, transparent 100%)",
}}
>
<h3 className="truncate text-lg font-semibold text-white text-shadow-sm">
{a.title}
</h3>
{a.shortStory && (
<p className="truncate text-xs font-normal text-white text-shadow-sm">
{excerpt(a.shortStory, 80)}
</p>
)}
</div>
</div>
</Link>
))}
</div>
)}
</div>
</div>
</div>
</div>
);
<div className="flex w-full flex-col gap-4 md:w-2/3">
<div
className="overflow-hidden rounded-lg border"
style={{
borderColor:
"color-mix(in srgb, var(--color-text-muted) 22%, transparent)",
backgroundColor: "var(--color-surface)",
}}
>
<div
className="flex h-12 w-full items-center justify-center"
style={{
background:
"linear-gradient(140deg, #1a3a5c 0%, #1e4a6e 20%, #2a5a80 40%, #3a6a90 60%, #4a7aa0 75%, #3a6a90 90%, #2a5a80 100%)",
}}
>
<h2 className="text-xl font-bold text-white">
{t("latestNews") || "Latest News"}
</h2>
</div>
<div className="p-4">
{articles.length === 0 ? (
<p
className="py-8 text-center"
style={{
color:
"var(--color-text-muted-readable, var(--color-text-muted))",
}}
>
{t("noArticles")}
</p>
) : (
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2">
{articles.map((a) => (
<Link
key={a.slug}
href={`/news/${a.slug}`}
className="group relative w-full overflow-hidden rounded-lg transition-all duration-200"
style={{
height: "215px",
backgroundColor: "var(--color-surface)",
border:
"1px solid color-mix(in srgb, var(--color-text-muted) 15%, transparent)",
}}
>
<div className="relative h-full w-full overflow-hidden rounded-lg">
<Image
src={a.image}
alt={a.title}
fill
className="rounded-lg object-cover transition-all duration-300 group-hover:scale-105"
unoptimized
/>
<div
className="absolute left-0 w-full p-2"
style={{
bottom: "-2px",
background:
"linear-gradient(to top, rgba(0,0,0,0.85) 0%, transparent 100%)",
}}
>
<h3 className="truncate text-lg font-semibold text-white text-shadow-sm">
{a.title}
</h3>
{a.shortStory && (
<p className="truncate text-xs font-normal text-white text-shadow-sm">
{excerpt(a.shortStory, 80)}
</p>
)}
</div>
</div>
</Link>
))}
</div>
)}
</div>
</div>
</div>
</div>
);
}
+222 -188
View File
@@ -1,202 +1,236 @@
import { getTranslations } from "next-intl/server";
import Link from "next/link";
import Image from "next/image";
import Link from "next/link";
import { getTranslations } from "next-intl/server";
import { avatarImageUrl, excerpt } from "@/lib/format";
import { prisma } from "@/lib/prisma";
import { siteSettings } from "@/lib/services/site-settings";
interface UserViewProps {
userId: number;
username: string;
look: string;
userId: number;
username: string;
look: string;
}
export default async function UserView({ userId, username, look }: UserViewProps) {
const t = await getTranslations("pages.home");
const hotelName = (await siteSettings.get("hotel_name", "Atom")) ?? "Atom";
const imager =
(await siteSettings.get("habbo_imaging_url", "https://www.habbo.com/habbo-imaging/avatarimage")) ?? "";
export default async function UserView({
userId,
username,
look,
}: UserViewProps) {
const t = await getTranslations("pages.home");
const hotelName = (await siteSettings.get("hotel_name", "Atom")) ?? "Atom";
const imager =
(await siteSettings.get(
"habbo_imaging_url",
"https://www.habbo.com/habbo-imaging/avatarimage",
)) ?? "";
let onlineFriends: Array<{ username: string; look: string }> = [];
try {
const friendships = await prisma.messengerFriendships.findMany({
where: { OR: [{ userOneId: userId }, { userTwoId: userId }] },
select: { userOneId: true, userTwoId: true },
});
const friendIds = friendships.map((f) => (f.userOneId === userId ? f.userTwoId : f.userOneId));
if (friendIds.length > 0) {
onlineFriends = await prisma.user.findMany({
where: { id: { in: friendIds }, online: "1" },
take: 10,
select: { username: true, look: true },
});
}
} catch {}
let onlineFriends: Array<{ username: string; look: string }> = [];
try {
const friendships = await prisma.messengerFriendships.findMany({
where: { OR: [{ userOneId: userId }, { userTwoId: userId }] },
select: { userOneId: true, userTwoId: true },
});
const friendIds = friendships.map((f) =>
f.userOneId === userId ? f.userTwoId : f.userOneId,
);
if (friendIds.length > 0) {
onlineFriends = await prisma.user.findMany({
where: { id: { in: friendIds }, online: "1" },
take: 10,
select: { username: true, look: true },
});
}
} catch {}
const [latestArticle] = await prisma.websiteArticles
.findMany({
orderBy: { createdAt: "desc" },
take: 1,
select: { slug: true, title: true, shortStory: true, image: true },
})
.catch(() => []);
const [latestArticle] = await prisma.websiteArticles
.findMany({
orderBy: { createdAt: "desc" },
take: 1,
select: { slug: true, title: true, shortStory: true, image: true },
})
.catch(() => []);
return (
<div className="flex flex-col gap-6 md:flex-row">
<div className="flex w-full flex-col gap-6 md:w-3/4">
<div className="relative flex h-[200px] items-end overflow-hidden rounded-lg">
<div
className="absolute inset-0"
style={{
backgroundImage: "url(/assets/images/kasja_mepage_header.png)",
backgroundSize: "cover",
backgroundPosition: "center 30%",
backgroundRepeat: "no-repeat",
}}
/>
<div
className="absolute inset-0"
style={{
background:
"linear-gradient(135deg, rgba(0,0,0,0.6) 0%, rgba(0,0,0,0.15) 40%, rgba(0,0,0,0.25) 65%, rgba(0,0,0,0.6) 100%)",
}}
/>
<div
className="absolute -bottom-10 -right-10 w-64 h-64 rounded-full opacity-[0.15] blur-[80px]"
style={{ background: "var(--color-primary)" }}
/>
<div
className="absolute -top-10 -left-10 w-48 h-48 rounded-full opacity-[0.08] blur-[60px]"
style={{ background: "var(--color-primary)" }}
/>
<div className="relative z-10 flex w-full items-end justify-between px-6 pb-2">
<Link href={`/u/${username}`} className="transition-transform duration-300 hover:scale-105 -mb-8">
<Image
src={avatarImageUrl(imager, look, { size: "l", direction: 2 })}
alt={username}
width={64}
height={110}
className="drop-shadow-2xl"
style={{ imageRendering: "pixelated" }}
unoptimized
/>
</Link>
<div className="flex items-center mb-4">
<Link href="/client" target="_blank" rel="noopener noreferrer" prefetch={true}>
<button
type="button"
className="group rounded-full px-7 py-3 text-sm font-bold tracking-wider transition-all duration-300 hover:scale-105 active:scale-95"
style={{
background:
"linear-gradient(135deg, color-mix(in srgb, var(--color-primary) 92%, white), color-mix(in srgb, var(--color-primary) 92%, black))",
color: "var(--button-text-color-readable, var(--button-text-color))",
border: "1px solid color-mix(in srgb, var(--color-primary) 60%, rgba(255,255,255,0.2))",
boxShadow:
"0 4px 24px color-mix(in srgb, var(--color-primary) 35%, transparent), inset 0 1px 0 rgba(255,255,255,0.2)",
}}
>
{t("enterHotel", { hotelName })}
<svg
className="inline-block ml-2 w-4 h-4 transition-transform duration-300 group-hover:translate-x-0.5"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2.5} d="M9 5l7 7-7 7" />
</svg>
</button>
</Link>
</div>
</div>
</div>
return (
<div className="flex flex-col gap-6 md:flex-row">
<div className="flex w-full flex-col gap-6 md:w-3/4">
<div className="relative flex h-[200px] items-end overflow-hidden rounded-lg">
<div
className="absolute inset-0"
style={{
backgroundImage: "url(/assets/images/kasja_mepage_header.png)",
backgroundSize: "cover",
backgroundPosition: "center 30%",
backgroundRepeat: "no-repeat",
}}
/>
<div
className="absolute inset-0"
style={{
background:
"linear-gradient(135deg, rgba(0,0,0,0.6) 0%, rgba(0,0,0,0.15) 40%, rgba(0,0,0,0.25) 65%, rgba(0,0,0,0.6) 100%)",
}}
/>
<div
className="absolute -bottom-10 -right-10 w-64 h-64 rounded-full opacity-[0.15] blur-[80px]"
style={{ background: "var(--color-primary)" }}
/>
<div
className="absolute -top-10 -left-10 w-48 h-48 rounded-full opacity-[0.08] blur-[60px]"
style={{ background: "var(--color-primary)" }}
/>
<div className="relative z-10 flex w-full items-end justify-between px-6 pb-2">
<Link
href={`/u/${username}`}
className="transition-transform duration-300 hover:scale-105 -mb-8"
>
<Image
src={avatarImageUrl(imager, look, { size: "l", direction: 2 })}
alt={username}
width={64}
height={110}
className="drop-shadow-2xl"
style={{ imageRendering: "pixelated" }}
unoptimized
/>
</Link>
<div className="flex items-center mb-4">
<Link
href="/client"
target="_blank"
rel="noopener noreferrer"
prefetch={true}
>
<button
type="button"
className="group rounded-full px-7 py-3 text-sm font-bold tracking-wider transition-all duration-300 hover:scale-105 active:scale-95"
style={{
background:
"linear-gradient(135deg, color-mix(in srgb, var(--color-primary) 92%, white), color-mix(in srgb, var(--color-primary) 92%, black))",
color:
"var(--button-text-color-readable, var(--button-text-color))",
border:
"1px solid color-mix(in srgb, var(--color-primary) 60%, rgba(255,255,255,0.2))",
boxShadow:
"0 4px 24px color-mix(in srgb, var(--color-primary) 35%, transparent), inset 0 1px 0 rgba(255,255,255,0.2)",
}}
>
{t("enterHotel", { hotelName })}
<svg
className="inline-block ml-2 w-4 h-4 transition-transform duration-300 group-hover:translate-x-0.5"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2.5}
d="M9 5l7 7-7 7"
/>
</svg>
</button>
</Link>
</div>
</div>
</div>
<div
className="flex flex-col gap-3 rounded-lg border p-1 lg:flex-row"
style={{
backgroundColor: "var(--color-surface)",
borderColor: "color-mix(in srgb, var(--color-text-muted) 22%, transparent)",
}}
>
<div
className="relative flex items-center justify-center rounded p-2 text-sm font-semibold"
style={{ backgroundColor: "#e9b124" }}
>
<span className="relative text-white">{t("onlineFriends")}</span>
</div>
<div className="flex items-center gap-3 px-3">
{onlineFriends.length === 0 ? (
<p
className="mb-3 block w-full text-center text-xs font-medium md:mb-0 md:text-left"
style={{ color: "var(--color-text-muted-readable, var(--color-text-muted))" }}
>
{t("noFriendsOnline")}
</p>
) : (
onlineFriends.map((f) => (
<Link
key={f.username}
href={`/u/${f.username}`}
className="transition-all duration-200 hover:scale-110"
>
<Image
src={avatarImageUrl(imager, f.look, { headOnly: true })}
alt={f.username}
width={40}
height={40}
className="h-10 w-10"
title={f.username}
unoptimized
/>
</Link>
))
)}
</div>
</div>
</div>
<div
className="flex flex-col gap-3 rounded-lg border p-1 lg:flex-row"
style={{
backgroundColor: "var(--color-surface)",
borderColor:
"color-mix(in srgb, var(--color-text-muted) 22%, transparent)",
}}
>
<div
className="relative flex items-center justify-center rounded p-2 text-sm font-semibold"
style={{ backgroundColor: "#e9b124" }}
>
<span className="relative text-white">{t("onlineFriends")}</span>
</div>
<div className="flex items-center gap-3 px-3">
{onlineFriends.length === 0 ? (
<p
className="mb-3 block w-full text-center text-xs font-medium md:mb-0 md:text-left"
style={{
color:
"var(--color-text-muted-readable, var(--color-text-muted))",
}}
>
{t("noFriendsOnline")}
</p>
) : (
onlineFriends.map((f) => (
<Link
key={f.username}
href={`/u/${f.username}`}
className="transition-all duration-200 hover:scale-110"
>
<Image
src={avatarImageUrl(imager, f.look, { headOnly: true })}
alt={f.username}
width={40}
height={40}
className="h-10 w-10"
title={f.username}
unoptimized
/>
</Link>
))
)}
</div>
</div>
</div>
<div className="flex w-full flex-col gap-6 md:w-1/4">
{latestArticle ? (
<div
className="overflow-hidden rounded-lg border"
style={{
backgroundColor: "var(--color-surface)",
borderColor: "color-mix(in srgb, var(--color-text-muted) 22%, transparent)",
}}
>
<div
className="flex h-12 items-center justify-center"
style={{
background:
"linear-gradient(140deg, #1a3a5c 0%, #1e4a6e 20%, #2a5a80 40%, #3a6a90 60%, #4a7aa0 75%, #3a6a90 90%, #2a5a80 100%)",
}}
>
<h2 className="text-lg font-bold text-white">{t("latestArticle")}</h2>
</div>
<Link href={`/news/${latestArticle.slug}`} className="group block">
<div className="relative aspect-[16/9] overflow-hidden">
<Image
src={latestArticle.image}
alt={latestArticle.title}
fill
className="object-cover transition-transform duration-300 group-hover:scale-105"
unoptimized
/>
</div>
<div className="p-3">
<h3 className="text-sm font-semibold">{latestArticle.title}</h3>
{latestArticle.shortStory && (
<p
className="mt-1 text-xs"
style={{ color: "var(--color-text-muted-readable, var(--color-text-muted))" }}
>
{excerpt(latestArticle.shortStory, 100)}
</p>
)}
</div>
</Link>
</div>
) : null}
</div>
</div>
);
<div className="flex w-full flex-col gap-6 md:w-1/4">
{latestArticle ? (
<div
className="overflow-hidden rounded-lg border"
style={{
backgroundColor: "var(--color-surface)",
borderColor:
"color-mix(in srgb, var(--color-text-muted) 22%, transparent)",
}}
>
<div
className="flex h-12 items-center justify-center"
style={{
background:
"linear-gradient(140deg, #1a3a5c 0%, #1e4a6e 20%, #2a5a80 40%, #3a6a90 60%, #4a7aa0 75%, #3a6a90 90%, #2a5a80 100%)",
}}
>
<h2 className="text-lg font-bold text-white">
{t("latestArticle")}
</h2>
</div>
<Link href={`/news/${latestArticle.slug}`} className="group block">
<div className="relative aspect-[16/9] overflow-hidden">
<Image
src={latestArticle.image}
alt={latestArticle.title}
fill
className="object-cover transition-transform duration-300 group-hover:scale-105"
unoptimized
/>
</div>
<div className="p-3">
<h3 className="text-sm font-semibold">{latestArticle.title}</h3>
{latestArticle.shortStory && (
<p
className="mt-1 text-xs"
style={{
color:
"var(--color-text-muted-readable, var(--color-text-muted))",
}}
>
{excerpt(latestArticle.shortStory, 100)}
</p>
)}
</div>
</Link>
</div>
) : null}
</div>
</div>
);
}