forked from emre/www_projectmycelium_com
feat: redesign pods page with enhanced UI and animations
- Replaced HomeBlink with HomeAurora component for improved visual experience - Added PodCapabilities horizontal slider with interactive navigation controls - Created PodsFeatures section showcasing use cases with hover animations - Updated PodsHow layout with bullet points and new PodsFlow animation component
This commit is contained in:
@@ -5,7 +5,7 @@ import { CallToAction } from './CallToAction'
|
||||
import { HomeTab } from './HomeTab'
|
||||
import { HomeMap } from './HomeMap'
|
||||
import { HomeAudience } from './HomeAudience'
|
||||
import { HomeBlink } from './HomeBlink'
|
||||
import { HomeAurora } from './HomeAurora'
|
||||
import { HomeArchitecture } from './HomeArchitecture';
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ export default function HomePage() {
|
||||
return (
|
||||
<div>
|
||||
<AnimatedSection>
|
||||
<HomeBlink onGetStartedClick={handleScrollToSlider} />
|
||||
<HomeAurora onGetStartedClick={handleScrollToSlider} />
|
||||
</AnimatedSection>
|
||||
|
||||
<AnimatedSection>
|
||||
|
||||
151
src/pages/pods/PodCapabilities.tsx
Normal file
151
src/pages/pods/PodCapabilities.tsx
Normal file
@@ -0,0 +1,151 @@
|
||||
"use client";
|
||||
|
||||
import { useRef } from "react";
|
||||
import { Eyebrow, CP, CT, H4 } from "@/components/Texts";
|
||||
import { IoArrowBackOutline, IoArrowForwardOutline } from "react-icons/io5";
|
||||
|
||||
import {
|
||||
HomeModernIcon,
|
||||
CpuChipIcon,
|
||||
ServerStackIcon,
|
||||
ShieldCheckIcon,
|
||||
} from "@heroicons/react/24/solid";
|
||||
|
||||
const capabilities = [
|
||||
{
|
||||
isIntro: true,
|
||||
eyebrow: "CAPABILITIES",
|
||||
title: "What is a Pod?",
|
||||
description: "",
|
||||
},
|
||||
|
||||
{
|
||||
title: "Your private digital home on the decentralized internet",
|
||||
description:
|
||||
"Your Pod is a private digital home where apps, data, and identity live independently of Big Tech and central servers.",
|
||||
icon: (
|
||||
<div className="flex items-start justify-start">
|
||||
<HomeModernIcon className="h-12 w-12 text-cyan-400" />
|
||||
</div>
|
||||
),
|
||||
},
|
||||
|
||||
{
|
||||
title: "An always-on space you fully control",
|
||||
description:
|
||||
"A dedicated, always-on environment you fully command — your own sovereign slice of the network that never goes offline.",
|
||||
icon: (
|
||||
<div className="flex items-start justify-start">
|
||||
<CpuChipIcon className="h-12 w-12 text-cyan-400" />
|
||||
</div>
|
||||
),
|
||||
},
|
||||
|
||||
{
|
||||
title: "Runs communication, storage, and collaboration tools",
|
||||
description:
|
||||
"Runs your communication, storage, and collaboration tools in a secure local environment without reliance on outside platforms.",
|
||||
icon: (
|
||||
<div className="flex items-start justify-start">
|
||||
<ServerStackIcon className="h-12 w-12 text-cyan-400" />
|
||||
</div>
|
||||
),
|
||||
},
|
||||
|
||||
{
|
||||
title: "Fully encrypted, federated peer-to-peer network",
|
||||
description:
|
||||
"Encrypted, federated peer-to-peer networking that links your Pod directly with trusted devices without intermediaries.",
|
||||
icon: (
|
||||
<div className="flex items-start justify-start">
|
||||
<ShieldCheckIcon className="h-12 w-12 text-cyan-400" />
|
||||
</div>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
export function PodCapabilities() {
|
||||
const sliderRef = useRef<HTMLUListElement>(null);
|
||||
|
||||
const scrollLeft = () =>
|
||||
sliderRef.current?.scrollBy({ left: -400, behavior: "smooth" });
|
||||
|
||||
const scrollRight = () =>
|
||||
sliderRef.current?.scrollBy({ left: 400, behavior: "smooth" });
|
||||
|
||||
return (
|
||||
<section className="bg-[#121212] w-full max-w-8xl mx-auto">
|
||||
<div className="max-w-7xl mx-auto py-6 border border-t-0 border-b-0 border-gray-800" />
|
||||
<div className="w-full border-t border-l border-r border-gray-800" />
|
||||
|
||||
<div className="relative mx-auto max-w-7xl border border-t-0 border-b-0 border-gray-800 bg-[#111111] overflow-hidden">
|
||||
{/* Horizontal Slider */}
|
||||
<ul
|
||||
ref={sliderRef}
|
||||
className="flex overflow-x-auto snap-x snap-mandatory scroll-smooth no-scrollbar"
|
||||
>
|
||||
{capabilities.map((item, idx) => (
|
||||
<li
|
||||
key={idx}
|
||||
className={`snap-start shrink-0 w-[85%] sm:w-[50%] lg:w-[33%] border border-gray-800 p-10 relative ${
|
||||
item.isIntro ? "" : "bg-[#111]/60"
|
||||
}`}
|
||||
>
|
||||
{/* INTRO CARD */}
|
||||
{item.isIntro ? (
|
||||
<div className="flex flex-col justify-between h-full">
|
||||
<div>
|
||||
<Eyebrow>{item.eyebrow}</Eyebrow>
|
||||
<H4 className="text-white mt-0 max-w-lg">{item.title}</H4>
|
||||
<p className="text-gray-400 lg:text-lg text-sm leading-relaxed">
|
||||
{item.description}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Arrow controls */}
|
||||
<div className="flex items-center gap-x-4 mt-2">
|
||||
<button
|
||||
onClick={scrollLeft}
|
||||
className="h-8 w-8 flex items-center justify-center border border-gray-800 rounded-md hover:border-cyan-500 transition-colors"
|
||||
>
|
||||
<IoArrowBackOutline className="text-gray-300" size={16} />
|
||||
</button>
|
||||
|
||||
<button
|
||||
onClick={scrollRight}
|
||||
className="h-8 w-8 flex items-center justify-center border border-gray-800 rounded-md hover:border-cyan-500 transition-colors"
|
||||
>
|
||||
<IoArrowForwardOutline
|
||||
className="text-gray-300"
|
||||
size={16}
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
{/* LEFT-ALIGNED ICON */}
|
||||
{item.icon}
|
||||
|
||||
<br />
|
||||
|
||||
{/* LEFT-ALIGNED TEXT */}
|
||||
<CT className="font-semibold leading-tight text-white text-left">
|
||||
{item.title}
|
||||
</CT>
|
||||
|
||||
<CP className="mt-2 text-gray-400 text-left">
|
||||
{item.description}
|
||||
</CP>
|
||||
</>
|
||||
)}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div className="w-full border-b border-gray-800" />
|
||||
<div className="max-w-7xl mx-auto py-6 border border-t-0 border-b-0 border-gray-800" />
|
||||
</section>
|
||||
);
|
||||
}
|
||||
142
src/pages/pods/PodsFeatures.tsx
Normal file
142
src/pages/pods/PodsFeatures.tsx
Normal file
@@ -0,0 +1,142 @@
|
||||
"use client";
|
||||
|
||||
import { Container } from "@/components/Container";
|
||||
import { CP, Small } from "@/components/Texts";
|
||||
|
||||
const useCases = [
|
||||
{
|
||||
title: "Private Messaging & Calling",
|
||||
description:
|
||||
"Communicate directly Pod-to-Pod with no centralized routing.",
|
||||
bullets: [
|
||||
"End-to-end encrypted messaging and voice calling.",
|
||||
"No intermediaries — connections flow directly between Pods.",
|
||||
"Zero metadata profiling, tracking, or data resale.",
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Safe File Storage & Sharing",
|
||||
description:
|
||||
"Store and share files securely without exposing data to third parties.",
|
||||
bullets: [
|
||||
"Files remain private with no platform-level scanning or analysis.",
|
||||
"Share documents and media directly with trusted contacts.",
|
||||
"Full ownership of your content — no cloud vendor dependencies.",
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Personal Calendar & Meetings",
|
||||
description:
|
||||
"Manage your schedule within your own sovereign digital space.",
|
||||
bullets: [
|
||||
"Keep events, appointments, and reminders fully private.",
|
||||
"Coordinate calls and meetings entirely inside your Pod.",
|
||||
"No syncing with external servers or corporate platforms.",
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Private Communities & Teams",
|
||||
description:
|
||||
"Create groups or collaborative spaces without platform ownership.",
|
||||
bullets: [
|
||||
"Form teams, friendship circles, and micro-communities.",
|
||||
"All interactions occur directly Pod-to-Pod.",
|
||||
"No hosting company or service provider controls your group data.",
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Quantum Safe File System (QSFS)",
|
||||
description:
|
||||
"Store data using a self-healing, encrypted, quantum-resistant system.",
|
||||
bullets: [
|
||||
"Files are encrypted, split, and distributed across trusted nodes.",
|
||||
"Designed to withstand future quantum-level attacks.",
|
||||
"Automatic repair and reconstruction of data fragments.",
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Access From Any Device",
|
||||
description:
|
||||
"Your Pod travels with you — always accessible, always yours.",
|
||||
bullets: [
|
||||
"Use your Pod from phones, laptops, tablets, or shared machines.",
|
||||
"Your identity, apps, and files follow you securely.",
|
||||
"No syncing or duplicated copies — direct access to your environment.",
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
export function PodsFeatures() {
|
||||
return (
|
||||
<section className="w-full max-w-8xl mx-auto bg-transparent">
|
||||
{/* Top horizontal spacing */}
|
||||
<div className="max-w-7xl bg-transparent mx-auto py-6 border border-t-0 border-b-0 border-gray-100"></div>
|
||||
<div className="w-full border-t border-l border-r border-gray-100" />
|
||||
|
||||
<Container className="py-12 border border-t-0 border-b-0 border-gray-100">
|
||||
{/* Header */}
|
||||
<div className="mx-auto max-w-4xl sm:text-center">
|
||||
<h2 className="text-base/7 font-semibold text-cyan-500">
|
||||
WHAT YOU CAN DO
|
||||
</h2>
|
||||
|
||||
<p className="text-3xl lg:text-4xl font-medium tracking-tight text-gray-900">
|
||||
A Fully Personal, Sovereign Digital Environment
|
||||
</p>
|
||||
|
||||
<p className="mt-6 text-lg text-gray-600">
|
||||
A Pod gives you a secure digital home where communication, storage,
|
||||
identity, and collaboration remain fully under your control.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Cards */}
|
||||
<ul
|
||||
role="list"
|
||||
className="mx-auto mt-12 grid max-w-2xl grid-cols-1 gap-6
|
||||
sm:grid-cols-2 lg:max-w-none lg:grid-cols-3 md:gap-y-10"
|
||||
>
|
||||
{useCases.map((useCase) => (
|
||||
<li
|
||||
key={useCase.title}
|
||||
className="rounded-md border border-gray-100 bg-white p-6 transition-all duration-300
|
||||
hover:scale-105 hover:border-cyan-500 hover:shadow-lg hover:shadow-cyan-500/20 flex flex-col"
|
||||
>
|
||||
{/* Title + label */}
|
||||
<div className="flex items-center justify-between">
|
||||
<h3 className="font-semibold text-gray-900">
|
||||
{useCase.title}
|
||||
</h3>
|
||||
<Small className="uppercase tracking-[0.25em] text-cyan-500">
|
||||
Feature
|
||||
</Small>
|
||||
</div>
|
||||
|
||||
{/* Short description */}
|
||||
<p className="mt-4 text-gray-700 leading-snug">
|
||||
{useCase.description}
|
||||
</p>
|
||||
|
||||
{/* Bullet list */}
|
||||
<ul className="mt-6 space-y-3 text-sm text-gray-600">
|
||||
{useCase.bullets.map((bullet) => (
|
||||
<li
|
||||
key={bullet}
|
||||
className="flex items-start gap-3 rounded-2xl border border-cyan-100 bg-cyan-50/60 p-3 leading-relaxed"
|
||||
>
|
||||
<span className="mt-1 inline-block size-2 rounded-full bg-cyan-500" />
|
||||
<span>{bullet}</span>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</Container>
|
||||
|
||||
{/* Bottom spacing */}
|
||||
<div className="w-full border-b border-gray-100" />
|
||||
<div className="max-w-7xl bg-transparent mx-auto py-6 border border-t-0 border-b-0 border-gray-100"></div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { Eyebrow, H3, P } from "@/components/Texts";
|
||||
import CloudPods from "./animations/CloudPods";
|
||||
import PodsFlow from "./animations/PodsFlow";
|
||||
|
||||
export function PodsHow() {
|
||||
return (
|
||||
@@ -13,34 +13,40 @@ export function PodsHow() {
|
||||
<div className="max-w-7xl mx-auto px-6 lg:px-8 py-12 border border-t-0 border-b-0 border-gray-800 bg-[#111111] overflow-hidden">
|
||||
|
||||
{/* ✅ Two-column layout */}
|
||||
<div className="flex flex-col lg:flex-row-reverse gap-16">
|
||||
<div className="flex flex-col lg:flex-row-reverse gap-8">
|
||||
|
||||
{/* ✅ Right side animation */}
|
||||
<div className="w-full lg:w-1/2">
|
||||
<CloudPods />
|
||||
<div className="w-full lg:w-4/9">
|
||||
<PodsFlow />
|
||||
</div>
|
||||
|
||||
{/* ✅ Left side content */}
|
||||
<div className="w-full lg:w-1/2 text-white">
|
||||
<div className="w-full lg:w-5/9 text-white">
|
||||
<Eyebrow color="accent" className="">
|
||||
How it works
|
||||
</Eyebrow>
|
||||
<H3 color="white" className="mt-6">
|
||||
What Living in a Pod Feels Like
|
||||
Living in a Pod
|
||||
</H3>
|
||||
<P className="max-w-3xl text-gray-400 mt-6">
|
||||
<P className="max-w-4xl text-gray-400 mt-6">
|
||||
When you use Mycelium, everything — your messages, calls, files — runs directly from your Pod.
|
||||
</P>
|
||||
<ul className="max-w-4xl text-gray-400 mt-6 space-y-3 ml-4">
|
||||
<li className="flex items-start gap-3">
|
||||
<span className="mt-1.5 inline-block size-2 rounded-full bg-cyan-400" />
|
||||
<span>When you message someone, it goes Pod to Pod, not through a central server.</span>
|
||||
</li>
|
||||
<li className="flex items-start gap-3">
|
||||
<span className="mt-1.5 inline-block size-2 rounded-full bg-cyan-400" />
|
||||
<span>When you host a call, it runs on your Pod — no third-party data centers.</span>
|
||||
</li>
|
||||
<li className="flex items-start gap-3">
|
||||
<span className="mt-1.5 inline-block size-2 rounded-full bg-cyan-400" />
|
||||
<span>When you save a file, it stays on your Pod, encrypted and always available.</span>
|
||||
</li>
|
||||
</ul>
|
||||
<P className="max-w-3xl text-gray-400 mt-4">
|
||||
It’s your personal digital hub:
|
||||
When you message someone, it goes Pod to Pod, not through a central server.
|
||||
When you host a call, it runs on your Pod — no third-party data centers.
|
||||
</P>
|
||||
<P className="max-w-3xl text-gray-400 mt-4">
|
||||
When you save a file, it stays on your Pod, encrypted and always available.
|
||||
No one else can read it, rent it, or switch it off.
|
||||
</P>
|
||||
<P className="max-w-3xl text-gray-400 mt-4">
|
||||
You don’t log in to the internet — you are part of it.
|
||||
</P>
|
||||
</div>
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
import Homepod from './Homepod';
|
||||
import { PodsCapabilities } from './PodsCapabilities';
|
||||
import { PodCapabilities } from './PodCapabilities';
|
||||
import { PodsHow } from './PodsHow';
|
||||
import { PodsFeatures } from './PodsFeatures';
|
||||
|
||||
const PodsPage = () => {
|
||||
return (
|
||||
<>
|
||||
<Homepod />
|
||||
<PodsCapabilities />
|
||||
<PodsHow />
|
||||
<PodCapabilities />
|
||||
<PodsFeatures />
|
||||
<PodsHow />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
192
src/pages/pods/animations/PodsFlow.tsx
Normal file
192
src/pages/pods/animations/PodsFlow.tsx
Normal file
@@ -0,0 +1,192 @@
|
||||
"use client";
|
||||
|
||||
import { motion } from "framer-motion";
|
||||
import clsx from "clsx";
|
||||
|
||||
type Props = {
|
||||
className?: string;
|
||||
accent?: string;
|
||||
gridStroke?: string;
|
||||
};
|
||||
|
||||
const W = 760;
|
||||
const H = 420;
|
||||
|
||||
export default function PodsFlow({
|
||||
className,
|
||||
accent = "#00b8db",
|
||||
gridStroke = "#2b2a2a",
|
||||
}: Props) {
|
||||
const pods = [
|
||||
{ x: 100, y: 180, label: "Pod 1" },
|
||||
{ x: 260, y: 180, label: "Pod 2" },
|
||||
{ x: 420, y: 180, label: "Pod 3" },
|
||||
{ x: 580, y: 180, label: "Pod 4" },
|
||||
];
|
||||
|
||||
// Pulse path
|
||||
const path = `
|
||||
M ${pods[0].x + 80} ${pods[0].y + 40}
|
||||
L ${pods[1].x - 10} ${pods[1].y + 40}
|
||||
L ${pods[1].x + 80} ${pods[1].y + 40}
|
||||
L ${pods[2].x - 10} ${pods[2].y + 40}
|
||||
L ${pods[2].x + 80} ${pods[2].y + 40}
|
||||
L ${pods[3].x - 10} ${pods[3].y + 40}
|
||||
`;
|
||||
|
||||
// Arrow segments
|
||||
const arrows = [
|
||||
{
|
||||
d: `M ${pods[0].x + 80} ${pods[0].y + 40} L ${pods[1].x - 6} ${pods[1].y + 40}`,
|
||||
end: { x: pods[1].x - 6, y: pods[1].y + 40 },
|
||||
},
|
||||
{
|
||||
d: `M ${pods[1].x + 80} ${pods[1].y + 40} L ${pods[2].x - 6} ${pods[2].y + 40}`,
|
||||
end: { x: pods[2].x - 6, y: pods[2].y + 40 },
|
||||
},
|
||||
{
|
||||
d: `M ${pods[2].x + 80} ${pods[2].y + 40} L ${pods[3].x - 6} ${pods[3].y + 40}`,
|
||||
end: { x: pods[3].x - 6, y: pods[3].y + 40 },
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<div
|
||||
className={clsx("relative overflow-hidden", className)}
|
||||
aria-hidden="true"
|
||||
role="img"
|
||||
aria-label="Pod-to-Pod signal transfer animation"
|
||||
style={{ background: "transparent" }}
|
||||
>
|
||||
<svg viewBox={`0 0 ${W} ${H}`} className="w-full h-full">
|
||||
{/* GRID BG */}
|
||||
<defs>
|
||||
<pattern id="pods-grid" width="28" height="28" patternUnits="userSpaceOnUse">
|
||||
<path d="M 28 0 L 0 0 0 28" fill="none" stroke={gridStroke} strokeWidth="1" opacity="0.6" />
|
||||
</pattern>
|
||||
|
||||
<filter id="pods-glow">
|
||||
<feGaussianBlur stdDeviation="4" result="blur" />
|
||||
<feMerge>
|
||||
<feMergeNode in="blur" />
|
||||
<feMergeNode in="SourceGraphic" />
|
||||
</feMerge>
|
||||
</filter>
|
||||
</defs>
|
||||
|
||||
<rect width={W} height={H} fill="url(#pods-grid)" />
|
||||
|
||||
{/* POD BOXES */}
|
||||
{pods.map((p, i) => (
|
||||
<motion.rect
|
||||
key={i}
|
||||
x={p.x}
|
||||
y={p.y}
|
||||
width={80}
|
||||
height={80}
|
||||
rx={14}
|
||||
fill="#0d0d0d"
|
||||
stroke="#1a1a1a"
|
||||
strokeWidth={2}
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 0.9 }}
|
||||
transition={{ duration: 0.5 + i * 0.15 }}
|
||||
/>
|
||||
))}
|
||||
|
||||
{/* POD LABELS */}
|
||||
{pods.map((p, i) => (
|
||||
<motion.text
|
||||
key={i}
|
||||
x={p.x + 40}
|
||||
y={p.y + 50}
|
||||
textAnchor="middle"
|
||||
fontSize="14"
|
||||
fontFamily="Inter, sans-serif"
|
||||
fill="#9ca3af"
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 0.9 }}
|
||||
transition={{ delay: 0.1 + i * 0.1, duration: 0.6 }}
|
||||
>
|
||||
{p.label}
|
||||
</motion.text>
|
||||
))}
|
||||
|
||||
{/* GREY LINES */}
|
||||
{arrows.map((a, i) => (
|
||||
<motion.path
|
||||
key={`grey-${i}`}
|
||||
d={a.d}
|
||||
stroke="#333"
|
||||
strokeWidth={4}
|
||||
strokeLinecap="round"
|
||||
fill="none"
|
||||
initial={{ pathLength: 0, opacity: 0 }}
|
||||
animate={{ pathLength: 1, opacity: 0.8 }}
|
||||
transition={{ delay: 0.2 * i, duration: 0.7 }}
|
||||
/>
|
||||
))}
|
||||
|
||||
{/* CYAN LINES */}
|
||||
{arrows.map((a, i) => (
|
||||
<motion.path
|
||||
key={`cyan-${i}`}
|
||||
d={a.d}
|
||||
stroke={accent}
|
||||
strokeWidth={2}
|
||||
strokeLinecap="round"
|
||||
strokeDasharray="10"
|
||||
fill="none"
|
||||
initial={{ pathLength: 0, opacity: 0 }}
|
||||
animate={{ pathLength: 1, opacity: 1 }}
|
||||
transition={{ delay: 0.25 * i, duration: 0.7 }}
|
||||
/>
|
||||
))}
|
||||
|
||||
{/* NEW: CYAN ENDPOINT PULSES */}
|
||||
{arrows.map((a, i) => (
|
||||
<motion.circle
|
||||
key={`endpoint-${i}`}
|
||||
cx={a.end.x}
|
||||
cy={a.end.y}
|
||||
r={10}
|
||||
fill={accent}
|
||||
opacity={0.12}
|
||||
filter="url(#pods-glow)"
|
||||
initial={{ scale: 0.8, opacity: 0 }}
|
||||
animate={{
|
||||
scale: [1, 1.2, 1],
|
||||
opacity: [0.05, 0.25, 0.05],
|
||||
}}
|
||||
transition={{
|
||||
duration: 1.5,
|
||||
delay: i * 0.2,
|
||||
repeat: Infinity,
|
||||
repeatType: "mirror",
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
|
||||
{/* MAIN MOVING CYAN PULSE */}
|
||||
<motion.circle
|
||||
r={8}
|
||||
fill={accent}
|
||||
filter="url(#pods-glow)"
|
||||
style={{
|
||||
offsetPath: `path('${path.replace(/\s+/g, " ")}')`,
|
||||
}}
|
||||
initial={{ offsetDistance: "0%", opacity: 0.4 }}
|
||||
animate={{
|
||||
offsetDistance: ["0%", "100%"],
|
||||
opacity: [0.4, 1, 0.4],
|
||||
}}
|
||||
transition={{
|
||||
duration: 2.6,
|
||||
repeat: Infinity,
|
||||
ease: "linear",
|
||||
}}
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user