ebade 0.3.0 → 0.4.1

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.
Files changed (52) hide show
  1. package/ARCHITECTURE.md +109 -0
  2. package/CHANGELOG.md +8 -1
  3. package/README.md +64 -202
  4. package/ROADMAP.md +17 -12
  5. package/cli/scaffold.js +465 -192
  6. package/cli/simulate.js +102 -0
  7. package/cli/templates/feature-grid.tsx +80 -0
  8. package/cli/templates/footer.tsx +121 -0
  9. package/cli/templates/hero-section.tsx +34 -0
  10. package/cli/templates/login-form.tsx +124 -0
  11. package/cli/templates/navbar.tsx +53 -0
  12. package/cli/templates/pricing-table.tsx +140 -0
  13. package/cli/templates/signup-form.tsx +111 -0
  14. package/demo.tape +2 -2
  15. package/examples/saas-dashboard.ebade.yaml +2 -0
  16. package/netlify.toml +7 -0
  17. package/package.json +1 -1
  18. package/packages/mcp-server/README.md +3 -3
  19. package/packages/mcp-server/package.json +2 -2
  20. package/packages/mcp-server/src/index.ts +12 -16
  21. package/packages/mcp-server/src/tools/scaffold.ts +153 -404
  22. package/packages/vscode-extension/README.md +11 -8
  23. package/packages/vscode-extension/ebade-0.3.0.vsix +0 -0
  24. package/packages/vscode-extension/ebade-0.3.1.vsix +0 -0
  25. package/packages/vscode-extension/ebade-0.3.2.vsix +0 -0
  26. package/packages/vscode-extension/images/icon.png +0 -0
  27. package/packages/vscode-extension/package.json +2 -1
  28. package/packages/vscode-extension/snippets/ebade.json +86 -0
  29. package/www/README.md +36 -0
  30. package/www/app/favicon.ico +0 -0
  31. package/{landing/style.css → www/app/globals.css} +691 -57
  32. package/www/app/layout.tsx +66 -0
  33. package/www/app/page.tsx +406 -0
  34. package/www/app/playground/page.tsx +610 -0
  35. package/www/components/Navbar.tsx +67 -0
  36. package/www/components/ThreeCanvas.tsx +156 -0
  37. package/www/next.config.ts +19 -0
  38. package/www/package-lock.json +1779 -0
  39. package/www/package.json +27 -0
  40. package/www/postcss.config.mjs +7 -0
  41. package/www/public/assets/demo.mp4 +0 -0
  42. package/www/public/logo.png +0 -0
  43. package/www/tsconfig.json +42 -0
  44. package/landing/index.html +0 -268
  45. package/landing/main.js +0 -147
  46. package/packages/vscode-extension/images/icon.svg +0 -6
  47. /package/{demo.gif → assets/demo.gif} +0 -0
  48. /package/{demo.mp4 → assets/demo.mp4} +0 -0
  49. /package/{landing → www/public}/_headers +0 -0
  50. /package/{landing → www/public}/favicon.svg +0 -0
  51. /package/{landing → www/public}/og-image.png +0 -0
  52. /package/{landing → www/public}/og-readme.png +0 -0
@@ -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
+ }