From e79c2fe5c51341844effec04829cb3cb95c96e1f Mon Sep 17 00:00:00 2001 From: Mark Henderson Date: Thu, 5 Mar 2026 20:55:21 -0800 Subject: [PATCH] Upgrade marketing scaffolds: real CSS animations, 18 DaisyUI themes, Aceternity accents MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - MarketingAceternity: animated gradient blobs (mix-blend-mode hard-light), meteor streaks, sparkle dots, CSS marquee testimonials, lamp cone, typewriter cursor, bento grid — all using namespaced CSS keyframes - MarketingDaisy: DaisyUI-style layouts (split hero with mockup, stats hero, step guide), testimonials, FAQ accordion, logo strip; full 18-theme palette - MarketingHeroUI: blur backdrop nav, gradient-mesh/glass/aurora backgrounds, metric cards with active-bg tint, avatar stack, glassmorphism cards - MarketingTailwind: editorial typography, dot-grid/lines backgrounds, terminal deploy mockup, checklist features, stats bar, high-contrast CTA - types.ts: expanded DAISY_THEMES to 18 themes (cyberpunk, halloween, valentine, aqua, luxury, night, coffee, nord, dim, sunset); added ACETERNITY_THEMES palette - index.ts: export ACETERNITY_THEMES, wire aceternity + tailwind-only into THEME_REGISTRY Made-with: Cursor --- components/design-scaffolds/index.ts | 10 +- components/design-scaffolds/marketing.tsx | 913 ++++++++++++---------- components/design-scaffolds/types.ts | 35 +- 3 files changed, 528 insertions(+), 430 deletions(-) diff --git a/components/design-scaffolds/index.ts b/components/design-scaffolds/index.ts index e10582f..59cfad9 100644 --- a/components/design-scaffolds/index.ts +++ b/components/design-scaffolds/index.ts @@ -11,7 +11,7 @@ export type { ThemeColor, DesignConfig, StyleOption, LibraryStyleOptions } from "./types"; export { SHADCN_THEMES, MANTINE_THEMES, HEROUI_THEMES, TREMOR_THEMES, - DAISY_THEMES, HEROUI_MARKETING_THEMES, + DAISY_THEMES, HEROUI_MARKETING_THEMES, ACETERNITY_THEMES, } from "./types"; import { WebAppShadcn, WebAppMantine, WebAppHeroUI, WebAppTremor } from "./web-app"; @@ -24,7 +24,7 @@ import { DocsNextra, DocsShadcnCustom } from "./docs"; import type { ThemeColor, DesignConfig } from "./types"; import { SHADCN_THEMES, MANTINE_THEMES, HEROUI_THEMES, TREMOR_THEMES, - DAISY_THEMES, HEROUI_MARKETING_THEMES, + DAISY_THEMES, HEROUI_MARKETING_THEMES, ACETERNITY_THEMES, } from "./types"; // --------------------------------------------------------------------------- @@ -74,8 +74,10 @@ export const THEME_REGISTRY: Record> = { tremor: TREMOR_THEMES, }, "marketing": { - "daisy-ui": DAISY_THEMES, - "hero-ui": HEROUI_MARKETING_THEMES, + "daisy-ui": DAISY_THEMES, + "hero-ui": HEROUI_MARKETING_THEMES, + "aceternity": ACETERNITY_THEMES, + "tailwind-only": SHADCN_THEMES, }, "admin": { mantine: MANTINE_THEMES, diff --git a/components/design-scaffolds/marketing.tsx b/components/design-scaffolds/marketing.tsx index e81f4fc..407290c 100644 --- a/components/design-scaffolds/marketing.tsx +++ b/components/design-scaffolds/marketing.tsx @@ -1,10 +1,6 @@ "use client"; -import { ThemeColor, DesignConfig, DAISY_THEMES, HEROUI_MARKETING_THEMES } from "./types"; - -// Marketing Site surface — public-facing pages: hero, features, pricing, CTA -// Context: prospective users discovering the product, not signed-in users. -// All components accept a DesignConfig to drive live preview changes. +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'; @@ -15,19 +11,338 @@ function fontStack(font?: string) { return "system-ui, sans-serif"; } +// CSS keyframes injected once per component render (scoped names prevent conflicts) +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); opacity: 0.8; } + 100% { transform: translateX(-180px) translateY(180px); 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); } + } +`; + +// --------------------------------------------------------------------------- +// Aceternity UI +// --------------------------------------------------------------------------- + +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 bg = isDark ? "#050010" : "#fafafa"; + const text = isDark ? "#fff" : "#0f172a"; + const muted = isDark ? "rgba(255,255,255,0.38)" : "#64748b"; + const card = isDark ? "rgba(255,255,255,0.035)" : "rgba(0,0,0,0.03)"; + const border= isDark ? "rgba(255,255,255,0.07)" : "rgba(0,0,0,0.08)"; + + // ── Background layers ────────────────────────────────────────────────────── + const BgLayer = () => { + if (bgStyle === "gradient") return ( +
+
+
+
+
+
+
+
+ ); + if (bgStyle === "beams") return ( +
+
+ {Array.from({ length: 10 }).map((_, i) => ( +
+ ))} +
+ ); + if (bgStyle === "meteors") return ( +
+
+ {Array.from({ length: 8 }).map((_, i) => ( +
+ ))} +
+ ); + if (bgStyle === "sparkles") return ( +
+ {Array.from({ length: 28 }).map((_, i) => ( +
+ ))} +
+ ); + if (bgStyle === "wavy") return ( +
+ + + + + + + + + + + +
+ ); + if (bgStyle === "dot-grid") return ( +
+ ); + // gradient fallback + return
; + }; + + const floatingNav = navStyle === "floating"; + + return ( +
+ + + + {/* Nav */} + {floatingNav ? ( +
+ +
+ ) : ( + + )} + + {/* Hero */} + {hdrStyle === "gradient-text" && ( +
+
+ ✦ Open source · 12k GitHub stars +
+

+ Build the future
of the web +

+

+ Beautifully crafted components built with Tailwind CSS and Framer Motion. +

+
+ + +
+
+ )} + + {hdrStyle === "lamp" && ( +
+ {/* Lamp cone */} +
+
+

Build the future
of the web

+

Powered by Framer Motion and Tailwind CSS.

+ +
+ )} + + {hdrStyle === "typewriter" && ( +
+
The future is here
+

+ Build the future
+ of the web + +

+

Components that bring ideas to life.

+ +
+ )} + + {/* Sections */} + {comps.includes("badge") && ( +
+ ✦ v2.0 just shipped — see what's new → +
+ )} + + {comps.includes("features") && ( +
+ {[{ label: "Animated", icon: "✦", c: p }, { label: "Accessible", icon: "◎", c: "#3b82f6" }, { label: "Open source", icon: "⬡", c: "#22c55e" }].map(f => ( +
+
{f.icon}
+

{f.label}

+

Built for production

+
+ ))} +
+ )} + + {comps.includes("moving-cards") && ( +
+

Trusted by developers worldwide

+
+ {[...Array(2)].map((_, pass) => ( +
+ {[ + { text: "\"Game changer for our team.\"", name: "Sarah K.", role: "CTO" }, + { text: "\"Ships 3× faster than before.\"", name: "James R.", role: "Eng Lead" }, + { text: "\"Zero-config deploys.\"", name: "Mia L.", role: "Founder" }, + { text: "\"Best DX I've ever had.\"", name: "Tom W.", role: "Developer" }, + ].map(t => ( +
+

{t.text}

+

— {t.name} · {t.role}

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

Analytics

+

$128k MRR

+
+ + + + + + + + + + +
+
+
+

Deploys

+

+
+
+

Uptime

+

99.9%

+
+
+
+ )} + + {comps.includes("pricing") && ( +
+
+ {[{ plan: "Starter", price: "Free", hi: false }, { plan: "Pro", price: "$29/mo", hi: true }, { plan: "Enterprise", price: "Custom", hi: false }].map(pl => ( +
+

{pl.plan}

+

{pl.price}

+ {pl.hi &&
Most popular
} +
+ ))} +
+
+ )} + + {comps.includes("cta") && ( +
+

Start building today

+

Join thousands of developers worldwide.

+ +
+ )} + +
+
+ ); +} + // --------------------------------------------------------------------------- // DaisyUI // --------------------------------------------------------------------------- export function MarketingDaisy({ themeColor, config }: { themeColor?: ThemeColor; config?: DesignConfig }) { - const theme = themeColor ?? DAISY_THEMES[0]; + 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 ?? "#a6adba") : (theme.textColor ?? "#1f2937"); + const text = isDark ? (theme.textColor ?? "#a6adba") : (theme.textColor ?? "#1f2937"); const muted = isDark ? (theme.mutedText ?? "rgba(255,255,255,0.4)") : (theme.mutedText ?? "#6b7280"); const card = isDark ? (theme.cardBg ?? "rgba(255,255,255,0.04)") : (theme.cardBg ?? "#f9fafb"); - const border = isDark ? (theme.borderColor ?? "rgba(255,255,255,0.08)") : (theme.borderColor ?? "#e5e7eb"); + const border = isDark ? (theme.borderColor ?? "rgba(255,255,255,0.09)") : (theme.borderColor ?? "#e5e7eb"); const bgStyle = config?.background ?? "solid"; const navStyle = config?.nav ?? "standard"; @@ -35,51 +350,39 @@ export function MarketingDaisy({ themeColor, config }: { themeColor?: ThemeColor const comps = config?.components ?? ["features", "pricing"]; const ff = fontStack(config?.font); - // Background overlay applied to the hero area const heroBgLayer = - bgStyle === "gradient" ? `radial-gradient(ellipse 80% 55% at 50% -5%, ${theme.primary}40, transparent)` : - bgStyle === "pattern" ? undefined : // handled as a full-page layer - bgStyle === "noise" ? undefined : - undefined; - - const navBg = navStyle === "transparent" ? "transparent" : bg; - const navBorderB = navStyle === "transparent" ? "none" : `1px solid ${border}`; - - const pillNav = navStyle === "pill"; - - const NavContent = () => ( - <> -
-
- Acme -
-
- {["Features", "Pricing", "Docs", "Blog"].map(i => {i})} -
-
- - -
- - ); + bgStyle === "gradient" ? `radial-gradient(ellipse 80% 55% at 50% -5%, ${theme.primary}45, transparent)` : + bgStyle === "noise" ? "none" : "none"; return (
- {/* Dot-pattern full-page overlay */} - {bgStyle === "pattern" && ( -
- )} + {bgStyle === "pattern" &&
} {/* Nav */} - {pillNav ? ( -
-