feat: update cube component color scheme from cyan to blue
- Changed cube gradient colors from cyan to blue for better visual consistency - Updated glow effects and shadows to use blue (rgba(59, 130, 246)) instead of cyan - Modified background aura gradients in StackSection for enhanced depth perception - Replaced HomeFeaturesDark component with new HomeSlider in HomePage layout - Added isolate property to StackSection to prevent gradient bleeding - Enhanced background layer in StackSection with additional
This commit is contained in:
		@@ -26,11 +26,11 @@ const CubeSvg: React.FC<React.SVGProps<SVGSVGElement> & { index: number }> = ({
 | 
				
			|||||||
    <path
 | 
					    <path
 | 
				
			||||||
      fill={`url(#cube-gradient-${index})`}
 | 
					      fill={`url(#cube-gradient-${index})`}
 | 
				
			||||||
      d="M491.651 144.747L287.198 227.339C265.219 236.22 241.783 236.22 219.802 227.339L15.3486 144.747C-5.11621 136.479 -5.11621 97.5191 15.3486 89.2539L219.802 6.65884C241.783 -2.21961 265.219 -2.21961 287.198 6.65884L491.651 89.2539C512.116 97.5191 512.116 136.479 491.651 144.747Z"
 | 
					      d="M491.651 144.747L287.198 227.339C265.219 236.22 241.783 236.22 219.802 227.339L15.3486 144.747C-5.11621 136.479 -5.11621 97.5191 15.3486 89.2539L219.802 6.65884C241.783 -2.21961 265.219 -2.21961 287.198 6.65884L491.651 89.2539C512.116 97.5191 512.116 136.479 491.651 144.747Z"
 | 
				
			||||||
      stroke="rgba(0,255,255,0.25)"
 | 
					      stroke="rgba(59, 130, 246, 0.25)"
 | 
				
			||||||
      strokeWidth="0.5"
 | 
					      strokeWidth="0.5"
 | 
				
			||||||
    />
 | 
					    />
 | 
				
			||||||
    <defs>
 | 
					    <defs>
 | 
				
			||||||
      {/* Cyan-white soft gradient */}
 | 
					      {/* Blue-white soft gradient */}
 | 
				
			||||||
      <linearGradient
 | 
					      <linearGradient
 | 
				
			||||||
        id={`cube-gradient-${index}`}
 | 
					        id={`cube-gradient-${index}`}
 | 
				
			||||||
        x1="185.298"
 | 
					        x1="185.298"
 | 
				
			||||||
@@ -39,8 +39,8 @@ const CubeSvg: React.FC<React.SVGProps<SVGSVGElement> & { index: number }> = ({
 | 
				
			|||||||
        y2="206.448"
 | 
					        y2="206.448"
 | 
				
			||||||
        gradientUnits="userSpaceOnUse"
 | 
					        gradientUnits="userSpaceOnUse"
 | 
				
			||||||
      >
 | 
					      >
 | 
				
			||||||
        <stop offset="0%" stopColor="#DFFFFF" stopOpacity="0.75" />
 | 
					        <stop offset="0%" stopColor="#EBF8FF" stopOpacity="0.75" />
 | 
				
			||||||
        <stop offset="40%" stopColor="#A5F4FF" stopOpacity="0.8" />
 | 
					        <stop offset="40%" stopColor="#BEE3F8" stopOpacity="0.8" />
 | 
				
			||||||
        <stop offset="100%" stopColor="#FFFFFF" stopOpacity="0.9" />
 | 
					        <stop offset="100%" stopColor="#FFFFFF" stopOpacity="0.9" />
 | 
				
			||||||
      </linearGradient>
 | 
					      </linearGradient>
 | 
				
			||||||
    </defs>
 | 
					    </defs>
 | 
				
			||||||
@@ -79,8 +79,8 @@ export function CubeLight({
 | 
				
			|||||||
        <div
 | 
					        <div
 | 
				
			||||||
          className={`absolute inset-0 blur-3xl rounded-2xl transition-all duration-500 ${
 | 
					          className={`absolute inset-0 blur-3xl rounded-2xl transition-all duration-500 ${
 | 
				
			||||||
            isActive
 | 
					            isActive
 | 
				
			||||||
              ? "bg-cyan-400/40 opacity-70"
 | 
					              ? "bg-blue-400/40 opacity-70"
 | 
				
			||||||
              : "bg-cyan-200/20 opacity-40"
 | 
					              : "bg-blue-200/20 opacity-40"
 | 
				
			||||||
          }`}
 | 
					          }`}
 | 
				
			||||||
        />
 | 
					        />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -90,8 +90,8 @@ export function CubeLight({
 | 
				
			|||||||
          className="w-48 sm:w-64 lg:w-80 h-auto relative"
 | 
					          className="w-48 sm:w-64 lg:w-80 h-auto relative"
 | 
				
			||||||
          style={{
 | 
					          style={{
 | 
				
			||||||
            filter: isActive
 | 
					            filter: isActive
 | 
				
			||||||
              ? "drop-shadow(0 0 25px rgba(0,255,255,0.4)) brightness(1.1)"
 | 
					              ? "drop-shadow(0 0 25px rgba(59, 130, 246, 0.4)) brightness(1.1)"
 | 
				
			||||||
              : "drop-shadow(0 0 10px rgba(0,255,255,0.15)) brightness(1)",
 | 
					              : "drop-shadow(0 0 10px rgba(59, 130, 246, 0.15)) brightness(1)",
 | 
				
			||||||
            transition: "all 0.4s ease",
 | 
					            transition: "all 0.4s ease",
 | 
				
			||||||
          }}
 | 
					          }}
 | 
				
			||||||
        />
 | 
					        />
 | 
				
			||||||
@@ -99,10 +99,10 @@ export function CubeLight({
 | 
				
			|||||||
        {/* Title overlay */}
 | 
					        {/* Title overlay */}
 | 
				
			||||||
        <div className="absolute inset-0 flex items-center justify-center">
 | 
					        <div className="absolute inset-0 flex items-center justify-center">
 | 
				
			||||||
          <h3
 | 
					          <h3
 | 
				
			||||||
            className="text-cyan-900 text-sm lg:text-base font-medium text-center px-4"
 | 
					            className="text-blue-900 text-sm lg:text-base font-medium text-center px-4"
 | 
				
			||||||
            style={{
 | 
					            style={{
 | 
				
			||||||
              textShadow:
 | 
					              textShadow:
 | 
				
			||||||
                "0 0 15px rgba(255,255,255,0.8), 0 0 25px rgba(0,255,255,0.5)",
 | 
					                "0 0 15px rgba(255,255,255,0.8), 0 0 25px rgba(59, 130, 246, 0.5)",
 | 
				
			||||||
            }}
 | 
					            }}
 | 
				
			||||||
          >
 | 
					          >
 | 
				
			||||||
            {title}
 | 
					            {title}
 | 
				
			||||||
@@ -131,7 +131,7 @@ export function CubeLight({
 | 
				
			|||||||
                y1="1"
 | 
					                y1="1"
 | 
				
			||||||
                x2="120"
 | 
					                x2="120"
 | 
				
			||||||
                y2="1"
 | 
					                y2="1"
 | 
				
			||||||
                stroke="rgba(0,255,255,0.6)"
 | 
					                stroke="rgba(59, 130, 246, 0.6)"
 | 
				
			||||||
                strokeWidth="1"
 | 
					                strokeWidth="1"
 | 
				
			||||||
                opacity="0.8"
 | 
					                opacity="0.8"
 | 
				
			||||||
              />
 | 
					              />
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										293
									
								
								src/components/ui/apple-cards-carousel.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										293
									
								
								src/components/ui/apple-cards-carousel.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,293 @@
 | 
				
			|||||||
 | 
					"use client";
 | 
				
			||||||
 | 
					import React, {
 | 
				
			||||||
 | 
					  useEffect,
 | 
				
			||||||
 | 
					  useRef,
 | 
				
			||||||
 | 
					  useState,
 | 
				
			||||||
 | 
					  createContext,
 | 
				
			||||||
 | 
					  useContext,
 | 
				
			||||||
 | 
					} from "react";
 | 
				
			||||||
 | 
					import {
 | 
				
			||||||
 | 
					  IconArrowNarrowLeft,
 | 
				
			||||||
 | 
					  IconArrowNarrowRight,
 | 
				
			||||||
 | 
					  IconX,
 | 
				
			||||||
 | 
					} from "@tabler/icons-react";
 | 
				
			||||||
 | 
					import { cn } from "@/lib/utils";
 | 
				
			||||||
 | 
					import { AnimatePresence, motion } from "motion/react";
 | 
				
			||||||
 | 
					import { useOutsideClick } from "@/hooks/use-outside-click";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					interface CarouselProps {
 | 
				
			||||||
 | 
					  items: JSX.Element[];
 | 
				
			||||||
 | 
					  initialScroll?: number;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Card = {
 | 
				
			||||||
 | 
					  src: string;
 | 
				
			||||||
 | 
					  title: string;
 | 
				
			||||||
 | 
					  category: string;
 | 
				
			||||||
 | 
					  content: React.ReactNode;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const CarouselContext = createContext<{
 | 
				
			||||||
 | 
					  onCardClose: (index: number) => void;
 | 
				
			||||||
 | 
					  currentIndex: number;
 | 
				
			||||||
 | 
					}>({
 | 
				
			||||||
 | 
					  onCardClose: () => {},
 | 
				
			||||||
 | 
					  currentIndex: 0,
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const Carousel = ({ items, initialScroll = 0 }: CarouselProps) => {
 | 
				
			||||||
 | 
					  const carouselRef = React.useRef<HTMLDivElement>(null);
 | 
				
			||||||
 | 
					  const [canScrollLeft, setCanScrollLeft] = React.useState(false);
 | 
				
			||||||
 | 
					  const [canScrollRight, setCanScrollRight] = React.useState(true);
 | 
				
			||||||
 | 
					  const [currentIndex, setCurrentIndex] = useState(0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  useEffect(() => {
 | 
				
			||||||
 | 
					    if (carouselRef.current) {
 | 
				
			||||||
 | 
					      carouselRef.current.scrollLeft = initialScroll;
 | 
				
			||||||
 | 
					      checkScrollability();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }, [initialScroll]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const checkScrollability = () => {
 | 
				
			||||||
 | 
					    if (carouselRef.current) {
 | 
				
			||||||
 | 
					      const { scrollLeft, scrollWidth, clientWidth } = carouselRef.current;
 | 
				
			||||||
 | 
					      setCanScrollLeft(scrollLeft > 0);
 | 
				
			||||||
 | 
					      setCanScrollRight(scrollLeft < scrollWidth - clientWidth);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const scrollLeft = () => {
 | 
				
			||||||
 | 
					    if (carouselRef.current) {
 | 
				
			||||||
 | 
					      carouselRef.current.scrollBy({ left: -300, behavior: "smooth" });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const scrollRight = () => {
 | 
				
			||||||
 | 
					    if (carouselRef.current) {
 | 
				
			||||||
 | 
					      carouselRef.current.scrollBy({ left: 300, behavior: "smooth" });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const handleCardClose = (index: number) => {
 | 
				
			||||||
 | 
					    if (carouselRef.current) {
 | 
				
			||||||
 | 
					      const cardWidth = isMobile() ? 230 : 384; // (md:w-96)
 | 
				
			||||||
 | 
					      const gap = isMobile() ? 4 : 8;
 | 
				
			||||||
 | 
					      const scrollPosition = (cardWidth + gap) * (index + 1);
 | 
				
			||||||
 | 
					      carouselRef.current.scrollTo({
 | 
				
			||||||
 | 
					        left: scrollPosition,
 | 
				
			||||||
 | 
					        behavior: "smooth",
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					      setCurrentIndex(index);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const isMobile = () => {
 | 
				
			||||||
 | 
					    return window && window.innerWidth < 768;
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return (
 | 
				
			||||||
 | 
					    <CarouselContext.Provider
 | 
				
			||||||
 | 
					      value={{ onCardClose: handleCardClose, currentIndex }}
 | 
				
			||||||
 | 
					    >
 | 
				
			||||||
 | 
					      <div className="relative w-full">
 | 
				
			||||||
 | 
					        <div
 | 
				
			||||||
 | 
					          className="flex w-full overflow-x-scroll overscroll-x-auto scroll-smooth py-10 [scrollbar-width:none] md:py-20"
 | 
				
			||||||
 | 
					          ref={carouselRef}
 | 
				
			||||||
 | 
					          onScroll={checkScrollability}
 | 
				
			||||||
 | 
					        >
 | 
				
			||||||
 | 
					          <div
 | 
				
			||||||
 | 
					            className={cn(
 | 
				
			||||||
 | 
					              "absolute right-0 z-[1000] h-auto w-[5%] overflow-hidden bg-gradient-to-l",
 | 
				
			||||||
 | 
					            )}
 | 
				
			||||||
 | 
					          ></div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          <div
 | 
				
			||||||
 | 
					            className={cn(
 | 
				
			||||||
 | 
					              "flex flex-row justify-start gap-4 pl-4",
 | 
				
			||||||
 | 
					              "mx-auto max-w-7xl", // remove max-w-4xl if you want the carousel to span the full width of its container
 | 
				
			||||||
 | 
					            )}
 | 
				
			||||||
 | 
					          >
 | 
				
			||||||
 | 
					            {items.map((item, index) => (
 | 
				
			||||||
 | 
					              <motion.div
 | 
				
			||||||
 | 
					                initial={{
 | 
				
			||||||
 | 
					                  opacity: 0,
 | 
				
			||||||
 | 
					                  y: 20,
 | 
				
			||||||
 | 
					                }}
 | 
				
			||||||
 | 
					                animate={{
 | 
				
			||||||
 | 
					                  opacity: 1,
 | 
				
			||||||
 | 
					                  y: 0,
 | 
				
			||||||
 | 
					                  transition: {
 | 
				
			||||||
 | 
					                    duration: 0.5,
 | 
				
			||||||
 | 
					                    delay: 0.2 * index,
 | 
				
			||||||
 | 
					                    ease: "easeOut",
 | 
				
			||||||
 | 
					                  },
 | 
				
			||||||
 | 
					                }}
 | 
				
			||||||
 | 
					                key={"card" + index}
 | 
				
			||||||
 | 
					                className="rounded-3xl last:pr-[5%] md:last:pr-[33%]"
 | 
				
			||||||
 | 
					              >
 | 
				
			||||||
 | 
					                {item}
 | 
				
			||||||
 | 
					              </motion.div>
 | 
				
			||||||
 | 
					            ))}
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        <div className="mr-10 flex justify-end gap-2">
 | 
				
			||||||
 | 
					          <button
 | 
				
			||||||
 | 
					            className="relative z-40 flex h-10 w-10 items-center justify-center rounded-full bg-neutral-800 disabled:opacity-50"
 | 
				
			||||||
 | 
					            onClick={scrollLeft}
 | 
				
			||||||
 | 
					            disabled={!canScrollLeft}
 | 
				
			||||||
 | 
					          >
 | 
				
			||||||
 | 
					            <IconArrowNarrowLeft className="h-6 w-6 text-white" />
 | 
				
			||||||
 | 
					          </button>
 | 
				
			||||||
 | 
					          <button
 | 
				
			||||||
 | 
					            className="relative z-40 flex h-10 w-10 items-center justify-center rounded-full bg-neutral-800 disabled:opacity-50"
 | 
				
			||||||
 | 
					            onClick={scrollRight}
 | 
				
			||||||
 | 
					            disabled={!canScrollRight}
 | 
				
			||||||
 | 
					          >
 | 
				
			||||||
 | 
					            <IconArrowNarrowRight className="h-6 w-6 text-white" />
 | 
				
			||||||
 | 
					          </button>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    </CarouselContext.Provider>
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const Card = ({
 | 
				
			||||||
 | 
					  card,
 | 
				
			||||||
 | 
					  index,
 | 
				
			||||||
 | 
					  layout = false,
 | 
				
			||||||
 | 
					}: {
 | 
				
			||||||
 | 
					  card: Card;
 | 
				
			||||||
 | 
					  index: number;
 | 
				
			||||||
 | 
					  layout?: boolean;
 | 
				
			||||||
 | 
					}) => {
 | 
				
			||||||
 | 
					  const [open, setOpen] = useState(false);
 | 
				
			||||||
 | 
					  const containerRef = useRef<HTMLDivElement>(null);
 | 
				
			||||||
 | 
					  const { onCardClose } = useContext(CarouselContext);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  useEffect(() => {
 | 
				
			||||||
 | 
					    function onKeyDown(event: KeyboardEvent) {
 | 
				
			||||||
 | 
					      if (event.key === "Escape") {
 | 
				
			||||||
 | 
					        handleClose();
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (open) {
 | 
				
			||||||
 | 
					      document.body.style.overflow = "hidden";
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      document.body.style.overflow = "auto";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    window.addEventListener("keydown", onKeyDown);
 | 
				
			||||||
 | 
					    return () => window.removeEventListener("keydown", onKeyDown);
 | 
				
			||||||
 | 
					  }, [open]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  useOutsideClick(containerRef, () => handleClose());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const handleOpen = () => {
 | 
				
			||||||
 | 
					    setOpen(true);
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const handleClose = () => {
 | 
				
			||||||
 | 
					    setOpen(false);
 | 
				
			||||||
 | 
					    onCardClose(index);
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return (
 | 
				
			||||||
 | 
					    <>
 | 
				
			||||||
 | 
					      <AnimatePresence>
 | 
				
			||||||
 | 
					        {open && (
 | 
				
			||||||
 | 
					          <div className="fixed inset-0 z-50 h-screen overflow-auto">
 | 
				
			||||||
 | 
					            <motion.div
 | 
				
			||||||
 | 
					              initial={{ opacity: 0 }}
 | 
				
			||||||
 | 
					              animate={{ opacity: 1 }}
 | 
				
			||||||
 | 
					              exit={{ opacity: 0 }}
 | 
				
			||||||
 | 
					              className="fixed inset-0 h-full w-full bg-black/80 backdrop-blur-lg"
 | 
				
			||||||
 | 
					            />
 | 
				
			||||||
 | 
					            <motion.div
 | 
				
			||||||
 | 
					              initial={{ opacity: 0 }}
 | 
				
			||||||
 | 
					              animate={{ opacity: 1 }}
 | 
				
			||||||
 | 
					              exit={{ opacity: 0 }}
 | 
				
			||||||
 | 
					              ref={containerRef}
 | 
				
			||||||
 | 
					              layoutId={layout ? `card-${card.title}` : undefined}
 | 
				
			||||||
 | 
					              className="relative z-[60] mx-auto my-10 h-fit max-w-5xl rounded-3xl bg-neutral-900 p-4 font-sans md:p-10"
 | 
				
			||||||
 | 
					            >
 | 
				
			||||||
 | 
					              <button
 | 
				
			||||||
 | 
					                className="sticky top-4 right-0 ml-auto flex h-8 w-8 items-center justify-center rounded-full bg-black dark:bg-white"
 | 
				
			||||||
 | 
					                onClick={handleClose}
 | 
				
			||||||
 | 
					              >
 | 
				
			||||||
 | 
					                <IconX className="h-6 w-6 text-neutral-100 dark:text-neutral-900" />
 | 
				
			||||||
 | 
					              </button>
 | 
				
			||||||
 | 
					              <motion.p
 | 
				
			||||||
 | 
					                layoutId={layout ? `category-${card.title}` : undefined}
 | 
				
			||||||
 | 
					                className="text-base font-medium text-black dark:text-white"
 | 
				
			||||||
 | 
					              >
 | 
				
			||||||
 | 
					                {card.category}
 | 
				
			||||||
 | 
					              </motion.p>
 | 
				
			||||||
 | 
					              <motion.p
 | 
				
			||||||
 | 
					                layoutId={layout ? `title-${card.title}` : undefined}
 | 
				
			||||||
 | 
					                className="mt-4 text-2xl font-semibold text-neutral-700 md:text-5xl dark:text-white"
 | 
				
			||||||
 | 
					              >
 | 
				
			||||||
 | 
					                {card.title}
 | 
				
			||||||
 | 
					              </motion.p>
 | 
				
			||||||
 | 
					              <div className="py-10">{card.content}</div>
 | 
				
			||||||
 | 
					            </motion.div>
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					        )}
 | 
				
			||||||
 | 
					      </AnimatePresence>
 | 
				
			||||||
 | 
					      <motion.button
 | 
				
			||||||
 | 
					        layoutId={layout ? `card-${card.title}` : undefined}
 | 
				
			||||||
 | 
					        onClick={handleOpen}
 | 
				
			||||||
 | 
					        className="relative z-10 flex h-60 w-56 flex-col items-start justify-start overflow-hidden rounded-3xl bg-neutral-900 md:h-120 md:w-96"
 | 
				
			||||||
 | 
					      >
 | 
				
			||||||
 | 
					        <div className="pointer-events-none absolute inset-x-0 top-0 z-30 h-full bg-gradient-to-b from-black/50 via-transparent to-transparent" />
 | 
				
			||||||
 | 
					        <div className="relative z-40 p-8">
 | 
				
			||||||
 | 
					          <motion.p
 | 
				
			||||||
 | 
					            layoutId={layout ? `category-${card.category}` : undefined}
 | 
				
			||||||
 | 
					            className="text-left font-sans text-sm font-medium text-white md:text-base"
 | 
				
			||||||
 | 
					          >
 | 
				
			||||||
 | 
					            {card.category}
 | 
				
			||||||
 | 
					          </motion.p>
 | 
				
			||||||
 | 
					          <motion.p
 | 
				
			||||||
 | 
					            layoutId={layout ? `title-${card.title}` : undefined}
 | 
				
			||||||
 | 
					            className="mt-2 max-w-xs text-left font-sans text-xl font-semibold [text-wrap:balance] text-white md:text-3xl"
 | 
				
			||||||
 | 
					          >
 | 
				
			||||||
 | 
					            {card.title}
 | 
				
			||||||
 | 
					          </motion.p>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        <BlurImage
 | 
				
			||||||
 | 
					          src={card.src}
 | 
				
			||||||
 | 
					          alt={card.title}
 | 
				
			||||||
 | 
					          className="absolute inset-0 z-10 h-full w-full object-cover"
 | 
				
			||||||
 | 
					        />
 | 
				
			||||||
 | 
					      </motion.button>
 | 
				
			||||||
 | 
					    </>
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const BlurImage = ({
 | 
				
			||||||
 | 
					  src,
 | 
				
			||||||
 | 
					  className,
 | 
				
			||||||
 | 
					  width,
 | 
				
			||||||
 | 
					  height,
 | 
				
			||||||
 | 
					  alt,
 | 
				
			||||||
 | 
					  ...rest
 | 
				
			||||||
 | 
					}: React.ImgHTMLAttributes<HTMLImageElement>) => {
 | 
				
			||||||
 | 
					  const [isLoading, setLoading] = useState(true);
 | 
				
			||||||
 | 
					  return (
 | 
				
			||||||
 | 
					    <img
 | 
				
			||||||
 | 
					      className={cn(
 | 
				
			||||||
 | 
					        "h-full w-full transition duration-300",
 | 
				
			||||||
 | 
					        isLoading ? "blur-sm" : "blur-0",
 | 
				
			||||||
 | 
					        className,
 | 
				
			||||||
 | 
					      )}
 | 
				
			||||||
 | 
					      onLoad={() => setLoading(false)}
 | 
				
			||||||
 | 
					      src={src as string}
 | 
				
			||||||
 | 
					      width={width}
 | 
				
			||||||
 | 
					      height={height}
 | 
				
			||||||
 | 
					      loading="lazy"
 | 
				
			||||||
 | 
					      decoding="async"
 | 
				
			||||||
 | 
					      alt={alt ? alt : "Background of a beautiful view"}
 | 
				
			||||||
 | 
					      {...rest}
 | 
				
			||||||
 | 
					    />
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
							
								
								
									
										42
									
								
								src/components/ui/son-of-a-glitch-text.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								src/components/ui/son-of-a-glitch-text.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,42 @@
 | 
				
			|||||||
 | 
					"use client";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { cn } from "@/lib/utils";
 | 
				
			||||||
 | 
					import { type HTMLAttributes, useEffect, useState } from "react";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					interface SonOfAGlitchProps extends HTMLAttributes<HTMLHeadingElement> {
 | 
				
			||||||
 | 
					  text: string;
 | 
				
			||||||
 | 
					  textClassName?: string;
 | 
				
			||||||
 | 
					  glitchClassName?: string;
 | 
				
			||||||
 | 
					  showGlitch?: boolean;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const SonOfAGlitch = ({
 | 
				
			||||||
 | 
					  text,
 | 
				
			||||||
 | 
					  className,
 | 
				
			||||||
 | 
					  textClassName,
 | 
				
			||||||
 | 
					  glitchClassName,
 | 
				
			||||||
 | 
					  showGlitch = true,
 | 
				
			||||||
 | 
					}: SonOfAGlitchProps) => {
 | 
				
			||||||
 | 
					  const [isGlitching, setIsGlitching] = useState(showGlitch);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  useEffect(() => {
 | 
				
			||||||
 | 
					    setIsGlitching(showGlitch);
 | 
				
			||||||
 | 
					  }, [showGlitch]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return (
 | 
				
			||||||
 | 
					    <h1 className={cn("relative font-mono", className)}>
 | 
				
			||||||
 | 
					      <span
 | 
				
			||||||
 | 
					        className={cn(
 | 
				
			||||||
 | 
					          "absolute top-0 left-0 w-full h-full bg-transparent",
 | 
				
			||||||
 | 
					          isGlitching &&
 | 
				
			||||||
 | 
					            "before:content-[attr(data-text)] before:absolute before:top-0 before:w-full before:h-full before:bg-transparent before:left-[-2px] before:text-red-500 before:overflow-hidden before:animate-glitch-1",
 | 
				
			||||||
 | 
					          isGlitching &&
 | 
				
			||||||
 | 
					            "after:content-[attr(data-text)] after:absolute after:top-0 after:w-full after:h-full after:bg-transparent after:left-[2px] after:text-blue-500 after:overflow-hidden after:animate-glitch-2",
 | 
				
			||||||
 | 
					          glitchClassName,
 | 
				
			||||||
 | 
					        )}
 | 
				
			||||||
 | 
					        data-text={text}
 | 
				
			||||||
 | 
					      ></span>
 | 
				
			||||||
 | 
					      <span className={cn(textClassName)}>{text}</span>
 | 
				
			||||||
 | 
					    </h1>
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
							
								
								
									
										23
									
								
								src/hooks/use-outside-click.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								src/hooks/use-outside-click.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,23 @@
 | 
				
			|||||||
 | 
					import React, { useEffect } from "react";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const useOutsideClick = (
 | 
				
			||||||
 | 
					  ref: React.RefObject<HTMLDivElement>,
 | 
				
			||||||
 | 
					  callback: Function
 | 
				
			||||||
 | 
					) => {
 | 
				
			||||||
 | 
					  useEffect(() => {
 | 
				
			||||||
 | 
					    const listener = (event: any) => {
 | 
				
			||||||
 | 
					      if (!ref.current || ref.current.contains(event.target)) {
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      callback(event);
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    document.addEventListener("mousedown", listener);
 | 
				
			||||||
 | 
					    document.addEventListener("touchstart", listener);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return () => {
 | 
				
			||||||
 | 
					      document.removeEventListener("mousedown", listener);
 | 
				
			||||||
 | 
					      document.removeEventListener("touchstart", listener);
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					  }, [ref, callback]);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
							
								
								
									
										24
									
								
								src/hooks/use-outside-click.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								src/hooks/use-outside-click.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
				
			|||||||
 | 
					import React, { useEffect } from "react";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const useOutsideClick = (
 | 
				
			||||||
 | 
					  ref: React.RefObject<HTMLDivElement>,
 | 
				
			||||||
 | 
					  callback: Function
 | 
				
			||||||
 | 
					) => {
 | 
				
			||||||
 | 
					  useEffect(() => {
 | 
				
			||||||
 | 
					    const listener = (event: any) => {
 | 
				
			||||||
 | 
					      // DO NOTHING if the element being clicked is the target element or their children
 | 
				
			||||||
 | 
					      if (!ref.current || ref.current.contains(event.target)) {
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      callback(event);
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    document.addEventListener("mousedown", listener);
 | 
				
			||||||
 | 
					    document.addEventListener("touchstart", listener);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return () => {
 | 
				
			||||||
 | 
					      document.removeEventListener("mousedown", listener);
 | 
				
			||||||
 | 
					      document.removeEventListener("touchstart", listener);
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					  }, [ref, callback]);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
@@ -5,6 +5,7 @@ import { StackSectionLight } from './StackSection'
 | 
				
			|||||||
import { WorldMap } from './HomeGlobe'
 | 
					import { WorldMap } from './HomeGlobe'
 | 
				
			||||||
import { HomeBenefits } from './HomeBenefits'
 | 
					import { HomeBenefits } from './HomeBenefits'
 | 
				
			||||||
import { CallToAction } from './CallToAction'
 | 
					import { CallToAction } from './CallToAction'
 | 
				
			||||||
 | 
					import { HomeSlider } from './HomeSlider'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default function HomePage() {
 | 
					export default function HomePage() {
 | 
				
			||||||
@@ -24,7 +25,7 @@ export default function HomePage() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      <AnimatedSection>
 | 
					      <AnimatedSection>
 | 
				
			||||||
        <HomeFeaturesDark />
 | 
					        <HomeSlider />
 | 
				
			||||||
      </AnimatedSection>
 | 
					      </AnimatedSection>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      <AnimatedSection>
 | 
					      <AnimatedSection>
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										84
									
								
								src/pages/home/HomeSlider.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								src/pages/home/HomeSlider.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,84 @@
 | 
				
			|||||||
 | 
					"use client";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import React from "react";
 | 
				
			||||||
 | 
					import { Carousel, Card } from "@/components/ui/apple-cards-carousel";
 | 
				
			||||||
 | 
					import { H2, H3, P } from "@/components/Texts";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function HomeSlider() {
 | 
				
			||||||
 | 
					  const cards = data.map((card, index) => (
 | 
				
			||||||
 | 
					    <Card key={card.src} card={card} index={index} />
 | 
				
			||||||
 | 
					  ));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return (
 | 
				
			||||||
 | 
					    <div className="w-full h-full py-20 bg-black">
 | 
				
			||||||
 | 
					      <div className="max-w-7xl mx-auto pl-4">
 | 
				
			||||||
 | 
					        <H3 className="text-left text-white">
 | 
				
			||||||
 | 
					          Discover the Mycelium Ecosystem
 | 
				
			||||||
 | 
					        </H3>
 | 
				
			||||||
 | 
					        <div className="mt-4 max-w-3xl">
 | 
				
			||||||
 | 
					          <P className="text-left text-neutral-400">
 | 
				
			||||||
 | 
					            From compute and networking to intelligent automation, these components work together to empower users, developers, and organizations to build freely, without intermediaries.
 | 
				
			||||||
 | 
					          </P>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					      <Carousel items={cards} />
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const DummyContent = () => {
 | 
				
			||||||
 | 
					  return (
 | 
				
			||||||
 | 
					    <div className="bg-neutral-800 p-8 md:p-14 rounded-3xl mb-4 max-w-3xl">
 | 
				
			||||||
 | 
					      <P className="text-neutral-400 text-base md:text-2xl font-sans  mx-auto">
 | 
				
			||||||
 | 
					        Mycelium is a decentralized compute network that allows you to run AI models and other software on a global network of devices. Mycelium is built on top of the Mycelium Network, a decentralized network of devices that are connected to each other and to the internet.
 | 
				
			||||||
 | 
					      </P>
 | 
				
			||||||
 | 
					      <img
 | 
				
			||||||
 | 
					        src="/images/gallery/1.webp"
 | 
				
			||||||
 | 
					        alt="Macbook mockup from Aceternity UI"
 | 
				
			||||||
 | 
					        height="500"
 | 
				
			||||||
 | 
					        width="500"
 | 
				
			||||||
 | 
					        className="md:w-1/2 md:h-1/2 h-full w-full mx-auto object-cover"
 | 
				
			||||||
 | 
					      />
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const data = [
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    category: "DePIN",
 | 
				
			||||||
 | 
					    title: "Mycelium Network",
 | 
				
			||||||
 | 
					    src: "/images/gallery/9.webp",
 | 
				
			||||||
 | 
					    content: <DummyContent />,
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    category: "AI Agent",
 | 
				
			||||||
 | 
					    title: "Mycelium Agent",
 | 
				
			||||||
 | 
					    src: "/images/gallery/2.webp",
 | 
				
			||||||
 | 
					    content: <DummyContent />,
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    category: "Cloud",
 | 
				
			||||||
 | 
					    title: "Mycelium Cloud",
 | 
				
			||||||
 | 
					    src: "/images/gallery/3.webp",
 | 
				
			||||||
 | 
					    content: <DummyContent />,
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    category: "GPU",
 | 
				
			||||||
 | 
					    title: "Mycelium GPU",
 | 
				
			||||||
 | 
					    src: "/images/gallery/4.webp",
 | 
				
			||||||
 | 
					    content: <DummyContent />,
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    category: "Compute",
 | 
				
			||||||
 | 
					    title: "Mycelium Compute",
 | 
				
			||||||
 | 
					    src: "/images/gallery/5.webp",
 | 
				
			||||||
 | 
					    content: <DummyContent />,
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    category: "Storage",
 | 
				
			||||||
 | 
					    title: "Mycelium Storage",
 | 
				
			||||||
 | 
					    src: "/images/gallery/6.webp",
 | 
				
			||||||
 | 
					    content: <DummyContent />,
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					];
 | 
				
			||||||
@@ -7,35 +7,53 @@ import { FadeIn } from "@/components/ui/FadeIn";
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
export function StackSectionLight() {
 | 
					export function StackSectionLight() {
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <section className="relative w-full overflow-hidden py-24 lg:py-40">
 | 
					    <section className="relative w-full overflow-hidden py-24 lg:py-40 isolate">
 | 
				
			||||||
      {/* === Background Layer === */}
 | 
					      {/* === Background Layer === */}
 | 
				
			||||||
      <div className="absolute inset-0 -z-10 bg-transparent">
 | 
					      <div className="absolute inset-0 z-0 bg-transparent">
 | 
				
			||||||
       
 | 
					        {/* Central main aura */}
 | 
				
			||||||
 | 
					 | 
				
			||||||
        {/* === Center Radial Glow Aura === */}
 | 
					 | 
				
			||||||
        <motion.div
 | 
					        <motion.div
 | 
				
			||||||
          className="absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 w-[1200px] h-[1200px] rounded-full pointer-events-none"
 | 
					          className="absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 w-[1200px] h-[1200px] rounded-full pointer-events-none"
 | 
				
			||||||
          style={{
 | 
					          style={{
 | 
				
			||||||
            background:
 | 
					            background:
 | 
				
			||||||
              "radial-gradient(circle, rgba(173,255,255,0.5) 0%, rgba(0,220,255,0.3) 30%, rgba(255,255,255,0) 70%)",
 | 
					              "radial-gradient(circle, rgba(180,255,255,0.55) 0%, rgba(0,210,255,0.35) 35%, rgba(255,255,255,0) 55%)",
 | 
				
			||||||
            filter: "blur(120px)",
 | 
					            filter: "blur(140px)",
 | 
				
			||||||
          }}
 | 
					          }}
 | 
				
			||||||
          animate={{
 | 
					          animate={{
 | 
				
			||||||
            opacity: [0.6, 0.8, 0.6],
 | 
					            opacity: [0.5, 0.8, 0.5],
 | 
				
			||||||
            scale: [1, 1.05, 1],
 | 
					            scale: [1, 1.05, 1],
 | 
				
			||||||
          }}
 | 
					          }}
 | 
				
			||||||
          transition={{
 | 
					          transition={{
 | 
				
			||||||
            duration: 8,
 | 
					            duration: 9,
 | 
				
			||||||
            repeat: Infinity,
 | 
					            repeat: Infinity,
 | 
				
			||||||
            ease: "easeInOut",
 | 
					            ease: "easeInOut",
 | 
				
			||||||
          }}
 | 
					          }}
 | 
				
			||||||
        />
 | 
					        />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        {/* Faint cyan mist in the back for depth */}
 | 
				
			||||||
 | 
					        <motion.div
 | 
				
			||||||
 | 
					          className="absolute left-[70%] top-[30%] -translate-x-1/2 -translate-y-1/2 w-[1600px] h-[1600px] rounded-full pointer-events-none"
 | 
				
			||||||
 | 
					          style={{
 | 
				
			||||||
 | 
					            background:
 | 
				
			||||||
 | 
					              "radial-gradient(circle, rgba(100,220,255,0.25) 0%, rgba(200,255,255,0.15) 50%, rgba(255,255,255,0) 90%)",
 | 
				
			||||||
 | 
					            filter: "blur(200px)",
 | 
				
			||||||
 | 
					          }}
 | 
				
			||||||
 | 
					          animate={{
 | 
				
			||||||
 | 
					            opacity: [0.2, 0.35, 0.2],
 | 
				
			||||||
 | 
					            scale: [1, 1.1, 1],
 | 
				
			||||||
 | 
					          }}
 | 
				
			||||||
 | 
					          transition={{
 | 
				
			||||||
 | 
					            duration: 12,
 | 
				
			||||||
 | 
					            repeat: Infinity,
 | 
				
			||||||
 | 
					            ease: "easeInOut",
 | 
				
			||||||
 | 
					            delay: 3,
 | 
				
			||||||
 | 
					          }}
 | 
				
			||||||
 | 
					        />
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      {/* === Content === */}
 | 
					      {/* === Content === */}
 | 
				
			||||||
      <div className="relative mx-auto max-w-7xl px-6 lg:px-8 grid grid-cols-1 lg:grid-cols-3 gap-16 items-center">
 | 
					      <div className="relative mx-auto max-w-7xl px-6 lg:px-8 grid grid-cols-1 lg:grid-cols-3 gap-16 items-center">
 | 
				
			||||||
        {/* Left Column - Text */}
 | 
					        {/* Left Column - Text */}
 | 
				
			||||||
        <div className="text-center lg:text-left">
 | 
					        <div className="text-center lg:text-left z-10">
 | 
				
			||||||
          <FadeIn>
 | 
					          <FadeIn>
 | 
				
			||||||
            <Eyebrow color="accent">Technology Layers</Eyebrow>
 | 
					            <Eyebrow color="accent">Technology Layers</Eyebrow>
 | 
				
			||||||
            <SectionHeader color="dark" className="text-4xl sm:text-5xl font-semibold">
 | 
					            <SectionHeader color="dark" className="text-4xl sm:text-5xl font-semibold">
 | 
				
			||||||
@@ -53,7 +71,7 @@ export function StackSectionLight() {
 | 
				
			|||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        {/* Right Column - Animated Stack */}
 | 
					        {/* Right Column - Animated Stack */}
 | 
				
			||||||
        <div className="lg:col-span-2 flex items-center justify-center lg:justify-start relative">
 | 
					        <div className="lg:col-span-2 flex items-center justify-center lg:justify-start relative z-10">
 | 
				
			||||||
          <motion.div
 | 
					          <motion.div
 | 
				
			||||||
            initial={{ y: 30, opacity: 0 }}
 | 
					            initial={{ y: 30, opacity: 0 }}
 | 
				
			||||||
            whileInView={{ y: 0, opacity: 1 }}
 | 
					            whileInView={{ y: 0, opacity: 1 }}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										32
									
								
								tailwind.config.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								tailwind.config.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,32 @@
 | 
				
			|||||||
 | 
					/** @type {import('tailwindcss').Config} */
 | 
				
			||||||
 | 
					export default {
 | 
				
			||||||
 | 
					  content: [
 | 
				
			||||||
 | 
					    "./index.html",
 | 
				
			||||||
 | 
					    "./src/**/*.{js,ts,jsx,tsx}",
 | 
				
			||||||
 | 
					  ],
 | 
				
			||||||
 | 
					  theme: {
 | 
				
			||||||
 | 
					    extend: {
 | 
				
			||||||
 | 
					      keyframes: {
 | 
				
			||||||
 | 
					        'glitch-1': {
 | 
				
			||||||
 | 
					          '0%': { transform: 'none' },
 | 
				
			||||||
 | 
					          '25%': { transform: 'skew(-0.5deg, -0.5deg)' },
 | 
				
			||||||
 | 
					          '50%': { transform: 'none' },
 | 
				
			||||||
 | 
					          '75%': { transform: 'skew(0.5deg, 0.5deg)' },
 | 
				
			||||||
 | 
					          '100%': { transform: 'none' },
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        'glitch-2': {
 | 
				
			||||||
 | 
					          '0%': { transform: 'none' },
 | 
				
			||||||
 | 
					          '25%': { transform: 'skew(-0.5deg, -0.5deg)' },
 | 
				
			||||||
 | 
					          '50%': { transform: 'none' },
 | 
				
			||||||
 | 
					          '75%': { transform: 'skew(0.5deg, 0.5deg)' },
 | 
				
			||||||
 | 
					          '100%': { transform: 'none' },
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      animation: {
 | 
				
			||||||
 | 
					        'glitch-1': 'glitch-1 1s infinite',
 | 
				
			||||||
 | 
					        'glitch-2': 'glitch-2 1s infinite',
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  plugins: [],
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user