Skip to content

Commit 19cdd45

Browse files
yethikrishnaclaude
andcommitted
feat: production-grade animated components replacing video demos
Create four high-fidelity animated React components that replace video demos with realistic, interactive product simulations: 1. TerminalAnimation - Pixel-perfect terminal emulator with: - macOS traffic lights, tab chrome, status bar - Realistic multi-agent workflow (File Picker → Planner → Editor → Reviewer) - Actual code diffs with syntax-highlighted +/- lines - File tree exploration animation - Typewriter effect with blinking cursor - "by Yethikrishna R" watermark in status bar 2. CodeEditAnimation - Split-pane IDE diff view with: - Before/After code comparison - Syntax highlighting (keywords, strings, methods) - Line numbers and +/- indicators - File tab cycling animation - Scroll-triggered reveal 3. FeatureShowcase - Four animated feature cards: - 200+ Models: Cycling model name badges - Multi-Agent: Orbiting agent icons around LC center - Open Source: Animated GitHub star counter - Standalone: Step-by-step install animation 4. BrandHero - Branded CTA section with: - Floating code symbols background - Gradient "LEVELCODE" text - "Founded by Yethikrishna R" credit - npm install command with copy button - GitHub stars badge All components use Framer Motion, support dark mode, are responsive, and loop seamlessly. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 927af68 commit 19cdd45

5 files changed

Lines changed: 1075 additions & 253 deletions

File tree

‎web/src/app/home-client.tsx‎

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ import { useSearchParams } from 'next/navigation'
66
import { useSession } from 'next-auth/react'
77
import { useEffect, Suspense } from 'react'
88

9+
import BrandHero from '@/components/BrandHero'
10+
import CodeEditAnimation from '@/components/CodeEditAnimation'
11+
import FeatureShowcase from '@/components/FeatureShowcase'
912
import TerminalAnimation from '@/components/TerminalAnimation'
1013
import { ReferralRedirect } from '@/components/referral-redirect'
1114
import { BlockColor, DecorativeBlocks } from '@/components/ui/decorative-blocks'
@@ -337,8 +340,54 @@ export default function HomeClient() {
337340
}
338341
/> */}
339342

343+
{/* ── Code Edit Animation ─────────────────────────────────────── */}
344+
<Section background={BlockColor.Black}>
345+
<div className="py-16 space-y-8 text-center">
346+
<motion.div
347+
initial={{ opacity: 0, y: 20 }}
348+
whileInView={{ opacity: 1, y: 0 }}
349+
viewport={{ once: true, amount: 0.3 }}
350+
transition={{ duration: 0.6 }}
351+
>
352+
<h2 className="text-3xl md:text-4xl font-bold text-white mb-3">
353+
See the Diff
354+
</h2>
355+
<p className="text-zinc-400 max-w-lg mx-auto">
356+
LevelCode shows you exactly what changes before applying them &mdash; real code diffs, not black-box edits.
357+
</p>
358+
</motion.div>
359+
<CodeEditAnimation />
360+
</div>
361+
</Section>
362+
363+
{/* ── Feature Showcase Cards ──────────────────────────────────── */}
364+
<Section background={BlockColor.BetweenGreen}>
365+
<div className="py-16 space-y-8 text-center">
366+
<motion.div
367+
initial={{ opacity: 0, y: 20 }}
368+
whileInView={{ opacity: 1, y: 0 }}
369+
viewport={{ once: true, amount: 0.3 }}
370+
transition={{ duration: 0.6 }}
371+
>
372+
<h2 className="text-3xl md:text-4xl font-bold text-black mb-3">
373+
Why Developers Choose LevelCode
374+
</h2>
375+
<p className="text-zinc-600 max-w-lg mx-auto">
376+
Built different. Open source, multi-agent, standalone.
377+
</p>
378+
</motion.div>
379+
<FeatureShowcase />
380+
</div>
381+
</Section>
382+
340383
{/* <CompetitionSection /> */}
341384
<TestimonialsSection />
385+
386+
{/* ── Brand Hero / CTA ────────────────────────────────────────── */}
387+
<Section background={BlockColor.Black}>
388+
<BrandHero />
389+
</Section>
390+
342391
<CTASection />
343392
</div>
344393
</div>

‎web/src/components/BrandHero.tsx‎

Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
'use client'
2+
3+
import { motion } from 'framer-motion'
4+
import { useCallback, useEffect, useState } from 'react'
5+
6+
// ─── FLOATING CODE SYMBOLS ──────────────────────────────────────────────────────
7+
8+
const SYMBOLS = [
9+
'{ }', '< />', '( )', '[ ]', '=>', '&&', '||', '...', '??', '::',
10+
'fn', 'if', 'let', '===', '#!', '/**', '*/', '/**/', '0x', '//',
11+
]
12+
13+
function FloatingSymbol({ symbol, index }: { symbol: string; index: number }) {
14+
const x = 5 + (index * 17) % 90
15+
const delay = index * 0.7
16+
const duration = 8 + (index % 5) * 2
17+
18+
return (
19+
<motion.span
20+
className="absolute text-zinc-800/40 font-mono text-sm sm:text-base pointer-events-none select-none"
21+
style={{ left: `${x}%` }}
22+
initial={{ y: '110%', opacity: 0 }}
23+
animate={{
24+
y: '-10%',
25+
opacity: [0, 0.4, 0.4, 0],
26+
}}
27+
transition={{
28+
duration,
29+
delay,
30+
repeat: Infinity,
31+
ease: 'linear',
32+
}}
33+
>
34+
{symbol}
35+
</motion.span>
36+
)
37+
}
38+
39+
// ─── COPY BUTTON ────────────────────────────────────────────────────────────────
40+
41+
function CopyInstallCommand() {
42+
const [copied, setCopied] = useState(false)
43+
const command = 'npm install -g @levelcode/cli'
44+
45+
const handleCopy = useCallback(async () => {
46+
try {
47+
await navigator.clipboard.writeText(command)
48+
setCopied(true)
49+
setTimeout(() => setCopied(false), 2000)
50+
} catch {
51+
// Fallback
52+
const textarea = document.createElement('textarea')
53+
textarea.value = command
54+
document.body.appendChild(textarea)
55+
textarea.select()
56+
document.execCommand('copy')
57+
document.body.removeChild(textarea)
58+
setCopied(true)
59+
setTimeout(() => setCopied(false), 2000)
60+
}
61+
}, [command])
62+
63+
return (
64+
<motion.button
65+
onClick={handleCopy}
66+
className="group flex items-center gap-3 px-5 py-3 rounded-lg bg-zinc-900/90 border border-zinc-800 hover:border-emerald-500/40 transition-all duration-300 cursor-pointer"
67+
whileHover={{ scale: 1.02 }}
68+
whileTap={{ scale: 0.98 }}
69+
>
70+
<span className="text-zinc-500 font-mono text-sm">$</span>
71+
<code className="text-emerald-400 font-mono text-sm sm:text-base">{command}</code>
72+
<span className="ml-2 text-zinc-500 group-hover:text-zinc-300 transition-colors">
73+
{copied ? (
74+
<svg className="w-4 h-4 text-emerald-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
75+
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" />
76+
</svg>
77+
) : (
78+
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
79+
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z" />
80+
</svg>
81+
)}
82+
</span>
83+
</motion.button>
84+
)
85+
}
86+
87+
// ─── ANIMATED STARS BADGE ───────────────────────────────────────────────────────
88+
89+
function GitHubStarsBadge() {
90+
return (
91+
<motion.a
92+
href="https://github.com/yethikrishna/levelcode"
93+
target="_blank"
94+
rel="noopener noreferrer"
95+
className="inline-flex items-center gap-2 px-3 py-1.5 rounded-full bg-zinc-900/80 border border-zinc-800 hover:border-zinc-700 transition-all text-xs font-mono text-zinc-400 hover:text-zinc-200"
96+
whileHover={{ scale: 1.05 }}
97+
>
98+
<svg className="w-3.5 h-3.5" fill="currentColor" viewBox="0 0 24 24">
99+
<path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z" />
100+
</svg>
101+
<span>Star on GitHub</span>
102+
<svg className="w-3.5 h-3.5 text-amber-400" fill="currentColor" viewBox="0 0 24 24">
103+
<path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z" />
104+
</svg>
105+
</motion.a>
106+
)
107+
}
108+
109+
// ─── MAIN COMPONENT ─────────────────────────────────────────────────────────────
110+
111+
export default function BrandHero() {
112+
return (
113+
<div className="relative w-full overflow-hidden py-16 sm:py-24">
114+
{/* Floating symbols background */}
115+
<div className="absolute inset-0 overflow-hidden">
116+
{SYMBOLS.map((sym, idx) => (
117+
<FloatingSymbol key={idx} symbol={sym} index={idx} />
118+
))}
119+
</div>
120+
121+
{/* Gradient backdrop */}
122+
<div className="absolute inset-0 bg-gradient-to-b from-transparent via-[#0c1018]/50 to-transparent pointer-events-none" />
123+
124+
<div className="relative z-10 flex flex-col items-center text-center px-4">
125+
{/* Badge */}
126+
<motion.div
127+
initial={{ opacity: 0, y: 15 }}
128+
animate={{ opacity: 1, y: 0 }}
129+
transition={{ duration: 0.5 }}
130+
className="mb-6"
131+
>
132+
<GitHubStarsBadge />
133+
</motion.div>
134+
135+
{/* Title with gradient */}
136+
<motion.h2
137+
initial={{ opacity: 0, y: 20 }}
138+
animate={{ opacity: 1, y: 0 }}
139+
transition={{ duration: 0.7, delay: 0.1 }}
140+
className="text-4xl sm:text-5xl md:text-6xl lg:text-7xl font-black tracking-tighter mb-4"
141+
>
142+
<span className="bg-gradient-to-r from-emerald-400 via-cyan-400 to-violet-400 bg-clip-text text-transparent">
143+
LEVELCODE
144+
</span>
145+
</motion.h2>
146+
147+
{/* Subtitle */}
148+
<motion.p
149+
initial={{ opacity: 0, y: 15 }}
150+
animate={{ opacity: 1, y: 0 }}
151+
transition={{ duration: 0.5, delay: 0.3 }}
152+
className="text-lg sm:text-xl text-zinc-400 max-w-lg mb-3"
153+
>
154+
The Open-Source AI Coding Agent
155+
</motion.p>
156+
157+
{/* Founder credit */}
158+
<motion.p
159+
initial={{ opacity: 0 }}
160+
animate={{ opacity: 1 }}
161+
transition={{ duration: 0.5, delay: 0.5 }}
162+
className="text-sm text-zinc-600 mb-8 font-mono"
163+
>
164+
Founded by{' '}
165+
<span className="text-zinc-400">Yethikrishna R</span>
166+
</motion.p>
167+
168+
{/* Install command with copy */}
169+
<motion.div
170+
initial={{ opacity: 0, y: 15 }}
171+
animate={{ opacity: 1, y: 0 }}
172+
transition={{ duration: 0.5, delay: 0.6 }}
173+
>
174+
<CopyInstallCommand />
175+
</motion.div>
176+
177+
{/* Subtext */}
178+
<motion.p
179+
initial={{ opacity: 0 }}
180+
animate={{ opacity: 1 }}
181+
transition={{ duration: 0.5, delay: 0.8 }}
182+
className="text-xs text-zinc-600 mt-4"
183+
>
184+
No account required · Apache 2.0 License · Works with 200+ models
185+
</motion.p>
186+
</div>
187+
</div>
188+
)
189+
}

0 commit comments

Comments
 (0)