updated landing page

This commit is contained in:
Ayush Rodrigues
2026-04-13 16:50:22 +01:00
parent d7a90df930
commit 8629228ed0
80 changed files with 8846 additions and 3759 deletions

View File

@@ -1,4 +1,4 @@
This is a [Next.js](https://nextjs.org) project bootstrapped with `[create-next-app](https://github.com/vercel/next.js/tree/canary/packages/create-next-app)`.
This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
## Getting Started
@@ -18,7 +18,7 @@ Open [http://localhost:3000](http://localhost:3000) with your browser to see the
You can start editing the page by modifying `app/page.js`. The page auto-updates as you edit the file.
This project uses `[next/font](https://nextjs.org/docs/app/building-your-application/optimizing/fonts)` to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel.
This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel.
## Learn More
@@ -35,10 +35,11 @@ The easiest way to deploy your Next.js app is to use the [Vercel Platform](https
Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details.
Designed by
██████ ██ ██ ██ ███████ ██ ██ ██ ██████ ██ █████ ██████ ███████
██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
██████ ██ ███ █████ ██ ██ ██ ██████ ██ ███████ ██████ ███████
██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
██ ██ ██ ██ ███████ ███████ ██████ ██ ███████ ██ ██ ██████ ███████

View File

@@ -459,9 +459,9 @@ export const IconAnalytics = (props) => (
</svg>
);
export const IconTeam = forwardRef((props, ref) => (
// Team Billing: billing.svg
export const IconTeam = (props) => (
<svg
ref={ref}
width="24"
height="24"
viewBox="0 0 24 24"
@@ -469,43 +469,17 @@ export const IconTeam = forwardRef((props, ref) => (
xmlns="http://www.w3.org/2000/svg"
{...props}
>
{/* Top Pixel */}
<path
className="icon-pixel-path"
d="M9.6 0H14.4V4.8H9.6V0Z"
fill="currentColor"
/>
{/* Right Pixel */}
<path
className="icon-pixel-path"
d="M19.2 9.6H24V14.4H19.2V9.6Z"
fill="currentColor"
/>
{/* Bottom Pixel */}
<path
className="icon-pixel-path"
d="M9.6 19.2H14.4V24H9.6V19.2Z"
fill="currentColor"
/>
{/* Left Pixel */}
<path
className="icon-pixel-path"
d="M0 9.6H4.8V14.4H0V9.6Z"
fill="currentColor"
/>
{/* Center Block with REAL HOLES (The Magic Fix) */}
<path
className="icon-pixel-path"
fillRule="evenodd"
clipRule="evenodd"
d="M4.8 4.8H19.2V19.2H4.8V4.8ZM9.6 4.8H14.4V9.6H9.6V4.8ZM9.6 14.4H14.4V19.2H9.6V14.4ZM4.8 9.6H9.6V14.4H4.8V9.6ZM14.4 9.6H19.2V14.4H14.4V9.6Z"
fill="currentColor"
/>
<path d="M9.6 0H14.4V4.8H9.6V0Z" fill="currentColor" />
<path d="M24 9.6V14.4H19.2V9.6H24Z" fill="currentColor" />
<path d="M9.6 19.2H14.4V24H9.6V19.2Z" fill="currentColor" />
<path d="M0 9.6H4.8V14.4H0V9.6Z" fill="currentColor" />
<path d="M4.8 4.8H9.6V9.6H4.8V4.8Z" fill="currentColor" />
<path d="M14.4 4.8H19.2V9.6H14.4V4.8Z" fill="currentColor" />
<path d="M9.6 9.6H14.4V14.4H9.6V9.6Z" fill="currentColor" />
<path d="M4.8 14.4H9.6V19.2H4.8V14.4Z" fill="currentColor" />
<path d="M14.4 14.4H19.2V19.2H14.4V14.4Z" fill="currentColor" />
</svg>
));
IconTeam.displayName = "IconTeam";
);
// Auto Top-ups: top-ups.svg
export const IconTopUp = (props) => (

View File

@@ -207,6 +207,7 @@ body {
background: var(--background);
color: var(--foreground);
font-family: var(--font-geist-sans);
overscroll-behavior-y: none;
}

View File

@@ -30,11 +30,11 @@ export const metadata = {
],
authors: [{ name: "Autumn" }],
creator: "Autumn",
metadataBase: new URL("https://useautumn.com/"),
metadataBase: new URL("https://autumndev.vercel.app"),
openGraph: {
type: "website",
locale: "en_US",
url: "https://useautumn.com/",
url: "https://autumndev.vercel.app",
siteName: "Autumn",
title: "Autumn — Billing Infrastructure for AI Startups",
description:

View File

@@ -26,8 +26,7 @@ export default function Home() {
</div>
<HomeSections />
<div
className="w-full flex-col gap-2.5 mt-10.5 hidden md:flex">
<div className="w-full flex-col gap-2.5 mt-10.5 hidden md:flex">
<div className="border-t border-[#292929] w-full" />
<div className="border-t border-[#292929] w-full" />
<div className="border-t border-[#292929] w-full" />

View File

@@ -1,31 +1,37 @@
"use client";
import Image from "next/image";
import { forwardRef } from "react";
export default function AnimatedFooterImage() {
const AnimatedFooterImage = forwardRef(function AnimatedFooterImage(_, ref) {
return (
<div className="fixed bottom-0 left-0 w-full z-0 pointer-events-none">
<div
ref={ref}
className="fixed bottom-0 lg:-bottom-46 left-0 w-full z-0 pointer-events-none"
>
{/* Mobile */}
<Image
src="/images/footer/maskedmobile.webp"
src="/images/footer/footer-mob.webp"
alt="footer background"
loading="lazy"
width={0}
height={0}
sizes="100vw"
className="block sm:hidden w-full h-auto"
className="block xl:hidden w-full h-[600px] md:h-[800px] object-cover object-top translate-y-35"
/>
{/* Desktop */}
<Image
src="/images/footer/maskedimage.webp"
src="/images/footer/footer.webp"
alt="footer background"
width={0}
height={0}
sizes="100vw"
loading="lazy"
className="hidden sm:block w-full h-auto"
className="hidden xl:block w-full h-auto xl:translate-y-16"
/>
</div>
);
}
});
export default AnimatedFooterImage;

View File

@@ -7,15 +7,7 @@ export const DashboardIconPixel = forwardRef(function DashboardIconPixel(
ref,
) {
const iconRef = useRef(null);
const pulseRef = useRef(null);
const tlRef = useRef(null);
const frames = [
"\u2800\u2836\u2800",
"\u2830\u28FF\u2806",
"\u28BE\u28C9\u2877",
"\u28CF\u2800\u28F9",
"\u2841\u2800\u2888",
];
useImperativeHandle(ref, () => ({
restart: () => tlRef.current?.play(),
@@ -23,48 +15,50 @@ export const DashboardIconPixel = forwardRef(function DashboardIconPixel(
}));
useEffect(() => {
const pixels = iconRef.current?.querySelectorAll(".icon-pixel-path");
const pulseEl = pulseRef.current;
if (!pixels || !pulseEl) return;
const pixelEls = iconRef.current?.querySelectorAll(".icon-pixel-path");
if (!pixelEls?.length) return;
// Sort pixels by visual position: bottom-left → top-right diagonal
const pixels = Array.from(pixelEls).sort((a, b) => {
const aBox = a.getBBox();
const bBox = b.getBBox();
return (
aBox.x +
aBox.width / 2 -
(aBox.y + aBox.height / 2) -
(bBox.x + bBox.width / 2 - (bBox.y + bBox.height / 2))
);
});
gsap.set(pixels, {
opacity: 0.25,
opacity: 0.15,
scale: 0.8,
transformOrigin: "left bottom",
fill: "currentColor",
});
gsap.set(pulseEl, { opacity: 0 });
tlRef.current = gsap
.timeline({ paused: true })
.to(pixels, { opacity: 0, duration: 0.05 })
.to(pulseEl, { opacity: 1, duration: 0.05 }, "<")
.to(pulseEl, {
tlRef.current = gsap.timeline({ paused: true });
tlRef.current
.to(pixels, {
opacity: 1,
scale: 1.15,
fill: "#FFFFFF",
duration: 0.2,
onUpdate: function () {
pulseEl.innerText =
frames[Math.floor(this.progress() * (frames.length - 1))];
},
stagger: 0.01,
ease: "power2.out",
})
.to(pulseEl, { opacity: 0, duration: 0.1 })
.to(
pixels,
{
opacity: 1,
scale: 1,
duration: 0.2,
stagger: { grid: [5, 5], from: [0, 4], amount: 0.2 },
},
"-=0.1",
);
.to(pixels, {
scale: 1,
duration: 0.01,
ease: "back.out(3)",
});
return () => tlRef.current?.kill();
}, []);
return (
// Height and Width match your original icon (14px)
<span className="relative inline-flex items-center justify-center w-[14px] h-[14px]">
<div
ref={pulseRef}
className="absolute z-20 font-mono text-[14px] text-white opacity-0"
/>
<Icon ref={iconRef} className="w-full h-full text-white" />
</span>
);

View File

@@ -1,14 +1,31 @@
"use client";
import { motion, useSpring, useTransform, useMotionValue } from "framer-motion";
import { useEffect } from "react";
import { motion, useMotionValue, useSpring, useTransform } from "framer-motion";
import { useEffect, useState } from "react";
import AnimatedFooterImage from "./animated-footer-image";
export default function ElasticRecoil({ children }) {
const liftAmount = useMotionValue(0);
const springConfig = { stiffness: 600, damping: 35, mass: 1 };
const [showFooter, setShowFooter] = useState(false);
const [isMobile, setIsMobile] = useState(false);
useEffect(() => {
const check = () => setIsMobile(window.innerWidth < 768);
check();
window.addEventListener("resize", check);
return () => window.removeEventListener("resize", check);
}, []);
const springConfig = { stiffness: 200, damping: 15, mass: 0.5 };
const animatedLift = useSpring(liftAmount, springConfig);
const y = useTransform(animatedLift, [0, 400], [0, -280]);
const cappedMax = isMobile ? -420 : -580;
const y = useTransform(animatedLift, [0, 400], [0, cappedMax]);
useEffect(() => {
return animatedLift.on("change", (v) => {
setShowFooter(v > 1);
});
}, [animatedLift]);
useEffect(() => {
let timeout;
@@ -29,16 +46,18 @@ export default function ElasticRecoil({ children }) {
document.documentElement.scrollHeight - 5;
if (isAtBottom && e.deltaY > 0) {
liftAmount.set(liftAmount.get() + e.deltaY * 0.5);
// Normalize delta: Firefox uses deltaMode=1 (lines, ~3/notch) instead of pixels
const normalizedDelta =
e.deltaMode === 1 ? e.deltaY * 20 : e.deltaMode === 2 ? e.deltaY * 300 : e.deltaY;
liftAmount.set(Math.min(liftAmount.get() + normalizedDelta * 0.5, 400));
recoilFired = false;
// Reset timeout on every wheel event
clearTimeout(timeout);
timeout = setTimeout(() => {
if (!isTouching) {
triggerRebound();
}
}, 1500); // Rebounds 1.5 seconds after wheel stops
}, 1500);
} else if (e.deltaY < 0) {
if (!isTouching) {
liftAmount.set(0);
@@ -47,36 +66,46 @@ export default function ElasticRecoil({ children }) {
}
};
let touchStart = 0;
let lastTouchY = 0;
let atBottomOnStart = false;
const handleTouchStart = (e) => {
isTouching = true;
touchStart = e.touches[0].clientY;
lastTouchY = e.touches[0].clientY;
atBottomOnStart =
window.innerHeight + window.pageYOffset >=
document.documentElement.scrollHeight - 5;
recoilFired = false;
clearTimeout(timeout);
};
const handleTouchMove = (e) => {
const isAtBottom =
window.innerHeight + window.pageYOffset >=
document.documentElement.scrollHeight - 5;
const currentY = e.touches[0].clientY;
const delta = lastTouchY - currentY;
lastTouchY = currentY;
if (isAtBottom) {
const touchDelta = touchStart - e.touches[0].clientY;
if (touchDelta > 0) {
liftAmount.set(touchDelta * 1.5);
recoilFired = false;
// Notice: We don't set a timeout here, so it never snaps back while touching
}
if (!atBottomOnStart) {
atBottomOnStart =
window.innerHeight + window.pageYOffset >=
document.documentElement.scrollHeight - 5;
return;
}
if (delta > 0) {
liftAmount.set(liftAmount.get() + delta * 0.8);
recoilFired = false;
} else if (liftAmount.get() > 0) {
liftAmount.set(Math.max(0, liftAmount.get() + delta * 0.8));
}
};
const handleTouchEnd = () => {
isTouching = false;
atBottomOnStart = false;
if (liftAmount.get() > 0) {
clearTimeout(timeout);
timeout = setTimeout(() => {
triggerRebound();
}, 1500); // Rebounds 1.5 seconds after lifting finger
}, 1500);
}
};
@@ -98,7 +127,7 @@ export default function ElasticRecoil({ children }) {
return (
<div className="relative w-full overflow-hidden">
<AnimatedFooterImage />
{showFooter && <AnimatedFooterImage />}
<motion.div style={{ y }} className="relative z-10 bg-black">
{children}
</motion.div>

View File

@@ -29,8 +29,8 @@ export default function FAQ() {
paddingRight: "var(--page-pad)",
}}
>
<div className="grid grid-cols-1 md:grid-cols-2 w-full min-h-[500px]">
<div className="md:border-r border-b border-[#292929] pl-4 md:pl-4 xl:pl-[90px] pr-6 lg:pr-12 py-12 md:py-[60px] flex flex-col justify-center">
<div className="grid grid-cols-1 lg:grid-cols-2 w-full min-h-[500px]">
<div className="lg:border-r border-b border-[#292929] pl-4 md:pl-4 xl:pl-[90px] pr-6 lg:pr-12 py-12 md:py-[60px] flex flex-col justify-center">
<h2 className="text-[30px] md:text-[40px] font-normal tracking-[-2%] leading-[1.1]">
<span className="text-[#FFFFFF99] font-light">
Frequently Asked
@@ -40,9 +40,9 @@ export default function FAQ() {
</h2>
</div>
<div className="hidden md:block border-b border-[#292929] h-full w-full"></div>
<div className="hidden lg:block border-b border-[#292929] h-full w-full"></div>
<div className="hidden md:block md:border-r border-[#292929] h-full w-full relative z-0">
<div className="hidden lg:block lg:border-r border-[#292929] h-full w-full relative z-0">
<div className="absolute bottom-0 w-full h-full pb-32"></div>
</div>
@@ -72,7 +72,7 @@ export default function FAQ() {
<div className="absolute inset-0 bg-linear-to-r from-[#351B6D]/90 via-[#351B6D]/80 to-black/75 mix-blend-normal" />
</div>
<div className="relative z-10 px-4.5 md:px-8 lg:px-[20px] py-[30px]">
<div className="relative z-10 px-4.5 md:px-4 lg:px-[20px] py-[30px]">
<div className="flex items-center justify-between gap-4">
<h3
className={`text-base lg:text-[18px] tracking-[-2%] transition-all duration-400 ${

View File

@@ -4,67 +4,50 @@ import gsap from "gsap";
export const FeatureIconAnimation = forwardRef(({ Icon }, ref) => {
const iconRef = useRef(null);
const pulseRef = useRef(null);
const tlRef = useRef(null);
const frames = [
"\u2800\u2836\u2800",
"\u2830\u28FF\u2806",
"\u28BE\u28C9\u2877",
"\u28CF\u2800\u28F9",
"\u2841\u2800\u2888",
];
useImperativeHandle(ref, () => ({
play: () => tlRef.current?.play(),
reverse: () => tlRef.current?.reverse(),
}));
useEffect(() => {
const pixels = iconRef.current?.querySelectorAll("path");
const pulseEl = pulseRef.current;
if (!pixels || !pulseEl) return;
const pixelEls = iconRef.current?.querySelectorAll("path");
if (!pixelEls?.length) return;
// Sort pixels by distance from center — center pixels animate first, outer ones last
const centers = Array.from(pixelEls).map((el) => {
const b = el.getBBox();
return { el, cx: b.x + b.width / 2, cy: b.y + b.height / 2 };
});
const midX = centers.reduce((s, c) => s + c.cx, 0) / centers.length;
const midY = centers.reduce((s, c) => s + c.cy, 0) / centers.length;
const pixels = centers
.sort((a, b) => {
const da = (a.cx - midX) ** 2 + (a.cy - midY) ** 2;
const db = (b.cx - midX) ** 2 + (b.cy - midY) ** 2;
return da - db;
})
.map((c) => c.el);
// IDLE: Subjugated/Ghost state
gsap.set(pixels, {
opacity: 0.15,
scale: 0.8,
transformOrigin: "left bottom",
transformOrigin: "center center",
fill: "currentColor",
});
gsap.set(pulseEl, { opacity: 0 });
tlRef.current = gsap.timeline({ paused: true });
tlRef.current
// SCRAMBLE
.to(pixels, { opacity: 0, duration: 0.05 })
.to(pulseEl, { opacity: 1, duration: 0.05 }, "<")
.to(pulseEl, {
duration: 0.3,
onUpdate: function () {
const frameIndex = Math.floor(this.progress() * (frames.length - 1));
pulseEl.innerText = frames[frameIndex];
},
ease: "none",
.to(pixels, {
opacity: 1,
scale: 1.15,
fill: "#9564ff",
duration: 0.2,
stagger: 0.04,
ease: "power2.out",
})
// REVEAL
.to(pulseEl, { opacity: 0, duration: 0.1, scale: 1.2 })
.to(
pixels,
{
opacity: 1,
scale: 1.15,
fill: "#9564ff", // Autumn Purple highlight for features
duration: 0.2,
stagger: {
grid: [5, 5],
from: [0, 4], // Bottom-Left Sweep
amount: 0.25,
},
ease: "power2.out",
},
"-=0.1",
)
.to(pixels, {
scale: 1,
duration: 0.15,
@@ -75,29 +58,8 @@ export const FeatureIconAnimation = forwardRef(({ Icon }, ref) => {
}, []);
return (
<div className="relative flex items-center justify-center w-12 h-12 group/icon">
{/* 5x5 Grid Mask */}
<div className="absolute inset-0 flex items-center justify-center pointer-events-none">
<div className="grid grid-cols-5 grid-rows-5 gap-[3px]">
{Array.from({ length: 25 }).map((_, i) => (
<div
key={i}
className="bg-white/[0.08] w-[2.5px] h-[2.5px] rounded-[0.5px]"
/>
))}
</div>
</div>
{/* Pulse Shuffle Layer */}
<div
ref={pulseRef}
className="absolute z-20 font-mono text-[20px] text-[#9564ff] pointer-events-none select-none"
>
{"\u2800\u2836\u2800"}
</div>
{/* Feature Icon Layer */}
<div className="relative z-10 w-[24px] h-[24px] flex items-center justify-center">
<div className="relative flex items-center justify-start w-12 h-12 group/icon">
<div className="relative w-[24px] h-[24px] flex items-center justify-center">
<Icon ref={iconRef} className="w-full h-full text-white" />
</div>
</div>

View File

@@ -4,14 +4,17 @@ import { useRef } from "react";
import { FeatureIconAnimation } from "./feature-icon-animation";
function FeatureCard({ feature }) {
const isDesktop =
typeof window !== "undefined" &&
window.matchMedia("(hover: hover)").matches;
const iconRef = useRef(null);
return (
<div
onMouseEnter={() => iconRef.current?.play()}
onMouseLeave={() => iconRef.current?.reverse()}
className="group relative flex px-4 md:px-6 flex-col justify-between p-6 bg-[#0F0F0F] min-h-[200px] md:min-h-[280px] border-r border-b border-[#292929] overflow-hidden cursor-pointer"
onMouseEnter={() => isDesktop && iconRef.current?.play()}
onMouseLeave={() => isDesktop && iconRef.current?.reverse()}
className="group relative flex px-4 md:px-4 flex-col justify-between p-6 bg-[#0F0F0F] min-h-[200px] md:min-h-[280px] border-r border-b border-[#292929] overflow-hidden cursor-pointer"
>
<div className="absolute inset-0 opacity-0 translate-y-6 group-hover:opacity-100 group-hover:translate-y-0 transition-all duration-500 ease-out pointer-events-none z-0 hidden md:block">
<div className="absolute inset-0 opacity-0 translate-y-6 md:group-hover:opacity-100 md:group-hover:translate-y-0 pointer-events-none z-0 hidden md:block">
<video
src="/images/features/pixel effect.webm"
autoPlay
@@ -22,7 +25,7 @@ function FeatureCard({ feature }) {
/>
</div>
{/* Hover Gradient Overlay */}
<div className="absolute inset-x-0 bottom-0 h-[70%] bg-[linear-gradient(to_bottom,rgba(10,10,10,0)_0%,rgba(135,82,250,0.15)_40%,rgba(135,82,250,0.45)_70%,rgba(135,82,250,0.85)_90%)] opacity-0 group-hover:opacity-100 transition-opacity duration-300 pointer-events-none" />
<div className="absolute inset-x-0 bottom-0 h-[70%] bg-[linear-gradient(to_bottom,rgba(10,10,10,0)_0%,rgba(135,82,250,0.15)_40%,rgba(135,82,250,0.45)_70%,rgba(135,82,250,0.85)_90%)] opacity-0 md:group-hover:opacity-100 transition-opacity duration-300 pointer-events-none" />
<div className="relative z-10 flex flex-col h-full gap-[42px] md:gap-24.5">
<feature.Icon className="w-6 h-6 text-white md:hidden" />

View File

@@ -147,7 +147,7 @@ export default function Hero() {
return (
<div ref={containerRef}>
<div className="relative hero-root opacity-0 flex flex-col items-stretch pb-0 xl:pb-2.5 mb-0 lg:mb-[33px] bg-[#0F0F0F]">
<div className="relative hero-root opacity-0 flex flex-col items-stretch pb-0 md:pb-12 mb-0 bg-[#0F0F0F]">
<div className="relative hidden xl:block">
<Image
className="hero-bg w-full hidden md:block"
@@ -205,10 +205,10 @@ export default function Hero() {
{/* Adjusted px-3 for mobile, md:px-4 for desktop */}
<div className="relative overflow-hidden flex items-center gap-1.5 md:gap-2.5 cursor-pointer justify-between py-2 px-3 md:px-4 md:py-3.5 md:w-50 font-sans bg-[#9564ff] hover:bg-[#7D46F4] transition-colors duration-300">
<CTALines />
<span className="relative z-10 tracking-tight text-white font-medium text-[13px] md:text-base whitespace-nowrap">
<span className="relative z-10 tracking-[-2%] uppercase md:normal-case text-white font-medium text-[12px] md:text-base whitespace-nowrap">
Start for free
</span>
<span className="relative z-10 scale-75 md:scale-100">
<span className="relative z-10 scale-95 md:scale-100">
<IconCTAStart />
</span>
</div>
@@ -227,10 +227,10 @@ export default function Hero() {
>
<div className="relative overflow-hidden flex items-center gap-1.5 md:gap-2.5 border-r border-[#292929] text-white cursor-pointer justify-between py-2 px-3 md:px-4 md:py-3.5 md:w-50 font-sans bg-[#0F0F0F] hover:bg-[#FFFFFF1F] transition-colors duration-300">
<CTALines />
<span className="relative z-10 tracking-tight text-[12px] md:text-[16px] whitespace-nowrap">
<span className="relative z-10 tracking-[-2%] text-[12px] uppercase md:normal-case md:text-[16px] whitespace-nowrap">
Read docs
</span>
<span className="relative z-10 scale-75 md:scale-100">
<span className="relative z-10 scale-100">
<IconCTADocs />
</span>
</div>
@@ -238,12 +238,12 @@ export default function Hero() {
</Link>
</div>
<div className="hero-cta flex flex-nowrap gap-2 md:gap-3 ml-2 md:ml-3 h-10.5 md:h-12.5 flex-1">
<div className="hero-cta hidden md:flex flex-nowrap gap-2 md:gap-3 ml-2 md:ml-3 h-10.5 md:h-12.5 flex-1">
<div className="border-r border-[#292929] h-full hidden md:block" />
<div className="border-r border-[#292929] h-full hidden md:block" />
<div className="border-r border-[#292929] h-full hidden md:block" />
<div className="border-r border-[#292929] h-full hidden min-[400px]:block" />
<div className="border-r border-[#292929] h-full hidden md:block" />
<div className="border-r border-[#292929] h-full hidden md:block" />
<div className="border-r border-[#292929] h-full hidden md:block" />
<div className="border-r border-[#292929] h-full hidden md:block" />

View File

@@ -37,30 +37,27 @@ const NAV_LINKS = [
const NavIconPixel = forwardRef(function NavIconPixel({ Icon }, ref) {
const iconRef = useRef(null);
const pulseRef = useRef(null);
const tlRef = useRef(null);
const frames = [
"\u2800\u2836\u2800",
"\u2830\u28FF\u2806",
"\u28BE\u28C9\u2877",
"\u28CF\u2800\u28F9",
"\u2841\u2800\u2888",
];
useImperativeHandle(ref, () => ({
restart: () => {
tlRef.current?.play();
},
reverse: () => {
tlRef.current?.reverse();
},
restart: () => tlRef.current?.play(),
reverse: () => tlRef.current?.reverse(),
}));
useEffect(() => {
const pixels = iconRef.current?.querySelectorAll(".icon-pixel-path");
const pulseEl = pulseRef.current;
if (!pixels || !pulseEl) return;
const pixelEls = iconRef.current?.querySelectorAll(".icon-pixel-path");
if (!pixelEls?.length) return;
const pixels = Array.from(pixelEls).sort((a, b) => {
const aBox = a.getBBox();
const bBox = b.getBBox();
return (
aBox.x +
aBox.width / 2 -
(aBox.y + aBox.height / 2) -
(bBox.x + bBox.width / 2 - (bBox.y + bBox.height / 2))
);
});
gsap.set(pixels, {
opacity: 0.15,
@@ -68,42 +65,21 @@ const NavIconPixel = forwardRef(function NavIconPixel({ Icon }, ref) {
transformOrigin: "left bottom",
fill: "currentColor",
});
gsap.set(pulseEl, { opacity: 0 });
tlRef.current = gsap.timeline({ paused: true });
tlRef.current
.to(pixels, { opacity: 0, duration: 0.05 })
.to(pulseEl, { opacity: 1, duration: 0.05 }, "<")
.to(pulseEl, {
duration: 0.3,
onUpdate: function () {
const frameIndex = Math.floor(this.progress() * (frames.length - 1));
pulseEl.innerText = frames[frameIndex];
},
ease: "none",
.to(pixels, {
opacity: 1,
scale: 1.15,
fill: "#FFFFFF",
duration: 0.01,
stagger: 0.025,
ease: "power2.out",
})
// 3. REVEAL: Pulse fades, SVG Icon sweeps in from bottom-left
.to(pulseEl, { opacity: 0, duration: 0.1, scale: 1.2 })
.to(
pixels,
{
opacity: 1,
scale: 1.15,
fill: "#FFFFFF",
duration: 0.2,
stagger: {
grid: [5, 5],
from: [0, 4], // Bottom-Left scan
amount: 0.25,
},
ease: "power2.out",
},
"-=0.1",
)
.to(pixels, {
scale: 1,
duration: 0.15,
duration: 0.01,
ease: "back.out(3)",
});
@@ -112,28 +88,7 @@ const NavIconPixel = forwardRef(function NavIconPixel({ Icon }, ref) {
return (
<span className="relative inline-flex items-center justify-center w-8 h-8 group/icon">
{/* BACKGROUND MASK: Static field dots */}
<div className="absolute inset-0 flex items-center justify-center pointer-events-none">
<div className="grid grid-cols-5 grid-rows-5 gap-[3px]">
{Array.from({ length: 25 }).map((_, i) => (
<div
key={i}
className="bg-white/[0.08] w-[1px] h-[1px] rounded-[0.5px]"
/>
))}
</div>
</div>
{/* BRAILLE PULSE LAYER */}
<div
ref={pulseRef}
className="absolute z-20 font-mono text-[16px] text-white pointer-events-none select-none"
>
{"\u2800\u2836\u2800"}
</div>
{/* SVG ICON LAYER (Idle: Faded / Hover: Solid) */}
<div className="relative z-10 w-[16px] h-[16px] flex items-center justify-center">
<div className="relative w-[16px] h-[16px] flex items-center justify-center">
<Icon ref={iconRef} className="w-full h-full text-white" />
</div>
</span>
@@ -330,10 +285,11 @@ export default function Navbar() {
)}
<div
className={`${scrolled && !recoilHidden
? "fixed top-0 left-0 z-80 w-full px-4 md:px-(--page-pad) bg-[#0F0F0F] backdrop-blur-md border-b border-t pt-4 border-[#292929]"
: "relative"
}`}
className={`${
scrolled && !recoilHidden
? "fixed top-0 left-0 z-80 w-full px-4 md:px-(--page-pad) bg-[#0F0F0F] backdrop-blur-md border-b border-t pt-4 border-[#292929]"
: "relative"
}`}
>
{scrolled && !recoilHidden && (
<>
@@ -342,7 +298,7 @@ export default function Navbar() {
<div className="absolute pointer-events-none right-4 md:right-(--page-pad) top-0 bottom-0 border-r border-[#292929]" />
</>
)}
<nav className="nav-root bg-[#0F0F0F] flex items-center justify-between font-mono uppercase text-xs pl-2 pt-2.5 lg:py-0 xl:py-0 pb-2.5 lg:pb-0 xl:pb-0">
<nav className="nav-root bg-[#0F0F0F] flex items-center justify-between font-mono uppercase text-xs pl-2 md:pl-0 h-[44px] md:h-[44px] lg:pb-0 xl:pb-0">
<Link href={"/"}>
<Image
src="/images/navbar/autumnlogo.svg"
@@ -354,13 +310,13 @@ export default function Navbar() {
/>
</Link>
<div className="hidden md:flex items-center gap-6">
<div className="hidden lg:flex items-center gap-6">
{NAV_LINKS.map((item) => (
<NavLinkItem key={item.label} item={item} />
))}
</div>
<div className="nav-dashboard hidden md:block">
<div className="nav-dashboard hidden lg:block">
<motion.div
initial="initial"
whileHover="hover"
@@ -389,7 +345,7 @@ export default function Navbar() {
</div>
<motion.button
className="md:hidden mr-2 p-1.5 text-[#FFFFFF99] cursor-pointer"
className="lg:hidden mr-2 p-1.5 text-[#FFFFFF99] cursor-pointer"
onClick={() => setMenuOpen(!menuOpen)}
whileTap={{ scale: 0.9 }}
aria-label="Toggle menu"
@@ -399,8 +355,12 @@ export default function Navbar() {
</nav>
</div>
<div
className={`fixed w-full nav-mobile left-0 overflow-y-auto bg-[#000000] flex flex-col font-mono uppercase ${scrolled && !recoilHidden ? "top-[62px] sm:top-[60px]" : "top-[66px] sm:top-[62px]"} md:top-5 h-[calc(100dvh-58px)] z-40 px-4 pb-8 transition-all duration-300`}
style={{ opacity: 0, pointerEvents: "none", clipPath: "inset(0% 0 100% 0)" }}
className={`fixed nav-mobile inset-x-0 overflow-y-auto overflow-x-hidden bg-[#000000] flex flex-col font-mono uppercase lg:top-5 h-[calc(100dvh-58px)] z-40 px-4 md:px-(--page-pad) pb-8 transition-all duration-300`}
style={{
opacity: 0,
pointerEvents: "none",
clipPath: "inset(0% 0 100% 0)",
}}
>
{/* Nav items */}
<div className="flex flex-col">

View File

@@ -73,7 +73,7 @@ export default function PricingModels() {
return (
<section className="bg-[#000000] w-full overflow-hidden flex flex-col">
<div className="hidden lg:flex w-full items-center justify-between py-24 relative z-10 px-4 xl:px-22.75">
<div className="hidden lg:flex w-full items-center justify-between py-12 xl:py-24 relative z-10 px-4 xl:px-22.75">
<div className="flex w-full">
<div className="">
<h2 className="text-[40px] leading-[1.1] font-sans tracking-[-2%] font-normal">
@@ -110,7 +110,7 @@ export default function PricingModels() {
</div>
</div>
<div className="border-t-0 lg:border-t border-[#292929] w-full relative grid grid-cols-1 lg:grid-cols-[60px_220px_220px_1fr] xl:grid-cols-[90px_291px_300px_1fr] auto-rows-auto lg:grid-rows-[260px_340px]">
<div className="border-t-0 lg:border-t border-[#292929] w-full relative grid grid-cols-1 lg:grid-cols-[60px_220px_220px_1fr] xl:grid-cols-[90px_291px_300px_1fr] auto-rows-auto lg:grid-rows-[200px_260px] xl:grid-rows-[260px_340px]">
<div className="absolute top-0 bottom-0 right-0 lg:w-[calc(100%-500px)] xl:w-[calc(100%-680px)] z-0 overflow-hidden hidden lg:block pointer-events-none">
<video
src="/images/pricing-models/pricingbg.webm"
@@ -189,7 +189,7 @@ export default function PricingModels() {
className="absolute inset-0 w-full h-full object-cover object-left mix-blend-screen opacity-100"
/>
</div>
<div className="absolute bottom-0 left-0 right-0 z-10 flex items-center justify-center px-2.5 pt-2">
<div className="absolute bottom-0 left-0 right-0 z-10 flex items-center justify-center px-3 pt-2">
<img
src={images[item.model]}
alt="Pricing Model"
@@ -202,7 +202,7 @@ export default function PricingModels() {
</AnimatePresence>
<div
className={`text-[20px] lg:text-[20px] tracking-[-5%] leading-none lg:leading-[20px] flex items-center gap-2 font-sans px-6 lg:px-[14px] py-5 lg:py-1.5 ${
className={`text-[20px] lg:text-[20px] tracking-[-5%] leading-none lg:leading-[20px] flex items-center gap-2 font-sans px-4 lg:px-[14px] py-5 lg:py-1.5 ${
isActive
? "text-white lg:text-[#FFFFFF99]"
: "text-[#FFFFFF99] lg:text-[#FFFFFF99] lg:opacity-50"
@@ -226,7 +226,7 @@ export default function PricingModels() {
initial={{ height: 0, opacity: 0 }}
animate={{ height: "auto", opacity: 1 }}
exit={{ height: 0, opacity: 0 }}
className="lg:hidden px-6 border-b border-[#8752FA] overflow-hidden text-[#FFFFFF99] text-[14px] md:text-[16px] lg:text-[14px] leading-[1.4] tracking-[-2%] font-light text-pretty"
className="lg:hidden px-4 border-b border-[#8752FA] overflow-hidden text-[#FFFFFF99] text-[14px] md:text-[16px] lg:text-[14px] leading-[1.4] tracking-[-2%] font-light text-pretty"
>
<div className="pb-6">{item.desc}</div>
</motion.div>

View File

@@ -57,7 +57,7 @@ export default function Pricing() {
<div className="min-h-screen relative flex w-full lg:w-[calc(100%+calc(var(--page-pad)*2))] lg:-ml-(--page-pad) items-center justify-center lg:py-24 pb-3">
{/* Desktop Background */}
<Image
src="/images/pricing/pricingbg.webp"
src="/images/pricing/pricing.webp"
alt="pricing background desktop"
fill
className="object-cover absolute z-10 lg:z-50 hidden md:block"
@@ -65,7 +65,7 @@ export default function Pricing() {
/>
{/* Mobile Background */}
<Image
src="/images/pricing/pricing_mobile.webp"
src="/images/pricing/pricing-mob.webp"
alt="pricing background mobile"
fill
className="object-cover absolute z-10 lg:z-50 block md:hidden"
@@ -85,11 +85,9 @@ export default function Pricing() {
{plans.map((plan, index) => (
<div
key={plan.name}
className={`relative flex flex-col bg-black lg:bg-transparent border lg:border-0 border-[#292929] ${
index === 0 ? "lg:border-r" : ""
} ${
index === 1 ? "lg:border-r" : ""
} ${index === 2 ? "md:col-span-2 lg:col-span-1 md:w-[calc(50%-16px)] md:justify-self-center lg:w-full lg:justify-self-auto" : ""}`}
className={`relative flex flex-col bg-black lg:bg-transparent border lg:border-0 border-[#292929] ${index === 0 ? "lg:border-r" : ""
} ${index === 1 ? "lg:border-r" : ""
} ${index === 2 ? "md:col-span-2 lg:col-span-1 md:w-[calc(50%-16px)] md:justify-self-center lg:w-full lg:justify-self-auto" : ""}`}
>
{plan.isPro && (
<div className="hidden lg:block absolute -inset-px z-20 pointer-events-none border border-transparent [border-image:linear-gradient(to_bottom,#A175FF,#000000)_1]"></div>

View File

@@ -149,16 +149,20 @@ export default function ProblemAnimation() {
const handleImageLoad = (index, event) => {
const img = event.target;
const isMobile = window.innerWidth < 768;
const scale = isMobile ? 0.6 : 1;
const scale = isMobile ? 0.7 : 1;
const w = img.naturalWidth * scale;
const h = img.naturalHeight * scale;
img.style.width = `${w}px`;
img.style.height = `${h}px`;
const container = containerRef.current;
const spread = isMobile ? 0.7 : 0.4;
const spawnX =
container.offsetWidth / 2 +
(Math.random() - 0.5) * (container.offsetWidth * 0.4);
const spawnY = -100 - index * 50;
(Math.random() - 0.5) * (container.offsetWidth * spread);
const spawnY = isMobile ? -100 : -100 - index * 50;
const body = Matter.Bodies.rectangle(spawnX, spawnY, w, h, {
chamfer: { radius: h / 4 },
@@ -187,7 +191,7 @@ export default function ProblemAnimation() {
return (
<div
ref={containerRef}
className="relative w-full h-[450px] lg:h-full bg-[#080808] overflow-hidden touch-none"
className="relative w-full h-140 md:h-175 lg:h-175 xl:h-full bg-[#080808] overflow-hidden touch-none"
>
{IMAGE_SOURCES.map((src, i) => (
<div

View File

@@ -24,27 +24,27 @@ export default function Problem() {
className="shrink-0 mt-1 md:mt-0"
style={{ width: "auto", height: "auto" }}
/>
<p className="text-[#D942B5] font-light tracking-[-2%] text-[14px] md:text-[16px] lg:text-[16px] leading-[18px] md:leading-[20px]">
<p className="text-[#D942B5] font-light tracking-[-2%] text-[14px] md:text-[16px] xl:text-[16px] leading-[18px] md:leading-[20px]">
<span className="font-light mr-1">The hidden complexity:</span>
Payment processors move money. They don&apos;t handle the state
management that happens between payments.
</p>
</div>
</div>
<div className="grid lg:grid-cols-2 gap-0 lg:h-[800px]">
<div className="grid xl:grid-cols-2 gap-0 xl:h-[800px]">
{/* LEFT COLUMN */}
<div className="bg-[#0D0D0D] flex flex-col border-r border-[#292929] border-l border-l-[#292929] pb-[20px] md:pb-0">
<div className="flex flex-col mb-2 gap-3 pl-[28px] xl:pl-[90px] pr-6 lg:pr-8 pt-14 sm:pt-16 lg:pt-16 items-center lg:items-start">
<h2 className="font-normal tracking-[-4%] leading-[32px] lg:leading-[40px] mb-2 lg:mb-4 text-center lg:text-left">
<span className="block text-white text-[30px] md:text-[36px] lg:text-[40px]">
<div className="flex flex-col mb-2 gap-3 pl-[28px] xl:pl-[90px] pr-6 xl:pr-8 pt-14 sm:pt-16 xl:pt-16 items-center xl:items-start">
<h2 className="font-normal tracking-[-4%] leading-[32px] xl:leading-[40px] mb-2 xl:mb-4 text-center xl:text-left">
<span className="block text-white text-[30px] md:text-[36px] xl:text-[40px]">
AI made billing
</span>
<span className="block text-[#686868] text-[30px] md:text-[36px] lg:text-[40px]">
<span className="block text-[#686868] text-[30px] md:text-[36px] xl:text-[40px]">
way harder
</span>
</h2>
<p className="text-[#888888] font-light text-[16px] md:text-[18px] lg:text-[16px] tracking-[-2%] leading-[20px] mb-8 lg:mb-10 max-w-sm md:max-w-lg lg:max-w-sm text-center lg:text-left">
<p className="text-[#888888] font-light text-[16px] md:text-[18px] xl:text-[16px] tracking-[-2%] leading-[20px] mb-8 xl:mb-10 max-w-sm md:max-w-lg xl:max-w-sm text-center xl:text-left">
You&apos;re not charging for access anymore. You&apos;re metering
tokens, tracking credits, resetting quotas &mdash;{" "}
<span className="text-white">
@@ -54,7 +54,7 @@ export default function Problem() {
</div>
<div className="mt-auto">
<div className="grid grid-cols-2 md:grid-cols-[max-content_max-content_max-content_auto] border-t border-b border-[#1E1E1E]">
<div className="grid grid-cols-2 xl:grid-cols-[max-content_max-content_max-content_auto] border-t border-b border-[#1E1E1E]">
{[
{ value: "36", label: "Uptime SLA target" },
{ value: "40+ lines", label: "to gate one feature" },
@@ -63,23 +63,25 @@ export default function Problem() {
<div
key={i}
className={`py-6 pr-9 border-[#292929] border-r
${i === 2 ? "col-span-2 md:col-span-1 border-t md:border-t-0 border-r-0 md:border-r" : ""}
${/* Mobile: Infinite cases (i=2) now matches the 28px padding of the first item (i=0) */ ""}
${i === 0 || i === 2 ? "pl-[28px]" : "pl-4"}
md:pl-6 ${i === 0 ? "xl:pl-[90px]" : ""}`}
${i === 2 ? "col-span-2 xl:col-span-1 border-t xl:border-t-0 border-r-0 xl:border-r" : ""}
${i === 1 ? "border-r-0 xl:border-r" : ""}
${i === 0 || i === 2 ? "pl-4" : "pl-4"}
xl:pl-6 ${i === 0 ? "xl:pl-[90px]" : ""}`}
>
<p className="text-white tracking-[-5%] font-normal text-[18px] lg:text-[24px] leading-none">
<p className="text-white tracking-[-5%] font-normal text-[18px] xl:text-[24px] leading-none">
{stat.value}
</p>
{/* whitespace-nowrap ensures it stays on one line regardless of container width */}
<p className="text-[#767676] font-light tracking-[-5%] text-[16px] lg:text-[18px] mt-1.5 leading-[20px] whitespace-nowrap">
<p className="text-[#767676] font-light tracking-[-5%] text-[16px] xl:text-[18px] mt-1.5 leading-[20px] whitespace-nowrap">
{stat.label}
</p>
</div>
))}
<div className="hidden md:flex flex-1 items-stretch">
<div className="hidden xl:flex flex-1 items-stretch">
{[...Array(4)].map((_, i) => (
<div key={i} className="flex-1 border-r border-[#292929]" />
<div
key={i}
className={`flex-1 ${i < 3 ? "border-r border-[#292929]" : ""}`}
/>
))}
</div>
</div>
@@ -89,7 +91,7 @@ export default function Problem() {
</div>
{/* RIGHT COLUMN — problem animation */}
<div className="relative overflow-hidden ">
<div className="relative overflow-hidden">
<ProblemAnimation />
</div>
</div>

View File

@@ -150,7 +150,7 @@ export default function ProductionScale() {
return (
<div ref={containerRef} className="overflow-hidden">
<section className="ps-section flex flex-col lg:flex-row items-start justify-between py-12 lg:py-16 gap-12 lg:gap-0 bg-[#0F0F0F]">
<div className="flex px-6 xl:pl-22.5 lg:pr-0 flex-col my-auto gap-4 lg:gap-6 pt-2 w-full lg:w-auto">
<div className="flex px-4 xl:pl-22.5 lg:pr-0 flex-col my-auto gap-4 lg:gap-6 pt-2 w-full lg:w-auto">
<div className="leading-none lg:leading-10">
<p className="text-[#FFFFFF99] tracking-[-4%] text-[30px] lg:text-[40px] font-normal">
Built for
@@ -163,7 +163,8 @@ export default function ProductionScale() {
Autumn handles billions of billing events monthly. Open source core,
self-host ready,{" "}
<span className="text-white">
designed for teams that <br className="hidden lg:block" /> can&apos;t afford billing downtime.
designed for teams that <br className="hidden lg:block" />{" "}
can&apos;t afford billing downtime.
</span>
</p>
</div>

View File

@@ -45,6 +45,7 @@ const testimonialsData = [
];
const Testimonials = () => {
const videoRef = useRef(null);
const scrollRef = useRef(null);
const progressRef = useRef(null);
const [canScrollLeft, setCanScrollLeft] = useState(false);
@@ -63,6 +64,11 @@ const Testimonials = () => {
}
}
};
useEffect(() => {
if (videoRef.current) {
videoRef.current.playbackRate = 0.4;
}
}, []);
useEffect(() => {
handleScroll();
@@ -79,7 +85,7 @@ const Testimonials = () => {
return (
<section className="w-full bg-[#000000] text-white overflow-hidden">
<div className=" mx-auto">
<div className="px-4 sm:px-6 md:px-4 xl:px-22.75 pt-[48px] xl:pt-32 pb-[48px] flex flex-row items-start justify-between">
<div className="px-4 sm:px-6 md:px-4 lg:px-4 xl:px-22.75 pt-[48px] xl:pt-32 pb-[48px] flex flex-row items-start justify-between">
<h2 className="w-full text-center md:w-auto md:text-left text-[30px] leading-[32px] sm:text-5xl md:text-[40px] font-normal tracking-[-5%]">
<span className="text-[#FFFFFF99]">Built by </span>
<span className="text-white">teams</span>
@@ -125,11 +131,21 @@ const Testimonials = () => {
{testimonialsData.map((testimonial) => (
<div
key={testimonial.id}
className="group shrink-0 w-[300px] sm:w-[300px] md:w-[360px] snap-start min-h-[360px] flex flex-col justify-between p-4 sm:p-10 border-l border-r border-b border-[#1A1A1A] transition-all duration-300 relative overflow-hidden"
className="group cursor-pointer shrink-0 w-[300px] sm:w-[300px] md:w-[360px] snap-start min-h-[360px] flex flex-col justify-between p-4 sm:p-10 border-l border-r border-b border-[#1A1A1A] transition-all duration-300 relative overflow-hidden"
>
{/* Hover Pixelated Pattern (Masked) */}
<div className="absolute inset-x-0 bottom-0 h-[120%] pointer-events-none z-0 overflow-hidden">
<PixelatedPattern className="w-full h-full object-cover object-bottom opacity-0 translate-y-6 group-hover:opacity-100 group-hover:translate-y-0 transition-all duration-500 ease-out" />
<div className="absolute inset-0 opacity-0 translate-y-6 group-hover:opacity-100 group-hover:translate-y-0 transition-all duration-500 ease-out pointer-events-none z-0 hidden md:block">
<video
ref={videoRef}
src="/images/testimonials/testimonial section.webm"
autoPlay
loop
muted
playsInline
className="w-full h-full object-cover"
/>
</div>
</div>
{/* Purple Glow Gradient Overlay */}
<div className="absolute inset-x-0 bottom-0 h-[70%] bg-[linear-gradient(to_bottom,rgba(10,10,10,0)_0%,rgba(135,82,250,0.15)_40%,rgba(135,82,250,0.45)_70%,rgba(135,82,250,0.85)_90%)] opacity-0 group-hover:opacity-100 transition-opacity duration-300 pointer-events-none z-0" />

View File

@@ -1,6 +1,7 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
/* config options here */
allowedDevOrigins: ['*.ngrok-free.dev']
};
export default nextConfig;

View File

@@ -1,11 +1,11 @@
{
"name": "pixelup-dev",
"name": "autumndev",
"version": "0.1.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "pixelup-dev",
"name": "autumndev",
"version": "0.1.0",
"dependencies": {
"@gsap/react": "^2.1.2",
@@ -14,6 +14,7 @@
"matter-js": "^0.20.0",
"motion": "^12.38.0",
"next": "16.2.1",
"ngrok": "^5.0.0-beta.2",
"react": "19.2.4",
"react-dom": "19.2.4",
"react-syntax-highlighter": "^16.1.1"
@@ -1254,6 +1255,18 @@
"dev": true,
"license": "MIT"
},
"node_modules/@sindresorhus/is": {
"version": "4.6.0",
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz",
"integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==",
"license": "MIT",
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sindresorhus/is?sponsor=1"
}
},
"node_modules/@swc/helpers": {
"version": "0.5.15",
"resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz",
@@ -1263,6 +1276,18 @@
"tslib": "^2.8.0"
}
},
"node_modules/@szmarczak/http-timer": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz",
"integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==",
"license": "MIT",
"dependencies": {
"defer-to-connect": "^2.0.0"
},
"engines": {
"node": ">=10"
}
},
"node_modules/@tailwindcss/node": {
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.2.2.tgz",
@@ -1545,6 +1570,18 @@
"tslib": "^2.4.0"
}
},
"node_modules/@types/cacheable-request": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz",
"integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==",
"license": "MIT",
"dependencies": {
"@types/http-cache-semantics": "*",
"@types/keyv": "^3.1.4",
"@types/node": "*",
"@types/responselike": "^1.0.0"
}
},
"node_modules/@types/estree": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
@@ -1561,6 +1598,12 @@
"@types/unist": "*"
}
},
"node_modules/@types/http-cache-semantics": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz",
"integrity": "sha512-L3LgimLHXtGkWikKnsPg0/VFx9OGZaC+eN1u4r+OB1XRqH3meBIAVC2zr1WdMH+RHmnRkqliQAOHNJ/E0j/e0Q==",
"license": "MIT"
},
"node_modules/@types/json-schema": {
"version": "7.0.15",
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
@@ -1575,18 +1618,55 @@
"dev": true,
"license": "MIT"
},
"node_modules/@types/keyv": {
"version": "3.1.4",
"resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz",
"integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==",
"license": "MIT",
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/node": {
"version": "25.6.0",
"resolved": "https://registry.npmjs.org/@types/node/-/node-25.6.0.tgz",
"integrity": "sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ==",
"license": "MIT",
"dependencies": {
"undici-types": "~7.19.0"
}
},
"node_modules/@types/prismjs": {
"version": "1.26.6",
"resolved": "https://registry.npmjs.org/@types/prismjs/-/prismjs-1.26.6.tgz",
"integrity": "sha512-vqlvI7qlMvcCBbVe0AKAb4f97//Hy0EBTaiW8AalRnG/xAN5zOiWWyrNqNXeq8+KAuvRewjCVY1+IPxk4RdNYw==",
"license": "MIT"
},
"node_modules/@types/responselike": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.3.tgz",
"integrity": "sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==",
"license": "MIT",
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/unist": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz",
"integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==",
"license": "MIT"
},
"node_modules/@types/yauzl": {
"version": "2.10.3",
"resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz",
"integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==",
"license": "MIT",
"optional": true,
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@typescript-eslint/eslint-plugin": {
"version": "8.57.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.57.2.tgz",
@@ -2514,6 +2594,42 @@
"node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
}
},
"node_modules/buffer-crc32": {
"version": "0.2.13",
"resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
"integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==",
"license": "MIT",
"engines": {
"node": "*"
}
},
"node_modules/cacheable-lookup": {
"version": "5.0.4",
"resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz",
"integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==",
"license": "MIT",
"engines": {
"node": ">=10.6.0"
}
},
"node_modules/cacheable-request": {
"version": "7.0.4",
"resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz",
"integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==",
"license": "MIT",
"dependencies": {
"clone-response": "^1.0.2",
"get-stream": "^5.1.0",
"http-cache-semantics": "^4.0.0",
"keyv": "^4.0.0",
"lowercase-keys": "^2.0.0",
"normalize-url": "^6.0.1",
"responselike": "^2.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/call-bind": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz",
@@ -2647,6 +2763,18 @@
"integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==",
"license": "MIT"
},
"node_modules/clone-response": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz",
"integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==",
"license": "MIT",
"dependencies": {
"mimic-response": "^1.0.0"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
@@ -2771,7 +2899,6 @@
"version": "4.4.3",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
"integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
"dev": true,
"license": "MIT",
"dependencies": {
"ms": "^2.1.3"
@@ -2798,6 +2925,33 @@
"url": "https://github.com/sponsors/wooorm"
}
},
"node_modules/decompress-response": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz",
"integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",
"license": "MIT",
"dependencies": {
"mimic-response": "^3.1.0"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/decompress-response/node_modules/mimic-response": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",
"integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==",
"license": "MIT",
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/deep-is": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
@@ -2805,6 +2959,15 @@
"dev": true,
"license": "MIT"
},
"node_modules/defer-to-connect": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz",
"integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==",
"license": "MIT",
"engines": {
"node": ">=10"
}
},
"node_modules/define-data-property": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
@@ -2893,6 +3056,15 @@
"dev": true,
"license": "MIT"
},
"node_modules/end-of-stream": {
"version": "1.4.5",
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz",
"integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==",
"license": "MIT",
"dependencies": {
"once": "^1.4.0"
}
},
"node_modules/enhanced-resolve": {
"version": "5.20.1",
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.20.1.tgz",
@@ -3538,6 +3710,26 @@
"node": ">=0.10.0"
}
},
"node_modules/extract-zip": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz",
"integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==",
"license": "BSD-2-Clause",
"dependencies": {
"debug": "^4.1.1",
"get-stream": "^5.1.0",
"yauzl": "^2.10.0"
},
"bin": {
"extract-zip": "cli.js"
},
"engines": {
"node": ">= 10.17.0"
},
"optionalDependencies": {
"@types/yauzl": "^2.9.1"
}
},
"node_modules/fast-deep-equal": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
@@ -3612,6 +3804,15 @@
"url": "https://github.com/sponsors/wooorm"
}
},
"node_modules/fd-slicer": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
"integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==",
"license": "MIT",
"dependencies": {
"pend": "~1.2.0"
}
},
"node_modules/file-entry-cache": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz",
@@ -3827,6 +4028,21 @@
"node": ">= 0.4"
}
},
"node_modules/get-stream": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
"integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
"license": "MIT",
"dependencies": {
"pump": "^3.0.0"
},
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/get-symbol-description": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz",
@@ -3914,6 +4130,31 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/got": {
"version": "11.8.6",
"resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz",
"integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==",
"license": "MIT",
"dependencies": {
"@sindresorhus/is": "^4.0.0",
"@szmarczak/http-timer": "^4.0.5",
"@types/cacheable-request": "^6.0.1",
"@types/responselike": "^1.0.0",
"cacheable-lookup": "^5.0.3",
"cacheable-request": "^7.0.2",
"decompress-response": "^6.0.0",
"http2-wrapper": "^1.0.0-beta.5.2",
"lowercase-keys": "^2.0.0",
"p-cancelable": "^2.0.0",
"responselike": "^2.0.0"
},
"engines": {
"node": ">=10.19.0"
},
"funding": {
"url": "https://github.com/sindresorhus/got?sponsor=1"
}
},
"node_modules/graceful-fs": {
"version": "4.2.11",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
@@ -4083,6 +4324,32 @@
"integrity": "sha512-PDEfEF102G23vHmPhLyPboFCD+BkMGu+GuJe2d9/eH4FsCwvgBpnc9n0pGE+ffKdph38s6foEZiEjdgHdzp+IA==",
"license": "CC0-1.0"
},
"node_modules/hpagent": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/hpagent/-/hpagent-0.1.2.tgz",
"integrity": "sha512-ePqFXHtSQWAFXYmj+JtOTHr84iNrII4/QRlAAPPE+zqnKy4xJo7Ie1Y4kC7AdB+LxLxSTTzBMASsEcy0q8YyvQ==",
"license": "MIT",
"optional": true
},
"node_modules/http-cache-semantics": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz",
"integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==",
"license": "BSD-2-Clause"
},
"node_modules/http2-wrapper": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz",
"integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==",
"license": "MIT",
"dependencies": {
"quick-lru": "^5.1.1",
"resolve-alpn": "^1.0.0"
},
"engines": {
"node": ">=10.19.0"
}
},
"node_modules/ignore": {
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
@@ -4673,7 +4940,6 @@
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
"integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
"dev": true,
"license": "MIT"
},
"node_modules/json-schema-traverse": {
@@ -4723,7 +4989,6 @@
"version": "4.5.4",
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
"integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
"dev": true,
"license": "MIT",
"dependencies": {
"json-buffer": "3.0.1"
@@ -5040,6 +5305,12 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/lodash.clonedeep": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
"integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==",
"license": "MIT"
},
"node_modules/lodash.merge": {
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
@@ -5079,6 +5350,15 @@
"integrity": "sha512-+gfBXl6sxXMPe8tKQm7qzLnUy5DUPJPKIyRHwtpCpyUEYjHYRJC/5gjUvdkuO2c3JllrPtHXH5UJJK8LRYl5yQ==",
"license": "MIT"
},
"node_modules/lowercase-keys": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz",
"integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==",
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/lowlight": {
"version": "1.20.0",
"resolved": "https://registry.npmjs.org/lowlight/-/lowlight-1.20.0.tgz",
@@ -5153,6 +5433,15 @@
"node": ">=8.6"
}
},
"node_modules/mimic-response": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz",
"integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==",
"license": "MIT",
"engines": {
"node": ">=4"
}
},
"node_modules/minimatch": {
"version": "3.1.5",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
@@ -5221,7 +5510,6 @@
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"dev": true,
"license": "MIT"
},
"node_modules/nanoid": {
@@ -5346,6 +5634,29 @@
"node": "^10 || ^12 || >=14"
}
},
"node_modules/ngrok": {
"version": "5.0.0-beta.2",
"resolved": "https://registry.npmjs.org/ngrok/-/ngrok-5.0.0-beta.2.tgz",
"integrity": "sha512-UzsyGiJ4yTTQLCQD11k1DQaMwq2/SsztBg2b34zAqcyjS25qjDpogMKPaCKHwe/APRTHeel3iDXcVctk5CNaCQ==",
"hasInstallScript": true,
"license": "BSD-2-Clause",
"dependencies": {
"extract-zip": "^2.0.1",
"got": "^11.8.5",
"lodash.clonedeep": "^4.5.0",
"uuid": "^7.0.0 || ^8.0.0",
"yaml": "^2.2.2"
},
"bin": {
"ngrok": "bin/ngrok"
},
"engines": {
"node": ">=14.2"
},
"optionalDependencies": {
"hpagent": "^0.1.2"
}
},
"node_modules/node-exports-info": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/node-exports-info/-/node-exports-info-1.6.0.tgz",
@@ -5372,6 +5683,18 @@
"dev": true,
"license": "MIT"
},
"node_modules/normalize-url": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz",
"integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==",
"license": "MIT",
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
@@ -5495,6 +5818,15 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
"license": "ISC",
"dependencies": {
"wrappy": "1"
}
},
"node_modules/optionator": {
"version": "0.9.4",
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
@@ -5531,6 +5863,15 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/p-cancelable": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz",
"integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==",
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/p-limit": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
@@ -5628,6 +5969,12 @@
"dev": true,
"license": "MIT"
},
"node_modules/pend": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
"integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==",
"license": "MIT"
},
"node_modules/picocolors": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
@@ -5727,6 +6074,16 @@
"url": "https://github.com/sponsors/wooorm"
}
},
"node_modules/pump": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.4.tgz",
"integrity": "sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==",
"license": "MIT",
"dependencies": {
"end-of-stream": "^1.1.0",
"once": "^1.3.1"
}
},
"node_modules/punycode": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
@@ -5758,6 +6115,18 @@
],
"license": "MIT"
},
"node_modules/quick-lru": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz",
"integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==",
"license": "MIT",
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/react": {
"version": "19.2.4",
"resolved": "https://registry.npmjs.org/react/-/react-19.2.4.tgz",
@@ -5887,6 +6256,12 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/resolve-alpn": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz",
"integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==",
"license": "MIT"
},
"node_modules/resolve-from": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
@@ -5907,6 +6282,18 @@
"url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1"
}
},
"node_modules/responselike": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz",
"integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==",
"license": "MIT",
"dependencies": {
"lowercase-keys": "^2.0.0"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/reusify": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz",
@@ -6720,6 +7107,12 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/undici-types": {
"version": "7.19.2",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.19.2.tgz",
"integrity": "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg==",
"license": "MIT"
},
"node_modules/unrs-resolver": {
"version": "1.11.1",
"resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.11.1.tgz",
@@ -6796,6 +7189,15 @@
"punycode": "^2.1.0"
}
},
"node_modules/uuid": {
"version": "8.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
"license": "MIT",
"bin": {
"uuid": "dist/bin/uuid"
}
},
"node_modules/which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
@@ -6911,6 +7313,12 @@
"node": ">=0.10.0"
}
},
"node_modules/wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
"license": "ISC"
},
"node_modules/yallist": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
@@ -6918,6 +7326,31 @@
"dev": true,
"license": "ISC"
},
"node_modules/yaml": {
"version": "2.8.3",
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.3.tgz",
"integrity": "sha512-AvbaCLOO2Otw/lW5bmh9d/WEdcDFdQp2Z2ZUH3pX9U2ihyUY0nvLv7J6TrWowklRGPYbB/IuIMfYgxaCPg5Bpg==",
"license": "ISC",
"bin": {
"yaml": "bin.mjs"
},
"engines": {
"node": ">= 14.6"
},
"funding": {
"url": "https://github.com/sponsors/eemeli"
}
},
"node_modules/yauzl": {
"version": "2.10.0",
"resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
"integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==",
"license": "MIT",
"dependencies": {
"buffer-crc32": "~0.2.3",
"fd-slicer": "~1.1.0"
}
},
"node_modules/yocto-queue": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",

View File

@@ -1,9 +1,9 @@
{
"name": "pixelup-dev",
"name": "autumndev",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "npx next dev -p 3005",
"dev": "next dev -p 3004",
"build": "next build",
"start": "next start",
"lint": "eslint"
@@ -15,6 +15,7 @@
"matter-js": "^0.20.0",
"motion": "^12.38.0",
"next": "16.2.1",
"ngrok": "^5.0.0-beta.2",
"react": "19.2.4",
"react-dom": "19.2.4",
"react-syntax-highlighter": "^16.1.1"

Binary file not shown.

After

Width:  |  Height:  |  Size: 594 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 698 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 346 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 641 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 791 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 540 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 292 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 542 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 842 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 530 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 18 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 632 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 598 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 540 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 416 KiB

After

Width:  |  Height:  |  Size: 996 KiB