Skip to content

Commit 09dfe9e

Browse files
authored
Merge pull request #27 from yandiaan/feature/landing-page
fix(): add new landing page sections including How It Works, Node-Bas…
2 parents 9e8e040 + b82371b commit 09dfe9e

4 files changed

Lines changed: 199 additions & 193 deletions

File tree

apps/web/src/components/landing/sections/ContributorsSection.tsx

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -308,20 +308,23 @@ export function ContributorsSection() {
308308
<div className="absolute top-1/2 left-1/4 w-2 h-2 bg-white rounded-full blur-sm" />
309309
</div>
310310

311-
{/* Header */}
312-
<div ref={headRef} className="relative z-10 shrink-0 px-5 pt-3 sm:pt-4 pb-2 text-center">
313-
<h2 className="text-xl sm:text-2xl md:text-3xl lg:text-4xl font-bold text-white tracking-tight">
314-
Built by <span className="text-primary">Architects</span> of the Future.
315-
</h2>
316-
<div className="h-1 w-16 bg-white/20 mx-auto rounded-full mt-2" />
317-
</div>
311+
{/* Scrollable Container with my-auto centering */}
312+
<div className="relative z-10 flex-1 px-4 sm:px-8 md:px-12 lg:px-16 py-4 sm:py-6 overflow-y-auto flex flex-col">
313+
<div className="my-auto w-full max-w-7xl mx-auto flex flex-col shrink-0 py-2">
314+
{/* Header */}
315+
<div ref={headRef} className="shrink-0 px-5 pb-5 sm:pb-8 lg:pb-12 text-center">
316+
<h2 className="text-xl sm:text-2xl md:text-3xl lg:text-4xl font-bold text-white tracking-tight text-balance">
317+
Built by <span className="text-primary">Architects</span> of the Future.
318+
</h2>
319+
<div className="h-1 w-16 bg-white/20 mx-auto rounded-full mt-3 sm:mt-4" />
320+
</div>
318321

319-
{/* Cards */}
320-
<div className="relative z-10 flex-1 px-4 sm:px-8 md:px-12 lg:px-16 pb-4 sm:pb-8 min-h-0 overflow-y-auto">
321-
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4 sm:gap-6 w-full">
322-
{contributors.map((c, i) => (
323-
<ContributorCard key={c.name} c={c} index={i} />
324-
))}
322+
{/* Cards */}
323+
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4 sm:gap-6 w-full">
324+
{contributors.map((c, i) => (
325+
<ContributorCard key={c.name} c={c} index={i} />
326+
))}
327+
</div>
325328
</div>
326329
</div>
327330
</div>

apps/web/src/components/landing/sections/HowItWorksSection.tsx

Lines changed: 63 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,10 @@ const StepNode = memo(function StepNode({
7878
<div ref={ref} className="flex flex-col items-center gap-3 group flex-1 min-w-0">
7979
{/* Icon node */}
8080
<div
81-
className={`relative rounded-2xl flex items-center justify-center border transition-all duration-300 ${
82-
step.active
83-
? 'w-16 h-16 sm:w-18 sm:h-18 border-primary/60 bg-primary/10'
84-
: 'w-14 h-14 sm:w-16 sm:h-16 border-white/10 hover:border-white/25 bg-surface-panel'
85-
}`}
81+
className={`relative rounded-2xl flex items-center justify-center border transition-all duration-300 ${step.active
82+
? 'w-16 h-16 sm:w-18 sm:h-18 border-primary/60 bg-primary/10'
83+
: 'w-14 h-14 sm:w-16 sm:h-16 border-white/10 hover:border-white/25 bg-surface-panel'
84+
}`}
8685
style={
8786
step.active
8887
? { boxShadow: '0 0 28px rgba(254,115,58,0.2), 0 0 0 4px rgba(254,115,58,0.08)' }
@@ -94,9 +93,8 @@ const StepNode = memo(function StepNode({
9493
className={step.active ? 'text-primary' : 'text-white/50'}
9594
/>
9695
<div
97-
className={`absolute -top-2.5 -right-2.5 text-xs font-bold px-1.5 py-0.5 rounded-full leading-none ${
98-
step.active ? 'bg-primary text-white' : 'bg-white/10 text-white/40'
99-
}`}
96+
className={`absolute -top-2.5 -right-2.5 text-xs font-bold px-1.5 py-0.5 rounded-full leading-none ${step.active ? 'bg-primary text-white' : 'bg-white/10 text-white/40'
97+
}`}
10098
>
10199
{step.n}
102100
</div>
@@ -107,11 +105,10 @@ const StepNode = memo(function StepNode({
107105

108106
{/* Info card */}
109107
<div
110-
className={`rounded-xl text-center w-full px-3 py-3 border transition-all duration-300 ${
111-
step.active
112-
? 'border-primary/25 bg-primary/5'
113-
: 'border-white/5 bg-surface-panel/50 group-hover:border-white/15'
114-
}`}
108+
className={`rounded-xl text-center w-full px-3 py-3 border transition-all duration-300 ${step.active
109+
? 'border-primary/25 bg-primary/5'
110+
: 'border-white/5 bg-surface-panel/50 group-hover:border-white/15'
111+
}`}
115112
>
116113
{step.active && (
117114
<p className="text-primary/80 font-bold uppercase text-[10px] tracking-widest mb-1">
@@ -192,61 +189,63 @@ export function HowItWorksSection({ onGetStarted }: SectionProps) {
192189
}}
193190
/>
194191

195-
<div ref={ref} className="relative z-10 flex flex-col h-full px-4 sm:px-10 md:px-14 py-4 sm:py-6 md:py-8 overflow-y-auto">
196-
{/* Header */}
197-
<div ref={headerRef} className="text-center mb-4 sm:mb-6 md:mb-8 shrink-0">
198-
<p className="text-white/30 text-xs font-bold tracking-[0.25em] uppercase mb-2">
199-
The Logic Engine
200-
</p>
201-
<h2 className="text-2xl sm:text-3xl md:text-4xl font-black text-white leading-tight tracking-tight uppercase">
202-
How It Works
203-
</h2>
204-
<p className="text-slate-400 text-sm mt-2 sm:mt-3 max-w-sm mx-auto leading-relaxed">
205-
Visualize your creative process through our advanced node-based workflow.
206-
</p>
207-
</div>
208-
209-
{/* Steps flow */}
210-
<div className="flex-1 flex flex-col min-h-0 md:justify-center">
211-
<div className="relative">
212-
{/* Connecting line – only visible on lg+ where all 5 fit in a row */}
213-
<div
214-
className="absolute left-0 right-0 h-px z-0 hidden lg:block"
215-
style={{
216-
top: '32px',
217-
background:
218-
'linear-gradient(to right, transparent, rgba(255,255,255,0.08) 20%, rgba(255,255,255,0.08) 80%, transparent)',
219-
}}
220-
/>
221-
222-
{/* Responsive grid: 2 cols on mobile, 3 on sm/md, 5 on lg+ */}
223-
<div className="relative z-10 grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-5 gap-3 sm:gap-4">
224-
{steps.map((s, i) => (
225-
<StepNode key={s.n} step={s} index={i} inView={inView} />
226-
))}
227-
</div>
192+
<div ref={ref} className="relative z-10 flex flex-col h-full px-4 sm:px-10 md:px-14 py-2 sm:py-4 overflow-y-auto">
193+
<div className="my-auto flex flex-col w-full max-w-7xl mx-auto shrink-0 py-4">
194+
{/* Header */}
195+
<div ref={headerRef} className="text-center mb-5 md:mb-6 lg:mb-8 shrink-0">
196+
<p className="text-white/30 text-[10px] sm:text-xs font-bold tracking-[0.25em] uppercase mb-1.5 sm:mb-2 text-balance">
197+
The Logic Engine
198+
</p>
199+
<h2 className="text-2xl sm:text-3xl lg:text-4xl font-black text-white leading-tight tracking-tight uppercase">
200+
How It Works
201+
</h2>
202+
<p className="text-slate-400 text-xs sm:text-sm mt-1.5 sm:mt-2 max-w-sm mx-auto leading-relaxed text-balance">
203+
Visualize your creative process through our advanced node-based workflow.
204+
</p>
228205
</div>
229206

230-
{/* CTA card */}
231-
<div
232-
ref={ctaRef}
233-
className="mt-4 sm:mt-6 md:mt-8 rounded-xl border border-white/10 bg-surface-panel px-4 sm:px-5 py-3 sm:py-4 flex flex-col sm:flex-row items-start sm:items-center justify-between gap-3 sm:gap-4"
234-
>
235-
<div>
236-
<h4 className="text-white font-bold text-sm sm:text-base">
237-
Ready to build your first pipeline?
238-
</h4>
239-
<p className="text-slate-400 text-xs sm:text-sm mt-0.5">
240-
Start with a template or build from scratch.
241-
</p>
207+
{/* Steps flow */}
208+
<div className="w-full flex flex-col min-h-0 pt-2 md:pt-0">
209+
<div className="relative">
210+
{/* Connecting line – only visible on lg+ where all 5 fit in a row */}
211+
<div
212+
className="absolute left-0 right-0 h-px z-0 hidden lg:block"
213+
style={{
214+
top: '32px',
215+
background:
216+
'linear-gradient(to right, transparent, rgba(255,255,255,0.08) 20%, rgba(255,255,255,0.08) 80%, transparent)',
217+
}}
218+
/>
219+
220+
{/* Responsive grid: 2 cols on mobile, 3 on sm/md, 5 on lg+ */}
221+
<div className="relative z-10 grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-5 gap-3 sm:gap-4">
222+
{steps.map((s, i) => (
223+
<StepNode key={s.n} step={s} index={i} inView={inView} />
224+
))}
225+
</div>
242226
</div>
243-
<button
244-
onClick={onGetStarted}
245-
className="cursor-pointer shrink-0 bg-primary text-white font-bold text-sm px-5 py-2.5 rounded-lg hover:opacity-90 transition-opacity flex items-center gap-2"
227+
228+
{/* CTA card */}
229+
<div
230+
ref={ctaRef}
231+
className="mt-5 lg:mt-6 rounded-xl border border-white/10 bg-surface-panel px-4 sm:px-5 py-3 sm:py-4 flex flex-col sm:flex-row items-start sm:items-center justify-between gap-3 sm:gap-4"
246232
>
247-
Launch Editor
248-
<ArrowRight size={14} />
249-
</button>
233+
<div>
234+
<h4 className="text-white font-bold text-sm sm:text-base">
235+
Ready to build your first pipeline?
236+
</h4>
237+
<p className="text-slate-400 text-[10px] sm:text-sm mt-0.5">
238+
Start with a template or build from scratch.
239+
</p>
240+
</div>
241+
<button
242+
onClick={onGetStarted}
243+
className="cursor-pointer shrink-0 bg-primary text-white font-bold text-xs sm:text-sm px-4 sm:px-5 py-2 sm:py-2.5 rounded-lg hover:opacity-90 transition-opacity flex items-center gap-2"
244+
>
245+
Launch Editor
246+
<ArrowRight size={14} />
247+
</button>
248+
</div>
250249
</div>
251250
</div>
252251
</div>

apps/web/src/components/landing/sections/NodeBasedSection.tsx

Lines changed: 74 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -288,86 +288,88 @@ export function NodeBasedSection({ onGetStarted }: SectionProps) {
288288
style={{ background: 'radial-gradient(circle, rgba(96,165,250,0.05) 0%, transparent 70%)', filter: 'blur(40px)' }}
289289
/>
290290

291-
<div ref={ref} className="relative z-10 flex flex-col h-full px-4 sm:px-10 md:px-14 py-4 sm:py-6 md:py-8 overflow-y-auto">
292-
{/* Header */}
293-
<div ref={headerRef} className="text-center mb-4 sm:mb-6 md:mb-8 shrink-0">
294-
<p className="text-white/30 text-xs font-bold tracking-[0.25em] uppercase mb-2">
295-
Visual Programming
296-
</p>
297-
<h2 className="text-2xl sm:text-3xl md:text-4xl font-black text-white leading-tight tracking-tight uppercase">
298-
Node Based System
299-
</h2>
300-
<p className="text-slate-400 text-sm mt-2 sm:mt-3 max-w-sm mx-auto leading-relaxed">
301-
Connect intelligent building blocks to create powerful AI pipelines.
302-
</p>
303-
</div>
291+
<div ref={ref} className="relative z-10 flex flex-col h-full px-4 sm:px-10 md:px-14 py-2 sm:py-4 overflow-y-auto">
292+
<div className="my-auto flex flex-col w-full max-w-7xl mx-auto shrink-0 py-4">
293+
{/* Header */}
294+
<div ref={headerRef} className="text-center mb-5 md:mb-6 lg:mb-8 shrink-0">
295+
<p className="text-white/30 text-[10px] sm:text-xs font-bold tracking-[0.25em] uppercase mb-1.5 sm:mb-2 text-balance">
296+
Visual Programming
297+
</p>
298+
<h2 className="text-2xl sm:text-3xl lg:text-4xl font-black text-white leading-tight tracking-tight uppercase">
299+
Node Based System
300+
</h2>
301+
<p className="text-slate-400 text-xs sm:text-sm mt-1.5 sm:mt-2 max-w-sm mx-auto leading-relaxed text-balance">
302+
Connect intelligent building blocks to create powerful AI pipelines.
303+
</p>
304+
</div>
304305

305-
{/* Pipeline preview */}
306-
<div className="flex-1 flex flex-col items-center min-h-0 gap-4 sm:gap-5 md:gap-6 md:justify-center">
307-
{/* Node row with wires — horizontally scrollable on very small screens */}
308-
<div className="w-full overflow-x-auto py-4 shrink-0">
309-
<div className="flex items-center justify-center gap-0 min-w-max mx-auto px-4">
310-
{previewNodes.map((node, i) => (
311-
<div key={node.type} className="flex items-center">
312-
<div className="w-44 sm:w-52 md:w-60">
313-
<StaticNode node={node} index={i} inView={inView} />
306+
{/* Pipeline preview */}
307+
<div className="w-full flex flex-col items-center min-h-0 gap-4 sm:gap-5 lg:gap-6 pt-2 md:pt-0">
308+
{/* Node row with wires — horizontally scrollable on very small screens */}
309+
<div className="w-full overflow-x-auto py-4 shrink-0">
310+
<div className="flex items-center justify-center gap-0 min-w-max mx-auto px-4">
311+
{previewNodes.map((node, i) => (
312+
<div key={node.type} className="flex items-center">
313+
<div className="w-44 sm:w-52 md:w-60">
314+
<StaticNode node={node} index={i} inView={inView} />
315+
</div>
316+
{i < previewNodes.length - 1 && (
317+
<WireConnector
318+
fromColor={previewNodes[i].color}
319+
toColor={previewNodes[i + 1].color}
320+
delay={0.3 + i * 0.15}
321+
inView={inView}
322+
/>
323+
)}
314324
</div>
315-
{i < previewNodes.length - 1 && (
316-
<WireConnector
317-
fromColor={previewNodes[i].color}
318-
toColor={previewNodes[i + 1].color}
319-
delay={0.3 + i * 0.15}
320-
inView={inView}
321-
/>
322-
)}
325+
))}
326+
</div>
327+
</div>
328+
329+
{/* Category legend */}
330+
<div
331+
ref={legendRef}
332+
className="flex items-center justify-center gap-3 sm:gap-4 flex-wrap"
333+
>
334+
{[
335+
{ label: 'Input', color: '#4ade80' },
336+
{ label: 'Transform', color: '#a78bfa' },
337+
{ label: 'Generate', color: '#60a5fa' },
338+
{ label: 'Compose', color: '#f59e0b' },
339+
{ label: 'Output', color: '#f87171' },
340+
].map((cat) => (
341+
<div key={cat.label} className="flex items-center gap-1.5">
342+
<div className="size-2 rounded-full" style={{ background: cat.color }} />
343+
<span className="text-xs font-medium text-white/40">{cat.label}</span>
323344
</div>
324345
))}
325346
</div>
326-
</div>
327347

328-
{/* Category legend */}
329-
<div
330-
ref={legendRef}
331-
className="flex items-center justify-center gap-3 sm:gap-4 flex-wrap"
332-
>
333-
{[
334-
{ label: 'Input', color: '#4ade80' },
335-
{ label: 'Transform', color: '#a78bfa' },
336-
{ label: 'Generate', color: '#60a5fa' },
337-
{ label: 'Compose', color: '#f59e0b' },
338-
{ label: 'Output', color: '#f87171' },
339-
].map((cat) => (
340-
<div key={cat.label} className="flex items-center gap-1.5">
341-
<div className="size-2 rounded-full" style={{ background: cat.color }} />
342-
<span className="text-xs font-medium text-white/40">{cat.label}</span>
343-
</div>
344-
))}
345-
</div>
348+
{/* Feature pills */}
349+
<div
350+
ref={pillsRef}
351+
className="flex items-center justify-center gap-2 flex-wrap"
352+
>
353+
{['Drag & Drop', 'Auto-connect', 'Type Safety', '10+ Node Types'].map((tag) => (
354+
<span
355+
key={tag}
356+
className="text-white/40 text-xs font-medium bg-white/5 rounded-full px-3 py-1 border border-white/8"
357+
>
358+
{tag}
359+
</span>
360+
))}
361+
</div>
346362

347-
{/* Feature pills */}
348-
<div
349-
ref={pillsRef}
350-
className="flex items-center justify-center gap-2 flex-wrap"
351-
>
352-
{['Drag & Drop', 'Auto-connect', 'Type Safety', '10+ Node Types'].map((tag) => (
353-
<span
354-
key={tag}
355-
className="text-white/40 text-xs font-medium bg-white/5 rounded-full px-3 py-1 border border-white/8"
363+
{/* CTA */}
364+
<div ref={ctaRef} className="mt-2 sm:mt-4">
365+
<button
366+
onClick={onGetStarted}
367+
className="cursor-pointer bg-primary text-white font-bold text-xs sm:text-sm px-5 sm:px-6 py-2 sm:py-2.5 rounded-lg hover:opacity-90 transition-opacity flex items-center gap-2"
356368
>
357-
{tag}
358-
</span>
359-
))}
360-
</div>
361-
362-
{/* CTA */}
363-
<div ref={ctaRef}>
364-
<button
365-
onClick={onGetStarted}
366-
className="cursor-pointer bg-primary text-white font-bold text-sm px-6 py-2.5 rounded-lg hover:opacity-90 transition-opacity flex items-center gap-2"
367-
>
368-
Try the Editor
369-
<ArrowRight size={14} />
370-
</button>
369+
Try the Editor
370+
<ArrowRight size={14} />
371+
</button>
372+
</div>
371373
</div>
372374
</div>
373375
</div>

0 commit comments

Comments
 (0)