Compare commits

...

1 Commits

Author SHA1 Message Date
Jiayuan Zhang
f4f83740a8 feat(web): surface latest release in landing hero
Add a "What's new" badge above the hero headline that pulls the most
recent entry from the existing changelog dictionary and links straight
to its anchor on /changelog. Visitors now see at a glance that the
product is shipping every few days, addressing the GitHub feedback that
the changelog was buried.

Refs multica-ai/multica#2361

Co-authored-by: multica-agent <github@multica.ai>
2026-05-10 14:33:41 +08:00
4 changed files with 45 additions and 1 deletions

View File

@@ -2,7 +2,7 @@
import Image from "next/image";
import Link from "next/link";
import { Download } from "lucide-react";
import { ArrowRight, Download } from "lucide-react";
import { useAuthStore } from "@multica/core/auth";
import { captureDownloadIntent } from "@multica/core/analytics";
import { useLocale } from "../i18n";
@@ -18,6 +18,7 @@ import {
export function LandingHero() {
const { t } = useLocale();
const user = useAuthStore((s) => s.user);
const latestRelease = t.changelog.entries[0];
return (
<div className="relative min-h-full overflow-hidden bg-[#05070b] text-white">
@@ -29,6 +30,13 @@ export function LandingHero() {
className="mx-auto max-w-[1320px] px-4 pb-16 pt-28 sm:px-6 sm:pt-32 lg:px-8 lg:pb-24 lg:pt-36"
>
<div className="mx-auto max-w-[1120px] text-center">
{latestRelease && (
<WhatsNewBadge
label={t.hero.whatsNewLabel}
version={latestRelease.version}
title={latestRelease.title}
/>
)}
<h1 className="font-[family-name:var(--font-serif)] text-[3.65rem] leading-[0.93] tracking-[-0.038em] text-white drop-shadow-[0_10px_34px_rgba(0,0,0,0.32)] sm:text-[4.85rem] lg:text-[6.4rem]">
{t.hero.headlineLine1}
<br />
@@ -91,6 +99,39 @@ export function LandingHero() {
);
}
function WhatsNewBadge({
label,
version,
title,
}: {
label: string;
version: string;
title: string;
}) {
const anchor = `release-${version.replace(/\./g, "-")}`;
return (
<div className="mb-7 flex justify-center">
<Link
href={`/changelog#${anchor}`}
className="group inline-flex max-w-full items-center gap-2 rounded-full border border-white/18 bg-white/8 px-3 py-1.5 text-[12px] font-medium text-white/85 backdrop-blur-sm transition-colors hover:border-white/32 hover:bg-white/12 sm:gap-2.5 sm:text-[13px]"
>
<span className="inline-flex items-center gap-1.5 rounded-full bg-white/12 px-2 py-0.5 text-[11px] font-semibold uppercase tracking-[0.08em] text-white">
{label}
</span>
<span className="tabular-nums text-white/70">v{version}</span>
<span aria-hidden className="hidden h-3 w-px bg-white/18 sm:inline-block" />
<span className="hidden truncate sm:inline-block sm:max-w-[420px]">
{title}
</span>
<ArrowRight
aria-hidden
className="size-3.5 shrink-0 text-white/60 transition-transform group-hover:translate-x-0.5 group-hover:text-white"
/>
</Link>
</div>
);
}
function LandingBackdrop() {
return (
<div className="pointer-events-none absolute inset-0">

View File

@@ -19,6 +19,7 @@ export function createEnDict(allowSignup: boolean): LandingDict {
downloadDesktop: "Download Desktop",
worksWith: "Works with",
imageAlt: "Multica board view \u2014 issues managed by humans and agents",
whatsNewLabel: "What\u2019s new",
},
features: {

View File

@@ -29,6 +29,7 @@ export type LandingDict = {
downloadDesktop: string;
worksWith: string;
imageAlt: string;
whatsNewLabel: string;
};
features: {
teammates: FeatureSection;

View File

@@ -19,6 +19,7 @@ export function createZhDict(allowSignup: boolean): LandingDict {
downloadDesktop: "下载桌面端",
worksWith: "支持",
imageAlt: "Multica \u770b\u677f\u89c6\u56fe\u2014\u2014\u4eba\u7c7b\u548c 智能体 \u534f\u540c\u7ba1\u7406\u4efb\u52a1",
whatsNewLabel: "\u6700\u65b0\u66f4\u65b0",
},
features: {