ebade 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +5 -0
- package/README.md +30 -30
- package/ROADMAP.md +17 -12
- package/cli/scaffold.js +315 -183
- package/cli/simulate.js +102 -0
- package/cli/templates/feature-grid.tsx +80 -0
- package/cli/templates/footer.tsx +121 -0
- package/cli/templates/hero-section.tsx +34 -0
- package/cli/templates/login-form.tsx +124 -0
- package/cli/templates/navbar.tsx +53 -0
- package/cli/templates/pricing-table.tsx +140 -0
- package/cli/templates/signup-form.tsx +111 -0
- package/demo.tape +2 -2
- package/examples/saas-dashboard.ebade.yaml +2 -0
- package/netlify.toml +7 -0
- package/package.json +1 -1
- package/packages/mcp-server/README.md +3 -3
- package/packages/mcp-server/package.json +2 -2
- package/packages/mcp-server/src/index.ts +12 -16
- package/packages/mcp-server/src/tools/scaffold.ts +153 -404
- package/packages/vscode-extension/README.md +11 -8
- package/packages/vscode-extension/ebade-0.3.0.vsix +0 -0
- package/packages/vscode-extension/ebade-0.3.1.vsix +0 -0
- package/packages/vscode-extension/ebade-0.3.2.vsix +0 -0
- package/packages/vscode-extension/images/icon.png +0 -0
- package/packages/vscode-extension/package.json +2 -1
- package/packages/vscode-extension/snippets/ebade.json +86 -0
- package/www/README.md +36 -0
- package/www/app/favicon.ico +0 -0
- package/{landing/style.css → www/app/globals.css} +390 -19
- package/www/app/layout.tsx +66 -0
- package/www/app/page.tsx +374 -0
- package/www/app/playground/page.tsx +627 -0
- package/www/components/ThreeCanvas.tsx +156 -0
- package/www/next.config.ts +19 -0
- package/www/package-lock.json +1779 -0
- package/www/package.json +27 -0
- package/www/postcss.config.mjs +7 -0
- package/www/public/logo.png +0 -0
- package/www/tsconfig.json +42 -0
- package/landing/index.html +0 -268
- package/landing/main.js +0 -147
- package/packages/vscode-extension/images/icon.svg +0 -6
- /package/{demo.gif → assets/demo.gif} +0 -0
- /package/{demo.mp4 → assets/demo.mp4} +0 -0
- /package/{landing → www/public}/_headers +0 -0
- /package/{landing → www/public}/favicon.svg +0 -0
- /package/{landing → www/public}/og-image.png +0 -0
- /package/{landing → www/public}/og-readme.png +0 -0
package/cli/simulate.js
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import chalk from "chalk";
|
|
4
|
+
import ora from "ora";
|
|
5
|
+
|
|
6
|
+
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
7
|
+
|
|
8
|
+
async function simulate() {
|
|
9
|
+
console.clear();
|
|
10
|
+
console.log(
|
|
11
|
+
chalk.bold.cyan("\n--- ebade Playground: Total Agent-First Flow ---")
|
|
12
|
+
);
|
|
13
|
+
console.log(
|
|
14
|
+
chalk.gray("Testing User Prompt: 'Make a premium SaaS landing page'\n")
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
// --- PHASE 0: The Intent Mapping (The Start) ---
|
|
18
|
+
const spinnerMapping = ora(
|
|
19
|
+
chalk.yellow("AI Agent is mapping Natural Language to ebade Intent...")
|
|
20
|
+
).start();
|
|
21
|
+
await sleep(1500);
|
|
22
|
+
|
|
23
|
+
const yamlOutput = `
|
|
24
|
+
pages:
|
|
25
|
+
- path: "/"
|
|
26
|
+
components:
|
|
27
|
+
- navbar
|
|
28
|
+
- hero-section
|
|
29
|
+
- pricing-table
|
|
30
|
+
- footer
|
|
31
|
+
`;
|
|
32
|
+
spinnerMapping.succeed(
|
|
33
|
+
chalk.yellow(
|
|
34
|
+
"Agent-First View: Intent mapped to 4 components in project.ebade.yaml"
|
|
35
|
+
)
|
|
36
|
+
);
|
|
37
|
+
console.log(chalk.gray("Generated Intent (YAML):") + chalk.white(yamlOutput));
|
|
38
|
+
|
|
39
|
+
await sleep(1000);
|
|
40
|
+
|
|
41
|
+
// --- PHASE 1: Legacy AI (The Token Burner) ---
|
|
42
|
+
console.log(chalk.red("\n[Legacy AI Path]"));
|
|
43
|
+
const spinnerAI = ora(
|
|
44
|
+
chalk.red("Generating 5000+ lines of raw React/CSS/Logic...")
|
|
45
|
+
).start();
|
|
46
|
+
|
|
47
|
+
// Simulate slow character-by-character generation (like a real LLM)
|
|
48
|
+
for (let i = 0; i < 40; i++) {
|
|
49
|
+
await sleep(30);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
spinnerAI.fail(
|
|
53
|
+
chalk.red(
|
|
54
|
+
"Legacy AI: Burned 4200 Tokens, 15 seconds wait, High risk of CSS bugs."
|
|
55
|
+
)
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
await sleep(1000);
|
|
59
|
+
|
|
60
|
+
// --- PHASE 2: ebade (The Agent-First Engine) ---
|
|
61
|
+
console.log(chalk.cyan("\n[ebade Agent-First Path]"));
|
|
62
|
+
const spinnerEbade = ora(
|
|
63
|
+
chalk.cyan("CLI is expanding intents into Shadcn code...")
|
|
64
|
+
).start();
|
|
65
|
+
|
|
66
|
+
const startTime = performance.now();
|
|
67
|
+
// Simulate reading all 4 components
|
|
68
|
+
const components = ["navbar", "hero-section", "pricing-table", "footer"];
|
|
69
|
+
let totalLines = 0;
|
|
70
|
+
components.forEach((c) => {
|
|
71
|
+
const p = path.join(process.cwd(), "cli/templates", `${c}.tsx`);
|
|
72
|
+
if (fs.existsSync(p))
|
|
73
|
+
totalLines += fs.readFileSync(p, "utf-8").split("\n").length;
|
|
74
|
+
});
|
|
75
|
+
const endTime = performance.now();
|
|
76
|
+
|
|
77
|
+
await sleep(800);
|
|
78
|
+
spinnerEbade.succeed(
|
|
79
|
+
chalk.cyan(
|
|
80
|
+
`ebade: Generated ${totalLines} lines of PR-Ready code in ${(
|
|
81
|
+
endTime - startTime
|
|
82
|
+
).toFixed(2)}ms!`
|
|
83
|
+
)
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
// --- PHASE 3: The Scorecard ---
|
|
87
|
+
console.log(chalk.bold.yellow("\n--- GREEN AI LIFECYCLE SCORECARD ---"));
|
|
88
|
+
console.log(
|
|
89
|
+
chalk.white("🧠 AI Thinking: ") + chalk.green("98% Less (YAML vs Code)")
|
|
90
|
+
);
|
|
91
|
+
console.log(
|
|
92
|
+
chalk.white("⚡ App Creation: ") + chalk.green("Instant (Deterministic)")
|
|
93
|
+
);
|
|
94
|
+
console.log(
|
|
95
|
+
chalk.white("🌿 Total Carbon: ") + chalk.green("Minimal (Native Speed)")
|
|
96
|
+
);
|
|
97
|
+
console.log(
|
|
98
|
+
chalk.gray("--------------------------------------------------\n")
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
simulate();
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { cn } from "@/lib/utils";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* 🧠 Generated via ebade
|
|
6
|
+
* Intent: feature-grid
|
|
7
|
+
*/
|
|
8
|
+
export function FeatureGrid() {
|
|
9
|
+
const features = [
|
|
10
|
+
{
|
|
11
|
+
title: "Agent-First Architecture",
|
|
12
|
+
description:
|
|
13
|
+
"Designed from the ground up for AI agents to understand and modify code effectively.",
|
|
14
|
+
icon: "🤖",
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
title: "Intent-Based Scaffolding",
|
|
18
|
+
description:
|
|
19
|
+
"Define what you want, not how to implement it. Let ebade handle the boilerplate.",
|
|
20
|
+
icon: "🎯",
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
title: "Production Ready",
|
|
24
|
+
description:
|
|
25
|
+
"Generates optimized, secure, and type-safe code that you can deploy immediately.",
|
|
26
|
+
icon: "🚀",
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
title: "Shadcn UI Standard",
|
|
30
|
+
description:
|
|
31
|
+
"Beautiful, accessible components built on Radix UI and Tailwind CSS.",
|
|
32
|
+
icon: "✨",
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
title: "Zero Token Waste",
|
|
36
|
+
description:
|
|
37
|
+
"Deterministic output saves 70% of tokens compared to raw LLM generation.",
|
|
38
|
+
icon: "💎",
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
title: "Framework Agnostic",
|
|
42
|
+
description:
|
|
43
|
+
"Supports Next.js today, with plans for Vue, Svelte, and Mobile targets.",
|
|
44
|
+
icon: "🌐",
|
|
45
|
+
},
|
|
46
|
+
];
|
|
47
|
+
|
|
48
|
+
return (
|
|
49
|
+
<section className="py-24 px-6 bg-muted/30">
|
|
50
|
+
<div className="max-w-7xl mx-auto">
|
|
51
|
+
<div className="text-center mb-16">
|
|
52
|
+
<h2 className="text-3xl md:text-5xl font-black tracking-tight mb-4">
|
|
53
|
+
Why choose <span className="text-primary">ebade</span>?
|
|
54
|
+
</h2>
|
|
55
|
+
<p className="text-lg text-muted-foreground max-w-2xl mx-auto">
|
|
56
|
+
The framework that adapts to the AI era. Build better software,
|
|
57
|
+
faster.
|
|
58
|
+
</p>
|
|
59
|
+
</div>
|
|
60
|
+
|
|
61
|
+
<div className="grid md:grid-cols-2 lg:grid-cols-3 gap-8">
|
|
62
|
+
{features.map((feature, idx) => (
|
|
63
|
+
<div
|
|
64
|
+
key={idx}
|
|
65
|
+
className="group p-8 rounded-2xl bg-card border border-border hover:border-primary/50 transition-all hover:shadow-lg hover:-translate-y-1"
|
|
66
|
+
>
|
|
67
|
+
<div className="w-12 h-12 rounded-xl bg-primary/10 flex items-center justify-center text-2xl mb-6 group-hover:scale-110 transition-transform">
|
|
68
|
+
{feature.icon}
|
|
69
|
+
</div>
|
|
70
|
+
<h3 className="text-xl font-bold mb-3">{feature.title}</h3>
|
|
71
|
+
<p className="text-muted-foreground leading-relaxed">
|
|
72
|
+
{feature.description}
|
|
73
|
+
</p>
|
|
74
|
+
</div>
|
|
75
|
+
))}
|
|
76
|
+
</div>
|
|
77
|
+
</div>
|
|
78
|
+
</section>
|
|
79
|
+
);
|
|
80
|
+
}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { cn } from "@/lib/utils";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* 🧠 Generated via ebade
|
|
6
|
+
* Intent: footer
|
|
7
|
+
*/
|
|
8
|
+
export function Footer() {
|
|
9
|
+
const currentYear = new Date().getFullYear();
|
|
10
|
+
|
|
11
|
+
return (
|
|
12
|
+
<footer className="border-t border-border bg-background pt-16 pb-8 px-6">
|
|
13
|
+
<div className="max-w-7xl mx-auto">
|
|
14
|
+
<div className="grid grid-cols-2 md:grid-cols-4 lg:grid-cols-5 gap-8 mb-12">
|
|
15
|
+
<div className="col-span-2 lg:col-span-2 pr-8">
|
|
16
|
+
<div className="flex items-center gap-2 mb-6">
|
|
17
|
+
<div className="w-8 h-8 bg-primary rounded-lg flex items-center justify-center font-bold text-primary-foreground">
|
|
18
|
+
e
|
|
19
|
+
</div>
|
|
20
|
+
<span className="text-xl font-bold tracking-tight">ebade</span>
|
|
21
|
+
</div>
|
|
22
|
+
<p className="text-muted-foreground mb-6 max-w-sm">
|
|
23
|
+
The first Agent-First framework. Empowering AI and humans to build
|
|
24
|
+
software together, faster and more reliably than ever before.
|
|
25
|
+
</p>
|
|
26
|
+
<div className="flex gap-4">
|
|
27
|
+
{/* Social Icons Placeholder */}
|
|
28
|
+
{[1, 2, 3, 4].map((i) => (
|
|
29
|
+
<div
|
|
30
|
+
key={i}
|
|
31
|
+
className="w-8 h-8 rounded-full bg-muted hover:bg-primary/20 transition-colors cursor-pointer"
|
|
32
|
+
/>
|
|
33
|
+
))}
|
|
34
|
+
</div>
|
|
35
|
+
</div>
|
|
36
|
+
|
|
37
|
+
<div>
|
|
38
|
+
<h4 className="font-bold mb-4">Product</h4>
|
|
39
|
+
<ul className="space-y-3 text-sm text-muted-foreground">
|
|
40
|
+
<li>
|
|
41
|
+
<a href="#" className="hover:text-primary transition-colors">
|
|
42
|
+
Features
|
|
43
|
+
</a>
|
|
44
|
+
</li>
|
|
45
|
+
<li>
|
|
46
|
+
<a href="#" className="hover:text-primary transition-colors">
|
|
47
|
+
Documentation
|
|
48
|
+
</a>
|
|
49
|
+
</li>
|
|
50
|
+
<li>
|
|
51
|
+
<a href="#" className="hover:text-primary transition-colors">
|
|
52
|
+
Templates
|
|
53
|
+
</a>
|
|
54
|
+
</li>
|
|
55
|
+
<li>
|
|
56
|
+
<a href="#" className="hover:text-primary transition-colors">
|
|
57
|
+
Pricing
|
|
58
|
+
</a>
|
|
59
|
+
</li>
|
|
60
|
+
</ul>
|
|
61
|
+
</div>
|
|
62
|
+
|
|
63
|
+
<div>
|
|
64
|
+
<h4 className="font-bold mb-4">Company</h4>
|
|
65
|
+
<ul className="space-y-3 text-sm text-muted-foreground">
|
|
66
|
+
<li>
|
|
67
|
+
<a href="#" className="hover:text-primary transition-colors">
|
|
68
|
+
About
|
|
69
|
+
</a>
|
|
70
|
+
</li>
|
|
71
|
+
<li>
|
|
72
|
+
<a href="#" className="hover:text-primary transition-colors">
|
|
73
|
+
Blog
|
|
74
|
+
</a>
|
|
75
|
+
</li>
|
|
76
|
+
<li>
|
|
77
|
+
<a href="#" className="hover:text-primary transition-colors">
|
|
78
|
+
Careers
|
|
79
|
+
</a>
|
|
80
|
+
</li>
|
|
81
|
+
<li>
|
|
82
|
+
<a href="#" className="hover:text-primary transition-colors">
|
|
83
|
+
Contact
|
|
84
|
+
</a>
|
|
85
|
+
</li>
|
|
86
|
+
</ul>
|
|
87
|
+
</div>
|
|
88
|
+
|
|
89
|
+
<div>
|
|
90
|
+
<h4 className="font-bold mb-4">Legal</h4>
|
|
91
|
+
<ul className="space-y-3 text-sm text-muted-foreground">
|
|
92
|
+
<li>
|
|
93
|
+
<a href="#" className="hover:text-primary transition-colors">
|
|
94
|
+
Privacy
|
|
95
|
+
</a>
|
|
96
|
+
</li>
|
|
97
|
+
<li>
|
|
98
|
+
<a href="#" className="hover:text-primary transition-colors">
|
|
99
|
+
Terms
|
|
100
|
+
</a>
|
|
101
|
+
</li>
|
|
102
|
+
<li>
|
|
103
|
+
<a href="#" className="hover:text-primary transition-colors">
|
|
104
|
+
Cookie Policy
|
|
105
|
+
</a>
|
|
106
|
+
</li>
|
|
107
|
+
</ul>
|
|
108
|
+
</div>
|
|
109
|
+
</div>
|
|
110
|
+
|
|
111
|
+
<div className="pt-8 border-t border-border flex flex-col md:flex-row justify-between items-center gap-4 text-sm text-muted-foreground">
|
|
112
|
+
<p>© {currentYear} ebade framework. All rights reserved.</p>
|
|
113
|
+
<div className="flex items-center gap-2">
|
|
114
|
+
<span className="w-2 h-2 rounded-full bg-green-500 animate-pulse"></span>
|
|
115
|
+
<span>All systems operational</span>
|
|
116
|
+
</div>
|
|
117
|
+
</div>
|
|
118
|
+
</div>
|
|
119
|
+
</footer>
|
|
120
|
+
);
|
|
121
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { cn } from "@/lib/utils";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* 🧠 Generated via ebade
|
|
6
|
+
* Intent: hero-section
|
|
7
|
+
*/
|
|
8
|
+
export function HeroSection() {
|
|
9
|
+
return (
|
|
10
|
+
<section className="relative py-24 px-6 md:px-10 overflow-hidden bg-background">
|
|
11
|
+
<div className="max-w-7xl mx-auto text-center relative z-10">
|
|
12
|
+
<h1 className="text-5xl md:text-8xl font-black tracking-tighter mb-8 leading-[0.9]">
|
|
13
|
+
NEXT ERA OF <br />
|
|
14
|
+
<span className="text-primary italic">BUILDING.</span>
|
|
15
|
+
</h1>
|
|
16
|
+
<p className="text-xl text-muted-foreground max-w-2xl mx-auto mb-12 font-medium tracking-tight">
|
|
17
|
+
Agent-First development is here. Build production-ready apps with
|
|
18
|
+
intent-based architecture and Shadcn aesthetics.
|
|
19
|
+
</p>
|
|
20
|
+
<div className="flex flex-col sm:flex-row justify-center gap-4">
|
|
21
|
+
<button className="h-14 px-10 rounded-full font-bold bg-primary text-primary-foreground transition-all hover:scale-105 hover:shadow-[0_0_20px_rgba(var(--primary),0.3)] shadow-xl active:scale-95">
|
|
22
|
+
Start Building
|
|
23
|
+
</button>
|
|
24
|
+
<button className="h-14 px-10 rounded-full font-bold bg-secondary text-secondary-foreground transition-all hover:bg-secondary/80 border border-border">
|
|
25
|
+
View Manifesto
|
|
26
|
+
</button>
|
|
27
|
+
</div>
|
|
28
|
+
</div>
|
|
29
|
+
{/* Background Decor */}
|
|
30
|
+
<div className="absolute top-0 left-0 w-full h-full opacity-20 pointer-events-none bg-[radial-gradient(circle_at_50%_50%,var(--primary)_0%,transparent_50%)]" />
|
|
31
|
+
<div className="absolute -top-24 -left-24 w-96 h-96 bg-primary/10 rounded-full blur-3xl pointer-events-none" />
|
|
32
|
+
</section>
|
|
33
|
+
);
|
|
34
|
+
}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { cn } from "@/lib/utils";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* 🧠 Generated via ebade
|
|
6
|
+
* Intent: login-form
|
|
7
|
+
*/
|
|
8
|
+
export function LoginForm() {
|
|
9
|
+
return (
|
|
10
|
+
<div className="w-full max-w-md mx-auto p-8">
|
|
11
|
+
<div className="mb-8 text-center">
|
|
12
|
+
<h2 className="text-3xl font-black tracking-tight mb-2">
|
|
13
|
+
Welcome back
|
|
14
|
+
</h2>
|
|
15
|
+
<p className="text-muted-foreground">
|
|
16
|
+
Enter your credentials to continue
|
|
17
|
+
</p>
|
|
18
|
+
</div>
|
|
19
|
+
|
|
20
|
+
<form className="space-y-6">
|
|
21
|
+
<div className="space-y-2">
|
|
22
|
+
<label htmlFor="email" className="text-sm font-medium">
|
|
23
|
+
Email
|
|
24
|
+
</label>
|
|
25
|
+
<input
|
|
26
|
+
id="email"
|
|
27
|
+
type="email"
|
|
28
|
+
placeholder="you@example.com"
|
|
29
|
+
className="w-full px-4 py-3 rounded-lg border border-input bg-background focus:outline-none focus:ring-2 focus:ring-ring focus:border-transparent transition-all"
|
|
30
|
+
/>
|
|
31
|
+
</div>
|
|
32
|
+
|
|
33
|
+
<div className="space-y-2">
|
|
34
|
+
<div className="flex items-center justify-between">
|
|
35
|
+
<label htmlFor="password" className="text-sm font-medium">
|
|
36
|
+
Password
|
|
37
|
+
</label>
|
|
38
|
+
<a href="#" className="text-xs text-primary hover:underline">
|
|
39
|
+
Forgot password?
|
|
40
|
+
</a>
|
|
41
|
+
</div>
|
|
42
|
+
<input
|
|
43
|
+
id="password"
|
|
44
|
+
type="password"
|
|
45
|
+
placeholder="••••••••"
|
|
46
|
+
className="w-full px-4 py-3 rounded-lg border border-input bg-background focus:outline-none focus:ring-2 focus:ring-ring focus:border-transparent transition-all"
|
|
47
|
+
/>
|
|
48
|
+
</div>
|
|
49
|
+
|
|
50
|
+
<div className="flex items-center gap-2">
|
|
51
|
+
<input
|
|
52
|
+
id="remember"
|
|
53
|
+
type="checkbox"
|
|
54
|
+
className="w-4 h-4 rounded border-input text-primary focus:ring-2 focus:ring-ring"
|
|
55
|
+
/>
|
|
56
|
+
<label htmlFor="remember" className="text-sm text-muted-foreground">
|
|
57
|
+
Remember me for 30 days
|
|
58
|
+
</label>
|
|
59
|
+
</div>
|
|
60
|
+
|
|
61
|
+
<button
|
|
62
|
+
type="submit"
|
|
63
|
+
className="w-full py-3 px-6 rounded-lg bg-primary text-primary-foreground font-bold hover:opacity-90 transition-all shadow-lg"
|
|
64
|
+
>
|
|
65
|
+
Sign in
|
|
66
|
+
</button>
|
|
67
|
+
|
|
68
|
+
<div className="relative my-6">
|
|
69
|
+
<div className="absolute inset-0 flex items-center">
|
|
70
|
+
<div className="w-full border-t border-border"></div>
|
|
71
|
+
</div>
|
|
72
|
+
<div className="relative flex justify-center text-xs uppercase">
|
|
73
|
+
<span className="bg-background px-2 text-muted-foreground">
|
|
74
|
+
Or continue with
|
|
75
|
+
</span>
|
|
76
|
+
</div>
|
|
77
|
+
</div>
|
|
78
|
+
|
|
79
|
+
<div className="grid grid-cols-2 gap-4">
|
|
80
|
+
<button
|
|
81
|
+
type="button"
|
|
82
|
+
className="py-3 px-4 rounded-lg border border-border bg-background hover:bg-accent transition-all flex items-center justify-center gap-2 font-medium"
|
|
83
|
+
>
|
|
84
|
+
<svg className="w-5 h-5" viewBox="0 0 24 24">
|
|
85
|
+
<path
|
|
86
|
+
fill="currentColor"
|
|
87
|
+
d="M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z"
|
|
88
|
+
/>
|
|
89
|
+
<path
|
|
90
|
+
fill="currentColor"
|
|
91
|
+
d="M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z"
|
|
92
|
+
/>
|
|
93
|
+
<path
|
|
94
|
+
fill="currentColor"
|
|
95
|
+
d="M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z"
|
|
96
|
+
/>
|
|
97
|
+
<path
|
|
98
|
+
fill="currentColor"
|
|
99
|
+
d="M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z"
|
|
100
|
+
/>
|
|
101
|
+
</svg>
|
|
102
|
+
Google
|
|
103
|
+
</button>
|
|
104
|
+
<button
|
|
105
|
+
type="button"
|
|
106
|
+
className="py-3 px-4 rounded-lg border border-border bg-background hover:bg-accent transition-all flex items-center justify-center gap-2 font-medium"
|
|
107
|
+
>
|
|
108
|
+
<svg className="w-5 h-5" fill="currentColor" viewBox="0 0 24 24">
|
|
109
|
+
<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" />
|
|
110
|
+
</svg>
|
|
111
|
+
GitHub
|
|
112
|
+
</button>
|
|
113
|
+
</div>
|
|
114
|
+
|
|
115
|
+
<p className="text-center text-sm text-muted-foreground">
|
|
116
|
+
Don't have an account?{" "}
|
|
117
|
+
<a href="#" className="text-primary font-medium hover:underline">
|
|
118
|
+
Sign up
|
|
119
|
+
</a>
|
|
120
|
+
</p>
|
|
121
|
+
</form>
|
|
122
|
+
</div>
|
|
123
|
+
);
|
|
124
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { cn } from "@/lib/utils";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* 🧠 Generated via ebade
|
|
6
|
+
* Intent: navbar
|
|
7
|
+
*/
|
|
8
|
+
export function Navbar() {
|
|
9
|
+
const links = [
|
|
10
|
+
{ label: "Essence", href: "#essence" },
|
|
11
|
+
{ label: "Flow", href: "#flow" },
|
|
12
|
+
{ label: "Pricing", href: "#pricing" },
|
|
13
|
+
{ label: "Github", href: "https://github.com/hasankemaldemirci/ebade" },
|
|
14
|
+
];
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
<nav className="fixed top-0 left-0 right-0 z-50 transition-all border-b border-white/5 backdrop-blur-md bg-background/50">
|
|
18
|
+
<div className="max-w-7xl mx-auto px-6">
|
|
19
|
+
<div className="flex items-center justify-between h-20">
|
|
20
|
+
<div className="flex items-center gap-3">
|
|
21
|
+
<div className="w-10 h-10 bg-primary rounded-xl flex items-center justify-center font-black text-primary-foreground transform rotate-3">
|
|
22
|
+
e
|
|
23
|
+
</div>
|
|
24
|
+
<span className="text-xl font-black tracking-tighter uppercase italic">
|
|
25
|
+
ebade
|
|
26
|
+
</span>
|
|
27
|
+
</div>
|
|
28
|
+
|
|
29
|
+
<div className="hidden md:flex items-center gap-10">
|
|
30
|
+
{links.map((link) => (
|
|
31
|
+
<a
|
|
32
|
+
key={link.label}
|
|
33
|
+
href={link.href}
|
|
34
|
+
className="text-[13px] uppercase font-bold tracking-widest text-muted-foreground hover:text-primary transition-colors"
|
|
35
|
+
>
|
|
36
|
+
{link.label}
|
|
37
|
+
</a>
|
|
38
|
+
))}
|
|
39
|
+
</div>
|
|
40
|
+
|
|
41
|
+
<div className="flex items-center gap-6">
|
|
42
|
+
<button className="text-xs font-bold uppercase tracking-widest opacity-50 hover:opacity-100 transition-opacity">
|
|
43
|
+
Login
|
|
44
|
+
</button>
|
|
45
|
+
<button className="h-10 px-6 rounded-lg bg-primary text-primary-foreground text-xs font-bold uppercase tracking-widest hover:opacity-90 transition-all shadow-lg active:scale-95">
|
|
46
|
+
Launch App
|
|
47
|
+
</button>
|
|
48
|
+
</div>
|
|
49
|
+
</div>
|
|
50
|
+
</div>
|
|
51
|
+
</nav>
|
|
52
|
+
);
|
|
53
|
+
}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { cn } from "@/lib/utils";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* 🧠 Generated via ebade
|
|
6
|
+
* Intent: pricing-table
|
|
7
|
+
*/
|
|
8
|
+
export function PricingTable() {
|
|
9
|
+
const plans = [
|
|
10
|
+
{
|
|
11
|
+
name: "Starter",
|
|
12
|
+
price: "$0",
|
|
13
|
+
period: "forever",
|
|
14
|
+
description: "Perfect for trying out ebade",
|
|
15
|
+
features: [
|
|
16
|
+
"Up to 3 projects",
|
|
17
|
+
"Basic components",
|
|
18
|
+
"Community support",
|
|
19
|
+
"Public templates",
|
|
20
|
+
],
|
|
21
|
+
cta: "Start Free",
|
|
22
|
+
popular: false,
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
name: "Pro",
|
|
26
|
+
price: "$29",
|
|
27
|
+
period: "per month",
|
|
28
|
+
description: "For serious builders",
|
|
29
|
+
features: [
|
|
30
|
+
"Unlimited projects",
|
|
31
|
+
"Premium components",
|
|
32
|
+
"Priority support",
|
|
33
|
+
"Private templates",
|
|
34
|
+
"Advanced analytics",
|
|
35
|
+
"Custom domains",
|
|
36
|
+
],
|
|
37
|
+
cta: "Go Pro",
|
|
38
|
+
popular: true,
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
name: "Enterprise",
|
|
42
|
+
price: "Custom",
|
|
43
|
+
period: "contact us",
|
|
44
|
+
description: "For teams and organizations",
|
|
45
|
+
features: [
|
|
46
|
+
"Everything in Pro",
|
|
47
|
+
"Dedicated support",
|
|
48
|
+
"SLA guarantee",
|
|
49
|
+
"Custom integrations",
|
|
50
|
+
"Team collaboration",
|
|
51
|
+
"Advanced security",
|
|
52
|
+
],
|
|
53
|
+
cta: "Contact Sales",
|
|
54
|
+
popular: false,
|
|
55
|
+
},
|
|
56
|
+
];
|
|
57
|
+
|
|
58
|
+
return (
|
|
59
|
+
<div className="py-20 px-6">
|
|
60
|
+
<div className="max-w-7xl mx-auto">
|
|
61
|
+
<div className="text-center mb-16">
|
|
62
|
+
<h2 className="text-4xl md:text-6xl font-black tracking-tight mb-4">
|
|
63
|
+
Simple, <span className="text-primary">transparent</span> pricing
|
|
64
|
+
</h2>
|
|
65
|
+
<p className="text-lg text-muted-foreground max-w-2xl mx-auto">
|
|
66
|
+
Choose the plan that fits your needs. All plans include core
|
|
67
|
+
features.
|
|
68
|
+
</p>
|
|
69
|
+
</div>
|
|
70
|
+
|
|
71
|
+
<div className="grid md:grid-cols-3 gap-8 max-w-6xl mx-auto">
|
|
72
|
+
{plans.map((plan, idx) => (
|
|
73
|
+
<div
|
|
74
|
+
key={idx}
|
|
75
|
+
className={cn(
|
|
76
|
+
"relative p-8 rounded-2xl border transition-all hover:shadow-xl",
|
|
77
|
+
plan.popular
|
|
78
|
+
? "border-primary bg-primary/5 shadow-lg scale-105"
|
|
79
|
+
: "border-border bg-card"
|
|
80
|
+
)}
|
|
81
|
+
>
|
|
82
|
+
{plan.popular && (
|
|
83
|
+
<div className="absolute -top-4 left-1/2 -translate-x-1/2 px-4 py-1 bg-primary text-primary-foreground text-xs font-bold rounded-full uppercase tracking-wider">
|
|
84
|
+
Most Popular
|
|
85
|
+
</div>
|
|
86
|
+
)}
|
|
87
|
+
|
|
88
|
+
<div className="mb-6">
|
|
89
|
+
<h3 className="text-2xl font-bold mb-2">{plan.name}</h3>
|
|
90
|
+
<p className="text-sm text-muted-foreground mb-4">
|
|
91
|
+
{plan.description}
|
|
92
|
+
</p>
|
|
93
|
+
<div className="flex items-baseline gap-2">
|
|
94
|
+
<span className="text-5xl font-black tracking-tight">
|
|
95
|
+
{plan.price}
|
|
96
|
+
</span>
|
|
97
|
+
<span className="text-muted-foreground text-sm">
|
|
98
|
+
/ {plan.period}
|
|
99
|
+
</span>
|
|
100
|
+
</div>
|
|
101
|
+
</div>
|
|
102
|
+
|
|
103
|
+
<ul className="space-y-3 mb-8">
|
|
104
|
+
{plan.features.map((feature, i) => (
|
|
105
|
+
<li key={i} className="flex items-start gap-3 text-sm">
|
|
106
|
+
<svg
|
|
107
|
+
className="w-5 h-5 text-primary flex-shrink-0 mt-0.5"
|
|
108
|
+
fill="none"
|
|
109
|
+
viewBox="0 0 24 24"
|
|
110
|
+
stroke="currentColor"
|
|
111
|
+
>
|
|
112
|
+
<path
|
|
113
|
+
strokeLinecap="round"
|
|
114
|
+
strokeLinejoin="round"
|
|
115
|
+
strokeWidth={2}
|
|
116
|
+
d="M5 13l4 4L19 7"
|
|
117
|
+
/>
|
|
118
|
+
</svg>
|
|
119
|
+
<span>{feature}</span>
|
|
120
|
+
</li>
|
|
121
|
+
))}
|
|
122
|
+
</ul>
|
|
123
|
+
|
|
124
|
+
<button
|
|
125
|
+
className={cn(
|
|
126
|
+
"w-full py-3 px-6 rounded-lg font-bold transition-all",
|
|
127
|
+
plan.popular
|
|
128
|
+
? "bg-primary text-primary-foreground hover:opacity-90 shadow-lg"
|
|
129
|
+
: "bg-secondary text-secondary-foreground hover:bg-secondary/80"
|
|
130
|
+
)}
|
|
131
|
+
>
|
|
132
|
+
{plan.cta}
|
|
133
|
+
</button>
|
|
134
|
+
</div>
|
|
135
|
+
))}
|
|
136
|
+
</div>
|
|
137
|
+
</div>
|
|
138
|
+
</div>
|
|
139
|
+
);
|
|
140
|
+
}
|