feat(website): wording and style
This commit is contained in:
@@ -44,7 +44,7 @@ export default function Header() {
|
||||
animateOnHover={true}
|
||||
aria-hidden="true"
|
||||
>
|
||||
GUI Agent in your webpage
|
||||
AI Agent In Your Webpage
|
||||
</HyperText>
|
||||
</div>
|
||||
</Link>
|
||||
|
||||
74
packages/website/src/components/ui/marquee.tsx
Normal file
74
packages/website/src/components/ui/marquee.tsx
Normal file
@@ -0,0 +1,74 @@
|
||||
import { ComponentPropsWithoutRef } from 'react'
|
||||
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
interface MarqueeProps extends ComponentPropsWithoutRef<'div'> {
|
||||
/**
|
||||
* Optional CSS class name to apply custom styles
|
||||
*/
|
||||
className?: string
|
||||
/**
|
||||
* Whether to reverse the animation direction
|
||||
* @default false
|
||||
*/
|
||||
reverse?: boolean
|
||||
/**
|
||||
* Whether to pause the animation on hover
|
||||
* @default false
|
||||
*/
|
||||
pauseOnHover?: boolean
|
||||
/**
|
||||
* Content to be displayed in the marquee
|
||||
*/
|
||||
children: React.ReactNode
|
||||
/**
|
||||
* Whether to animate vertically instead of horizontally
|
||||
* @default false
|
||||
*/
|
||||
vertical?: boolean
|
||||
/**
|
||||
* Number of times to repeat the content
|
||||
* @default 4
|
||||
*/
|
||||
repeat?: number
|
||||
}
|
||||
|
||||
export function Marquee({
|
||||
className,
|
||||
reverse = false,
|
||||
pauseOnHover = false,
|
||||
children,
|
||||
vertical = false,
|
||||
repeat = 4,
|
||||
...props
|
||||
}: MarqueeProps) {
|
||||
return (
|
||||
<div
|
||||
{...props}
|
||||
className={cn(
|
||||
'group flex [gap:var(--gap)] overflow-hidden p-2 [--duration:40s] [--gap:1rem]',
|
||||
{
|
||||
'flex-row': !vertical,
|
||||
'flex-col': vertical,
|
||||
},
|
||||
className
|
||||
)}
|
||||
>
|
||||
{Array(repeat)
|
||||
.fill(0)
|
||||
.map((_, i) => (
|
||||
<div
|
||||
key={i}
|
||||
className={cn('flex shrink-0 justify-around [gap:var(--gap)]', {
|
||||
'animate-marquee flex-row': !vertical,
|
||||
'animate-marquee-vertical flex-col': vertical,
|
||||
'group-hover:[animation-play-state:paused]': pauseOnHover,
|
||||
'[animation-direction:reverse]': reverse,
|
||||
})}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -377,6 +377,24 @@ td {
|
||||
background-position: bottom center;
|
||||
}
|
||||
}
|
||||
--animate-marquee: marquee var(--duration) infinite linear;
|
||||
--animate-marquee-vertical: marquee-vertical var(--duration) linear infinite;
|
||||
@keyframes marquee {
|
||||
from {
|
||||
transform: translateX(0);
|
||||
}
|
||||
to {
|
||||
transform: translateX(calc(-100% - var(--gap)));
|
||||
}
|
||||
}
|
||||
@keyframes marquee-vertical {
|
||||
from {
|
||||
transform: translateY(0);
|
||||
}
|
||||
to {
|
||||
transform: translateY(calc(-100% - var(--gap)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* shadcn dark mode */
|
||||
|
||||
@@ -1,678 +1,20 @@
|
||||
/* eslint-disable react-dom/no-dangerously-set-innerhtml */
|
||||
import {
|
||||
Bot,
|
||||
Box,
|
||||
ExternalLink,
|
||||
MessageSquare,
|
||||
PlayCircle,
|
||||
Shield,
|
||||
Sparkles,
|
||||
Users,
|
||||
Zap,
|
||||
} from 'lucide-react'
|
||||
import { PageAgent } from 'page-agent'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { siGooglechrome } from 'simple-icons'
|
||||
import { Link, useSearchParams } from 'wouter'
|
||||
|
||||
import Footer from '../components/Footer'
|
||||
import Header from '../components/Header'
|
||||
import { AnimatedGradientText } from '../components/ui/animated-gradient-text'
|
||||
import { Highlighter } from '../components/ui/highlighter'
|
||||
import { NeonGradientCard } from '../components/ui/neon-gradient-card'
|
||||
import { Particles } from '../components/ui/particles'
|
||||
import { SparklesText } from '../components/ui/sparkles-text'
|
||||
import {
|
||||
CDN_DEMO_CN_URL,
|
||||
CDN_DEMO_URL,
|
||||
DEMO_API_KEY,
|
||||
DEMO_BASE_URL,
|
||||
DEMO_MODEL,
|
||||
} from '../constants'
|
||||
import { useLanguage } from '../i18n/context'
|
||||
|
||||
function getInjection(useCN?: boolean) {
|
||||
const cdn = useCN ? CDN_DEMO_CN_URL : CDN_DEMO_URL
|
||||
|
||||
const injection = encodeURI(
|
||||
`javascript:(function(){var s=document.createElement('script');s.src=\`${cdn}?t=\${Math.random()}\`;s.setAttribute('crossorigin', true);s.type="text/javascript";s.onload=()=>console.log('PageAgent script loaded!');document.body.appendChild(s);})();`
|
||||
)
|
||||
|
||||
return `
|
||||
<a
|
||||
href=${injection}
|
||||
class="inline-flex items-center text-xs px-3 py-2 bg-blue-500 text-white font-medium rounded-lg hover:shadow-md transform hover:scale-105 transition-all duration-200 cursor-move border-2 border-dashed border-green-300"
|
||||
draggable="true"
|
||||
onclick="return false;"
|
||||
title="Drag me to your bookmarks bar!"
|
||||
>
|
||||
✨PageAgent
|
||||
</a>
|
||||
`
|
||||
}
|
||||
import FeaturesSection from './home/FeaturesSection'
|
||||
import HeroSection from './home/HeroSection'
|
||||
import OneMoreThingSection from './home/OneMoreThingSection'
|
||||
import ScenariosSection from './home/ScenariosSection'
|
||||
|
||||
export default function HomePage() {
|
||||
const { language, isZh } = useLanguage()
|
||||
|
||||
const defaultTask = isZh
|
||||
? '从导航栏中进入文档页,打开"快速开始"相关的文档,帮我总结成 markdown'
|
||||
: 'Goto docs in navigation bar, find Quick-Start section, and summarize in markdown'
|
||||
|
||||
const [task, setTask] = useState(() => defaultTask)
|
||||
|
||||
// Update task when language changes
|
||||
useEffect(() => {
|
||||
setTask(defaultTask)
|
||||
}, [defaultTask])
|
||||
|
||||
const [params, setParams] = useSearchParams()
|
||||
const isOther = params.has('try_other')
|
||||
|
||||
const [activeTab, setActiveTab] = useState<'try' | 'other'>(isOther ? 'other' : 'try')
|
||||
const [cdnSource, setCdnSource] = useState<'international' | 'china'>('international')
|
||||
|
||||
const handleExecute = async () => {
|
||||
if (!task.trim()) return
|
||||
|
||||
const win = window as any
|
||||
|
||||
if (!win.pageAgent || win.pageAgent.disposed) {
|
||||
win.pageAgent = new PageAgent({
|
||||
// 把 react 根元素排除掉,挂了很多冒泡时间导致假阳
|
||||
interactiveBlacklist: [document.getElementById('root')!],
|
||||
language: language,
|
||||
|
||||
instructions: {
|
||||
system: 'You are a helpful assistant on PageAgent website.',
|
||||
getPageInstructions: (url) => {
|
||||
const hint = url.includes('page-agent') ? 'This is PageAgent demo page.' : undefined
|
||||
console.log('[instructions] getPageInstructions:', url, '->', hint)
|
||||
return hint
|
||||
},
|
||||
},
|
||||
|
||||
model:
|
||||
import.meta.env.DEV && import.meta.env.LLM_MODEL_NAME
|
||||
? import.meta.env.LLM_MODEL_NAME
|
||||
: DEMO_MODEL,
|
||||
baseURL:
|
||||
import.meta.env.DEV && import.meta.env.LLM_BASE_URL
|
||||
? import.meta.env.LLM_BASE_URL
|
||||
: DEMO_BASE_URL,
|
||||
apiKey:
|
||||
import.meta.env.DEV && import.meta.env.LLM_API_KEY
|
||||
? import.meta.env.LLM_API_KEY
|
||||
: DEMO_API_KEY,
|
||||
|
||||
// enableAskUser: false,
|
||||
// promptForNextTask: false,
|
||||
// enablePanel: false,
|
||||
})
|
||||
}
|
||||
|
||||
const result = await win.pageAgent.execute(task)
|
||||
console.log(result)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-linear-to-br from-blue-50 to-purple-50 dark:from-gray-900 dark:to-gray-800">
|
||||
<Header />
|
||||
|
||||
{/* Hero Section */}
|
||||
<main id="main-content">
|
||||
<section
|
||||
className="relative px-6 py-22 pb-18 lg:py-28 overflow-hidden"
|
||||
aria-labelledby="hero-heading"
|
||||
>
|
||||
<div className="max-w-7xl mx-auto text-center">
|
||||
{/* Background Pattern + Particles */}
|
||||
<div className="absolute inset-0 opacity-30" aria-hidden="true">
|
||||
<div className="absolute inset-0 bg-linear-to-r from-blue-400/20 to-purple-400/20 rounded-3xl transform rotate-1"></div>
|
||||
<div className="absolute inset-0 bg-linear-to-l from-purple-400/20 to-blue-400/20 rounded-3xl transform -rotate-1"></div>
|
||||
</div>
|
||||
<Particles
|
||||
className="absolute inset-0"
|
||||
quantity={80}
|
||||
staticity={30}
|
||||
ease={80}
|
||||
color="#6366f1"
|
||||
/>
|
||||
|
||||
<div className="relative z-10">
|
||||
<div className="inline-flex items-center px-4 py-2 mb-8 text-sm font-medium bg-white/90 dark:bg-gray-800/90 rounded-full shadow-lg border border-gray-200 dark:border-gray-700">
|
||||
<span
|
||||
className="w-2 h-2 bg-blue-500 rounded-full mr-2 animate-pulse"
|
||||
aria-hidden="true"
|
||||
></span>
|
||||
<AnimatedGradientText colorFrom="#3b82f6" colorTo="#8b5cf6">
|
||||
GUI Agent in your webpage
|
||||
</AnimatedGradientText>
|
||||
</div>
|
||||
|
||||
<h1
|
||||
id="hero-heading"
|
||||
className="text-5xl lg:text-7xl font-bold mb-8 bg-linear-to-r from-blue-600 to-purple-600 bg-clip-text text-transparent pb-1"
|
||||
>
|
||||
{isZh ? '让你的 Web 应用' : 'The AI Operator'}
|
||||
<br />
|
||||
{isZh ? '拥有 AI 操作员' : 'Living in Your Web App'}
|
||||
</h1>
|
||||
|
||||
<p className="text-xl lg:text-2xl text-gray-600 dark:text-gray-300 mb-12 max-w-4xl mx-auto leading-relaxed">
|
||||
<Highlighter action="underline" color="#8b5cf6" strokeWidth={2}>
|
||||
<span className="bg-linear-to-r from-blue-500 to-purple-500 bg-clip-text text-transparent font-bold">
|
||||
{isZh ? '🪄一行代码' : '🪄One line of code'}
|
||||
</span>
|
||||
</Highlighter>
|
||||
{isZh
|
||||
? ',为你的网站添加 GUI Agent。'
|
||||
: ' adds intelligent GUI Agents to your website.'}
|
||||
<br />
|
||||
{isZh
|
||||
? '用户/答疑机器人给出文字指示,AI 帮你操作页面。'
|
||||
: 'Users give natural language commands, AI handles the rest.'}
|
||||
</p>
|
||||
|
||||
{/* Try It Now Section - Tab Card */}
|
||||
<div className="mb-12">
|
||||
<div className="max-w-3xl mx-auto">
|
||||
<NeonGradientCard
|
||||
borderSize={2}
|
||||
borderRadius={20}
|
||||
neonColors={{ firstColor: '#ff00aa', secondColor: '#00FFF1' }}
|
||||
>
|
||||
{/* Tab Headers */}
|
||||
<div className="flex border-b border-gray-200 dark:border-gray-700">
|
||||
<button
|
||||
onClick={() => setActiveTab('try')}
|
||||
className={`flex-1 px-4 py-4 text-lg font-medium transition-colors duration-200 rounded-tl-2xl ${
|
||||
activeTab === 'try'
|
||||
? 'bg-linear-to-r from-blue-50 to-purple-50 dark:from-blue-900/30 dark:to-purple-900/30 text-blue-700 dark:text-blue-300 border-b-2 border-blue-500'
|
||||
: 'text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white hover:bg-gray-50 dark:hover:bg-gray-700'
|
||||
}`}
|
||||
>
|
||||
{isZh ? '🚀 立即尝试' : '🚀 Try It Now'}
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setActiveTab('other')}
|
||||
className={`flex-1 px-4 py-4 text-lg font-medium transition-colors duration-200 rounded-tr-2xl ${
|
||||
activeTab === 'other'
|
||||
? 'bg-linear-to-r from-green-50 to-blue-50 dark:from-green-900/30 dark:to-blue-900/30 text-green-700 dark:text-green-300 border-b-2 border-green-500'
|
||||
: 'text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white hover:bg-gray-50 dark:hover:bg-gray-700'
|
||||
}`}
|
||||
>
|
||||
{isZh ? '🌐 其他网页尝试' : '🌐 Try on Other Sites'}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Tab Content */}
|
||||
<div className="p-4">
|
||||
{activeTab === 'try' && (
|
||||
<div className="space-y-4">
|
||||
<div className="relative">
|
||||
<input
|
||||
value={task}
|
||||
onChange={(e) => setTask(e.target.value)}
|
||||
placeholder={
|
||||
isZh
|
||||
? '输入您想要 AI 执行的任务...'
|
||||
: 'Describe what you want AI to do...'
|
||||
}
|
||||
className="w-full px-4 py-3 pr-20 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white placeholder-gray-500 dark:placeholder-gray-400 focus:ring-2 focus:ring-blue-500 focus:border-transparent resize-none text-sm mb-0"
|
||||
data-page-agent-not-interactive
|
||||
/>
|
||||
<button
|
||||
onClick={handleExecute}
|
||||
// disabled
|
||||
// disabled={!task.trim()}
|
||||
className="absolute right-2 top-2 px-5 py-1.5 bg-linear-to-r from-blue-600 to-purple-600 text-white font-medium rounded-md hover:shadow-md transform hover:scale-105 transition-all duration-200 disabled:opacity-50 disabled:cursor-not-allowed disabled:transform-none text-sm"
|
||||
data-page-agent-not-interactive
|
||||
>
|
||||
{isZh ? '执行' : 'Run'}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{activeTab === 'other' && (
|
||||
<div className="grid md:grid-cols-2 gap-6">
|
||||
{/* 左侧:操作步骤 */}
|
||||
<div className="space-y-4">
|
||||
{/* Keyboard Shortcut Hint */}
|
||||
<div className="bg-blue-50 dark:bg-gray-700 p-4 rounded-lg">
|
||||
<p className="text-gray-700 dark:text-gray-300 text-sm mb-3">
|
||||
<span className="font-semibold">
|
||||
{isZh ? '步骤 1:' : 'Step 1:'}
|
||||
</span>{' '}
|
||||
{isZh ? '显示收藏夹栏' : 'Show your bookmarks bar'}
|
||||
</p>
|
||||
<div className="flex items-center justify-center gap-2">
|
||||
<kbd className="px-2 py-1 bg-white dark:bg-gray-600 border border-gray-300 dark:border-gray-500 rounded text-xs font-mono">
|
||||
Ctrl + Shift + B
|
||||
</kbd>
|
||||
<span className="text-gray-500 dark:text-gray-400">
|
||||
{isZh ? '或' : 'or'}
|
||||
</span>
|
||||
<kbd className="px-2 py-1 bg-white dark:bg-gray-600 border border-gray-300 dark:border-gray-500 rounded text-xs font-mono">
|
||||
⌘ + Shift + B
|
||||
</kbd>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Draggable Bookmarklet */}
|
||||
<div className="bg-green-50 dark:bg-gray-700 p-4 rounded-lg">
|
||||
<p className="text-gray-700 dark:text-gray-300 text-sm mb-3">
|
||||
<span className="font-semibold">
|
||||
{isZh ? '步骤 2:' : 'Step 2:'}
|
||||
</span>{' '}
|
||||
{isZh
|
||||
? '拖拽下面按钮到收藏夹栏'
|
||||
: 'Drag this button to your bookmarks'}
|
||||
</p>
|
||||
<div className="flex items-center justify-center gap-3">
|
||||
<select
|
||||
value={cdnSource}
|
||||
onChange={(e) =>
|
||||
setCdnSource(e.target.value as 'international' | 'china')
|
||||
}
|
||||
className="px-2 py-1.5 text-xs border border-gray-300 dark:border-gray-500 rounded bg-white dark:bg-gray-600 text-gray-700 dark:text-gray-200"
|
||||
>
|
||||
<option value="international">
|
||||
{isZh ? '国际' : 'International'}
|
||||
</option>
|
||||
<option value="china">
|
||||
{isZh ? '国内镜像' : 'China Mirror'}
|
||||
</option>
|
||||
</select>
|
||||
<div
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: getInjection(cdnSource === 'china'),
|
||||
}}
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Usage Instructions */}
|
||||
<div className="bg-purple-50 dark:bg-gray-700 p-4 rounded-lg">
|
||||
<p className="text-gray-700 dark:text-gray-300 text-sm">
|
||||
<span className="font-semibold">
|
||||
{isZh ? '步骤 3:' : 'Step 3:'}
|
||||
</span>{' '}
|
||||
{isZh
|
||||
? '在其他网站点击收藏夹中的按钮即可使用'
|
||||
: 'Click the bookmark on any site to activate'}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 右侧:注意事项 */}
|
||||
<div className="bg-yellow-50 dark:bg-gray-700 p-4 rounded-lg">
|
||||
<h4 className="font-semibold text-gray-900 dark:text-white mb-3 text-sm">
|
||||
{isZh ? '⚠️ 注意' : '⚠️ Heads Up'}
|
||||
</h4>
|
||||
<ul className="space-y-2 text-sm text-gray-700 dark:text-gray-300">
|
||||
<li className="flex items-start text-left">
|
||||
<span className="w-1.5 h-1.5 bg-yellow-500 rounded-full mt-2 mr-2 shrink-0 "></span>
|
||||
{isZh
|
||||
? '仅做技术评估,链接定期失效'
|
||||
: 'Demo only—link may expire without notice'}
|
||||
</li>
|
||||
<li className="flex items-start text-left">
|
||||
<span className="w-1.5 h-1.5 bg-yellow-500 rounded-full mt-2 mr-2 shrink-0 "></span>
|
||||
{isZh
|
||||
? '使用 DeepSeek 模型,参考 DeepSeek 用户协议和隐私政策'
|
||||
: 'This free demo uses DeepSeek API (see their terms and privacy policy)'}
|
||||
</li>
|
||||
<li className="flex items-start text-left">
|
||||
<span className="w-1.5 h-1.5 bg-yellow-500 rounded-full mt-2 mr-2 shrink-0 "></span>
|
||||
{isZh
|
||||
? '部分网站屏蔽了链接嵌入,将无反应'
|
||||
: 'Some sites block script injection (CSP policies)'}
|
||||
</li>
|
||||
<li className="flex items-start text-left">
|
||||
<span className="w-1.5 h-1.5 bg-yellow-500 rounded-full mt-2 mr-2 shrink-0 "></span>
|
||||
{isZh
|
||||
? '仅支持单页应用,页面跳转后需要重新注入'
|
||||
: 'Works on single-page apps only—reload required after navigation'}
|
||||
</li>
|
||||
<li className="flex items-start text-left">
|
||||
<span className="w-1.5 h-1.5 bg-yellow-500 rounded-full mt-2 mr-2 shrink-0 "></span>
|
||||
{isZh
|
||||
? '仅识别文本,不识别图像,不支持拖拽等复杂交互'
|
||||
: 'Text-only understanding—no image recognition or drag-and-drop'}
|
||||
</li>
|
||||
<li className="flex items-start text-left">
|
||||
<span className="w-1.5 h-1.5 bg-yellow-500 rounded-full mt-2 mr-2 shrink-0 "></span>
|
||||
{isZh ? '详细使用限制参照' : 'Full limitations in'}{' '}
|
||||
<Link
|
||||
href="/docs/introduction/limitations"
|
||||
className="text-blue-600 dark:text-blue-400 hover:underline"
|
||||
>
|
||||
{isZh ? '《文档》' : 'Docs'}
|
||||
</Link>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</NeonGradientCard>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ul
|
||||
className="flex flex-wrap justify-center gap-6 text-sm text-gray-500 dark:text-gray-400"
|
||||
role="list"
|
||||
>
|
||||
<li className="flex items-center">
|
||||
<span
|
||||
className="w-2 h-2 bg-green-500 rounded-full mr-2"
|
||||
aria-hidden="true"
|
||||
></span>
|
||||
{isZh ? '纯前端方案' : 'Pure Front-end Solution'}
|
||||
</li>
|
||||
<li className="flex items-center">
|
||||
<span
|
||||
className="w-2 h-2 bg-green-500 rounded-full mr-2"
|
||||
aria-hidden="true"
|
||||
></span>
|
||||
{isZh ? '支持私有模型' : 'Your Own Models'}
|
||||
</li>
|
||||
<li className="flex items-center">
|
||||
<span
|
||||
className="w-2 h-2 bg-green-500 rounded-full mr-2"
|
||||
aria-hidden="true"
|
||||
></span>
|
||||
{isZh ? '无痛脱敏' : 'Built-in Privacy'}
|
||||
</li>
|
||||
<li className="flex items-center">
|
||||
<span
|
||||
className="w-2 h-2 bg-green-500 rounded-full mr-2"
|
||||
aria-hidden="true"
|
||||
></span>
|
||||
{isZh ? 'MIT 开源' : 'MIT Open Source'}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Features Section */}
|
||||
<section
|
||||
className="px-6 py-20 bg-white/50 dark:bg-gray-800/50 backdrop-blur-sm"
|
||||
aria-labelledby="features-heading"
|
||||
>
|
||||
<div className="max-w-7xl mx-auto">
|
||||
<div className="grid md:grid-cols-2 lg:grid-cols-4 gap-8" role="list">
|
||||
{/* Feature 1 */}
|
||||
<article
|
||||
className="group p-8 bg-linear-to-br from-blue-100 to-purple-100 dark:from-gray-700 dark:to-gray-800 rounded-2xl shadow-lg hover:shadow-xl transition-all duration-300 border border-gray-100 dark:border-gray-700"
|
||||
role="listitem"
|
||||
>
|
||||
<div
|
||||
className="w-14 h-14 bg-linear-to-br from-blue-500 to-blue-600 rounded-xl flex items-center justify-center mb-6 group-hover:scale-110 group-hover:rotate-3 transition-all duration-300 shadow-lg"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<Box className="w-7 h-7 text-white" strokeWidth={2.5} />
|
||||
</div>
|
||||
<h3 className="text-xl font-bold mb-4 text-gray-900 dark:text-white">
|
||||
{isZh ? '纯页面内方案' : 'In-page Solution'}
|
||||
</h3>
|
||||
<p className="text-gray-600 dark:text-gray-300 leading-relaxed">
|
||||
{isZh
|
||||
? '完全运行在你的页面内。不需要浏览器插件、不需要无头浏览器,不需要后端。'
|
||||
: 'Runs entirely within your page. No browser extensions, no headless browsers, and no backend required.'}
|
||||
</p>
|
||||
</article>
|
||||
|
||||
{/* Feature 2 */}
|
||||
<article
|
||||
className="group p-8 bg-linear-to-br from-purple-100 to-pink-100 dark:from-gray-700 dark:to-gray-800 rounded-2xl shadow-lg hover:shadow-xl transition-all duration-300 border border-gray-100 dark:border-gray-700"
|
||||
role="listitem"
|
||||
>
|
||||
<div
|
||||
className="w-14 h-14 bg-linear-to-br from-green-500 to-green-600 rounded-xl flex items-center justify-center mb-6 group-hover:scale-110 group-hover:rotate-3 transition-all duration-300 shadow-lg"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<Zap className="w-7 h-7 text-white fill-white" strokeWidth={2.5} />
|
||||
</div>
|
||||
<h3 className="text-xl font-bold mb-4 text-gray-900 dark:text-white">
|
||||
{isZh ? '零后端部署' : 'Zero Backend Setup'}
|
||||
</h3>
|
||||
<p className="text-gray-600 dark:text-gray-300 leading-relaxed">
|
||||
{isZh
|
||||
? '前端脚本引入,自定义 LLM 接入点。从 OpenAI 到 qwen3,完全由你掌控。'
|
||||
: 'Just drop in a script. Works with any LLM provider—OpenAI, Anthropic, or your own models.'}
|
||||
</p>
|
||||
</article>
|
||||
|
||||
{/* Feature 3 */}
|
||||
<article
|
||||
className="group p-8 bg-linear-to-br from-orange-100 to-red-100 dark:from-gray-700 dark:to-gray-800 rounded-2xl shadow-lg hover:shadow-xl transition-all duration-300 border border-gray-100 dark:border-gray-700"
|
||||
role="listitem"
|
||||
>
|
||||
<div
|
||||
className="w-14 h-14 bg-linear-to-br from-purple-500 to-purple-600 rounded-xl flex items-center justify-center mb-6 group-hover:scale-110 group-hover:rotate-3 transition-all duration-300 shadow-lg"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<MessageSquare className="w-7 h-7 text-white" strokeWidth={2.5} />
|
||||
</div>
|
||||
<h3 className="text-xl font-bold mb-4 text-gray-900 dark:text-white">
|
||||
{isZh ? '普惠智能交互' : 'Natural Language UI'}
|
||||
</h3>
|
||||
<p className="text-gray-600 dark:text-gray-300 leading-relaxed">
|
||||
{isZh
|
||||
? '为复杂 B端系统、管理后台提供自然语言入口。让每个用户都能轻松上手。'
|
||||
: 'Transform complex admin panels into chat interfaces. Make powerful tools accessible to everyone, not just experts.'}
|
||||
</p>
|
||||
</article>
|
||||
|
||||
{/* Feature 4 */}
|
||||
<article
|
||||
className="group p-8 bg-linear-to-br from-green-100 to-blue-100 dark:from-gray-700 dark:to-gray-800 rounded-2xl shadow-lg hover:shadow-xl transition-all duration-300 border border-gray-100 dark:border-gray-700"
|
||||
role="listitem"
|
||||
>
|
||||
<div
|
||||
className="w-14 h-14 bg-linear-to-br from-orange-500 to-orange-600 rounded-xl flex items-center justify-center mb-6 group-hover:scale-110 group-hover:rotate-3 transition-all duration-300 shadow-lg"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<Shield className="w-7 h-7 text-white" strokeWidth={2.5} />
|
||||
</div>
|
||||
<h3 className="text-xl font-bold mb-4 text-gray-900 dark:text-white">
|
||||
{isZh ? '安全可控集成' : 'Secure by Design'}
|
||||
</h3>
|
||||
<p className="text-gray-600 dark:text-gray-300 leading-relaxed">
|
||||
{isZh
|
||||
? '支持操作黑白名单、数据脱敏保护。注入自定义知识库,让 AI 按你的规则工作。'
|
||||
: 'Control what AI can access with allowlists, data masking, and custom knowledge injection. Your rules, your data.'}
|
||||
</p>
|
||||
</article>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Use Cases Section */}
|
||||
<section className="px-6 py-20" aria-labelledby="use-cases-heading">
|
||||
<div className="max-w-7xl mx-auto">
|
||||
<div className="text-center mb-16">
|
||||
<SparklesText
|
||||
className="text-4xl lg:text-5xl mb-6"
|
||||
colors={{ first: '#3b82f6', second: '#8b5cf6' }}
|
||||
>
|
||||
{isZh ? '应用场景' : 'Where It Shines'}
|
||||
</SparklesText>
|
||||
<p className="text-xl text-gray-600 dark:text-gray-300 max-w-3xl mx-auto">
|
||||
{isZh
|
||||
? '从简单的表单填写到复杂的业务流程,AI 都能理解并执行'
|
||||
: 'From simple forms to complex workflows, AI understands and executes'}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="grid lg:grid-cols-2 gap-12" role="list">
|
||||
{/* Use Case 1 */}
|
||||
<div className="group bg-linear-to-br from-blue-100 to-purple-100 dark:from-gray-700 dark:to-gray-800 p-8 rounded-2xl hover:shadow-xl transition-all duration-300">
|
||||
<div className="flex items-start space-x-4">
|
||||
<div className="w-12 h-12 bg-linear-to-br from-blue-500 to-purple-500 rounded-xl flex items-center justify-center shrink-0 group-hover:scale-110 transition-transform duration-300 shadow-md">
|
||||
<Bot className="w-6 h-6 text-white" strokeWidth={2.5} />
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 className="text-xl font-bold mb-2 text-gray-900 dark:text-white">
|
||||
{isZh ? '对接答疑机器人' : 'Supercharge Support Bots'}
|
||||
</h3>
|
||||
<p className="text-gray-600 dark:text-gray-300">
|
||||
{isZh
|
||||
? '把你的答疑助手变成全能Agent。客服机器人不再只说「请先点击设置按钮然后点击...」,而是直接帮用户现场操作。'
|
||||
: 'Stop telling users where to click—let AI do it for them. Turn your chatbot from a guide into an operator that actually completes tasks.'}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Use Case 2 */}
|
||||
<div className="group bg-linear-to-br from-green-100 to-blue-100 dark:from-gray-700 dark:to-gray-800 p-8 rounded-2xl hover:shadow-xl transition-all duration-300">
|
||||
<div className="flex items-start space-x-4">
|
||||
<div className="w-12 h-12 bg-linear-to-br from-green-500 to-blue-500 rounded-xl flex items-center justify-center shrink-0 group-hover:scale-110 transition-transform duration-300 shadow-md">
|
||||
<Sparkles className="w-6 h-6 text-white" strokeWidth={2.5} />
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-xl font-bold mb-2 text-gray-900 dark:text-white">
|
||||
{isZh ? '交互升级/智能化改造' : 'Modernize Legacy Apps'}
|
||||
</h3>
|
||||
<p className="text-gray-600 dark:text-gray-300">
|
||||
{isZh
|
||||
? '一行代码,老应用变身Agent,产品专家帮用户操作复杂 B 端软件。降低人工支持成本,提高用户满意度。'
|
||||
: 'Add AI superpowers to old software without rebuilding. One script tag transforms complex enterprise tools into chat-driven interfaces.'}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Use Case 3 */}
|
||||
<div className="group bg-linear-to-br from-purple-100 to-pink-100 dark:from-gray-700 dark:to-gray-800 p-8 rounded-2xl hover:shadow-xl transition-all duration-300">
|
||||
<div className="flex items-start space-x-4">
|
||||
<div className="w-12 h-12 bg-linear-to-br from-purple-500 to-pink-500 rounded-xl flex items-center justify-center shrink-0 group-hover:scale-110 transition-transform duration-300 shadow-md">
|
||||
<PlayCircle className="w-6 h-6 text-white fill-white/30" strokeWidth={2.5} />
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-xl font-bold mb-2 text-gray-900 dark:text-white">
|
||||
{isZh ? '产品教学' : 'Interactive Walkthroughs'}
|
||||
</h3>
|
||||
<p className="text-gray-600 dark:text-gray-300">
|
||||
{isZh
|
||||
? '向用户演示交互过程,边做边教。例如让AI演示「如何提交报销申请」的完整操作流程。'
|
||||
: "Show, don't tell. Let AI demonstrate workflows in real-time—perfect for onboarding or training new users on complex systems."}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Use Case 4 */}
|
||||
<div className="group bg-linear-to-br from-orange-100 to-red-100 dark:from-gray-700 dark:to-gray-800 p-8 rounded-2xl hover:shadow-xl transition-all duration-300">
|
||||
<div className="flex items-start space-x-4">
|
||||
<div className="w-12 h-12 bg-linear-to-br from-orange-500 to-red-500 rounded-xl flex items-center justify-center shrink-0 group-hover:scale-110 transition-transform duration-300 shadow-md">
|
||||
<Users className="w-6 h-6 text-white" strokeWidth={2.5} />
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-xl font-bold mb-2 text-gray-900 dark:text-white">
|
||||
{isZh ? '无障碍支持' : 'Accessibility First'}
|
||||
</h3>
|
||||
<p className="text-gray-600 dark:text-gray-300">
|
||||
{isZh
|
||||
? '为视障用户、老年用户提供自然语言交互,对接屏幕阅读器或语音助理,让软件人人可用。'
|
||||
: 'Make web apps accessible through natural language. Perfect for screen readers, voice control, or users who find traditional interfaces challenging.'}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* One More Thing */}
|
||||
<section
|
||||
className="px-6 py-20 bg-white/50 dark:bg-gray-800/50 backdrop-blur-sm"
|
||||
aria-labelledby="one-more-thing-heading"
|
||||
>
|
||||
<div className="max-w-4xl mx-auto text-center">
|
||||
<h2
|
||||
id="one-more-thing-heading"
|
||||
className="text-4xl lg:text-5xl font-bold mb-6 bg-linear-to-r from-blue-600 to-purple-600 bg-clip-text text-transparent"
|
||||
>
|
||||
One More Thing
|
||||
</h2>
|
||||
<p className="text-xl text-gray-600 dark:text-gray-300 mb-4 max-w-2xl mx-auto">
|
||||
{isZh
|
||||
? '想要多页面控制?试试可选的浏览器扩展。'
|
||||
: 'Need multi-page control? Try the optional browser extension.'}
|
||||
</p>
|
||||
<p className="text-sm text-gray-500 dark:text-gray-400 mb-12 max-w-2xl mx-auto">
|
||||
{'* '}
|
||||
{isZh
|
||||
? 'PageAgent.js 本身无需任何扩展即可工作,扩展是额外的能力增强。'
|
||||
: 'PageAgent.js works without any extension — this is a power-up, not a dependency.'}
|
||||
</p>
|
||||
|
||||
<div className="flex flex-col sm:flex-row items-center justify-center gap-4 mb-10">
|
||||
<a
|
||||
href="https://chromewebstore.google.com/detail/page-agent-ext/akldabonmimlicnjlflnapfeklbfemhj"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="group inline-flex items-center gap-3 px-8 py-4 bg-linear-to-r from-blue-600 to-blue-700 hover:from-blue-700 hover:to-blue-800 text-white font-medium rounded-2xl shadow-lg hover:shadow-xl transition-all duration-300 hover:scale-105"
|
||||
>
|
||||
<img
|
||||
src="https://img.alicdn.com/imgextra/i3/O1CN01JpW0Vo1sR3FpiZKFM_!!6000000005762-55-tps-192-192.svg"
|
||||
alt="Chrome Web Store"
|
||||
className="w-7 h-7"
|
||||
/>
|
||||
<span>{isZh ? '从 Chrome 应用商店安装' : 'Install from Chrome Web Store'}</span>
|
||||
<ExternalLink className="w-4 h-4 opacity-50 group-hover:opacity-100 transition-opacity" />
|
||||
</a>
|
||||
<Link
|
||||
href="/docs/features/chrome-extension"
|
||||
className="inline-flex items-center gap-3 px-8 py-4 bg-gray-100 dark:bg-gray-700 hover:bg-gray-200 dark:hover:bg-gray-600 text-gray-900 dark:text-white font-medium rounded-2xl transition-all duration-300 hover:scale-105"
|
||||
>
|
||||
<svg className="w-5 h-5" viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path d={siGooglechrome.path} fill="currentColor" />
|
||||
</svg>
|
||||
<span>{isZh ? '查看文档' : 'Read the Docs'}</span>
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<div className="grid sm:grid-cols-3 gap-6 text-left max-w-3xl mx-auto">
|
||||
<div className="p-5 bg-linear-to-br from-blue-50 to-purple-50 dark:from-gray-700 dark:to-gray-800 rounded-xl">
|
||||
<h3 className="font-semibold text-gray-900 dark:text-white mb-1">
|
||||
{isZh ? '多页面任务' : 'Multi-Page Tasks'}
|
||||
</h3>
|
||||
<p className="text-sm text-gray-600 dark:text-gray-300">
|
||||
{isZh
|
||||
? '跨多个页面和标签页连续执行任务,不再受限于单页上下文'
|
||||
: 'Run tasks across multiple pages and tabs without being limited to a single page context'}
|
||||
</p>
|
||||
</div>
|
||||
<div className="p-5 bg-linear-to-br from-green-50 to-blue-50 dark:from-gray-700 dark:to-gray-800 rounded-xl">
|
||||
<h3 className="font-semibold text-gray-900 dark:text-white mb-1">
|
||||
{isZh ? '页面内发起控制' : 'Control from Your Page'}
|
||||
</h3>
|
||||
<p className="text-sm text-gray-600 dark:text-gray-300">
|
||||
{isZh
|
||||
? '在页面 JS 中发起任务,驱动整个浏览器完成跨标签操作'
|
||||
: 'Trigger tasks from page JS to drive the entire browser across tabs'}
|
||||
</p>
|
||||
</div>
|
||||
<div className="p-5 bg-linear-to-br from-purple-50 to-pink-50 dark:from-gray-700 dark:to-gray-800 rounded-xl">
|
||||
<h3 className="font-semibold text-gray-900 dark:text-white mb-1">
|
||||
{isZh ? '外部发起任务' : 'External Triggers'}
|
||||
</h3>
|
||||
<p className="text-sm text-gray-600 dark:text-gray-300">
|
||||
{isZh
|
||||
? '页面 JS、本地 Agent 或云端 Agent 均可通过扩展发起任务'
|
||||
: 'Page JS, local agents, or cloud agents can trigger tasks through the extension'}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<HeroSection />
|
||||
<FeaturesSection />
|
||||
<ScenariosSection />
|
||||
<OneMoreThingSection />
|
||||
</main>
|
||||
|
||||
<Footer />
|
||||
|
||||
166
packages/website/src/pages/home/FeaturesSection.tsx
Normal file
166
packages/website/src/pages/home/FeaturesSection.tsx
Normal file
@@ -0,0 +1,166 @@
|
||||
import { Bot, Box, MessageSquare, Shield, Sparkles, Users } from 'lucide-react'
|
||||
|
||||
import { BlurFade } from '../../components/ui/blur-fade'
|
||||
import { Marquee } from '../../components/ui/marquee'
|
||||
import { Particles } from '../../components/ui/particles'
|
||||
import { useLanguage } from '../../i18n/context'
|
||||
|
||||
export default function FeaturesSection() {
|
||||
const { isZh } = useLanguage()
|
||||
|
||||
return (
|
||||
<section className="px-6 py-14" aria-labelledby="features-heading">
|
||||
<div className="max-w-6xl mx-auto">
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-4 auto-rows-[22rem]">
|
||||
{/* Zero Infrastructure (2-col) */}
|
||||
<BlurFade inView className="col-span-1 md:col-span-2">
|
||||
<div className="group relative h-full overflow-hidden rounded-2xl bg-white/80 dark:bg-gray-900/80 backdrop-blur-xl border border-gray-200/60 dark:border-white/8 [box-shadow:0_0_0_1px_rgba(0,0,0,.03),0_2px_4px_rgba(0,0,0,.05),0_12px_24px_rgba(0,0,0,.05)] dark:[box-shadow:0_-20px_80px_-20px_#ffffff1f_inset] hover:shadow-xl transition-all duration-500 flex flex-col">
|
||||
<div className="flex-1 p-8 flex flex-col justify-center">
|
||||
<div className="space-y-3 mb-6">
|
||||
{[
|
||||
'pip install browser-use playwright',
|
||||
'docker run -p 3000:3000 playwright-mcp',
|
||||
'const browser = await chromium.launch()',
|
||||
].map((cmd) => (
|
||||
<div
|
||||
key={cmd}
|
||||
className="flex items-center gap-2.5 font-mono text-sm text-gray-400 dark:text-gray-600 line-through decoration-red-400/40 truncate"
|
||||
>
|
||||
<span className="text-red-400/60 text-xs shrink-0">✗</span>
|
||||
{cmd}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div className="bg-emerald-50 dark:bg-emerald-950/20 border border-emerald-200/60 dark:border-emerald-800/30 rounded-xl px-5 py-3.5 font-mono text-sm text-emerald-700 dark:text-emerald-400 flex items-center gap-2.5">
|
||||
<span className="text-emerald-500 text-xs shrink-0">✓</span>
|
||||
{'<script src="page-agent.js"></script>'}
|
||||
</div>
|
||||
</div>
|
||||
<div className="px-8 pb-6">
|
||||
<div className="flex items-center gap-2.5 mb-1.5">
|
||||
<Box className="w-5 h-5 text-blue-500" />
|
||||
<h3 className="font-semibold text-lg text-gray-900 dark:text-white">
|
||||
{isZh ? '零基建集成' : 'Zero Infrastructure'}
|
||||
</h3>
|
||||
</div>
|
||||
<p className="text-sm text-gray-500 dark:text-gray-400 leading-relaxed">
|
||||
{isZh
|
||||
? '无需 Python、无头浏览器、服务端部署。一行 script 标签搞定。'
|
||||
: "No Python. No headless browser. No server. One script tag — that's it."}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</BlurFade>
|
||||
|
||||
{/* Privacy by Default (1-col) */}
|
||||
<BlurFade inView delay={0.1} className="col-span-1">
|
||||
<div className="group relative h-full overflow-hidden rounded-2xl bg-white/80 dark:bg-gray-900/80 backdrop-blur-xl border border-gray-200/60 dark:border-white/8 [box-shadow:0_0_0_1px_rgba(0,0,0,.03),0_2px_4px_rgba(0,0,0,.05),0_12px_24px_rgba(0,0,0,.05)] dark:[box-shadow:0_-20px_80px_-20px_#ffffff1f_inset] hover:shadow-xl transition-all duration-500 flex flex-col">
|
||||
<div className="flex-1 relative overflow-hidden">
|
||||
<Particles
|
||||
className="absolute inset-0"
|
||||
quantity={40}
|
||||
staticity={50}
|
||||
ease={80}
|
||||
color="#8b5cf6"
|
||||
/>
|
||||
<div className="absolute inset-0 flex items-center justify-center">
|
||||
<div className="w-20 h-20 rounded-2xl bg-purple-500/10 dark:bg-purple-500/20 backdrop-blur-sm flex items-center justify-center ring-1 ring-purple-500/20">
|
||||
<Shield className="w-10 h-10 text-purple-500" strokeWidth={1.5} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="px-6 pb-6">
|
||||
<h3 className="font-semibold text-lg text-gray-900 dark:text-white mb-1.5">
|
||||
{isZh ? '隐私优先' : 'Privacy by Default'}
|
||||
</h3>
|
||||
<p className="text-sm text-gray-500 dark:text-gray-400 leading-relaxed">
|
||||
{isZh
|
||||
? '浏览器内运行,数据完全由你掌控。'
|
||||
: 'Runs in the browser. You control your data, always.'}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</BlurFade>
|
||||
|
||||
{/* Any LLM (1-col) */}
|
||||
<BlurFade inView delay={0.15} className="col-span-1">
|
||||
<div className="group relative h-full overflow-hidden rounded-2xl bg-white/80 dark:bg-gray-900/80 backdrop-blur-xl border border-gray-200/60 dark:border-white/8 [box-shadow:0_0_0_1px_rgba(0,0,0,.03),0_2px_4px_rgba(0,0,0,.05),0_12px_24px_rgba(0,0,0,.05)] dark:[box-shadow:0_-20px_80px_-20px_#ffffff1f_inset] hover:shadow-xl transition-all duration-500 flex flex-col">
|
||||
<div className="flex-1 relative overflow-hidden">
|
||||
<Marquee vertical pauseOnHover className="h-full [--duration:25s] [--gap:0.75rem]">
|
||||
{['OpenAI', 'Claude', 'DeepSeek', 'Qwen', 'Gemini', 'GLM', 'Ollama', 'Groq'].map(
|
||||
(name) => (
|
||||
<div
|
||||
key={name}
|
||||
className="mx-auto rounded-full bg-gray-100 dark:bg-gray-800 px-4 py-2 text-sm font-medium text-gray-600 dark:text-gray-300 ring-1 ring-gray-200/50 dark:ring-white/5"
|
||||
>
|
||||
{name}
|
||||
</div>
|
||||
)
|
||||
)}
|
||||
</Marquee>
|
||||
</div>
|
||||
<div className="px-6 pb-6">
|
||||
<div className="flex items-center gap-2.5 mb-1.5">
|
||||
<Sparkles className="w-5 h-5 text-amber-500" />
|
||||
<h3 className="font-semibold text-lg text-gray-900 dark:text-white">
|
||||
{isZh ? '兼容多种 LLM' : 'Bring Your Own LLMs'}
|
||||
</h3>
|
||||
</div>
|
||||
<p className="text-sm text-gray-500 dark:text-gray-400 leading-relaxed">
|
||||
{isZh
|
||||
? 'OpenAI、Claude、DeepSeek、Qwen 等,或通过 Ollama 完全离线。'
|
||||
: 'OpenAI, Claude, DeepSeek, Qwen, and more — or fully offline via Ollama.'}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</BlurFade>
|
||||
|
||||
{/* Human-in-the-Loop (2-col) */}
|
||||
<BlurFade inView delay={0.2} className="col-span-1 md:col-span-2">
|
||||
<div className="group relative h-full overflow-hidden rounded-2xl bg-white/80 dark:bg-gray-900/80 backdrop-blur-xl border border-gray-200/60 dark:border-white/8 [box-shadow:0_0_0_1px_rgba(0,0,0,.03),0_2px_4px_rgba(0,0,0,.05),0_12px_24px_rgba(0,0,0,.05)] dark:[box-shadow:0_-20px_80px_-20px_#ffffff1f_inset] hover:shadow-xl transition-all duration-500 flex flex-col">
|
||||
<div className="flex-1 p-8 flex flex-col justify-center max-w-md mx-auto w-full">
|
||||
<div className="flex gap-2.5 mb-3">
|
||||
<div className="shrink-0 w-7 h-7 rounded-full bg-purple-100 dark:bg-purple-900/50 flex items-center justify-center">
|
||||
<Bot className="w-4 h-4 text-purple-600 dark:text-purple-400" />
|
||||
</div>
|
||||
<div className="bg-gray-100 dark:bg-gray-800 rounded-2xl rounded-tl-md px-4 py-2.5 text-sm text-gray-700 dark:text-gray-300">
|
||||
{isZh ? '找到 3 条匹配记录。选择哪一条?' : 'Found 3 matches. Which one?'}
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex gap-2.5 justify-end mb-3">
|
||||
<div className="bg-blue-500 rounded-2xl rounded-tr-md px-4 py-2.5 text-sm text-white">
|
||||
{isZh ? '第二条' : 'The second one.'}
|
||||
</div>
|
||||
<div className="shrink-0 w-7 h-7 rounded-full bg-blue-100 dark:bg-blue-900/50 flex items-center justify-center">
|
||||
<Users className="w-4 h-4 text-blue-600 dark:text-blue-400" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex gap-2.5">
|
||||
<div className="shrink-0 w-7 h-7 rounded-full bg-emerald-100 dark:bg-emerald-900/50 flex items-center justify-center text-emerald-600 dark:text-emerald-400 text-xs font-bold">
|
||||
✓
|
||||
</div>
|
||||
<div className="bg-gray-100 dark:bg-gray-800 rounded-2xl rounded-tl-md px-4 py-2.5 text-sm text-gray-700 dark:text-gray-300">
|
||||
{isZh ? '已选择并提交!' : 'Done! Selected and submitted.'}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="px-8 pb-6">
|
||||
<div className="flex items-center gap-2.5 mb-1.5">
|
||||
<MessageSquare className="w-5 h-5 text-blue-500" />
|
||||
<h3 className="font-semibold text-lg text-gray-900 dark:text-white">
|
||||
{isZh ? '人机协同' : 'Human-in-the-Loop'}
|
||||
</h3>
|
||||
</div>
|
||||
<p className="text-sm text-gray-500 dark:text-gray-400 leading-relaxed">
|
||||
{isZh
|
||||
? '内置协作面板,AI 操作前先确认——不是盲目自动化。'
|
||||
: 'Built-in collaborative panel. Agent asks before acting — not blind automation.'}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</BlurFade>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
358
packages/website/src/pages/home/HeroSection.tsx
Normal file
358
packages/website/src/pages/home/HeroSection.tsx
Normal file
@@ -0,0 +1,358 @@
|
||||
/* eslint-disable react-dom/no-dangerously-set-innerhtml */
|
||||
import { PageAgent } from 'page-agent'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { Link, useSearchParams } from 'wouter'
|
||||
|
||||
import { AnimatedGradientText } from '../../components/ui/animated-gradient-text'
|
||||
import { Highlighter } from '../../components/ui/highlighter'
|
||||
import { NeonGradientCard } from '../../components/ui/neon-gradient-card'
|
||||
import { Particles } from '../../components/ui/particles'
|
||||
import {
|
||||
CDN_DEMO_CN_URL,
|
||||
CDN_DEMO_URL,
|
||||
DEMO_API_KEY,
|
||||
DEMO_BASE_URL,
|
||||
DEMO_MODEL,
|
||||
} from '../../constants'
|
||||
import { useLanguage } from '../../i18n/context'
|
||||
|
||||
function getInjection(useCN?: boolean) {
|
||||
const cdn = useCN ? CDN_DEMO_CN_URL : CDN_DEMO_URL
|
||||
|
||||
const injection = encodeURI(
|
||||
`javascript:(function(){var s=document.createElement('script');s.src=\`${cdn}?t=\${Math.random()}\`;s.setAttribute('crossorigin', true);s.type="text/javascript";s.onload=()=>console.log('PageAgent script loaded!');document.body.appendChild(s);})();`
|
||||
)
|
||||
|
||||
return `
|
||||
<a
|
||||
href=${injection}
|
||||
class="inline-flex items-center text-xs px-3 py-2 bg-blue-500 text-white font-medium rounded-lg hover:shadow-md transform hover:scale-105 transition-all duration-200 cursor-move border-2 border-dashed border-green-300"
|
||||
draggable="true"
|
||||
onclick="return false;"
|
||||
title="Drag me to your bookmarks bar!"
|
||||
>
|
||||
✨PageAgent
|
||||
</a>
|
||||
`
|
||||
}
|
||||
|
||||
export default function HeroSection() {
|
||||
const { language, isZh } = useLanguage()
|
||||
|
||||
const defaultTask = isZh
|
||||
? '从导航栏中进入文档页,打开"快速开始"相关的文档,帮我总结成 markdown'
|
||||
: 'Goto docs in navigation bar, find Quick-Start section, and summarize in markdown'
|
||||
|
||||
const [task, setTask] = useState(() => defaultTask)
|
||||
|
||||
useEffect(() => {
|
||||
setTask(defaultTask)
|
||||
}, [defaultTask])
|
||||
|
||||
const [params] = useSearchParams()
|
||||
const isOther = params.has('try_other')
|
||||
|
||||
const [activeTab, setActiveTab] = useState<'try' | 'other'>(isOther ? 'other' : 'try')
|
||||
const [cdnSource, setCdnSource] = useState<'international' | 'china'>('international')
|
||||
|
||||
const handleExecute = async () => {
|
||||
if (!task.trim()) return
|
||||
|
||||
const win = window as any
|
||||
|
||||
if (!win.pageAgent || win.pageAgent.disposed) {
|
||||
win.pageAgent = new PageAgent({
|
||||
interactiveBlacklist: [document.getElementById('root')!],
|
||||
language: language,
|
||||
|
||||
instructions: {
|
||||
system: 'You are a helpful assistant on PageAgent website.',
|
||||
getPageInstructions: (url: string) => {
|
||||
const hint = url.includes('page-agent') ? 'This is PageAgent demo page.' : undefined
|
||||
console.log('[instructions] getPageInstructions:', url, '->', hint)
|
||||
return hint
|
||||
},
|
||||
},
|
||||
|
||||
model:
|
||||
import.meta.env.DEV && import.meta.env.LLM_MODEL_NAME
|
||||
? import.meta.env.LLM_MODEL_NAME
|
||||
: DEMO_MODEL,
|
||||
baseURL:
|
||||
import.meta.env.DEV && import.meta.env.LLM_BASE_URL
|
||||
? import.meta.env.LLM_BASE_URL
|
||||
: DEMO_BASE_URL,
|
||||
apiKey:
|
||||
import.meta.env.DEV && import.meta.env.LLM_API_KEY
|
||||
? import.meta.env.LLM_API_KEY
|
||||
: DEMO_API_KEY,
|
||||
})
|
||||
}
|
||||
|
||||
const result = await win.pageAgent.execute(task)
|
||||
console.log(result)
|
||||
}
|
||||
|
||||
return (
|
||||
<section
|
||||
className="relative px-6 pt-24 py-20 pb-18 lg:py-22 lg:pt-28 overflow-hidden"
|
||||
aria-labelledby="hero-heading"
|
||||
>
|
||||
<div className="max-w-7xl mx-auto text-center">
|
||||
{/* Background Pattern + Particles */}
|
||||
<div className="absolute inset-0 opacity-30" aria-hidden="true">
|
||||
<div className="absolute inset-0 bg-linear-to-r from-blue-400/20 to-purple-400/20 rounded-3xl transform rotate-1"></div>
|
||||
<div className="absolute inset-0 bg-linear-to-l from-purple-400/20 to-blue-400/20 rounded-3xl transform -rotate-1"></div>
|
||||
</div>
|
||||
<Particles
|
||||
className="absolute inset-0"
|
||||
quantity={80}
|
||||
staticity={30}
|
||||
ease={80}
|
||||
color="#6366f1"
|
||||
/>
|
||||
|
||||
<div className="relative z-10">
|
||||
<div className="inline-flex items-center px-4 py-2 mb-8 text-sm font-medium bg-white/90 dark:bg-gray-800/90 rounded-full shadow-lg border border-gray-200 dark:border-gray-700">
|
||||
<span
|
||||
className="w-2 h-2 bg-blue-500 rounded-full mr-2 animate-pulse"
|
||||
aria-hidden="true"
|
||||
></span>
|
||||
<AnimatedGradientText colorFrom="#3b82f6" colorTo="#8b5cf6">
|
||||
AI Agent In Your Webpage
|
||||
</AnimatedGradientText>
|
||||
</div>
|
||||
|
||||
<h1
|
||||
id="hero-heading"
|
||||
className="text-5xl lg:text-7xl font-bold mb-14 mt-8 bg-linear-to-r from-blue-600 to-purple-600 bg-clip-text text-transparent pb-1"
|
||||
>
|
||||
{isZh ? (
|
||||
<>
|
||||
<span className="text-6xl lg:text-7xl">你网站里的 AI 操作员</span>
|
||||
<span className="block text-xl lg:text-2xl mt-5 font-medium bg-linear-to-r from-blue-400 to-purple-400 bg-clip-text text-transparent">
|
||||
The AI Operator Living in Your Web Page
|
||||
</span>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
The AI Operator
|
||||
<br />
|
||||
Living in Your Web Page
|
||||
</>
|
||||
)}
|
||||
</h1>
|
||||
|
||||
<p className="text-xl lg:text-2xl text-gray-600 dark:text-gray-300 mb-12 max-w-4xl mx-auto leading-relaxed">
|
||||
<Highlighter action="underline" color="#8b5cf6" strokeWidth={2}>
|
||||
<span className="bg-linear-to-r from-blue-500 to-purple-500 bg-clip-text text-transparent font-bold">
|
||||
{isZh ? '🪄一行代码' : '🪄One line of code'}
|
||||
</span>
|
||||
</Highlighter>
|
||||
{isZh
|
||||
? ',让你的网站变身 AI 原生应用。'
|
||||
: ', turns your website into an AI-native app.'}
|
||||
<br />
|
||||
{isZh
|
||||
? '用户/答疑机器人给出文字指示,AI 帮你操作页面。'
|
||||
: 'Users give natural language commands, AI handles the rest.'}
|
||||
</p>
|
||||
|
||||
{/* Try It Now Section - Tab Card */}
|
||||
<div className="mb-12">
|
||||
<div className="max-w-3xl mx-auto">
|
||||
<NeonGradientCard
|
||||
borderSize={2}
|
||||
borderRadius={20}
|
||||
neonColors={{ firstColor: '#ff00aa', secondColor: '#00FFF1' }}
|
||||
>
|
||||
{/* Tab Headers */}
|
||||
<div className="flex border-b border-gray-200 dark:border-gray-700">
|
||||
<button
|
||||
onClick={() => setActiveTab('try')}
|
||||
className={`flex-1 px-4 py-4 text-lg font-medium transition-colors duration-200 rounded-tl-2xl ${
|
||||
activeTab === 'try'
|
||||
? 'bg-linear-to-r from-blue-50 to-purple-50 dark:from-blue-900/30 dark:to-purple-900/30 text-blue-700 dark:text-blue-300 border-b-2 border-blue-500'
|
||||
: 'text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white hover:bg-gray-50 dark:hover:bg-gray-700'
|
||||
}`}
|
||||
>
|
||||
{isZh ? '🚀 立即尝试' : '🚀 Try It Now'}
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setActiveTab('other')}
|
||||
className={`flex-1 px-4 py-4 text-lg font-medium transition-colors duration-200 rounded-tr-2xl ${
|
||||
activeTab === 'other'
|
||||
? 'bg-linear-to-r from-green-50 to-blue-50 dark:from-green-900/30 dark:to-blue-900/30 text-green-700 dark:text-green-300 border-b-2 border-green-500'
|
||||
: 'text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white hover:bg-gray-50 dark:hover:bg-gray-700'
|
||||
}`}
|
||||
>
|
||||
{isZh ? '🌐 其他网页尝试' : '🌐 Try on Other Sites'}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Tab Content */}
|
||||
<div className="p-4">
|
||||
{activeTab === 'try' && (
|
||||
<div className="space-y-4">
|
||||
<div className="relative">
|
||||
<input
|
||||
value={task}
|
||||
onChange={(e) => setTask(e.target.value)}
|
||||
placeholder={
|
||||
isZh
|
||||
? '输入您想要 AI 执行的任务...'
|
||||
: 'Describe what you want AI to do...'
|
||||
}
|
||||
className="w-full px-4 py-3 pr-20 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white placeholder-gray-500 dark:placeholder-gray-400 focus:ring-2 focus:ring-blue-500 focus:border-transparent resize-none text-sm mb-0"
|
||||
data-page-agent-not-interactive
|
||||
/>
|
||||
<button
|
||||
onClick={handleExecute}
|
||||
className="absolute right-2 top-2 px-5 py-1.5 bg-linear-to-r from-blue-600 to-purple-600 text-white font-medium rounded-md hover:shadow-md transform hover:scale-105 transition-all duration-200 disabled:opacity-50 disabled:cursor-not-allowed disabled:transform-none text-sm"
|
||||
data-page-agent-not-interactive
|
||||
>
|
||||
{isZh ? '执行' : 'Run'}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{activeTab === 'other' && (
|
||||
<div className="grid md:grid-cols-2 gap-6">
|
||||
{/* 左侧:操作步骤 */}
|
||||
<div className="space-y-4">
|
||||
<div className="bg-blue-50 dark:bg-gray-700 p-4 rounded-lg">
|
||||
<p className="text-gray-700 dark:text-gray-300 text-sm mb-3">
|
||||
<span className="font-semibold">{isZh ? '步骤 1:' : 'Step 1:'}</span>{' '}
|
||||
{isZh ? '显示收藏夹栏' : 'Show your bookmarks bar'}
|
||||
</p>
|
||||
<div className="flex items-center justify-center gap-2">
|
||||
<kbd className="px-2 py-1 bg-white dark:bg-gray-600 border border-gray-300 dark:border-gray-500 rounded text-xs font-mono">
|
||||
Ctrl + Shift + B
|
||||
</kbd>
|
||||
<span className="text-gray-500 dark:text-gray-400">
|
||||
{isZh ? '或' : 'or'}
|
||||
</span>
|
||||
<kbd className="px-2 py-1 bg-white dark:bg-gray-600 border border-gray-300 dark:border-gray-500 rounded text-xs font-mono">
|
||||
⌘ + Shift + B
|
||||
</kbd>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="bg-green-50 dark:bg-gray-700 p-4 rounded-lg">
|
||||
<p className="text-gray-700 dark:text-gray-300 text-sm mb-3">
|
||||
<span className="font-semibold">{isZh ? '步骤 2:' : 'Step 2:'}</span>{' '}
|
||||
{isZh ? '拖拽下面按钮到收藏夹栏' : 'Drag this button to your bookmarks'}
|
||||
</p>
|
||||
<div className="flex items-center justify-center gap-3">
|
||||
<select
|
||||
value={cdnSource}
|
||||
onChange={(e) =>
|
||||
setCdnSource(e.target.value as 'international' | 'china')
|
||||
}
|
||||
className="px-2 py-1.5 text-xs border border-gray-300 dark:border-gray-500 rounded bg-white dark:bg-gray-600 text-gray-700 dark:text-gray-200"
|
||||
>
|
||||
<option value="international">
|
||||
{isZh ? '国际' : 'International'}
|
||||
</option>
|
||||
<option value="china">{isZh ? '国内镜像' : 'China Mirror'}</option>
|
||||
</select>
|
||||
<div
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: getInjection(cdnSource === 'china'),
|
||||
}}
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="bg-purple-50 dark:bg-gray-700 p-4 rounded-lg">
|
||||
<p className="text-gray-700 dark:text-gray-300 text-sm">
|
||||
<span className="font-semibold">{isZh ? '步骤 3:' : 'Step 3:'}</span>{' '}
|
||||
{isZh
|
||||
? '在其他网站点击收藏夹中的按钮即可使用'
|
||||
: 'Click the bookmark on any site to activate'}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 右侧:注意事项 */}
|
||||
<div className="bg-yellow-50 dark:bg-gray-700 p-4 rounded-lg">
|
||||
<h4 className="font-semibold text-gray-900 dark:text-white mb-3 text-sm">
|
||||
{isZh ? '⚠️ 注意' : '⚠️ Heads Up'}
|
||||
</h4>
|
||||
<ul className="space-y-2 text-sm text-gray-700 dark:text-gray-300">
|
||||
<li className="flex items-start text-left">
|
||||
<span className="w-1.5 h-1.5 bg-yellow-500 rounded-full mt-2 mr-2 shrink-0 "></span>
|
||||
{isZh
|
||||
? '仅做技术评估,链接定期失效'
|
||||
: 'Demo only—link may expire without notice'}
|
||||
</li>
|
||||
<li className="flex items-start text-left">
|
||||
<span className="w-1.5 h-1.5 bg-yellow-500 rounded-full mt-2 mr-2 shrink-0 "></span>
|
||||
{isZh
|
||||
? '使用 DeepSeek 模型,参考 DeepSeek 用户协议和隐私政策'
|
||||
: 'This free demo uses DeepSeek API (see their terms and privacy policy)'}
|
||||
</li>
|
||||
<li className="flex items-start text-left">
|
||||
<span className="w-1.5 h-1.5 bg-yellow-500 rounded-full mt-2 mr-2 shrink-0 "></span>
|
||||
{isZh
|
||||
? '部分网站屏蔽了链接嵌入,将无反应'
|
||||
: 'Some sites block script injection (CSP policies)'}
|
||||
</li>
|
||||
<li className="flex items-start text-left">
|
||||
<span className="w-1.5 h-1.5 bg-yellow-500 rounded-full mt-2 mr-2 shrink-0 "></span>
|
||||
{isZh
|
||||
? '仅支持单页应用,页面跳转后需要重新注入'
|
||||
: 'Works on single-page apps only—reload required after navigation'}
|
||||
</li>
|
||||
<li className="flex items-start text-left">
|
||||
<span className="w-1.5 h-1.5 bg-yellow-500 rounded-full mt-2 mr-2 shrink-0 "></span>
|
||||
{isZh
|
||||
? '仅识别文本,不识别图像,不支持拖拽等复杂交互'
|
||||
: 'Text-only understanding—no image recognition or drag-and-drop'}
|
||||
</li>
|
||||
<li className="flex items-start text-left">
|
||||
<span className="w-1.5 h-1.5 bg-yellow-500 rounded-full mt-2 mr-2 shrink-0 "></span>
|
||||
{isZh ? '详细使用限制参照' : 'Full limitations in'}{' '}
|
||||
<Link
|
||||
href="/docs/introduction/limitations"
|
||||
className="text-blue-600 dark:text-blue-400 hover:underline"
|
||||
>
|
||||
{isZh ? '《文档》' : 'Docs'}
|
||||
</Link>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</NeonGradientCard>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ul
|
||||
className="flex flex-wrap justify-center gap-6 text-sm text-gray-500 dark:text-gray-400"
|
||||
role="list"
|
||||
>
|
||||
<li className="flex items-center">
|
||||
<span className="w-2 h-2 bg-green-500 rounded-full mr-2" aria-hidden="true"></span>
|
||||
{isZh ? '纯前端方案' : 'Pure Front-end Solution'}
|
||||
</li>
|
||||
<li className="flex items-center">
|
||||
<span className="w-2 h-2 bg-green-500 rounded-full mr-2" aria-hidden="true"></span>
|
||||
{isZh ? '支持私有模型' : 'Your Own Models'}
|
||||
</li>
|
||||
<li className="flex items-center">
|
||||
<span className="w-2 h-2 bg-green-500 rounded-full mr-2" aria-hidden="true"></span>
|
||||
{isZh ? '无痛脱敏' : 'Built-in Privacy'}
|
||||
</li>
|
||||
<li className="flex items-center">
|
||||
<span className="w-2 h-2 bg-green-500 rounded-full mr-2" aria-hidden="true"></span>
|
||||
{isZh ? 'MIT 开源' : 'MIT Open Source'}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
98
packages/website/src/pages/home/OneMoreThingSection.tsx
Normal file
98
packages/website/src/pages/home/OneMoreThingSection.tsx
Normal file
@@ -0,0 +1,98 @@
|
||||
import { ExternalLink } from 'lucide-react'
|
||||
import { siGooglechrome } from 'simple-icons'
|
||||
import { Link } from 'wouter'
|
||||
|
||||
import { BlurFade } from '../../components/ui/blur-fade'
|
||||
import { MagicCard } from '../../components/ui/magic-card'
|
||||
import { useLanguage } from '../../i18n/context'
|
||||
|
||||
export default function OneMoreThingSection() {
|
||||
const { isZh } = useLanguage()
|
||||
|
||||
return (
|
||||
<section className="px-6 py-14" aria-labelledby="one-more-thing-heading">
|
||||
<div className="max-w-4xl mx-auto text-center">
|
||||
<BlurFade inView>
|
||||
<h2
|
||||
id="one-more-thing-heading"
|
||||
className="text-4xl lg:text-5xl font-bold mb-6 bg-linear-to-r from-blue-600 to-purple-600 bg-clip-text text-transparent"
|
||||
>
|
||||
One More Thing
|
||||
</h2>
|
||||
<p className="text-xl text-gray-600 dark:text-gray-300 mb-4 max-w-2xl mx-auto">
|
||||
{isZh
|
||||
? '想要多页面控制?试试可选的浏览器扩展。'
|
||||
: 'Need multi-page control? Try the optional browser extension.'}
|
||||
</p>
|
||||
<p className="text-sm text-gray-500 dark:text-gray-400 mb-12 max-w-2xl mx-auto">
|
||||
{'* '}
|
||||
{isZh
|
||||
? 'PageAgent.js 本身无需任何扩展即可工作,扩展是额外的能力增强。'
|
||||
: 'PageAgent.js works without any extension — this is a power-up, not a dependency.'}
|
||||
</p>
|
||||
</BlurFade>
|
||||
|
||||
<div className="flex flex-col sm:flex-row items-center justify-center gap-4 mb-12">
|
||||
<a
|
||||
href="https://chromewebstore.google.com/detail/page-agent-ext/akldabonmimlicnjlflnapfeklbfemhj"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="group inline-flex items-center gap-3 px-8 py-4 bg-linear-to-r from-blue-600 to-blue-700 hover:from-blue-700 hover:to-blue-800 text-white font-medium rounded-2xl shadow-lg hover:shadow-xl transition-all duration-300 hover:scale-105"
|
||||
>
|
||||
<img
|
||||
src="https://img.alicdn.com/imgextra/i3/O1CN01JpW0Vo1sR3FpiZKFM_!!6000000005762-55-tps-192-192.svg"
|
||||
alt="Chrome Web Store"
|
||||
className="w-7 h-7"
|
||||
/>
|
||||
<span>{isZh ? '从 Chrome 应用商店安装' : 'Install from Chrome Web Store'}</span>
|
||||
<ExternalLink className="w-4 h-4 opacity-50 group-hover:opacity-100 transition-opacity" />
|
||||
</a>
|
||||
<Link
|
||||
href="/docs/features/chrome-extension"
|
||||
className="inline-flex items-center gap-3 px-8 py-4 bg-gray-100 dark:bg-gray-700 hover:bg-gray-200 dark:hover:bg-gray-600 text-gray-900 dark:text-white font-medium rounded-2xl transition-all duration-300 hover:scale-105"
|
||||
>
|
||||
<svg className="w-5 h-5" viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path d={siGooglechrome.path} fill="currentColor" />
|
||||
</svg>
|
||||
<span>{isZh ? '查看文档' : 'Read the Docs'}</span>
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<div className="grid sm:grid-cols-3 gap-5 text-left max-w-3xl mx-auto">
|
||||
{[
|
||||
{
|
||||
title: isZh ? '多页面任务' : 'Multi-Page Tasks',
|
||||
desc: isZh
|
||||
? '跨多个页面和标签页连续执行任务,不再受限于单页上下文'
|
||||
: 'Run tasks across multiple pages and tabs without being limited to a single page context',
|
||||
},
|
||||
{
|
||||
title: isZh ? '页面内发起控制' : 'Control from Your Page',
|
||||
desc: isZh
|
||||
? '在页面 JS 中发起任务,驱动整个浏览器完成跨标签操作'
|
||||
: 'Trigger tasks from page JS to drive the entire browser across tabs',
|
||||
},
|
||||
{
|
||||
title: isZh ? '外部发起任务' : 'External Triggers',
|
||||
desc: isZh
|
||||
? '页面 JS、本地 Agent 或云端 Agent 均可通过扩展发起任务'
|
||||
: 'Page JS, local agents, or cloud agents can trigger tasks through the extension',
|
||||
},
|
||||
].map((item) => (
|
||||
<MagicCard
|
||||
key={item.title}
|
||||
className="rounded-xl"
|
||||
gradientColor="#8b5cf620"
|
||||
gradientOpacity={0.15}
|
||||
>
|
||||
<div className="p-5">
|
||||
<h3 className="font-semibold text-gray-900 dark:text-white mb-1">{item.title}</h3>
|
||||
<p className="text-sm text-gray-600 dark:text-gray-300">{item.desc}</p>
|
||||
</div>
|
||||
</MagicCard>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
172
packages/website/src/pages/home/ScenariosSection.tsx
Normal file
172
packages/website/src/pages/home/ScenariosSection.tsx
Normal file
@@ -0,0 +1,172 @@
|
||||
import { Bot, Users, Zap } from 'lucide-react'
|
||||
|
||||
import { BlurFade } from '../../components/ui/blur-fade'
|
||||
import { SparklesText } from '../../components/ui/sparkles-text'
|
||||
import { useLanguage } from '../../i18n/context'
|
||||
|
||||
export default function ScenariosSection() {
|
||||
const { isZh } = useLanguage()
|
||||
|
||||
return (
|
||||
<section
|
||||
className="px-6 py-16 bg-white/50 dark:bg-gray-800/50 backdrop-blur-sm"
|
||||
aria-labelledby="scenarios-heading"
|
||||
>
|
||||
<div className="max-w-6xl mx-auto">
|
||||
<BlurFade inView>
|
||||
<div className="text-center mb-12">
|
||||
<SparklesText
|
||||
className="text-4xl lg:text-5xl mb-6"
|
||||
colors={{ first: '#3b82f6', second: '#8b5cf6' }}
|
||||
>
|
||||
{isZh ? '应用场景' : 'Built For'}
|
||||
</SparklesText>
|
||||
</div>
|
||||
</BlurFade>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
|
||||
{/* Scenario 1: SaaS AI Copilot */}
|
||||
<BlurFade inView delay={0.05}>
|
||||
<div className="group relative overflow-hidden rounded-2xl bg-linear-to-b from-blue-50 to-white dark:from-blue-950/20 dark:to-gray-900 border border-blue-100/80 dark:border-blue-900/30 hover:shadow-xl hover:-translate-y-1 transition-all duration-500">
|
||||
<div className="p-6 pb-4">
|
||||
<div className="rounded-xl bg-gray-950 p-4 font-mono text-xs leading-6 text-gray-300 overflow-hidden shadow-inner">
|
||||
<div>
|
||||
<span className="text-purple-400">import</span> {'{ PageAgent }'}{' '}
|
||||
<span className="text-purple-400">from</span>{' '}
|
||||
<span className="text-emerald-400">'page-agent'</span>
|
||||
</div>
|
||||
<div className="mt-2">
|
||||
<span className="text-purple-400">const</span>{' '}
|
||||
<span className="text-blue-300">copilot</span> ={' '}
|
||||
<span className="text-purple-400">new</span>{' '}
|
||||
<span className="text-yellow-300">PageAgent</span>
|
||||
{'({'}
|
||||
</div>
|
||||
<div className="pl-4">
|
||||
<span className="text-blue-300">model</span>:{' '}
|
||||
<span className="text-emerald-400">'gpt-5.1'</span>,
|
||||
</div>
|
||||
<div className="pl-4">
|
||||
<span className="text-blue-300">apiKey</span>:{' '}
|
||||
<span className="text-emerald-400">process.env.KEY</span>,
|
||||
</div>
|
||||
<div>{'})'}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="p-6 pt-2">
|
||||
<div className="flex items-center gap-2 mb-2">
|
||||
<Bot className="w-5 h-5 text-blue-500" />
|
||||
<h3 className="font-semibold text-lg text-gray-900 dark:text-white">
|
||||
{isZh ? 'SaaS AI 副驾驶' : 'SaaS AI Copilot'}
|
||||
</h3>
|
||||
</div>
|
||||
<p className="text-sm text-gray-600 dark:text-gray-400 leading-relaxed">
|
||||
{isZh
|
||||
? '几小时内为你的产品加上 AI 副驾驶,不需要重写后端。'
|
||||
: 'Ship an AI copilot in your product in hours, not months. No backend rewrite needed.'}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</BlurFade>
|
||||
|
||||
{/* Scenario 2: Smart Form Filling */}
|
||||
<BlurFade inView delay={0.1}>
|
||||
<div className="group relative overflow-hidden rounded-2xl bg-linear-to-b from-amber-50 to-white dark:from-amber-950/20 dark:to-gray-900 border border-amber-100/80 dark:border-amber-900/30 hover:shadow-xl hover:-translate-y-1 transition-all duration-500">
|
||||
<div className="p-6 pb-4">
|
||||
<div className="rounded-xl bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 p-4 shadow-inner space-y-2.5">
|
||||
<div className="flex items-center gap-2 text-xs text-gray-500 bg-amber-50 dark:bg-amber-900/20 rounded-lg px-3 py-2 border border-amber-200/50 dark:border-amber-800/30">
|
||||
<span>🪄</span>
|
||||
<span className="italic">
|
||||
{isZh
|
||||
? '"填写上周五出差的报销单"'
|
||||
: '"Fill the expense report for Friday\'s trip"'}
|
||||
</span>
|
||||
</div>
|
||||
{[
|
||||
{
|
||||
label: isZh ? '姓名' : 'Name',
|
||||
value: 'John Smith',
|
||||
},
|
||||
{
|
||||
label: isZh ? '金额' : 'Amount',
|
||||
value: '$342.50',
|
||||
},
|
||||
{
|
||||
label: isZh ? '类目' : 'Category',
|
||||
value: 'Travel',
|
||||
},
|
||||
].map((field) => (
|
||||
<div key={field.label} className="flex items-center gap-2">
|
||||
<span className="text-xs text-gray-400 w-12 shrink-0">{field.label}</span>
|
||||
<div className="flex-1 h-7 bg-gray-50 dark:bg-gray-700 rounded border border-gray-200 dark:border-gray-600 px-2 flex items-center text-xs text-gray-600 dark:text-gray-300">
|
||||
{field.value}
|
||||
</div>
|
||||
<span className="text-emerald-500 text-xs">✓</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div className="p-6 pt-2">
|
||||
<div className="flex items-center gap-2 mb-2">
|
||||
<Zap className="w-5 h-5 text-amber-500" />
|
||||
<h3 className="font-semibold text-lg text-gray-900 dark:text-white">
|
||||
{isZh ? '智能表单填写' : 'Smart Form Filling'}
|
||||
</h3>
|
||||
</div>
|
||||
<p className="text-sm text-gray-600 dark:text-gray-400 leading-relaxed">
|
||||
{isZh
|
||||
? '把 20 次点击变成一句话。ERP、CRM、管理后台的最佳拍档。'
|
||||
: 'Turn 20-click workflows into one sentence. Perfect for ERP, CRM, and admin systems.'}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</BlurFade>
|
||||
|
||||
{/* Scenario 3: Accessibility */}
|
||||
<BlurFade inView delay={0.15}>
|
||||
<div className="group relative overflow-hidden rounded-2xl bg-linear-to-b from-purple-50 to-white dark:from-purple-950/20 dark:to-gray-900 border border-purple-100/80 dark:border-purple-900/30 hover:shadow-xl hover:-translate-y-1 transition-all duration-500">
|
||||
<div className="p-6 pb-4 flex flex-col items-center justify-center">
|
||||
<div className="w-full rounded-xl bg-purple-50 dark:bg-purple-900/20 p-5 space-y-3">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="w-8 h-8 rounded-full bg-purple-500/10 flex items-center justify-center text-base">
|
||||
🎤
|
||||
</div>
|
||||
<div className="text-sm text-purple-700 dark:text-purple-300 italic">
|
||||
{isZh ? '"点击提交按钮"' : '"Click the submit button"'}
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center gap-3 pl-11">
|
||||
<div className="flex items-center gap-1.5">
|
||||
<div className="w-1.5 h-1.5 bg-purple-400 rounded-full animate-pulse"></div>
|
||||
<div className="w-1.5 h-1.5 bg-purple-400 rounded-full animate-pulse [animation-delay:0.2s]"></div>
|
||||
<div className="w-1.5 h-1.5 bg-purple-400 rounded-full animate-pulse [animation-delay:0.4s]"></div>
|
||||
</div>
|
||||
<span className="text-xs text-purple-500">
|
||||
{isZh ? 'AI 正在执行...' : 'AI executing...'}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-3 pl-11 text-sm text-emerald-600 dark:text-emerald-400">
|
||||
<span>✓</span> {isZh ? '按钮已点击' : 'Button clicked'}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="p-6 pt-2">
|
||||
<div className="flex items-center gap-2 mb-2">
|
||||
<Users className="w-5 h-5 text-purple-500" />
|
||||
<h3 className="font-semibold text-lg text-gray-900 dark:text-white">
|
||||
{isZh ? '无障碍增强' : 'Accessibility'}
|
||||
</h3>
|
||||
</div>
|
||||
<p className="text-sm text-gray-600 dark:text-gray-400 leading-relaxed">
|
||||
{isZh
|
||||
? '用自然语言让任何网页无障碍。语音指令、屏幕阅读器,零门槛。'
|
||||
: 'Make any web app accessible through natural language. Voice, screen readers, zero barrier.'}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</BlurFade>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user