VIBN Frontend for Coolify deployment

This commit is contained in:
2026-02-15 19:25:52 -08:00
commit 40bf8428cd
398 changed files with 76513 additions and 0 deletions

70
marketing/README.md Normal file
View File

@@ -0,0 +1,70 @@
# 📢 Marketing Directory
This directory contains all marketing-specific code for the VIBN landing pages and promotional content.
## 📁 Structure
```
marketing/
├── components/ # Marketing-specific React components
│ ├── hero.tsx # Hero section with main CTA
│ ├── features.tsx # Features grid with cards
│ ├── cta.tsx # Call-to-action sections
│ └── index.ts # Component exports
├── content/ # Marketing copy and content
│ └── homepage.ts # Homepage content/copy
└── styles/ # Marketing-specific styles (future)
```
## 🎯 Purpose
This directory keeps marketing code separate from application code, making it easier to:
- Update messaging and copy
- Redesign marketing pages without affecting the app
- Collaborate with designers/copywriters
- Maintain consistent branding
## 🔗 Usage
Marketing components are used in the `app/(marketing)/` routes:
```tsx
import { Hero, Features, CTA } from "@/marketing/components";
export default function Page() {
return (
<>
<Hero />
<Features />
<CTA />
</>
);
}
```
## 📝 Content Management
All marketing copy is centralized in `content/homepage.ts` for easy updates:
```typescript
import { homepage } from "@/marketing/content/homepage";
// Use in components
<h1>{homepage.hero.title}</h1>
```
## 🚀 Adding New Sections
1. Create component in `components/`
2. Add content to `content/homepage.ts`
3. Export from `components/index.ts`
4. Use in `app/(marketing)/page.tsx`
## 📖 Design Guidelines
Follow the guidelines in `/PROJECT_INSTRUCTIONS.md` for:
- Voice & tone
- Design principles
- SEO requirements
- Accessibility standards

View File

@@ -0,0 +1,33 @@
import { Button } from "@/components/ui/button";
import { Sparkles, Calendar } from "lucide-react";
import Link from "next/link";
import { homepage } from "@/marketing/content/homepage";
export function CTA() {
return (
<section className="w-full py-16 md:py-24">
<div className="container mx-auto px-6">
<div className="mx-auto flex max-w-[980px] flex-col items-center gap-6 rounded-2xl border bg-gradient-to-br from-blue-50 to-purple-50 dark:from-blue-950/20 dark:to-purple-950/20 p-12 md:p-16">
<h2 className="text-2xl font-bold leading-tight tracking-tight md:text-4xl lg:text-5xl text-center max-w-[800px]">
{homepage.finalCTA.title}
</h2>
<div className="flex flex-col sm:flex-row gap-4 pt-4">
<Link href="/auth">
<Button size="lg" className="h-12 px-8 text-base">
<Sparkles className="mr-2 h-5 w-5" />
{homepage.finalCTA.cta.primary}
</Button>
</Link>
<Link href="https://calendly.com/your-link" target="_blank" rel="noopener noreferrer">
<Button variant="outline" size="lg" className="h-12 px-8 text-base">
<Calendar className="mr-2 h-5 w-5" />
{homepage.finalCTA.cta.secondary}
</Button>
</Link>
</div>
</div>
</div>
</section>
);
}

View File

@@ -0,0 +1,22 @@
import { homepage } from "@/marketing/content/homepage";
export function EmotionalHook() {
return (
<section className="w-full py-16 md:py-24">
<div className="container mx-auto px-6">
<div className="mx-auto max-w-[800px] text-center space-y-4">
<h2 className="text-3xl font-bold tracking-tight md:text-5xl">
{homepage.emotionalHook.title}
</h2>
<p className="text-4xl font-bold tracking-tight md:text-6xl bg-gradient-to-r from-blue-600 to-purple-600 bg-clip-text text-transparent">
{homepage.emotionalHook.subtitle}
</p>
<p className="text-lg text-muted-foreground md:text-xl pt-4 leading-relaxed">
{homepage.emotionalHook.description}
</p>
</div>
</div>
</section>
);
}

View File

@@ -0,0 +1,32 @@
import { Card, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { homepage } from "@/marketing/content/homepage";
export function Features() {
return (
<section id="features" className="w-full py-16 md:py-24">
<div className="container mx-auto px-6">
<div className="mx-auto flex max-w-[980px] flex-col items-center gap-4 mb-12">
<h2 className="text-3xl font-bold leading-tight tracking-tighter md:text-5xl text-center">
{homepage.features.title}
</h2>
<p className="max-w-[750px] text-center text-lg text-muted-foreground md:text-xl">
{homepage.features.description}
</p>
</div>
<div className="mx-auto grid max-w-6xl grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3">
{homepage.features.list.map((feature, index) => (
<Card key={index} className="transition-all hover:border-primary/50">
<CardHeader>
<CardTitle className="text-lg">{feature.title}</CardTitle>
<CardDescription className="text-base leading-relaxed">
{feature.description}
</CardDescription>
</CardHeader>
</Card>
))}
</div>
</div>
</section>
);
}

View File

@@ -0,0 +1,43 @@
import { Button } from "@/components/ui/button";
import Link from "next/link";
import { Sparkles, ArrowRight } from "lucide-react";
import { homepage } from "@/marketing/content/homepage";
export function Hero() {
return (
<section className="w-full">
<div className="container mx-auto px-6">
<div className="flex flex-col items-center gap-6 pb-16 pt-16 md:py-24 lg:py-32">
<div className="flex max-w-[980px] flex-col items-center gap-6 text-center">
{/* Main title */}
<h1 className="text-3xl font-extrabold leading-tight tracking-tighter md:text-5xl lg:text-6xl lg:leading-[1.1]">
{homepage.hero.title}
</h1>
{/* Subtitle */}
<p className="max-w-[750px] text-lg text-muted-foreground sm:text-xl md:text-2xl">
{homepage.hero.subtitle}
</p>
{/* CTAs */}
<div className="flex flex-col sm:flex-row gap-4 mt-4">
<Link href="/auth">
<Button size="lg" className="h-12 px-8 text-base">
<Sparkles className="mr-2 h-5 w-5" />
{homepage.hero.cta.primary}
</Button>
</Link>
<Link href="#how-it-works">
<Button variant="outline" size="lg" className="h-12 px-8 text-base">
{homepage.hero.cta.secondary}
<ArrowRight className="ml-2 h-5 w-5" />
</Button>
</Link>
</div>
</div>
</div>
</div>
</section>
);
}

View File

@@ -0,0 +1,39 @@
import { homepage } from "@/marketing/content/homepage";
export function HowItWorks() {
return (
<section id="how-it-works" className="w-full py-16 md:py-24">
<div className="container mx-auto px-6">
<div className="mx-auto max-w-[900px] space-y-12">
<div className="text-center space-y-4">
<h2 className="text-3xl font-bold tracking-tight md:text-5xl">
{homepage.howItWorks.title}
</h2>
<p className="text-lg text-muted-foreground md:text-xl">
{homepage.howItWorks.description}
</p>
</div>
<div className="space-y-8 pt-8">
{homepage.howItWorks.steps.map((step) => (
<div key={step.number} className="flex gap-6">
<div className="flex-shrink-0">
<div className="flex h-12 w-12 items-center justify-center rounded-full bg-gradient-to-br from-blue-600 to-purple-600 text-white font-bold text-xl">
{step.number}
</div>
</div>
<div className="space-y-2 pt-1">
<h3 className="text-2xl font-bold">{step.title}</h3>
<p className="text-lg text-muted-foreground leading-relaxed">
{step.description}
</p>
</div>
</div>
))}
</div>
</div>
</div>
</section>
);
}

View File

@@ -0,0 +1,14 @@
/**
* Marketing Components
* All marketing-specific components for the landing page
*/
export { Hero } from "./hero";
export { EmotionalHook } from "./emotional-hook";
export { WhoItsFor } from "./who-its-for";
export { Transformation } from "./transformation";
export { Features } from "./features";
export { HowItWorks } from "./how-it-works";
export { Pricing } from "./pricing";
export { CTA } from "./cta";

View File

@@ -0,0 +1,69 @@
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { Check } from "lucide-react";
import Link from "next/link";
import { homepage } from "@/marketing/content/homepage";
export function Pricing() {
return (
<section id="pricing" className="w-full py-16 md:py-24">
<div className="container mx-auto px-6">
<div className="mx-auto max-w-[980px] space-y-12">
<div className="text-center space-y-4">
<h2 className="text-3xl font-bold tracking-tight md:text-5xl">
{homepage.pricing.title}
</h2>
<p className="text-lg text-muted-foreground md:text-xl">
{homepage.pricing.description}
</p>
</div>
<div className="grid gap-8 md:grid-cols-3 pt-8">
{homepage.pricing.tiers.map((tier) => (
<Card
key={tier.name}
className={`flex flex-col ${
tier.highlighted
? "border-primary shadow-lg scale-105"
: ""
}`}
>
<CardHeader>
<CardTitle className="text-2xl">{tier.name}</CardTitle>
<CardDescription className="text-base">
{tier.description}
</CardDescription>
<div className="pt-4">
<span className="text-4xl font-bold">{tier.price}</span>
{tier.price !== "Free" && (
<span className="text-muted-foreground">/month</span>
)}
</div>
</CardHeader>
<CardContent className="flex-1 space-y-4">
<ul className="space-y-3">
{tier.features.map((feature, index) => (
<li key={index} className="flex items-start gap-3">
<Check className="h-5 w-5 text-primary mt-0.5 flex-shrink-0" />
<span className="text-sm">{feature}</span>
</li>
))}
</ul>
<Link href="/auth" className="block pt-4">
<Button
className="w-full"
variant={tier.highlighted ? "default" : "outline"}
>
{tier.price === "Free" ? "Start Free" : "Get Started"}
</Button>
</Link>
</CardContent>
</Card>
))}
</div>
</div>
</div>
</section>
);
}

View File

@@ -0,0 +1,36 @@
import { Sparkles } from "lucide-react";
import { homepage } from "@/marketing/content/homepage";
export function Transformation() {
return (
<section className="w-full py-16 md:py-24 bg-muted/30">
<div className="container mx-auto px-6">
<div className="mx-auto max-w-[900px] space-y-12">
<div className="text-center space-y-4">
<h2 className="text-3xl font-bold tracking-tight md:text-5xl">
{homepage.transformation.title}
</h2>
<p className="text-lg text-muted-foreground md:text-xl pt-4 leading-relaxed">
{homepage.transformation.description}
</p>
</div>
<div className="grid gap-6 md:grid-cols-2 pt-8">
{homepage.transformation.outcomes.map((outcome, index) => (
<div
key={index}
className="flex items-start gap-4 rounded-lg border bg-background p-6 shadow-sm"
>
<div className="rounded-full bg-gradient-to-br from-blue-500 to-purple-600 p-2 mt-1">
<Sparkles className="h-5 w-5 text-white" />
</div>
<p className="text-lg leading-relaxed font-medium">{outcome}</p>
</div>
))}
</div>
</div>
</div>
</section>
);
}

View File

@@ -0,0 +1,39 @@
import { Check } from "lucide-react";
import { homepage } from "@/marketing/content/homepage";
export function WhoItsFor() {
return (
<section id="who-its-for" className="w-full py-16 md:py-24">
<div className="container mx-auto px-6">
<div className="mx-auto max-w-[900px] space-y-12">
<div className="text-center space-y-4">
<h2 className="text-3xl font-bold tracking-tight md:text-5xl">
{homepage.whoItsFor.title}
</h2>
<p className="text-2xl font-semibold text-muted-foreground md:text-3xl">
{homepage.whoItsFor.subtitle}
</p>
<p className="text-lg text-muted-foreground md:text-xl pt-4 leading-relaxed">
{homepage.whoItsFor.description}
</p>
</div>
<div className="grid gap-4 pt-8">
{homepage.whoItsFor.traits.map((trait, index) => (
<div
key={index}
className="flex items-start gap-4 rounded-lg border bg-card p-6 transition-all hover:border-primary/50"
>
<div className="rounded-full bg-primary/10 p-2 mt-1">
<Check className="h-5 w-5 text-primary" />
</div>
<p className="text-lg leading-relaxed">{trait}</p>
</div>
))}
</div>
</div>
</div>
</section>
);
}

View File

@@ -0,0 +1,205 @@
/**
* Marketing content for the homepage
* Centralized location for all copy to make updates easier
*/
export const homepage = {
hero: {
title: "AI Coding Tools for Vibe Coders.",
subtitle: "We take you from idea to market and beyond — so you can finally finish what you start and share it with the world.",
cta: {
primary: "Start Your Idea",
secondary: "See How It Works",
},
},
emotionalHook: {
title: "You've been waiting",
subtitle: "Now you can",
description: "You've had the ideas. You've started the projects. But somewhere between no-code limitations and overwhelming dev tools, momentum stalls. Not anymore.",
},
whoItsFor: {
title: "Creators stuck between ideas and code",
subtitle: "You're a Vibe Coder",
description: "You're ambitious. You have vision. You know what you want to build. But you're not fluent in code yet, and no-code tools feel limiting. You're stuck in the gap — and we built Vibn to meet you there.",
traits: [
"You have big ideas but hit walls with no-code tools",
"You want to learn to code, but need to ship while you learn",
"You're tired of starting projects that never launch",
"You need guidance, not just more tutorials",
"You want to build real products, not just prototypes",
],
},
transformation: {
title: "From stalled chaos to unstoppable momentum",
description: "When you join Vibn, something shifts. The overwhelm fades. The path becomes clear. You're not just learning — you're building. You're not just building — you're shipping. And you're not alone.",
outcomes: [
"Clarity on what to build next",
"Confidence in your technical decisions",
"Momentum that carries you forward",
"A product you're proud to share",
],
},
features: {
title: "Everything you need in one calm, guided flow",
description: "Vibn gives you structure without rigidity, guidance without hand-holding, and momentum without overwhelm.",
list: [
{
title: "Project Home",
description: "One central place for your vision, progress, and next steps.",
},
{
title: "Scope & Roadmap",
description: "Define what you're building and break it into achievable milestones.",
},
{
title: "AI Guardrails",
description: "Keep AI coding assistants on track with your project's scope and standards.",
},
{
title: "Build, Don't Babysit",
description: "Track your coding sessions, costs, and progress automatically.",
},
{
title: "Backend & Hosting Simplified",
description: "Deploy with confidence. No DevOps degree required.",
},
{
title: "v0 Integration",
description: "Generate beautiful UI components and iterate visually.",
},
{
title: "Collaboration & Chat",
description: "Get unstuck with AI and human support that understands your project.",
},
{
title: "Launch Suite",
description: "Go from localhost to production with guided deployment.",
},
{
title: "Market & Grow",
description: "Tools to help you share your product and find your first users.",
},
{
title: "Progress & Cost Tracking",
description: "Stay on budget. Stay motivated. See how far you've come.",
},
],
},
howItWorks: {
title: "Plan. Build. Launch. Grow",
description: "Vibn guides you from idea to market, one clear step at a time.",
steps: [
{
number: 1,
title: "Start with your idea",
description: "Tell us what you want to build. We'll help you define scope and create a roadmap that feels achievable.",
},
{
number: 2,
title: "Build with AI assistance",
description: "Use Cursor, ChatGPT, and other AI tools — but with guardrails that keep you on track and on budget.",
},
{
number: 3,
title: "Launch with confidence",
description: "Deploy your product with guided setup for hosting, domains, and everything you need to go live.",
},
{
number: 4,
title: "Grow your product",
description: "Market your launch, gather feedback, and iterate with the same support that got you here.",
},
],
},
pricing: {
title: "Simple, fair, transparent",
description: "Pay for what you use. No surprises. No hidden fees.",
tiers: [
{
name: "Starter",
price: "Free",
description: "For exploring and getting started",
features: [
"1 active project",
"Basic AI tracking",
"Community support",
"7-day history",
],
},
{
name: "Creator",
price: "$29/mo",
description: "For builders shipping real products",
features: [
"5 active projects",
"Full AI tracking & analytics",
"Priority support",
"Unlimited history",
"Deployment guides",
"v0 integration",
],
highlighted: true,
},
{
name: "Studio",
price: "$99/mo",
description: "For teams and agencies",
features: [
"Unlimited projects",
"Team collaboration",
"White-label options",
"Custom integrations",
"Dedicated support",
"SLA guarantee",
],
},
],
},
finalCTA: {
title: "Start your idea — we'll meet you where you are and help you finish what you start.",
cta: {
primary: "Get Started Free",
secondary: "Book a Demo",
},
},
meta: {
title: "VIBN - From Ideas to Market for Vibe Coders",
description: "AI coding tools aren't made for you. We are. Take your product from idea to market with guidance, structure, and momentum.",
},
};
/**
* Future content sections (from PROJECT_INSTRUCTIONS.md)
* TODO: Implement these sections
*/
export const futureContent = {
emotionalHook: {
title: "You've been waiting. Now you can.",
// Short, empathetic copy about frustration and transition
},
whoItsFor: {
title: "Creators stuck between ideas and code",
// Describes Vibe Coders: ambitious, not yet fluent in code
},
transformation: {
title: "From stalled chaos to unstoppable momentum",
// Emotional shift when users join VIBN
},
howItWorks: {
title: "Plan. Build. Launch. Grow.",
// Step-based explanation
},
pricing: {
title: "Simple, fair, transparent",
// Pricing tiers
},
};