Add Lines Gradient Shader + fix Aurora/Sparkles/Meteors to match real Aceternity visuals

- New 'shader' background: bold diagonal purple→pink→orange→yellow gradient
  with subtle repeating line overlay (mirrors ui.aceternity.com lines-gradient-shader)
- Aurora background: now renders on light bg (#f8f9ff) with soft lavender/blue blurs
- Sparkles: forces black base with white star particles and glow box-shadow
- Meteors: horizontal streaks with glow, animate diagonally like shooting stars
- Beams: switched to SVG lines radiating from a central vanishing point
- Auto-adapt text/nav colours for forced-dark (shader, sparkles) and forced-light (aurora)
- LIBRARY_STYLE_OPTIONS: 8 Aceternity background options, default changed to gradient

Made-with: Cursor
This commit is contained in:
2026-03-05 21:08:14 -08:00
parent e79c2fe5c5
commit e95761cc61
2 changed files with 101 additions and 49 deletions

View File

@@ -32,8 +32,9 @@ const ACE_KEYFRAMES = `
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; }
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); }
@@ -70,14 +71,20 @@ export function MarketingAceternity({ themeColor, config }: { themeColor?: Theme
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)";
// sparkles forces black; aurora forces light; shader always dark-text-over-vibrant
const forcedDark = bgStyle === "sparkles" || bgStyle === "shader";
const forcedLight = bgStyle === "aurora";
const effectiveDark = forcedDark ? true : forcedLight ? false : isDark;
const bg = forcedDark ? "#000" : forcedLight ? "#f8f9ff" : isDark ? "#050010" : "#fafafa";
const text = effectiveDark ? "#fff" : "#0f172a";
const muted = effectiveDark ? "rgba(255,255,255,0.38)" : "#64748b";
const card = effectiveDark ? "rgba(255,255,255,0.035)" : "rgba(0,0,0,0.03)";
const border= effectiveDark ? "rgba(255,255,255,0.07)" : "rgba(0,0,0,0.08)";
// ── Background layers ──────────────────────────────────────────────────────
const BgLayer = () => {
// Animated gradient blobs — mirrors Aceternity's Background Gradient Animation
if (bgStyle === "gradient") return (
<div style={{ position: "absolute", inset: 0, overflow: "hidden", zIndex: 0, background: isDark ? "rgb(8,0,20)" : "rgb(240,235,255)" }}>
<div style={{ position: "absolute", inset: 0, filter: "blur(50px)", mixBlendMode: isDark ? "hard-light" : "multiply" }}>
@@ -88,51 +95,95 @@ export function MarketingAceternity({ themeColor, config }: { themeColor?: Theme
</div>
</div>
);
if (bgStyle === "beams") return (
<div style={{ position: "absolute", inset: 0, overflow: "hidden", zIndex: 0 }}>
<div style={{ position: "absolute", inset: 0, background: `radial-gradient(ellipse 70% 45% at 50% 0%, ${p}18, transparent)` }} />
{Array.from({ length: 10 }).map((_, i) => (
<div key={i} style={{
position: "absolute", top: 0, bottom: 0, width: 1,
left: `${6 + i * 10}%`,
background: `linear-gradient(180deg, transparent 0%, ${i % 3 === 0 ? p : i % 3 === 1 ? "#3b82f6" : "#06b6d4"}${i % 2 === 0 ? "22" : "14"} 40%, transparent 100%)`,
animation: `ace-beam-pulse ${3 + i * 0.4}s ease-in-out ${i * 0.3}s infinite`,
}} />
))}
// Lines Gradient Shader — bold diagonal rainbow band: purple→pink→orange→yellow
if (bgStyle === "shader") return (
<div style={{ position: "absolute", inset: 0, overflow: "hidden", zIndex: 0, background: isDark ? "#09090b" : "#fafafa" }}>
{/* Diagonal gradient band */}
<div style={{ position: "absolute", inset: 0, background: "linear-gradient(135deg, #7c3aed 0%, #db2777 35%, #ea580c 65%, #ca8a04 100%)", opacity: isDark ? 0.9 : 0.85 }} />
{/* Subtle line overlay */}
<div style={{ position: "absolute", inset: 0, backgroundImage: "repeating-linear-gradient(135deg, transparent 0px, transparent 12px, rgba(255,255,255,0.04) 12px, rgba(255,255,255,0.04) 13px)", pointerEvents: "none" }} />
{/* Soft vignette */}
<div style={{ position: "absolute", inset: 0, background: "radial-gradient(ellipse 80% 80% at 50% 50%, transparent 40%, rgba(0,0,0,0.35) 100%)", pointerEvents: "none" }} />
</div>
);
// Background Beams — SVG-style radial beams on dark bg
if (bgStyle === "beams") return (
<div style={{ position: "absolute", inset: 0, overflow: "hidden", zIndex: 0 }}>
<svg style={{ position: "absolute", inset: 0, width: "100%", height: "100%" }} viewBox="0 0 400 600" preserveAspectRatio="xMidYMid slice">
<defs>
<radialGradient id="beam-glow" cx="50%" cy="0%" r="70%">
<stop offset="0%" stopColor={p} stopOpacity="0.18" />
<stop offset="100%" stopColor={p} stopOpacity="0" />
</radialGradient>
</defs>
<rect width="400" height="600" fill="url(#beam-glow)" />
{Array.from({ length: 12 }).map((_, i) => {
const x = 200 + (i - 6) * 34;
return (
<line key={i} x1={200} y1={0} x2={x} y2={600}
stroke={i % 3 === 0 ? p : i % 3 === 1 ? "#3b82f6" : "#06b6d4"}
strokeWidth={i % 4 === 0 ? 0.6 : 0.3}
strokeOpacity={0.12 + (i % 3) * 0.04}
style={{ animation: `ace-beam-pulse ${3 + i * 0.5}s ease-in-out ${i * 0.25}s infinite` }}
/>
);
})}
</svg>
</div>
);
// Meteors — diagonal shooting-star streaks with glow tails
if (bgStyle === "meteors") return (
<div style={{ position: "absolute", inset: 0, overflow: "hidden", zIndex: 0 }}>
<div style={{ position: "absolute", inset: 0, background: `radial-gradient(ellipse 60% 40% at 50% 0%, ${p}15, transparent)` }} />
{Array.from({ length: 8 }).map((_, i) => (
{Array.from({ length: 12 }).map((_, i) => (
<div key={i} style={{
position: "absolute",
top: `${(i * 40) % 70}%`,
left: `${15 + i * 12}%`,
width: 1, height: `${24 + i * 6}px`,
background: `linear-gradient(180deg, transparent, ${p}cc, transparent)`,
transform: "rotate(-45deg)",
animation: `ace-meteor ${1.5 + i * 0.4}s linear ${i * 0.7}s infinite`,
opacity: 0,
}} />
))}
</div>
);
if (bgStyle === "sparkles") return (
<div style={{ position: "absolute", inset: 0, overflow: "hidden", zIndex: 0 }}>
{Array.from({ length: 28 }).map((_, i) => (
<div key={i} style={{
position: "absolute",
width: i % 4 === 0 ? 3 : 2, height: i % 4 === 0 ? 3 : 2,
top: `${(i * 31 + 5) % 65}%`,
right: `${(i * 47) % 90}%`,
width: `${36 + i * 8}px`, height: "1px",
background: `linear-gradient(90deg, ${p}ee, rgba(255,255,255,0.7), transparent)`,
transform: "rotate(-35deg)",
animation: `ace-meteor ${1.2 + (i % 5) * 0.5}s linear ${i * 0.55}s infinite`,
borderRadius: "50%",
background: [p, "#3b82f6", "#06b6d4", "#a855f7"][i % 4],
top: `${(i * 37 + 5) % 88}%`,
left: `${(i * 53 + 3) % 92}%`,
animation: `ace-sparkle ${1.8 + (i % 5) * 0.4}s ease-in-out ${(i * 0.25) % 2}s infinite`,
boxShadow: `0 0 4px ${p}80`,
}} />
))}
</div>
);
// Sparkles — true black bg with small twinkling star particles
if (bgStyle === "sparkles") return (
<div style={{ position: "absolute", inset: 0, overflow: "hidden", zIndex: 0, background: "#000" }}>
{Array.from({ length: 40 }).map((_, i) => {
const size = i % 6 === 0 ? 3 : i % 3 === 0 ? 2 : 1.5;
return (
<div key={i} style={{
position: "absolute",
width: size, height: size,
borderRadius: "50%",
background: "#fff",
boxShadow: `0 0 ${size * 2}px ${i % 4 === 0 ? p : "rgba(255,255,255,0.8)"}`,
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>
);
// Aurora — soft lavender/blue glow on a LIGHT background (matches Aceternity's Aurora)
if (bgStyle === "aurora") return (
<div style={{ position: "absolute", inset: 0, overflow: "hidden", zIndex: 0, background: "#f8f9ff" }}>
<div style={{ position: "absolute", top: "-30%", left: "-10%", width: "70%", height: "70%", borderRadius: "50%", background: "radial-gradient(circle, rgba(196,181,253,0.55) 0%, transparent 65%)", filter: "blur(40px)", animation: "ace-blob1 18s ease infinite" }} />
<div style={{ position: "absolute", top: "-20%", right: "-5%", width: "60%", height: "60%", borderRadius: "50%", background: "radial-gradient(circle, rgba(147,197,253,0.45) 0%, transparent 65%)", filter: "blur(40px)", animation: "ace-blob2 22s reverse infinite" }} />
<div style={{ position: "absolute", top: "20%", left: "30%", width: "50%", height: "50%", borderRadius: "50%", background: "radial-gradient(circle, rgba(216,180,254,0.35) 0%, transparent 65%)", filter: "blur(40px)", animation: "ace-blob3 26s 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%" }}>
@@ -151,7 +202,6 @@ export function MarketingAceternity({ themeColor, config }: { themeColor?: Theme
if (bgStyle === "dot-grid") return (
<div style={{ position: "absolute", inset: 0, zIndex: 0, backgroundImage: `radial-gradient(${p}28 1px, transparent 1px)`, backgroundSize: "20px 20px" }} />
);
// gradient fallback
return <div style={{ position: "absolute", inset: 0, background: `radial-gradient(ellipse 70% 50% at 50% 0%, ${p}18, transparent)`, zIndex: 0 }} />;
};