From 4f9e6aa121ee8df5de9ee1854ad7d5d717d1850a Mon Sep 17 00:00:00 2001 From: Charlie Lamb Date: Thu, 16 Apr 2026 15:55:39 +0100 Subject: [PATCH] Revert "chore(site): basic best practises" This reverts commit 1080e459f951c51057be1cf4c23a4e9264ef2d08. --- apps/website/app/constant.js | 1317 ++++ apps/website/app/constant.tsx | 1417 ---- apps/website/app/layout.js | 81 + apps/website/app/layout.tsx | 84 - apps/website/app/not-found.js | 111 + apps/website/app/not-found.tsx | 119 - apps/website/app/page.js | 42 + apps/website/app/page.tsx | 43 - apps/website/app/privacy/page.js | 191 + apps/website/app/privacy/page.tsx | 198 - apps/website/biome.jsonc | 17 - apps/website/bun.lock | 387 - .../components/animated-footer-image.jsx | 31 + .../components/animated-footer-image.tsx | 31 - apps/website/components/autumn-config.jsx | 247 + apps/website/components/autumn-config.tsx | 252 - .../components/dashboard-icon-pixel.jsx | 71 + .../components/dashboard-icon-pixel.tsx | 76 - apps/website/components/elastic-footer.jsx | 107 + apps/website/components/elastic-footer.tsx | 108 - apps/website/components/faq.jsx | 147 + apps/website/components/faq.tsx | 165 - .../components/feature-icon-animation.jsx | 106 + .../components/feature-icon-animation.tsx | 135 - apps/website/components/features.jsx | 70 + apps/website/components/features.tsx | 68 - apps/website/components/footer.jsx | 181 + apps/website/components/footer.tsx | 181 - apps/website/components/hero.jsx | 282 + apps/website/components/hero.tsx | 283 - .../{home-sections.tsx => home-sections.jsx} | 92 +- apps/website/components/navbar.jsx | 442 ++ apps/website/components/navbar.tsx | 474 -- apps/website/components/preloader.jsx | 238 + apps/website/components/preloader.tsx | 241 - apps/website/components/pricing-models.jsx | 258 + apps/website/components/pricing-models.tsx | 263 - apps/website/components/pricing.jsx | 183 + apps/website/components/pricing.tsx | 185 - apps/website/components/problem-animation.jsx | 211 + apps/website/components/problem-animation.tsx | 253 - apps/website/components/problem.jsx | 98 + apps/website/components/problem.tsx | 101 - apps/website/components/production-scale.jsx | 227 + apps/website/components/production-scale.tsx | 237 - apps/website/components/section-divider.jsx | 19 + apps/website/components/section-divider.tsx | 19 - .../website/components/solution-animation.jsx | 54 + .../website/components/solution-animation.tsx | 54 - apps/website/components/solution.jsx | 68 + apps/website/components/solution.tsx | 68 - apps/website/components/testimonials.jsx | 206 + apps/website/components/testimonials.tsx | 210 - apps/website/components/website-types.ts | 28 - apps/website/eslint.config.mjs | 16 + apps/website/jsconfig.json | 7 + apps/website/lib/utils.ts | 4 - apps/website/package-lock.json | 6958 +++++++++++++++++ apps/website/package.json | 22 +- apps/website/tsconfig.json | 23 - 60 files changed, 12021 insertions(+), 5786 deletions(-) create mode 100755 apps/website/app/constant.js delete mode 100755 apps/website/app/constant.tsx create mode 100755 apps/website/app/layout.js delete mode 100755 apps/website/app/layout.tsx create mode 100755 apps/website/app/not-found.js delete mode 100755 apps/website/app/not-found.tsx create mode 100755 apps/website/app/page.js delete mode 100755 apps/website/app/page.tsx create mode 100755 apps/website/app/privacy/page.js delete mode 100755 apps/website/app/privacy/page.tsx delete mode 100644 apps/website/biome.jsonc delete mode 100644 apps/website/bun.lock create mode 100755 apps/website/components/animated-footer-image.jsx delete mode 100755 apps/website/components/animated-footer-image.tsx create mode 100755 apps/website/components/autumn-config.jsx delete mode 100755 apps/website/components/autumn-config.tsx create mode 100755 apps/website/components/dashboard-icon-pixel.jsx delete mode 100755 apps/website/components/dashboard-icon-pixel.tsx create mode 100755 apps/website/components/elastic-footer.jsx delete mode 100755 apps/website/components/elastic-footer.tsx create mode 100755 apps/website/components/faq.jsx delete mode 100755 apps/website/components/faq.tsx create mode 100755 apps/website/components/feature-icon-animation.jsx delete mode 100755 apps/website/components/feature-icon-animation.tsx create mode 100755 apps/website/components/features.jsx delete mode 100755 apps/website/components/features.tsx create mode 100755 apps/website/components/footer.jsx delete mode 100755 apps/website/components/footer.tsx create mode 100755 apps/website/components/hero.jsx delete mode 100755 apps/website/components/hero.tsx rename apps/website/components/{home-sections.tsx => home-sections.jsx} (56%) create mode 100755 apps/website/components/navbar.jsx delete mode 100755 apps/website/components/navbar.tsx create mode 100755 apps/website/components/preloader.jsx delete mode 100755 apps/website/components/preloader.tsx create mode 100755 apps/website/components/pricing-models.jsx delete mode 100755 apps/website/components/pricing-models.tsx create mode 100755 apps/website/components/pricing.jsx delete mode 100755 apps/website/components/pricing.tsx create mode 100755 apps/website/components/problem-animation.jsx delete mode 100755 apps/website/components/problem-animation.tsx create mode 100755 apps/website/components/problem.jsx delete mode 100755 apps/website/components/problem.tsx create mode 100755 apps/website/components/production-scale.jsx delete mode 100755 apps/website/components/production-scale.tsx create mode 100755 apps/website/components/section-divider.jsx delete mode 100755 apps/website/components/section-divider.tsx create mode 100755 apps/website/components/solution-animation.jsx delete mode 100755 apps/website/components/solution-animation.tsx create mode 100755 apps/website/components/solution.jsx delete mode 100755 apps/website/components/solution.tsx create mode 100755 apps/website/components/testimonials.jsx delete mode 100755 apps/website/components/testimonials.tsx delete mode 100644 apps/website/components/website-types.ts create mode 100755 apps/website/eslint.config.mjs create mode 100755 apps/website/jsconfig.json delete mode 100644 apps/website/lib/utils.ts create mode 100755 apps/website/package-lock.json delete mode 100755 apps/website/tsconfig.json diff --git a/apps/website/app/constant.js b/apps/website/app/constant.js new file mode 100755 index 000000000..88d8cef9a --- /dev/null +++ b/apps/website/app/constant.js @@ -0,0 +1,1317 @@ +import { motion } from "motion/react"; +import { forwardRef } from "react"; + +export const CyberGlitchIcon = forwardRef(({ paths, className }, ref) => ( + + {paths.map((d, i) => ( + + ))} + +)); +CyberGlitchIcon.displayName = "CyberGlitchIcon"; + +export const MenuGridIcon = ({ isOpen }) => { + const gridSquares = [ + { is: "M0 0H3V3H0V0Z", ts: "M0 0H3V3H0V0Z" }, + { is: "M6 0H9V3H6V0Z", ts: "M3 3H6V6H3V3Z" }, + { is: "M12 0H15V3H12V0Z", ts: "M12 0H15V3H12V0Z" }, + { is: "M0 6H3V9H0V6Z", ts: "M3 9H6V12H3V9Z" }, + { is: "M6 6H9V9H6V6Z", ts: "M6 6H9V9H6V6Z" }, + { is: "M12 6H15V9H12V6Z", ts: "M9 3H12V6H9V3Z" }, + { is: "M0 12H3V15H0V12Z", ts: "M0 12H3V15H0V12Z" }, + { is: "M6 12H9V15H6V12Z", ts: "M9 9H12V12H9V9Z" }, + { is: "M12 12H15V15H12V12Z", ts: "M12 12H15V15H12V12Z" }, + ]; + + return ( + + {gridSquares.map((sq, i) => ( + + ))} + + ); +}; + +export const CTALines = () => { + const lines = [ + { bottom: "0%", opacity: 0.25 }, + { bottom: "15%", opacity: 0.18 }, + { bottom: "30%", opacity: 0.12 }, + { bottom: "45%", opacity: 0.08 }, + { bottom: "60%", opacity: 0.05 }, + { bottom: "75%", opacity: 0.02 }, + ]; + + return ( + + {lines.map((line, i) => ( +
+ ))} + + ); +}; + +export const IconCTAStart = () => ( + + + + + + + + + + + + + + + + + + +); + +export const IconCTADocs = () => ( + + + + + + + + + + + + + + + + + + + + + + + + + + +); + +export const IconDiscord = forwardRef((props, ref) => ( + +)); +IconDiscord.displayName = "IconDiscord"; + +// 2. Blog +export const IconBlog = forwardRef((props, ref) => ( + +)); +IconBlog.displayName = "IconBlog"; + +// 3. Docs +export const IconDocs = forwardRef((props, ref) => ( + +)); +IconDocs.displayName = "IconDocs"; + +// 4. Pricing +export const IconPricing = forwardRef((props, ref) => ( + +)); +IconPricing.displayName = "IconPricing"; + +export const IconDashboard = forwardRef(({ className }, ref) => ( + + + + + + + + + + + +)); +IconDashboard.displayName = "IconDashboard"; + +export const IconWebhooks = (props) => ( + + + + + + + + + + + + + +); + +// Usage Analytics: analytics.svg +export const IconAnalytics = (props) => ( + + + + + + + + + + + +); + +export const IconTeam = forwardRef((props, ref) => ( + + {/* Top Pixel */} + + {/* Right Pixel */} + + {/* Bottom Pixel */} + + {/* Left Pixel */} + + + {/* Center Block with REAL HOLES (The Magic Fix) */} + + +)); + +IconTeam.displayName = "IconTeam"; + +// Auto Top-ups: top-ups.svg +export const IconTopUp = (props) => ( + + + + + + + + + + + + + + + +); + +// Custom Plans: custom-plans.svg +export const IconPlans = (props) => ( + + + + + + + + + + + +); + +// Pricing Versioning: pricing.svg +export const IconVersioning = (props) => ( + + + + + + + + + + + + + + +); + +// React Components: react-components.svg +export const IconReact = (props) => ( + + + + + + + + + + +); + +// Referral Programs: referral.svg +export const IconReferral = (props) => ( + + + + + + + + + + + + + + + + + +); + +export const IconArrowLeft = ({ className, disabled, ...props }) => ( + + + + + + + + + + + + + + + + + + + +); + +export const IconArrowRight = ({ className, disabled, ...props }) => ( + + + + + + + + + + + + + + + + + +); + +export const IconQuotes = ({ className, ...props }) => ( + + + + + + + + + + +); + +export const IconTick = ({ className, ...props }) => ( + + + + +); + +export const IconArrowRightSmall = ({ className, ...props }) => ( + + + + + + + + + + + + + + + + + +); + +export const AnimatedPlusMinus = ({ isOpen, className, ...props }) => { + // Fragments that form the vertical line of the "Plus" + const vPixels = [ + { y: 3, originY: "center", xBurst: -8, delay: 0 }, + { y: 5, originY: "center", xBurst: -4, delay: 0.05 }, + { y: 9, originY: "center", xBurst: 4, delay: 0.05 }, + { y: 11, originY: "center", xBurst: 8, delay: 0 }, + ]; + + return ( + + {/* Corner decorative pixels - stay static but fade slightly */} + {[ + [0, 0], + [14, 0], + [0, 14], + [14, 14], + ].map(([x, y], i) => ( + + ))} + + {/* Horizontal Bar - The "Minus" part (Static) */} + + + + + + + {/* Vertical Bursting Pixels */} + {vPixels.map((pixel, i) => ( + + ))} + + ); +}; + +export const IconPlus = ({ className, ...props }) => ( + + + + + + + + + + + + + + + + +); + +export const IconMinus = ({ className, ...props }) => ( + + + + + + + + + + +); + +export const faqData = [ + { + id: 1, + question: "Do I still need Stripe?", + answer: + "Yes. Autumn works with Stripe—it handles the billing logic that Stripe doesn't. You keep your Stripe account, your customer relationships, and your payment data. Autumn sits between your app and Stripe, managing webhooks, usage limits, and state.\n\nYou're never locked in. Your subscriptions live in Stripe.", + }, + { + id: 2, + question: "What if Autumn goes down?", + answer: + "We run on redundant infrastructure with 99.99% uptime. If Autumn doesn't return a response, your app should default to allowing usage. This means Autumn will never take your app down—some users may temporarily get extra usage.\n\nWe'll work with you to reconcile usage tracking and balances afterward if needed.", + }, + { + id: 3, + question: "How is Autumn different from Orb or Metronome?", + answer: + "Orb and Metronome focus on usage metering—tracking how much customers consume. You still have to build entitlements, access control, and state management separately.\n\nAutumn is a complete system of record. We handle usage metering + entitlements + feature gating + billing state in one API. `check()` tells you if a user can access a feature in <50ms. You don't build that logic.", + }, + { + id: 4, + question: "What if I need to move off Autumn?", + answer: + "Autumn is open source. You can self-host anytime, or export all your data. Your Stripe subscriptions remain yours—we never lock you in. Most customers who self-host do so for compliance reasons, not because they're leaving.", + }, + { + id: 5, + question: "How long does integration take?", + answer: + "Most teams go live in under an hour. Migrating from an existing billing system typically takes 1–2 weeks, depending on complexity. We provide migration guides and work directly with your team.", + }, + { + id: 6, + question: "Can you handle our event volume?", + answer: + "Yes. Autumn supports 10,000+ events per second per customer. We've processed millions of billing events daily for AI companies at scale. If you have specific requirements, reach out—we'll walk through your architecture.", + }, +]; + +export const featuresData = [ + { + title: "Webhooks Handled", + description: + "Gate features with a single API call. check() resolves what each customer can access in under 50ms no database queries, no hardcoded logic.", + Icon: IconWebhooks, + }, + { + title: "Usage Analytics", + description: + "Timeseries charts and event logs out of the box. See usage trends, credit consumption, and feature adoption per customer.", + Icon: IconAnalytics, + }, + { + title: "Team Billing", + description: + "Bill organizations, track usage per seat. Add/remove team members. Prorate seat charges automatically.", + Icon: IconTeam, + }, + { + title: "Auto Top-ups", + description: + "Let users refill credits when balance runs low. Configure thresholds and amounts. Fully automated.", + Icon: IconTopUp, + }, + { + title: "Custom Plans", + description: + "Create one-off deals for enterprise customers. Unique pricing, credits, and limits without touching code.", + Icon: IconPlans, + }, + { + title: "Pricing Versioning", + description: + "Change your pricing model without breaking existing customers. Grandfather old plans or migrate users gradually. No database migrations.", + Icon: IconVersioning, + }, + { + title: "React Components", + description: + "Drop-in components for pricing tables, usage displays, and upgrade flows. Fully styled, production-ready.", + Icon: IconReact, + }, + { + title: "Referral Programs", + description: + "Built-in referral system with rewards, tracking, and attribution. Launch referral programs in minutes.", + Icon: IconReferral, + }, +]; + +export const PixelatedPattern = ({ className, ...props }) => ( + // eslint-disable-next-line @next/next/no-img-element + +); + +export const PRELOADER_LOGO_PATH = + "M0 138.789C12.1644 110.86 24.3298 82.9305 36.4942 55.001L159.78 0V149.976C112.437 178.653 65.0945 207.323 17.7521 236L113.418 65.9915L107.494 73.674C81.1937 107.783 54.8935 141.893 28.601 176.002C19.0674 163.601 9.53363 151.191 0 138.789Z"; + +export const PRELOADER_LOGO_VIEWBOX = { width: 160, height: 236 }; + +export const PreloaderLogo = ({ className, ...props }) => ( + +); + +export const ProblemBgSvg = (props) => ( +
+ {/* eslint-disable-next-line @next/next/no-img-element */} + Problem Background +
+); diff --git a/apps/website/app/constant.tsx b/apps/website/app/constant.tsx deleted file mode 100755 index aa0e1c2b7..000000000 --- a/apps/website/app/constant.tsx +++ /dev/null @@ -1,1417 +0,0 @@ -import { motion } from "motion/react"; -import type { - ComponentPropsWithoutRef, - CSSProperties, - ForwardedRef, -} from "react"; -import { forwardRef } from "react"; -import type { - FaqItem, - FeatureItem, - IconProps, - ImageProps, -} from "@/components/website-types"; -import { cn } from "@/lib/utils"; - -type ButtonIconProps = IconProps & { disabled?: boolean }; -type MotionIconProps = { isOpen: boolean; className?: string }; -type ProblemBgProps = ComponentPropsWithoutRef<"div">; -type GlitchIconProps = IconProps & { paths: string[] }; - -export const CyberGlitchIcon = forwardRef(function CyberGlitchIcon( - { paths, className }: GlitchIconProps, - ref: ForwardedRef, -) { - return ( - - ); -}); - -export const MenuGridIcon = ({ isOpen }: { isOpen: boolean }) => { - const gridSquares = [ - { is: "M0 0H3V3H0V0Z", ts: "M0 0H3V3H0V0Z" }, - { is: "M6 0H9V3H6V0Z", ts: "M3 3H6V6H3V3Z" }, - { is: "M12 0H15V3H12V0Z", ts: "M12 0H15V3H12V0Z" }, - { is: "M0 6H3V9H0V6Z", ts: "M3 9H6V12H3V9Z" }, - { is: "M6 6H9V9H6V6Z", ts: "M6 6H9V9H6V6Z" }, - { is: "M12 6H15V9H12V6Z", ts: "M9 3H12V6H9V3Z" }, - { is: "M0 12H3V15H0V12Z", ts: "M0 12H3V15H0V12Z" }, - { is: "M6 12H9V15H6V12Z", ts: "M9 9H12V12H9V9Z" }, - { is: "M12 12H15V15H12V12Z", ts: "M12 12H15V15H12V12Z" }, - ]; - - return ( - - ); -}; - -export const CTALines = () => { - const lines = [ - { bottom: "0%", opacity: 0.25 }, - { bottom: "15%", opacity: 0.18 }, - { bottom: "30%", opacity: 0.12 }, - { bottom: "45%", opacity: 0.08 }, - { bottom: "60%", opacity: 0.05 }, - { bottom: "75%", opacity: 0.02 }, - ]; - - return ( - - {lines.map((line) => ( -
- ))} - - ); -}; - -export const IconCTAStart = ({ className }: IconProps) => ( - -); - -export const IconCTADocs = ({ className }: IconProps) => ( - -); - -export const IconDiscord = forwardRef(function IconDiscord( - props: IconProps, - ref: ForwardedRef, -) { - return ( - - ); -}); - -// 2. Blog -export const IconBlog = forwardRef(function IconBlog( - props: IconProps, - ref: ForwardedRef, -) { - return ( - - ); -}); - -// 3. Docs -export const IconDocs = forwardRef(function IconDocs( - props: IconProps, - ref: ForwardedRef, -) { - return ( - - ); -}); - -// 4. Pricing -export const IconPricing = forwardRef(function IconPricing( - props: IconProps, - ref: ForwardedRef, -) { - return ( - - ); -}); - -export const IconDashboard = forwardRef(function IconDashboard( - { className }: IconProps, - ref: ForwardedRef, -) { - return ( - - ); -}); - -export const IconWebhooks = (props: IconProps) => ( - -); - -// Usage Analytics: analytics.svg -export const IconAnalytics = (props: IconProps) => ( - -); - -export const IconTeam = forwardRef(function IconTeam( - props: IconProps, - ref: ForwardedRef, -) { - return ( - - ); -}); - -// Auto Top-ups: top-ups.svg -export const IconTopUp = (props: IconProps) => ( - -); - -// Custom Plans: custom-plans.svg -export const IconPlans = (props: IconProps) => ( - -); - -// Pricing Versioning: pricing.svg -export const IconVersioning = (props: IconProps) => ( - -); - -// React Components: react-components.svg -export const IconReact = (props: IconProps) => ( - -); - -// Referral Programs: referral.svg -export const IconReferral = (props: IconProps) => ( - -); - -export const IconArrowLeft = ({ - className, - disabled, - ...props -}: ButtonIconProps) => ( - -); - -export const IconArrowRight = ({ - className, - disabled, - ...props -}: ButtonIconProps) => ( - -); - -export const IconQuotes = ({ className, ...props }: IconProps) => ( - -); - -export const IconTick = ({ className, ...props }: IconProps) => ( - -); - -export const IconArrowRightSmall = ({ className }: { className?: string }) => ( - -); - -export const AnimatedPlusMinus = ({ isOpen, className }: MotionIconProps) => { - // Fragments that form the vertical line of the "Plus" - const vPixels = [ - { y: 3, originY: "center", xBurst: -8, delay: 0 }, - { y: 5, originY: "center", xBurst: -4, delay: 0.05 }, - { y: 9, originY: "center", xBurst: 4, delay: 0.05 }, - { y: 11, originY: "center", xBurst: 8, delay: 0 }, - ]; - - return ( - - ); -}; - -export const IconPlus = ({ className, ...props }: IconProps) => ( - -); - -export const IconMinus = ({ className, ...props }: IconProps) => ( - -); - -export const faqData: FaqItem[] = [ - { - id: 1, - question: "Do I still need Stripe?", - answer: - "Yes. Autumn works with Stripe—it handles the billing logic that Stripe doesn't. You keep your Stripe account, your customer relationships, and your payment data. Autumn sits between your app and Stripe, managing webhooks, usage limits, and state.\n\nYou're never locked in. Your subscriptions live in Stripe.", - }, - { - id: 2, - question: "What if Autumn goes down?", - answer: - "We run on redundant infrastructure with 99.99% uptime. If Autumn doesn't return a response, your app should default to allowing usage. This means Autumn will never take your app down—some users may temporarily get extra usage.\n\nWe'll work with you to reconcile usage tracking and balances afterward if needed.", - }, - { - id: 3, - question: "How is Autumn different from Orb or Metronome?", - answer: - "Orb and Metronome focus on usage metering—tracking how much customers consume. You still have to build entitlements, access control, and state management separately.\n\nAutumn is a complete system of record. We handle usage metering + entitlements + feature gating + billing state in one API. `check()` tells you if a user can access a feature in <50ms. You don't build that logic.", - }, - { - id: 4, - question: "What if I need to move off Autumn?", - answer: - "Autumn is open source. You can self-host anytime, or export all your data. Your Stripe subscriptions remain yours—we never lock you in. Most customers who self-host do so for compliance reasons, not because they're leaving.", - }, - { - id: 5, - question: "How long does integration take?", - answer: - "Most teams go live in under an hour. Migrating from an existing billing system typically takes 1–2 weeks, depending on complexity. We provide migration guides and work directly with your team.", - }, - { - id: 6, - question: "Can you handle our event volume?", - answer: - "Yes. Autumn supports 10,000+ events per second per customer. We've processed millions of billing events daily for AI companies at scale. If you have specific requirements, reach out—we'll walk through your architecture.", - }, -]; - -export const featuresData: FeatureItem[] = [ - { - title: "Webhooks Handled", - description: - "Gate features with a single API call. check() resolves what each customer can access in under 50ms no database queries, no hardcoded logic.", - Icon: IconWebhooks, - }, - { - title: "Usage Analytics", - description: - "Timeseries charts and event logs out of the box. See usage trends, credit consumption, and feature adoption per customer.", - Icon: IconAnalytics, - }, - { - title: "Team Billing", - description: - "Bill organizations, track usage per seat. Add/remove team members. Prorate seat charges automatically.", - Icon: IconTeam, - }, - { - title: "Auto Top-ups", - description: - "Let users refill credits when balance runs low. Configure thresholds and amounts. Fully automated.", - Icon: IconTopUp, - }, - { - title: "Custom Plans", - description: - "Create one-off deals for enterprise customers. Unique pricing, credits, and limits without touching code.", - Icon: IconPlans, - }, - { - title: "Pricing Versioning", - description: - "Change your pricing model without breaking existing customers. Grandfather old plans or migrate users gradually. No database migrations.", - Icon: IconVersioning, - }, - { - title: "React Components", - description: - "Drop-in components for pricing tables, usage displays, and upgrade flows. Fully styled, production-ready.", - Icon: IconReact, - }, - { - title: "Referral Programs", - description: - "Built-in referral system with rewards, tracking, and attribution. Launch referral programs in minutes.", - Icon: IconReferral, - }, -]; - -export const PixelatedPattern = ({ className, ...props }: ImageProps) => ( - -); - -export const PRELOADER_LOGO_PATH = - "M0 138.789C12.1644 110.86 24.3298 82.9305 36.4942 55.001L159.78 0V149.976C112.437 178.653 65.0945 207.323 17.7521 236L113.418 65.9915L107.494 73.674C81.1937 107.783 54.8935 141.893 28.601 176.002C19.0674 163.601 9.53363 151.191 0 138.789Z"; - -export const PRELOADER_LOGO_VIEWBOX = { width: 160, height: 236 } as const; - -export const PreloaderLogo = ({ className, ...props }: IconProps) => ( - -); - -export const ProblemBgSvg = (props: ProblemBgProps) => ( -
- Problem Background -
-); diff --git a/apps/website/app/layout.js b/apps/website/app/layout.js new file mode 100755 index 000000000..130387808 --- /dev/null +++ b/apps/website/app/layout.js @@ -0,0 +1,81 @@ +import { Geist, Geist_Mono } from "next/font/google"; +import "./globals.css"; + +const geistSans = Geist({ + variable: "--font-geist-sans", + subsets: ["latin"], +}); + +const geistMono = Geist_Mono({ + variable: "--font-geist-mono", + subsets: ["latin"], +}); + +export const metadata = { + title: { + default: "Autumn — Billing Infrastructure for AI Startups", + template: "%s | Autumn", + }, + description: + "The drop-in billing layer for AI startups. Stop rebuilding usage limits, credit systems, and subscription logic. Autumn keeps webhooks, payments, and usage perfectly in-sync.", + keywords: [ + "AI billing", + "usage-based billing", + "subscription management", + "AI startups", + "billing infrastructure", + "payment integration", + "usage limits", + "credit system", + ], + authors: [{ name: "Autumn" }], + creator: "Autumn", + metadataBase: new URL("https://useautumn.com/"), + openGraph: { + type: "website", + locale: "en_US", + url: "https://useautumn.com/", + siteName: "Autumn", + title: "Autumn — Billing Infrastructure for AI Startups", + description: + "The drop-in billing layer for AI startups. Stop rebuilding usage limits, credit systems, and subscription logic.", + images: [ + { + url: "/images/og-image.png", + width: 1200, + height: 630, + alt: "Autumn — Billing Infrastructure for AI Startups", + }, + ], + }, + twitter: { + card: "summary_large_image", + title: "Autumn — Billing Infrastructure for AI Startups", + description: + "The drop-in billing layer for AI startups. Stop rebuilding usage limits, credit systems, and subscription logic.", + images: ["/images/og-image.png"], + }, + robots: { + index: true, + follow: true, + googleBot: { + index: true, + follow: true, + "max-video-preview": -1, + "max-image-preview": "large", + "max-snippet": -1, + }, + }, +}; + +export default function RootLayout({ children }) { + return ( + + {children} + + ); +} diff --git a/apps/website/app/layout.tsx b/apps/website/app/layout.tsx deleted file mode 100755 index 04285110d..000000000 --- a/apps/website/app/layout.tsx +++ /dev/null @@ -1,84 +0,0 @@ -import type { Metadata } from "next"; -import { Geist, Geist_Mono } from "next/font/google"; -import type { ReactNode } from "react"; -import { cn } from "@/lib/utils"; -import "./globals.css"; - -const geistSans = Geist({ - variable: "--font-geist-sans", - subsets: ["latin"], -}); - -const geistMono = Geist_Mono({ - variable: "--font-geist-mono", - subsets: ["latin"], -}); - -export const metadata: Metadata = { - title: { - default: "Autumn — Billing Infrastructure for AI Startups", - template: "%s | Autumn", - }, - description: - "The drop-in billing layer for AI startups. Stop rebuilding usage limits, credit systems, and subscription logic. Autumn keeps webhooks, payments, and usage perfectly in-sync.", - keywords: [ - "AI billing", - "usage-based billing", - "subscription management", - "AI startups", - "billing infrastructure", - "payment integration", - "usage limits", - "credit system", - ], - authors: [{ name: "Autumn" }], - creator: "Autumn", - metadataBase: new URL("https://useautumn.com/"), - openGraph: { - type: "website", - locale: "en_US", - url: "https://useautumn.com/", - siteName: "Autumn", - title: "Autumn — Billing Infrastructure for AI Startups", - description: - "The drop-in billing layer for AI startups. Stop rebuilding usage limits, credit systems, and subscription logic.", - images: [ - { - url: "/images/og-image.png", - width: 1200, - height: 630, - alt: "Autumn — Billing Infrastructure for AI Startups", - }, - ], - }, - twitter: { - card: "summary_large_image", - title: "Autumn — Billing Infrastructure for AI Startups", - description: - "The drop-in billing layer for AI startups. Stop rebuilding usage limits, credit systems, and subscription logic.", - images: ["/images/og-image.png"], - }, - robots: { - index: true, - follow: true, - googleBot: { - index: true, - follow: true, - "max-video-preview": -1, - "max-image-preview": "large", - "max-snippet": -1, - }, - }, -}; - -export default function RootLayout({ children }: { children: ReactNode }) { - return ( - - {children} - - ); -} diff --git a/apps/website/app/not-found.js b/apps/website/app/not-found.js new file mode 100755 index 000000000..db985d678 --- /dev/null +++ b/apps/website/app/not-found.js @@ -0,0 +1,111 @@ +"use client"; +import Navbar from "@/components/navbar"; +import Image from "next/image"; +import Link from "next/link"; +import { IconArrowRightSmall } from "@/app/constant"; +import { motion } from "motion/react"; + +export default function NotFound() { + return ( +
+
+
+
+ + + +
+
+ + 404 Background City Base + + + + 404 Background City Glitch + +
+ +
+ Autumn Logo + +

+ Page not found +

+ +

+ The page you are looking for doesn't exist or has been moved. +

+ + + + +
+
+
+
+ ); +} diff --git a/apps/website/app/not-found.tsx b/apps/website/app/not-found.tsx deleted file mode 100755 index 699de90c3..000000000 --- a/apps/website/app/not-found.tsx +++ /dev/null @@ -1,119 +0,0 @@ -"use client"; -import { motion } from "motion/react"; -import Image from "next/image"; -import Link from "next/link"; -import { IconArrowRightSmall } from "@/app/constant"; -import Navbar from "@/components/navbar"; -import type { PageStyle } from "@/components/website-types"; - -const pageStyle: PageStyle = { - "--page-pad": "max(2.5rem, calc((100vw - 1440px) / 2))", -}; - -export default function NotFound() { - return ( -
-
-
-
- - - -
-
- - 404 Background City Base - - - - 404 Background City Glitch - -
- -
- Autumn Logo - -

- Page not found -

- -

- The page you are looking for doesn't exist or has been moved. -

- - - - -
-
-
-
- ); -} diff --git a/apps/website/app/page.js b/apps/website/app/page.js new file mode 100755 index 000000000..3cdcfaf76 --- /dev/null +++ b/apps/website/app/page.js @@ -0,0 +1,42 @@ +import ElasticRecoil from "@/components/elastic-footer"; +import HomeSections from "@/components/home-sections"; +import Navbar from "@/components/navbar"; +import Preloader from "@/components/preloader"; + +export default function Home() { + return ( +
+ + +
+
+
+ +
+ +
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+ +
+ ); +} diff --git a/apps/website/app/page.tsx b/apps/website/app/page.tsx deleted file mode 100755 index 98fedb479..000000000 --- a/apps/website/app/page.tsx +++ /dev/null @@ -1,43 +0,0 @@ -import ElasticRecoil from "@/components/elastic-footer"; -import HomeSections from "@/components/home-sections"; -import Navbar from "@/components/navbar"; -import Preloader from "@/components/preloader"; -import type { PageStyle } from "@/components/website-types"; - -const pageStyle: PageStyle = { - "--page-pad": "max(2.5rem, calc((100vw - 1440px) / 2))", -}; - -export default function Home() { - return ( -
- - -
-
-
- -
- -
-
-
-
-
-
-
- - -
-
-
-
-
-
-
-
-
- -
- ); -} diff --git a/apps/website/app/privacy/page.js b/apps/website/app/privacy/page.js new file mode 100755 index 000000000..164ce0f21 --- /dev/null +++ b/apps/website/app/privacy/page.js @@ -0,0 +1,191 @@ +import AnimatedFooterImage from "@/components/animated-footer-image"; +import Footer from "@/components/footer"; +import Navbar from "@/components/navbar"; + +const privacyTerms = [ + { + title: "1. Acceptance of Terms", + content: + 'By accessing or using the Autumn platform, APIs, SDKs, or any related services (collectively, the "Services") provided by Rebase, Inc., a Delaware corporation ("Autumn," "we," "us," or "our"), you agree to be bound by these Terms of Service ("Terms"). If you do not agree to these Terms, do not use our Services.', + isUppercase: false, + }, + { + title: "2. Description of Services", + content: + "Autumn provides billing infrastructure, including usage-based billing, credits management, pricing configuration, and entitlements management for software applications. Our Services are designed for developers and businesses building products that require flexible billing and pricing capabilities.", + isUppercase: false, + }, + { + title: "3. Account Registration", + content: + "To use certain features of our Services, you must create an account. You agree to provide accurate, current, and complete information during registration and to update such information as necessary. You are responsible for maintaining the confidentiality of your account credentials and for all activities that occur under your account.", + isUppercase: false, + }, + { + title: "4. Acceptable Use", + content: + "You agree not to use the Services for any unlawful purpose or in violation of any applicable laws; (b) interfere with or disrupt the integrity or performance of the Services; (c) attempt to gain unauthorized access to the Services or related systems; (d) use the Services to transmit malicious code or harmful content; or (e) resell or redistribute the Services without our prior written consent.", + isUppercase: false, + }, + { + title: "5. Payment Terms", + content: + "Fees for the Services are set forth on our pricing page or in a separate agreement. You agree to pay all applicable fees in accordance with the payment terms. All fees are non-refundable except as expressly stated otherwise. We reserve the right to modify our pricing with 30 days' notice.", + isUppercase: false, + }, + { + title: "6. Data and Privacy", + content: + 'Your use of the Services is subject to our Privacy Policy. You retain ownership of any data you submit to the Services ("Customer Data"). You grant us a limited license to process Customer Data solely to provide the Services. We implement reasonable security measures to protect Customer Data, but you acknowledge that no system is completely secure.', + isUppercase: false, + }, + { + title: "7. Intellectual Property", + content: + "The Services, including all software, APIs, documentation, and related materials, are owned by Autumn and protected by intellectual property laws. We grant you a limited, non-exclusive, non-transferable license to use the Services in accordance with these Terms. You may not copy, modify, or create derivative works of the Services except as expressly permitted.", + isUppercase: false, + }, + { + title: "8. Confidentiality", + content: + "Each party agrees to maintain the confidentiality of any non-public information disclosed by the other party and to use such information only for the purposes of these Terms. This obligation does not apply to information that is publicly available, independently developed, or rightfully received from a third party.", + isUppercase: false, + }, + { + title: "9. Warranties and Disclaimers", + content: + 'THE SERVICES ARE PROVIDED "AS IS" AND "AS AVAILABLE" WITHOUT WARRANTIES OF ANY KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. WE DO NOT WARRANT THAT THE SERVICES WILL BE UNINTERRUPTED OR ERROR-FREE.', + isUppercase: true, + }, + { + title: "10. Limitation of Liability", + content: + "TO THE MAXIMUM EXTENT PERMITTED BY LAW, AUTUMN SHALL NOT BE LIABLE FOR ANY INDIRECT, INCIDENTAL, SPECIAL, CONSEQUENTIAL, OR PUNITIVE DAMAGES, OR ANY LOSS OF PROFITS OR REVENUES. OUR TOTAL LIABILITY FOR ANY CLAIMS ARISING FROM THESE TERMS SHALL NOT EXCEED THE AMOUNTS PAID BY YOU TO AUTUMN IN THE TWELVE MONTHS PRECEDING THE CLAIM.", + isUppercase: true, + }, + { + title: "11. Indemnification", + content: + "You agree to indemnify, defend, and hold harmless Autumn and its officers, directors, employees, and agents from any claims, liabilities, damages, losses, or expenses arising from your use of the Services, your violation of these Terms, or your infringement of any third-party rights.", + isUppercase: false, + }, + { + title: "12. Term and Termination", + content: + "These Terms remain in effect until terminated. Either party may terminate for convenience with 30 days' written notice. We may suspend or terminate your access immediately if you breach these Terms. Upon termination, your right to use the Services ceases, and you must pay any outstanding fees.", + isUppercase: false, + }, + { + title: "13. Modifications", + content: + "We may modify these Terms at any time by posting the revised Terms on our website. Material changes will be communicated with at least 30 days' notice. Your continued use of the Services after such changes constitutes acceptance of the modified Terms.", + isUppercase: false, + }, + { + title: "14. Governing Law and Disputes", + content: + "These Terms are governed by the laws of the State of Delaware, without regard to conflict of law principles. Any disputes arising from these Terms shall be resolved through binding arbitration in accordance with the rules of the American Arbitration Association, except that either party may seek injunctive relief in any court of competent jurisdiction.", + isUppercase: false, + }, + { + title: "15. General Provisions", + content: + "These Terms constitute the entire agreement between you and Autumn regarding the Services. If any provision is found unenforceable, the remaining provisions will continue in effect. Our failure to enforce any right or provision does not constitute a waiver. You may not assign these Terms without our prior written consent.", + isUppercase: false, + }, + { + title: "16. Contact Information", + content: ( + <> + For questions about these Terms, please contact us at + security@useautumn.com or at: +
+ Rebase, Inc. (d/b/a Autumn) +
+ Email: security@useautumn.com +
+ Website: https://useautumn.com + + ), + isUppercase: false, + }, +]; + +export default function PrivacyPolicy() { + return ( +
+
+
+
+
+ +
+
+ +
+
+
+
+
+
+
+ +
+
+
+
+

+ Terms of Service +

+
+
+
+ +
+
+
+

+ Autumn (Rebase, Inc.) +
+ Effective Date: February 1, 2025 +

+ + {privacyTerms.map((term, index) => ( +
+

+ {term.title} +

+

+ {term.content} +

+
+ ))} +
+
+
+
+ +
+
+ +
+
+
+
+
+
+
+
+ +
+ +
+ ); +} diff --git a/apps/website/app/privacy/page.tsx b/apps/website/app/privacy/page.tsx deleted file mode 100755 index 9a4b4e86e..000000000 --- a/apps/website/app/privacy/page.tsx +++ /dev/null @@ -1,198 +0,0 @@ -import AnimatedFooterImage from "@/components/animated-footer-image"; -import Footer from "@/components/footer"; -import Navbar from "@/components/navbar"; -import type { PageStyle } from "@/components/website-types"; -import { cn } from "@/lib/utils"; - -const pageStyle: PageStyle = { - "--page-pad": "max(2.5rem, calc((100vw - 1440px) / 2))", -}; - -const privacyTerms = [ - { - title: "1. Acceptance of Terms", - content: - 'By accessing or using the Autumn platform, APIs, SDKs, or any related services (collectively, the "Services") provided by Rebase, Inc., a Delaware corporation ("Autumn," "we," "us," or "our"), you agree to be bound by these Terms of Service ("Terms"). If you do not agree to these Terms, do not use our Services.', - isUppercase: false, - }, - { - title: "2. Description of Services", - content: - "Autumn provides billing infrastructure, including usage-based billing, credits management, pricing configuration, and entitlements management for software applications. Our Services are designed for developers and businesses building products that require flexible billing and pricing capabilities.", - isUppercase: false, - }, - { - title: "3. Account Registration", - content: - "To use certain features of our Services, you must create an account. You agree to provide accurate, current, and complete information during registration and to update such information as necessary. You are responsible for maintaining the confidentiality of your account credentials and for all activities that occur under your account.", - isUppercase: false, - }, - { - title: "4. Acceptable Use", - content: - "You agree not to use the Services for any unlawful purpose or in violation of any applicable laws; (b) interfere with or disrupt the integrity or performance of the Services; (c) attempt to gain unauthorized access to the Services or related systems; (d) use the Services to transmit malicious code or harmful content; or (e) resell or redistribute the Services without our prior written consent.", - isUppercase: false, - }, - { - title: "5. Payment Terms", - content: - "Fees for the Services are set forth on our pricing page or in a separate agreement. You agree to pay all applicable fees in accordance with the payment terms. All fees are non-refundable except as expressly stated otherwise. We reserve the right to modify our pricing with 30 days' notice.", - isUppercase: false, - }, - { - title: "6. Data and Privacy", - content: - 'Your use of the Services is subject to our Privacy Policy. You retain ownership of any data you submit to the Services ("Customer Data"). You grant us a limited license to process Customer Data solely to provide the Services. We implement reasonable security measures to protect Customer Data, but you acknowledge that no system is completely secure.', - isUppercase: false, - }, - { - title: "7. Intellectual Property", - content: - "The Services, including all software, APIs, documentation, and related materials, are owned by Autumn and protected by intellectual property laws. We grant you a limited, non-exclusive, non-transferable license to use the Services in accordance with these Terms. You may not copy, modify, or create derivative works of the Services except as expressly permitted.", - isUppercase: false, - }, - { - title: "8. Confidentiality", - content: - "Each party agrees to maintain the confidentiality of any non-public information disclosed by the other party and to use such information only for the purposes of these Terms. This obligation does not apply to information that is publicly available, independently developed, or rightfully received from a third party.", - isUppercase: false, - }, - { - title: "9. Warranties and Disclaimers", - content: - 'THE SERVICES ARE PROVIDED "AS IS" AND "AS AVAILABLE" WITHOUT WARRANTIES OF ANY KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. WE DO NOT WARRANT THAT THE SERVICES WILL BE UNINTERRUPTED OR ERROR-FREE.', - isUppercase: true, - }, - { - title: "10. Limitation of Liability", - content: - "TO THE MAXIMUM EXTENT PERMITTED BY LAW, AUTUMN SHALL NOT BE LIABLE FOR ANY INDIRECT, INCIDENTAL, SPECIAL, CONSEQUENTIAL, OR PUNITIVE DAMAGES, OR ANY LOSS OF PROFITS OR REVENUES. OUR TOTAL LIABILITY FOR ANY CLAIMS ARISING FROM THESE TERMS SHALL NOT EXCEED THE AMOUNTS PAID BY YOU TO AUTUMN IN THE TWELVE MONTHS PRECEDING THE CLAIM.", - isUppercase: true, - }, - { - title: "11. Indemnification", - content: - "You agree to indemnify, defend, and hold harmless Autumn and its officers, directors, employees, and agents from any claims, liabilities, damages, losses, or expenses arising from your use of the Services, your violation of these Terms, or your infringement of any third-party rights.", - isUppercase: false, - }, - { - title: "12. Term and Termination", - content: - "These Terms remain in effect until terminated. Either party may terminate for convenience with 30 days' written notice. We may suspend or terminate your access immediately if you breach these Terms. Upon termination, your right to use the Services ceases, and you must pay any outstanding fees.", - isUppercase: false, - }, - { - title: "13. Modifications", - content: - "We may modify these Terms at any time by posting the revised Terms on our website. Material changes will be communicated with at least 30 days' notice. Your continued use of the Services after such changes constitutes acceptance of the modified Terms.", - isUppercase: false, - }, - { - title: "14. Governing Law and Disputes", - content: - "These Terms are governed by the laws of the State of Delaware, without regard to conflict of law principles. Any disputes arising from these Terms shall be resolved through binding arbitration in accordance with the rules of the American Arbitration Association, except that either party may seek injunctive relief in any court of competent jurisdiction.", - isUppercase: false, - }, - { - title: "15. General Provisions", - content: - "These Terms constitute the entire agreement between you and Autumn regarding the Services. If any provision is found unenforceable, the remaining provisions will continue in effect. Our failure to enforce any right or provision does not constitute a waiver. You may not assign these Terms without our prior written consent.", - isUppercase: false, - }, - { - title: "16. Contact Information", - content: ( - <> - For questions about these Terms, please contact us at - security@useautumn.com or at: -
- Rebase, Inc. (d/b/a Autumn) -
- Email: security@useautumn.com -
- Website: https://useautumn.com - - ), - isUppercase: false, - }, -]; - -export default function PrivacyPolicy() { - return ( -
-
-
-
-
- -
-
- -
-
-
-
-
-
-
- -
-
-
-
-

- Terms of Service -

-
-
-
- -
-
-
-

- Autumn (Rebase, Inc.) -
- Effective Date: February 1, 2025 -

- - {privacyTerms.map((term) => ( -
-

- {term.title} -

-

- {term.content} -

-
- ))} -
-
-
-
- -
-
- -
-
-
-
-
-
-
-
- -
- -
- ); -} diff --git a/apps/website/biome.jsonc b/apps/website/biome.jsonc deleted file mode 100644 index e1896d306..000000000 --- a/apps/website/biome.jsonc +++ /dev/null @@ -1,17 +0,0 @@ -{ - "$schema": "./node_modules/@biomejs/biome/configuration_schema.json", - "root": true, - "extends": [ - "ultracite/biome/core", - "ultracite/biome/react", - "ultracite/biome/next" - ], - "files": { - "includes": ["**", "!node_modules", "!.next", "!dist", "!build"] - }, - "css": { - "parser": { - "tailwindDirectives": true - } - } -} diff --git a/apps/website/bun.lock b/apps/website/bun.lock deleted file mode 100644 index 691ecfc0a..000000000 --- a/apps/website/bun.lock +++ /dev/null @@ -1,387 +0,0 @@ -{ - "lockfileVersion": 1, - "configVersion": 0, - "workspaces": { - "": { - "name": "pixelup-dev", - "dependencies": { - "@gsap/react": "^2.1.2", - "clsx": "^2.1.1", - "gsap": "^3.14.2", - "lottie-react": "^2.4.1", - "matter-js": "^0.20.0", - "motion": "^12.38.0", - "next": "16.2.1", - "react": "19.2.4", - "react-dom": "19.2.4", - "react-syntax-highlighter": "^16.1.1", - "tailwind-merge": "^3.5.0", - }, - "devDependencies": { - "@biomejs/biome": "2.4.12", - "@tailwindcss/postcss": "^4.2.2", - "@types/matter-js": "^0.20.2", - "@types/node": "^25.6.0", - "@types/react": "^19.2.14", - "@types/react-dom": "^19.2.3", - "@types/react-syntax-highlighter": "^15.5.13", - "tailwindcss": "^4.2.2", - "typescript": "^6.0.2", - "ultracite": "7.5.9", - }, - }, - }, - "packages": { - "@alloc/quick-lru": ["@alloc/quick-lru@5.2.0", "", {}, "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw=="], - - "@babel/runtime": ["@babel/runtime@7.29.2", "", {}, "sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g=="], - - "@biomejs/biome": ["@biomejs/biome@2.4.12", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "2.4.12", "@biomejs/cli-darwin-x64": "2.4.12", "@biomejs/cli-linux-arm64": "2.4.12", "@biomejs/cli-linux-arm64-musl": "2.4.12", "@biomejs/cli-linux-x64": "2.4.12", "@biomejs/cli-linux-x64-musl": "2.4.12", "@biomejs/cli-win32-arm64": "2.4.12", "@biomejs/cli-win32-x64": "2.4.12" }, "bin": { "biome": "bin/biome" } }, "sha512-Rro7adQl3NLq/zJCIL98eElXKI8eEiBtoeu5TbXF/U3qbjuSc7Jb5rjUbeHHcquDWeSf3HnGP7XI5qGrlRk/pA=="], - - "@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@2.4.12", "", { "os": "darwin", "cpu": "arm64" }, "sha512-BnMU4Pc3ciEVteVpZ0BK33MLr7X57F5w1dwDLDn+/iy/yTrA4Q/N2yftidFtsA4vrDh0FMXDpacNV/Tl3fbmng=="], - - "@biomejs/cli-darwin-x64": ["@biomejs/cli-darwin-x64@2.4.12", "", { "os": "darwin", "cpu": "x64" }, "sha512-x9uJ0bI1rJsWICp3VH8w/5PnAVD3A7SqzDpbrfoUQX1QyWrK5jSU4fRLo/wSgGeplCivbxBRKmt5Xq4/nWvq8A=="], - - "@biomejs/cli-linux-arm64": ["@biomejs/cli-linux-arm64@2.4.12", "", { "os": "linux", "cpu": "arm64" }, "sha512-tOwuCuZZtKi1jVzbk/5nXmIsziOB6yqN8c9r9QM0EJYPU6DpQWf11uBOSCfFKKM4H3d9ZoarvlgMfbcuD051Pw=="], - - "@biomejs/cli-linux-arm64-musl": ["@biomejs/cli-linux-arm64-musl@2.4.12", "", { "os": "linux", "cpu": "arm64" }, "sha512-FhfpkAAlKL6kwvcVap0Hgp4AhZmtd3YImg0kK1jd7C/aSoh4SfsB2f++yG1rU0lr8Y5MCFJrcSkmssiL9Xnnig=="], - - "@biomejs/cli-linux-x64": ["@biomejs/cli-linux-x64@2.4.12", "", { "os": "linux", "cpu": "x64" }, "sha512-8pFeAnLU9QdW9jCIslB/v82bI0lhBmz2ZAKc8pVMFPO0t0wAHsoEkrUQUbMkIorTRIjbqyNZHA3lEXavsPWYSw=="], - - "@biomejs/cli-linux-x64-musl": ["@biomejs/cli-linux-x64-musl@2.4.12", "", { "os": "linux", "cpu": "x64" }, "sha512-dwTIgZrGutzhkQCuvHynCkyW6hJxUuyZqKKO0YNfaS2GUoRO+tOvxXZqZB6SkWAOdfZTzwaw8IEdUnIkHKHoew=="], - - "@biomejs/cli-win32-arm64": ["@biomejs/cli-win32-arm64@2.4.12", "", { "os": "win32", "cpu": "arm64" }, "sha512-B0DLnx0vA9ya/3v7XyCaP+/lCpnbWbMOfUFFve+xb5OxyYvdHaS55YsSddr228Y+JAFk58agCuZTsqNiw2a6ig=="], - - "@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@2.4.12", "", { "os": "win32", "cpu": "x64" }, "sha512-yMckRzTyZ83hkk8iDFWswqSdU8tvZxspJKnYNh7JZr/zhZNOlzH13k4ecboU6MurKExCe2HUkH75pGI/O2JwGA=="], - - "@clack/core": ["@clack/core@1.2.0", "", { "dependencies": { "fast-wrap-ansi": "^0.1.3", "sisteransi": "^1.0.5" } }, "sha512-qfxof/3T3t9DPU/Rj3OmcFyZInceqj/NVtO9rwIuJqCUgh32gwPjpFQQp/ben07qKlhpwq7GzfWpST4qdJ5Drg=="], - - "@clack/prompts": ["@clack/prompts@1.2.0", "", { "dependencies": { "@clack/core": "1.2.0", "fast-string-width": "^1.1.0", "fast-wrap-ansi": "^0.1.3", "sisteransi": "^1.0.5" } }, "sha512-4jmztR9fMqPMjz6H/UZXj0zEmE43ha1euENwkckKKel4XpSfokExPo5AiVStdHSAlHekz4d0CA/r45Ok1E4D3w=="], - - "@emnapi/runtime": ["@emnapi/runtime@1.9.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-VYi5+ZVLhpgK4hQ0TAjiQiZ6ol0oe4mBx7mVv7IflsiEp0OWoVsp/+f9Vc1hOhE0TtkORVrI1GvzyreqpgWtkA=="], - - "@gsap/react": ["@gsap/react@2.1.2", "", { "peerDependencies": { "gsap": "^3.12.5", "react": ">=17" } }, "sha512-JqliybO1837UcgH2hVOM4VO+38APk3ECNrsuSM4MuXp+rbf+/2IG2K1YJiqfTcXQHH7XlA0m3ykniFYstfq0Iw=="], - - "@img/colour": ["@img/colour@1.1.0", "", {}, "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ=="], - - "@img/sharp-darwin-arm64": ["@img/sharp-darwin-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-arm64": "1.2.4" }, "os": "darwin", "cpu": "arm64" }, "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w=="], - - "@img/sharp-darwin-x64": ["@img/sharp-darwin-x64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-x64": "1.2.4" }, "os": "darwin", "cpu": "x64" }, "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw=="], - - "@img/sharp-libvips-darwin-arm64": ["@img/sharp-libvips-darwin-arm64@1.2.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g=="], - - "@img/sharp-libvips-darwin-x64": ["@img/sharp-libvips-darwin-x64@1.2.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg=="], - - "@img/sharp-libvips-linux-arm": ["@img/sharp-libvips-linux-arm@1.2.4", "", { "os": "linux", "cpu": "arm" }, "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A=="], - - "@img/sharp-libvips-linux-arm64": ["@img/sharp-libvips-linux-arm64@1.2.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw=="], - - "@img/sharp-libvips-linux-ppc64": ["@img/sharp-libvips-linux-ppc64@1.2.4", "", { "os": "linux", "cpu": "ppc64" }, "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA=="], - - "@img/sharp-libvips-linux-riscv64": ["@img/sharp-libvips-linux-riscv64@1.2.4", "", { "os": "linux", "cpu": "none" }, "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA=="], - - "@img/sharp-libvips-linux-s390x": ["@img/sharp-libvips-linux-s390x@1.2.4", "", { "os": "linux", "cpu": "s390x" }, "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ=="], - - "@img/sharp-libvips-linux-x64": ["@img/sharp-libvips-linux-x64@1.2.4", "", { "os": "linux", "cpu": "x64" }, "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw=="], - - "@img/sharp-libvips-linuxmusl-arm64": ["@img/sharp-libvips-linuxmusl-arm64@1.2.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw=="], - - "@img/sharp-libvips-linuxmusl-x64": ["@img/sharp-libvips-linuxmusl-x64@1.2.4", "", { "os": "linux", "cpu": "x64" }, "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg=="], - - "@img/sharp-linux-arm": ["@img/sharp-linux-arm@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm": "1.2.4" }, "os": "linux", "cpu": "arm" }, "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw=="], - - "@img/sharp-linux-arm64": ["@img/sharp-linux-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm64": "1.2.4" }, "os": "linux", "cpu": "arm64" }, "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg=="], - - "@img/sharp-linux-ppc64": ["@img/sharp-linux-ppc64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-ppc64": "1.2.4" }, "os": "linux", "cpu": "ppc64" }, "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA=="], - - "@img/sharp-linux-riscv64": ["@img/sharp-linux-riscv64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-riscv64": "1.2.4" }, "os": "linux", "cpu": "none" }, "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw=="], - - "@img/sharp-linux-s390x": ["@img/sharp-linux-s390x@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-s390x": "1.2.4" }, "os": "linux", "cpu": "s390x" }, "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg=="], - - "@img/sharp-linux-x64": ["@img/sharp-linux-x64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-x64": "1.2.4" }, "os": "linux", "cpu": "x64" }, "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ=="], - - "@img/sharp-linuxmusl-arm64": ["@img/sharp-linuxmusl-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-arm64": "1.2.4" }, "os": "linux", "cpu": "arm64" }, "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg=="], - - "@img/sharp-linuxmusl-x64": ["@img/sharp-linuxmusl-x64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-x64": "1.2.4" }, "os": "linux", "cpu": "x64" }, "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q=="], - - "@img/sharp-wasm32": ["@img/sharp-wasm32@0.34.5", "", { "dependencies": { "@emnapi/runtime": "^1.7.0" }, "cpu": "none" }, "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw=="], - - "@img/sharp-win32-arm64": ["@img/sharp-win32-arm64@0.34.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g=="], - - "@img/sharp-win32-ia32": ["@img/sharp-win32-ia32@0.34.5", "", { "os": "win32", "cpu": "ia32" }, "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg=="], - - "@img/sharp-win32-x64": ["@img/sharp-win32-x64@0.34.5", "", { "os": "win32", "cpu": "x64" }, "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw=="], - - "@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.13", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA=="], - - "@jridgewell/remapping": ["@jridgewell/remapping@2.3.5", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ=="], - - "@jridgewell/resolve-uri": ["@jridgewell/resolve-uri@3.1.2", "", {}, "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="], - - "@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="], - - "@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="], - - "@next/env": ["@next/env@16.2.1", "", {}, "sha512-n8P/HCkIWW+gVal2Z8XqXJ6aB3J0tuM29OcHpCsobWlChH/SITBs1DFBk/HajgrwDkqqBXPbuUuzgDvUekREPg=="], - - "@next/swc-darwin-arm64": ["@next/swc-darwin-arm64@16.2.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-BwZ8w8YTaSEr2HIuXLMLxIdElNMPvY9fLqb20LX9A9OMGtJilhHLbCL3ggyd0TwjmMcTxi0XXt+ur1vWUoxj2Q=="], - - "@next/swc-darwin-x64": ["@next/swc-darwin-x64@16.2.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-/vrcE6iQSJq3uL3VGVHiXeaKbn8Es10DGTGRJnRZlkNQQk3kaNtAJg8Y6xuAlrx/6INKVjkfi5rY0iEXorZ6uA=="], - - "@next/swc-linux-arm64-gnu": ["@next/swc-linux-arm64-gnu@16.2.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-uLn+0BK+C31LTVbQ/QU+UaVrV0rRSJQ8RfniQAHPghDdgE+SlroYqcmFnO5iNjNfVWCyKZHYrs3Nl0mUzWxbBw=="], - - "@next/swc-linux-arm64-musl": ["@next/swc-linux-arm64-musl@16.2.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-ssKq6iMRnHdnycGp9hCuGnXJZ0YPr4/wNwrfE5DbmvEcgl9+yv97/Kq3TPVDfYome1SW5geciLB9aiEqKXQjlQ=="], - - "@next/swc-linux-x64-gnu": ["@next/swc-linux-x64-gnu@16.2.1", "", { "os": "linux", "cpu": "x64" }, "sha512-HQm7SrHRELJ30T1TSmT706IWovFFSRGxfgUkyWJZF/RKBMdbdRWJuFrcpDdE5vy9UXjFOx6L3mRdqH04Mmx0hg=="], - - "@next/swc-linux-x64-musl": ["@next/swc-linux-x64-musl@16.2.1", "", { "os": "linux", "cpu": "x64" }, "sha512-aV2iUaC/5HGEpbBkE+4B8aHIudoOy5DYekAKOMSHoIYQ66y/wIVeaRx8MS2ZMdxe/HIXlMho4ubdZs/J8441Tg=="], - - "@next/swc-win32-arm64-msvc": ["@next/swc-win32-arm64-msvc@16.2.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-IXdNgiDHaSk0ZUJ+xp0OQTdTgnpx1RCfRTalhn3cjOP+IddTMINwA7DXZrwTmGDO8SUr5q2hdP/du4DcrB1GxA=="], - - "@next/swc-win32-x64-msvc": ["@next/swc-win32-x64-msvc@16.2.1", "", { "os": "win32", "cpu": "x64" }, "sha512-qvU+3a39Hay+ieIztkGSbF7+mccbbg1Tk25hc4JDylf8IHjYmY/Zm64Qq1602yPyQqvie+vf5T/uPwNxDNIoeg=="], - - "@swc/helpers": ["@swc/helpers@0.5.15", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g=="], - - "@tailwindcss/node": ["@tailwindcss/node@4.2.2", "", { "dependencies": { "@jridgewell/remapping": "^2.3.5", "enhanced-resolve": "^5.19.0", "jiti": "^2.6.1", "lightningcss": "1.32.0", "magic-string": "^0.30.21", "source-map-js": "^1.2.1", "tailwindcss": "4.2.2" } }, "sha512-pXS+wJ2gZpVXqFaUEjojq7jzMpTGf8rU6ipJz5ovJV6PUGmlJ+jvIwGrzdHdQ80Sg+wmQxUFuoW1UAAwHNEdFA=="], - - "@tailwindcss/oxide": ["@tailwindcss/oxide@4.2.2", "", { "optionalDependencies": { "@tailwindcss/oxide-android-arm64": "4.2.2", "@tailwindcss/oxide-darwin-arm64": "4.2.2", "@tailwindcss/oxide-darwin-x64": "4.2.2", "@tailwindcss/oxide-freebsd-x64": "4.2.2", "@tailwindcss/oxide-linux-arm-gnueabihf": "4.2.2", "@tailwindcss/oxide-linux-arm64-gnu": "4.2.2", "@tailwindcss/oxide-linux-arm64-musl": "4.2.2", "@tailwindcss/oxide-linux-x64-gnu": "4.2.2", "@tailwindcss/oxide-linux-x64-musl": "4.2.2", "@tailwindcss/oxide-wasm32-wasi": "4.2.2", "@tailwindcss/oxide-win32-arm64-msvc": "4.2.2", "@tailwindcss/oxide-win32-x64-msvc": "4.2.2" } }, "sha512-qEUA07+E5kehxYp9BVMpq9E8vnJuBHfJEC0vPC5e7iL/hw7HR61aDKoVoKzrG+QKp56vhNZe4qwkRmMC0zDLvg=="], - - "@tailwindcss/oxide-android-arm64": ["@tailwindcss/oxide-android-arm64@4.2.2", "", { "os": "android", "cpu": "arm64" }, "sha512-dXGR1n+P3B6748jZO/SvHZq7qBOqqzQ+yFrXpoOWWALWndF9MoSKAT3Q0fYgAzYzGhxNYOoysRvYlpixRBBoDg=="], - - "@tailwindcss/oxide-darwin-arm64": ["@tailwindcss/oxide-darwin-arm64@4.2.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-iq9Qjr6knfMpZHj55/37ouZeykwbDqF21gPFtfnhCCKGDcPI/21FKC9XdMO/XyBM7qKORx6UIhGgg6jLl7BZlg=="], - - "@tailwindcss/oxide-darwin-x64": ["@tailwindcss/oxide-darwin-x64@4.2.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-BlR+2c3nzc8f2G639LpL89YY4bdcIdUmiOOkv2GQv4/4M0vJlpXEa0JXNHhCHU7VWOKWT/CjqHdTP8aUuDJkuw=="], - - "@tailwindcss/oxide-freebsd-x64": ["@tailwindcss/oxide-freebsd-x64@4.2.2", "", { "os": "freebsd", "cpu": "x64" }, "sha512-YUqUgrGMSu2CDO82hzlQ5qSb5xmx3RUrke/QgnoEx7KvmRJHQuZHZmZTLSuuHwFf0DJPybFMXMYf+WJdxHy/nQ=="], - - "@tailwindcss/oxide-linux-arm-gnueabihf": ["@tailwindcss/oxide-linux-arm-gnueabihf@4.2.2", "", { "os": "linux", "cpu": "arm" }, "sha512-FPdhvsW6g06T9BWT0qTwiVZYE2WIFo2dY5aCSpjG/S/u1tby+wXoslXS0kl3/KXnULlLr1E3NPRRw0g7t2kgaQ=="], - - "@tailwindcss/oxide-linux-arm64-gnu": ["@tailwindcss/oxide-linux-arm64-gnu@4.2.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-4og1V+ftEPXGttOO7eCmW7VICmzzJWgMx+QXAJRAhjrSjumCwWqMfkDrNu1LXEQzNAwz28NCUpucgQPrR4S2yw=="], - - "@tailwindcss/oxide-linux-arm64-musl": ["@tailwindcss/oxide-linux-arm64-musl@4.2.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-oCfG/mS+/+XRlwNjnsNLVwnMWYH7tn/kYPsNPh+JSOMlnt93mYNCKHYzylRhI51X+TbR+ufNhhKKzm6QkqX8ag=="], - - "@tailwindcss/oxide-linux-x64-gnu": ["@tailwindcss/oxide-linux-x64-gnu@4.2.2", "", { "os": "linux", "cpu": "x64" }, "sha512-rTAGAkDgqbXHNp/xW0iugLVmX62wOp2PoE39BTCGKjv3Iocf6AFbRP/wZT/kuCxC9QBh9Pu8XPkv/zCZB2mcMg=="], - - "@tailwindcss/oxide-linux-x64-musl": ["@tailwindcss/oxide-linux-x64-musl@4.2.2", "", { "os": "linux", "cpu": "x64" }, "sha512-XW3t3qwbIwiSyRCggeO2zxe3KWaEbM0/kW9e8+0XpBgyKU4ATYzcVSMKteZJ1iukJ3HgHBjbg9P5YPRCVUxlnQ=="], - - "@tailwindcss/oxide-wasm32-wasi": ["@tailwindcss/oxide-wasm32-wasi@4.2.2", "", { "cpu": "none" }, "sha512-eKSztKsmEsn1O5lJ4ZAfyn41NfG7vzCg496YiGtMDV86jz1q/irhms5O0VrY6ZwTUkFy/EKG3RfWgxSI3VbZ8Q=="], - - "@tailwindcss/oxide-win32-arm64-msvc": ["@tailwindcss/oxide-win32-arm64-msvc@4.2.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-qPmaQM4iKu5mxpsrWZMOZRgZv1tOZpUm+zdhhQP0VhJfyGGO3aUKdbh3gDZc/dPLQwW4eSqWGrrcWNBZWUWaXQ=="], - - "@tailwindcss/oxide-win32-x64-msvc": ["@tailwindcss/oxide-win32-x64-msvc@4.2.2", "", { "os": "win32", "cpu": "x64" }, "sha512-1T/37VvI7WyH66b+vqHj/cLwnCxt7Qt3WFu5Q8hk65aOvlwAhs7rAp1VkulBJw/N4tMirXjVnylTR72uI0HGcA=="], - - "@tailwindcss/postcss": ["@tailwindcss/postcss@4.2.2", "", { "dependencies": { "@alloc/quick-lru": "^5.2.0", "@tailwindcss/node": "4.2.2", "@tailwindcss/oxide": "4.2.2", "postcss": "^8.5.6", "tailwindcss": "4.2.2" } }, "sha512-n4goKQbW8RVXIbNKRB/45LzyUqN451deQK0nzIeauVEqjlI49slUlgKYJM2QyUzap/PcpnS7kzSUmPb1sCRvYQ=="], - - "@types/hast": ["@types/hast@3.0.4", "", { "dependencies": { "@types/unist": "*" } }, "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ=="], - - "@types/matter-js": ["@types/matter-js@0.20.2", "", {}, "sha512-3PPKy3QxvZ89h9+wdBV2488I1JLVs7DEpIkPvgO8JC1mUdiVSO37ZIvVctOTD7hIq8OAL2gJ3ugGSuUip6DhCw=="], - - "@types/node": ["@types/node@25.6.0", "", { "dependencies": { "undici-types": "~7.19.0" } }, "sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ=="], - - "@types/prismjs": ["@types/prismjs@1.26.6", "", {}, "sha512-vqlvI7qlMvcCBbVe0AKAb4f97//Hy0EBTaiW8AalRnG/xAN5zOiWWyrNqNXeq8+KAuvRewjCVY1+IPxk4RdNYw=="], - - "@types/react": ["@types/react@19.2.14", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w=="], - - "@types/react-dom": ["@types/react-dom@19.2.3", "", { "peerDependencies": { "@types/react": "^19.2.0" } }, "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ=="], - - "@types/react-syntax-highlighter": ["@types/react-syntax-highlighter@15.5.13", "", { "dependencies": { "@types/react": "*" } }, "sha512-uLGJ87j6Sz8UaBAooU0T6lWJ0dBmjZgN1PZTrj05TNql2/XpC6+4HhMT5syIdFUUt+FASfCeLLv4kBygNU+8qA=="], - - "@types/unist": ["@types/unist@3.0.3", "", {}, "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q=="], - - "balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="], - - "baseline-browser-mapping": ["baseline-browser-mapping@2.10.10", "", { "bin": "dist/cli.cjs" }, "sha512-sUoJ3IMxx4AyRqO4MLeHlnGDkyXRoUG0/AI9fjK+vS72ekpV0yWVY7O0BVjmBcRtkNcsAO2QDZ4tdKKGoI6YaQ=="], - - "brace-expansion": ["brace-expansion@5.0.5", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ=="], - - "caniuse-lite": ["caniuse-lite@1.0.30001781", "", {}, "sha512-RdwNCyMsNBftLjW6w01z8bKEvT6e/5tpPVEgtn22TiLGlstHOVecsX2KHFkD5e/vRnIE4EGzpuIODb3mtswtkw=="], - - "character-entities": ["character-entities@2.0.2", "", {}, "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ=="], - - "character-entities-legacy": ["character-entities-legacy@3.0.0", "", {}, "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ=="], - - "character-reference-invalid": ["character-reference-invalid@2.0.1", "", {}, "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw=="], - - "citty": ["citty@0.2.2", "", {}, "sha512-+6vJA3L98yv+IdfKGZHBNiGW5KHn22e/JwID0Strsz8h4S/csAu/OuICwxrg44k5MRiZHWIo8XXuJgQTriRP4w=="], - - "client-only": ["client-only@0.0.1", "", {}, "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA=="], - - "clsx": ["clsx@2.1.1", "", {}, "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA=="], - - "comma-separated-tokens": ["comma-separated-tokens@2.0.3", "", {}, "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg=="], - - "commander": ["commander@14.0.3", "", {}, "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw=="], - - "cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="], - - "csstype": ["csstype@3.2.3", "", {}, "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="], - - "decode-named-character-reference": ["decode-named-character-reference@1.3.0", "", { "dependencies": { "character-entities": "^2.0.0" } }, "sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q=="], - - "deepmerge": ["deepmerge@4.3.1", "", {}, "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A=="], - - "detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="], - - "enhanced-resolve": ["enhanced-resolve@5.20.1", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.3.0" } }, "sha512-Qohcme7V1inbAfvjItgw0EaxVX5q2rdVEZHRBrEQdRZTssLDGsL8Lwrznl8oQ/6kuTJONLaDcGjkNP247XEhcA=="], - - "fast-string-truncated-width": ["fast-string-truncated-width@1.2.1", "", {}, "sha512-Q9acT/+Uu3GwGj+5w/zsGuQjh9O1TyywhIwAxHudtWrgF09nHOPrvTLhQevPbttcxjr/SNN7mJmfOw/B1bXgow=="], - - "fast-string-width": ["fast-string-width@1.1.0", "", { "dependencies": { "fast-string-truncated-width": "^1.2.0" } }, "sha512-O3fwIVIH5gKB38QNbdg+3760ZmGz0SZMgvwJbA1b2TGXceKE6A2cOlfogh1iw8lr049zPyd7YADHy+B7U4W9bQ=="], - - "fast-wrap-ansi": ["fast-wrap-ansi@0.1.6", "", { "dependencies": { "fast-string-width": "^1.1.0" } }, "sha512-HlUwET7a5gqjURj70D5jl7aC3Zmy4weA1SHUfM0JFI0Ptq987NH2TwbBFLoERhfwk+E+eaq4EK3jXoT+R3yp3w=="], - - "fault": ["fault@1.0.4", "", { "dependencies": { "format": "^0.2.0" } }, "sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA=="], - - "format": ["format@0.2.2", "", {}, "sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww=="], - - "framer-motion": ["framer-motion@12.38.0", "", { "dependencies": { "motion-dom": "^12.38.0", "motion-utils": "^12.36.0", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid"] }, "sha512-rFYkY/pigbcswl1XQSb7q424kSTQ8q6eAC+YUsSKooHQYuLdzdHjrt6uxUC+PRAO++q5IS7+TamgIw1AphxR+g=="], - - "glob": ["glob@13.0.6", "", { "dependencies": { "minimatch": "^10.2.2", "minipass": "^7.1.3", "path-scurry": "^2.0.2" } }, "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw=="], - - "graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="], - - "gsap": ["gsap@3.14.2", "", {}, "sha512-P8/mMxVLU7o4+55+1TCnQrPmgjPKnwkzkXOK1asnR9Jg2lna4tEY5qBJjMmAaOBDDZWtlRjBXjLa0w53G/uBLA=="], - - "hast-util-parse-selector": ["hast-util-parse-selector@4.0.0", "", { "dependencies": { "@types/hast": "^3.0.0" } }, "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A=="], - - "hastscript": ["hastscript@9.0.1", "", { "dependencies": { "@types/hast": "^3.0.0", "comma-separated-tokens": "^2.0.0", "hast-util-parse-selector": "^4.0.0", "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0" } }, "sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w=="], - - "highlight.js": ["highlight.js@10.7.3", "", {}, "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A=="], - - "highlightjs-vue": ["highlightjs-vue@1.0.0", "", {}, "sha512-PDEfEF102G23vHmPhLyPboFCD+BkMGu+GuJe2d9/eH4FsCwvgBpnc9n0pGE+ffKdph38s6foEZiEjdgHdzp+IA=="], - - "is-alphabetical": ["is-alphabetical@2.0.1", "", {}, "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ=="], - - "is-alphanumerical": ["is-alphanumerical@2.0.1", "", { "dependencies": { "is-alphabetical": "^2.0.0", "is-decimal": "^2.0.0" } }, "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw=="], - - "is-decimal": ["is-decimal@2.0.1", "", {}, "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A=="], - - "is-hexadecimal": ["is-hexadecimal@2.0.1", "", {}, "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg=="], - - "isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="], - - "jiti": ["jiti@2.6.1", "", { "bin": "lib/jiti-cli.mjs" }, "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ=="], - - "jsonc-parser": ["jsonc-parser@3.3.1", "", {}, "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ=="], - - "lightningcss": ["lightningcss@1.32.0", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.32.0", "lightningcss-darwin-arm64": "1.32.0", "lightningcss-darwin-x64": "1.32.0", "lightningcss-freebsd-x64": "1.32.0", "lightningcss-linux-arm-gnueabihf": "1.32.0", "lightningcss-linux-arm64-gnu": "1.32.0", "lightningcss-linux-arm64-musl": "1.32.0", "lightningcss-linux-x64-gnu": "1.32.0", "lightningcss-linux-x64-musl": "1.32.0", "lightningcss-win32-arm64-msvc": "1.32.0", "lightningcss-win32-x64-msvc": "1.32.0" } }, "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ=="], - - "lightningcss-android-arm64": ["lightningcss-android-arm64@1.32.0", "", { "os": "android", "cpu": "arm64" }, "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg=="], - - "lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.32.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ=="], - - "lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.32.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w=="], - - "lightningcss-freebsd-x64": ["lightningcss-freebsd-x64@1.32.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig=="], - - "lightningcss-linux-arm-gnueabihf": ["lightningcss-linux-arm-gnueabihf@1.32.0", "", { "os": "linux", "cpu": "arm" }, "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw=="], - - "lightningcss-linux-arm64-gnu": ["lightningcss-linux-arm64-gnu@1.32.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ=="], - - "lightningcss-linux-arm64-musl": ["lightningcss-linux-arm64-musl@1.32.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg=="], - - "lightningcss-linux-x64-gnu": ["lightningcss-linux-x64-gnu@1.32.0", "", { "os": "linux", "cpu": "x64" }, "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA=="], - - "lightningcss-linux-x64-musl": ["lightningcss-linux-x64-musl@1.32.0", "", { "os": "linux", "cpu": "x64" }, "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg=="], - - "lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.32.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw=="], - - "lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.32.0", "", { "os": "win32", "cpu": "x64" }, "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q=="], - - "lottie-react": ["lottie-react@2.4.1", "", { "dependencies": { "lottie-web": "^5.10.2" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-LQrH7jlkigIIv++wIyrOYFLHSKQpEY4zehPicL9bQsrt1rnoKRYCYgpCUe5maqylNtacy58/sQDZTkwMcTRxZw=="], - - "lottie-web": ["lottie-web@5.13.0", "", {}, "sha512-+gfBXl6sxXMPe8tKQm7qzLnUy5DUPJPKIyRHwtpCpyUEYjHYRJC/5gjUvdkuO2c3JllrPtHXH5UJJK8LRYl5yQ=="], - - "lowlight": ["lowlight@1.20.0", "", { "dependencies": { "fault": "^1.0.0", "highlight.js": "~10.7.0" } }, "sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw=="], - - "lru-cache": ["lru-cache@11.3.5", "", {}, "sha512-NxVFwLAnrd9i7KUBxC4DrUhmgjzOs+1Qm50D3oF1/oL+r1NpZ4gA7xvG0/zJ8evR7zIKn4vLf7qTNduWFtCrRw=="], - - "magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="], - - "matter-js": ["matter-js@0.20.0", "", {}, "sha512-iC9fYR7zVT3HppNnsFsp9XOoQdQN2tUyfaKg4CHLH8bN+j6GT4Gw7IH2rP0tflAebrHFw730RR3DkVSZRX8hwA=="], - - "minimatch": ["minimatch@10.2.5", "", { "dependencies": { "brace-expansion": "^5.0.5" } }, "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg=="], - - "minipass": ["minipass@7.1.3", "", {}, "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A=="], - - "motion": ["motion@12.38.0", "", { "dependencies": { "framer-motion": "^12.38.0", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid"] }, "sha512-uYfXzeHlgThchzwz5Te47dlv5JOUC7OB4rjJ/7XTUgtBZD8CchMN8qEJ4ZVsUmTyYA44zjV0fBwsiktRuFnn+w=="], - - "motion-dom": ["motion-dom@12.38.0", "", { "dependencies": { "motion-utils": "^12.36.0" } }, "sha512-pdkHLD8QYRp8VfiNLb8xIBJis1byQ9gPT3Jnh2jqfFtAsWUA3dEepDlsWe/xMpO8McV+VdpKVcp+E+TGJEtOoA=="], - - "motion-utils": ["motion-utils@12.36.0", "", {}, "sha512-eHWisygbiwVvf6PZ1vhaHCLamvkSbPIeAYxWUuL3a2PD/TROgE7FvfHWTIH4vMl798QLfMw15nRqIaRDXTlYRg=="], - - "nanoid": ["nanoid@3.3.11", "", { "bin": "bin/nanoid.cjs" }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="], - - "next": ["next@16.2.1", "", { "dependencies": { "@next/env": "16.2.1", "@swc/helpers": "0.5.15", "baseline-browser-mapping": "^2.9.19", "caniuse-lite": "^1.0.30001579", "postcss": "8.4.31", "styled-jsx": "5.1.6" }, "optionalDependencies": { "@next/swc-darwin-arm64": "16.2.1", "@next/swc-darwin-x64": "16.2.1", "@next/swc-linux-arm64-gnu": "16.2.1", "@next/swc-linux-arm64-musl": "16.2.1", "@next/swc-linux-x64-gnu": "16.2.1", "@next/swc-linux-x64-musl": "16.2.1", "@next/swc-win32-arm64-msvc": "16.2.1", "@next/swc-win32-x64-msvc": "16.2.1", "sharp": "^0.34.5" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", "@playwright/test": "^1.51.1", "babel-plugin-react-compiler": "*", "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "sass": "^1.3.0" }, "optionalPeers": ["@opentelemetry/api", "@playwright/test", "babel-plugin-react-compiler", "sass"], "bin": "dist/bin/next" }, "sha512-VaChzNL7o9rbfdt60HUj8tev4m6d7iC1igAy157526+cJlXOQu5LzsBXNT+xaJnTP/k+utSX5vMv7m0G+zKH+Q=="], - - "nypm": ["nypm@0.6.5", "", { "dependencies": { "citty": "^0.2.0", "pathe": "^2.0.3", "tinyexec": "^1.0.2" }, "bin": { "nypm": "dist/cli.mjs" } }, "sha512-K6AJy1GMVyfyMXRVB88700BJqNUkByijGJM8kEHpLdcAt+vSQAVfkWWHYzuRXHSY6xA2sNc5RjTj0p9rE2izVQ=="], - - "parse-entities": ["parse-entities@4.0.2", "", { "dependencies": { "@types/unist": "^2.0.0", "character-entities-legacy": "^3.0.0", "character-reference-invalid": "^2.0.0", "decode-named-character-reference": "^1.0.0", "is-alphanumerical": "^2.0.0", "is-decimal": "^2.0.0", "is-hexadecimal": "^2.0.0" } }, "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw=="], - - "path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="], - - "path-scurry": ["path-scurry@2.0.2", "", { "dependencies": { "lru-cache": "^11.0.0", "minipass": "^7.1.2" } }, "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg=="], - - "pathe": ["pathe@2.0.3", "", {}, "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w=="], - - "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="], - - "postcss": ["postcss@8.5.8", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg=="], - - "prismjs": ["prismjs@1.30.0", "", {}, "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw=="], - - "property-information": ["property-information@7.1.0", "", {}, "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ=="], - - "react": ["react@19.2.4", "", {}, "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ=="], - - "react-dom": ["react-dom@19.2.4", "", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.4" } }, "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ=="], - - "react-syntax-highlighter": ["react-syntax-highlighter@16.1.1", "", { "dependencies": { "@babel/runtime": "^7.28.4", "highlight.js": "^10.4.1", "highlightjs-vue": "^1.0.0", "lowlight": "^1.17.0", "prismjs": "^1.30.0", "refractor": "^5.0.0" }, "peerDependencies": { "react": ">= 0.14.0" } }, "sha512-PjVawBGy80C6YbC5DDZJeUjBmC7skaoEUdvfFQediQHgCL7aKyVHe57SaJGfQsloGDac+gCpTfRdtxzWWKmCXA=="], - - "refractor": ["refractor@5.0.0", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/prismjs": "^1.0.0", "hastscript": "^9.0.0", "parse-entities": "^4.0.0" } }, "sha512-QXOrHQF5jOpjjLfiNk5GFnWhRXvxjUVnlFxkeDmewR5sXkr3iM46Zo+CnRR8B+MDVqkULW4EcLVcRBNOPXHosw=="], - - "scheduler": ["scheduler@0.27.0", "", {}, "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q=="], - - "semver": ["semver@7.7.4", "", { "bin": "bin/semver.js" }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="], - - "sharp": ["sharp@0.34.5", "", { "dependencies": { "@img/colour": "^1.0.0", "detect-libc": "^2.1.2", "semver": "^7.7.3" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.34.5", "@img/sharp-darwin-x64": "0.34.5", "@img/sharp-libvips-darwin-arm64": "1.2.4", "@img/sharp-libvips-darwin-x64": "1.2.4", "@img/sharp-libvips-linux-arm": "1.2.4", "@img/sharp-libvips-linux-arm64": "1.2.4", "@img/sharp-libvips-linux-ppc64": "1.2.4", "@img/sharp-libvips-linux-riscv64": "1.2.4", "@img/sharp-libvips-linux-s390x": "1.2.4", "@img/sharp-libvips-linux-x64": "1.2.4", "@img/sharp-libvips-linuxmusl-arm64": "1.2.4", "@img/sharp-libvips-linuxmusl-x64": "1.2.4", "@img/sharp-linux-arm": "0.34.5", "@img/sharp-linux-arm64": "0.34.5", "@img/sharp-linux-ppc64": "0.34.5", "@img/sharp-linux-riscv64": "0.34.5", "@img/sharp-linux-s390x": "0.34.5", "@img/sharp-linux-x64": "0.34.5", "@img/sharp-linuxmusl-arm64": "0.34.5", "@img/sharp-linuxmusl-x64": "0.34.5", "@img/sharp-wasm32": "0.34.5", "@img/sharp-win32-arm64": "0.34.5", "@img/sharp-win32-ia32": "0.34.5", "@img/sharp-win32-x64": "0.34.5" } }, "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg=="], - - "shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="], - - "shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="], - - "sisteransi": ["sisteransi@1.0.5", "", {}, "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg=="], - - "source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="], - - "space-separated-tokens": ["space-separated-tokens@2.0.2", "", {}, "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q=="], - - "styled-jsx": ["styled-jsx@5.1.6", "", { "dependencies": { "client-only": "0.0.1" }, "peerDependencies": { "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0" } }, "sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA=="], - - "tailwind-merge": ["tailwind-merge@3.5.0", "", {}, "sha512-I8K9wewnVDkL1NTGoqWmVEIlUcB9gFriAEkXkfCjX5ib8ezGxtR3xD7iZIxrfArjEsH7F1CHD4RFUtxefdqV/A=="], - - "tailwindcss": ["tailwindcss@4.2.2", "", {}, "sha512-KWBIxs1Xb6NoLdMVqhbhgwZf2PGBpPEiwOqgI4pFIYbNTfBXiKYyWoTsXgBQ9WFg/OlhnvHaY+AEpW7wSmFo2Q=="], - - "tapable": ["tapable@2.3.1", "", {}, "sha512-b+u3CEM6FjDHru+nhUSjDofpWSBp2rINziJWgApm72wwGasQ/wKXftZe4tI2Y5HPv6OpzXSZHOFq87H4vfsgsw=="], - - "tinyexec": ["tinyexec@1.1.1", "", {}, "sha512-VKS/ZaQhhkKFMANmAOhhXVoIfBXblQxGX1myCQ2faQrfmobMftXeJPcZGp0gS07ocvGJWDLZGyOZDadDBqYIJg=="], - - "tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - - "typescript": ["typescript@6.0.2", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-bGdAIrZ0wiGDo5l8c++HWtbaNCWTS4UTv7RaTH/ThVIgjkveJt83m74bBHMJkuCbslY8ixgLBVZJIOiQlQTjfQ=="], - - "ultracite": ["ultracite@7.5.9", "", { "dependencies": { "@clack/prompts": "^1.2.0", "commander": "^14.0.3", "cross-spawn": "^7.0.6", "deepmerge": "^4.3.1", "glob": "^13.0.6", "jsonc-parser": "^3.3.1", "nypm": "^0.6.5", "yaml": "^2.8.3", "zod": "^4.3.2" }, "peerDependencies": { "oxfmt": ">=0.1.0", "oxlint": "^1.0.0" }, "optionalPeers": ["oxfmt", "oxlint"], "bin": { "ultracite": "dist/index.js" } }, "sha512-6UBZNXqUm9tosAQ/nBQaWeCHWBcOVZmDl9Jfg33o9jSrUSTobpphI23Wh72tc8iYPTR3tXGHWhO+GvC7w/QyQQ=="], - - "undici-types": ["undici-types@7.19.2", "", {}, "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg=="], - - "which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="], - - "yaml": ["yaml@2.8.3", "", { "bin": { "yaml": "bin.mjs" } }, "sha512-AvbaCLOO2Otw/lW5bmh9d/WEdcDFdQp2Z2ZUH3pX9U2ihyUY0nvLv7J6TrWowklRGPYbB/IuIMfYgxaCPg5Bpg=="], - - "zod": ["zod@4.3.6", "", {}, "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg=="], - - "next/postcss": ["postcss@8.4.31", "", { "dependencies": { "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" } }, "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ=="], - - "parse-entities/@types/unist": ["@types/unist@2.0.11", "", {}, "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA=="], - } -} diff --git a/apps/website/components/animated-footer-image.jsx b/apps/website/components/animated-footer-image.jsx new file mode 100755 index 000000000..0c63aae4e --- /dev/null +++ b/apps/website/components/animated-footer-image.jsx @@ -0,0 +1,31 @@ +"use client"; + +import Image from "next/image"; + +export default function AnimatedFooterImage() { + return ( +
+ {/* Mobile */} + footer background + + {/* Desktop */} + footer background +
+ ); +} diff --git a/apps/website/components/animated-footer-image.tsx b/apps/website/components/animated-footer-image.tsx deleted file mode 100755 index a652b1a55..000000000 --- a/apps/website/components/animated-footer-image.tsx +++ /dev/null @@ -1,31 +0,0 @@ -"use client"; - -import Image from "next/image"; - -export default function AnimatedFooterImage() { - return ( -
- {/* Mobile */} - footer background - - {/* Desktop */} - footer background -
- ); -} diff --git a/apps/website/components/autumn-config.jsx b/apps/website/components/autumn-config.jsx new file mode 100755 index 000000000..c172545d7 --- /dev/null +++ b/apps/website/components/autumn-config.jsx @@ -0,0 +1,247 @@ +"use client"; + +import Image from "next/image"; +import { useEffect, useLayoutEffect, useRef, useState } from "react"; +import { Light as SyntaxHighlighter } from "react-syntax-highlighter"; +import js from "react-syntax-highlighter/dist/esm/languages/hljs/javascript"; + +// useLayoutEffect runs synchronously before browser paint on the client, +// eliminating the container-query font-size race that causes CLS on reload. +const useIsomorphicLayoutEffect = + typeof window !== "undefined" ? useLayoutEffect : useEffect; + +SyntaxHighlighter.registerLanguage("javascript", js); + +const autumnTheme = { + hljs: { + display: "block", + background: "transparent", + color: "#BFBFBF", + padding: "0", + margin: "0", + }, + "hljs-comment": { color: "#6B6B6B" }, + "hljs-keyword": { color: "#9564ff" }, + "hljs-built_in": { color: "#BFBFBF" }, + "hljs-string": { color: "#2B8C3F" }, + "hljs-number": { color: "#9564ff" }, + "hljs-literal": { color: "#2B8C3F" }, + "hljs-attr": { color: "#FF1F12" }, + "hljs-property": { color: "#FF1F12" }, + "hljs-variable": { color: "#0161B5" }, + "hljs-title": { color: "#BFBFBF" }, + "hljs-params": { color: "#0161B5" }, + "hljs-punctuation": { color: "#BFBFBF" }, +}; + +const TOTAL_LINES = 21; +const LINE_HEIGHT = 24; + +const codeContent = `// Your entire billing integration +const { allowed, remaining } = await +autumn.check({ + featureId: "ai_tokens" +}); + +if (allowed) { + await autumn.track({ + featureId: "ai_tokens", + value: 1024 + }); +}`; + +const TYPING_SPEED = 10; + +export default function AutumnConfig({ + lines = TOTAL_LINES, + initialDelay = 0, + awaitEvent = null, +}) { + const fullCode = (() => { + const lineCount = codeContent.split("\n").length; + return codeContent + "\n".repeat(Math.max(0, lines - lineCount)); + })(); + const containerRef = useRef(null); + const [fontSize, setFontSize] = useState(16); + const [displayed, setDisplayed] = useState(""); + const [cursorVisible, setCursorVisible] = useState(true); + const [awaitDone, setAwaitDone] = useState(!awaitEvent); + const [started, setStarted] = useState(initialDelay === 0 && !awaitEvent); + const done = displayed.length >= fullCode.length; + + // Wait for the signal event before starting the delay countdown + useEffect(() => { + if (!awaitEvent) return; + const handler = () => setAwaitDone(true); + window.addEventListener(awaitEvent, handler, { once: true }); + return () => window.removeEventListener(awaitEvent, handler); + }, [awaitEvent]); + + // Start typing after awaitDone, respecting initialDelay + useEffect(() => { + if (!awaitDone) return; + const t = setTimeout(() => setStarted(true), initialDelay); + return () => clearTimeout(t); + }, [awaitDone, initialDelay]); + + useIsomorphicLayoutEffect(() => { + const el = containerRef.current; + if (!el) return; + const measure = () => + setFontSize(Math.min(Math.max(el.offsetWidth * 0.0385, 10), 20)); + measure(); + const ro = new ResizeObserver(measure); + ro.observe(el); + return () => ro.disconnect(); + }, []); + + const displayedPadded = + displayed + "\n".repeat(Math.max(0, lines - displayed.split("\n").length)); + useEffect(() => { + if (!started || done) return; + const timer = setTimeout(() => { + setDisplayed(fullCode.slice(0, displayed.length + 1)); + }, TYPING_SPEED); + return () => clearTimeout(timer); + }, [displayed, done, started]); + + // Blinking cursor after done + useEffect(() => { + if (!done) return; + const interval = setInterval(() => setCursorVisible((v) => !v), 530); + return () => clearInterval(interval); + }, [done]); + + return ( +
+ {/* Title bar */} + {/*
+
+ Box +
+ + autumn.config.ts + +
+ Box +
+ + cross + +
*/} +
+ {/* Left Vent: flex-1 makes it stretch, min-w-0 allows it to shrink below its content if needed */} +
+
+
+
+
+ + {/* Filename: shrink-0 ensures the text never gets squashed */} + + autumn.config.ts + + + {/* Right Vent: Matches the left one */} +
+
+
+
+
+ + {/* Close Button Container */} +
+ Box +
+
+ + {/* Code area — fluidly driven by container query relative font sizes so height never distorts */} +
+ {/* Dynamic-height inner box: 20 lines × 1.25em */} +
+ + {displayedPadded} + +
+ +
+ +
+ +
+ +
+
+
+ allowed: + true + remaining: + 8976 +
+ 92ms +
+
+
+
+ ); +} diff --git a/apps/website/components/autumn-config.tsx b/apps/website/components/autumn-config.tsx deleted file mode 100755 index b104fbf65..000000000 --- a/apps/website/components/autumn-config.tsx +++ /dev/null @@ -1,252 +0,0 @@ -"use client"; - -import Image from "next/image"; -import type { CSSProperties } from "react"; -import { useEffect, useLayoutEffect, useRef, useState } from "react"; -import { Light as SyntaxHighlighter } from "react-syntax-highlighter"; -import js from "react-syntax-highlighter/dist/esm/languages/hljs/javascript"; - -// useLayoutEffect runs synchronously before browser paint on the client, -// eliminating the container-query font-size race that causes CLS on reload. -const useIsomorphicLayoutEffect = - typeof window !== "undefined" ? useLayoutEffect : useEffect; - -SyntaxHighlighter.registerLanguage("javascript", js); - -const autumnTheme: Record = { - hljs: { - display: "block", - background: "transparent", - color: "#BFBFBF", - padding: "0", - margin: "0", - }, - "hljs-comment": { color: "#6B6B6B" }, - "hljs-keyword": { color: "#9564ff" }, - "hljs-built_in": { color: "#BFBFBF" }, - "hljs-string": { color: "#2B8C3F" }, - "hljs-number": { color: "#9564ff" }, - "hljs-literal": { color: "#2B8C3F" }, - "hljs-attr": { color: "#FF1F12" }, - "hljs-property": { color: "#FF1F12" }, - "hljs-variable": { color: "#0161B5" }, - "hljs-title": { color: "#BFBFBF" }, - "hljs-params": { color: "#0161B5" }, - "hljs-punctuation": { color: "#BFBFBF" }, -}; - -const TOTAL_LINES = 21; -const LINE_HEIGHT = 24; - -const codeContent = `// Your entire billing integration -const { allowed, remaining } = await -autumn.check({ - featureId: "ai_tokens" -}); - -if (allowed) { - await autumn.track({ - featureId: "ai_tokens", - value: 1024 - }); -}`; - -const TYPING_SPEED = 10; - -export default function AutumnConfig({ - lines = TOTAL_LINES, - initialDelay = 0, - awaitEvent = null, -}: { - lines?: number; - initialDelay?: number; - awaitEvent?: string | null; -}) { - const fullCode = (() => { - const lineCount = codeContent.split("\n").length; - return codeContent + "\n".repeat(Math.max(0, lines - lineCount)); - })(); - const containerRef = useRef(null); - const [fontSize, setFontSize] = useState(16); - const [displayed, setDisplayed] = useState(""); - const [cursorVisible, setCursorVisible] = useState(true); - const [awaitDone, setAwaitDone] = useState(!awaitEvent); - const [started, setStarted] = useState(initialDelay === 0 && !awaitEvent); - const done = displayed.length >= fullCode.length; - - // Wait for the signal event before starting the delay countdown - useEffect(() => { - if (!awaitEvent) return; - const handler = () => setAwaitDone(true); - window.addEventListener(awaitEvent, handler, { once: true }); - return () => window.removeEventListener(awaitEvent, handler); - }, [awaitEvent]); - - // Start typing after awaitDone, respecting initialDelay - useEffect(() => { - if (!awaitDone) return; - const t = setTimeout(() => setStarted(true), initialDelay); - return () => clearTimeout(t); - }, [awaitDone, initialDelay]); - - useIsomorphicLayoutEffect(() => { - const el = containerRef.current; - if (!el) return; - const measure = () => - setFontSize(Math.min(Math.max(el.offsetWidth * 0.0385, 10), 20)); - measure(); - const ro = new ResizeObserver(measure); - ro.observe(el); - return () => ro.disconnect(); - }, []); - - const displayedPadded = - displayed + "\n".repeat(Math.max(0, lines - displayed.split("\n").length)); - useEffect(() => { - if (!started || done) return; - const timer = setTimeout(() => { - setDisplayed(fullCode.slice(0, displayed.length + 1)); - }, TYPING_SPEED); - return () => clearTimeout(timer); - }, [displayed, done, fullCode, started]); - - // Blinking cursor after done - useEffect(() => { - if (!done) return; - const interval = setInterval(() => setCursorVisible((v) => !v), 530); - return () => clearInterval(interval); - }, [done]); - - return ( -
- {/* Title bar */} - {/*
-
- Box -
- - autumn.config.ts - -
- Box -
- - cross - -
*/} -
- {/* Left Vent: flex-1 makes it stretch, min-w-0 allows it to shrink below its content if needed */} -
-
-
-
-
- - {/* Filename: shrink-0 ensures the text never gets squashed */} - - autumn.config.ts - - - {/* Right Vent: Matches the left one */} -
-
-
-
-
- - {/* Close Button Container */} -
- Box -
-
- - {/* Code area — fluidly driven by container query relative font sizes so height never distorts */} -
- {/* Dynamic-height inner box: 20 lines × 1.25em */} -
- - {displayedPadded} - -
- -
- -
- -
- -
-
-
- allowed: - true - remaining: - 8976 -
- 92ms -
-
-
-
- ); -} diff --git a/apps/website/components/dashboard-icon-pixel.jsx b/apps/website/components/dashboard-icon-pixel.jsx new file mode 100755 index 000000000..84822aaca --- /dev/null +++ b/apps/website/components/dashboard-icon-pixel.jsx @@ -0,0 +1,71 @@ +"use client"; +import { forwardRef, useImperativeHandle, useRef, useEffect } from "react"; +import gsap from "gsap"; + +export const DashboardIconPixel = forwardRef(function DashboardIconPixel( + { 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(), + })); + + useEffect(() => { + const pixels = iconRef.current?.querySelectorAll(".icon-pixel-path"); + const pulseEl = pulseRef.current; + if (!pixels || !pulseEl) return; + + gsap.set(pixels, { + opacity: 0.25, + scale: 0.8, + transformOrigin: "left bottom", + }); + 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, { + duration: 0.2, + onUpdate: function () { + pulseEl.innerText = + frames[Math.floor(this.progress() * (frames.length - 1))]; + }, + }) + .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", + ); + }, []); + + return ( + // Height and Width match your original icon (14px) + +
+ + + ); +}); diff --git a/apps/website/components/dashboard-icon-pixel.tsx b/apps/website/components/dashboard-icon-pixel.tsx deleted file mode 100755 index 207f7469e..000000000 --- a/apps/website/components/dashboard-icon-pixel.tsx +++ /dev/null @@ -1,76 +0,0 @@ -"use client"; -import gsap from "gsap"; -import { forwardRef, useEffect, useImperativeHandle, useRef } from "react"; -import type { IconComponent, NavIconHandle } from "./website-types"; - -const BRAILLE_FRAMES = [ - "\u2800\u2836\u2800", - "\u2830\u28FF\u2806", - "\u28BE\u28C9\u2877", - "\u28CF\u2800\u28F9", - "\u2841\u2800\u2888", -] as const; - -export const DashboardIconPixel = forwardRef< - NavIconHandle, - { Icon: IconComponent } ->(function DashboardIconPixel({ Icon }, ref) { - const iconRef = useRef(null); - const pulseRef = useRef(null); - const tlRef = useRef(null); - - useImperativeHandle(ref, () => ({ - 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; - - gsap.set(pixels, { - opacity: 0.25, - scale: 0.8, - transformOrigin: "left bottom", - }); - 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, { - duration: 0.2, - onUpdate: function () { - pulseEl.innerText = - BRAILLE_FRAMES[ - Math.floor(this.progress() * (BRAILLE_FRAMES.length - 1)) - ]; - }, - }) - .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", - ); - }, []); - - return ( - -
-
- -
- - ); -}); diff --git a/apps/website/components/elastic-footer.jsx b/apps/website/components/elastic-footer.jsx new file mode 100755 index 000000000..8b32a272b --- /dev/null +++ b/apps/website/components/elastic-footer.jsx @@ -0,0 +1,107 @@ +"use client"; +import { motion, useSpring, useTransform, useMotionValue } from "framer-motion"; +import { useEffect } 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 animatedLift = useSpring(liftAmount, springConfig); + const y = useTransform(animatedLift, [0, 400], [0, -280]); + + useEffect(() => { + let timeout; + let recoilFired = false; + let isTouching = false; // Track if finger is on screen + + const triggerRebound = () => { + liftAmount.set(0); + if (!recoilFired) { + recoilFired = true; + window.dispatchEvent(new CustomEvent("elastic-recoil")); + } + }; + + const handleWheel = (e) => { + const isAtBottom = + window.innerHeight + window.pageYOffset >= + document.documentElement.scrollHeight - 5; + + if (isAtBottom && e.deltaY > 0) { + liftAmount.set(liftAmount.get() + e.deltaY * 0.5); + recoilFired = false; + + // Reset timeout on every wheel event + clearTimeout(timeout); + timeout = setTimeout(() => { + if (!isTouching) { + triggerRebound(); + } + }, 1500); // Rebounds 1.5 seconds after wheel stops + } else if (e.deltaY < 0) { + if (!isTouching) { + liftAmount.set(0); + recoilFired = false; + } + } + }; + + let touchStart = 0; + const handleTouchStart = (e) => { + isTouching = true; + touchStart = e.touches[0].clientY; + recoilFired = false; + clearTimeout(timeout); + }; + + const handleTouchMove = (e) => { + const isAtBottom = + window.innerHeight + window.pageYOffset >= + document.documentElement.scrollHeight - 5; + + 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 + } + } + }; + + const handleTouchEnd = () => { + isTouching = false; + if (liftAmount.get() > 0) { + clearTimeout(timeout); + timeout = setTimeout(() => { + triggerRebound(); + }, 1500); // Rebounds 1.5 seconds after lifting finger + } + }; + + window.addEventListener("wheel", handleWheel, { passive: true }); + window.addEventListener("touchstart", handleTouchStart, { passive: true }); + window.addEventListener("touchmove", handleTouchMove, { passive: true }); + window.addEventListener("touchend", handleTouchEnd, { passive: true }); + window.addEventListener("touchcancel", handleTouchEnd, { passive: true }); + + return () => { + clearTimeout(timeout); + window.removeEventListener("wheel", handleWheel); + window.removeEventListener("touchstart", handleTouchStart); + window.removeEventListener("touchmove", handleTouchMove); + window.removeEventListener("touchend", handleTouchEnd); + window.removeEventListener("touchcancel", handleTouchEnd); + }; + }, [liftAmount]); + + return ( +
+ + + {children} + +
+ ); +} diff --git a/apps/website/components/elastic-footer.tsx b/apps/website/components/elastic-footer.tsx deleted file mode 100755 index 92f08ab67..000000000 --- a/apps/website/components/elastic-footer.tsx +++ /dev/null @@ -1,108 +0,0 @@ -"use client"; -import { motion, useMotionValue, useSpring, useTransform } from "framer-motion"; -import type { ReactNode } from "react"; -import { useEffect } from "react"; -import AnimatedFooterImage from "./animated-footer-image"; - -export default function ElasticRecoil({ children }: { children: ReactNode }) { - const liftAmount = useMotionValue(0); - - const springConfig = { stiffness: 600, damping: 35, mass: 1 }; - const animatedLift = useSpring(liftAmount, springConfig); - const y = useTransform(animatedLift, [0, 400], [0, -280]); - - useEffect(() => { - let timeout: ReturnType | null = null; - let recoilFired = false; - let isTouching = false; // Track if finger is on screen - - const triggerRebound = () => { - liftAmount.set(0); - if (!recoilFired) { - recoilFired = true; - window.dispatchEvent(new CustomEvent("elastic-recoil")); - } - }; - - const handleWheel = (e: WheelEvent) => { - const isAtBottom = - window.innerHeight + window.pageYOffset >= - document.documentElement.scrollHeight - 5; - - if (isAtBottom && e.deltaY > 0) { - liftAmount.set(liftAmount.get() + e.deltaY * 0.5); - recoilFired = false; - - // Reset timeout on every wheel event - if (timeout) clearTimeout(timeout); - timeout = setTimeout(() => { - if (!isTouching) { - triggerRebound(); - } - }, 1500); // Rebounds 1.5 seconds after wheel stops - } else if (e.deltaY < 0) { - if (!isTouching) { - liftAmount.set(0); - recoilFired = false; - } - } - }; - - let touchStart = 0; - const handleTouchStart = (e: TouchEvent) => { - isTouching = true; - touchStart = e.touches[0].clientY; - recoilFired = false; - if (timeout) clearTimeout(timeout); - }; - - const handleTouchMove = (e: TouchEvent) => { - const isAtBottom = - window.innerHeight + window.pageYOffset >= - document.documentElement.scrollHeight - 5; - - 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 - } - } - }; - - const handleTouchEnd = () => { - isTouching = false; - if (liftAmount.get() > 0) { - if (timeout) clearTimeout(timeout); - timeout = setTimeout(() => { - triggerRebound(); - }, 1500); // Rebounds 1.5 seconds after lifting finger - } - }; - - window.addEventListener("wheel", handleWheel, { passive: true }); - window.addEventListener("touchstart", handleTouchStart, { passive: true }); - window.addEventListener("touchmove", handleTouchMove, { passive: true }); - window.addEventListener("touchend", handleTouchEnd, { passive: true }); - window.addEventListener("touchcancel", handleTouchEnd, { passive: true }); - - return () => { - if (timeout) clearTimeout(timeout); - window.removeEventListener("wheel", handleWheel); - window.removeEventListener("touchstart", handleTouchStart); - window.removeEventListener("touchmove", handleTouchMove); - window.removeEventListener("touchend", handleTouchEnd); - window.removeEventListener("touchcancel", handleTouchEnd); - }; - }, [liftAmount]); - - return ( -
- - - {children} - -
- ); -} diff --git a/apps/website/components/faq.jsx b/apps/website/components/faq.jsx new file mode 100755 index 000000000..288083817 --- /dev/null +++ b/apps/website/components/faq.jsx @@ -0,0 +1,147 @@ +"use client"; +import { faqData, AnimatedPlusMinus } from "@/app/constant"; +import Image from "next/image"; +import { useState } from "react"; +import { motion, AnimatePresence } from "framer-motion"; + +export default function FAQ() { + const [openId, setOpenId] = useState(3); + + const springConfig = { + type: "spring", + stiffness: 280, + damping: 32, + mass: 1, + restDelta: 0.01, + }; + + const toggleAccordion = (id) => { + setOpenId(openId === id ? null : id); + }; + + return ( +
+
+
+

+ + Frequently Asked + +
+ Questions +

+
+ +
+ +
+
+
+ +
+ {faqData.map((faq) => { + const isOpen = openId === faq.id; + + return ( +
toggleAccordion(faq.id)} + className={`group relative border-b last:border-b-0 border-[#292929] cursor-pointer w-full flex flex-col justify-center transition-colors duration-300 ${isOpen ? "" : "hover:bg-[#080808]"}`} + > +
+
+ + faq background +
+
+ +
+
+

+ {faq.question} +

+
+ +
+
+ +
+
+ + {isOpen && ( + + {faq.answer.split("\n\n").map((paragraph, idx) => ( +

{paragraph}

+ ))} +
+ )} +
+
+
+
+
+ ); + })} + + +
+
+
+ ); +} diff --git a/apps/website/components/faq.tsx b/apps/website/components/faq.tsx deleted file mode 100755 index 977be553a..000000000 --- a/apps/website/components/faq.tsx +++ /dev/null @@ -1,165 +0,0 @@ -"use client"; -import Image from "next/image"; -import { AnimatePresence, motion } from "framer-motion"; -import { useState } from "react"; -import { AnimatedPlusMinus, faqData } from "@/app/constant"; -import { cn } from "@/lib/utils"; - -export default function FAQ() { - const [openId, setOpenId] = useState(3); - - const springConfig = { - type: "spring", - stiffness: 280, - damping: 32, - mass: 1, - restDelta: 0.01, - } as const; - - const toggleAccordion = (id: number) => { - setOpenId(openId === id ? null : id); - }; - - return ( -
-
-
-

- - Frequently Asked - -
- Questions -

-
- -
- -
-
-
- -
- {faqData.map((faq) => { - const isOpen = openId === faq.id; - const answerId = `faq-answer-${faq.id}`; - - return ( -
-
-
- - faq background -
-
- -
- - -
-
- - {isOpen && ( - - {faq.answer.split("\n\n").map((paragraph) => ( -

- {paragraph} -

- ))} -
- )} -
-
-
-
-
- ); - })} - - -
-
-
- ); -} diff --git a/apps/website/components/feature-icon-animation.jsx b/apps/website/components/feature-icon-animation.jsx new file mode 100755 index 000000000..45618003f --- /dev/null +++ b/apps/website/components/feature-icon-animation.jsx @@ -0,0 +1,106 @@ +"use client"; +import { forwardRef, useImperativeHandle, useRef, useEffect } from "react"; +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; + + // IDLE: Subjugated/Ghost state + gsap.set(pixels, { + opacity: 0.15, + scale: 0.8, + transformOrigin: "left bottom", + }); + 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", + }) + // 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, + ease: "back.out(3)", + }); + + return () => tlRef.current?.kill(); + }, []); + + return ( +
+ {/* 5x5 Grid Mask */} +
+
+ {Array.from({ length: 25 }).map((_, i) => ( +
+ ))} +
+
+ + {/* Pulse Shuffle Layer */} +
+ {"\u2800\u2836\u2800"} +
+ + {/* Feature Icon Layer */} +
+ +
+
+ ); +}); +FeatureIconAnimation.displayName = "FeatureIconAnimation"; diff --git a/apps/website/components/feature-icon-animation.tsx b/apps/website/components/feature-icon-animation.tsx deleted file mode 100755 index 3ce252be3..000000000 --- a/apps/website/components/feature-icon-animation.tsx +++ /dev/null @@ -1,135 +0,0 @@ -"use client"; -import gsap from "gsap"; -import { forwardRef, useEffect, useImperativeHandle, useRef } from "react"; -import type { IconAnimationHandle, IconComponent } from "./website-types"; - -const BRAILLE_FRAMES = [ - "\u2800\u2836\u2800", - "\u2830\u28FF\u2806", - "\u28BE\u28C9\u2877", - "\u28CF\u2800\u28F9", - "\u2841\u2800\u2888", -] as const; - -const FEATURE_GRID_KEYS = Array.from( - { length: 25 }, - (_, i) => `${Math.floor(i / 5)}-${i % 5}`, -); - -export const FeatureIconAnimation = forwardRef< - IconAnimationHandle, - { Icon: IconComponent } ->(function FeatureIconAnimation({ Icon }, ref) { - const iconRef = useRef(null); - const pulseRef = useRef(null); - const tlRef = useRef(null); - - 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; - - // IDLE: Subjugated/Ghost state - gsap.set(pixels, { - opacity: 0.15, - scale: 0.8, - transformOrigin: "left bottom", - }); - 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() * (BRAILLE_FRAMES.length - 1), - ); - pulseEl.innerText = BRAILLE_FRAMES[frameIndex]; - }, - ease: "none", - }) - // 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, - ease: "back.out(3)", - }); - - const hoverTarget = iconRef.current?.closest(".group"); - if (!hoverTarget) { - return () => { - tlRef.current?.kill(); - }; - } - - const handlePointerEnter = () => tlRef.current?.play(); - const handlePointerLeave = () => tlRef.current?.reverse(); - hoverTarget.addEventListener("pointerenter", handlePointerEnter); - hoverTarget.addEventListener("pointerleave", handlePointerLeave); - - return () => { - hoverTarget.removeEventListener("pointerenter", handlePointerEnter); - hoverTarget.removeEventListener("pointerleave", handlePointerLeave); - tlRef.current?.kill(); - }; - }, []); - - return ( -
- {/* 5x5 Grid Mask */} -
-
- {FEATURE_GRID_KEYS.map((key) => ( -
- ))} -
-
- - {/* Pulse Shuffle Layer */} -
- {"\u2800\u2836\u2800"} -
- - {/* Feature Icon Layer */} -
- -
-
- ); -}); diff --git a/apps/website/components/features.jsx b/apps/website/components/features.jsx new file mode 100755 index 000000000..c5116c7dd --- /dev/null +++ b/apps/website/components/features.jsx @@ -0,0 +1,70 @@ +"use client"; +import { featuresData } from "@/app/constant"; +import { useRef } from "react"; +import { FeatureIconAnimation } from "./feature-icon-animation"; + +function FeatureCard({ feature }) { + const iconRef = useRef(null); + return ( +
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" + > +
+
+ {/* Hover Gradient Overlay */} +
+ +
+ +
+ +
+
+

+ {feature.title} +

+

+ {feature.description} +

+
+
+
+ ); +} + +export default function Features() { + return ( +
+
+

+
Everything you need.
+
Nothing you have to build.
+

+
+ Eight features that eliminate your entire{" "} + + billing infrastructure, fully managed. + +
+
+ +
+
+ {featuresData.map((feature, i) => ( + + ))} +
+
+
+ ); +} diff --git a/apps/website/components/features.tsx b/apps/website/components/features.tsx deleted file mode 100755 index 5573ce4af..000000000 --- a/apps/website/components/features.tsx +++ /dev/null @@ -1,68 +0,0 @@ -"use client"; -import { useRef } from "react"; -import { featuresData } from "@/app/constant"; -import { FeatureIconAnimation } from "./feature-icon-animation"; -import type { FeatureItem, IconAnimationHandle } from "./website-types"; - -function FeatureCard({ feature }: { feature: FeatureItem }) { - return ( -
-
-
- {/* Hover Gradient Overlay */} -
- -
- -
- -
-
-

- {feature.title} -

-

- {feature.description} -

-
-
-
- ); -} - -export default function Features() { - return ( -
-
-

-
Everything you need.
-
Nothing you have to build.
-

-
- Eight features that eliminate your entire{" "} - - billing infrastructure, fully managed. - -
-
- -
-
- {featuresData.map((feature) => ( - - ))} -
-
-
- ); -} diff --git a/apps/website/components/footer.jsx b/apps/website/components/footer.jsx new file mode 100755 index 000000000..993c949f1 --- /dev/null +++ b/apps/website/components/footer.jsx @@ -0,0 +1,181 @@ +import Image from "next/image"; +import Link from "next/link"; + +const footerColumns = [ + { + title: "PRODUCT", + links: [ + { label: "FEATURES", href: "#" }, + { label: "INTEGRATIONS", href: "#" }, + { label: "PRICING", href: "#" }, + { label: "CHANGELOG", href: "#" }, + { label: "ROADMAP", href: "#" }, + ], + }, + { + title: "COMPANY", + links: [ + { label: "OUR TEAM", href: "#" }, + { label: "OUR VALUES", href: "/privacy" }, + { label: "BLOG", href: "https://useautumn.com/blog" }, + ], + }, + { + title: "RESOURCES", + links: [ + { label: "DOWNLOADS", href: "https://useautumn.com/" }, + { label: "DOCUMENTATION", href: "https://docs.useautumn.com/welcome" }, + { label: "CONTACT", href: "https://cal.com/ayrod/a?user=ayrod" }, + ], + }, +]; + +export default function Footer() { + return ( + <> +
+
+
+
+ +
+ {/* Left Side: Logo and Description */} +
+ + Autumn + +

+ Autumn is built on top of Stripe Billing (for now), so their + fees (0.7%, and 2.9% + 30c) still apply. +

+
+ + {/* Right Side: Columns */} +
+ {footerColumns.map((col, index) => ( +
+

+
+ {col.title} +

+
    + {col.links.map((link, i) => ( +
  • + + + + + + {link.label} + + + + +
  • + ))} +
+
+ ))} +
+
+
+ +
+
+ {/* Social Left Box */} +
+
+ SOCIAL +
+
+ + + + LINKEDIN + + + + +
+ + + + TWITTER + + + + +
+
+ +
+ Copyright © 2026 Autumn All rights reserved +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + ); +} diff --git a/apps/website/components/footer.tsx b/apps/website/components/footer.tsx deleted file mode 100755 index cd229487f..000000000 --- a/apps/website/components/footer.tsx +++ /dev/null @@ -1,181 +0,0 @@ -import Image from "next/image"; -import Link from "next/link"; - -const footerColumns = [ - { - title: "PRODUCT", - links: [ - { label: "FEATURES", href: "#" }, - { label: "INTEGRATIONS", href: "#" }, - { label: "PRICING", href: "#" }, - { label: "CHANGELOG", href: "#" }, - { label: "ROADMAP", href: "#" }, - ], - }, - { - title: "COMPANY", - links: [ - { label: "OUR TEAM", href: "#" }, - { label: "OUR VALUES", href: "/privacy" }, - { label: "BLOG", href: "https://useautumn.com/blog" }, - ], - }, - { - title: "RESOURCES", - links: [ - { label: "DOWNLOADS", href: "https://useautumn.com/" }, - { label: "DOCUMENTATION", href: "https://docs.useautumn.com/welcome" }, - { label: "CONTACT", href: "https://cal.com/ayrod/a?user=ayrod" }, - ], - }, -]; - -export default function Footer() { - return ( - <> -
-
-
-
- -
- {/* Left Side: Logo and Description */} -
- - Autumn - -

- Autumn is built on top of Stripe Billing (for now), so their - fees (0.7%, and 2.9% + 30c) still apply. -

-
- - {/* Right Side: Columns */} -
- {footerColumns.map((col, index) => ( -
-

-
- {col.title} -

-
    - {col.links.map((link, i) => ( -
  • - - - - - - {link.label} - - - - -
  • - ))} -
-
- ))} -
-
-
- -
-
- {/* Social Left Box */} -
-
- SOCIAL -
-
- - - - LINKEDIN - - - - -
- - - - TWITTER - - - - -
-
- -
- Copyright © 2026 Autumn All rights reserved -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- - ); -} diff --git a/apps/website/components/hero.jsx b/apps/website/components/hero.jsx new file mode 100755 index 000000000..f1ea3e2c6 --- /dev/null +++ b/apps/website/components/hero.jsx @@ -0,0 +1,282 @@ +"use client"; + +import { CTALines, IconCTADocs, IconCTAStart } from "@/app/constant"; +import { useGSAP } from "@gsap/react"; +import gsap from "gsap"; +import { motion } from "motion/react"; +import Image from "next/image"; +import Link from "next/link"; +import { useEffect, useRef, useState } from "react"; +import AutumnConfig from "./autumn-config"; +// import dynamic from "next/dynamic"; + +// const AutumnConfig = dynamic(() => import("./autumn-config"), { ssr: false }); + +const BADGE_TEXT = "// billing infrastructure for ai"; + +export default function Hero() { + const containerRef = useRef(null); + const heroTlRef = useRef(null); + const [displayedText, setDisplayedText] = useState(""); + + // Badge typewriter + useEffect(() => { + const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*0123456789"; + let intervalId; + let timeoutId; + + const startTypewriter = () => { + timeoutId = setTimeout(() => { + let iteration = 0; + intervalId = setInterval(() => { + setDisplayedText( + BADGE_TEXT.split("") + .map((char, index) => { + if (char === " ") return " "; + if (index < Math.floor(iteration)) return char; + if (index === Math.floor(iteration)) + return chars[Math.floor(Math.random() * chars.length)]; + return ""; + }) + .join(""), + ); + + iteration += 0.4; + + if (iteration >= BADGE_TEXT.length) { + clearInterval(intervalId); + setDisplayedText(BADGE_TEXT); + } + }, 30); + }, 150); + }; + + window.addEventListener("preloader:complete", startTypewriter, { + once: true, + }); + return () => { + window.removeEventListener("preloader:complete", startTypewriter); + clearTimeout(timeoutId); + clearInterval(intervalId); + }; + }, []); + + useEffect(() => { + const handler = () => heroTlRef.current?.play(); + window.addEventListener("preloader:complete", handler, { once: true }); + return () => window.removeEventListener("preloader:complete", handler); + }, []); + + useGSAP( + () => { + gsap.set(".hero-root", { opacity: 0 }); + + gsap.set(".hero-bg", { + opacity: 0, + filter: "blur(6px) brightness(1)", + scale: 0.97, + transformOrigin: "center top", + }); + + gsap.set(".hero-reveal", { + opacity: 0, + y: 25, + filter: "blur(12px)", + scale: 0.96, + transformOrigin: "center bottom", + }); + + gsap.set(".hero-cta", { opacity: 0, scale: 0.95 }); + + const tl = gsap.timeline({ + paused: true, + defaults: { overwrite: "auto" }, + }); + heroTlRef.current = tl; + + tl.to(".hero-root", { opacity: 1, duration: 0.3, ease: "none" }) + + .to(".hero-bg", { + opacity: 1, + filter: "blur(0px) brightness(1)", + scale: 1, + duration: 0.4, + ease: "power2.out", + }) + + .to(".hero-bg", { + filter: "blur(0px) brightness(1.6)", + duration: 0.125, + ease: "power2.in", + }) + + .to(".hero-bg", { + filter: "blur(0px) brightness(1)", + duration: 0.125, + ease: "power2.out", + }) + + .to( + ".hero-reveal", + { + opacity: 1, + y: 0, + filter: "blur(0px)", + scale: 1, + duration: 1.1, + stagger: 0.1, + ease: "power3.out", + }, + "-=0.2", + ) + + .to( + ".hero-cta", + { + opacity: 1, + scale: 1, + duration: 0.3, + stagger: 0.06, + ease: "back.out(1.5)", + }, + "-=0.1", + ); + }, + { scope: containerRef }, + ); + + return ( +
+
+
+ hero-bg +
+ +
+
+ +
+

+ + + {displayedText} + +

+
+

+ + The drop-in billing layer for + {" "} + AI startups +

+

+ Stop rebuilding usage limits, credit systems, and subscription + logic.{" "} + + Autumn is the source of truth + {" "} + that keeps webhooks, payments and usage perfectly in-sync. +

+
+
+ +
+
+ {/* Primary CTA */} +
+ + + {/* Adjusted px-3 for mobile, md:px-4 for desktop */} +
+ + + Start for free + + + + +
+
+ +
+ + {/* Secondary CTA */} +
+ + +
+ + + Read docs + + + + +
+
+ +
+ +
+
+
+
+ +
+
+
+
+
+
+
+
+
+ {/* MOBILE VIEW*/} +
+
+ hero-bg-mobile + +
+ {/* */} + xyz +
+
+
+
+
+ ); +} diff --git a/apps/website/components/hero.tsx b/apps/website/components/hero.tsx deleted file mode 100755 index ab7a9b760..000000000 --- a/apps/website/components/hero.tsx +++ /dev/null @@ -1,283 +0,0 @@ -"use client"; - -import { useGSAP } from "@gsap/react"; -import gsap from "gsap"; -import { motion } from "motion/react"; -import Image from "next/image"; -import Link from "next/link"; -import { useEffect, useRef, useState } from "react"; -import { CTALines, IconCTADocs, IconCTAStart } from "@/app/constant"; -import AutumnConfig from "./autumn-config"; - -// import dynamic from "next/dynamic"; - -// const AutumnConfig = dynamic(() => import("./autumn-config"), { ssr: false }); - -const BADGE_TEXT = "// billing infrastructure for ai"; - -export default function Hero() { - const containerRef = useRef(null); - const heroTlRef = useRef(null); - const [displayedText, setDisplayedText] = useState(""); - - // Badge typewriter - useEffect(() => { - const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*0123456789"; - let intervalId: ReturnType | null = null; - let timeoutId: ReturnType | null = null; - - const startTypewriter = () => { - timeoutId = setTimeout(() => { - let iteration = 0; - intervalId = setInterval(() => { - setDisplayedText( - BADGE_TEXT.split("") - .map((char, index) => { - if (char === " ") return " "; - if (index < Math.floor(iteration)) return char; - if (index === Math.floor(iteration)) - return chars[Math.floor(Math.random() * chars.length)]; - return ""; - }) - .join(""), - ); - - iteration += 0.4; - - if (iteration >= BADGE_TEXT.length) { - if (intervalId) clearInterval(intervalId); - setDisplayedText(BADGE_TEXT); - } - }, 30); - }, 150); - }; - - window.addEventListener("preloader:complete", startTypewriter, { - once: true, - }); - return () => { - window.removeEventListener("preloader:complete", startTypewriter); - if (timeoutId) clearTimeout(timeoutId); - if (intervalId) clearInterval(intervalId); - }; - }, []); - - useEffect(() => { - const handler = () => heroTlRef.current?.play(); - window.addEventListener("preloader:complete", handler, { once: true }); - return () => window.removeEventListener("preloader:complete", handler); - }, []); - - useGSAP( - () => { - gsap.set(".hero-root", { opacity: 0 }); - - gsap.set(".hero-bg", { - opacity: 0, - filter: "blur(6px) brightness(1)", - scale: 0.97, - transformOrigin: "center top", - }); - - gsap.set(".hero-reveal", { - opacity: 0, - y: 25, - filter: "blur(12px)", - scale: 0.96, - transformOrigin: "center bottom", - }); - - gsap.set(".hero-cta", { opacity: 0, scale: 0.95 }); - - const tl = gsap.timeline({ - paused: true, - defaults: { overwrite: "auto" }, - }); - heroTlRef.current = tl; - - tl.to(".hero-root", { opacity: 1, duration: 0.3, ease: "none" }) - - .to(".hero-bg", { - opacity: 1, - filter: "blur(0px) brightness(1)", - scale: 1, - duration: 0.4, - ease: "power2.out", - }) - - .to(".hero-bg", { - filter: "blur(0px) brightness(1.6)", - duration: 0.125, - ease: "power2.in", - }) - - .to(".hero-bg", { - filter: "blur(0px) brightness(1)", - duration: 0.125, - ease: "power2.out", - }) - - .to( - ".hero-reveal", - { - opacity: 1, - y: 0, - filter: "blur(0px)", - scale: 1, - duration: 1.1, - stagger: 0.1, - ease: "power3.out", - }, - "-=0.2", - ) - - .to( - ".hero-cta", - { - opacity: 1, - scale: 1, - duration: 0.3, - stagger: 0.06, - ease: "back.out(1.5)", - }, - "-=0.1", - ); - }, - { scope: containerRef }, - ); - - return ( -
-
-
- hero-bg -
- -
-
- -
-

- - - {displayedText} - -

-
-

- - The drop-in billing layer for - {" "} - AI startups -

-

- Stop rebuilding usage limits, credit systems, and subscription - logic.{" "} - - Autumn is the source of truth - {" "} - that keeps webhooks, payments and usage perfectly in-sync. -

-
-
- -
-
- {/* Primary CTA */} -
- - - {/* Adjusted px-3 for mobile, md:px-4 for desktop */} -
- - - Start for free - - - - -
-
- -
- - {/* Secondary CTA */} -
- - -
- - - Read docs - - - - -
-
- -
- -
-
-
-
- -
-
-
-
-
-
-
-
-
- {/* MOBILE VIEW*/} -
-
- hero-bg-mobile - -
- {/* */} - xyz -
-
-
-
-
- ); -} diff --git a/apps/website/components/home-sections.tsx b/apps/website/components/home-sections.jsx similarity index 56% rename from apps/website/components/home-sections.tsx rename to apps/website/components/home-sections.jsx index d6900e0e5..4ee195814 100755 --- a/apps/website/components/home-sections.tsx +++ b/apps/website/components/home-sections.jsx @@ -1,46 +1,46 @@ -"use client"; - -import dynamic from "next/dynamic"; -import Hero from "./hero"; -import SectionDivider from "./section-divider"; - -const ProductionScale = dynamic(() => import("@/components/production-scale"), { - ssr: false, -}); -const Problem = dynamic(() => import("@/components/problem"), { ssr: false }); -const Solution = dynamic(() => import("@/components/solution"), { ssr: false }); -const Features = dynamic(() => import("@/components/features"), { ssr: false }); -const PricingModels = dynamic(() => import("@/components/pricing-models"), { - ssr: false, -}); -const Testimonials = dynamic(() => import("@/components/testimonials"), { - ssr: false, -}); -const Pricing = dynamic(() => import("@/components/pricing"), { ssr: false }); -const FAQ = dynamic(() => import("@/components/faq"), { ssr: false }); -const Footer = dynamic(() => import("@/components/footer"), { ssr: false }); - -export default function HomeSections() { - return ( - <> - - - - - - - - - - - - - - - - - -