diff --git a/src/app/globals.css b/src/app/globals.css index 2c63f2a..795bcfc 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -8,6 +8,8 @@ :root { --font-geist-sans: "Geist", sans-serif; --font-geist-mono: "Geist Mono", monospace; + --font-editorial-display: + "Iowan Old Style", "Palatino Linotype", "Book Antiqua", Georgia, serif; --app-shell-nav-offset: 5.5rem; /* Light theme defaults */ @@ -89,6 +91,11 @@ body { font-size: var(--type-body-size); line-height: var(--type-body-line-height); background-color: var(--color-background); + background-image: linear-gradient( + 180deg, + rgba(255, 255, 255, 0.58), + rgba(255, 255, 255, 0) + ); color: var(--color-text); -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility; @@ -149,6 +156,13 @@ button { } } +@layer components { + .editorial-display { + font-family: var(--font-editorial-display); + letter-spacing: -0.04em; + } +} + @media (max-width: 1023px) { .mobile-home-shell { --color-background: #fbfaf7; diff --git a/src/app/page.tsx b/src/app/page.tsx index 680a0e1..fd62204 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -18,19 +18,25 @@ import { Terminal, Users, } from "lucide-react"; +import useSWR from "swr"; + import Footer from "../components/Footer"; +import { HeroCard } from "../components/HeroCard"; import UnifiedNavigation from "../components/UnifiedNavigation"; -import { useUserStore } from "../lib/userStore"; import { useLanguage } from "../i18n/LanguageProvider"; import { translations } from "../i18n/translations"; import { useMoltbotStore } from "../lib/moltbotStore"; +import { useUserStore } from "../lib/userStore"; import { cn } from "../lib/utils"; -import { AskAIDialog } from "../components/AskAIDialog"; -import { HeroCard } from "../components/HeroCard"; -import useSWR from "swr"; + +const HOME_SECTION_CLASS = + "rounded-[2rem] border border-slate-900/10 bg-white/90 shadow-[0_18px_40px_rgba(15,23,42,0.05)]"; +const HOME_SECTION_LABEL_CLASS = + "text-[0.68rem] font-semibold uppercase tracking-[0.26em] text-text-subtle"; +const HOME_LIST_CARD_CLASS = + "rounded-[1.5rem] border border-slate-900/10 bg-[#fcfbf8] transition duration-200"; const iconMap: Record = { - // English keys "Global Acceleration Network": Link, "Full-link SaaS Hosting": Layers, "AI-Driven Observability": Sparkles, @@ -45,7 +51,6 @@ const iconMap: Record = { "Machine-to-Machine": Layers, "Connect via CLI": Terminal, "REST & Admin APIs": Link, - // Chinese keys 全球加速网络: Link, "全链路 SaaS 托管": Layers, "AI 驱动的可观测性": Sparkles, @@ -67,22 +72,22 @@ export default function HomePage() { const { mode, isOpen } = useMoltbotStore(); return ( -
+
+
-
+
-
-
+
@@ -101,70 +106,113 @@ export default function HomePage() { export function HeroSection() { const { user } = useUserStore(); const { language } = useLanguage(); + const isChinese = language === "zh"; const t = translations[language].marketing.home; return ( -
-
-
- {t.hero.eyebrow && ( -

- {t.hero.eyebrow} +

+
+
+
+
+
+
+ +
+
+
+ {t.hero.eyebrow ? ( +

{t.hero.eyebrow}

+ ) : null} +

+ {t.hero.title} +

+

+ {t.hero.subtitle}

- )} -

- {t.hero.title} -

-

- {t.hero.subtitle} -

-
-
- {user ? ( -
-
- {t.signedIn.replace("{{username}}", user.username)} -
- ) : ( -
+ +
+ {user ? ( +
+
+ {t.signedIn.replace("{{username}}", user.username)} +
+ ) : ( + + )} + - )} - - -
-
-

{t.trustedBy}

-
- - - - - + +
+ +
+

{t.trustedBy}

+
+ + + + + +
-
-
-
- {t.heroCards.map((card) => { - const Icon = getIcon(card.title, PlusCircle); - return ( - - ); - })} + +
+
+
+

+ {isChinese ? "主要入口" : "Launch paths"} +

+

+ {isChinese + ? "从接入、托管到观测,保留原有入口,但改成更轻的阅读节奏。" + : "Keep the same entry points, but present them with a calmer editorial rhythm."} +

+
+ + {t.heroCards.length} {isChinese ? "个入口" : "entry paths"} + +
+ +
+ {t.heroCards.map((card) => { + const Icon = getIcon(card.title, PlusCircle); + return ( + + ); + })} +
@@ -176,40 +224,50 @@ export function NextStepsSection() { const t = translations[language].marketing.home; return ( -
-
-

- {t.nextSteps.title} -

- +
+
+
+

{t.nextSteps.title}

+

+ {language === "zh" + ? "保留原有 onboarding 内容,但改成更轻、更整齐的起步列表。" + : "Keep the same onboarding content, in a lighter and calmer starting list."} +

+
+ {t.nextSteps.badge}
+
{t.nextSteps.items.map((item, index: number) => { const Icon = getIcon(item.title, Users); return (
-
- -
-
-
- +
+
+
+ +
+ {item.status}
-

+

{item.title}

-
+ +
); })} @@ -286,17 +344,33 @@ export function StatsSection() { ]; return ( -
-
+
+
+
+

+ {language === "zh" ? "平台统计" : "Platform pulse"} +

+

+ {language === "zh" + ? "把关键数字收在同一条平静的视线上,不再单独做成重型数据舱。" + : "Keep key numbers in the same calm visual rhythm instead of a separate heavy dashboard block."} +

+
+ + {language === "zh" ? "每小时更新" : "Updated hourly"} + +
+ +
{displayStats.map((stat, index: number) => (
-
+
{stat.value}
-

+

{stat.label}

@@ -306,16 +380,6 @@ export function StatsSection() { ); } -type HomeStatsResponse = { - registeredUsers: number | null; - visits: { - daily: number | null; - weekly: number | null; - monthly: number | null; - }; - updatedAt: string; -}; - export function ShortcutsSection() { const { language } = useLanguage(); const t = translations[language].marketing.home; @@ -352,26 +416,37 @@ export function ShortcutsSection() { })); return ( -
-
+
+
-

- {t.shortcuts.title} +

{t.shortcuts.title}

+

+ {t.shortcuts.subtitle}

-

{t.shortcuts.subtitle}

-
- - -
+
{shortcutItems.map((item, index: number) => { const Icon = getIcon(item.title, Sparkles); @@ -379,19 +454,24 @@ export function ShortcutsSection() { -
+
-
+
{item.title}
-

{item.description}

+

+ {item.description} +

@@ -402,6 +482,16 @@ export function ShortcutsSection() { ); } +type HomeStatsResponse = { + registeredUsers: number | null; + visits: { + daily: number | null; + weekly: number | null; + monthly: number | null; + }; + updatedAt: string; +}; + type LatestBlogPost = { slug: string; title: string; @@ -410,8 +500,8 @@ type LatestBlogPost = { function LogoPill({ label }: { label: string }) { return ( - -
+ +
{label} ); diff --git a/src/app/xworkmate/admin/page.tsx b/src/app/xworkmate/admin/page.tsx index 68f9046..192ee5a 100644 --- a/src/app/xworkmate/admin/page.tsx +++ b/src/app/xworkmate/admin/page.tsx @@ -1,8 +1,6 @@ import { headers } from "next/headers"; import { redirect } from "next/navigation"; - export const dynamic = "force-dynamic"; - import { XWorkmateProfileEditor } from "@/components/xworkmate/XWorkmateProfileEditor"; import { buildSharedXWorkmateUrl, diff --git a/src/app/xworkmate/integrations/page.tsx b/src/app/xworkmate/integrations/page.tsx index 9a52775..a043365 100644 --- a/src/app/xworkmate/integrations/page.tsx +++ b/src/app/xworkmate/integrations/page.tsx @@ -1,8 +1,6 @@ import { headers } from "next/headers"; import { redirect } from "next/navigation"; - export const dynamic = "force-dynamic"; - import { XWorkmateProfileEditor } from "@/components/xworkmate/XWorkmateProfileEditor"; import { buildSharedXWorkmateUrl, diff --git a/src/components/Footer.tsx b/src/components/Footer.tsx index 4e02433..6165cfb 100644 --- a/src/components/Footer.tsx +++ b/src/components/Footer.tsx @@ -36,25 +36,16 @@ export default function Footer() { }; return ( -