Custom CTA-Buttons: Sparkle/Demo-Button, blauer Primary-Button mit Text-Animation, einheitlicher Stil für alle blauen Buttons

This commit is contained in:
Basilosaurusrex
2026-02-02 09:29:37 +01:00
parent 22d641e4e5
commit 01102ef3f7
8 changed files with 954 additions and 312 deletions

View File

@@ -42,7 +42,6 @@ const Header = () => {
<NavbarButton
as="span"
variant="primary"
className="!text-black"
>
Kontakt
</NavbarButton>
@@ -86,7 +85,7 @@ const Header = () => {
<NavbarButton
as="span"
variant="primary"
className="block w-full text-center !text-black"
className="block w-full text-center"
>
Kontakt
</NavbarButton>

View File

@@ -1,12 +1,34 @@
import { Link } from "react-router-dom";
import { Button } from "@/components/ui/button";
import { useNavigate } from "react-router-dom";
import { ArrowRight } from "lucide-react";
import { useState, useEffect } from "react";
import Silk from "@/components/Silk";
const SPARKLE_SVG = (
<svg className="btn-svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M9.813 15.904 9 18.75l-.813-2.846a4.5 4.5 0 0 0-3.09-3.09L2.25 12l2.846-.813a4.5 4.5 0 0 0 3.09-3.09L9 5.25l.813 2.846a4.5 4.5 0 0 0 3.09 3.09L15.75 12l-2.846.813a4.5 4.5 0 0 0-3.09 3.09ZM18.259 8.715 18 9.75l-.259-1.035a3.375 3.375 0 0 0-2.455-2.456L14.25 6l1.036-.259a3.375 3.375 0 0 0 2.455-2.456L18 2.25l.259 1.035a3.375 3.375 0 0 0 2.456 2.456L21.75 6l-1.035.259a3.375 3.375 0 0 0-2.456 2.456ZM16.894 20.567 16.5 21.75l-.394-1.183a2.25 2.25 0 0 0-1.423-1.423L13.5 18.75l1.183-.394a2.25 2.25 0 0 0 1.423-1.423l.394-1.183.394 1.183a2.25 2.25 0 0 0 1.423 1.423l1.183.394-1.183.394a2.25 2.25 0 0 0-1.423 1.423Z"
/>
</svg>
);
function DemoButtonLetters({ text }: { text: string }) {
return (
<>
{text.split("").map((char, i) => (
<span key={i} className="btn-letter">
{char}
</span>
))}
</>
);
}
const FOUNDING_DATE = new Date("2026-01-25"); // Samstag, 25. Januar 2026
const Hero = () => {
const navigate = useNavigate();
const [companyAge, setCompanyAge] = useState("");
useEffect(() => {
@@ -66,23 +88,49 @@ const Hero = () => {
</p>
{/* CTA Buttons */}
<div className="flex flex-col sm:flex-row gap-4 mb-6 animate-fade-in" style={{ animationDelay: '0.5s' }}>
<Link to="/kontakt">
<Button
size="lg"
className="btn-minimal rounded-full px-8 py-6 text-base font-medium group"
<div className="flex flex-row flex-nowrap items-center gap-4 mb-6 animate-fade-in" style={{ animationDelay: '0.5s' }}>
<div className="btn-wrapper shrink-0">
<button
type="button"
className="btn btn-primary"
onClick={() => navigate("/kontakt")}
aria-label="Kostenlose Potenzialanalyse sichern"
>
Kostenlose Potenzialanalyse sichern
<ArrowRight className="w-4 h-4 ml-2 group-hover:translate-x-1 transition-transform" />
</Button>
</Link>
<Button
size="lg"
variant="outline"
className="btn-outline rounded-full px-8 py-6 text-base font-medium"
>
System-Demo anfordern
</Button>
<ArrowRight className="btn-icon" size={24} strokeWidth={2} aria-hidden />
<div className="txt-wrapper">
<span className="txt-width-helper" aria-hidden="true">
<DemoButtonLetters text="Kostenlose Potenzialanalyse sichern" />
</span>
<div className="txt-1">
<DemoButtonLetters text="Kostenlose Potenzialanalyse sichern" />
</div>
<div className="txt-2">
<DemoButtonLetters text="Wird weitergeleitet..." />
</div>
</div>
</button>
</div>
<div className="btn-wrapper">
<button
type="button"
className="btn"
onClick={() => navigate("/kontakt")}
aria-label="System-Demo anfordern"
>
{SPARKLE_SVG}
<div className="txt-wrapper">
<span className="txt-width-helper" aria-hidden="true">
<DemoButtonLetters text="System-Demo anfordern" />
</span>
<div className="txt-1">
<DemoButtonLetters text="System-Demo anfordern" />
</div>
<div className="txt-2">
<DemoButtonLetters text="Wird angefordert..." />
</div>
</div>
</button>
</div>
</div>
{/* Trust Line */}

View File

@@ -5,7 +5,7 @@ import { cn } from "@/lib/utils";
const buttonVariants = cva("inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0", {
variants: {
variant: {
default: "bg-primary text-primary-foreground hover:bg-primary/90",
default: "btn-primary-style rounded-full bg-[hsl(198,93%,42%)] text-white hover:bg-[hsl(198,93%,48%)] border border-white/20",
destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
outline: "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",

View File

@@ -290,11 +290,11 @@ export const NavbarButton = ({
...props
}: NavbarButtonProps) => {
const baseStyles =
"px-4 py-2 rounded-md bg-white text-black text-sm font-bold relative cursor-pointer hover:-translate-y-0.5 transition duration-200 inline-block text-center";
"px-4 py-2 rounded-full text-sm font-bold relative cursor-pointer transition duration-200 inline-block text-center";
const variantStyles = {
primary:
"shadow-[0_0_24px_rgba(34,_42,_53,_0.06),_0_1px_1px_rgba(0,_0,_0,_0.05),_0_0_0_1px_rgba(34,_42,_53,_0.04),_0_0_4px_rgba(34,_42,_53,_0.08),_0_16px_68px_rgba(47,_48,_55,_0.05),_0_1px_0_rgba(255,_255,_255,_0.1)_inset]",
"bg-[hsl(198,93%,42%)] text-white border border-white/20 shadow-[inset_0_1px_1px_rgba(255,255,255,0.25),inset_0_2px_2px_rgba(255,255,255,0.2),0_2px_4px_rgba(0,0,0,0.2),0_4px_8px_rgba(0,0,0,0.15)] hover:border-white/40 hover:shadow-[inset_0_1px_1px_rgba(255,255,255,0.3),inset_0_2px_2px_rgba(255,255,255,0.25),0_2px_4px_rgba(0,0,0,0.2),0_4px_8px_rgba(0,0,0,0.15)]",
secondary: "bg-transparent shadow-none dark:text-white",
dark: "bg-black text-white shadow-[0_0_24px_rgba(34,_42,_53,_0.06),_0_1px_1px_rgba(0,_0,_0,_0.05),_0_0_0_1px_rgba(34,_42,_53,_0.04),_0_0_4px_rgba(34,_42,_53,_0.08),_0_16px_68px_rgba(47,_48,_55,_0.05),_0_1px_0_rgba(255,_255,_255,_0.1)_inset]",
gradient: