update home page
This commit is contained in:
51
components/shared/CardShared.module.css
Normal file
51
components/shared/CardShared.module.css
Normal file
@@ -0,0 +1,51 @@
|
||||
.iconWrapper {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
background-color: #FFFFFF;
|
||||
border-top-left-radius: 30px;
|
||||
border-bottom-right-radius: 25px;
|
||||
padding: 10px 10px 0 10px;
|
||||
z-index: 20;
|
||||
}
|
||||
|
||||
.iconWrapper::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: -20px;
|
||||
right: 0;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background: radial-gradient(circle at 0 0, transparent 20px, #ffffff 20.5px);
|
||||
}
|
||||
|
||||
.iconWrapper::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: -20px;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background: radial-gradient(circle at 0 0, transparent 20px, #ffffff 20.5px);
|
||||
}
|
||||
|
||||
.iconSlideAslant {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.iconSlideAslantInner {
|
||||
display: inline-flex;
|
||||
transform: translate3d(-12px, 12px, 0);
|
||||
transition: transform 0.34s cubic-bezier(0.22, 1, 0.36, 1);
|
||||
will-change: transform;
|
||||
}
|
||||
|
||||
.iconSlideAslantInner svg {
|
||||
flex: 0 0 auto;
|
||||
margin: 0 12px;
|
||||
}
|
||||
|
||||
.iconSlideAslant:hover .iconSlideAslantInner,
|
||||
:global(.aiero-card:hover) .iconSlideAslantInner {
|
||||
transform: translate3d(12px, -12px, 0);
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
import { ArrowIcon } from "@/components/shared/icons/ArrowIcon";
|
||||
import styles from "./CardShared.module.css";
|
||||
|
||||
interface CardHeadingProps {
|
||||
title: string;
|
||||
@@ -19,20 +20,13 @@ export function CardHeading({
|
||||
<div className={`mb-5 ${wrapperClassName}`}>
|
||||
{subtitle && (
|
||||
<div
|
||||
className={`aiero-subheading ${subtitleClassName}`}
|
||||
style={{ fontFamily: "var(--font-sora)" }}
|
||||
className={`aiero-subheading font-sora ${subtitleClassName}`}
|
||||
>
|
||||
{subtitle}
|
||||
</div>
|
||||
)}
|
||||
<h4
|
||||
className={`tracking-[-0.03em] ${titleClassName}`}
|
||||
style={{
|
||||
fontFamily: "var(--font-dm-sans)",
|
||||
fontSize: "30px",
|
||||
fontWeight: 500,
|
||||
lineHeight: "1.16666em",
|
||||
}}
|
||||
className={`font-dm-sans text-[30px] font-medium leading-[1.16666em] tracking-[-0.03em] ${titleClassName}`}
|
||||
>
|
||||
{title}
|
||||
</h4>
|
||||
@@ -42,10 +36,17 @@ export function CardHeading({
|
||||
|
||||
export function IconButton({ className = "" }: { className?: string }) {
|
||||
return (
|
||||
<div className={`absolute bottom-0 right-0 icon-decoration ${className}`}>
|
||||
<div className="icon-inner flex h-[52px] w-[52px] items-center justify-center rounded-tl-[30px] bg-white text-[#333333] transition-colors hover:bg-[#333333] hover:text-white">
|
||||
<ArrowIcon className="h-3 w-3" />
|
||||
</div>
|
||||
<div className={`${styles.iconWrapper} ${className}`}>
|
||||
<a
|
||||
href="#"
|
||||
className={`${styles.iconSlideAslant} flex h-[52px] w-[52px] items-center justify-center rounded-[15px] bg-aiero-card-dark text-white transition-all duration-300 hover:bg-aiero-teal hover:text-aiero-dark`}
|
||||
aria-label="Open details"
|
||||
>
|
||||
<span className={styles.iconSlideAslantInner} aria-hidden="true">
|
||||
<ArrowIcon className="h-3 w-3" />
|
||||
<ArrowIcon className="h-3 w-3" />
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
171
components/shared/ContactFormSection.tsx
Normal file
171
components/shared/ContactFormSection.tsx
Normal file
@@ -0,0 +1,171 @@
|
||||
"use client";
|
||||
|
||||
import { type FormEvent, useState } from "react";
|
||||
import { siteConfig } from "@/data/site-config";
|
||||
import { SectionHeading } from "@/components/shared/SectionHeading";
|
||||
import { SocialIcons } from "@/components/shared/SocialIcons";
|
||||
import { PageContainer } from "@/components/shared/PageContainer";
|
||||
import { SectionContainer } from "@/components/shared/SectionContainer";
|
||||
import { ArrowIcon } from "@/components/shared/icons/ArrowIcon";
|
||||
|
||||
/**
|
||||
* ContactFormSection — dark card with contact info + form.
|
||||
*
|
||||
* Shared by: About page (section 8) and Contacts page (section 2).
|
||||
* Single implementation — avoids duplicated markup.
|
||||
*
|
||||
* Data sourced from `data/site-config.ts`.
|
||||
*/
|
||||
export function ContactFormSection() {
|
||||
const [formState, setFormState] = useState({
|
||||
fullName: "",
|
||||
email: "",
|
||||
subject: "",
|
||||
message: "",
|
||||
});
|
||||
|
||||
function handleSubmit(e: FormEvent) {
|
||||
e.preventDefault();
|
||||
// Form submission logic will be implemented later
|
||||
}
|
||||
|
||||
function handleChange(
|
||||
e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>
|
||||
) {
|
||||
setFormState((prev) => ({ ...prev, [e.target.name]: e.target.value }));
|
||||
}
|
||||
|
||||
return (
|
||||
<SectionContainer paddingY="lg" className="bg-aiero-dark px-5">
|
||||
<div className="overflow-hidden rounded-[25px] bg-aiero-card-dark">
|
||||
<PageContainer className="grid grid-cols-1 gap-12 py-16 md:py-20 lg:grid-cols-2 lg:gap-16 lg:py-24">
|
||||
{/* ── Left: Info column ── */}
|
||||
<div className="flex flex-col">
|
||||
<SectionHeading
|
||||
tag="get in touch"
|
||||
title="We are always ready to help you and answer your questions"
|
||||
titleClassName="text-white"
|
||||
description="Pacific hake false trevally queen parrotfish black prickleback mosshead warbonnet sweeper! Greenling sleeper."
|
||||
/>
|
||||
|
||||
{/* Contact details grid */}
|
||||
<div className="mt-10 grid grid-cols-1 gap-8 sm:grid-cols-2">
|
||||
{/* Call Center */}
|
||||
<div>
|
||||
<h6 className="mb-3 font-sora text-sm font-semibold text-white">
|
||||
Call Center
|
||||
</h6>
|
||||
<div className="flex flex-col gap-1">
|
||||
<a
|
||||
href={`tel:${siteConfig.phoneRaw}`}
|
||||
className="text-[15px] text-aiero-text-muted transition-colors hover:text-aiero-teal"
|
||||
>
|
||||
{siteConfig.phone}
|
||||
</a>
|
||||
<a
|
||||
href="tel:+11800234567"
|
||||
className="text-[15px] text-aiero-text-muted transition-colors hover:text-aiero-teal"
|
||||
>
|
||||
+ (123) 1800-234-5678
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Our Location */}
|
||||
<div>
|
||||
<h6 className="mb-3 font-sora text-sm font-semibold text-white">
|
||||
Our Location
|
||||
</h6>
|
||||
<p className="text-[15px] leading-relaxed text-aiero-text-muted">
|
||||
{siteConfig.address.line1}
|
||||
<br />
|
||||
{siteConfig.address.line2}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Email */}
|
||||
<div>
|
||||
<h6 className="mb-3 font-sora text-sm font-semibold text-white">
|
||||
Email
|
||||
</h6>
|
||||
<a
|
||||
href={`mailto:${siteConfig.email}`}
|
||||
className="text-[15px] text-aiero-text-muted underline transition-colors hover:text-aiero-teal"
|
||||
>
|
||||
{siteConfig.email}
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{/* Social */}
|
||||
<div>
|
||||
<h6 className="mb-3 font-sora text-sm font-semibold text-white">
|
||||
Social network
|
||||
</h6>
|
||||
<SocialIcons links={siteConfig.socials} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* ── Right: Form column ── */}
|
||||
<div className="rounded-[25px] bg-white p-8 md:p-10">
|
||||
<h4
|
||||
className="mb-8 text-aiero-dark"
|
||||
style={{
|
||||
fontFamily: "var(--font-sora)",
|
||||
fontSize: "28px",
|
||||
fontWeight: 700,
|
||||
lineHeight: 1.2,
|
||||
}}
|
||||
>
|
||||
Get in Touch
|
||||
</h4>
|
||||
|
||||
<form onSubmit={handleSubmit} className="flex flex-col gap-5">
|
||||
<input
|
||||
type="text"
|
||||
name="fullName"
|
||||
placeholder="Full name"
|
||||
value={formState.fullName}
|
||||
onChange={handleChange}
|
||||
className="rounded-xl border border-gray-200 bg-gray-50 px-5 py-3.5 text-[15px] text-aiero-dark outline-none transition-colors focus:border-aiero-teal"
|
||||
/>
|
||||
<input
|
||||
type="email"
|
||||
name="email"
|
||||
placeholder="Email"
|
||||
required
|
||||
value={formState.email}
|
||||
onChange={handleChange}
|
||||
className="rounded-xl border border-gray-200 bg-gray-50 px-5 py-3.5 text-[15px] text-aiero-dark outline-none transition-colors focus:border-aiero-teal"
|
||||
/>
|
||||
<input
|
||||
type="text"
|
||||
name="subject"
|
||||
placeholder="Subject"
|
||||
value={formState.subject}
|
||||
onChange={handleChange}
|
||||
className="rounded-xl border border-gray-200 bg-gray-50 px-5 py-3.5 text-[15px] text-aiero-dark outline-none transition-colors focus:border-aiero-teal"
|
||||
/>
|
||||
<textarea
|
||||
name="message"
|
||||
placeholder="Message"
|
||||
rows={4}
|
||||
value={formState.message}
|
||||
onChange={handleChange}
|
||||
className="resize-none rounded-xl border border-gray-200 bg-gray-50 px-5 py-3.5 text-[15px] text-aiero-dark outline-none transition-colors focus:border-aiero-teal"
|
||||
/>
|
||||
<button
|
||||
type="submit"
|
||||
className="aiero-button aiero-button-gradient-border mt-2 self-start rounded-full px-8 py-4 font-sora text-base font-semibold text-aiero-dark"
|
||||
>
|
||||
Send message
|
||||
<ArrowIcon className="h-3 w-3" />
|
||||
<span className="button-inner" />
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</PageContainer>
|
||||
</div>
|
||||
</SectionContainer>
|
||||
);
|
||||
}
|
||||
@@ -53,7 +53,7 @@ export function Counter({
|
||||
requestAnimationFrame(animate);
|
||||
}
|
||||
},
|
||||
{ threshold: 0.3 }
|
||||
{ rootMargin: "0px 0px 20% 0px", threshold: 0.01 }
|
||||
);
|
||||
|
||||
observer.observe(el);
|
||||
|
||||
109
components/shared/Footer.tsx
Normal file
109
components/shared/Footer.tsx
Normal file
@@ -0,0 +1,109 @@
|
||||
import Image from "next/image";
|
||||
import Link from "next/link";
|
||||
import { siteConfig } from "@/data/site-config";
|
||||
import { SocialIcons } from "@/components/shared/SocialIcons";
|
||||
import { PageContainer } from "@/components/shared/PageContainer";
|
||||
|
||||
/**
|
||||
* Footer — shared site-wide footer.
|
||||
*
|
||||
* Renders on every page via layout.tsx.
|
||||
* Data sourced from `data/site-config.ts` — no hardcoded links.
|
||||
*
|
||||
* Structure (from reference):
|
||||
* Left: Logo · social icons · outline "since 2024" text
|
||||
* Right: Company links column · Services links column
|
||||
* Bottom: Copyright · Terms/Privacy
|
||||
*/
|
||||
export function Footer() {
|
||||
return (
|
||||
<footer className="bg-aiero-dark px-5 pb-10 pt-16 md:pt-20">
|
||||
<PageContainer>
|
||||
{/* ── Top row: Logo + link columns ── */}
|
||||
<div className="grid grid-cols-1 gap-12 md:grid-cols-2 lg:grid-cols-[1.5fr_1fr_1fr]">
|
||||
{/* Brand column */}
|
||||
<div className="flex flex-col items-start gap-8">
|
||||
<Link href="/" aria-label="Home">
|
||||
<Image
|
||||
src="/images/aiero/logo-dark.png"
|
||||
alt={siteConfig.name}
|
||||
width={146}
|
||||
height={26}
|
||||
className="h-auto w-auto brightness-0 invert"
|
||||
/>
|
||||
</Link>
|
||||
|
||||
<SocialIcons links={siteConfig.socials} />
|
||||
|
||||
{/* Outline "since 2024" decorative text */}
|
||||
<span
|
||||
className="mt-4 select-none font-sora text-[clamp(48px,6vw,80px)] font-bold leading-none tracking-tight"
|
||||
style={{
|
||||
WebkitTextStroke: "1px rgba(255,255,255,0.12)",
|
||||
WebkitTextFillColor: "transparent",
|
||||
}}
|
||||
>
|
||||
since 2024
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/* Company links */}
|
||||
<div>
|
||||
<h4 className="mb-6 font-sora text-sm font-semibold uppercase tracking-widest text-white">
|
||||
Company
|
||||
</h4>
|
||||
<ul className="flex flex-col gap-3">
|
||||
{siteConfig.footerLinks.company.map((link) => (
|
||||
<li key={link.label}>
|
||||
<a
|
||||
href={link.href}
|
||||
className="text-[15px] text-aiero-text-muted transition-colors duration-300 hover:text-aiero-teal"
|
||||
>
|
||||
{link.label}
|
||||
</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
{/* Services links */}
|
||||
<div>
|
||||
<h4 className="mb-6 font-sora text-sm font-semibold uppercase tracking-widest text-white">
|
||||
Services
|
||||
</h4>
|
||||
<ul className="flex flex-col gap-3">
|
||||
{siteConfig.footerLinks.services.map((link) => (
|
||||
<li key={link.label}>
|
||||
<a
|
||||
href={link.href}
|
||||
className="text-[15px] text-aiero-text-muted transition-colors duration-300 hover:text-aiero-teal"
|
||||
>
|
||||
{link.label}
|
||||
</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* ── Bottom bar ── */}
|
||||
<div className="mt-14 flex flex-col items-center justify-between gap-4 border-t border-aiero-card-border pt-8 md:flex-row">
|
||||
<p className="text-sm text-aiero-text-muted">
|
||||
{siteConfig.copyright}
|
||||
</p>
|
||||
<div className="flex gap-6">
|
||||
{siteConfig.legalLinks.map((link) => (
|
||||
<a
|
||||
key={link.label}
|
||||
href={link.href}
|
||||
className="text-sm text-aiero-text-muted transition-colors duration-300 hover:text-aiero-teal"
|
||||
>
|
||||
{link.label}
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</PageContainer>
|
||||
</footer>
|
||||
);
|
||||
}
|
||||
@@ -1,38 +1,53 @@
|
||||
import { ReactNode } from "react";
|
||||
|
||||
interface IconBoxProps {
|
||||
icon: ReactNode;
|
||||
icon?: ReactNode;
|
||||
title: string;
|
||||
description: string;
|
||||
hasBorder?: boolean;
|
||||
theme?: "dark" | "light";
|
||||
}
|
||||
|
||||
export function IconBox({ icon, title, description, hasBorder = true }: IconBoxProps) {
|
||||
export function IconBox({ icon, title, description, hasBorder = true, theme = "dark" }: IconBoxProps) {
|
||||
const isLight = theme === "light";
|
||||
|
||||
return (
|
||||
<div className="flex flex-col items-start gap-[20px] sm:flex-row sm:gap-[40px]">
|
||||
<div className="flex h-[88px] w-[88px] shrink-0 items-center justify-center">
|
||||
{icon}
|
||||
</div>
|
||||
|
||||
<div
|
||||
className={`flex-1 pb-[30px] pt-[5px] ${
|
||||
hasBorder ? "border-b border-[#3F3F3F]" : ""
|
||||
}`}
|
||||
>
|
||||
<h5
|
||||
className="mb-[15px] text-white"
|
||||
style={{
|
||||
fontFamily: "var(--font-manrope)",
|
||||
fontSize: "25px",
|
||||
lineHeight: 1.4,
|
||||
fontWeight: 500,
|
||||
}}
|
||||
<div className="aiero-icon-box-widget w-full">
|
||||
<div className="icon-box-item flex flex-col items-start gap-[20px] sm:flex-row sm:gap-[40px]">
|
||||
{icon && (
|
||||
<div className="icon-container background-type-none flex h-[88px] w-[88px] shrink-0 items-center justify-center">
|
||||
<span className="icon block h-full w-full">
|
||||
{icon}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div
|
||||
className={`content-container flex-1 pb-[30px] pt-[5px] ${
|
||||
hasBorder
|
||||
? isLight
|
||||
? "border-b border-gray-200"
|
||||
: "border-b border-aiero-card-border"
|
||||
: ""
|
||||
}`}
|
||||
>
|
||||
{title}
|
||||
</h5>
|
||||
<p className="text-[16px] leading-[1.6] text-[#87899B]">
|
||||
{description}
|
||||
</p>
|
||||
<h5
|
||||
className={`icon-box-title mb-[15px] ${isLight ? "text-aiero-dark" : "text-white"}`}
|
||||
style={{
|
||||
fontFamily: "var(--font-manrope)",
|
||||
fontSize: "25px",
|
||||
lineHeight: 1.4,
|
||||
fontWeight: 500,
|
||||
}}
|
||||
>
|
||||
{title}
|
||||
</h5>
|
||||
<div className="icon-box-info">
|
||||
<p className="text-[16px] leading-[1.6] text-aiero-text-muted">
|
||||
{description}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
22
components/shared/PageContainer.tsx
Normal file
22
components/shared/PageContainer.tsx
Normal file
@@ -0,0 +1,22 @@
|
||||
import { type ReactNode } from "react";
|
||||
|
||||
interface PageContainerProps {
|
||||
children: ReactNode;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* PageContainer — global max-width + horizontal padding wrapper.
|
||||
*
|
||||
* Every section's inner content should be wrapped in this to ensure
|
||||
* consistent container width across all pages.
|
||||
*
|
||||
* Default: max-w-[1260px], px-[15px], mx-auto
|
||||
*/
|
||||
export function PageContainer({ children, className = "" }: PageContainerProps) {
|
||||
return (
|
||||
<div className={`mx-auto w-full max-w-[1260px] px-[15px] ${className}`}>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
126
components/shared/PageTitleBanner.tsx
Normal file
126
components/shared/PageTitleBanner.tsx
Normal file
@@ -0,0 +1,126 @@
|
||||
interface BreadcrumbItem {
|
||||
label: string;
|
||||
href?: string;
|
||||
}
|
||||
|
||||
interface PageTitleBannerProps {
|
||||
/** Page title — "About us", "Services", "Contacts" */
|
||||
title: string;
|
||||
/** Breadcrumb trail */
|
||||
breadcrumbs: BreadcrumbItem[];
|
||||
}
|
||||
|
||||
/**
|
||||
* PageTitleBanner — shared inner-page hero banner.
|
||||
*
|
||||
* Used by: About, Services, Contacts pages.
|
||||
*
|
||||
* Structure (from reference):
|
||||
* - Full-width rounded card with gradient background
|
||||
* - Centered "/ Title /" text
|
||||
* - Breadcrumbs bottom-left
|
||||
* - Decorative "Aiero" outline text right side
|
||||
* - Top-left and bottom-right rounded corner decorations
|
||||
*/
|
||||
export function PageTitleBanner({ title, breadcrumbs }: PageTitleBannerProps) {
|
||||
return (
|
||||
<div className="relative mx-5 overflow-hidden rounded-[25px] bg-aiero-dark">
|
||||
{/* Background image */}
|
||||
<div
|
||||
className="absolute inset-0 bg-cover bg-center opacity-80"
|
||||
style={{
|
||||
backgroundImage: "url(/images/aiero/page-top-bg-min.png)",
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* Gradient overlay */}
|
||||
<div className="absolute inset-0 bg-gradient-to-b from-transparent via-transparent to-aiero-dark/60" />
|
||||
|
||||
{/* Top-left corner decoration */}
|
||||
<div className="absolute left-0 top-0 h-20 w-20">
|
||||
<div className="absolute left-0 top-0 h-full w-full rounded-br-[25px] bg-white" />
|
||||
<div className="absolute left-0 top-0 h-full w-full rounded-tl-[25px] bg-aiero-dark">
|
||||
<div
|
||||
className="absolute inset-0 bg-cover bg-center opacity-80"
|
||||
style={{
|
||||
backgroundImage: "url(/images/aiero/page-top-bg-min.png)",
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Bottom-right corner decoration */}
|
||||
<div className="absolute bottom-0 right-0 h-20 w-20">
|
||||
<div className="absolute bottom-0 right-0 h-full w-full rounded-tl-[25px] bg-white" />
|
||||
<div className="absolute bottom-0 right-0 h-full w-full rounded-br-[25px] bg-aiero-dark">
|
||||
<div
|
||||
className="absolute inset-0 bg-cover bg-center opacity-80"
|
||||
style={{
|
||||
backgroundImage: "url(/images/aiero/page-top-bg-min.png)",
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Content */}
|
||||
<div className="relative z-10 flex min-h-[320px] flex-col items-center justify-center px-8 py-16 md:min-h-[400px] lg:min-h-[460px]">
|
||||
{/* Title */}
|
||||
<h1
|
||||
className="text-center text-white"
|
||||
style={{
|
||||
fontFamily: "var(--font-sora)",
|
||||
fontSize: "clamp(36px, 5vw, 72px)",
|
||||
fontWeight: 700,
|
||||
lineHeight: 1.1,
|
||||
}}
|
||||
>
|
||||
<span className="mr-3 text-aiero-text-muted">/</span>
|
||||
{title}
|
||||
<span className="ml-3 text-aiero-text-muted">/</span>
|
||||
</h1>
|
||||
|
||||
{/* Breadcrumbs */}
|
||||
<nav className="absolute bottom-8 left-8 md:bottom-10 md:left-12" aria-label="Breadcrumb">
|
||||
<ol className="flex items-center gap-2 text-sm text-white/70">
|
||||
{breadcrumbs.map((crumb, index) => (
|
||||
<li key={crumb.label} className="flex items-center gap-2">
|
||||
{index > 0 && (
|
||||
<span className="mx-1 inline-block h-1 w-1 rounded-full bg-aiero-teal" />
|
||||
)}
|
||||
{index < breadcrumbs.length - 1 && crumb.href ? (
|
||||
<a
|
||||
href={crumb.href}
|
||||
className="transition-colors hover:text-aiero-teal"
|
||||
>
|
||||
{crumb.label}
|
||||
</a>
|
||||
) : (
|
||||
<span className="text-white">{crumb.label}</span>
|
||||
)}
|
||||
</li>
|
||||
))}
|
||||
</ol>
|
||||
</nav>
|
||||
|
||||
{/* Decorative vertical "Aiero" text */}
|
||||
<div
|
||||
className="absolute bottom-8 right-8 hidden select-none lg:block"
|
||||
style={{
|
||||
writingMode: "vertical-rl",
|
||||
textOrientation: "mixed",
|
||||
}}
|
||||
>
|
||||
<span
|
||||
className="font-sora text-[clamp(48px,5vw,72px)] font-bold leading-none tracking-tight"
|
||||
style={{
|
||||
WebkitTextStroke: "1px rgba(255,255,255,0.1)",
|
||||
WebkitTextFillColor: "transparent",
|
||||
}}
|
||||
>
|
||||
Aiero
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
48
components/shared/PartnerLogosSection.tsx
Normal file
48
components/shared/PartnerLogosSection.tsx
Normal file
@@ -0,0 +1,48 @@
|
||||
"use client";
|
||||
|
||||
import { PageContainer } from "@/components/shared/PageContainer";
|
||||
import { SectionContainer } from "@/components/shared/SectionContainer";
|
||||
|
||||
export function PartnerLogosSection() {
|
||||
const logos = [
|
||||
"/images/aiero/partners-1.png",
|
||||
"/images/aiero/partners-2.png",
|
||||
"/images/aiero/partners-1.png",
|
||||
"/images/aiero/partners-2.png",
|
||||
"/images/aiero/partners-1.png",
|
||||
"/images/aiero/partners-2.png",
|
||||
];
|
||||
|
||||
return (
|
||||
<SectionContainer paddingY="lg" className="border-t border-aiero-card-border bg-aiero-dark">
|
||||
<PageContainer className="flex flex-col items-center">
|
||||
<h3
|
||||
className="mb-16 max-w-[800px] text-center text-white"
|
||||
style={{
|
||||
fontFamily: "var(--font-dm-sans)",
|
||||
fontSize: "clamp(24px, 3vw, 36px)",
|
||||
fontWeight: 500,
|
||||
lineHeight: 1.2,
|
||||
}}
|
||||
>
|
||||
Tinker with a Neural Network right here in your browser. Don’t worry, you can’t break it. We Promise.
|
||||
</h3>
|
||||
|
||||
<div className="flex flex-wrap justify-center gap-8 md:gap-16 lg:gap-24 opacity-60">
|
||||
{logos.map((src, index) => (
|
||||
<div key={index} className="flex h-12 items-center justify-center grayscale transition-all hover:grayscale-0">
|
||||
<img
|
||||
src={src}
|
||||
alt={`Partner ${index + 1}`}
|
||||
className="h-full w-auto object-contain"
|
||||
onError={(e) => {
|
||||
(e.target as HTMLImageElement).src = "/images/aiero/logo-dark.png";
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</PageContainer>
|
||||
</SectionContainer>
|
||||
);
|
||||
}
|
||||
45
components/shared/PreFooterCTA.tsx
Normal file
45
components/shared/PreFooterCTA.tsx
Normal file
@@ -0,0 +1,45 @@
|
||||
import { AieroButton } from "@/components/shared/AieroButton";
|
||||
import { PageContainer } from "@/components/shared/PageContainer";
|
||||
|
||||
/**
|
||||
* PreFooterCTA — "It's blow your mind! Meet Neural Networks" banner.
|
||||
*
|
||||
* Shared across: Home, About, Services, Contacts.
|
||||
*
|
||||
* Structure (from reference):
|
||||
* - Dark grey rounded card
|
||||
* - Large teal gradient heading
|
||||
* - "Get a Quote" button with arrow
|
||||
*/
|
||||
export function PreFooterCTA() {
|
||||
return (
|
||||
<section className="px-5 pb-5">
|
||||
<div className="overflow-hidden rounded-[25px] bg-aiero-card-dark">
|
||||
<PageContainer className="flex flex-col items-center gap-8 py-16 text-center md:flex-row md:justify-between md:py-20 md:text-left lg:py-24">
|
||||
{/* Heading */}
|
||||
<h2
|
||||
className="max-w-[700px]"
|
||||
style={{
|
||||
fontFamily: "var(--font-sora)",
|
||||
fontSize: "clamp(28px, 3.5vw, 48px)",
|
||||
fontWeight: 700,
|
||||
lineHeight: 1.15,
|
||||
}}
|
||||
>
|
||||
<span className="text-white">{"It's blow your mind! "}</span>
|
||||
<span className="gradient-text-purple">Meet Neural Networks</span>
|
||||
</h2>
|
||||
|
||||
{/* CTA */}
|
||||
<AieroButton
|
||||
href="/contacts"
|
||||
variant="gradient-border"
|
||||
className="shrink-0 rounded-full px-8 py-4 text-base font-semibold text-white"
|
||||
>
|
||||
Get a Quote
|
||||
</AieroButton>
|
||||
</PageContainer>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
46
components/shared/RevealOnView.tsx
Normal file
46
components/shared/RevealOnView.tsx
Normal file
@@ -0,0 +1,46 @@
|
||||
"use client";
|
||||
|
||||
import { type CSSProperties, type ReactNode, useEffect, useRef, useState } from "react";
|
||||
|
||||
interface RevealOnViewProps {
|
||||
children: ReactNode;
|
||||
className?: string;
|
||||
delay?: number;
|
||||
}
|
||||
|
||||
export function RevealOnView({
|
||||
children,
|
||||
className = "",
|
||||
delay = 0,
|
||||
}: RevealOnViewProps) {
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
const [isVisible, setIsVisible] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const element = ref.current;
|
||||
if (!element) return;
|
||||
|
||||
const observer = new IntersectionObserver(
|
||||
([entry]) => {
|
||||
if (entry.isIntersecting) {
|
||||
setIsVisible(true);
|
||||
observer.unobserve(element);
|
||||
}
|
||||
},
|
||||
{ rootMargin: "0px 0px 18% 0px", threshold: 0.01 }
|
||||
);
|
||||
|
||||
observer.observe(element);
|
||||
return () => observer.disconnect();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={ref}
|
||||
className={`reveal-on-view ${isVisible ? "is-visible" : ""} ${className}`}
|
||||
style={{ "--reveal-delay": `${delay}ms` } as CSSProperties}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
35
components/shared/ScrollDown.tsx
Normal file
35
components/shared/ScrollDown.tsx
Normal file
@@ -0,0 +1,35 @@
|
||||
|
||||
import { ArrowIcon } from "./icons/ArrowIcon";
|
||||
|
||||
interface ScrollDownProps {
|
||||
href?: string;
|
||||
className?: string;
|
||||
text?: string;
|
||||
light?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* ScrollDown — interactive scroll indicator.
|
||||
* Matches original Aiero reference animation and styling.
|
||||
*/
|
||||
export function ScrollDown({
|
||||
href = "#scroll-down",
|
||||
className = "",
|
||||
text = "Scroll down",
|
||||
light = true,
|
||||
}: ScrollDownProps) {
|
||||
return (
|
||||
<span className={`scroll-btn-decoration ${className}`}>
|
||||
<a
|
||||
href={href}
|
||||
className={`inline-flex h-[78px] w-[190px] items-center justify-center gap-2 rounded-b-[25px] ${
|
||||
light ? "bg-white text-aiero-dark" : "bg-aiero-dark text-white"
|
||||
} text-[14px] font-semibold no-underline transition-all hover:text-aiero-teal hover:shadow-scroll-btn`}
|
||||
style={{ fontFamily: "var(--font-sora)" }}
|
||||
>
|
||||
{text}
|
||||
<ArrowIcon className="h-3 w-3" />
|
||||
</a>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
54
components/shared/SectionContainer.tsx
Normal file
54
components/shared/SectionContainer.tsx
Normal file
@@ -0,0 +1,54 @@
|
||||
import { type ReactNode } from "react";
|
||||
|
||||
type PaddingSize = "none" | "sm" | "md" | "lg" | "xl";
|
||||
|
||||
interface SectionContainerProps {
|
||||
children: ReactNode;
|
||||
className?: string;
|
||||
/** Vertical padding preset — maps to spacing tokens */
|
||||
paddingY?: PaddingSize;
|
||||
/** HTML element to render */
|
||||
as?: "section" | "div";
|
||||
/** Section id for anchor links */
|
||||
id?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tailwind class map for vertical section padding.
|
||||
*
|
||||
* Values use the spacing tokens from design-tokens.ts:
|
||||
* sm = 60px
|
||||
* md = 60px → 80px
|
||||
* lg = 60px → 80px → 100px
|
||||
* xl = 60px → 80px → 100px → 120px
|
||||
*/
|
||||
const paddingYClasses: Record<PaddingSize, string> = {
|
||||
none: "",
|
||||
sm: "py-[60px]",
|
||||
md: "py-[60px] md:py-[80px]",
|
||||
lg: "py-[60px] md:py-[80px] lg:py-[100px]",
|
||||
xl: "py-[60px] md:py-[80px] lg:py-[100px] xl:py-[120px]",
|
||||
};
|
||||
|
||||
/**
|
||||
* SectionContainer — consistent vertical spacing for page sections.
|
||||
*
|
||||
* Use this to wrap every major page section. The `paddingY` prop
|
||||
* selects from predefined responsive spacing tokens.
|
||||
*
|
||||
* Does NOT include horizontal constraints — nest a `PageContainer`
|
||||
* inside for boxed content.
|
||||
*/
|
||||
export function SectionContainer({
|
||||
children,
|
||||
className = "",
|
||||
paddingY = "lg",
|
||||
as: Tag = "section",
|
||||
id,
|
||||
}: SectionContainerProps) {
|
||||
return (
|
||||
<Tag id={id} className={`${paddingYClasses[paddingY]} ${className}`}>
|
||||
{children}
|
||||
</Tag>
|
||||
);
|
||||
}
|
||||
72
components/shared/SectionHeading.tsx
Normal file
72
components/shared/SectionHeading.tsx
Normal file
@@ -0,0 +1,72 @@
|
||||
import { type ReactNode } from "react";
|
||||
|
||||
interface SectionHeadingProps {
|
||||
/** Small tag label — e.g. "team", "get in touch" */
|
||||
tag?: string;
|
||||
/** Main heading text */
|
||||
title: string | ReactNode;
|
||||
/** Optional description paragraph below the heading */
|
||||
description?: string;
|
||||
/** HTML heading level */
|
||||
titleAs?: "h1" | "h2" | "h3" | "h4";
|
||||
/** Wrapper className */
|
||||
className?: string;
|
||||
/** Title className override */
|
||||
titleClassName?: string;
|
||||
/** Description className override */
|
||||
descriptionClassName?: string;
|
||||
/** Tag className override */
|
||||
tagClassName?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* SectionHeading — page-level section header.
|
||||
*
|
||||
* Pattern: [tag] + heading + optional description.
|
||||
* Used for top-level section titles across all pages.
|
||||
*
|
||||
* For card-internal headings, use `CardHeading` instead.
|
||||
*/
|
||||
export function SectionHeading({
|
||||
tag,
|
||||
title,
|
||||
description,
|
||||
titleAs: Tag = "h2",
|
||||
className = "",
|
||||
titleClassName = "",
|
||||
descriptionClassName = "",
|
||||
tagClassName = "",
|
||||
}: SectionHeadingProps) {
|
||||
return (
|
||||
<div className={className}>
|
||||
{tag && (
|
||||
<span
|
||||
className={`aiero-subheading mb-4 text-aiero-teal ${tagClassName}`}
|
||||
style={{ fontFamily: "var(--font-sora)" }}
|
||||
>
|
||||
{tag}
|
||||
</span>
|
||||
)}
|
||||
|
||||
<Tag
|
||||
className={`tracking-[-0.03em] ${titleClassName}`}
|
||||
style={{
|
||||
fontFamily: "var(--font-dm-sans)",
|
||||
fontSize: "clamp(32px, 4vw, 56px)",
|
||||
fontWeight: 500,
|
||||
lineHeight: 1.1,
|
||||
}}
|
||||
>
|
||||
{title}
|
||||
</Tag>
|
||||
|
||||
{description && (
|
||||
<p
|
||||
className={`mt-6 text-base leading-relaxed text-aiero-text-muted ${descriptionClassName}`}
|
||||
>
|
||||
{description}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
67
components/shared/SocialIcons.tsx
Normal file
67
components/shared/SocialIcons.tsx
Normal file
@@ -0,0 +1,67 @@
|
||||
import { type SocialLink } from "@/data/site-config";
|
||||
|
||||
interface SocialIconsProps {
|
||||
links: readonly SocialLink[] | SocialLink[];
|
||||
className?: string;
|
||||
iconClassName?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reusable social icon list.
|
||||
* Used in: Footer, ContactFormSection.
|
||||
*/
|
||||
export function SocialIcons({
|
||||
links,
|
||||
className = "",
|
||||
iconClassName = "",
|
||||
}: SocialIconsProps) {
|
||||
return (
|
||||
<div className={`flex items-center gap-4 ${className}`} role="list">
|
||||
{links.map((link) => (
|
||||
<a
|
||||
key={link.platform}
|
||||
href={link.url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
role="listitem"
|
||||
aria-label={link.platform}
|
||||
className={`flex h-10 w-10 items-center justify-center rounded-full border border-aiero-card-border text-aiero-text-muted transition-all duration-300 hover:border-aiero-teal hover:text-aiero-teal ${iconClassName}`}
|
||||
>
|
||||
<SocialSvg icon={link.icon} />
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
/** Inline SVG icons for each social platform */
|
||||
function SocialSvg({ icon }: { icon: SocialLink["icon"] }) {
|
||||
const size = "h-4 w-4";
|
||||
|
||||
switch (icon) {
|
||||
case "facebook":
|
||||
return (
|
||||
<svg className={size} viewBox="0 0 24 24" fill="currentColor">
|
||||
<path d="M9.198 21.5h4v-8.01h3.604l.396-3.98h-4V7.5a1 1 0 0 1 1-1h3v-4h-3a5 5 0 0 0-5 5v2.01h-2l-.396 3.98h2.396v8.01Z" />
|
||||
</svg>
|
||||
);
|
||||
case "x-twitter":
|
||||
return (
|
||||
<svg className={size} viewBox="0 0 24 24" fill="currentColor">
|
||||
<path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231 5.45-6.231Zm-1.161 17.52h1.833L7.084 4.126H5.117L17.083 19.77Z" />
|
||||
</svg>
|
||||
);
|
||||
case "linkedin":
|
||||
return (
|
||||
<svg className={size} viewBox="0 0 24 24" fill="currentColor">
|
||||
<path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286ZM5.337 7.433a2.062 2.062 0 0 1-2.063-2.065 2.064 2.064 0 1 1 2.063 2.065Zm1.782 13.019H3.555V9h3.564v11.452ZM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003Z" />
|
||||
</svg>
|
||||
);
|
||||
case "youtube":
|
||||
return (
|
||||
<svg className={size} viewBox="0 0 24 24" fill="currentColor">
|
||||
<path d="M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814ZM9.545 15.568V8.432L15.818 12l-6.273 3.568Z" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,19 +1,90 @@
|
||||
export function OrbitIcon({ className = "" }: { className?: string }) {
|
||||
return (
|
||||
<svg className={className} viewBox="0 0 78 88" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M45.74 40.8109C51.6726 37.3857 53.7055 29.8003 50.2807 23.8683C46.8559 17.9363 39.2702 15.9042 33.3376 19.3294C27.405 22.7546 25.3721 30.3401 28.7969 36.2721C32.2217 42.2041 39.8074 44.2361 45.74 40.8109Z" stroke="url(#paint0_linear)" strokeWidth="0.6"/>
|
||||
<path d="M47.1284 43.216C53.426 39.58 55.5842 31.528 51.9488 25.2313C48.3134 18.9346 40.2611 16.7777 33.9634 20.4136C27.6658 24.0496 25.5076 32.1016 29.143 38.3982C32.7784 44.6949 40.8307 46.8518 47.1284 43.216Z" stroke="url(#paint1_linear)" strokeWidth="0.6"/>
|
||||
<path d="M48.5691 45.7111C55.2842 41.8341 57.5856 33.2485 53.7094 26.5346C49.8331 19.8208 41.2471 17.521 34.5319 21.398C27.8168 25.275 25.5154 33.8606 29.3916 40.5745C33.2679 47.2883 41.8539 49.5881 48.5691 45.7111Z" stroke="url(#paint2_linear)" strokeWidth="0.6"/>
|
||||
<path d="M50.0791 48.2764C57.2512 44.1205 59.6971 34.9389 55.5422 27.7685C51.3874 20.5981 42.205 18.1543 35.0329 22.3102C27.8609 26.466 25.415 35.6477 29.5698 42.8181C33.7247 49.9885 42.9071 52.4322 50.0791 48.2764Z" stroke="url(#paint3_linear)" strokeWidth="0.6"/>
|
||||
<path d="M51.5834 50.9308C59.2604 46.4985 61.8917 36.6837 57.4607 29.0089C53.0296 21.334 43.2141 18.7054 35.5371 23.1377C27.8601 27.57 25.2288 37.3848 29.6599 45.0596C34.091 52.7345 43.9065 55.3631 51.5834 50.9308Z" stroke="url(#paint4_linear)" strokeWidth="0.6"/>
|
||||
<path d="M53.1404 53.6281C61.3442 48.8916 64.1552 38.4018 59.419 30.1984C54.6827 21.995 44.1928 19.1845 35.989 23.921C27.7852 28.6574 24.9742 39.1472 29.7105 47.3506C34.4467 55.554 44.9366 58.3645 53.1404 53.6281Z" stroke="url(#paint5_linear)" strokeWidth="0.6"/>
|
||||
<path d="M54.7248 56.3733C63.4817 51.3175 66.4824 40.1209 61.4271 31.3649C56.3718 22.609 45.1749 19.6093 36.4181 24.6651C27.6613 29.7208 24.6606 40.9175 29.7159 49.6734C34.7711 58.4294 45.968 61.429 54.7248 56.3733Z" stroke="url(#paint6_linear)" strokeWidth="0.6"/>
|
||||
<path d="M56.3293 59.1495C65.6588 53.7631 68.856 41.8346 63.4704 32.5064C58.0847 23.1782 46.1557 19.9827 36.8262 25.3691C27.4967 30.7555 24.2995 42.6841 29.6852 52.0123C35.0708 61.3405 47.0001 64.5359 56.3293 59.1495Z" stroke="url(#paint7_linear)" strokeWidth="0.6"/>
|
||||
<path d="M57.9492 61.9564C67.8667 56.2305 71.2646 43.5487 65.5385 33.6308C59.8124 23.7129 47.1307 20.3147 37.2132 26.0406C27.2956 31.7664 23.8978 44.4482 29.6239 54.3661C35.35 64.284 48.0317 67.6823 57.9492 61.9564Z" stroke="url(#paint8_linear)" strokeWidth="0.6"/>
|
||||
<path d="M59.5832 64.788C70.104 58.7138 73.7088 45.2609 67.6347 34.7402C61.5606 24.2195 48.1077 20.6149 37.5868 26.6892C27.0659 32.7634 23.4612 46.2162 29.5353 56.7369C35.6094 67.2576 49.0623 70.8623 59.5832 64.788Z" stroke="url(#paint9_linear)" strokeWidth="0.6"/>
|
||||
<path d="M77.3353 53.9649C75.6778 68.1777 62.8087 78.3548 48.5983 76.6937C34.3841 75.0349 24.2075 62.1707 25.8712 47.9595C27.5286 33.7467 40.3978 23.5695 54.6081 25.2307C68.8224 26.8895 78.999 39.7537 77.3353 53.9649Z" stroke="url(#paint10_linear)" strokeWidth="0.6"/>
|
||||
<path d="M79.5896 56.4701C77.5065 71.3716 63.7371 81.7627 48.8364 79.6828C33.9358 77.603 23.5412 63.8311 25.6244 48.9296C27.7075 34.0281 41.4769 23.637 56.3776 25.7169C71.2805 27.8007 81.6728 41.5686 79.5896 56.4701Z" stroke="url(#paint11_linear)" strokeWidth="0.6"/>
|
||||
<path d="M81.8459 58.9799C79.3371 74.5701 64.6657 85.1813 49.0742 82.6726C33.4849 80.1677 22.873 65.4985 25.3795 49.9043C27.8882 34.3142 42.5596 23.7029 58.1512 26.2116C73.7428 28.7204 84.3524 43.3857 81.8459 58.9799Z" stroke="url(#paint12_linear)" strokeWidth="0.6"/>
|
||||
<svg className={className} viewBox="0 0 86 88" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g opacity="0.9">
|
||||
<path d="M72.9676 74.6603C80.1714 67.289 72.5959 47.586 56.0472 30.6525C39.4986 13.719 20.2435 5.96732 13.0397 13.3386C5.83591 20.7099 13.4114 40.4129 29.9601 57.3464C46.5087 74.2799 65.7639 82.0316 72.9676 74.6603Z" stroke="url(#paint0_linear)" strokeWidth="2" strokeMiterlimit="10"></path>
|
||||
<path d="M69.1024 78.6075C76.3062 71.2362 68.7307 51.5333 52.182 34.5998C35.6334 17.6663 16.3782 9.91459 9.17444 17.2859C1.97067 24.6572 9.54619 44.3601 26.0948 61.2936C42.6435 78.2271 61.8986 85.9788 69.1024 78.6075Z" stroke="url(#paint0_linear)" strokeWidth="2" strokeMiterlimit="10"></path>
|
||||
<path d="M74.8934 72.6837C82.0972 65.3124 74.5217 45.6095 57.973 28.676C41.4244 11.7425 22.1692 3.99076 14.9655 11.3621C7.76168 18.7334 15.3372 38.4363 31.8859 55.3698C48.4345 72.3033 67.6896 80.055 74.8934 72.6837Z" stroke="url(#paint0_linear)" strokeWidth="2" strokeMiterlimit="10"></path>
|
||||
<path d="M78.7587 68.7345C85.9624 61.3632 78.3869 41.6602 61.8383 24.7267C45.2896 7.79324 26.0345 0.0415411 18.8307 7.41284C11.6269 14.7841 19.2024 34.4871 35.7511 51.4206C52.2997 68.3541 71.5549 76.1058 78.7587 68.7345Z" stroke="url(#paint0_linear)" strokeWidth="2" strokeMiterlimit="10"></path>
|
||||
<path d="M80.6844 66.7579C87.8882 59.3866 80.3127 39.6837 63.764 22.7502C47.2154 5.81667 27.9602 -1.93502 20.7565 5.43628C13.5527 12.8076 21.1282 32.5105 37.6769 49.444C54.2255 66.3775 73.4807 74.1292 80.6844 66.7579Z" stroke="url(#paint0_linear)" strokeWidth="2" strokeMiterlimit="10"></path>
|
||||
<path d="M76.827 70.7091C84.0308 63.3378 76.4553 43.6349 59.9066 26.7013C43.358 9.76785 24.1028 2.01615 16.8991 9.38745C9.69528 16.7588 17.2708 36.4617 33.8194 53.3952C50.3681 70.3287 69.6232 78.0804 76.827 70.7091Z" stroke="url(#paint0_linear)" strokeWidth="2" strokeMiterlimit="10"></path>
|
||||
<path d="M71.034 76.6349C78.2378 69.2636 70.6623 49.5606 54.1136 32.6271C37.565 15.6936 18.3099 7.94193 11.1061 15.3132C3.90231 22.6845 11.4778 42.3875 28.0265 59.321C44.5751 76.2545 63.8303 84.0062 71.034 76.6349Z" stroke="url(#paint0_linear)" strokeWidth="2" strokeMiterlimit="10"></path>
|
||||
<path d="M63.3055 84.5392C70.5093 77.1679 62.9338 57.4649 46.3851 40.5314C29.8365 23.5979 10.5813 15.8462 3.37757 23.2175C-3.8262 30.5888 3.74932 50.2918 20.298 67.2253C36.8466 84.1588 56.1018 91.9105 63.3055 84.5392Z" stroke="url(#paint0_linear)" strokeWidth="2" strokeMiterlimit="10"></path>
|
||||
<path d="M67.1747 80.586C74.3784 73.2147 66.8029 53.5118 50.2543 36.5783C33.7056 19.6448 14.4505 11.8931 7.24671 19.2644C0.0429349 26.6357 7.61846 46.3386 24.1671 63.2721C40.7158 80.2056 59.9709 87.9573 67.1747 80.586Z" stroke="url(#paint0_linear)" strokeWidth="2" strokeMiterlimit="10"></path>
|
||||
<path d="M65.243 82.5606C72.4468 75.1893 64.8713 55.4864 48.3226 38.5529C31.774 21.6194 12.5188 13.8677 5.31507 21.239C-1.88871 28.6103 5.68682 48.3133 22.2355 65.2468C38.7841 82.1803 58.0393 89.932 65.243 82.5606Z" stroke="url(#paint0_linear)" strokeWidth="2" strokeMiterlimit="10"></path>
|
||||
<path d="M82.6141 64.7794C89.8179 57.4081 82.2424 37.7052 65.6937 20.7717C49.1451 3.83816 29.8899 -3.91354 22.6862 3.45777C15.4824 10.8291 23.0579 30.532 39.6066 47.4655C56.1552 64.399 75.4103 72.1507 82.6141 64.7794Z" stroke="url(#paint0_linear)" strokeWidth="2" strokeMiterlimit="10"></path>
|
||||
</g>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear" x1="0" y1="26" x2="35" y2="-2" gradientUnits="userSpaceOnUse">
|
||||
<stop stopColor="#8258C8"></stop>
|
||||
<stop offset="0.315" stopColor="#6766C8"></stop>
|
||||
<stop offset="1" stopColor="#2C84C8"></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
export function FanIcon({ className = "" }: { className?: string }) {
|
||||
return (
|
||||
<svg className={className} viewBox="0 0 88 80" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g opacity="0.9">
|
||||
<path d="M87.7358 51.8843C88.5393 40.4428 69.6078 29.7137 45.4514 27.92C21.2949 26.1264 1.06085 33.9474 0.257442 45.3889C-0.545971 56.8303 18.3854 67.5595 42.5419 69.3532C66.6984 71.1468 86.9324 63.3257 87.7358 51.8843Z" stroke="url(#paint0_linear)" strokeWidth="0.8" strokeMiterlimit="10"></path>
|
||||
<path d="M86.1273 49.4961C86.4426 38.3099 67.5487 28.671 43.9267 27.9671C20.3047 27.2631 0.899755 35.7606 0.584497 46.9468C0.269239 58.133 19.1631 67.7718 42.7851 68.4758C66.4071 69.1798 85.8121 60.6822 86.1273 49.4961Z" stroke="url(#paint0_linear)" strokeWidth="0.8" strokeMiterlimit="10"></path>
|
||||
<path d="M43.0465 67.609C66.1301 67.2237 84.7032 58.0488 84.5306 47.1164C84.358 36.1839 65.5051 27.6338 42.4216 28.0191C19.338 28.4044 0.764905 37.5793 0.937486 48.5117C1.11007 59.4442 19.9629 67.9943 43.0465 67.609Z" stroke="url(#paint0_linear)" strokeWidth="0.8" strokeMiterlimit="10"></path>
|
||||
<path d="M43.2948 66.7346C65.8425 65.2596 83.5855 55.4071 82.9249 44.7284C82.2642 34.0497 63.4501 26.5887 40.9024 28.0637C18.3547 29.5387 0.611718 39.3911 1.27235 50.0698C1.93298 60.7485 20.7471 68.2095 43.2948 66.7346Z" stroke="url(#paint0_linear)" strokeWidth="0.8" strokeMiterlimit="10"></path>
|
||||
<path d="M43.5405 65.8641C65.5549 63.3009 82.4707 52.7731 81.323 42.3497C80.1753 31.9264 61.3986 25.5544 39.3841 28.1177C17.3697 30.6809 0.453861 41.2086 1.6016 51.632C2.74933 62.0554 21.526 68.4273 43.5405 65.8641Z" stroke="url(#paint0_linear)" strokeWidth="0.8" strokeMiterlimit="10"></path>
|
||||
<path d="M43.7803 65.0011C65.2575 61.3489 81.3422 50.1424 79.7064 39.9708C78.0706 29.7992 59.3338 24.5142 37.8567 28.1664C16.3795 31.8186 0.294806 43.025 1.93058 53.1966C3.56635 63.3683 22.3031 68.6533 43.7803 65.0011Z" stroke="url(#paint0_linear)" strokeWidth="0.8" strokeMiterlimit="10"></path>
|
||||
<path d="M44.0316 64.1276C64.974 59.3849 80.2298 47.5022 78.1062 37.5869C75.9827 27.6716 57.284 23.4784 36.3416 28.2211C15.3991 32.9639 0.143341 44.8465 2.26688 54.7618C4.39041 64.6771 23.0891 68.8703 44.0316 64.1276Z" stroke="url(#paint0_linear)" strokeWidth="0.8" strokeMiterlimit="10"></path>
|
||||
</g>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear" x1="0" y1="26" x2="35" y2="-2" gradientUnits="userSpaceOnUse">
|
||||
<stop stopColor="#8258C8"></stop>
|
||||
<stop offset="0.315" stopColor="#6766C8"></stop>
|
||||
<stop offset="1" stopColor="#2C84C8"></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
export function CirclesIcon({ className = "" }: { className?: string }) {
|
||||
return (
|
||||
<svg className={className} viewBox="0 0 84 84" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g opacity="0.9">
|
||||
<path d="M41.9976 83C64.64 83 82.9952 64.6437 82.9952 42C82.9952 19.3563 64.64 1 41.9976 1C19.3553 1 1 19.3563 1 42C1 64.6437 19.3553 83 41.9976 83Z" stroke="url(#paint0_linear)" strokeMiterlimit="10"></path>
|
||||
<path d="M82.0594 41.1137C82.0909 43.1738 82.0144 45.1755 81.7758 47.1501C81.1772 52.0351 79.611 56.722 77.2346 60.8963C75.6728 63.6356 73.8365 66.15 71.8381 68.4845C69.8173 70.8505 67.5579 72.9646 64.9789 74.7998C61.9679 76.9409 58.6013 78.6412 54.9872 79.7702C52.5298 80.5439 49.9823 81.0567 47.3764 81.3131C45.7156 81.475 44.0368 81.5245 42.322 81.4885C39.9996 81.439 37.7132 81.2186 35.4763 80.8408C34.1846 80.6203 32.9109 80.355 31.6642 80.0266C25.6781 78.4568 20.1557 75.6365 15.6864 71.5432C14.2776 70.2523 12.9589 68.8669 11.7212 67.4005C10.2449 65.6552 8.8857 63.8155 7.68849 61.8768C6.49578 59.9517 5.46961 57.932 4.60546 55.8179C3.88533 54.0592 3.30023 52.233 2.87266 50.3483C2.23354 47.555 1.94099 44.6357 1.9995 41.6445C2.04001 39.2875 2.28755 36.98 2.68812 34.7219C3.79982 28.4651 6.07271 22.7121 9.64633 17.7507C12.1263 14.3187 15.2003 11.3319 18.6659 8.91196C22.1045 6.50998 25.9347 4.65228 30.0394 3.39731C33.8875 2.21881 37.9878 1.5576 42.205 1.49013C49.1632 1.38217 55.7118 3.10943 61.4548 6.21311C67.2653 9.35727 72.2072 13.9318 75.7628 19.4779C79.7685 25.7258 81.9424 33.1611 82.0639 41.1137H82.0594Z" stroke="url(#paint0_linear)" strokeMiterlimit="10"></path>
|
||||
<path d="M81.1161 40.2325C81.1791 42.2566 81.1881 44.2133 81.0081 46.1475C80.5625 50.9424 79.0773 55.6294 76.6963 59.7542C75.1211 62.471 73.3072 64.936 71.4394 67.2975C69.5581 69.6679 67.4697 71.7955 64.9673 73.6622C62.0418 75.8393 58.7157 77.5441 55.1151 78.6101C52.6757 79.3388 50.1507 79.7796 47.5988 79.9595C45.9695 80.0675 44.3267 80.0585 42.6479 79.9865C40.3885 79.8876 38.1472 79.6492 35.9553 79.2803C34.6861 79.0689 33.4393 78.8215 32.2151 78.5202C26.3596 77.0628 20.8597 74.4809 16.5389 70.3786C15.1842 69.0922 13.9195 67.7158 12.7087 66.2764C11.2685 64.5626 9.90476 62.7814 8.69855 60.9237C7.49684 59.0795 6.46166 57.1498 5.566 55.1212C4.81887 53.4254 4.21127 51.6576 3.78369 49.8224C3.14008 47.0966 2.88804 44.2313 3.00056 41.2941C3.08607 38.991 3.36512 36.733 3.77019 34.5154C4.89089 28.3621 6.86223 22.7125 10.3323 17.7871C12.7357 14.391 15.7963 11.4718 19.2259 9.14628C22.633 6.83427 26.4136 5.08451 30.4508 3.89252C34.245 2.7725 38.2822 2.11128 42.4004 1.98534C49.1336 1.77393 55.4842 3.37974 61.1011 6.33948C66.7721 9.3397 71.6105 13.7658 75.0536 19.1725C78.9332 25.2719 80.8776 32.5138 81.1206 40.228L81.1161 40.2325Z" stroke="url(#paint0_linear)" strokeMiterlimit="10"></path>
|
||||
</g>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear" x1="0" y1="26" x2="35" y2="-2" gradientUnits="userSpaceOnUse">
|
||||
<stop stopColor="#8258C8"></stop>
|
||||
<stop offset="0.315" stopColor="#6766C8"></stop>
|
||||
<stop offset="1" stopColor="#2C84C8"></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
export function ExpandIcon({ className = "" }: { className?: string }) {
|
||||
return (
|
||||
<svg className={className} viewBox="0 0 86 88" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g opacity="0.9">
|
||||
<path d="M45.74 40.8109C51.6726 37.3857 53.7055 29.8003 50.2807 23.8683C46.8559 17.9363 39.2702 15.9042 33.3376 19.3294C27.405 22.7546 25.3721 30.3401 28.7969 36.2721C32.2217 42.2041 39.8074 44.2361 45.74 40.8109Z" stroke="url(#paint0_linear)" strokeWidth="0.6"/>
|
||||
<path d="M47.1284 43.216C53.426 39.58 55.5842 31.528 51.9488 25.2313C48.3134 18.9346 40.2611 16.7777 33.9634 20.4136C27.6658 24.0496 25.5076 32.1016 29.143 38.3982C32.7784 44.6949 40.8307 46.8518 47.1284 43.216Z" stroke="url(#paint1_linear)" strokeWidth="0.6"/>
|
||||
<path d="M48.5691 45.7111C55.2842 41.8341 57.5856 33.2485 53.7094 26.5346C49.8331 19.8208 41.2471 17.521 34.5319 21.398C27.8168 25.275 25.5154 33.8606 29.3916 40.5745C33.2679 47.2883 41.8539 49.5881 48.5691 45.7111Z" stroke="url(#paint2_linear)" strokeWidth="0.6"/>
|
||||
<path d="M50.0791 48.2764C57.2512 44.1205 59.6971 34.9389 55.5422 27.7685C51.3874 20.5981 42.205 18.1543 35.0329 22.3102C27.8609 26.466 25.415 35.6477 29.5698 42.8181C33.7247 49.9885 42.9071 52.4322 50.0791 48.2764Z" stroke="url(#paint3_linear)" strokeWidth="0.6"/>
|
||||
<path d="M51.5834 50.9308C59.2604 46.4985 61.8917 36.6837 57.4607 29.0089C53.0296 21.334 43.2141 18.7054 35.5371 23.1377C27.8601 27.57 25.2288 37.3848 29.6599 45.0596C34.091 52.7345 43.9065 55.3631 51.5834 50.9308Z" stroke="url(#paint4_linear)" strokeWidth="0.6"/>
|
||||
<path d="M53.1404 53.6281C61.3442 48.8916 64.1552 38.4018 59.419 30.1984C54.6827 21.995 44.1928 19.1845 35.989 23.921C27.7852 28.6574 24.9742 39.1472 29.7105 47.3506C34.4467 55.554 44.9366 58.3645 53.1404 53.6281Z" stroke="url(#paint5_linear)" strokeWidth="0.6"/>
|
||||
<path d="M54.7248 56.3733C63.4817 51.3175 66.4824 40.1209 61.4271 31.3649C56.3718 22.609 45.1749 19.6093 36.4181 24.6651C27.6613 29.7208 24.6606 40.9175 29.7159 49.6734C34.7711 58.4294 45.968 61.429 54.7248 56.3733Z" stroke="url(#paint6_linear)" strokeWidth="0.6"/>
|
||||
<path d="M56.3293 59.1495C65.6588 53.7631 68.856 41.8346 63.4704 32.5064C58.0847 23.1782 46.1557 19.9827 36.8262 25.3691C27.4967 30.7555 24.2995 42.6841 29.6852 52.0123C35.0708 61.3405 47.0001 64.5359 56.3293 59.1495Z" stroke="url(#paint7_linear)" strokeWidth="0.6"/>
|
||||
<path d="M57.9492 61.9564C67.8667 56.2305 71.2646 43.5487 65.5385 33.6308C59.8124 23.7129 47.1307 20.3147 37.2132 26.0406C27.2956 31.7664 23.8978 44.4482 29.6239 54.3661C35.35 64.284 48.0317 67.6823 57.9492 61.9564Z" stroke="url(#paint8_linear)" strokeWidth="0.6"/>
|
||||
<path d="M59.5832 64.788C70.104 58.7138 73.7088 45.2609 67.6347 34.7402C61.5606 24.2195 48.1077 20.6149 37.5868 26.6892C27.0659 32.7634 23.4612 46.2162 29.5353 56.7369C35.6094 67.2576 49.0623 70.8623 59.5832 64.788Z" stroke="url(#paint9_linear)" strokeWidth="0.6"/>
|
||||
<path d="M77.3353 53.9649C75.6778 68.1777 62.8087 78.3548 48.5983 76.6937C34.3841 75.0349 24.2075 62.1707 25.8712 47.9595C27.5286 33.7467 40.3978 23.5695 54.6081 25.2307C68.8224 26.8895 78.999 39.7537 77.3353 53.9649Z" stroke="url(#paint10_linear)" strokeWidth="0.6"/>
|
||||
<path d="M79.5896 56.4701C77.5065 71.3716 63.7371 81.7627 48.8364 79.6828C33.9358 77.603 23.5412 63.8311 25.6244 48.9296C27.7075 34.0281 41.4769 23.637 56.3776 25.7169C71.2805 27.8007 81.6728 41.5686 79.5896 56.4701Z" stroke="url(#paint11_linear)" strokeWidth="0.6"/>
|
||||
<path d="M81.8459 58.9799C79.3371 74.5701 64.6657 85.1813 49.0742 82.6726C33.4849 80.1677 22.873 65.4985 25.3795 49.9043C27.8882 34.3142 42.5596 23.7029 58.1512 26.2116C73.7428 28.7204 84.3524 43.3857 81.8459 58.9799Z" stroke="url(#paint12_linear)" strokeWidth="0.6"/>
|
||||
</g>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear" x1="1.76204" y1="0.999985" x2="96.3599" y2="20.9846" gradientUnits="userSpaceOnUse"><stop stopColor="#8258C8"/><stop offset="0.315" stopColor="#6766C8"/><stop offset="1" stopColor="#2C84C8"/></linearGradient>
|
||||
<linearGradient id="paint1_linear" x1="2.73637" y1="1.48534" x2="95.1113" y2="21.0161" gradientUnits="userSpaceOnUse"><stop stopColor="#8258C8"/><stop offset="0.315" stopColor="#6766C8"/><stop offset="1" stopColor="#2C84C8"/></linearGradient>
|
||||
@@ -32,50 +103,3 @@ export function OrbitIcon({ className = "" }: { className?: string }) {
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
export function FanIcon({ className = "" }: { className?: string }) {
|
||||
return (
|
||||
<svg className={className} viewBox="0 0 78 88" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M48.5691 45.7111C55.2842 41.8341 57.5856 33.2485 53.7094 26.5346C49.8331 19.8208 41.2471 17.521 34.5319 21.398C27.8168 25.275 25.5154 33.8606 29.3916 40.5745C33.2679 47.2883 41.8539 49.5881 48.5691 45.7111Z" stroke="url(#paint0_linear)" strokeWidth="0.6"/>
|
||||
<path d="M50.0791 48.2764C57.2512 44.1205 59.6971 34.9389 55.5422 27.7685C51.3874 20.5981 42.205 18.1543 35.0329 22.3102C27.8609 26.466 25.415 35.6477 29.5698 42.8181C33.7247 49.9885 42.9071 52.4322 50.0791 48.2764Z" stroke="url(#paint1_linear)" strokeWidth="0.6"/>
|
||||
<path d="M51.5834 50.9308C59.2604 46.4985 61.8917 36.6837 57.4607 29.0089C53.0296 21.334 43.2141 18.7054 35.5371 23.1377C27.8601 27.57 25.2288 37.3848 29.6599 45.0596C34.091 52.7345 43.9065 55.3631 51.5834 50.9308Z" stroke="url(#paint2_linear)" strokeWidth="0.6"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear" x1="1.76204" y1="0.999985" x2="96.3599" y2="20.9846" gradientUnits="userSpaceOnUse"><stop stopColor="#8258C8"/><stop offset="0.315" stopColor="#6766C8"/><stop offset="1" stopColor="#2C84C8"/></linearGradient>
|
||||
<linearGradient id="paint1_linear" x1="2.73637" y1="1.48534" x2="95.1113" y2="21.0161" gradientUnits="userSpaceOnUse"><stop stopColor="#8258C8"/><stop offset="0.315" stopColor="#6766C8"/><stop offset="1" stopColor="#2C84C8"/></linearGradient>
|
||||
<linearGradient id="paint2_linear" x1="3.70122" y1="1.96678" x2="93.8892" y2="21.0474" gradientUnits="userSpaceOnUse"><stop stopColor="#8258C8"/><stop offset="0.315" stopColor="#6766C8"/><stop offset="1" stopColor="#2C84C8"/></linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
export function CirclesIcon({ className = "" }: { className?: string }) {
|
||||
return (
|
||||
<svg className={className} viewBox="0 0 78 88" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="39" cy="44" r="30" stroke="url(#paint0_linear)" strokeWidth="0.6"/>
|
||||
<circle cx="39" cy="44" r="25" stroke="url(#paint1_linear)" strokeWidth="0.6"/>
|
||||
<circle cx="39" cy="44" r="20" stroke="url(#paint2_linear)" strokeWidth="0.6"/>
|
||||
<circle cx="39" cy="44" r="15" stroke="url(#paint3_linear)" strokeWidth="0.6"/>
|
||||
<circle cx="39" cy="44" r="10" stroke="url(#paint4_linear)" strokeWidth="0.6"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear" x1="9" y1="14" x2="69" y2="74" gradientUnits="userSpaceOnUse"><stop stopColor="#8258C8"/><stop offset="0.315" stopColor="#6766C8"/><stop offset="1" stopColor="#2C84C8"/></linearGradient>
|
||||
<linearGradient id="paint1_linear" x1="14" y1="19" x2="64" y2="69" gradientUnits="userSpaceOnUse"><stop stopColor="#8258C8"/><stop offset="0.315" stopColor="#6766C8"/><stop offset="1" stopColor="#2C84C8"/></linearGradient>
|
||||
<linearGradient id="paint2_linear" x1="19" y1="24" x2="59" y2="64" gradientUnits="userSpaceOnUse"><stop stopColor="#8258C8"/><stop offset="0.315" stopColor="#6766C8"/><stop offset="1" stopColor="#2C84C8"/></linearGradient>
|
||||
<linearGradient id="paint3_linear" x1="24" y1="29" x2="54" y2="59" gradientUnits="userSpaceOnUse"><stop stopColor="#8258C8"/><stop offset="0.315" stopColor="#6766C8"/><stop offset="1" stopColor="#2C84C8"/></linearGradient>
|
||||
<linearGradient id="paint4_linear" x1="29" y1="34" x2="49" y2="54" gradientUnits="userSpaceOnUse"><stop stopColor="#8258C8"/><stop offset="0.315" stopColor="#6766C8"/><stop offset="1" stopColor="#2C84C8"/></linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
export function ExpandIcon({ className = "" }: { className?: string }) {
|
||||
return (
|
||||
<svg className={className} viewBox="0 0 78 88" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M45.74 40.8109C51.6726 37.3857 53.7055 29.8003 50.2807 23.8683C46.8559 17.9363 39.2702 15.9042 33.3376 19.3294C27.405 22.7546 25.3721 30.3401 28.7969 36.2721C32.2217 42.2041 39.8074 44.2361 45.74 40.8109Z" stroke="url(#paint0_linear)" strokeWidth="0.6"/>
|
||||
<path d="M48.5691 45.7111C55.2842 41.8341 57.5856 33.2485 53.7094 26.5346C49.8331 19.8208 41.2471 17.521 34.5319 21.398C27.8168 25.275 25.5154 33.8606 29.3916 40.5745C33.2679 47.2883 41.8539 49.5881 48.5691 45.7111Z" stroke="url(#paint1_linear)" strokeWidth="0.6"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear" x1="1.76204" y1="0.999985" x2="96.3599" y2="20.9846" gradientUnits="userSpaceOnUse"><stop stopColor="#8258C8"/><stop offset="0.315" stopColor="#6766C8"/><stop offset="1" stopColor="#2C84C8"/></linearGradient>
|
||||
<linearGradient id="paint1_linear" x1="3.70122" y1="1.96678" x2="93.8892" y2="21.0474" gradientUnits="userSpaceOnUse"><stop stopColor="#8258C8"/><stop offset="0.315" stopColor="#6766C8"/><stop offset="1" stopColor="#2C84C8"/></linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user