diff --git a/components/design-scaffolds/marketing.tsx b/components/design-scaffolds/marketing.tsx index 121af61..3e12a4a 100644 --- a/components/design-scaffolds/marketing.tsx +++ b/components/design-scaffolds/marketing.tsx @@ -11,83 +11,499 @@ function fontStack(font?: string) { return "system-ui, sans-serif"; } -// CSS keyframes injected once per component render (scoped names prevent conflicts) +// Namespaced CSS keyframes (won't conflict with page styles) const ACE_KEYFRAMES = ` - @keyframes ace-blob1 { - 0%,100% { transform: translate(0%,0%) scale(1); } - 33% { transform: translate(28%,-22%) scale(1.12); } - 66% { transform: translate(-18%,18%) scale(0.9); } - } - @keyframes ace-blob2 { - 0%,100% { transform: translate(0%,0%) scale(1); } - 33% { transform: translate(-24%,14%) scale(0.95); } - 66% { transform: translate(20%,-24%) scale(1.08); } - } - @keyframes ace-blob3 { - 0%,100% { transform: translate(0%,0%) rotate(0deg); } - 50% { transform: translate(12%,-14%) rotate(180deg); } - } - @keyframes ace-blob4 { - 0%,100% { transform: translate(0%,0%) scale(1); } - 50% { transform: translate(-16%,20%) scale(1.1); } - } - @keyframes ace-meteor { - 0% { transform: translateX(0) translateY(0) rotate(-35deg); opacity: 1; } - 70% { opacity: 0.6; } - 100% { transform: translateX(160px) translateY(160px) rotate(-35deg); opacity: 0; } - } - @keyframes ace-sparkle { - 0%,100% { opacity:0; transform:scale(0.4); } - 40%,60% { opacity:1; transform:scale(1); } - } - @keyframes ace-cursor { - 0%,100% { opacity:1; } 50% { opacity:0; } - } - @keyframes ace-marquee { - 0% { transform: translateX(0); } - 100% { transform: translateX(-50%); } - } - @keyframes ace-beam-pulse { - 0%,100% { opacity:0.08; } 50% { opacity:0.22; } - } - @keyframes ace-lamp { - 0%,100% { opacity:0.6; transform:scaleX(1); } - 50% { opacity:1; transform:scaleX(1.15); } - } + @keyframes ace-blob1 { 0%,100%{transform:translate(0%,0%) scale(1)} 33%{transform:translate(28%,-22%) scale(1.12)} 66%{transform:translate(-18%,18%) scale(0.9)} } + @keyframes ace-blob2 { 0%,100%{transform:translate(0%,0%) scale(1)} 33%{transform:translate(-24%,14%) scale(0.95)} 66%{transform:translate(20%,-24%) scale(1.08)} } + @keyframes ace-blob3 { 0%,100%{transform:translate(0%,0%) rotate(0deg)} 50%{transform:translate(12%,-14%) rotate(180deg)} } + @keyframes ace-blob4 { 0%,100%{transform:translate(0%,0%) scale(1)} 50%{transform:translate(-16%,20%) scale(1.1)} } + @keyframes ace-meteor { 0%{transform:translateX(0) translateY(0) rotate(-35deg);opacity:1} 70%{opacity:0.6} 100%{transform:translateX(160px) translateY(160px) rotate(-35deg);opacity:0} } + @keyframes ace-sparkle { 0%,100%{opacity:0;transform:scale(0.4)} 40%,60%{opacity:1;transform:scale(1)} } + @keyframes ace-cursor { 0%,100%{opacity:1} 50%{opacity:0} } + @keyframes ace-marquee { 0%{transform:translateX(0)} 100%{transform:translateX(-50%)} } + @keyframes ace-beam-pulse { 0%,100%{opacity:0.06} 50%{opacity:0.2} } + @keyframes ace-lamp { 0%,100%{opacity:0.6;transform:scaleX(1)} 50%{opacity:1;transform:scaleX(1.2)} } + @keyframes ace-float { 0%,100%{transform:translateY(0)} 50%{transform:translateY(-6px)} } + @keyframes ace-float2 { 0%,100%{transform:translateY(0) rotate(-4deg)} 50%{transform:translateY(-8px) rotate(-4deg)} } + @keyframes ace-float3 { 0%,100%{transform:translateY(0) rotate(3deg)} 50%{transform:translateY(-5px) rotate(3deg)} } `; // --------------------------------------------------------------------------- -// Aceternity UI +// Shared: product dashboard mockup // --------------------------------------------------------------------------- +function DashMockup({ + bg, card, border, text, muted, accent, +}: { + bg: string; card: string; border: string; text: string; muted: string; accent: string; +}) { + const uid = accent.replace(/[^a-z0-9]/gi, "").slice(0, 6) || "acc"; + return ( +
+ {/* Browser chrome */} +
+ {["#ff5f56","#ffbd2e","#27c93f"].map((c, i) => ( +
+ ))} +
+
+ +
+ {/* Sidebar */} +
+
+ {[ + "M4 6h16M4 12h16M4 18h10", + "M3 3h7v7H3zM14 3h7v7h-7zM3 14h7v7H3zM14 14h7v7h-7z", + "M12 2a10 10 0 100 20A10 10 0 0012 2z", + "M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z", + ].map((d, i) => ( +
+ + + +
+ ))} +
+ + {/* Main area */} +
+ {/* Header row */} +
+

Analytics

+
+ + New report +
+
+ + {/* KPI cards */} +
+ {[ + { l: "MRR", v: "$24.8k", d: "+18%", up: true }, + { l: "Users", v: "12.4k", d: "+8%", up: true }, + { l: "Churn", v: "1.2%", d: "-0.4%",up: false }, + ].map(m => ( +
+

{m.l}

+

{m.v}

+

{m.d}

+
+ ))} +
+ + {/* Chart */} +
+
+

Revenue trend

+
+ {["7d","30d","90d"].map((l, i) => ( + {l} + ))} +
+
+ + + + + + + + + + +
+
+
+
+ ); +} + +// Minimal SVG icon — inline path, no emoji +function Ico({ d, color, size = 15, fill = false }: { d: string; color: string; size?: number; fill?: boolean }) { + return ( + + + + ); +} + +const ICO = { + bolt: "M13 2L4.09 13h7.41L10 22l9.91-11H12.5L13 2z", + shield: "M12 2L4 5v6c0 5.25 3.5 9.74 8 11 4.5-1.26 8-5.75 8-11V5l-8-3z", + trend: "M22 7l-8.5 8.5-4.5-4.5L2 18M16 7h6v6", + globe: "M12 2a10 10 0 100 20A10 10 0 0012 2zM2 12h20M12 2c-3 4-4.5 7-4.5 10S9 18 12 22M12 2c3 4 4.5 7 4.5 10S15 18 12 22", + code: "M8 3L3 12l5 9M16 3l5 9-5 9M14.5 3.5l-4 17", + layers: "M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5", + clock: "M12 2a10 10 0 100 20A10 10 0 0012 2zM12 6v6l4 2", + target: "M12 2a10 10 0 100 20A10 10 0 0012 2zM12 7a5 5 0 100 10A5 5 0 0012 7zM12 11a1 1 0 100 2A1 1 0 0012 11z", + cpu: "M9 3H5a2 2 0 00-2 2v4m6-6h10a2 2 0 012 2v4M9 3v18m0 0h10a2 2 0 002-2V9M9 21H5a2 2 0 01-2-2V9m0 0h18", + zap: "M4 14a1 1 0 01-.78-1.63l9.9-10.2a.5.5 0 01.86.46l-1.92 6.02A1 1 0 0013 10h7a1 1 0 01.78 1.63l-9.9 10.2a.5.5 0 01-.86-.46l1.92-6.02A1 1 0 0011 14z", + users: "M17 21v-2a4 4 0 00-4-4H5a4 4 0 00-4 4v2M9 11a4 4 0 100-8 4 4 0 000 8zM23 21v-2a4 4 0 00-3-3.87M16 3.13a4 4 0 010 7.75", + sparkle: "M9.937 15.5A2 2 0 008.5 14.063l-6.135-1.582a.5.5 0 010-.962L8.5 9.936A2 2 0 009.937 8.5l1.582-6.135a.5.5 0 01.963 0L14.063 8.5A2 2 0 0015.5 9.937l6.135 1.581a.5.5 0 010 .964L15.5 14.063a2 2 0 00-1.437 1.437l-1.582 6.135a.5.5 0 01-.963 0z", +}; + +// --------------------------------------------------------------------------- +// DaisyUI — premium SaaS landing page +// --------------------------------------------------------------------------- + +export function MarketingDaisy({ themeColor, config }: { themeColor?: ThemeColor; config?: DesignConfig }) { + const theme = themeColor ?? DAISY_THEMES[0]; + const isDark = config ? config.mode === "dark" : ((theme.bg ?? "#fff").match(/^#[012]/i) !== null); + + const bg = isDark ? (theme.bg ?? "#1d232a") : (theme.bg?.match(/^#[012]/) ? "#fff" : (theme.bg ?? "#fff")); + const text = isDark ? (theme.textColor ?? "#f4f5f6") : (theme.textColor ?? "#09090b"); + const muted = isDark ? (theme.mutedText ?? "rgba(255,255,255,0.42)") : (theme.mutedText ?? "#6b7280"); + const card = isDark ? (theme.cardBg ?? "#191e24") : (theme.cardBg ?? "#ffffff"); + const border = isDark ? (theme.borderColor ?? "rgba(255,255,255,0.09)") : (theme.borderColor ?? "#e5e7eb"); + const p = theme.primary; + const pFg = theme.primaryFg; + + const bgStyle = config?.background ?? "solid"; + const navStyle = config?.nav ?? "standard"; + const hdrStyle = config?.header ?? "centered"; + const comps = config?.components ?? ["features","pricing"]; + const ff = fontStack(config?.font); + + const heroBg = + bgStyle === "gradient" ? `radial-gradient(ellipse 75% 50% at 50% -5%, ${p}40, transparent 65%)` : + bgStyle === "pattern" ? undefined : undefined; + + return ( +
+ {bgStyle === "pattern" && ( +
+ )} + + {/* Nav */} + {navStyle === "pill" ? ( +
+ +
+ ) : ( + + )} + + {/* Hero */} + {hdrStyle === "centered" && ( +
+ {heroBg &&
} +
+ ✦ {theme.label} theme — v2.0 just shipped +
+

+ Build faster,
ship smarter. +

+

+ The all-in-one platform that helps teams build, launch, and scale production apps with confidence. +

+
+ + +
+
+ +
+
+ )} + + {hdrStyle === "split" && ( +
+ {heroBg &&
} +
+
✦ {theme.label}
+

+ Build faster,
ship smarter. +

+

+ The platform teams trust to ship faster and sleep better. +

+
+ + +
+
+ {[["50k+","Teams"],["99.9%","Uptime"],["$0","To start"]].map(([v,l]) => ( +
+

{v}

+

{l}

+
+ ))} +
+
+
+ +
+
+ )} + + {hdrStyle === "stats" && ( +
+ {heroBg &&
} +

Build faster,
ship smarter.

+

The platform that helps teams ship with confidence.

+
+ + +
+
+ {[["50k+","Teams"],["99.9%","Uptime"],["10ms","Latency"],["$0","To start"]].map(([v,l]) => ( +
+

{v}

+

{l}

+
+ ))} +
+ +
+ )} + + {/* Sections */} + {comps.includes("logos") && ( +
+ Trusted by + {["Vercel","Stripe","Linear","Notion","Supabase","Raycast"].map(b => ( + {b} + ))} +
+ )} + + {comps.includes("features") && ( +
+
+

Features

+

Everything you need
to ship faster

+
+
+ {[ + { icon: "bolt", title: "10× faster deploys", desc: "Push to production in under 30 seconds. Zero config required.", key: "bolt" }, + { icon: "shield", title: "Enterprise security", desc: "SOC 2 compliant with end-to-end encryption and audit logs.", key: "shld" }, + { icon: "trend", title: "Real-time analytics", desc: "Track every metric that matters. Live dashboards, zero lag.", key: "trnd" }, + { icon: "globe", title: "Global edge network", desc: "300+ PoPs worldwide. Your users get sub-10ms response times.", key: "glb" }, + { icon: "layers", title: "Any stack, any scale", desc: "Node, Python, Go, Rust — deploy whatever your team builds.", key: "lyr" }, + { icon: "clock", title: "99.99% uptime SLA", desc: "We guarantee it. And we back that up with automatic credits.", key: "clk" }, + ].map(f => ( +
+
+ +
+

{f.title}

+

{f.desc}

+
+ ))} +
+
+ )} + + {comps.includes("steps") && ( +
+

Up and running in 3 steps

+
+ {[ + { n: "01", title: "Connect your repo", desc: "Push to GitHub and we handle the rest." }, + { n: "02", title: "Configure your stack", desc: "Env vars, domains, and scaling — all in one place." }, + { n: "03", title: "Ship to production", desc: "One click. Zero downtime deploys, every time." }, + ].map(s => ( +
+

{s.n}

+

{s.title}

+

{s.desc}

+
+ ))} +
+
+ )} + + {comps.includes("testimonials") && ( +
+

Loved by engineering teams

+
+ {[ + { q: "\"We cut our deploy time from 20 minutes to 45 seconds. Game changer.\"", name: "Sarah K.", role: "CTO at Linear", stars: 5 }, + { q: "\"Reduced infrastructure costs by 40% in our first month. Incredible ROI.\"", name: "James R.", role: "Eng Lead at Stripe", stars: 5 }, + { q: "\"The DX is in a league of its own. Every edge case is handled perfectly.\"", name: "Mia Chen", role: "Staff Eng at Vercel", stars: 5 }, + { q: "\"Finally, a platform that just works. Zero incidents in 8 months.\"", name: "Tom W.", role: "Founder at Raycast", stars: 5 }, + ].map(t => ( +
+
+ {Array(t.stars).fill(0).map((_, i) => )} +
+

{t.q}

+
+
+ {t.name[0]} +
+
+

{t.name}

+

{t.role}

+
+
+
+ ))} +
+
+ )} + + {comps.includes("pricing") && ( +
+
+

Simple, transparent pricing

+

No surprises. No hidden fees. Cancel anytime.

+
+
+ {[ + { plan: "Starter", price: "Free", period: "forever", hi: false, features: ["5 projects","100 deploys/mo","Community support","Basic analytics"] }, + { plan: "Pro", price: "$29", period: "/month", hi: true, features: ["Unlimited projects","Unlimited deploys","Priority support","Advanced analytics","Custom domains","Team members"] }, + { plan: "Enterprise", price: "Custom", period: "contact us", hi: false, features: ["Everything in Pro","SLA guarantee","SSO / SAML","Dedicated support","Audit logs"] }, + ].map(pl => ( +
+

{pl.plan}

+

{pl.price}

+

{pl.period}

+
+ {pl.features.map(f => ( +
+
+ + + +
+ {f} +
+ ))} +
+ +
+ ))} +
+
+ )} + + {comps.includes("faq") && ( +
+

Frequently asked

+ {[ + ["What's included in the free plan?","5 projects, 100 deploys per month, community forum access, and basic analytics."], + ["Can I upgrade or downgrade anytime?","Yes. Changes take effect immediately. We prorate billing automatically."], + ["Do you offer team billing?","Yes. Add team members to your workspace and manage billing centrally."], + ].map(([q, a], i) => ( +
+
+

{q}

+ {i === 0 ? "−" : "+"} +
+ {i === 0 &&

{a}

} +
+ ))} +
+ )} + + {comps.includes("cta") && ( +
+

Ready to ship faster?

+

Join 50,000+ teams already building on Acme. Free forever.

+ +
+ )} + +
+
+ ); +} + +// --------------------------------------------------------------------------- +// Aceternity UI — atmospheric, animated +// --------------------------------------------------------------------------- + +const ACE_BG_BASE = "#050010"; +const ACE_BG_LIGHT = "#fafafa"; + export function MarketingAceternity({ themeColor, config }: { themeColor?: ThemeColor; config?: DesignConfig }) { - const accent = themeColor ?? ACETERNITY_THEMES[0]; - const p = accent.primary; - const p2 = accent.ring.replace("0.4)", "1)").replace("rgba(", "rgb("); // second accent - const isDark = config?.mode !== "light"; - const bgStyle = config?.background ?? "beams"; - const navStyle = config?.nav ?? "minimal"; - const hdrStyle = config?.header ?? "gradient-text"; - const comps = config?.components ?? ["features", "moving-cards"]; - const ff = fontStack(config?.font); + const accent = themeColor ?? ACETERNITY_THEMES[0]; + const p = accent.primary; + const bgStyle = config?.background ?? "gradient"; + const isDark = bgStyle !== "aurora" && bgStyle !== "shader" && (config?.mode !== "light"); + const navStyle = config?.nav ?? "minimal"; + const hdrStyle = config?.header ?? "gradient-text"; + const comps = config?.components ?? ["features","moving-cards"]; + const ff = fontStack(config?.font); - // sparkles forces black; aurora forces light; shader always dark-text-over-vibrant - const forcedDark = bgStyle === "sparkles" || bgStyle === "shader"; + // Force correct bg/text per effect + const forcedBlack = bgStyle === "sparkles"; const forcedLight = bgStyle === "aurora"; - const effectiveDark = forcedDark ? true : forcedLight ? false : isDark; + const forceShader = bgStyle === "shader"; - const bg = forcedDark ? "#000" : forcedLight ? "#f8f9ff" : isDark ? "#050010" : "#fafafa"; - const text = effectiveDark ? "#fff" : "#0f172a"; - const muted = effectiveDark ? "rgba(255,255,255,0.38)" : "#64748b"; - const card = effectiveDark ? "rgba(255,255,255,0.035)" : "rgba(0,0,0,0.03)"; - const border= effectiveDark ? "rgba(255,255,255,0.07)" : "rgba(0,0,0,0.08)"; + const bg = forcedBlack ? "#000" : forcedLight ? "#f8f9ff" : forceShader ? "#06010e" : isDark ? ACE_BG_BASE : ACE_BG_LIGHT; + const text = (forcedLight) ? "#1e1b4b" : "#fff"; + const muted = forcedLight ? "#6b7280" : "rgba(255,255,255,0.42)"; + const card = forcedLight ? "rgba(0,0,0,0.04)" : "rgba(255,255,255,0.04)"; + const border= forcedLight ? "rgba(0,0,0,0.09)" : "rgba(255,255,255,0.08)"; - // ── Background layers ────────────────────────────────────────────────────── const BgLayer = () => { - // Animated gradient blobs — mirrors Aceternity's Background Gradient Animation if (bgStyle === "gradient") return ( -
-
+
+
@@ -95,77 +511,65 @@ export function MarketingAceternity({ themeColor, config }: { themeColor?: Theme
); - - // Lines Gradient Shader — bold diagonal rainbow band: purple→pink→orange→yellow if (bgStyle === "shader") return ( -
- {/* Diagonal gradient band */} -
- {/* Subtle line overlay */} -
- {/* Soft vignette */} -
+
+
+
+
); - - // Background Beams — SVG-style radial beams on dark bg if (bgStyle === "beams") return (
- + - + - - {Array.from({ length: 12 }).map((_, i) => { - const x = 200 + (i - 6) * 34; + + {Array.from({ length: 14 }).map((_, i) => { + const x = 200 + (i - 7) * 32; return ( - ); })}
); - - // Meteors — diagonal shooting-star streaks with glow tails if (bgStyle === "meteors") return (
-
+
{Array.from({ length: 12 }).map((_, i) => (
))}
); - - // Sparkles — true black bg with small twinkling star particles if (bgStyle === "sparkles") return (
- {Array.from({ length: 40 }).map((_, i) => { - const size = i % 6 === 0 ? 3 : i % 3 === 0 ? 2 : 1.5; + {Array.from({ length: 45 }).map((_, i) => { + const sz = i % 6 === 0 ? 3 : i % 3 === 0 ? 2 : 1.5; return (
); - - // Aurora — soft lavender/blue glow on a LIGHT background (matches Aceternity's Aurora) if (bgStyle === "aurora") return ( -
-
-
-
+
+
+
+
); - if (bgStyle === "wavy") return (
- + - - +
); if (bgStyle === "dot-grid") return ( -
+
); return
; }; - const floatingNav = navStyle === "floating"; - return (
{/* Nav */} - {floatingNav ? ( -
-