Skip to content

Commit 6ad20c8

Browse files
committed
feat(website): styling
1 parent ff4caae commit 6ad20c8

File tree

4 files changed

+216
-160
lines changed

4 files changed

+216
-160
lines changed

packages/website/src/components/ui/magic-card.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ export function MagicCard({
8585
`,
8686
}}
8787
/>
88-
<div className="bg-background absolute inset-px rounded-[inherit]" />
88+
<div className="absolute inset-px rounded-[inherit] bg-white dark:bg-neutral-900" />
8989
<motion.div
9090
className="pointer-events-none absolute inset-px rounded-[inherit] opacity-0 transition-opacity duration-300 group-hover:opacity-100"
9191
style={{

packages/website/src/pages/home/FeaturesSection.tsx

Lines changed: 191 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -1,163 +1,229 @@
11
import { Bot, Box, MessageSquare, Shield, Sparkles, Users } from 'lucide-react'
22

33
import { BlurFade } from '../../components/ui/blur-fade'
4-
import { Marquee } from '../../components/ui/marquee'
4+
import { Highlighter } from '../../components/ui/highlighter'
5+
import { MagicCard } from '../../components/ui/magic-card'
56
import { Particles } from '../../components/ui/particles'
67
import { useLanguage } from '../../i18n/context'
78

9+
// Word-cloud style: each item has a position (%), size, opacity, and color for a scattered look
10+
const LLM_CLOUD: {
11+
name: string
12+
color: string
13+
x: number
14+
y: number
15+
size: number
16+
opacity: number
17+
}[] = [
18+
{ name: 'OpenAI', color: '#10b981', x: 18, y: 22, size: 1.5, opacity: 1 },
19+
{ name: 'Claude', color: '#f97316', x: 62, y: 15, size: 1.35, opacity: 0.95 },
20+
{ name: 'Qwen', color: '#8b5cf6', x: 38, y: 50, size: 1.8, opacity: 0.9 },
21+
{ name: 'Gemini', color: '#3b82f6', x: 68, y: 48, size: 1.2, opacity: 0.85 },
22+
{ name: 'DeepSeek', color: '#06b6d4', x: 10, y: 65, size: 1.1, opacity: 0.8 },
23+
{ name: 'Grok', color: '#f43f5e', x: 52, y: 78, size: 1.0, opacity: 0.75 },
24+
{ name: 'Ollama', color: '#9ca3af', x: 82, y: 25, size: 1.1, opacity: 0.8 },
25+
{ name: 'Kimi', color: '#14b8a6', x: 30, y: 82, size: 0.85, opacity: 0.6 },
26+
{ name: 'GLM', color: '#f59e0b', x: 70, y: 72, size: 0.85, opacity: 0.55 },
27+
{ name: 'LLaMA', color: '#60a5fa', x: 88, y: 70, size: 0.8, opacity: 0.45 },
28+
]
29+
30+
const CARD_HEIGHT = 'h-72'
31+
832
export default function FeaturesSection() {
933
const { isZh } = useLanguage()
1034

1135
return (
1236
<section className="px-6 py-14" aria-labelledby="features-heading">
1337
<div className="max-w-6xl mx-auto">
14-
<div className="grid grid-cols-1 md:grid-cols-3 gap-4 auto-rows-[22rem]">
15-
{/* Zero Infrastructure (2-col) */}
38+
<div className="grid grid-cols-1 md:grid-cols-3 gap-4 auto-rows-[18rem]">
39+
{/* Row 1: Zero Infrastructure (2col) + Privacy (1col) */}
1640
<BlurFade inView className="col-span-1 md:col-span-2">
17-
<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">
18-
<div className="flex-1 p-8 flex flex-col justify-center">
19-
<div className="space-y-3 mb-6">
20-
{[
21-
'pip install browser-use playwright',
22-
'docker run -p 3000:3000 playwright-mcp',
23-
'const browser = await chromium.launch()',
24-
].map((cmd) => (
25-
<div
26-
key={cmd}
27-
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"
28-
>
29-
<span className="text-red-400/60 text-xs shrink-0"></span>
30-
{cmd}
31-
</div>
32-
))}
33-
</div>
34-
<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">
35-
<span className="text-emerald-500 text-xs shrink-0"></span>
36-
{'<script src="page-agent.js"></script>'}
41+
<MagicCard
42+
className="h-full rounded-2xl"
43+
gradientFrom="#3b82f6"
44+
gradientTo="#06b6d4"
45+
gradientColor="#3b82f6"
46+
gradientOpacity={0.15}
47+
>
48+
<div className={`flex ${CARD_HEIGHT} flex-col`}>
49+
<div className="flex-1 p-7 flex flex-col justify-center">
50+
<div className="space-y-2.5 mb-5">
51+
{[
52+
'pip install browser-use playwright',
53+
'docker run -p 3000:3000 playwright-mcp',
54+
'const browser = await chromium.launch()',
55+
].map((cmd) => (
56+
<div
57+
key={cmd}
58+
className="font-mono text-sm text-white-400 dark:text-gray-300 truncate"
59+
>
60+
<Highlighter
61+
action="strike-through"
62+
color="#ef4444aa"
63+
strokeWidth={1.5}
64+
// multiline={false}
65+
isView
66+
>
67+
{cmd}
68+
</Highlighter>
69+
</div>
70+
))}
71+
</div>
72+
<div className="bg-emerald-50 dark:bg-emerald-950/30 border border-emerald-200/60 dark:border-emerald-700/40 rounded-xl px-5 py-3 font-mono text-sm text-emerald-700 dark:text-emerald-400 flex items-center gap-2.5">
73+
<span className="text-emerald-500 text-xs shrink-0"></span>
74+
{'<script src="page-agent.js"></script>'}
75+
</div>
3776
</div>
38-
</div>
39-
<div className="px-8 pb-6">
40-
<div className="flex items-center gap-2.5 mb-1.5">
41-
<Box className="w-5 h-5 text-blue-500" />
42-
<h3 className="font-semibold text-lg text-gray-900 dark:text-white">
43-
{isZh ? '零基建集成' : 'Zero Infrastructure'}
44-
</h3>
77+
<div className="px-7 pb-5">
78+
<div className="flex items-center gap-2.5 mb-1">
79+
<Box className="w-5 h-5 text-blue-500" />
80+
<h3 className="font-semibold text-lg text-gray-900 dark:text-white">
81+
{isZh ? '零基建集成' : 'Zero Infrastructure'}
82+
</h3>
83+
</div>
84+
<p className="text-sm text-gray-500 dark:text-gray-300 leading-relaxed">
85+
{isZh
86+
? '无需 Python、无头浏览器、服务端部署。一行 script 标签搞定。'
87+
: "No Python. No headless browser. No server. One script tag — that's it."}
88+
</p>
4589
</div>
46-
<p className="text-sm text-gray-500 dark:text-gray-400 leading-relaxed">
47-
{isZh
48-
? '无需 Python、无头浏览器、服务端部署。一行 script 标签搞定。'
49-
: "No Python. No headless browser. No server. One script tag — that's it."}
50-
</p>
5190
</div>
52-
</div>
91+
</MagicCard>
5392
</BlurFade>
5493

55-
{/* Privacy by Default (1-col) */}
5694
<BlurFade inView delay={0.1} className="col-span-1">
57-
<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">
58-
<div className="flex-1 relative overflow-hidden">
59-
<Particles
60-
className="absolute inset-0"
61-
quantity={40}
62-
staticity={50}
63-
ease={80}
64-
color="#8b5cf6"
65-
/>
66-
<div className="absolute inset-0 flex items-center justify-center">
67-
<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">
68-
<Shield className="w-10 h-10 text-purple-500" strokeWidth={1.5} />
95+
<MagicCard
96+
className="h-full rounded-2xl"
97+
gradientFrom="#8b5cf6"
98+
gradientTo="#a855f7"
99+
gradientColor="#8b5cf6"
100+
gradientOpacity={0.12}
101+
>
102+
<div className={`flex ${CARD_HEIGHT} flex-col`}>
103+
<div className="flex-1 relative overflow-hidden">
104+
<Particles
105+
className="absolute inset-0"
106+
quantity={40}
107+
staticity={50}
108+
ease={80}
109+
color="#8b5cf6"
110+
/>
111+
<div className="absolute inset-0 flex items-center justify-center">
112+
<div className="w-16 h-16 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">
113+
<Shield className="w-8 h-8 text-purple-500" strokeWidth={1.5} />
114+
</div>
69115
</div>
70116
</div>
71-
</div>
72-
<div className="px-6 pb-6">
73-
<h3 className="font-semibold text-lg text-gray-900 dark:text-white mb-1.5">
74-
{isZh ? '隐私优先' : 'Privacy by Default'}
75-
</h3>
76-
<p className="text-sm text-gray-500 dark:text-gray-400 leading-relaxed">
77-
{isZh
78-
? '浏览器内运行,数据完全由你掌控。'
79-
: 'Runs in the browser. You control your data, always.'}
80-
</p>
81-
</div>
82-
</div>
83-
</BlurFade>
84-
85-
{/* Any LLM (1-col) */}
86-
<BlurFade inView delay={0.15} className="col-span-1">
87-
<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">
88-
<div className="flex-1 relative overflow-hidden">
89-
<Marquee vertical pauseOnHover className="h-full [--duration:25s] [--gap:0.75rem]">
90-
{['OpenAI', 'Claude', 'DeepSeek', 'Qwen', 'Gemini', 'GLM', 'Ollama', 'Groq'].map(
91-
(name) => (
92-
<div
93-
key={name}
94-
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"
95-
>
96-
{name}
97-
</div>
98-
)
99-
)}
100-
</Marquee>
101-
</div>
102-
<div className="px-6 pb-6">
103-
<div className="flex items-center gap-2.5 mb-1.5">
104-
<Sparkles className="w-5 h-5 text-amber-500" />
105-
<h3 className="font-semibold text-lg text-gray-900 dark:text-white">
106-
{isZh ? '兼容多种 LLM' : 'Bring Your Own LLMs'}
117+
<div className="px-6 pb-5">
118+
<h3 className="font-semibold text-lg text-gray-900 dark:text-white mb-1">
119+
{isZh ? '隐私优先' : 'Privacy by Default'}
107120
</h3>
121+
<p className="text-sm text-gray-500 dark:text-gray-300 leading-relaxed">
122+
{isZh
123+
? '浏览器内运行,数据完全由你掌控。'
124+
: 'Runs in the browser. You control your data, always.'}
125+
</p>
108126
</div>
109-
<p className="text-sm text-gray-500 dark:text-gray-400 leading-relaxed">
110-
{isZh
111-
? 'OpenAI、Claude、DeepSeek、Qwen 等,或通过 Ollama 完全离线。'
112-
: 'OpenAI, Claude, DeepSeek, Qwen, and more — or fully offline via Ollama.'}
113-
</p>
114127
</div>
115-
</div>
128+
</MagicCard>
116129
</BlurFade>
117130

118-
{/* Human-in-the-Loop (2-col) */}
119-
<BlurFade inView delay={0.2} className="col-span-1 md:col-span-2">
120-
<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">
121-
<div className="flex-1 p-8 flex flex-col justify-center max-w-md mx-auto w-full">
122-
<div className="flex gap-2.5 mb-3">
123-
<div className="shrink-0 w-7 h-7 rounded-full bg-purple-100 dark:bg-purple-900/50 flex items-center justify-center">
124-
<Bot className="w-4 h-4 text-purple-600 dark:text-purple-400" />
125-
</div>
126-
<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">
127-
{isZh ? '找到 3 条匹配记录。选择哪一条?' : 'Found 3 matches. Which one?'}
131+
{/* Row 2: Human-in-the-Loop (1col) + LLM (2col) */}
132+
<BlurFade inView delay={0.15} className="col-span-1">
133+
<MagicCard
134+
className="h-full rounded-2xl"
135+
gradientFrom="#3b82f6"
136+
gradientTo="#8b5cf6"
137+
gradientColor="#6366f1"
138+
gradientOpacity={0.12}
139+
>
140+
<div className={`flex ${CARD_HEIGHT} flex-col`}>
141+
<div className="flex-1 p-5 flex flex-col justify-center max-w-xs mx-auto w-full">
142+
<div className="flex gap-2 mb-2.5">
143+
<div className="shrink-0 w-6 h-6 rounded-full bg-purple-100 dark:bg-purple-900/50 flex items-center justify-center">
144+
<Bot className="w-3.5 h-3.5 text-purple-600 dark:text-purple-400" />
145+
</div>
146+
<div className="bg-gray-100 dark:bg-white/10 rounded-2xl rounded-tl-md px-3.5 py-2 text-sm text-gray-700 dark:text-gray-200">
147+
{isZh ? '找到 3 条匹配记录。选择哪一条?' : 'Found 3 matches. Which one?'}
148+
</div>
128149
</div>
129-
</div>
130-
<div className="flex gap-2.5 justify-end mb-3">
131-
<div className="bg-blue-500 rounded-2xl rounded-tr-md px-4 py-2.5 text-sm text-white">
132-
{isZh ? '第二条' : 'The second one.'}
150+
<div className="flex gap-2 justify-end mb-2.5">
151+
<div className="bg-blue-500 rounded-2xl rounded-tr-md px-3.5 py-2 text-sm text-white">
152+
{isZh ? '第二条' : 'The second one.'}
153+
</div>
154+
<div className="shrink-0 w-6 h-6 rounded-full bg-blue-100 dark:bg-blue-900/50 flex items-center justify-center">
155+
<Users className="w-3.5 h-3.5 text-blue-600 dark:text-blue-400" />
156+
</div>
133157
</div>
134-
<div className="shrink-0 w-7 h-7 rounded-full bg-blue-100 dark:bg-blue-900/50 flex items-center justify-center">
135-
<Users className="w-4 h-4 text-blue-600 dark:text-blue-400" />
158+
<div className="flex gap-2">
159+
<div className="shrink-0 w-6 h-6 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">
160+
161+
</div>
162+
<div className="bg-gray-100 dark:bg-white/10 rounded-2xl rounded-tl-md px-3.5 py-2 text-sm text-gray-700 dark:text-gray-200">
163+
{isZh ? '已选择并提交!' : 'Done! Selected and submitted.'}
164+
</div>
136165
</div>
137166
</div>
138-
<div className="flex gap-2.5">
139-
<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">
140-
141-
</div>
142-
<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">
143-
{isZh ? '已选择并提交!' : 'Done! Selected and submitted.'}
167+
<div className="px-5 pb-5">
168+
<div className="flex items-center gap-2.5 mb-1">
169+
<MessageSquare className="w-5 h-5 text-blue-500" />
170+
<h3 className="font-semibold text-lg text-gray-900 dark:text-white">
171+
{isZh ? '人机协同' : 'Human-in-the-Loop'}
172+
</h3>
144173
</div>
174+
<p className="text-sm text-gray-500 dark:text-gray-300 leading-relaxed">
175+
{isZh
176+
? '内置协作面板,AI 操作前先确认——不是盲目自动化。'
177+
: 'Built-in collaborative panel. Agent asks before acting — not blind automation.'}
178+
</p>
145179
</div>
146180
</div>
147-
<div className="px-8 pb-6">
148-
<div className="flex items-center gap-2.5 mb-1.5">
149-
<MessageSquare className="w-5 h-5 text-blue-500" />
150-
<h3 className="font-semibold text-lg text-gray-900 dark:text-white">
151-
{isZh ? '人机协同' : 'Human-in-the-Loop'}
152-
</h3>
181+
</MagicCard>
182+
</BlurFade>
183+
184+
<BlurFade inView delay={0.2} className="col-span-1 md:col-span-2">
185+
<MagicCard
186+
className="h-full rounded-2xl"
187+
gradientFrom="#f59e0b"
188+
gradientTo="#f97316"
189+
gradientColor="#f59e0b"
190+
gradientOpacity={0.12}
191+
>
192+
<div className={`flex ${CARD_HEIGHT} flex-col`}>
193+
<div className="flex-1 overflow-hidden relative">
194+
{LLM_CLOUD.map((item) => (
195+
<span
196+
key={item.name}
197+
className="absolute font-semibold whitespace-nowrap select-none"
198+
style={{
199+
left: `${item.x}%`,
200+
top: `${item.y}%`,
201+
fontSize: `${item.size}rem`,
202+
color: item.color,
203+
opacity: item.opacity,
204+
transform: 'translate(-50%, -50%)',
205+
textShadow: `0 0 80px ${item.color}99`,
206+
}}
207+
>
208+
{item.name}
209+
</span>
210+
))}
211+
</div>
212+
<div className="px-7 pb-5">
213+
<div className="flex items-center gap-2.5 mb-1">
214+
<Sparkles className="w-5 h-5 text-amber-500" />
215+
<h3 className="font-semibold text-lg text-gray-900 dark:text-white">
216+
{isZh ? '兼容多种 LLM' : 'Bring Your Own LLMs'}
217+
</h3>
218+
</div>
219+
<p className="text-sm text-gray-500 dark:text-gray-300 leading-relaxed">
220+
{isZh
221+
? 'OpenAI、Claude、DeepSeek、Qwen 等,或通过 Ollama 完全离线。'
222+
: 'OpenAI, Claude, DeepSeek, Qwen, and more — or fully offline via Ollama.'}
223+
</p>
153224
</div>
154-
<p className="text-sm text-gray-500 dark:text-gray-400 leading-relaxed">
155-
{isZh
156-
? '内置协作面板,AI 操作前先确认——不是盲目自动化。'
157-
: 'Built-in collaborative panel. Agent asks before acting — not blind automation.'}
158-
</p>
159225
</div>
160-
</div>
226+
</MagicCard>
161227
</BlurFade>
162228
</div>
163229
</div>

packages/website/src/pages/home/HeroSection.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ export default function HeroSection() {
170170
<div className="flex border-b border-gray-200 dark:border-gray-700">
171171
<button
172172
onClick={() => setActiveTab('try')}
173-
className={`flex-1 px-4 py-4 text-lg font-medium transition-colors duration-200 rounded-tl-2xl ${
173+
className={`cursor-pointer flex-1 px-4 py-4 text-lg font-medium transition-colors duration-200 rounded-tl-2xl ${
174174
activeTab === 'try'
175175
? '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'
176176
: 'text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white hover:bg-gray-50 dark:hover:bg-gray-700'
@@ -180,7 +180,7 @@ export default function HeroSection() {
180180
</button>
181181
<button
182182
onClick={() => setActiveTab('other')}
183-
className={`flex-1 px-4 py-4 text-lg font-medium transition-colors duration-200 rounded-tr-2xl ${
183+
className={`cursor-pointer flex-1 px-4 py-4 text-lg font-medium transition-colors duration-200 rounded-tr-2xl ${
184184
activeTab === 'other'
185185
? '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'
186186
: 'text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white hover:bg-gray-50 dark:hover:bg-gray-700'

0 commit comments

Comments
 (0)