- beams: replaced SVG gradient <rect fill='url(#bm-glow)'> with a CSS radial-gradient div — browser SVG gradient reference fallback is solid black which produced the dark rectangle. Also adapt line colors and opacity for light mode. - meteors: switch tail gradient from white-tip to dark-tip in light mode so meteors are visible on a light background. - wavy: remove SVG linearGradient id references (same black-fill risk); use inline hex alpha on fill instead. Made-with: Cursor
1301 lines
89 KiB
TypeScript
1301 lines
89 KiB
TypeScript
"use client";
|
||
|
||
import { ThemeColor, DesignConfig, DAISY_THEMES, HEROUI_MARKETING_THEMES, ACETERNITY_THEMES } from "./types";
|
||
|
||
function fontStack(font?: string) {
|
||
if (font === "plus-jakarta") return '"Plus Jakarta Sans", system-ui, sans-serif';
|
||
if (font === "dm-sans") return '"DM Sans", system-ui, sans-serif';
|
||
if (font === "geist") return '"Geist Sans", system-ui, sans-serif';
|
||
if (font === "inter") return '"Inter", system-ui, sans-serif';
|
||
if (font === "nunito") return '"Nunito", system-ui, sans-serif';
|
||
return "system-ui, sans-serif";
|
||
}
|
||
|
||
function fontImport(font?: string): string {
|
||
if (font === "plus-jakarta") return "@import url('https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800;900&display=swap');";
|
||
if (font === "dm-sans") return "@import url('https://fonts.googleapis.com/css2?family=DM+Sans:ital,opsz,wght@0,9..40,400;0,9..40,500;0,9..40,600;0,9..40,700;0,9..40,800;0,9..40,900;1,9..40,400&display=swap');";
|
||
if (font === "geist") return "@import url('https://fonts.googleapis.com/css2?family=Geist:wght@400;500;600;700;800;900&display=swap');";
|
||
if (font === "inter") return "@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800;900&display=swap');";
|
||
if (font === "nunito") return "@import url('https://fonts.googleapis.com/css2?family=Nunito:wght@400;500;600;700;800;900&display=swap');";
|
||
return "";
|
||
}
|
||
|
||
// 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.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)} }
|
||
`;
|
||
|
||
// ---------------------------------------------------------------------------
|
||
// 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 (
|
||
<div style={{
|
||
borderRadius: 16, overflow: "hidden",
|
||
border: `1px solid ${border}`,
|
||
boxShadow: "0 48px 120px rgba(0,0,0,0.25), 0 12px 36px rgba(0,0,0,0.12)",
|
||
background: card, userSelect: "none",
|
||
}}>
|
||
{/* Browser chrome */}
|
||
<div style={{
|
||
height: 40, display: "flex", alignItems: "center", gap: 7,
|
||
padding: "0 16px", background: bg, borderBottom: `1px solid ${border}`, flexShrink: 0,
|
||
}}>
|
||
{["#ff5f56","#ffbd2e","#27c93f"].map((c, i) => (
|
||
<div key={i} style={{ width: 10, height: 10, borderRadius: "50%", background: c }} />
|
||
))}
|
||
<div style={{ marginLeft: 12, height: 18, width: 220, borderRadius: 6, background: border, opacity: 0.55 }} />
|
||
</div>
|
||
|
||
<div style={{ display: "flex", height: 340 }}>
|
||
{/* Sidebar */}
|
||
<div style={{
|
||
width: 64, background: bg, borderRight: `1px solid ${border}`,
|
||
padding: "16px 10px", display: "flex", flexDirection: "column", gap: 6, flexShrink: 0,
|
||
}}>
|
||
<div style={{ width: 34, height: 34, borderRadius: 9, background: accent, marginBottom: 10 }} />
|
||
{[
|
||
"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) => (
|
||
<div key={i} style={{
|
||
width: 40, height: 40, borderRadius: 9, display: "flex", alignItems: "center", justifyContent: "center",
|
||
background: i === 0 ? `${accent}18` : "transparent",
|
||
}}>
|
||
<svg viewBox="0 0 24 24" fill="none" stroke={i === 0 ? accent : muted} strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" style={{ width: 18, height: 18 }}>
|
||
<path d={d} />
|
||
</svg>
|
||
</div>
|
||
))}
|
||
</div>
|
||
|
||
{/* Main area */}
|
||
<div style={{ flex: 1, padding: "20px 24px", display: "flex", flexDirection: "column", gap: 16, overflow: "hidden" }}>
|
||
{/* Header row */}
|
||
<div style={{ display: "flex", alignItems: "center", justifyContent: "space-between" }}>
|
||
<p style={{ fontSize: 17, fontWeight: 700, color: text, letterSpacing: "-0.01em" }}>Analytics</p>
|
||
<div style={{ height: 32, padding: "0 16px", borderRadius: 8, background: accent, display: "flex", alignItems: "center" }}>
|
||
<span style={{ fontSize: 12, fontWeight: 600, color: "#fff" }}>+ New report</span>
|
||
</div>
|
||
</div>
|
||
|
||
{/* KPI cards */}
|
||
<div style={{ display: "grid", gridTemplateColumns: "repeat(3,1fr)", gap: 12 }}>
|
||
{[
|
||
{ 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 => (
|
||
<div key={m.l} style={{
|
||
padding: "16px 18px", borderRadius: 12,
|
||
background: card, border: `1px solid ${border}`,
|
||
boxShadow: "0 1px 4px rgba(0,0,0,0.06)",
|
||
}}>
|
||
<p style={{ fontSize: 12, color: muted, marginBottom: 4, fontWeight: 500 }}>{m.l}</p>
|
||
<p style={{ fontSize: 24, fontWeight: 900, color: text, letterSpacing: "-0.02em", lineHeight: 1.1 }}>{m.v}</p>
|
||
<p style={{ fontSize: 12, color: m.up ? "#16a34a" : "#dc2626", marginTop: 4, fontWeight: 600 }}>{m.d}</p>
|
||
</div>
|
||
))}
|
||
</div>
|
||
|
||
{/* Chart */}
|
||
<div style={{
|
||
flex: 1, padding: "16px 18px", borderRadius: 12,
|
||
background: card, border: `1px solid ${border}`,
|
||
boxShadow: "0 1px 4px rgba(0,0,0,0.06)",
|
||
display: "flex", flexDirection: "column",
|
||
}}>
|
||
<div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 12 }}>
|
||
<p style={{ fontSize: 14, fontWeight: 700, color: text }}>Revenue trend</p>
|
||
<div style={{ display: "flex", gap: 6 }}>
|
||
{["7d","30d","90d"].map((l, i) => (
|
||
<span key={l} style={{
|
||
fontSize: 11, fontWeight: i === 1 ? 700 : 400,
|
||
color: i === 1 ? accent : muted,
|
||
padding: "2px 8px", borderRadius: 5,
|
||
background: i === 1 ? `${accent}14` : "transparent",
|
||
}}>{l}</span>
|
||
))}
|
||
</div>
|
||
</div>
|
||
<svg viewBox="0 0 240 80" style={{ flex: 1, width: "100%", overflow: "visible" }} preserveAspectRatio="none">
|
||
<defs>
|
||
<linearGradient id={`g-${uid}`} x1="0" y1="0" x2="0" y2="1">
|
||
<stop offset="0%" stopColor={accent} stopOpacity="0.35" />
|
||
<stop offset="100%" stopColor={accent} stopOpacity="0" />
|
||
</linearGradient>
|
||
</defs>
|
||
<path d="M0,75 C24,68 38,58 56,46 C74,34 88,26 108,18 C128,10 148,6 168,4 C188,3 210,2 240,1"
|
||
stroke={accent} strokeWidth="2.5" fill="none" strokeLinecap="round" />
|
||
<path d="M0,75 C24,68 38,58 56,46 C74,34 88,26 108,18 C128,10 148,6 168,4 C188,3 210,2 240,1 L240,80 L0,80 Z"
|
||
fill={`url(#g-${uid})`} />
|
||
</svg>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|
||
|
||
// Minimal SVG icon — inline path, no emoji
|
||
function Ico({ d, color, size = 15, fill = false }: { d: string; color: string; size?: number; fill?: boolean }) {
|
||
return (
|
||
<svg viewBox="0 0 24 24" fill={fill ? color : "none"} stroke={fill ? "none" : color}
|
||
strokeWidth="1.9" strokeLinecap="round" strokeLinejoin="round" style={{ width: size, height: size }}>
|
||
<path d={d} />
|
||
</svg>
|
||
);
|
||
}
|
||
|
||
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 (
|
||
<div style={{ height: "100%", fontFamily: ff, background: bg, color: text, overflow: "auto", position: "relative" }}>
|
||
<style>{fontImport(config?.font)}</style>
|
||
{bgStyle === "pattern" && (
|
||
<div style={{ position: "absolute", inset: 0, backgroundImage: `radial-gradient(${p}22 1px, transparent 1px)`, backgroundSize: "20px 20px", pointerEvents: "none", zIndex: 0 }} />
|
||
)}
|
||
{bgStyle === "noise" && (
|
||
<div style={{ position: "absolute", inset: 0, backgroundImage: `url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.75' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='1'/%3E%3C/svg%3E")`, backgroundSize: "200px", opacity: isDark ? 0.06 : 0.04, pointerEvents: "none", zIndex: 0 }} />
|
||
)}
|
||
|
||
{/* Nav */}
|
||
{navStyle === "pill" ? (
|
||
<div style={{ display: "flex", justifyContent: "center", padding: "20px 40px", position: "relative", zIndex: 2 }}>
|
||
<nav style={{ display: "flex", alignItems: "center", gap: 32, padding: "12px 28px", borderRadius: 50, border: `1px solid ${border}`, background: isDark ? "rgba(255,255,255,0.05)" : "rgba(0,0,0,0.03)", backdropFilter: "blur(10px)" }}>
|
||
<div style={{ display: "flex", alignItems: "center", gap: 9 }}>
|
||
<div style={{ width: 28, height: 28, borderRadius: 7, background: p }} />
|
||
<span style={{ fontWeight: 800, fontSize: 17, color: text }}>Acme</span>
|
||
</div>
|
||
{["Features","Pricing","Docs"].map(i => <span key={i} style={{ fontSize: 15, color: muted }}>{i}</span>)}
|
||
<button style={{ height: 40, padding: "0 22px", borderRadius: 24, fontSize: 14, fontWeight: 700, background: p, color: pFg, border: "none", cursor: "pointer" }}>Get started</button>
|
||
</nav>
|
||
</div>
|
||
) : (
|
||
<nav style={{
|
||
display: "flex", alignItems: "center", justifyContent: "space-between",
|
||
padding: "18px 48px", borderBottom: navStyle === "transparent" ? "none" : `1px solid ${border}`,
|
||
background: navStyle === "transparent" ? "transparent" : bg,
|
||
position: "relative", zIndex: 2,
|
||
}}>
|
||
<div style={{ display: "flex", alignItems: "center", gap: 10 }}>
|
||
<div style={{ width: 28, height: 28, borderRadius: 7, background: p }} />
|
||
<span style={{ fontWeight: 800, fontSize: 17, color: text, letterSpacing: "-0.01em" }}>Acme</span>
|
||
</div>
|
||
<div style={{ display: "flex", gap: 32, fontSize: 15, color: muted }}>
|
||
{["Features","Pricing","Docs","Blog"].map(i => <span key={i}>{i}</span>)}
|
||
</div>
|
||
<div style={{ display: "flex", gap: 10 }}>
|
||
<button style={{ height: 42, padding: "0 22px", borderRadius: 24, fontSize: 14, fontWeight: 500, background: "none", border: `1px solid ${border}`, color: muted, cursor: "pointer" }}>Log in</button>
|
||
<button style={{ height: 42, padding: "0 24px", borderRadius: 24, fontSize: 14, fontWeight: 700, background: p, color: pFg, border: "none", cursor: "pointer" }}>Get started →</button>
|
||
</div>
|
||
</nav>
|
||
)}
|
||
|
||
{/* Hero */}
|
||
{hdrStyle === "centered" && (
|
||
<div style={{ padding: "80px 48px 0", textAlign: "center", position: "relative", zIndex: 1 }}>
|
||
{heroBg && <div style={{ position: "absolute", inset: 0, background: heroBg, pointerEvents: "none" }} />}
|
||
<div style={{ display: "inline-flex", alignItems: "center", gap: 8, padding: "6px 18px", borderRadius: 24, fontSize: 13, fontWeight: 700, marginBottom: 24, background: `${p}18`, color: p, border: `1px solid ${p}40` }}>
|
||
✦ {theme.label} theme — v2.0 just shipped
|
||
</div>
|
||
<h1 style={{ fontSize: 72, fontWeight: 900, marginBottom: 20, color: text, lineHeight: 1.02, letterSpacing: "-0.045em" }}>
|
||
Build faster,<br />ship smarter.
|
||
</h1>
|
||
<p style={{ fontSize: 18, color: muted, maxWidth: 560, margin: "0 auto 32px", lineHeight: 1.75 }}>
|
||
The all-in-one platform that helps teams build, launch, and scale production apps with confidence.
|
||
</p>
|
||
<div style={{ display: "flex", gap: 14, justifyContent: "center", marginBottom: 56 }}>
|
||
<button style={{ height: 52, padding: "0 32px", borderRadius: 28, fontSize: 16, fontWeight: 700, background: p, color: pFg, border: "none", cursor: "pointer" }}>Start for free</button>
|
||
<button style={{ height: 52, padding: "0 28px", borderRadius: 28, fontSize: 16, border: `1px solid ${border}`, color: muted, background: "none", cursor: "pointer" }}>See demo →</button>
|
||
</div>
|
||
<div style={{ padding: "0 0 0" }}>
|
||
<DashMockup bg={bg} card={card} border={border} text={text} muted={muted} accent={p} />
|
||
</div>
|
||
</div>
|
||
)}
|
||
|
||
{hdrStyle === "split" && (
|
||
<div style={{ display: "flex", gap: 48, padding: "72px 48px 0", alignItems: "flex-start", position: "relative", zIndex: 1 }}>
|
||
{heroBg && <div style={{ position: "absolute", inset: 0, background: heroBg, pointerEvents: "none" }} />}
|
||
<div style={{ flex: "0 0 44%", paddingTop: 16 }}>
|
||
<div style={{ display: "inline-flex", alignItems: "center", gap: 6, padding: "5px 14px", borderRadius: 20, fontSize: 13, fontWeight: 700, marginBottom: 20, background: `${p}18`, color: p, border: `1px solid ${p}40` }}>✦ {theme.label}</div>
|
||
<h1 style={{ fontSize: 58, fontWeight: 900, marginBottom: 18, color: text, lineHeight: 1.06, letterSpacing: "-0.04em" }}>
|
||
Build faster,<br />ship smarter.
|
||
</h1>
|
||
<p style={{ fontSize: 17, color: muted, marginBottom: 28, lineHeight: 1.75 }}>
|
||
The platform teams trust to ship faster and sleep better.
|
||
</p>
|
||
<div style={{ display: "flex", gap: 12, marginBottom: 40 }}>
|
||
<button style={{ height: 50, padding: "0 28px", borderRadius: 26, fontSize: 15, fontWeight: 700, background: p, color: pFg, border: "none", cursor: "pointer" }}>Start free</button>
|
||
<button style={{ height: 50, padding: "0 24px", borderRadius: 26, fontSize: 15, border: `1px solid ${border}`, color: muted, background: "none", cursor: "pointer" }}>Demo →</button>
|
||
</div>
|
||
<div style={{ display: "flex", gap: 32 }}>
|
||
{[["50k+","Teams"],["99.9%","Uptime"],["$0","To start"]].map(([v,l]) => (
|
||
<div key={l}>
|
||
<p style={{ fontSize: 28, fontWeight: 900, color: p, letterSpacing: "-0.02em" }}>{v}</p>
|
||
<p style={{ fontSize: 13, color: muted }}>{l}</p>
|
||
</div>
|
||
))}
|
||
</div>
|
||
</div>
|
||
<div style={{ flex: 1, minWidth: 0 }}>
|
||
<DashMockup bg={bg} card={card} border={border} text={text} muted={muted} accent={p} />
|
||
</div>
|
||
</div>
|
||
)}
|
||
|
||
{hdrStyle === "stats" && (
|
||
<div style={{ padding: "80px 48px 0", textAlign: "center", position: "relative", zIndex: 1 }}>
|
||
{heroBg && <div style={{ position: "absolute", inset: 0, background: heroBg, pointerEvents: "none" }} />}
|
||
<h1 style={{ fontSize: 70, fontWeight: 900, marginBottom: 20, color: text, lineHeight: 1.02, letterSpacing: "-0.045em" }}>Build faster,<br />ship smarter.</h1>
|
||
<p style={{ fontSize: 18, color: muted, maxWidth: 520, margin: "0 auto 28px", lineHeight: 1.75 }}>The platform that helps teams ship with confidence.</p>
|
||
<div style={{ display: "flex", gap: 14, justifyContent: "center", marginBottom: 32 }}>
|
||
<button style={{ height: 50, padding: "0 30px", borderRadius: 26, fontSize: 16, fontWeight: 700, background: p, color: pFg, border: "none", cursor: "pointer" }}>Start free</button>
|
||
<button style={{ height: 50, padding: "0 26px", borderRadius: 26, fontSize: 16, border: `1px solid ${border}`, color: muted, background: "none", cursor: "pointer" }}>Demo →</button>
|
||
</div>
|
||
<div style={{ display: "flex", justifyContent: "center", gap: 56, marginBottom: 48, padding: "28px 0", borderTop: `1px solid ${border}`, borderBottom: `1px solid ${border}` }}>
|
||
{[["50k+","Teams"],["99.9%","Uptime"],["10ms","Latency"],["$0","To start"]].map(([v,l]) => (
|
||
<div key={l} style={{ textAlign: "center" }}>
|
||
<p style={{ fontSize: 36, fontWeight: 900, color: p, letterSpacing: "-0.02em" }}>{v}</p>
|
||
<p style={{ fontSize: 14, color: muted }}>{l}</p>
|
||
</div>
|
||
))}
|
||
</div>
|
||
<DashMockup bg={bg} card={card} border={border} text={text} muted={muted} accent={p} />
|
||
</div>
|
||
)}
|
||
|
||
{/* Sections */}
|
||
{comps.includes("logos") && (
|
||
<div style={{ padding: "28px 48px", display: "flex", alignItems: "center", gap: 24, borderTop: `1px solid ${border}`, borderBottom: `1px solid ${border}`, background: isDark ? "rgba(255,255,255,0.02)" : "rgba(0,0,0,0.015)", position: "relative", zIndex: 1, marginTop: 40 }}>
|
||
<span style={{ fontSize: 13, color: muted, whiteSpace: "nowrap", flexShrink: 0 }}>Trusted by</span>
|
||
{["Vercel","Stripe","Linear","Notion","Supabase","Raycast"].map(b => (
|
||
<span key={b} style={{ fontSize: 15, fontWeight: 700, color: muted, opacity: 0.45 }}>{b}</span>
|
||
))}
|
||
</div>
|
||
)}
|
||
|
||
{comps.includes("features") && (
|
||
<div style={{ padding: "80px 48px", position: "relative", zIndex: 1 }}>
|
||
<div style={{ textAlign: "center", marginBottom: 48 }}>
|
||
<p style={{ fontSize: 13, fontWeight: 700, color: p, letterSpacing: "0.12em", textTransform: "uppercase", marginBottom: 10 }}>Features</p>
|
||
<h2 style={{ fontSize: 40, fontWeight: 900, color: text, letterSpacing: "-0.02em", lineHeight: 1.12 }}>Everything you need<br />to ship faster</h2>
|
||
</div>
|
||
<div style={{ display: "grid", gridTemplateColumns: "repeat(3,1fr)", gap: 20 }}>
|
||
{[
|
||
{ icon: "bolt", title: "10× faster deploys", desc: "Push to production in under 30 seconds. Zero config required." },
|
||
{ icon: "shield", title: "Enterprise security", desc: "SOC 2 compliant with end-to-end encryption and audit logs." },
|
||
{ icon: "trend", title: "Real-time analytics", desc: "Track every metric that matters. Live dashboards, zero lag." },
|
||
{ icon: "globe", title: "Global edge network", desc: "300+ PoPs worldwide. Your users get sub-10ms response times." },
|
||
{ icon: "layers", title: "Any stack, any scale", desc: "Node, Python, Go, Rust — deploy whatever your team builds." },
|
||
{ icon: "clock", title: "99.99% uptime SLA", desc: "We guarantee it. And we back that up with automatic credits." },
|
||
].map(f => (
|
||
<div key={f.title} style={{ padding: "28px 28px", borderRadius: 16, background: card, border: `1px solid ${border}`, boxShadow: "0 2px 12px rgba(0,0,0,0.06)" }}>
|
||
<div style={{ width: 48, height: 48, borderRadius: 12, background: `${p}16`, display: "flex", alignItems: "center", justifyContent: "center", marginBottom: 18 }}>
|
||
<Ico d={ICO[f.icon as keyof typeof ICO]} color={p} size={22} />
|
||
</div>
|
||
<p style={{ fontSize: 16, fontWeight: 700, color: text, marginBottom: 8, letterSpacing: "-0.01em" }}>{f.title}</p>
|
||
<p style={{ fontSize: 14, color: muted, lineHeight: 1.7 }}>{f.desc}</p>
|
||
</div>
|
||
))}
|
||
</div>
|
||
</div>
|
||
)}
|
||
|
||
{comps.includes("steps") && (
|
||
<div style={{ padding: "80px 48px", position: "relative", zIndex: 1 }}>
|
||
<h2 style={{ fontSize: 36, fontWeight: 900, color: text, letterSpacing: "-0.02em", marginBottom: 40, textAlign: "center" }}>Up and running in 3 steps</h2>
|
||
<div style={{ display: "grid", gridTemplateColumns: "1fr 1fr 1fr", gap: 20 }}>
|
||
{[
|
||
{ 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 => (
|
||
<div key={s.n} style={{ padding: "28px 28px", borderRadius: 16, background: card, border: `1px solid ${border}` }}>
|
||
<p style={{ fontSize: 36, fontWeight: 900, color: `${p}50`, letterSpacing: "-0.04em", marginBottom: 14 }}>{s.n}</p>
|
||
<p style={{ fontSize: 17, fontWeight: 700, color: text, marginBottom: 8 }}>{s.title}</p>
|
||
<p style={{ fontSize: 14, color: muted, lineHeight: 1.7 }}>{s.desc}</p>
|
||
</div>
|
||
))}
|
||
</div>
|
||
</div>
|
||
)}
|
||
|
||
{comps.includes("testimonials") && (
|
||
<div style={{ padding: "80px 48px", position: "relative", zIndex: 1 }}>
|
||
<h2 style={{ fontSize: 36, fontWeight: 900, color: text, letterSpacing: "-0.02em", marginBottom: 36, textAlign: "center" }}>Loved by engineering teams</h2>
|
||
<div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 20 }}>
|
||
{[
|
||
{ q: "\"We cut our deploy time from 20 minutes to 45 seconds. Game changer.\"", name: "Sarah K.", role: "CTO at Linear" },
|
||
{ q: "\"Reduced infrastructure costs by 40% in our first month. Incredible ROI.\"", name: "James R.", role: "Eng Lead at Stripe" },
|
||
{ q: "\"The DX is in a league of its own. Every edge case handled perfectly.\"", name: "Mia Chen", role: "Staff Eng at Vercel" },
|
||
{ q: "\"Finally, a platform that just works. Zero incidents in 8 months.\"", name: "Tom W.", role: "Founder at Raycast" },
|
||
].map(t => (
|
||
<div key={t.name} style={{ padding: "28px 28px", borderRadius: 16, background: card, border: `1px solid ${border}`, boxShadow: "0 2px 12px rgba(0,0,0,0.05)" }}>
|
||
<div style={{ display: "flex", gap: 3, marginBottom: 14 }}>
|
||
{Array(5).fill(0).map((_, i) => <span key={i} style={{ color: "#f59e0b", fontSize: 16 }}>★</span>)}
|
||
</div>
|
||
<p style={{ fontSize: 16, color: text, marginBottom: 18, lineHeight: 1.7, fontStyle: "italic" }}>{t.q}</p>
|
||
<div style={{ display: "flex", alignItems: "center", gap: 12 }}>
|
||
<div style={{ width: 36, height: 36, borderRadius: "50%", background: `${p}22`, display: "flex", alignItems: "center", justifyContent: "center" }}>
|
||
<span style={{ fontSize: 15, fontWeight: 700, color: p }}>{t.name[0]}</span>
|
||
</div>
|
||
<div>
|
||
<p style={{ fontSize: 14, fontWeight: 700, color: text }}>{t.name}</p>
|
||
<p style={{ fontSize: 13, color: muted }}>{t.role}</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
))}
|
||
</div>
|
||
</div>
|
||
)}
|
||
|
||
{comps.includes("pricing") && (
|
||
<div style={{ padding: "80px 48px", position: "relative", zIndex: 1 }}>
|
||
<div style={{ textAlign: "center", marginBottom: 48 }}>
|
||
<h2 style={{ fontSize: 40, fontWeight: 900, color: text, letterSpacing: "-0.02em", marginBottom: 10 }}>Simple, transparent pricing</h2>
|
||
<p style={{ fontSize: 16, color: muted }}>No surprises. No hidden fees. Cancel anytime.</p>
|
||
</div>
|
||
<div style={{ display: "grid", gridTemplateColumns: "1fr 1fr 1fr", gap: 20 }}>
|
||
{[
|
||
{ 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 => (
|
||
<div key={pl.plan} style={{
|
||
padding: "32px 28px", borderRadius: 20,
|
||
background: pl.hi ? p : card,
|
||
border: `2px solid ${pl.hi ? p : border}`,
|
||
boxShadow: pl.hi ? `0 12px 48px ${p}40` : "0 2px 12px rgba(0,0,0,0.05)",
|
||
}}>
|
||
<p style={{ fontSize: 14, fontWeight: 600, color: pl.hi ? `${pFg}bb` : muted, marginBottom: 6 }}>{pl.plan}</p>
|
||
<p style={{ fontSize: 44, fontWeight: 900, color: pl.hi ? pFg : text, letterSpacing: "-0.03em", lineHeight: 1.1 }}>{pl.price}</p>
|
||
<p style={{ fontSize: 13, color: pl.hi ? `${pFg}88` : muted, marginBottom: 24 }}>{pl.period}</p>
|
||
<div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
|
||
{pl.features.map(f => (
|
||
<div key={f} style={{ display: "flex", alignItems: "center", gap: 10 }}>
|
||
<div style={{ width: 18, height: 18, borderRadius: "50%", background: pl.hi ? `${pFg}22` : `${p}18`, display: "flex", alignItems: "center", justifyContent: "center", flexShrink: 0 }}>
|
||
<svg viewBox="0 0 10 10" fill="none" style={{ width: 9, height: 9 }}>
|
||
<path d="M2 5l2 2 4-4" stroke={pl.hi ? pFg : p} strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
|
||
</svg>
|
||
</div>
|
||
<span style={{ fontSize: 14, color: pl.hi ? `${pFg}dd` : muted }}>{f}</span>
|
||
</div>
|
||
))}
|
||
</div>
|
||
<button style={{ marginTop: 24, width: "100%", height: 48, borderRadius: 26, fontSize: 15, fontWeight: 700, background: pl.hi ? pFg : p, color: pl.hi ? p : pFg, border: "none", cursor: "pointer" }}>
|
||
{pl.plan === "Enterprise" ? "Contact sales" : "Get started"}
|
||
</button>
|
||
</div>
|
||
))}
|
||
</div>
|
||
</div>
|
||
)}
|
||
|
||
{comps.includes("faq") && (
|
||
<div style={{ padding: "80px 48px", position: "relative", zIndex: 1 }}>
|
||
<h2 style={{ fontSize: 36, fontWeight: 900, color: text, letterSpacing: "-0.02em", marginBottom: 28, textAlign: "center" }}>Frequently asked</h2>
|
||
{[
|
||
["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) => (
|
||
<div key={q} style={{ padding: "22px 0", borderBottom: `1px solid ${border}` }}>
|
||
<div style={{ display: "flex", justifyContent: "space-between", alignItems: "center" }}>
|
||
<p style={{ fontSize: 17, fontWeight: 600, color: text }}>{q}</p>
|
||
<span style={{ fontSize: 22, color: muted, marginLeft: 20 }}>{i === 0 ? "−" : "+"}</span>
|
||
</div>
|
||
{i === 0 && <p style={{ fontSize: 15, color: muted, marginTop: 12, lineHeight: 1.7 }}>{a}</p>}
|
||
</div>
|
||
))}
|
||
</div>
|
||
)}
|
||
|
||
{comps.includes("cta") && (
|
||
<div style={{ margin: "0 48px 80px", padding: "60px 48px", borderRadius: 24, background: `linear-gradient(135deg, ${p}18, ${p}08)`, border: `1px solid ${p}30`, textAlign: "center", position: "relative", zIndex: 1 }}>
|
||
<h2 style={{ fontSize: 42, fontWeight: 900, color: text, letterSpacing: "-0.02em", marginBottom: 12 }}>Ready to ship faster?</h2>
|
||
<p style={{ fontSize: 17, color: muted, marginBottom: 28 }}>Join 50,000+ teams already building on Acme. Free forever.</p>
|
||
<button style={{ height: 52, padding: "0 36px", borderRadius: 28, fontSize: 16, fontWeight: 700, background: p, color: pFg, border: "none", cursor: "pointer" }}>Start building for free →</button>
|
||
</div>
|
||
)}
|
||
|
||
<div style={{ height: 24 }} />
|
||
</div>
|
||
);
|
||
}
|
||
|
||
// ---------------------------------------------------------------------------
|
||
// 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 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);
|
||
|
||
// Force correct bg/text per effect
|
||
const forcedBlack = bgStyle === "sparkles";
|
||
const forcedLight = bgStyle === "aurora";
|
||
const forceShader = bgStyle === "shader";
|
||
|
||
const bg = forcedBlack ? "#000" : forcedLight ? "#f8f9ff" : forceShader ? "#06010e" : isDark ? ACE_BG_BASE : ACE_BG_LIGHT;
|
||
// text/muted/card/border must respond to isDark (not just forcedLight=aurora)
|
||
const text = isDark ? "#fff" : "#1e1b4b";
|
||
const muted = isDark ? "rgba(255,255,255,0.42)" : "#6b7280";
|
||
const card = isDark ? "rgba(255,255,255,0.05)" : "rgba(0,0,0,0.04)";
|
||
const border= isDark ? "rgba(255,255,255,0.08)" : "rgba(0,0,0,0.1)";
|
||
|
||
const BgLayer = () => {
|
||
if (bgStyle === "gradient") {
|
||
if (!isDark) return (
|
||
<div style={{ position: "absolute", inset: 0, overflow: "hidden", zIndex: 0, background: "rgb(248,247,255)" }}>
|
||
<div style={{ position: "absolute", inset: 0, filter: "blur(70px)", opacity: 0.55 }}>
|
||
<div style={{ position: "absolute", width: "70%", height: "70%", top: "5%", left: "10%", borderRadius: "50%", background: `radial-gradient(circle, rgba(196,181,253,0.7) 0%, transparent 65%)`, animation: "ace-blob1 22s ease infinite" }} />
|
||
<div style={{ position: "absolute", width: "65%", height: "65%", top: "-10%", left: "-5%", borderRadius: "50%", background: `radial-gradient(circle, rgba(147,197,253,0.6) 0%, transparent 65%)`, animation: "ace-blob2 18s reverse infinite" }} />
|
||
<div style={{ position: "absolute", width: "55%", height: "55%", bottom: "10%", right: "10%", borderRadius: "50%", background: `radial-gradient(circle, rgba(216,180,254,0.5) 0%, transparent 65%)`, animation: "ace-blob3 28s linear infinite" }} />
|
||
<div style={{ position: "absolute", width: "50%", height: "50%", bottom: "-10%", left: "30%", borderRadius: "50%", background: `radial-gradient(circle, ${p}40 0%, transparent 65%)`, animation: "ace-blob4 24s ease infinite" }} />
|
||
</div>
|
||
</div>
|
||
);
|
||
return (
|
||
<div style={{ position: "absolute", inset: 0, overflow: "hidden", zIndex: 0, background: "rgb(8,0,20)" }}>
|
||
<div style={{ position: "absolute", inset: 0, filter: "blur(55px)", mixBlendMode: "hard-light" }}>
|
||
<div style={{ position: "absolute", width: "70%", height: "70%", top: "5%", left: "10%", borderRadius: "50%", background: `radial-gradient(circle, rgba(18,113,255,0.85) 0%, transparent 65%)`, animation: "ace-blob1 22s ease infinite" }} />
|
||
<div style={{ position: "absolute", width: "65%", height: "65%", top: "-10%", left: "-5%", borderRadius: "50%", background: `radial-gradient(circle, ${p}cc 0%, transparent 65%)`, animation: "ace-blob2 18s reverse infinite" }} />
|
||
<div style={{ position: "absolute", width: "55%", height: "55%", bottom: "10%", right: "10%", borderRadius: "50%", background: `radial-gradient(circle, rgba(100,220,255,0.7) 0%, transparent 65%)`, animation: "ace-blob3 28s linear infinite" }} />
|
||
<div style={{ position: "absolute", width: "50%", height: "50%", bottom: "-10%", left: "30%", borderRadius: "50%", background: `radial-gradient(circle, rgba(200,50,50,0.65) 0%, transparent 65%)`, animation: "ace-blob4 24s ease infinite" }} />
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|
||
if (bgStyle === "shader") return (
|
||
<div style={{ position: "absolute", inset: 0, overflow: "hidden", zIndex: 0 }}>
|
||
<div style={{ position: "absolute", inset: 0, background: "linear-gradient(135deg, #7c3aed 0%, #db2777 35%, #ea580c 65%, #ca8a04 100%)", opacity: 0.92 }} />
|
||
<div style={{ position: "absolute", inset: 0, backgroundImage: "repeating-linear-gradient(135deg, transparent 0px, transparent 14px, rgba(255,255,255,0.04) 14px, rgba(255,255,255,0.04) 15px)" }} />
|
||
<div style={{ position: "absolute", inset: 0, background: "radial-gradient(ellipse 80% 80% at 50% 50%, transparent 35%, rgba(0,0,0,0.4) 100%)" }} />
|
||
</div>
|
||
);
|
||
if (bgStyle === "beams") return (
|
||
<div style={{ position: "absolute", inset: 0, overflow: "hidden", zIndex: 0 }}>
|
||
{/* CSS radial glow — no SVG gradient ID reference (avoids black-fill fallback) */}
|
||
<div style={{ position: "absolute", top: 0, left: "50%", transform: "translateX(-50%)", width: "80%", height: "60%", background: `radial-gradient(ellipse at 50% 0%, ${p}${isDark ? "30" : "18"}, transparent 70%)`, pointerEvents: "none" }} />
|
||
<svg style={{ position: "absolute", inset: 0, width: "100%", height: "100%" }} viewBox="0 0 400 700" preserveAspectRatio="xMidYMid slice">
|
||
{Array.from({ length: 14 }).map((_, i) => {
|
||
const x = 200 + (i - 7) * 32;
|
||
const lineColor = isDark
|
||
? (i % 3 === 0 ? p : i % 3 === 1 ? "#3b82f6" : "#06b6d4")
|
||
: (i % 3 === 0 ? p : i % 3 === 1 ? "#6366f1" : "#0891b2");
|
||
return (
|
||
<line key={i} x1={200} y1={0} x2={x} y2={700}
|
||
stroke={lineColor}
|
||
strokeWidth={i % 4 === 0 ? 0.7 : 0.35}
|
||
strokeOpacity={isDark ? (0.12 + (i % 3) * 0.05) : (0.18 + (i % 3) * 0.06)}
|
||
style={{ animation: `ace-beam-pulse ${3 + i * 0.4}s ease-in-out ${i * 0.22}s infinite` }}
|
||
/>
|
||
);
|
||
})}
|
||
</svg>
|
||
</div>
|
||
);
|
||
if (bgStyle === "meteors") return (
|
||
<div style={{ position: "absolute", inset: 0, overflow: "hidden", zIndex: 0 }}>
|
||
<div style={{ position: "absolute", inset: 0, background: `radial-gradient(ellipse 55% 35% at 50% 0%, ${p}${isDark ? "20" : "12"}, transparent)` }} />
|
||
{Array.from({ length: 12 }).map((_, i) => (
|
||
<div key={i} style={{
|
||
position: "absolute",
|
||
top: `${(i * 31 + 5) % 65}%`,
|
||
right: `${(i * 47) % 90}%`,
|
||
width: `${36 + i * 8}px`, height: "1.5px",
|
||
background: isDark
|
||
? `linear-gradient(90deg, ${p}ee, rgba(255,255,255,0.8), transparent)`
|
||
: `linear-gradient(90deg, ${p}cc, rgba(0,0,0,0.15), transparent)`,
|
||
transform: "rotate(-35deg)",
|
||
animation: `ace-meteor ${1.2 + (i % 5) * 0.5}s linear ${i * 0.55}s infinite`,
|
||
borderRadius: "50%",
|
||
boxShadow: `0 0 5px ${p}90`,
|
||
}} />
|
||
))}
|
||
</div>
|
||
);
|
||
if (bgStyle === "sparkles") return (
|
||
<div style={{ position: "absolute", inset: 0, overflow: "hidden", zIndex: 0, background: "#000" }}>
|
||
{Array.from({ length: 45 }).map((_, i) => {
|
||
const sz = i % 6 === 0 ? 3 : i % 3 === 0 ? 2 : 1.5;
|
||
return (
|
||
<div key={i} style={{
|
||
position: "absolute",
|
||
width: sz, height: sz, borderRadius: "50%",
|
||
background: "#fff",
|
||
boxShadow: `0 0 ${sz * 3}px ${i % 4 === 0 ? p : "rgba(255,255,255,0.9)"}`,
|
||
top: `${(i * 37 + 5) % 92}%`,
|
||
left: `${(i * 53 + 3) % 94}%`,
|
||
animation: `ace-sparkle ${1.4 + (i % 7) * 0.3}s ease-in-out ${(i * 0.18) % 2.2}s infinite`,
|
||
}} />
|
||
);
|
||
})}
|
||
</div>
|
||
);
|
||
if (bgStyle === "aurora") return (
|
||
<div style={{ position: "absolute", inset: 0, overflow: "hidden", zIndex: 0, background: "#f0f0ff" }}>
|
||
<div style={{ position: "absolute", top: "-35%", left: "-10%", width: "75%", height: "75%", borderRadius: "50%", background: "radial-gradient(circle, rgba(196,181,253,0.6) 0%, transparent 65%)", filter: "blur(50px)", animation: "ace-blob1 18s ease infinite" }} />
|
||
<div style={{ position: "absolute", top: "-20%", right: "-5%", width: "65%", height: "65%", borderRadius: "50%", background: "radial-gradient(circle, rgba(147,197,253,0.5) 0%, transparent 65%)", filter: "blur(45px)", animation: "ace-blob2 24s reverse infinite" }} />
|
||
<div style={{ position: "absolute", top: "25%", left: "32%", width: "55%", height: "55%", borderRadius: "50%", background: "radial-gradient(circle, rgba(216,180,254,0.4) 0%, transparent 65%)", filter: "blur(45px)", animation: "ace-blob3 28s linear infinite" }} />
|
||
</div>
|
||
);
|
||
if (bgStyle === "wavy") return (
|
||
<div style={{ position: "absolute", top: 0, left: 0, right: 0, height: "55%", zIndex: 0, overflow: "hidden" }}>
|
||
<svg viewBox="0 0 400 120" preserveAspectRatio="none" style={{ width: "100%", height: "100%" }}>
|
||
<path d="M0,40 Q50,10 100,40 T200,40 T300,40 T400,40 L400,120 L0,120 Z" fill={`${p}${isDark ? "20" : "14"}`} />
|
||
<path d="M0,65 Q70,35 140,65 T280,65 T400,65 L400,120 L0,120 Z" fill={`${p}${isDark ? "0e" : "07"}`} />
|
||
</svg>
|
||
</div>
|
||
);
|
||
if (bgStyle === "dot-grid") return (
|
||
<div style={{ position: "absolute", inset: 0, zIndex: 0, backgroundImage: `radial-gradient(${p}30 1px, transparent 1px)`, backgroundSize: "22px 22px" }} />
|
||
);
|
||
return <div style={{ position: "absolute", inset: 0, background: `radial-gradient(ellipse 70% 50% at 50% 0%, ${p}18, transparent)`, zIndex: 0 }} />;
|
||
};
|
||
|
||
return (
|
||
<div style={{ height: "100%", fontFamily: ff, background: bg, overflow: "auto", position: "relative", color: text }}>
|
||
<style>{ACE_KEYFRAMES + fontImport(config?.font)}</style>
|
||
<BgLayer />
|
||
|
||
{/* Nav */}
|
||
{navStyle === "floating" ? (
|
||
<div style={{ display: "flex", justifyContent: "center", padding: "20px 48px", position: "relative", zIndex: 10 }}>
|
||
<nav style={{ display: "flex", alignItems: "center", gap: 32, padding: "14px 32px", borderRadius: 50, background: isDark ? "rgba(255,255,255,0.06)" : "rgba(0,0,0,0.04)", border: `1px solid ${p}40`, backdropFilter: "blur(14px)" }}>
|
||
<div style={{ display: "flex", alignItems: "center", gap: 9 }}>
|
||
<div style={{ width: 26, height: 26, borderRadius: 6, background: `linear-gradient(135deg,${p},#3b82f6)` }} />
|
||
<span style={{ fontWeight: 800, fontSize: 17, color: text }}>Acme</span>
|
||
</div>
|
||
{["Features","Pricing","Docs"].map(i => <span key={i} style={{ fontSize: 15, color: muted }}>{i}</span>)}
|
||
<button style={{ height: 42, padding: "0 22px", borderRadius: 22, fontSize: 14, fontWeight: 700, color: "#fff", background: `${p}55`, border: `1px solid ${p}60`, cursor: "pointer" }}>Get started</button>
|
||
</nav>
|
||
</div>
|
||
) : (
|
||
<nav style={{ display: "flex", alignItems: "center", justifyContent: "space-between", padding: "18px 48px", backdropFilter: "blur(8px)", background: isDark ? "rgba(5,0,16,0.55)" : "rgba(255,255,255,0.8)", position: "relative", zIndex: 10 }}>
|
||
<div style={{ display: "flex", alignItems: "center", gap: 10 }}>
|
||
<div style={{ width: 28, height: 28, borderRadius: 7, background: `linear-gradient(135deg,${p},#3b82f6)` }} />
|
||
<span style={{ fontWeight: 800, fontSize: 17, color: text }}>Acme</span>
|
||
</div>
|
||
<div style={{ display: "flex", gap: 32, fontSize: 15, color: muted }}>
|
||
{["Features","Pricing","Docs","Blog"].map(i => <span key={i}>{i}</span>)}
|
||
</div>
|
||
<button style={{ height: 44, padding: "0 24px", borderRadius: 8, fontSize: 14, fontWeight: 600, color: "#fff", background: `linear-gradient(135deg,${p},#3b82f6)`, border: "none", cursor: "pointer", boxShadow: `0 4px 16px ${p}40` }}>Get started</button>
|
||
</nav>
|
||
)}
|
||
|
||
{/* Hero: Gradient text */}
|
||
{hdrStyle === "gradient-text" && (
|
||
<div style={{ padding: "80px 48px 48px", textAlign: "center", position: "relative", zIndex: 1 }}>
|
||
<div style={{ display: "inline-flex", alignItems: "center", gap: 8, padding: "7px 20px", borderRadius: 28, fontSize: 13, fontWeight: 600, marginBottom: 28, border: `1px solid ${p}45`, color: `${p}dd`, background: `${p}10` }}>
|
||
✦ Open source · 12k GitHub stars · Now in v2
|
||
</div>
|
||
<h1 style={{
|
||
fontSize: 80, fontWeight: 900, marginBottom: 20, lineHeight: 0.98, letterSpacing: "-0.05em",
|
||
background: isDark
|
||
? "linear-gradient(180deg, #fff 35%, rgba(255,255,255,0.3) 100%)"
|
||
: "linear-gradient(180deg, #1e1b4b 30%, #6d28d9 100%)",
|
||
WebkitBackgroundClip: "text", WebkitTextFillColor: "transparent",
|
||
}}>
|
||
Build the future<br />of the web.
|
||
</h1>
|
||
<p style={{ fontSize: 18, color: muted, maxWidth: 520, margin: "0 auto 32px", lineHeight: 1.75 }}>
|
||
Beautifully crafted components built with Tailwind CSS and Framer Motion. Copy, paste, ship.
|
||
</p>
|
||
<div style={{ display: "flex", gap: 14, justifyContent: "center" }}>
|
||
<button style={{ height: 52, padding: "0 36px", borderRadius: 10, fontSize: 16, fontWeight: 700, color: "#fff", background: `linear-gradient(135deg,${p},#3b82f6)`, border: "none", cursor: "pointer", boxShadow: `0 8px 28px ${p}45` }}>Get started →</button>
|
||
<button style={{ height: 52, padding: "0 28px", borderRadius: 10, fontSize: 16, color: muted, border: `1px solid ${border}`, background: isDark ? "rgba(255,255,255,0.04)" : "rgba(0,0,0,0.03)", cursor: "pointer", backdropFilter: "blur(4px)" }}>Browse components</button>
|
||
</div>
|
||
</div>
|
||
)}
|
||
|
||
{/* Hero: Lamp */}
|
||
{hdrStyle === "lamp" && (
|
||
<div style={{ padding: "64px 48px 48px", textAlign: "center", position: "relative", zIndex: 1 }}>
|
||
<div style={{ position: "absolute", top: 0, left: "50%", transform: "translateX(-50%)", width: "65%", height: 160, background: `conic-gradient(from 263deg at 50% 0%, transparent 0deg, ${p}35 22deg, ${p}20 44deg, transparent 66deg)`, pointerEvents: "none" }} />
|
||
<div style={{ width: 160, height: 2, background: `linear-gradient(90deg, transparent, ${p}, transparent)`, margin: "0 auto 32px", animation: "ace-lamp 3.5s ease-in-out infinite" }} />
|
||
<h1 style={{ fontSize: 72, fontWeight: 900, marginBottom: 18, color: text, lineHeight: 1.02, letterSpacing: "-0.045em" }}>
|
||
Build the future<br />of the web.
|
||
</h1>
|
||
<p style={{ fontSize: 18, color: muted, maxWidth: 480, margin: "0 auto 28px", lineHeight: 1.75 }}>
|
||
Powered by Framer Motion and Tailwind CSS.
|
||
</p>
|
||
<button style={{ height: 52, padding: "0 32px", borderRadius: 10, fontSize: 16, fontWeight: 700, color: "#fff", background: `linear-gradient(135deg,${p},#3b82f6)`, border: "none", cursor: "pointer", boxShadow: `0 6px 24px ${p}40` }}>Get started →</button>
|
||
</div>
|
||
)}
|
||
|
||
{/* Hero: Typewriter */}
|
||
{hdrStyle === "typewriter" && (
|
||
<div style={{ padding: "80px 48px 48px", textAlign: "center", position: "relative", zIndex: 1 }}>
|
||
<div style={{ fontSize: 14, letterSpacing: "0.2em", color: `${p}90`, marginBottom: 24, textTransform: "uppercase", fontWeight: 600 }}>The future of the web</div>
|
||
<h1 style={{ fontSize: 76, fontWeight: 900, marginBottom: 20, lineHeight: 0.98, letterSpacing: "-0.05em" }}>
|
||
<span style={{ background: `linear-gradient(135deg,${p},#3b82f6)`, WebkitBackgroundClip: "text", WebkitTextFillColor: "transparent" }}>Build</span>
|
||
{" "}<span style={{ color: text }}>the future</span><br />
|
||
<span style={{ color: text }}>of the web</span>
|
||
<span style={{ display: "inline-block", width: 4, height: "0.9em", background: p, verticalAlign: "text-bottom", marginLeft: 4, animation: "ace-cursor 0.85s step-end infinite", borderRadius: 1 }} />
|
||
</h1>
|
||
<p style={{ fontSize: 18, color: muted, maxWidth: 480, margin: "0 auto 28px", lineHeight: 1.75 }}>
|
||
Components that bring ideas to life. No more boring UIs.
|
||
</p>
|
||
<button style={{ height: 52, padding: "0 32px", borderRadius: 10, fontSize: 16, fontWeight: 700, color: "#fff", background: `linear-gradient(135deg,${p},#3b82f6)`, border: "none", cursor: "pointer" }}>Get started →</button>
|
||
</div>
|
||
)}
|
||
|
||
{/* Sections */}
|
||
{comps.includes("badge") && (
|
||
<div style={{ textAlign: "center", padding: "0 48px 20px", position: "relative", zIndex: 1 }}>
|
||
<span style={{ display: "inline-block", padding: "7px 22px", borderRadius: 26, fontSize: 14, border: `1px solid ${p}45`, color: `${p}cc`, background: `${p}0e` }}>
|
||
✦ v2.0 just shipped — see what is new →
|
||
</span>
|
||
</div>
|
||
)}
|
||
|
||
{comps.includes("features") && (
|
||
<div style={{ display: "grid", gridTemplateColumns: "1fr 1fr 1fr", gap: 20, padding: "40px 48px 80px", position: "relative", zIndex: 1 }}>
|
||
{[
|
||
{ icon: "sparkle", title: "100+ components", desc: "From simple buttons to complex layouts. Copy-paste ready." },
|
||
{ icon: "zap", title: "Framer Motion", desc: "Buttery smooth animations that feel native to your app." },
|
||
{ icon: "code", title: "TypeScript first", desc: "Full type safety. IDE autocomplete. Zero runtime errors." },
|
||
].map(f => (
|
||
<div key={f.title} style={{ padding: "28px 28px", borderRadius: 16, background: card, border: `1px solid ${border}`, backdropFilter: "blur(4px)" }}>
|
||
<div style={{ width: 48, height: 48, borderRadius: 12, background: `${p}18`, display: "flex", alignItems: "center", justifyContent: "center", marginBottom: 18 }}>
|
||
<Ico d={ICO[f.icon as keyof typeof ICO]} color={p} size={22} />
|
||
</div>
|
||
<p style={{ fontSize: 17, fontWeight: 700, color: text, marginBottom: 8 }}>{f.title}</p>
|
||
<p style={{ fontSize: 14, color: muted, lineHeight: 1.7 }}>{f.desc}</p>
|
||
</div>
|
||
))}
|
||
</div>
|
||
)}
|
||
|
||
{comps.includes("moving-cards") && (
|
||
<div style={{ padding: "40px 0 80px", position: "relative", zIndex: 1, overflow: "hidden" }}>
|
||
<p style={{ fontSize: 13, color: muted, marginBottom: 24, textAlign: "center", textTransform: "uppercase", letterSpacing: "0.1em" }}>Loved by developers worldwide</p>
|
||
<div style={{ display: "flex", width: "200%", animation: "ace-marquee 24s linear infinite" }}>
|
||
{[...Array(2)].map((_, pass) => (
|
||
<div key={pass} style={{ display: "flex", gap: 16, paddingRight: 16, width: "50%", flexShrink: 0 }}>
|
||
{[
|
||
{ text: "\"Changed how I think about building UIs. Nothing else comes close.\"", name: "Sarah K.", role: "CTO" },
|
||
{ text: "\"Ships 3× faster. The Framer Motion integration is magic.\"", name: "James R.", role: "Eng Lead" },
|
||
{ text: "\"Every component is production-ready. Zero tweaking needed.\"", name: "Mia L.", role: "Founder" },
|
||
{ text: "\"Best component library I have ever used. The DX is incredible.\"", name: "Tom W.", role: "Developer" },
|
||
{ text: "\"Went from design to deployed in a weekend. Mind-blowing.\"", name: "Alex P.", role: "Designer" },
|
||
].map(t => (
|
||
<div key={t.name + pass} style={{ minWidth: 280, flexShrink: 0, padding: "22px 24px", borderRadius: 16, background: card, border: `1px solid ${p}22`, backdropFilter: "blur(4px)" }}>
|
||
<p style={{ fontSize: 14, color: muted, marginBottom: 14, lineHeight: 1.7 }}>{t.text}</p>
|
||
<p style={{ fontSize: 13, fontWeight: 700, color: text }}>— {t.name} <span style={{ fontWeight: 400 }}>· {t.role}</span></p>
|
||
</div>
|
||
))}
|
||
</div>
|
||
))}
|
||
</div>
|
||
</div>
|
||
)}
|
||
|
||
{comps.includes("bento") && (
|
||
<div style={{ padding: "40px 48px 80px", position: "relative", zIndex: 1 }}>
|
||
<div style={{ display: "grid", gridTemplateColumns: "2fr 1fr 1fr", gridTemplateRows: "auto auto", gap: 16 }}>
|
||
<div style={{ padding: "28px", borderRadius: 18, background: card, border: `1px solid ${p}18`, gridRow: "1 / 3", backdropFilter: "blur(4px)" }}>
|
||
<p style={{ fontSize: 13, color: muted, marginBottom: 8, textTransform: "uppercase", letterSpacing: "0.1em" }}>Revenue</p>
|
||
<p style={{ fontSize: 36, fontWeight: 900, color: text, marginBottom: 20, letterSpacing: "-0.02em" }}>$128k MRR</p>
|
||
<svg viewBox="0 0 160 70" style={{ width: "100%", overflow: "visible" }}>
|
||
<defs>
|
||
<linearGradient id="bg-chart" x1="0" y1="0" x2="0" y2="1">
|
||
<stop offset="0%" stopColor={p} stopOpacity="0.5" />
|
||
<stop offset="100%" stopColor={p} stopOpacity="0" />
|
||
</linearGradient>
|
||
</defs>
|
||
<path d="M0,66 C20,58 35,48 55,36 C75,24 90,16 115,10 C135,5 148,3 160,1" stroke={p} strokeWidth="2.5" fill="none" strokeLinecap="round" />
|
||
<path d="M0,66 C20,58 35,48 55,36 C75,24 90,16 115,10 C135,5 148,3 160,1 L160,70 L0,70 Z" fill="url(#bg-chart)" />
|
||
</svg>
|
||
</div>
|
||
<div style={{ padding: "24px", borderRadius: 18, background: card, border: `1px solid ${border}`, backdropFilter: "blur(4px)" }}>
|
||
<p style={{ fontSize: 13, color: muted, marginBottom: 6 }}>Components</p>
|
||
<p style={{ fontSize: 44, fontWeight: 900, color: p, letterSpacing: "-0.02em" }}>100+</p>
|
||
</div>
|
||
<div style={{ padding: "24px", borderRadius: 18, background: `${p}18`, border: `1px solid ${p}30`, backdropFilter: "blur(4px)" }}>
|
||
<p style={{ fontSize: 13, color: muted, marginBottom: 6 }}>Users</p>
|
||
<p style={{ fontSize: 36, fontWeight: 900, color: text, letterSpacing: "-0.02em" }}>120k+</p>
|
||
</div>
|
||
<div style={{ padding: "24px", borderRadius: 18, background: card, border: `1px solid ${border}`, backdropFilter: "blur(4px)", gridColumn: "2 / 4" }}>
|
||
<p style={{ fontSize: 13, color: muted, marginBottom: 6 }}>Uptime</p>
|
||
<p style={{ fontSize: 36, fontWeight: 900, color: text, letterSpacing: "-0.02em" }}>99.99%</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
)}
|
||
|
||
{comps.includes("pricing") && (
|
||
<div style={{ padding: "40px 48px 80px", position: "relative", zIndex: 1 }}>
|
||
<div style={{ display: "flex", gap: 16 }}>
|
||
{[{ plan: "Starter", price: "Free", hi: false }, { plan: "All-Access", price: "$299", hi: true }, { plan: "Team", price: "Custom", hi: false }].map(pl => (
|
||
<div key={pl.plan} style={{ flex: 1, padding: "28px 24px", borderRadius: 18, background: pl.hi ? `linear-gradient(160deg, ${p}30, #3b82f620)` : card, border: `1px solid ${pl.hi ? `${p}55` : border}`, textAlign: "center", backdropFilter: "blur(4px)" }}>
|
||
<p style={{ fontSize: 14, color: pl.hi ? `${p}dd` : muted, marginBottom: 8 }}>{pl.plan}</p>
|
||
<p style={{ fontSize: 42, fontWeight: 900, color: text, letterSpacing: "-0.02em" }}>{pl.price}</p>
|
||
{pl.hi && <div style={{ marginTop: 8, fontSize: 13, color: `${p}aa` }}>lifetime access</div>}
|
||
</div>
|
||
))}
|
||
</div>
|
||
</div>
|
||
)}
|
||
|
||
{comps.includes("cta") && (
|
||
<div style={{ margin: "0 48px 80px", padding: "60px 48px", borderRadius: 20, background: `linear-gradient(135deg, ${p}18, #3b82f614)`, border: `1px solid ${p}28`, textAlign: "center", position: "relative", zIndex: 1, backdropFilter: "blur(6px)" }}>
|
||
<p style={{ fontSize: 42, fontWeight: 900, color: text, marginBottom: 12, letterSpacing: "-0.02em" }}>Start building today</p>
|
||
<p style={{ fontSize: 17, color: muted, marginBottom: 28 }}>Join 120,000+ developers worldwide.</p>
|
||
<button style={{ height: 52, padding: "0 34px", borderRadius: 10, fontSize: 16, fontWeight: 700, color: "#fff", background: `linear-gradient(135deg,${p},#3b82f6)`, border: "none", cursor: "pointer", boxShadow: `0 6px 24px ${p}40` }}>Get All-Access →</button>
|
||
</div>
|
||
)}
|
||
|
||
<div style={{ height: 24 }} />
|
||
</div>
|
||
);
|
||
}
|
||
|
||
// ---------------------------------------------------------------------------
|
||
// HeroUI — polished, premium
|
||
// ---------------------------------------------------------------------------
|
||
|
||
export function MarketingHeroUI({ themeColor, config }: { themeColor?: ThemeColor; config?: DesignConfig }) {
|
||
const theme = themeColor ?? HEROUI_MARKETING_THEMES[0];
|
||
const isDark = config ? config.mode === "dark" : (theme.bg ?? "#fff") === "#09090b";
|
||
|
||
const bg = isDark ? (theme.bg ?? "#09090b") : "#ffffff";
|
||
const text = isDark ? (theme.textColor ?? "#f4f4f5") : "#09090b";
|
||
const muted = isDark ? (theme.mutedText ?? "#71717a") : "#71717a";
|
||
const card = isDark ? (theme.cardBg ?? "#18181b") : "#fafafa";
|
||
const border = isDark ? (theme.borderColor ?? "#27272a") : "#f0f0f0";
|
||
|
||
const bgStyle = config?.background ?? "clean";
|
||
const navStyle = config?.nav ?? "blur";
|
||
const hdrStyle = config?.header ?? "animated-badge";
|
||
const comps = config?.components ?? ["features","metrics"];
|
||
const ff = fontStack(config?.font);
|
||
|
||
const navBlur = navStyle === "blur";
|
||
const navBg = navBlur ? (isDark ? "rgba(9,9,11,0.65)" : "rgba(255,255,255,0.65)") : bg;
|
||
|
||
const heroBgOverlay =
|
||
bgStyle === "gradient-mesh" ? `radial-gradient(ellipse 65% 55% at 20% 40%, ${theme.primary}22, transparent 55%), radial-gradient(ellipse 55% 50% at 80% 65%, #06b6d420, transparent 55%)` :
|
||
bgStyle === "glass" ? `linear-gradient(130deg, ${theme.primary}14, ${isDark ? "#18181b" : "#fff"} 55%)` :
|
||
bgStyle === "aurora" ? `radial-gradient(ellipse 80% 60% at 50% -10%, ${theme.primary}38, transparent 70%)` :
|
||
undefined;
|
||
|
||
return (
|
||
<div style={{ height: "100%", fontFamily: ff, background: bg, overflow: "auto", position: "relative" }}>
|
||
<style>{fontImport(config?.font)}</style>
|
||
{heroBgOverlay && <div style={{ position: "absolute", top: 0, left: 0, right: 0, height: "70%", background: heroBgOverlay, pointerEvents: "none", zIndex: 0 }} />}
|
||
|
||
<nav style={{
|
||
display: "flex", alignItems: "center", justifyContent: "space-between",
|
||
padding: "18px 48px", borderBottom: navStyle === "minimal" ? "none" : `1px solid ${border}`,
|
||
position: "sticky", top: 0, zIndex: 10,
|
||
background: navBg,
|
||
backdropFilter: navBlur ? "blur(16px)" : undefined,
|
||
WebkitBackdropFilter: navBlur ? "blur(16px)" : undefined,
|
||
}}>
|
||
<div style={{ display: "flex", alignItems: "center", gap: 10 }}>
|
||
<div style={{ width: 28, height: 28, borderRadius: "50%", background: theme.primary }} />
|
||
<span style={{ fontWeight: 800, fontSize: 17, color: text, letterSpacing: "-0.01em" }}>Acme</span>
|
||
</div>
|
||
<div style={{ display: "flex", gap: 32, fontSize: 15, color: muted }}>
|
||
{["Features","Pricing","Docs","Blog"].map(i => <span key={i}>{i}</span>)}
|
||
</div>
|
||
<div style={{ display: "flex", gap: 10 }}>
|
||
<button style={{ height: 42, padding: "0 20px", borderRadius: 22, border: `1px solid ${border}`, fontSize: 14, background: "none", color: muted, cursor: "pointer" }}>Login</button>
|
||
<button style={{ height: 42, padding: "0 22px", borderRadius: 22, fontSize: 14, fontWeight: 700, background: theme.primary, color: theme.primaryFg, border: "none", cursor: "pointer", boxShadow: `0 2px 16px ${theme.ring}` }}>Get started</button>
|
||
</div>
|
||
</nav>
|
||
|
||
{hdrStyle === "animated-badge" && (
|
||
<div style={{ padding: "80px 48px 0", textAlign: "center", position: "relative", zIndex: 1 }}>
|
||
<div style={{ display: "inline-flex", alignItems: "center", gap: 9, padding: "7px 20px", borderRadius: 28, fontSize: 13, fontWeight: 600, marginBottom: 28, background: theme.activeBg, color: theme.activeFg, border: `1px solid ${theme.ring}`, boxShadow: `0 0 0 4px ${theme.ring}44` }}>
|
||
🚀 Now in public beta · <span style={{ fontWeight: 800 }}>Join 12k users →</span>
|
||
</div>
|
||
<h1 style={{ fontSize: 76, fontWeight: 900, color: theme.primary, marginBottom: 20, lineHeight: 0.98, letterSpacing: "-0.05em" }}>
|
||
Build faster,<br />ship smarter.
|
||
</h1>
|
||
<p style={{ fontSize: 18, color: muted, maxWidth: 560, margin: "0 auto 32px", lineHeight: 1.75 }}>
|
||
The all-in-one platform for teams that move fast. Deploy in seconds, scale to millions.
|
||
</p>
|
||
<div style={{ display: "flex", gap: 14, justifyContent: "center", marginBottom: 56 }}>
|
||
<button style={{ height: 52, padding: "0 34px", borderRadius: 28, fontSize: 16, fontWeight: 700, background: theme.primary, color: theme.primaryFg, border: "none", cursor: "pointer", boxShadow: `0 6px 28px ${theme.ring}` }}>Start for free</button>
|
||
<button style={{ height: 52, padding: "0 28px", borderRadius: 28, fontSize: 16, background: "none", border: `1px solid ${border}`, color: muted, cursor: "pointer" }}>Live demo →</button>
|
||
</div>
|
||
<DashMockup bg={bg} card={card} border={border} text={text} muted={muted} accent={theme.primary} />
|
||
</div>
|
||
)}
|
||
|
||
{hdrStyle === "split" && (
|
||
<div style={{ display: "flex", gap: 48, padding: "72px 48px 0", alignItems: "flex-start", position: "relative", zIndex: 1 }}>
|
||
<div style={{ flex: "0 0 42%", paddingTop: 14 }}>
|
||
<div style={{ display: "inline-flex", alignItems: "center", gap: 6, padding: "5px 14px", borderRadius: 20, fontSize: 13, fontWeight: 700, marginBottom: 22, background: theme.activeBg, color: theme.activeFg, border: `1px solid ${theme.ring}` }}>🚀 Now in beta</div>
|
||
<h1 style={{ fontSize: 58, fontWeight: 900, color: theme.primary, marginBottom: 18, lineHeight: 1.06, letterSpacing: "-0.04em" }}>
|
||
Build faster,<br />ship smarter.
|
||
</h1>
|
||
<p style={{ fontSize: 17, color: muted, marginBottom: 28, lineHeight: 1.75 }}>The platform for fast-moving teams.</p>
|
||
<div style={{ display: "flex", gap: 12, marginBottom: 36 }}>
|
||
<button style={{ height: 50, padding: "0 28px", borderRadius: 26, fontSize: 15, fontWeight: 700, background: theme.primary, color: theme.primaryFg, border: "none", cursor: "pointer", boxShadow: `0 4px 20px ${theme.ring}` }}>Start free</button>
|
||
<button style={{ height: 50, padding: "0 24px", borderRadius: 26, fontSize: 15, border: `1px solid ${border}`, color: muted, background: "none", cursor: "pointer" }}>Demo →</button>
|
||
</div>
|
||
<div style={{ display: "flex", gap: 32 }}>
|
||
{[["50k+","Teams"],["99.9%","Uptime"]].map(([v,l]) => (
|
||
<div key={l}>
|
||
<p style={{ fontSize: 30, fontWeight: 900, color: theme.primary, letterSpacing: "-0.02em" }}>{v}</p>
|
||
<p style={{ fontSize: 13, color: muted }}>{l}</p>
|
||
</div>
|
||
))}
|
||
</div>
|
||
</div>
|
||
<div style={{ flex: 1, minWidth: 0 }}>
|
||
<DashMockup bg={bg} card={card} border={border} text={text} muted={muted} accent={theme.primary} />
|
||
</div>
|
||
</div>
|
||
)}
|
||
|
||
{hdrStyle === "gradient" && (
|
||
<div style={{ padding: "80px 48px 0", textAlign: "center", position: "relative", zIndex: 1 }}>
|
||
<h1 style={{ fontSize: 76, fontWeight: 900, lineHeight: 0.98, marginBottom: 20, background: `linear-gradient(135deg, ${theme.primary}, ${isDark ? "#06b6d4" : "#7c3aed"})`, WebkitBackgroundClip: "text", WebkitTextFillColor: "transparent", letterSpacing: "-0.05em" }}>
|
||
Build faster.<br />Ship smarter.
|
||
</h1>
|
||
<p style={{ fontSize: 18, color: muted, maxWidth: 500, margin: "0 auto 28px", lineHeight: 1.75 }}>Everything your team needs in one platform.</p>
|
||
<div style={{ display: "flex", gap: 14, justifyContent: "center", marginBottom: 52 }}>
|
||
<button style={{ height: 52, padding: "0 32px", borderRadius: 28, fontSize: 16, fontWeight: 700, background: `linear-gradient(135deg, ${theme.primary}, #06b6d4)`, color: "#fff", border: "none", cursor: "pointer", boxShadow: `0 6px 28px ${theme.ring}` }}>Get started →</button>
|
||
<button style={{ height: 52, padding: "0 26px", borderRadius: 28, fontSize: 16, background: "none", border: `1px solid ${border}`, color: muted, cursor: "pointer" }}>Learn more</button>
|
||
</div>
|
||
<DashMockup bg={bg} card={card} border={border} text={text} muted={muted} accent={theme.primary} />
|
||
</div>
|
||
)}
|
||
|
||
{comps.includes("features") && (
|
||
<div style={{ padding: "80px 48px", position: "relative", zIndex: 1 }}>
|
||
<div style={{ textAlign: "center", marginBottom: 48 }}>
|
||
<h2 style={{ fontSize: 36, fontWeight: 900, color: text, letterSpacing: "-0.02em", marginBottom: 10 }}>Built for what matters</h2>
|
||
<p style={{ fontSize: 16, color: muted }}>Every feature designed around the way modern teams actually work.</p>
|
||
</div>
|
||
<div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 16 }}>
|
||
{[
|
||
{ icon: "bolt", title: "10× faster deploys", desc: "Zero-config CI/CD. Push and ship in under a minute." },
|
||
{ icon: "shield", title: "Zero-trust security", desc: "SOC 2 compliant. End-to-end encryption by default." },
|
||
{ icon: "layers", title: "Any stack", desc: "Node, Python, Go, Rust — we handle all of them." },
|
||
{ icon: "globe", title: "Global CDN", desc: "300+ edge locations. Sub-10ms for every user." },
|
||
].map(f => (
|
||
<div key={f.title} style={{ padding: "24px 26px", borderRadius: 18, background: card, border: `1px solid ${border}`, display: "flex", gap: 20, alignItems: "flex-start", boxShadow: "0 2px 12px rgba(0,0,0,0.05)" }}>
|
||
<div style={{ width: 48, height: 48, borderRadius: 12, background: theme.activeBg, display: "flex", alignItems: "center", justifyContent: "center", flexShrink: 0 }}>
|
||
<Ico d={ICO[f.icon as keyof typeof ICO]} color={theme.primary} size={22} />
|
||
</div>
|
||
<div>
|
||
<p style={{ fontSize: 17, fontWeight: 700, color: text, marginBottom: 6 }}>{f.title}</p>
|
||
<p style={{ fontSize: 14, color: muted, lineHeight: 1.7 }}>{f.desc}</p>
|
||
</div>
|
||
</div>
|
||
))}
|
||
</div>
|
||
</div>
|
||
)}
|
||
|
||
{comps.includes("metrics") && (
|
||
<div style={{ padding: "0 48px 80px", position: "relative", zIndex: 1 }}>
|
||
<div style={{ padding: "28px 32px", borderRadius: 20, border: `1px solid ${border}`, background: card, boxShadow: "0 4px 28px rgba(0,0,0,0.06)" }}>
|
||
<p style={{ fontSize: 13, color: muted, marginBottom: 20, textTransform: "uppercase", letterSpacing: "0.09em", fontWeight: 600 }}>Live metrics</p>
|
||
<div style={{ display: "grid", gridTemplateColumns: "1fr 1fr 1fr 1fr", gap: 14 }}>
|
||
{[["MRR","$128k"],[" Users","24.8k"],["Growth","+34%"],["Churn","1.4%"]].map(([l, v]) => (
|
||
<div key={l} style={{ padding: "18px 20px", borderRadius: 14, background: theme.activeBg, border: `1px solid ${theme.ring}` }}>
|
||
<p style={{ fontSize: 12, color: muted, marginBottom: 5 }}>{l}</p>
|
||
<p style={{ fontSize: 28, fontWeight: 900, color: text, letterSpacing: "-0.02em" }}>{v}</p>
|
||
</div>
|
||
))}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
)}
|
||
|
||
{comps.includes("avatars") && (
|
||
<div style={{ padding: "0 48px 28px", display: "flex", alignItems: "center", gap: 16, position: "relative", zIndex: 1 }}>
|
||
<div style={{ display: "flex" }}>
|
||
{[theme.primary,"#2563eb","#0d9488","#e11d48","#7c3aed"].map((c, i) => (
|
||
<div key={c} style={{ width: 36, height: 36, borderRadius: "50%", background: c, border: `2px solid ${bg}`, marginLeft: i > 0 ? -12 : 0, display: "flex", alignItems: "center", justifyContent: "center" }}>
|
||
<span style={{ color: "#fff", fontSize: 12, fontWeight: 700 }}>{String.fromCharCode(65+i)}</span>
|
||
</div>
|
||
))}
|
||
</div>
|
||
<span style={{ fontSize: 14, color: muted }}><strong style={{ color: text }}>50,000+</strong> teams ship on Acme</span>
|
||
</div>
|
||
)}
|
||
|
||
{comps.includes("pricing") && (
|
||
<div style={{ padding: "0 28px 28px", position: "relative", zIndex: 1 }}>
|
||
<div style={{ display: "flex", gap: 10 }}>
|
||
{[
|
||
{ plan: "Starter", price: "Free", hi: false },
|
||
{ plan: "Pro", price: "$29/mo", hi: true },
|
||
{ plan: "Enterprise", price: "Custom", hi: false },
|
||
].map(pl => (
|
||
<div key={pl.plan} style={{ flex: 1, padding: "16px 14px", borderRadius: 14, background: pl.hi ? theme.primary : card, border: `1px solid ${pl.hi ? "transparent" : border}`, textAlign: "center", boxShadow: pl.hi ? `0 8px 30px ${theme.ring}` : "none" }}>
|
||
<p style={{ fontSize: 9.5, fontWeight: 600, color: pl.hi ? theme.primaryFg : muted, marginBottom: 4 }}>{pl.plan}</p>
|
||
<p style={{ fontSize: 22, fontWeight: 900, color: pl.hi ? theme.primaryFg : text, letterSpacing: "-0.02em" }}>{pl.price}</p>
|
||
{pl.hi && <div style={{ marginTop: 4, fontSize: 8.5, color: `${theme.primaryFg}88` }}>Most popular</div>}
|
||
</div>
|
||
))}
|
||
</div>
|
||
</div>
|
||
)}
|
||
|
||
{comps.includes("testimonials") && (
|
||
<div style={{ padding: "0 28px 28px", position: "relative", zIndex: 1 }}>
|
||
<div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 10 }}>
|
||
{[
|
||
{ q: "\"Shipped 3× faster since switching. Absolute game changer.\"", name: "Sarah K.", role: "CTO" },
|
||
{ q: "\"Cut infrastructure costs by 40%. The ROI was immediate.\"", name: "James R.", role: "Eng Lead" },
|
||
].map(t => (
|
||
<div key={t.name} style={{ padding: "16px 18px", borderRadius: 14, background: card, border: `1px solid ${border}` }}>
|
||
<div style={{ display: "flex", gap: 2, marginBottom: 8 }}>
|
||
{Array(5).fill(0).map((_, i) => <span key={i} style={{ color: "#f59e0b", fontSize: 11 }}>★</span>)}
|
||
</div>
|
||
<p style={{ fontSize: 11, color: text, marginBottom: 12, lineHeight: 1.65, fontStyle: "italic" }}>{t.q}</p>
|
||
<p style={{ fontSize: 10, fontWeight: 700, color: text }}>{t.name} <span style={{ fontWeight: 400, color: muted }}>· {t.role}</span></p>
|
||
</div>
|
||
))}
|
||
</div>
|
||
</div>
|
||
)}
|
||
|
||
{comps.includes("cta") && (
|
||
<div style={{ margin: "0 48px 80px", padding: "60px 48px", borderRadius: 24, background: `linear-gradient(135deg, ${theme.primary}18, ${theme.ring}22)`, border: `1px solid ${theme.ring}`, textAlign: "center", position: "relative", zIndex: 1 }}>
|
||
<h2 style={{ fontSize: 42, fontWeight: 900, color: text, letterSpacing: "-0.02em", marginBottom: 12 }}>Ready to ship faster?</h2>
|
||
<p style={{ fontSize: 17, color: muted, marginBottom: 28 }}>Join 50,000+ teams already on Acme. Free forever.</p>
|
||
<button style={{ height: 52, padding: "0 34px", borderRadius: 28, fontSize: 16, fontWeight: 700, background: theme.primary, color: theme.primaryFg, border: "none", cursor: "pointer", boxShadow: `0 6px 24px ${theme.ring}` }}>Get started free →</button>
|
||
</div>
|
||
)}
|
||
|
||
<div style={{ height: 20 }} />
|
||
</div>
|
||
);
|
||
}
|
||
|
||
// ---------------------------------------------------------------------------
|
||
// Tailwind only — editorial, minimal, typographic
|
||
// ---------------------------------------------------------------------------
|
||
|
||
export function MarketingTailwind({ themeColor, config }: { themeColor?: ThemeColor; config?: DesignConfig }) {
|
||
const isDark = config?.mode === "dark";
|
||
const bgStyle = config?.background ?? "clean";
|
||
const navStyle = config?.nav ?? "minimal";
|
||
const hdrStyle = config?.header ?? "editorial";
|
||
const comps = config?.components ?? ["features","stats","pricing"];
|
||
const ff = fontStack(config?.font);
|
||
|
||
const accent = themeColor?.primary ?? (isDark ? "#f4f4f5" : "#09090b");
|
||
const accentFg = themeColor?.primaryFg ?? (isDark ? "#09090b" : "#fff");
|
||
|
||
const bg = isDark ? "#09090b" : "#fff";
|
||
const text = isDark ? "#f4f4f5" : "#09090b";
|
||
const muted = isDark ? "#71717a" : "#71717a";
|
||
const card = isDark ? "#18181b" : "#f9fafb";
|
||
const border= isDark ? "#27272a" : "#e5e7eb";
|
||
|
||
const useAccent = themeColor?.primary ?? text;
|
||
|
||
return (
|
||
<div style={{ height: "100%", fontFamily: ff, background: bg, overflow: "auto", position: "relative", color: text }}>
|
||
<style>{fontImport(config?.font)}</style>
|
||
{bgStyle === "dot-grid" && (
|
||
<div style={{ position: "absolute", inset: 0, backgroundImage: `radial-gradient(${isDark ? "#ffffff14" : "#00000012"} 1px, transparent 1px)`, backgroundSize: "20px 20px", pointerEvents: "none" }} />
|
||
)}
|
||
{bgStyle === "lines" && (
|
||
<div style={{ position: "absolute", inset: 0, backgroundImage: `linear-gradient(${isDark ? "#ffffff08" : "#00000008"} 1px, transparent 1px), linear-gradient(90deg, ${isDark ? "#ffffff08" : "#00000008"} 1px, transparent 1px)`, backgroundSize: "26px 26px", pointerEvents: "none" }} />
|
||
)}
|
||
|
||
{/* Nav */}
|
||
<nav style={{ display: "flex", alignItems: "center", justifyContent: "space-between", padding: "18px 48px", background: navStyle === "minimal" ? "transparent" : bg, borderBottom: navStyle === "bordered" ? `1px solid ${border}` : "none", position: "relative", zIndex: 2 }}>
|
||
<span style={{ fontWeight: 900, fontSize: 20, color: text, letterSpacing: "-0.03em" }}>acme</span>
|
||
<div style={{ display: "flex", gap: 32, fontSize: 15, color: muted }}>
|
||
{["Features","Pricing","Blog","Docs"].map(i => <span key={i}>{i}</span>)}
|
||
</div>
|
||
<div style={{ display: "flex", gap: 10 }}>
|
||
<button style={{ height: 42, padding: "0 18px", fontSize: 14, color: muted, background: "none", border: "none", cursor: "pointer" }}>Log in</button>
|
||
<button style={{ height: 42, padding: "0 22px", borderRadius: 7, fontSize: 14, fontWeight: 700, background: text, color: bg, border: "none", cursor: "pointer" }}>Sign up</button>
|
||
</div>
|
||
</nav>
|
||
|
||
{hdrStyle === "editorial" && (
|
||
<div style={{ padding: "80px 48px 0", position: "relative", zIndex: 1 }}>
|
||
<div style={{ display: "inline-flex", alignItems: "center", gap: 8, marginBottom: 20 }}>
|
||
<div style={{ width: 8, height: 8, borderRadius: "50%", background: useAccent }} />
|
||
<span style={{ fontSize: 13, fontWeight: 600, color: useAccent, letterSpacing: "0.1em", textTransform: "uppercase" }}>Now in public beta</span>
|
||
</div>
|
||
<h1 style={{ fontSize: 80, fontWeight: 900, color: text, lineHeight: 0.96, letterSpacing: "-0.05em", marginBottom: 22 }}>
|
||
The platform<br />built for scale.
|
||
</h1>
|
||
<p style={{ fontSize: 18, color: muted, maxWidth: 560, marginBottom: 36, lineHeight: 1.75 }}>
|
||
Everything your team needs to build, deploy, and monitor production applications — in one place.
|
||
</p>
|
||
<div style={{ display: "flex", gap: 14, marginBottom: 56 }}>
|
||
<button style={{ height: 52, padding: "0 28px", borderRadius: 8, fontSize: 15, fontWeight: 700, background: text, color: bg, border: "none", cursor: "pointer" }}>Get started free</button>
|
||
<button style={{ height: 52, padding: "0 26px", borderRadius: 8, fontSize: 15, border: `1px solid ${border}`, color: muted, background: "none", cursor: "pointer" }}>Documentation →</button>
|
||
</div>
|
||
{/* Terminal mockup */}
|
||
<div style={{ borderRadius: 14, overflow: "hidden", border: `1px solid ${border}`, boxShadow: isDark ? "0 32px 80px rgba(0,0,0,0.5)" : "0 32px 80px rgba(0,0,0,0.12)", background: isDark ? "#0d0d0d" : "#1e1e1e" }}>
|
||
<div style={{ height: 36, display: "flex", alignItems: "center", gap: 7, padding: "0 16px", background: isDark ? "#161616" : "#2a2a2a", borderBottom: "1px solid rgba(255,255,255,0.08)" }}>
|
||
{["#ff5f56","#ffbd2e","#27c93f"].map((c, i) => <div key={i} style={{ width: 10, height: 10, borderRadius: "50%", background: c }} />)}
|
||
<span style={{ fontSize: 12, color: "rgba(255,255,255,0.35)", marginLeft: 10 }}>bash</span>
|
||
</div>
|
||
<div style={{ padding: "24px 28px", fontFamily: '"JetBrains Mono", "Fira Code", monospace', fontSize: 15, lineHeight: 2.0 }}>
|
||
<div style={{ color: "rgba(255,255,255,0.4)" }}>$ git push origin main</div>
|
||
<div style={{ color: "#4ade80" }}>✓ Build complete <span style={{ color: "rgba(255,255,255,0.35)" }}>(2.1s)</span></div>
|
||
<div style={{ color: "#60a5fa" }}>→ Deploying to production…</div>
|
||
<div style={{ color: "#4ade80" }}>✓ Live at <span style={{ color: "#f472b6" }}>acme.vercel.app</span> <span style={{ color: "rgba(255,255,255,0.35)" }}>(8.4s)</span></div>
|
||
<div style={{ color: "rgba(255,255,255,0.25)", marginTop: 6 }}>$ <span style={{ animation: "ace-cursor 0.85s step-end infinite", display: "inline-block", width: 9, height: 16, background: "rgba(255,255,255,0.5)", verticalAlign: "text-bottom", borderRadius: 1 }} /></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
)}
|
||
|
||
{hdrStyle === "split" && (
|
||
<div style={{ display: "flex", gap: 48, padding: "72px 48px 0", alignItems: "flex-start", position: "relative", zIndex: 1 }}>
|
||
<div style={{ flex: "0 0 45%", paddingTop: 12 }}>
|
||
<div style={{ display: "inline-flex", alignItems: "center", gap: 7, marginBottom: 20 }}>
|
||
<div style={{ width: 7, height: 7, borderRadius: "50%", background: useAccent }} />
|
||
<span style={{ fontSize: 13, fontWeight: 600, color: useAccent, letterSpacing: "0.1em", textTransform: "uppercase" }}>Public beta</span>
|
||
</div>
|
||
<h1 style={{ fontSize: 60, fontWeight: 900, color: text, lineHeight: 1.03, letterSpacing: "-0.045em", marginBottom: 18 }}>The platform<br />built for scale.</h1>
|
||
<p style={{ fontSize: 17, color: muted, marginBottom: 28, lineHeight: 1.75 }}>Deploy anywhere. Monitor everything. Sleep soundly.</p>
|
||
<div style={{ display: "flex", gap: 12 }}>
|
||
<button style={{ height: 50, padding: "0 26px", borderRadius: 8, fontSize: 15, fontWeight: 700, background: text, color: bg, border: "none", cursor: "pointer" }}>Get started</button>
|
||
<button style={{ height: 50, padding: "0 22px", borderRadius: 8, fontSize: 15, border: `1px solid ${border}`, color: muted, background: "none", cursor: "pointer" }}>Docs →</button>
|
||
</div>
|
||
</div>
|
||
<div style={{ flex: 1, minWidth: 0 }}>
|
||
<div style={{ borderRadius: 14, overflow: "hidden", border: `1px solid ${border}`, background: "#1e1e1e" }}>
|
||
<div style={{ height: 34, display: "flex", alignItems: "center", gap: 6, padding: "0 14px", background: "#2a2a2a", borderBottom: "1px solid rgba(255,255,255,0.08)" }}>
|
||
{["#ff5f56","#ffbd2e","#27c93f"].map((c, i) => <div key={i} style={{ width: 9, height: 9, borderRadius: "50%", background: c }} />)}
|
||
</div>
|
||
<div style={{ padding: "20px 24px", fontFamily: '"JetBrains Mono", monospace', fontSize: 14, lineHeight: 2.0 }}>
|
||
<div style={{ color: "rgba(255,255,255,0.4)" }}>$ git push origin main</div>
|
||
<div style={{ color: "#4ade80" }}>✓ Build complete (2.1s)</div>
|
||
<div style={{ color: "#60a5fa" }}>→ Deploying to prod…</div>
|
||
<div style={{ color: "#4ade80" }}>✓ Live at acme.app (8s)</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
)}
|
||
|
||
{hdrStyle === "centered" && (
|
||
<div style={{ padding: "80px 48px 0", textAlign: "center", position: "relative", zIndex: 1 }}>
|
||
<h1 style={{ fontSize: 80, fontWeight: 900, color: text, lineHeight: 0.96, letterSpacing: "-0.05em", marginBottom: 20 }}>
|
||
The platform<br />built for scale.
|
||
</h1>
|
||
<p style={{ fontSize: 18, color: muted, maxWidth: 480, margin: "0 auto 32px", lineHeight: 1.75 }}>Everything your team needs.</p>
|
||
<button style={{ height: 52, padding: "0 32px", borderRadius: 8, fontSize: 16, fontWeight: 700, background: text, color: bg, border: "none", cursor: "pointer" }}>Get started free →</button>
|
||
</div>
|
||
)}
|
||
|
||
{/* Sections */}
|
||
{comps.includes("badge") && (
|
||
<div style={{ padding: "20px 48px 0", position: "relative", zIndex: 1 }}>
|
||
<span style={{ display: "inline-block", padding: "6px 16px", borderRadius: 6, fontSize: 14, background: `${useAccent}12`, color: useAccent, fontWeight: 600 }}>→ v2.0 released — see what is new</span>
|
||
</div>
|
||
)}
|
||
|
||
{comps.includes("logos") && (
|
||
<div style={{ padding: "24px 48px", display: "flex", alignItems: "center", gap: 28, borderTop: `1px solid ${border}`, borderBottom: `1px solid ${border}`, background: card, position: "relative", zIndex: 1, marginTop: 48 }}>
|
||
<span style={{ fontSize: 13, color: muted, flexShrink: 0 }}>Trusted by</span>
|
||
{["Vercel","Stripe","Linear","Notion","Supabase","Raycast"].map(b => (
|
||
<span key={b} style={{ fontSize: 14, fontWeight: 800, color: muted, opacity: 0.4, whiteSpace: "nowrap" }}>{b}</span>
|
||
))}
|
||
</div>
|
||
)}
|
||
|
||
{comps.includes("features") && (
|
||
<div style={{ padding: "80px 48px", position: "relative", zIndex: 1 }}>
|
||
<h2 style={{ fontSize: 36, fontWeight: 900, color: text, letterSpacing: "-0.02em", marginBottom: 32 }}>Everything you need.</h2>
|
||
<div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 16 }}>
|
||
{[
|
||
{ icon: "bolt", title: "99.9% uptime SLA", desc: "We guarantee it. Backed by automatic service credits." },
|
||
{ icon: "shield", title: "SOC 2 compliant", desc: "Enterprise-grade security, privacy by default." },
|
||
{ icon: "trend", title: "10ms avg latency", desc: "Edge-first network. Fast for every user, everywhere." },
|
||
{ icon: "globe", title: "GDPR ready", desc: "Full data residency controls and audit trail." },
|
||
{ icon: "code", title: "Any stack", desc: "Node, Python, Go, Rust, Ruby — we deploy everything." },
|
||
{ icon: "layers", title: "Instant rollbacks", desc: "One click to revert. Zero-downtime deployments." },
|
||
].map(f => (
|
||
<div key={f.title} style={{ display: "flex", gap: 18, padding: "20px 22px", borderRadius: 12, background: card, border: `1px solid ${border}` }}>
|
||
<div style={{ width: 42, height: 42, borderRadius: 10, background: border, display: "flex", alignItems: "center", justifyContent: "center", flexShrink: 0 }}>
|
||
<Ico d={ICO[f.icon as keyof typeof ICO]} color={text} size={20} />
|
||
</div>
|
||
<div>
|
||
<p style={{ fontSize: 16, fontWeight: 700, color: text, marginBottom: 5 }}>{f.title}</p>
|
||
<p style={{ fontSize: 14, color: muted, lineHeight: 1.7 }}>{f.desc}</p>
|
||
</div>
|
||
</div>
|
||
))}
|
||
</div>
|
||
</div>
|
||
)}
|
||
|
||
{comps.includes("stats") && (
|
||
<div style={{ padding: "0 48px 80px", position: "relative", zIndex: 1 }}>
|
||
<div style={{ display: "flex", borderRadius: 14, overflow: "hidden", border: `1px solid ${border}` }}>
|
||
{[["50k+","Teams"],["99.9%","Uptime"],["10ms","Latency"],["$0","To start"]].map(([v,l], i) => (
|
||
<div key={l} style={{ flex: 1, textAlign: "center", padding: "28px 12px", borderRight: i < 3 ? `1px solid ${border}` : "none", background: i % 2 === 0 ? card : bg }}>
|
||
<p style={{ fontSize: 36, fontWeight: 900, color: text, letterSpacing: "-0.03em", lineHeight: 1.1 }}>{v}</p>
|
||
<p style={{ fontSize: 13, color: muted, marginTop: 5 }}>{l}</p>
|
||
</div>
|
||
))}
|
||
</div>
|
||
</div>
|
||
)}
|
||
|
||
{comps.includes("testimonials") && (
|
||
<div style={{ padding: "0 48px 80px", position: "relative", zIndex: 1 }}>
|
||
<div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 16 }}>
|
||
{[
|
||
{ q: "\"Shipped 3× faster since switching. Zero regrets.\"", name: "Sarah K.", role: "CTO" },
|
||
{ q: "\"Cut infra costs by 40% in our first month.\"", name: "James R.", role: "Eng Lead" },
|
||
].map(t => (
|
||
<div key={t.name} style={{ padding: "24px 26px", borderRadius: 14, background: card, border: `1px solid ${border}` }}>
|
||
<div style={{ display: "flex", gap: 3, marginBottom: 14 }}>
|
||
{Array(5).fill(0).map((_, i) => <span key={i} style={{ color: "#f59e0b", fontSize: 16 }}>★</span>)}
|
||
</div>
|
||
<p style={{ fontSize: 16, color: text, marginBottom: 14, lineHeight: 1.7, fontStyle: "italic" }}>{t.q}</p>
|
||
<p style={{ fontSize: 14, fontWeight: 700, color: text }}>{t.name} <span style={{ fontWeight: 400, color: muted }}>· {t.role}</span></p>
|
||
</div>
|
||
))}
|
||
</div>
|
||
</div>
|
||
)}
|
||
|
||
{comps.includes("pricing") && (
|
||
<div style={{ padding: "0 48px 80px", position: "relative", zIndex: 1 }}>
|
||
<h2 style={{ fontSize: 36, fontWeight: 900, color: text, letterSpacing: "-0.02em", marginBottom: 28 }}>Simple pricing.</h2>
|
||
<div style={{ display: "flex", gap: 16 }}>
|
||
{[
|
||
{ plan: "Starter", price: "Free", period: "forever", hi: false, features: ["5 projects","100 deploys/mo","Community support"] },
|
||
{ plan: "Pro", price: "$29", period: "/month", hi: true, features: ["Unlimited projects","Unlimited deploys","Priority support","Custom domains","Team members"] },
|
||
{ plan: "Enterprise", price: "Custom", period: "", hi: false, features: ["Everything in Pro","SLA guarantee","SSO/SAML","Dedicated support"] },
|
||
].map(pl => (
|
||
<div key={pl.plan} style={{ flex: 1, padding: "28px 26px", borderRadius: 16, background: pl.hi ? text : card, border: `1px solid ${pl.hi ? "transparent" : border}` }}>
|
||
<p style={{ fontSize: 14, fontWeight: 600, color: pl.hi ? bg : muted, marginBottom: 6 }}>{pl.plan}</p>
|
||
<p style={{ fontSize: 42, fontWeight: 900, color: pl.hi ? bg : text, letterSpacing: "-0.03em", lineHeight: 1.1 }}>{pl.price}</p>
|
||
<p style={{ fontSize: 13, color: pl.hi ? `${bg}88` : muted, marginBottom: 22 }}>{pl.period}</p>
|
||
<div style={{ display: "flex", flexDirection: "column", gap: 10 }}>
|
||
{pl.features.map(f => (
|
||
<div key={f} style={{ display: "flex", alignItems: "center", gap: 10 }}>
|
||
<svg viewBox="0 0 10 10" fill="none" style={{ width: 12, height: 12, flexShrink: 0 }}>
|
||
<path d="M2 5l2 2 4-4" stroke={pl.hi ? bg : text} strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
|
||
</svg>
|
||
<span style={{ fontSize: 14, color: pl.hi ? `${bg}cc` : muted }}>{f}</span>
|
||
</div>
|
||
))}
|
||
</div>
|
||
</div>
|
||
))}
|
||
</div>
|
||
</div>
|
||
)}
|
||
|
||
{comps.includes("faq") && (
|
||
<div style={{ padding: "0 48px 80px", position: "relative", zIndex: 1 }}>
|
||
<h2 style={{ fontSize: 32, fontWeight: 900, color: text, letterSpacing: "-0.02em", marginBottom: 22 }}>FAQ</h2>
|
||
{[
|
||
["What's included in free?","5 projects, 100 deploys/month, community support, and basic analytics."],
|
||
["Can I upgrade anytime?","Yes. Changes are immediate. We prorate everything automatically."],
|
||
["Do you offer team plans?","Yes — add members and manage billing centrally on any paid plan."],
|
||
].map(([q, a], i) => (
|
||
<div key={q} style={{ padding: "20px 0", borderBottom: `1px solid ${border}` }}>
|
||
<div style={{ display: "flex", justifyContent: "space-between" }}>
|
||
<p style={{ fontSize: 16, fontWeight: 600, color: text }}>{q}</p>
|
||
<span style={{ fontSize: 22, color: muted }}>{i === 0 ? "−" : "+"}</span>
|
||
</div>
|
||
{i === 0 && <p style={{ fontSize: 15, color: muted, marginTop: 12, lineHeight: 1.75 }}>{a}</p>}
|
||
</div>
|
||
))}
|
||
</div>
|
||
)}
|
||
|
||
{comps.includes("cta") && (
|
||
<div style={{ margin: "0 48px 80px", padding: "60px 48px", borderRadius: 16, background: text, textAlign: "center", position: "relative", zIndex: 1 }}>
|
||
<h2 style={{ fontSize: 42, fontWeight: 900, color: bg, letterSpacing: "-0.02em", marginBottom: 12 }}>Ready to ship faster?</h2>
|
||
<p style={{ fontSize: 17, color: isDark ? "#6b7280" : "#9ca3af", marginBottom: 28 }}>Join 50,000+ teams already building on Acme. Free forever.</p>
|
||
<button style={{ height: 52, padding: "0 32px", borderRadius: 8, fontSize: 15, fontWeight: 700, background: bg, color: text, border: "none", cursor: "pointer" }}>Get started free →</button>
|
||
</div>
|
||
)}
|
||
|
||
<div style={{ height: 24 }} />
|
||
</div>
|
||
);
|
||
}
|
||
|
||
export { DAISY_THEMES, HEROUI_MARKETING_THEMES, ACETERNITY_THEMES };
|