diff --git a/src/app/AppProviders.tsx b/src/app/AppProviders.tsx index f09ced8..a5c1d70 100644 --- a/src/app/AppProviders.tsx +++ b/src/app/AppProviders.tsx @@ -1,6 +1,6 @@ "use client"; -import { useEffect, type ReactNode } from "react"; +import { useEffect, useState, type CSSProperties, type ReactNode } from "react"; import { usePathname } from "next/navigation"; import { ThemeProvider } from "../components/theme"; import { LanguageProvider } from "../i18n/LanguageProvider"; @@ -20,18 +20,42 @@ export function AppProviders({ const { isOpen, isMinimized, close, toggleOpen } = useMoltbotStore(); const applyDefaults = useOpenClawConsoleStore((state) => state.applyDefaults); const pathname = usePathname(); + const [isMobileViewport, setIsMobileViewport] = useState(false); const isOpenClawWorkspace = pathname.startsWith("/xworkmate") || pathname.startsWith("/services/openclaw"); - // Always reserve space if open and not minimized, since we only have "Float/Sidebar" mode now - // and user wants it to NEVER cover the homepage. - const reserveSpace = !isOpenClawWorkspace && isOpen && !isMinimized; + const reserveSpace = + !isOpenClawWorkspace && isOpen && !isMinimized && !isMobileViewport; useEffect(() => { applyDefaults(assistantDefaults); }, [applyDefaults, assistantDefaults]); + useEffect(() => { + if (typeof window === "undefined") { + return; + } + + const mediaQuery = window.matchMedia("(max-width: 1023px)"); + const syncViewport = () => { + setIsMobileViewport(mediaQuery.matches); + }; + + syncViewport(); + mediaQuery.addEventListener("change", syncViewport); + + return () => { + mediaQuery.removeEventListener("change", syncViewport); + }; + }, []); + + useEffect(() => { + if (isMobileViewport && !isOpenClawWorkspace) { + close(); + } + }, [close, isMobileViewport, isOpenClawWorkspace]); + return ( @@ -40,7 +64,7 @@ export function AppProviders({ style={ { "--assistant-reserve-offset": reserveSpace ? "400px" : "0px", - } as React.CSSProperties + } as CSSProperties } className={cn( "flex-1 flex flex-col relative w-full overflow-hidden transition-[padding] duration-300 ease-in-out", diff --git a/src/app/page.tsx b/src/app/page.tsx index ffecd06..78d3038 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -77,12 +77,12 @@ export default function HomePage() { )} >
-
+
-
+
@@ -104,43 +104,45 @@ export function HeroSection() { const t = translations[language].marketing.home; return ( -
-
-
+
+
+
{t.hero.eyebrow && ( -

+

{t.hero.eyebrow}

)} -

+

{t.hero.title}

-

{t.hero.subtitle}

+

+ {t.hero.subtitle} +

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

{t.trustedBy}

-
+
@@ -149,8 +151,8 @@ export function HeroSection() {
-
-
+
+
{t.heroCards.map((card) => { const Icon = getIcon(card.title, PlusCircle); return ( @@ -174,12 +176,12 @@ export function NextStepsSection() { const t = translations[language].marketing.home; return ( -
-
-

+

+
+

{t.nextSteps.title}

- + {t.nextSteps.badge}
@@ -189,9 +191,9 @@ export function NextStepsSection() { return (
-
+
@@ -284,14 +286,19 @@ export function StatsSection() { ]; return ( -
-
+
+
{displayStats.map((stat, index: number) => ( -
-
+
+
{stat.value}
-

{stat.label}

+

+ {stat.label} +

))}
@@ -345,22 +352,22 @@ export function ShortcutsSection() { })); return ( -
-
+
+
-

+

{t.shortcuts.title}

-

{t.shortcuts.subtitle}

+

{t.shortcuts.subtitle}

-
- - -
@@ -372,12 +379,12 @@ export function ShortcutsSection() { -
+
-
+
{item.title}
@@ -403,7 +410,7 @@ type LatestBlogPost = { function LogoPill({ label }: { label: string }) { return ( - +
{label} diff --git a/src/components/AskAIDialog.tsx b/src/components/AskAIDialog.tsx index 3647a9c..de8dbc0 100644 --- a/src/components/AskAIDialog.tsx +++ b/src/components/AskAIDialog.tsx @@ -50,57 +50,67 @@ export function AskAIDialog({ } return ( -
-
-
-
-

- XWorkmate -

-

- AI Assistant -

+ <> + {open ? ( + + +
-
- - +
+
- -
- -
-
+ ); } diff --git a/src/components/HeroCard.tsx b/src/components/HeroCard.tsx index 9219a63..96deaa8 100644 --- a/src/components/HeroCard.tsx +++ b/src/components/HeroCard.tsx @@ -59,23 +59,25 @@ export function HeroCard({ onClick={hasGuide ? openGuide : undefined} onKeyDown={handleCardKeyDown} className={cn( - "group relative flex items-start gap-4 rounded-2xl border border-surface-border bg-surface p-6 transition-all duration-300", + "group relative flex items-start gap-4 overflow-hidden rounded-[1.6rem] border border-surface-border bg-white/88 p-5 shadow-[0_18px_42px_rgba(15,23,42,0.05)] transition-all duration-300 sm:rounded-2xl sm:p-6", hasGuide ? "cursor-pointer hover:border-primary/50 hover:bg-surface-hover" : "hover:border-primary/50 hover:bg-surface-hover", showGuide ? "border-primary/50 shadow-lg" : "", )} > -
+
-
+
-

{title}

-

{description}

+

+ {title} +

+

{description}

{hasGuide ? ( - + 点击查看向导 @@ -86,13 +88,16 @@ export function HeroCard({ {guide ? (
-
-
-

+
+
+

@@ -109,7 +114,7 @@ export function HeroCard({

-
+
{guide.steps.map((step, idx) => (
{idx !== guide.steps.length - 1 ? (