From 453305223e1bc347d4a96aa2ea8de5a7cfb766a7 Mon Sep 17 00:00:00 2001 From: kudinDmitriyUp Date: Wed, 15 Apr 2026 12:16:08 +0000 Subject: [PATCH] Initial commit --- .env | 4 + .gitea/workflows/build.yml | 46 + .gitignore | 24 + THEME_PROVIDER_OPTIONS.txt | 58 + colorThemes.json | 677 +++++ cssOptions.json | 41 + eslint.config.js | 26 + fontThemes.json | 237 ++ index.html | 13 + package.json | 40 + pnpm-lock.yaml | 2228 +++++++++++++++++ public/favicon.svg | 1 + registry.json | 1010 ++++++++ src/App.tsx | 272 ++ .../sections/about/AboutTextSplit.tsx | 56 + .../sections/contact/ContactCta.tsx | 47 + .../sections/features/FeaturesFlipCards.tsx | 118 + .../sections/footer/FooterBrandReveal.tsx | 101 + src/components/sections/hero/HeroSplit.tsx | 64 + .../pricing/PricingHighlightedCards.tsx | 105 + .../testimonial/TestimonialMetricsCards.tsx | 126 + src/components/ui/AnimatedBarChart.tsx | 46 + src/components/ui/AutoFillText.tsx | 67 + src/components/ui/Button.tsx | 44 + src/components/ui/ChatMarquee.tsx | 43 + src/components/ui/ChecklistTimeline.tsx | 47 + src/components/ui/GridOrCarousel.tsx | 64 + src/components/ui/HoverPattern.tsx | 61 + src/components/ui/IconTextMarquee.tsx | 27 + src/components/ui/ImageOrVideo.tsx | 41 + src/components/ui/InfoCardMarquee.tsx | 27 + src/components/ui/LoopCarousel.tsx | 76 + src/components/ui/MediaStack.tsx | 32 + src/components/ui/NavbarCentered.tsx | 122 + src/components/ui/OrbitingIcons.tsx | 30 + src/components/ui/TextAnimation.tsx | 60 + src/components/ui/TiltedStackCards.tsx | 28 + src/components/ui/Transition.tsx | 37 + src/hooks/useButtonClick.ts | 51 + src/hooks/useCarouselControls.ts | 45 + src/index.css | 181 ++ src/lib/utils.ts | 10 + src/main.tsx | 13 + src/styles/animations.css | 158 ++ src/styles/masks.css | 61 + src/vite-env.d.ts | 3 + tsconfig.app.json | 27 + tsconfig.json | 7 + tsconfig.node.json | 24 + vercel.json | 10 + vite.config.ts | 18 + 51 files changed, 6754 insertions(+) create mode 100644 .env create mode 100644 .gitea/workflows/build.yml create mode 100644 .gitignore create mode 100644 THEME_PROVIDER_OPTIONS.txt create mode 100644 colorThemes.json create mode 100644 cssOptions.json create mode 100644 eslint.config.js create mode 100644 fontThemes.json create mode 100644 index.html create mode 100644 package.json create mode 100644 pnpm-lock.yaml create mode 100644 public/favicon.svg create mode 100644 registry.json create mode 100644 src/App.tsx create mode 100644 src/components/sections/about/AboutTextSplit.tsx create mode 100644 src/components/sections/contact/ContactCta.tsx create mode 100644 src/components/sections/features/FeaturesFlipCards.tsx create mode 100644 src/components/sections/footer/FooterBrandReveal.tsx create mode 100644 src/components/sections/hero/HeroSplit.tsx create mode 100644 src/components/sections/pricing/PricingHighlightedCards.tsx create mode 100644 src/components/sections/testimonial/TestimonialMetricsCards.tsx create mode 100644 src/components/ui/AnimatedBarChart.tsx create mode 100644 src/components/ui/AutoFillText.tsx create mode 100644 src/components/ui/Button.tsx create mode 100644 src/components/ui/ChatMarquee.tsx create mode 100644 src/components/ui/ChecklistTimeline.tsx create mode 100644 src/components/ui/GridOrCarousel.tsx create mode 100644 src/components/ui/HoverPattern.tsx create mode 100644 src/components/ui/IconTextMarquee.tsx create mode 100644 src/components/ui/ImageOrVideo.tsx create mode 100644 src/components/ui/InfoCardMarquee.tsx create mode 100644 src/components/ui/LoopCarousel.tsx create mode 100644 src/components/ui/MediaStack.tsx create mode 100644 src/components/ui/NavbarCentered.tsx create mode 100644 src/components/ui/OrbitingIcons.tsx create mode 100644 src/components/ui/TextAnimation.tsx create mode 100644 src/components/ui/TiltedStackCards.tsx create mode 100644 src/components/ui/Transition.tsx create mode 100644 src/hooks/useButtonClick.ts create mode 100644 src/hooks/useCarouselControls.ts create mode 100644 src/index.css create mode 100644 src/lib/utils.ts create mode 100644 src/main.tsx create mode 100644 src/styles/animations.css create mode 100644 src/styles/masks.css create mode 100644 src/vite-env.d.ts create mode 100644 tsconfig.app.json create mode 100644 tsconfig.json create mode 100644 tsconfig.node.json create mode 100644 vercel.json create mode 100644 vite.config.ts diff --git a/.env b/.env new file mode 100644 index 0000000..35853b1 --- /dev/null +++ b/.env @@ -0,0 +1,4 @@ + + NEXT_PUBLIC_API_URL=https://dev.api.webild.io + NEXT_PUBLIC_PROJECT_ID=4d070abf-ca94-44bb-b333-e8a4e6214b03 + \ No newline at end of file diff --git a/.gitea/workflows/build.yml b/.gitea/workflows/build.yml new file mode 100644 index 0000000..a5ace31 --- /dev/null +++ b/.gitea/workflows/build.yml @@ -0,0 +1,46 @@ +name: Code Check + +on: + workflow_dispatch: + +jobs: + check: + runs-on: ubuntu-latest + + steps: + - name: Checkout + run: git clone --depth 1 --branch ${{ gitea.ref_name }} ${{ gitea.server_url }}/${{ gitea.repository }}.git . || exit 1 + + - name: Install dependencies + run: | + if [ -f "vite.config.ts" ]; then + if [ -d "/var/node_modules_cache_v4/node_modules" ]; then + ln -s /var/node_modules_cache_v4/node_modules ./node_modules + elif [ -f "pnpm-lock.yaml" ]; then + npm install -g pnpm --silent + pnpm install --frozen-lockfile + else + npm ci --prefer-offline --no-audit + fi + elif [ -d "/var/node_modules_cache/node_modules" ]; then + ln -s /var/node_modules_cache/node_modules ./node_modules + else + npm ci --prefer-offline --no-audit + fi + timeout-minutes: 5 + + - name: TypeScript check + run: npm run typecheck 2>&1 | tee build.log + timeout-minutes: 3 + + - name: ESLint check + run: npm run lint 2>&1 | tee -a build.log + timeout-minutes: 3 + + - name: Upload build log on failure + if: failure() + uses: actions/upload-artifact@v3 + with: + name: build-log + path: build.log + retention-days: 1 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a547bf3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/THEME_PROVIDER_OPTIONS.txt b/THEME_PROVIDER_OPTIONS.txt new file mode 100644 index 0000000..6edb716 --- /dev/null +++ b/THEME_PROVIDER_OPTIONS.txt @@ -0,0 +1,58 @@ +================================================================================ + THEME OPTIONS (v4) +================================================================================ + +STYLE PROPS +----------- + +1. borderRadius + • "rounded" + • "soft" + • "pill" + +2. contentWidth + • "small" + • "compact" + • "medium" + • "mediumLarge" + +3. cardStyle + • "solid" + • "outline" + • "gradient-mesh" + • "gradient-radial" + • "inset" + • "glass-elevated" + • "glass-depth" + • "gradient-bordered" + • "layered-gradient" + • "soft-shadow" + • "subtle-shadow" + • "elevated-border" + • "inner-glow" + • "spotlight" + +4. primaryButtonStyle + • "gradient" + • "shadow" + • "flat" + • "radial-glow" + • "diagonal-gradient" + • "double-inset" + • "primary-glow" + • "inset-glow" + • "soft-glow" + • "glass-shimmer" + • "neon-outline" + • "lifted" + • "depth-layers" + • "accent-edge" + • "metallic" + +5. secondaryButtonStyle + • "glass" + • "solid" + • "layered" + • "radial-glow" + +================================================================================ diff --git a/colorThemes.json b/colorThemes.json new file mode 100644 index 0000000..2e4fccc --- /dev/null +++ b/colorThemes.json @@ -0,0 +1,677 @@ +{ + "lightTheme": { + "minimalDarkBlue": { + "--background": "#ffffff", + "--card": "#f9f9f9", + "--foreground": "#000612e6", + "--primary-cta": "#15479c", + "--secondary-cta": "#f9f9f9", + "--accent": "#e2e2e2", + "--background-accent": "#c4c4c4", + "--primary-cta-text": "#ffffff", + "--secondary-cta-text": "#000612e6" + }, + "minimalDarkGreen": { + "--background": "#ffffff", + "--card": "#f9f9f9", + "--foreground": "#000f06e6", + "--primary-cta": "#0a7039", + "--secondary-cta": "#f9f9f9", + "--accent": "#e2e2e2", + "--background-accent": "#c4c4c4", + "--primary-cta-text": "#ffffff", + "--secondary-cta-text": "#000f06e6" + }, + "minimalLightRed": { + "--background": "#ffffff", + "--card": "#f9f9f9", + "--foreground": "#120006e6", + "--primary-cta": "#e63946", + "--secondary-cta": "#f9f9f9", + "--accent": "#e2e2e2", + "--background-accent": "#c4c4c4", + "--primary-cta-text": "#ffffff", + "--secondary-cta-text": "#120006e6" + }, + "minimalBrightBlue": { + "--background": "#ffffff", + "--card": "#f9f9f9", + "--foreground": "#000612e6", + "--primary-cta": "#106EFB", + "--secondary-cta": "#f9f9f9", + "--accent": "#e2e2e2", + "--background-accent": "#106EFB", + "--primary-cta-text": "#ffffff", + "--secondary-cta-text": "#000612e6" + }, + "minimalBrightOrange": { + "--background": "#ffffff", + "--card": "#f9f9f9", + "--foreground": "#120a00e6", + "--primary-cta": "#E34400", + "--secondary-cta": "#f9f9f9", + "--accent": "#e2e2e2", + "--background-accent": "#E34400", + "--primary-cta-text": "#ffffff", + "--secondary-cta-text": "#120a00e6" + }, + "minimalGoldenOrange": { + "--background": "#ffffff", + "--card": "#f9f9f9", + "--foreground": "#120a00e6", + "--primary-cta": "#FF7B05", + "--secondary-cta": "#f9f9f9", + "--accent": "#e2e2e2", + "--background-accent": "#FF7B05", + "--primary-cta-text": "#ffffff", + "--secondary-cta-text": "#120a00e6" + }, + "minimalLightOrange": { + "--background": "#ffffff", + "--card": "#f9f9f9", + "--foreground": "#120a00e6", + "--primary-cta": "#ff8c42", + "--secondary-cta": "#f9f9f9", + "--accent": "#e2e2e2", + "--background-accent": "#c4c4c4", + "--primary-cta-text": "#ffffff", + "--secondary-cta-text": "#120a00e6" + }, + "darkBlue": { + "--background": "#f5faff", + "--card": "#f1f8ff", + "--foreground": "#001122", + "--primary-cta": "#15479c", + "--secondary-cta": "#ffffff", + "--accent": "#a8cce8", + "--background-accent": "#7ba3cf", + "--primary-cta-text": "#f5faff", + "--secondary-cta-text": "#001122" + }, + "darkGreen": { + "--background": "#fafffb", + "--card": "#f7fffa", + "--foreground": "#001a0a", + "--primary-cta": "#0a7039", + "--secondary-cta": "#ffffff", + "--accent": "#a8d9be", + "--background-accent": "#6bbf8e", + "--primary-cta-text": "#fafffb", + "--secondary-cta-text": "#001a0a" + }, + "lightRed": { + "--background": "#fffafa", + "--card": "#fff7f7", + "--foreground": "#1a0000", + "--primary-cta": "#e63946", + "--secondary-cta": "#ffffff", + "--accent": "#f5c4c7", + "--background-accent": "#f09199", + "--primary-cta-text": "#fffafa", + "--secondary-cta-text": "#1a0000" + }, + "lightPurple": { + "--background": "#fbfaff", + "--card": "#f7f5ff", + "--foreground": "#0f0022", + "--primary-cta": "#8b5cf6", + "--secondary-cta": "#ffffff", + "--accent": "#d8cef5", + "--background-accent": "#c4a8f9", + "--primary-cta-text": "#fbfaff", + "--secondary-cta-text": "#0f0022" + }, + "warmCream": { + "--background": "#f6f0e9", + "--card": "#efe7dd", + "--foreground": "#2b180a", + "--primary-cta": "#2b180a", + "--secondary-cta": "#efe7dd", + "--accent": "#94877c", + "--background-accent": "#afa094", + "--primary-cta-text": "#f6f0e9", + "--secondary-cta-text": "#2b180a" + }, + "grayBlueAccent": { + "--background": "#f5f5f5", + "--card": "#ffffff", + "--foreground": "#1c1c1c", + "--primary-cta": "#1c1c1c", + "--secondary-cta": "#ffffff", + "--accent": "#15479c", + "--background-accent": "#a8cce8", + "--primary-cta-text": "#f5f5f5", + "--secondary-cta-text": "#1c1c1c" + }, + "grayGreenAccent": { + "--background": "#f5f5f5", + "--card": "#ffffff", + "--foreground": "#1c1c1c", + "--primary-cta": "#1c1c1c", + "--secondary-cta": "#ffffff", + "--accent": "#159c49", + "--background-accent": "#a8e8ba", + "--primary-cta-text": "#f5f5f5", + "--secondary-cta-text": "#1c1c1c" + }, + "grayRedAccent": { + "--background": "#f5f5f5", + "--card": "#ffffff", + "--foreground": "#1c1c1c", + "--primary-cta": "#1c1c1c", + "--secondary-cta": "#ffffff", + "--accent": "#e63946", + "--background-accent": "#e8bea8", + "--primary-cta-text": "#f5f5f5", + "--secondary-cta-text": "#1c1c1c" + }, + "grayPurpleAccent": { + "--background": "#f5f5f5", + "--card": "#ffffff", + "--foreground": "#1c1c1c", + "--primary-cta": "#1c1c1c", + "--secondary-cta": "#ffffff", + "--accent": "#6139e6", + "--background-accent": "#b3a8e8", + "--primary-cta-text": "#f5f5f5", + "--secondary-cta-text": "#1c1c1c" + }, + "warmBeige": { + "--background": "#efebe5", + "--card": "#f7f2ea", + "--foreground": "#000000", + "--primary-cta": "#000000", + "--secondary-cta": "#ffffff", + "--accent": "#ffffff", + "--background-accent": "#e1b875", + "--primary-cta-text": "#efebe5", + "--secondary-cta-text": "#000000" + }, + "grayTealGreen": { + "--background": "#f5f5f5", + "--card": "#ffffff", + "--foreground": "#1c1c1c", + "--primary-cta": "#1f514c", + "--secondary-cta": "#ffffff", + "--accent": "#159c49", + "--background-accent": "#a8e8ba", + "--primary-cta-text": "#f5f5f5", + "--secondary-cta-text": "#1c1c1c" + }, + "grayNavyBlue": { + "--background": "#f5f5f5", + "--card": "#ffffff", + "--foreground": "#1c1c1c", + "--primary-cta": "#1f3251", + "--secondary-cta": "#ffffff", + "--accent": "#15479c", + "--background-accent": "#a8cce8", + "--primary-cta-text": "#f5f5f5", + "--secondary-cta-text": "#1c1c1c" + }, + "grayBurgundyRed": { + "--background": "#f5f5f5", + "--card": "#ffffff", + "--foreground": "#1c1c1c", + "--primary-cta": "#511f1f", + "--secondary-cta": "#ffffff", + "--accent": "#e63946", + "--background-accent": "#e8bea8", + "--primary-cta-text": "#f5f5f5", + "--secondary-cta-text": "#1c1c1c" + }, + "grayIndigoPurple": { + "--background": "#f5f5f5", + "--card": "#ffffff", + "--foreground": "#1c1c1c", + "--primary-cta": "#341f51", + "--secondary-cta": "#ffffff", + "--accent": "#6139e6", + "--background-accent": "#b3a8e8", + "--primary-cta-text": "#f5f5f5", + "--secondary-cta-text": "#1c1c1c" + }, + "warmgrayPink": { + "--background": "#f7f6f7", + "--card": "#ffffff", + "--foreground": "#1b0c25", + "--primary-cta": "#1b0c25", + "--secondary-cta": "#ffffff", + "--accent": "#ff93e4", + "--background-accent": "#e8a8c3", + "--primary-cta-text": "#f7f6f7", + "--secondary-cta-text": "#1b0c25" + }, + "warmgrayOrange": { + "--background": "#f7f6f7", + "--card": "#ffffff", + "--foreground": "#25190c", + "--primary-cta": "#ff6207", + "--secondary-cta": "#ffffff", + "--accent": "#ffce93", + "--background-accent": "#e8cfa8", + "--primary-cta-text": "#f7f6f7", + "--secondary-cta-text": "#25190c" + }, + "warmgrayBlue": { + "--background": "#f7f6f7", + "--card": "#ffffff", + "--foreground": "#0c1325", + "--primary-cta": "#0798ff", + "--secondary-cta": "#ffffff", + "--accent": "#93c7ff", + "--background-accent": "#a8cde8", + "--primary-cta-text": "#f7f6f7", + "--secondary-cta-text": "#0c1325" + }, + "warmgrayIndigo": { + "--background": "#f7f6f7", + "--card": "#ffffff", + "--foreground": "#0c1325", + "--primary-cta": "#0b07ff", + "--secondary-cta": "#ffffff", + "--accent": "#93b7ff", + "--background-accent": "#a8bae8", + "--primary-cta-text": "#f7f6f7", + "--secondary-cta-text": "#0c1325" + }, + "lavenderPeach": { + "--background": "#e3deea", + "--card": "#ffffff", + "--foreground": "#27231f", + "--primary-cta": "#27231f", + "--secondary-cta": "#ffffff", + "--accent": "#c68a62", + "--background-accent": "#c68a62", + "--primary-cta-text": "#e3deea", + "--secondary-cta-text": "#27231f" + }, + "lavenderBlue": { + "--background": "#e3deea", + "--card": "#ffffff", + "--foreground": "#1f2027", + "--primary-cta": "#1f2027", + "--secondary-cta": "#ffffff", + "--accent": "#627dc6", + "--background-accent": "#627dc6", + "--primary-cta-text": "#e3deea", + "--secondary-cta-text": "#1f2027" + }, + "warmStone": { + "--background": "#f5f4ef", + "--card": "#dad6cd", + "--foreground": "#2a2928", + "--primary-cta": "#2a2928", + "--secondary-cta": "#ecebea", + "--accent": "#ffffff", + "--background-accent": "#c6b180", + "--primary-cta-text": "#f5f4ef", + "--secondary-cta-text": "#2a2928" + }, + "warmStoneGray": { + "--background": "#f5f4f0", + "--card": "#ffffff", + "--foreground": "#1a1a1a", + "--primary-cta": "#2c2c2c", + "--secondary-cta": "#f5f4f0", + "--accent": "#8a8a8a", + "--background-accent": "#e8e6e1", + "--primary-cta-text": "#f5f4f0", + "--secondary-cta-text": "#1a1a1a" + }, + "warmGreen": { + "--background": "#fffefe", + "--card": "#f6f7f4", + "--foreground": "#080908", + "--primary-cta": "#0e3a29", + "--secondary-cta": "#e7eecd", + "--accent": "#35c18b", + "--background-accent": "#ecebe4", + "--primary-cta-text": "#fffefe", + "--secondary-cta-text": "#080908" + }, + "warmSand": { + "--background": "#fcf6ec", + "--card": "#f3ede2", + "--foreground": "#2e2521", + "--primary-cta": "#2e2521", + "--secondary-cta": "#ffffff", + "--accent": "#b2a28b", + "--background-accent": "#b2a28b", + "--primary-cta-text": "#fcf6ec", + "--secondary-cta-text": "#2e2521" + }, + "warmgrayRed": { + "--background": "#f7f6f7", + "--card": "#ffffff", + "--foreground": "#250c0d", + "--primary-cta": "#b82b40", + "--secondary-cta": "#ffffff", + "--accent": "#b90941", + "--background-accent": "#e8a8b6", + "--primary-cta-text": "#f7f6f7", + "--secondary-cta-text": "#250c0d" + } + }, + "darkTheme": { + "minimal": { + "--background": "#0a0a0a", + "--card": "#1a1a1a", + "--foreground": "#ffffffe6", + "--primary-cta": "#e6e6e6", + "--secondary-cta": "#1a1a1a", + "--accent": "#737373", + "--background-accent": "#737373", + "--primary-cta-text": "#0a0a0a", + "--secondary-cta-text": "#ffffffe6" + }, + "minimalLightBlue": { + "--background": "#0a0a0a", + "--card": "#1a1a1a", + "--foreground": "#f0f8ffe6", + "--primary-cta": "#cee7ff", + "--secondary-cta": "#1a1a1a", + "--accent": "#737373", + "--background-accent": "#737373", + "--primary-cta-text": "#0a0a0a", + "--secondary-cta-text": "#f0f8ffe6" + }, + "minimalLightGreen": { + "--background": "#0a0a0a", + "--card": "#1a1a1a", + "--foreground": "#f5fffae6", + "--primary-cta": "#80da9b", + "--secondary-cta": "#1a1a1a", + "--accent": "#737373", + "--background-accent": "#737373", + "--primary-cta-text": "#0a0a0a", + "--secondary-cta-text": "#f5fffae6" + }, + "minimalLightRed": { + "--background": "#0a0a0a", + "--card": "#1a1a1a", + "--foreground": "#fff5f5e6", + "--primary-cta": "#ff7a7a", + "--secondary-cta": "#1a1a1a", + "--accent": "#737373", + "--background-accent": "#737373", + "--primary-cta-text": "#0a0a0a", + "--secondary-cta-text": "#fff5f5e6" + }, + "minimalLightPurple": { + "--background": "#0a0a0a", + "--card": "#1a1a1a", + "--foreground": "#f8f5ffe6", + "--primary-cta": "#c89bff", + "--secondary-cta": "#1a1a1a", + "--accent": "#737373", + "--background-accent": "#737373", + "--primary-cta-text": "#0a0a0a", + "--secondary-cta-text": "#f8f5ffe6" + }, + "lightBlueWhite": { + "--background": "#010912", + "--card": "#152840", + "--foreground": "#e6f0ff", + "--primary-cta": "#cee7ff", + "--secondary-cta": "#0e1a29", + "--accent": "#3f5c79", + "--background-accent": "#004a93", + "--primary-cta-text": "#010912", + "--secondary-cta-text": "#ffffff" + }, + "lime": { + "--background": "#0a0a0a", + "--card": "#1a1a1a", + "--foreground": "#f5f5f5", + "--primary-cta": "#dfff1c", + "--secondary-cta": "#1a1a1a", + "--accent": "#8b9a1b", + "--background-accent": "#5d6b00", + "--primary-cta-text": "#0a0a0a", + "--secondary-cta-text": "#ffffff" + }, + "gold": { + "--background": "#0a0a0a", + "--card": "#1a1a1a", + "--foreground": "#f5f5f5", + "--primary-cta": "#ffdf7d", + "--secondary-cta": "#1a1a1a", + "--accent": "#b8860b", + "--background-accent": "#8b6914", + "--primary-cta-text": "#0a0a0a", + "--secondary-cta-text": "#ffffff" + }, + "crimson": { + "--background": "#0a0a0a", + "--card": "#1a1a1a", + "--foreground": "#f5f5f5", + "--primary-cta": "#ff0000", + "--secondary-cta": "#1a1a1a", + "--accent": "#991b1b", + "--background-accent": "#7f1d1d", + "--primary-cta-text": "#ffffff", + "--secondary-cta-text": "#ffffff" + }, + "midnightIce": { + "--background": "#000000", + "--card": "#0c0c0c", + "--foreground": "#ffffff", + "--primary-cta": "#cee7ff", + "--secondary-cta": "#000000", + "--accent": "#535353", + "--background-accent": "#CEE7FF", + "--primary-cta-text": "#000000", + "--secondary-cta-text": "#ffffff" + }, + "midnightBlue": { + "--background": "#000000", + "--card": "#0c0c0c", + "--foreground": "#ffffff", + "--primary-cta": "#106EFB", + "--secondary-cta": "#000000", + "--accent": "#535353", + "--background-accent": "#106EFB", + "--primary-cta-text": "#ffffff", + "--secondary-cta-text": "#ffffff" + }, + "blueOrangeAccent": { + "--background": "#0a0a0a", + "--card": "#1a1a1a", + "--foreground": "#ffffff", + "--primary-cta": "#1f7cff", + "--secondary-cta": "#010101", + "--accent": "#1f7cff", + "--background-accent": "#f96b2f", + "--primary-cta-text": "#ffffff", + "--secondary-cta-text": "#ffffff" + }, + "orangeBlueAccent": { + "--background": "#0a0a0a", + "--card": "#1a1a1a", + "--foreground": "#ffffff", + "--primary-cta": "#e34400", + "--secondary-cta": "#010101", + "--accent": "#ff7b05", + "--background-accent": "#106efb", + "--primary-cta-text": "#ffffff", + "--secondary-cta-text": "#ffffff" + }, + "minimalBrightOrange": { + "--background": "#0a0a0a", + "--card": "#1a1a1a", + "--foreground": "#ffffff", + "--primary-cta": "#e34400", + "--secondary-cta": "#010101", + "--accent": "#737373", + "--background-accent": "#e34400", + "--primary-cta-text": "#ffffff", + "--secondary-cta-text": "#ffffff" + }, + "minimalLightOrange": { + "--background": "#0a0a0a", + "--card": "#1a1a1a", + "--foreground": "#fffaf5e6", + "--primary-cta": "#ffaa70", + "--secondary-cta": "#1a1a1a", + "--accent": "#737373", + "--background-accent": "#737373", + "--primary-cta-text": "#0a0a0a", + "--secondary-cta-text": "#fffaf5e6" + }, + "minimalLightYellow": { + "--background": "#0a0a0a", + "--card": "#1a1a1a", + "--foreground": "#fffffae6", + "--primary-cta": "#fde047", + "--secondary-cta": "#1a1a1a", + "--accent": "#737373", + "--background-accent": "#737373", + "--primary-cta-text": "#0a0a0a", + "--secondary-cta-text": "#fffffae6" + }, + "lightBlue": { + "--background": "#010912", + "--card": "#152840", + "--foreground": "#e6f0ff", + "--primary-cta": "#cee7ff", + "--secondary-cta": "#0e1a29", + "--accent": "#3f5c79", + "--background-accent": "#004a93", + "--primary-cta-text": "#010912", + "--secondary-cta-text": "#e6f0ff" + }, + "lightGreen": { + "--background": "#000802", + "--card": "#0b1a0b", + "--foreground": "#e6ffe6", + "--primary-cta": "#80da9b", + "--secondary-cta": "#07170b", + "--accent": "#38714a", + "--background-accent": "#2c6541", + "--primary-cta-text": "#000802", + "--secondary-cta-text": "#e6ffe6" + }, + "lightRed": { + "--background": "#080000", + "--card": "#1e0d0d", + "--foreground": "#ffe6e6", + "--primary-cta": "#ff7a7a", + "--secondary-cta": "#1e0909", + "--accent": "#7b4242", + "--background-accent": "#65292c", + "--primary-cta-text": "#080000", + "--secondary-cta-text": "#ffe6e6" + }, + "darkRed": { + "--background": "#060000", + "--card": "#1d0d0d", + "--foreground": "#ffe6e6", + "--primary-cta": "#ff3d4a", + "--secondary-cta": "#1f0a0a", + "--accent": "#7b2d2d", + "--background-accent": "#b8111f", + "--primary-cta-text": "#ffffff", + "--secondary-cta-text": "#ffe6e6" + }, + "lightPurple": { + "--background": "#050012", + "--card": "#040121", + "--foreground": "#f0e6ff", + "--primary-cta": "#c89bff", + "--secondary-cta": "#1d123b", + "--accent": "#684f7b", + "--background-accent": "#65417c", + "--primary-cta-text": "#050012", + "--secondary-cta-text": "#f0e6ff" + }, + "lightOrange": { + "--background": "#080200", + "--card": "#1a0d0b", + "--foreground": "#ffe6d5", + "--primary-cta": "#ffaa70", + "--secondary-cta": "#170b07", + "--accent": "#7b5e4a", + "--background-accent": "#b8541e", + "--primary-cta-text": "#080200", + "--secondary-cta-text": "#ffe6d5" + }, + "deepBlue": { + "--background": "#020617", + "--card": "#0f172a", + "--foreground": "#e2e8f0", + "--primary-cta": "#c4d8f9", + "--secondary-cta": "#041633", + "--accent": "#2d30f3", + "--background-accent": "#1d4ed8", + "--primary-cta-text": "#020617", + "--secondary-cta-text": "#e2e8f0" + }, + "violet": { + "--background": "#030128", + "--card": "#241f48", + "--foreground": "#ffffff", + "--primary-cta": "#ffffff", + "--secondary-cta": "#131136", + "--accent": "#44358a", + "--background-accent": "#b597fe", + "--primary-cta-text": "#030128", + "--secondary-cta-text": "#d5d4f6" + }, + "ruby": { + "--background": "#000000", + "--card": "#481f1f", + "--foreground": "#ffffff", + "--primary-cta": "#ffffff", + "--secondary-cta": "#361311", + "--accent": "#51000b", + "--background-accent": "#ff2231", + "--primary-cta-text": "#280101", + "--secondary-cta-text": "#f6d4d4" + }, + "emerald": { + "--background": "#000000", + "--card": "#1f4035", + "--foreground": "#ffffff", + "--primary-cta": "#ffffff", + "--secondary-cta": "#0d2b1f", + "--accent": "#0d5238", + "--background-accent": "#10b981", + "--primary-cta-text": "#051a12", + "--secondary-cta-text": "#d4f6e8" + }, + "indigo": { + "--background": "#000000", + "--card": "#1f1f40", + "--foreground": "#ffffff", + "--primary-cta": "#ffffff", + "--secondary-cta": "#0d0d2b", + "--accent": "#3d2880", + "--background-accent": "#663cff", + "--primary-cta-text": "#0a051a", + "--secondary-cta-text": "#d4d4f6" + }, + "forest": { + "--background": "#000000", + "--card": "#1a2f1d", + "--foreground": "#ffffff", + "--primary-cta": "#ffffff", + "--secondary-cta": "#0d200f", + "--accent": "#1a3d1f", + "--background-accent": "#355e3b", + "--primary-cta-text": "#0a1a0c", + "--secondary-cta-text": "#d4f6d8" + }, + "mint": { + "--background": "#000000", + "--card": "#1a2a1a", + "--foreground": "#ffffff", + "--primary-cta": "#ffffff", + "--secondary-cta": "#0d1a0d", + "--accent": "#2d4a2d", + "--background-accent": "#c1e1c1", + "--primary-cta-text": "#0a150a", + "--secondary-cta-text": "#e1f6e1" + } + } +} diff --git a/cssOptions.json b/cssOptions.json new file mode 100644 index 0000000..25689e5 --- /dev/null +++ b/cssOptions.json @@ -0,0 +1,41 @@ +{ + "cards": { + "solid": "background: var(--color-card);", + "outline": "background: var(--color-card);\nborder: 1px solid color-mix(in srgb, var(--color-accent) 25%, transparent);", + "gradient-mesh": "background:\n radial-gradient(at 0% 0%, color-mix(in srgb, var(--color-accent) 15%, transparent) 0px, transparent 50%),\n radial-gradient(at 100% 0%, color-mix(in srgb, var(--color-accent) 10%, transparent) 0px, transparent 50%),\n radial-gradient(at 100% 100%, color-mix(in srgb, var(--color-accent) 20%, transparent) 0px, transparent 50%),\n radial-gradient(at 0% 100%, color-mix(in srgb, var(--color-accent) 12%, transparent) 0px, transparent 50%),\n var(--color-card);", + "gradient-radial": "background: radial-gradient(circle at center, color-mix(in srgb, var(--color-card) 100%, var(--color-accent) 20%) 0%, var(--color-card) 90%);", + "inset": "background: color-mix(in srgb, var(--color-card) 95%, var(--color-accent) 5%);\nbox-shadow:\n inset 2px 2px 4px color-mix(in srgb, var(--color-foreground) 8%, transparent),\n inset -2px -2px 4px color-mix(in srgb, var(--color-background) 20%, transparent);", + "glass-elevated": "backdrop-filter: blur(8px);\nbackground: linear-gradient(to bottom right, color-mix(in srgb, var(--color-card) 80%, transparent), color-mix(in srgb, var(--color-card) 40%, transparent));\nbox-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);\nborder: 1px solid var(--color-card);", + "glass-depth": "background: color-mix(in srgb, var(--color-card) 80%, transparent);\nbackdrop-filter: blur(14px);\nbox-shadow:\n inset 0 0 20px 0 color-mix(in srgb, var(--color-accent) 7.5%, transparent);\nborder: 1px solid color-mix(in srgb, var(--color-accent) 7.5%, transparent);", + "gradient-bordered": "background: linear-gradient(180deg, color-mix(in srgb, var(--color-card) 100%, var(--color-accent) 5%) -35%, var(--color-card) 65%);\nbox-shadow: 0px 0px 10px 4px color-mix(in srgb, var(--color-accent) 4%, transparent);\nborder: 1px solid color-mix(in srgb, var(--color-accent) 15%, transparent);", + "layered-gradient": "background:\n linear-gradient(color-mix(in srgb, var(--color-accent) 6%, transparent) 0%, transparent 59.26%),\n linear-gradient(var(--color-card) 0%, var(--color-card) 100%),\n var(--color-card);\nbox-shadow:\n 20px 18px 7px color-mix(in srgb, var(--color-accent) 0%, transparent),\n 2px 2px 2px color-mix(in srgb, var(--color-accent) 6.5%, transparent),\n 1px 1px 2px color-mix(in srgb, var(--color-accent) 2%, transparent);\nborder: 2px solid var(--color-secondary-cta);", + "soft-shadow": "background: var(--color-card);\nbox-shadow: color-mix(in srgb, var(--color-accent) 10%, transparent) 0px 0.706592px 0.706592px -0.666667px, color-mix(in srgb, var(--color-accent) 8%, transparent) 0px 1.80656px 1.80656px -1.33333px, color-mix(in srgb, var(--color-accent) 7%, transparent) 0px 3.62176px 3.62176px -2px, color-mix(in srgb, var(--color-accent) 7%, transparent) 0px 6.8656px 6.8656px -2.66667px, color-mix(in srgb, var(--color-accent) 5%, transparent) 0px 13.6468px 13.6468px -3.33333px, color-mix(in srgb, var(--color-accent) 2%, transparent) 0px 30px 30px -4px, var(--color-background) 0px 3px 1px 0px inset;", + "subtle-shadow": "background: var(--color-card);\nbox-shadow: color-mix(in srgb, var(--color-foreground) 5%, transparent) 0px 4px 32px 0px;", + "elevated-border": "background: linear-gradient(180deg, color-mix(in srgb, var(--color-card) 100%, var(--color-foreground) 3%) 0%, var(--color-card) 100%);\nbox-shadow: 0 1px 0 0 color-mix(in srgb, var(--color-foreground) 8%, transparent), 0 4px 6px -1px color-mix(in srgb, var(--color-foreground) 5%, transparent), 0 10px 15px -3px color-mix(in srgb, var(--color-foreground) 4%, transparent);\nborder: 1px solid color-mix(in srgb, var(--color-foreground) 6%, transparent);", + "inner-glow": "background: var(--color-card);\nbox-shadow: inset 0 0 30px 0 color-mix(in srgb, var(--color-foreground) 4%, transparent), inset 0 1px 0 0 color-mix(in srgb, var(--color-foreground) 8%, transparent), 0 4px 12px -4px color-mix(in srgb, var(--color-foreground) 8%, transparent);", + "spotlight": "background:\n radial-gradient(ellipse at 0% 0%, color-mix(in srgb, var(--color-accent) 20%, transparent) 0%, transparent 50%),\n var(--color-card);\nbox-shadow: inset 1px 1px 0 0 color-mix(in srgb, var(--color-foreground) 10%, transparent), 0 4px 16px -4px color-mix(in srgb, var(--color-foreground) 10%, transparent);" + }, + "primaryButtons": { + "gradient": "background: linear-gradient(to bottom, color-mix(in srgb, var(--color-primary-cta) 75%, transparent), var(--color-primary-cta));\nbox-shadow: color-mix(in srgb, var(--color-background) 25%, transparent) 0px 1px 1px 0px inset, color-mix(in srgb, var(--color-primary-cta) 15%, transparent) 3px 3px 3px 0px;", + "shadow": "background: var(--color-primary-cta);\nbox-shadow: 2.10837px 3.16256px 9.48767px color-mix(in srgb, var(--color-primary-cta) 40%, transparent);", + "flat": "background: var(--color-primary-cta);", + "radial-glow": "background:\n radial-gradient(circle at 0% 0%, color-mix(in srgb, var(--color-background) 32.5%, transparent) 0%, transparent 45%),\n radial-gradient(circle at 100% 100%, color-mix(in srgb, var(--color-background) 32.5%, transparent) 0%, transparent 45%),\n var(--color-primary-cta);\nbox-shadow: 2.10837px 3.16256px 9.48767px color-mix(in srgb, var(--color-accent) 30%, transparent);", + "diagonal-gradient": "background: linear-gradient(to bottom right, color-mix(in srgb, var(--color-primary-cta) 80%, transparent), var(--color-foreground));\nbox-shadow: 2.10837px 3.16256px 9.48767px color-mix(in srgb, var(--color-accent) 30%, transparent);", + "double-inset": "background: var(--color-primary-cta);\nbox-shadow: color-mix(in srgb, var(--color-background) 15%, transparent) 0px 4px 10px 0px inset, color-mix(in srgb, var(--color-background) 15%, transparent) 0px -4px 8px 0px inset;", + "primary-glow": "background: var(--color-primary-cta);\nbox-shadow: color-mix(in srgb, var(--color-background) 20%, transparent) 0px 3px 1px 0px inset, color-mix(in srgb, var(--color-primary-cta) 13%, transparent) 0px 0.839802px 0.503881px -0.3125px, color-mix(in srgb, var(--color-primary-cta) 13%, transparent) 0px 1.99048px 1.19429px -0.625px, color-mix(in srgb, var(--color-primary-cta) 13%, transparent) 0px 3.63084px 2.1785px -0.9375px, color-mix(in srgb, var(--color-primary-cta) 13%, transparent) 0px 6.03627px 3.62176px -1.25px, color-mix(in srgb, var(--color-primary-cta) 13%, transparent) 0px 9.74808px 5.84885px -1.5625px, color-mix(in srgb, var(--color-primary-cta) 13%, transparent) 0px 15.9566px 9.57398px -1.875px, color-mix(in srgb, var(--color-primary-cta) 13%, transparent) 0px 27.4762px 16.4857px -2.1875px, color-mix(in srgb, var(--color-primary-cta) 13%, transparent) 0px 50px 30px -2.5px;", + "inset-glow": "background: linear-gradient(180deg, color-mix(in srgb, var(--color-primary-cta) 65%, var(--color-background)) -35%, var(--color-primary-cta) 65%);\nbox-shadow: 0 10px 18px -7px color-mix(in srgb, var(--color-background) 50%, transparent), inset 0 1px 0 0 color-mix(in srgb, var(--color-foreground) 15%, transparent);\nborder: 1px solid color-mix(in srgb, var(--color-foreground) 20%, transparent);", + "soft-glow": "background: radial-gradient(ellipse at 50% -20%, color-mix(in srgb, var(--color-primary-cta) 70%, var(--color-foreground)) 0%, var(--color-primary-cta) 70%);\nbox-shadow: 0 8px 24px -6px color-mix(in srgb, var(--color-primary-cta) 35%, transparent), inset 0 1px 0 0 color-mix(in srgb, var(--color-foreground) 20%, transparent);", + "glass-shimmer": "background: linear-gradient(165deg, color-mix(in srgb, var(--color-primary-cta) 85%, var(--color-foreground)) 0%, var(--color-primary-cta) 40%, color-mix(in srgb, var(--color-primary-cta) 90%, var(--color-background)) 100%);\nbox-shadow: inset 0 1px 1px 0 color-mix(in srgb, var(--color-foreground) 25%, transparent), inset 0 -1px 1px 0 color-mix(in srgb, var(--color-background) 15%, transparent), 0 4px 12px -2px color-mix(in srgb, var(--color-primary-cta) 25%, transparent);", + "neon-outline": "background: var(--color-primary-cta);\nbox-shadow: 0 0 5px color-mix(in srgb, var(--color-accent) 50%, transparent), 0 0 15px color-mix(in srgb, var(--color-accent) 30%, transparent), 0 0 30px color-mix(in srgb, var(--color-accent) 15%, transparent), inset 0 0 8px color-mix(in srgb, var(--color-accent) 10%, transparent);", + "lifted": "background: linear-gradient(180deg, color-mix(in srgb, var(--color-primary-cta) 95%, var(--color-foreground)) 0%, var(--color-primary-cta) 50%, color-mix(in srgb, var(--color-primary-cta) 95%, var(--color-background)) 100%);\nbox-shadow: inset 0 2px 3px 0 color-mix(in srgb, var(--color-foreground) 20%, transparent), inset 0 -2px 3px 0 color-mix(in srgb, var(--color-background) 25%, transparent), 0 2px 4px -1px color-mix(in srgb, var(--color-background) 40%, transparent);", + "depth-layers": "background: var(--color-primary-cta);\nbox-shadow: 0 1px 2px color-mix(in srgb, var(--color-primary-cta) 20%, transparent), 0 2px 4px color-mix(in srgb, var(--color-primary-cta) 20%, transparent), 0 4px 8px color-mix(in srgb, var(--color-primary-cta) 15%, transparent), 0 8px 16px color-mix(in srgb, var(--color-primary-cta) 10%, transparent), 0 16px 32px color-mix(in srgb, var(--color-primary-cta) 5%, transparent);", + "accent-edge": "background: linear-gradient(180deg, var(--color-primary-cta) 0%, color-mix(in srgb, var(--color-primary-cta) 90%, var(--color-background)) 100%);\nbox-shadow: 0 0 0 1px color-mix(in srgb, var(--color-accent) 60%, transparent), 0 4px 12px -2px color-mix(in srgb, var(--color-accent) 35%, transparent), inset 0 1px 0 0 color-mix(in srgb, var(--color-foreground) 20%, transparent);", + "metallic": "background: linear-gradient(135deg, color-mix(in srgb, var(--color-primary-cta) 80%, var(--color-foreground)) 0%, var(--color-primary-cta) 25%, color-mix(in srgb, var(--color-primary-cta) 90%, var(--color-background)) 50%, var(--color-primary-cta) 75%, color-mix(in srgb, var(--color-primary-cta) 85%, var(--color-foreground)) 100%);\nbox-shadow: inset 0 1px 0 0 color-mix(in srgb, var(--color-foreground) 30%, transparent), 0 3px 8px -2px color-mix(in srgb, var(--color-background) 50%, transparent);" + }, + "secondaryButtons": { + "glass": "backdrop-filter: blur(8px);\nbackground: linear-gradient(to bottom right, color-mix(in srgb, var(--color-secondary-cta) 80%, transparent), var(--color-secondary-cta));\nbox-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);\nborder: 1px solid var(--color-secondary-cta);", + "solid": "background: var(--color-secondary-cta);", + "layered": "background:\n linear-gradient(color-mix(in srgb, var(--color-accent) 5%, transparent) 0%, transparent 59.26%),\n linear-gradient(var(--color-secondary-cta), var(--color-secondary-cta)),\n linear-gradient(var(--color-secondary-cta), var(--color-secondary-cta)),\n linear-gradient(color-mix(in srgb, var(--color-accent) 5%, transparent) 0%, transparent 59.26%),\n linear-gradient(color-mix(in srgb, var(--color-secondary-cta) 60%, transparent), color-mix(in srgb, var(--color-secondary-cta) 60%, transparent)),\n var(--color-secondary-cta);\nbox-shadow:\n 2.10837px 3.16256px 9.48767px color-mix(in srgb, var(--color-accent) 10%, transparent);\nborder: 1px solid var(--color-secondary-cta);", + "radial-glow": "background:\n radial-gradient(circle at 0% 0%, color-mix(in srgb, var(--color-accent) 15%, transparent) 0%, transparent 40%),\n radial-gradient(circle at 100% 100%, color-mix(in srgb, var(--color-accent) 15%, transparent) 0%, transparent 40%),\n var(--color-secondary-cta);\nbox-shadow: 2.10837px 3.16256px 9.48767px color-mix(in srgb, var(--color-accent) 10%, transparent);" + } +} diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 0000000..8438870 --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,26 @@ +import js from '@eslint/js' +import globals from 'globals' +import reactHooks from 'eslint-plugin-react-hooks' +import reactRefresh from 'eslint-plugin-react-refresh' +import tseslint from 'typescript-eslint' +import { defineConfig, globalIgnores } from 'eslint/config' + +export default defineConfig([ + globalIgnores(['dist']), + { + files: ['**/*.{ts,tsx}'], + extends: [ + js.configs.recommended, + tseslint.configs.recommended, + reactHooks.configs.flat.recommended, + reactRefresh.configs.vite, + ], + rules: { + 'react-hooks/set-state-in-effect': 'off', + }, + languageOptions: { + ecmaVersion: 2020, + globals: globals.browser, + }, + }, +]) diff --git a/fontThemes.json b/fontThemes.json new file mode 100644 index 0000000..e14bbca --- /dev/null +++ b/fontThemes.json @@ -0,0 +1,237 @@ +{ + "singleFonts": { + "interTight": { + "name": "Inter Tight", + "import": "import { Inter_Tight } from \"next/font/google\";", + "initialization": "const interTight = Inter_Tight({\n variable: \"--font-inter-tight\",\n subsets: [\"latin\"],\n weight: [\"100\", \"200\", \"300\", \"400\", \"500\", \"600\", \"700\", \"800\", \"900\"],\n});", + "className": "${interTight.variable}", + "cssVariable": "font-family: var(--font-inter-tight), sans-serif;" + }, + "inter": { + "name": "Inter", + "import": "import { Inter } from \"next/font/google\";", + "initialization": "const inter = Inter({\n variable: \"--font-inter\",\n subsets: [\"latin\"],\n});", + "className": "${inter.variable}", + "cssVariable": "font-family: var(--font-inter), sans-serif;" + }, + "poppins": { + "name": "Poppins", + "import": "import { Poppins } from \"next/font/google\";", + "initialization": "const poppins = Poppins({\n variable: \"--font-poppins\",\n subsets: [\"latin\"],\n weight: [\"100\", \"200\", \"300\", \"400\", \"500\", \"600\", \"700\", \"800\", \"900\"],\n});", + "className": "${poppins.variable}", + "cssVariable": "font-family: var(--font-poppins), sans-serif;" + }, + "montserrat": { + "name": "Montserrat", + "import": "import { Montserrat } from \"next/font/google\";", + "initialization": "const montserrat = Montserrat({\n variable: \"--font-montserrat\",\n subsets: [\"latin\"],\n});", + "className": "${montserrat.variable}", + "cssVariable": "font-family: var(--font-montserrat), sans-serif;" + }, + "roboto": { + "name": "Roboto", + "import": "import { Roboto } from \"next/font/google\";", + "initialization": "const roboto = Roboto({\n variable: \"--font-roboto\",\n subsets: [\"latin\"],\n weight: [\"100\", \"300\", \"400\", \"500\", \"700\", \"900\"],\n});", + "className": "${roboto.variable}", + "cssVariable": "font-family: var(--font-roboto), sans-serif;" + }, + "openSans": { + "name": "Open Sans", + "import": "import { Open_Sans } from \"next/font/google\";", + "initialization": "const openSans = Open_Sans({\n variable: \"--font-open-sans\",\n subsets: [\"latin\"],\n});", + "className": "${openSans.variable}", + "cssVariable": "font-family: var(--font-open-sans), sans-serif;" + }, + "lato": { + "name": "Lato", + "import": "import { Lato } from \"next/font/google\";", + "initialization": "const lato = Lato({\n variable: \"--font-lato\",\n subsets: [\"latin\"],\n weight: [\"100\", \"300\", \"400\", \"700\", \"900\"],\n});", + "className": "${lato.variable}", + "cssVariable": "font-family: var(--font-lato), sans-serif;" + }, + "dmSans": { + "name": "DM Sans", + "import": "import { DM_Sans } from \"next/font/google\";", + "initialization": "const dmSans = DM_Sans({\n variable: \"--font-dm-sans\",\n subsets: [\"latin\"],\n});", + "className": "${dmSans.variable}", + "cssVariable": "font-family: var(--font-dm-sans), sans-serif;" + }, + "manrope": { + "name": "Manrope", + "import": "import { Manrope } from \"next/font/google\";", + "initialization": "const manrope = Manrope({\n variable: \"--font-manrope\",\n subsets: [\"latin\"],\n});", + "className": "${manrope.variable}", + "cssVariable": "font-family: var(--font-manrope), sans-serif;" + }, + "sourceSans3": { + "name": "Source Sans 3", + "import": "import { Source_Sans_3 } from \"next/font/google\";", + "initialization": "const sourceSans3 = Source_Sans_3({\n variable: \"--font-source-sans-3\",\n subsets: [\"latin\"],\n});", + "className": "${sourceSans3.variable}", + "cssVariable": "font-family: var(--font-source-sans-3), sans-serif;" + }, + "publicSans": { + "name": "Public Sans", + "import": "import { Public_Sans } from \"next/font/google\";", + "initialization": "const publicSans = Public_Sans({\n variable: \"--font-public-sans\",\n subsets: [\"latin\"],\n});", + "className": "${publicSans.variable}", + "cssVariable": "font-family: var(--font-public-sans), sans-serif;" + }, + "mulish": { + "name": "Mulish", + "import": "import { Mulish } from \"next/font/google\";", + "initialization": "const mulish = Mulish({\n variable: \"--font-mulish\",\n subsets: [\"latin\"],\n});", + "className": "${mulish.variable}", + "cssVariable": "font-family: var(--font-mulish), sans-serif;" + }, + "nunito": { + "name": "Nunito", + "import": "import { Nunito } from \"next/font/google\";", + "initialization": "const nunito = Nunito({\n variable: \"--font-nunito\",\n subsets: [\"latin\"],\n});", + "className": "${nunito.variable}", + "cssVariable": "font-family: var(--font-nunito), sans-serif;" + }, + "nunitoSans": { + "name": "Nunito Sans", + "import": "import { Nunito_Sans } from \"next/font/google\";", + "initialization": "const nunitoSans = Nunito_Sans({\n variable: \"--font-nunito-sans\",\n subsets: [\"latin\"],\n});", + "className": "${nunitoSans.variable}", + "cssVariable": "font-family: var(--font-nunito-sans), sans-serif;" + }, + "raleway": { + "name": "Raleway", + "import": "import { Raleway } from \"next/font/google\";", + "initialization": "const raleway = Raleway({\n variable: \"--font-raleway\",\n subsets: [\"latin\"],\n});", + "className": "${raleway.variable}", + "cssVariable": "font-family: var(--font-raleway), sans-serif;" + }, + "archivo": { + "name": "Archivo", + "import": "import { Archivo } from \"next/font/google\";", + "initialization": "const archivo = Archivo({\n variable: \"--font-archivo\",\n subsets: [\"latin\"],\n});", + "className": "${archivo.variable}", + "cssVariable": "font-family: var(--font-archivo), sans-serif;" + }, + "figtree": { + "name": "Figtree", + "import": "import { Figtree } from \"next/font/google\";", + "initialization": "const figtree = Figtree({\n variable: \"--font-figtree\",\n subsets: [\"latin\"],\n});", + "className": "${figtree.variable}", + "cssVariable": "font-family: var(--font-figtree), sans-serif;" + } + }, + "fontPairings": { + "interOpenSans": { + "name": "Inter + Open Sans", + "description": "Neutral headings with friendly body. Clean and approachable.", + "headingFont": "inter", + "bodyFont": "openSans", + "imports": "import { Inter } from \"next/font/google\";\nimport { Open_Sans } from \"next/font/google\";", + "initializations": "const inter = Inter({\n variable: \"--font-inter\",\n subsets: [\"latin\"],\n});\n\nconst openSans = Open_Sans({\n variable: \"--font-open-sans\",\n subsets: [\"latin\"],\n});", + "classNames": "${inter.variable} ${openSans.variable}", + "globalsCss": { + "instructions": "Update the font-family property within the existing CSS rules in globals.css (@layer base section)", + "bodyRule": "body {\n /* ... existing properties ... */\n font-family: var(--font-open-sans), sans-serif;\n}", + "headingsRule": "h1, h2, h3, h4, h5, h6 {\n font-family: var(--font-inter), sans-serif;\n}", + "bodyFontFamily": "var(--font-open-sans), sans-serif", + "headingsFontFamily": "var(--font-inter), sans-serif" + } + }, + "dmSansInter": { + "name": "DM Sans + Inter", + "description": "Modern geometric headings with neutral body. Contemporary and clean.", + "headingFont": "dmSans", + "bodyFont": "inter", + "imports": "import { DM_Sans } from \"next/font/google\";\nimport { Inter } from \"next/font/google\";", + "initializations": "const dmSans = DM_Sans({\n variable: \"--font-dm-sans\",\n subsets: [\"latin\"],\n});\n\nconst inter = Inter({\n variable: \"--font-inter\",\n subsets: [\"latin\"],\n});", + "classNames": "${dmSans.variable} ${inter.variable}", + "globalsCss": { + "instructions": "Update the font-family property within the existing CSS rules in globals.css (@layer base section)", + "bodyRule": "body {\n /* ... existing properties ... */\n font-family: var(--font-inter), sans-serif;\n}", + "headingsRule": "h1, h2, h3, h4, h5, h6 {\n font-family: var(--font-dm-sans), sans-serif;\n}", + "bodyFontFamily": "var(--font-inter), sans-serif", + "headingsFontFamily": "var(--font-dm-sans), sans-serif" + } + }, + "manropeDmSans": { + "name": "Manrope + DM Sans", + "description": "Geometric headings with clean body. Modern and professional.", + "headingFont": "manrope", + "bodyFont": "dmSans", + "imports": "import { Manrope } from \"next/font/google\";\nimport { DM_Sans } from \"next/font/google\";", + "initializations": "const manrope = Manrope({\n variable: \"--font-manrope\",\n subsets: [\"latin\"],\n});\n\nconst dmSans = DM_Sans({\n variable: \"--font-dm-sans\",\n subsets: [\"latin\"],\n});", + "classNames": "${manrope.variable} ${dmSans.variable}", + "globalsCss": { + "instructions": "Update the font-family property within the existing CSS rules in globals.css (@layer base section)", + "bodyRule": "body {\n /* ... existing properties ... */\n font-family: var(--font-dm-sans), sans-serif;\n}", + "headingsRule": "h1, h2, h3, h4, h5, h6 {\n font-family: var(--font-manrope), sans-serif;\n}", + "bodyFontFamily": "var(--font-dm-sans), sans-serif", + "headingsFontFamily": "var(--font-manrope), sans-serif" + } + }, + "publicSansInter": { + "name": "Public Sans + Inter", + "description": "Government-inspired headings with neutral body. Professional and trustworthy.", + "headingFont": "publicSans", + "bodyFont": "inter", + "imports": "import { Public_Sans } from \"next/font/google\";\nimport { Inter } from \"next/font/google\";", + "initializations": "const publicSans = Public_Sans({\n variable: \"--font-public-sans\",\n subsets: [\"latin\"],\n});\n\nconst inter = Inter({\n variable: \"--font-inter\",\n subsets: [\"latin\"],\n});", + "classNames": "${publicSans.variable} ${inter.variable}", + "globalsCss": { + "instructions": "Update the font-family property within the existing CSS rules in globals.css (@layer base section)", + "bodyRule": "body {\n /* ... existing properties ... */\n font-family: var(--font-inter), sans-serif;\n}", + "headingsRule": "h1, h2, h3, h4, h5, h6 {\n font-family: var(--font-public-sans), sans-serif;\n}", + "bodyFontFamily": "var(--font-inter), sans-serif", + "headingsFontFamily": "var(--font-public-sans), sans-serif" + } + }, + "mulishInter": { + "name": "Mulish + Inter", + "description": "Minimal headings with neutral body. Clean and modern.", + "headingFont": "mulish", + "bodyFont": "inter", + "imports": "import { Mulish } from \"next/font/google\";\nimport { Inter } from \"next/font/google\";", + "initializations": "const mulish = Mulish({\n variable: \"--font-mulish\",\n subsets: [\"latin\"],\n});\n\nconst inter = Inter({\n variable: \"--font-inter\",\n subsets: [\"latin\"],\n});", + "classNames": "${mulish.variable} ${inter.variable}", + "globalsCss": { + "instructions": "Update the font-family property within the existing CSS rules in globals.css (@layer base section)", + "bodyRule": "body {\n /* ... existing properties ... */\n font-family: var(--font-inter), sans-serif;\n}", + "headingsRule": "h1, h2, h3, h4, h5, h6 {\n font-family: var(--font-mulish), sans-serif;\n}", + "bodyFontFamily": "var(--font-inter), sans-serif", + "headingsFontFamily": "var(--font-mulish), sans-serif" + } + }, + "montserratInter": { + "name": "Montserrat + Inter", + "description": "Geometric sans-serif headings with neutral body. Popular and reliable.", + "headingFont": "montserrat", + "bodyFont": "inter", + "imports": "import { Montserrat } from \"next/font/google\";\nimport { Inter } from \"next/font/google\";", + "initializations": "const montserrat = Montserrat({\n variable: \"--font-montserrat\",\n subsets: [\"latin\"],\n});\n\nconst inter = Inter({\n variable: \"--font-inter\",\n subsets: [\"latin\"],\n});", + "classNames": "${montserrat.variable} ${inter.variable}", + "globalsCss": { + "instructions": "Update the font-family property within the existing CSS rules in globals.css (@layer base section)", + "bodyRule": "body {\n /* ... existing properties ... */\n font-family: var(--font-inter), sans-serif;\n}", + "headingsRule": "h1, h2, h3, h4, h5, h6 {\n font-family: var(--font-montserrat), sans-serif;\n}", + "bodyFontFamily": "var(--font-inter), sans-serif", + "headingsFontFamily": "var(--font-montserrat), sans-serif" + } + }, + "libreBaskervilleInter": { + "name": "Libre Baskerville + Inter", + "description": "Classic serif headings with neutral body. Elegant and readable.", + "headingFont": "libreBaskerville", + "bodyFont": "inter", + "imports": "import { Libre_Baskerville } from \"next/font/google\";\nimport { Inter } from \"next/font/google\";", + "initializations": "const libreBaskerville = Libre_Baskerville({\n variable: \"--font-libre-baskerville\",\n subsets: [\"latin\"],\n weight: [\"400\", \"700\"],\n});\n\nconst inter = Inter({\n variable: \"--font-inter\",\n subsets: [\"latin\"],\n});", + "classNames": "${libreBaskerville.variable} ${inter.variable}", + "globalsCss": { + "instructions": "Update the font-family property within the existing CSS rules in globals.css (@layer base section)", + "bodyRule": "body {\n /* ... existing properties ... */\n font-family: var(--font-inter), sans-serif;\n}", + "headingsRule": "h1, h2, h3, h4, h5, h6 {\n font-family: var(--font-libre-baskerville), serif;\n}", + "bodyFontFamily": "var(--font-inter), sans-serif", + "headingsFontFamily": "var(--font-libre-baskerville), serif" + } + } + } +} diff --git a/index.html b/index.html new file mode 100644 index 0000000..c7652cd --- /dev/null +++ b/index.html @@ -0,0 +1,13 @@ + + + + + + + Webild Components + + +
+ + + diff --git a/package.json b/package.json new file mode 100644 index 0000000..06ebd3c --- /dev/null +++ b/package.json @@ -0,0 +1,40 @@ +{ + "name": "webild-components", + "private": true, + "version": "0.0.1", + "type": "module", + "scripts": { + "dev": "vite", + "build": "tsc -b && vite build", + "lint": "eslint .", + "preview": "vite preview", + "typecheck": "tsc --noEmit --project tsconfig.app.json" + }, + "dependencies": { + "@tailwindcss/vite": "^4.2.2", + "clsx": "^2.1.1", + "embla-carousel": "^8.6.0", + "embla-carousel-react": "^8.6.0", + "motion": "^12.38.0", + "lucide-react": "^1.7.0", + "react": "^19.2.4", + "react-dom": "^19.2.4", + "react-router-dom": "^7.14.0", + "tailwind-merge": "^3.5.0", + "tailwindcss": "^4.2.2" + }, + "devDependencies": { + "@eslint/js": "^9.39.4", + "@types/node": "^24.12.2", + "@types/react": "^19.2.14", + "@types/react-dom": "^19.2.3", + "@vitejs/plugin-react": "^6.0.1", + "eslint": "^9.39.4", + "eslint-plugin-react-hooks": "^7.0.1", + "eslint-plugin-react-refresh": "^0.5.2", + "globals": "^17.4.0", + "typescript": "~6.0.2", + "typescript-eslint": "^8.58.0", + "vite": "^8.0.4" + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..fc9c5ba --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,2228 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@tailwindcss/vite': + specifier: ^4.2.2 + version: 4.2.2(vite@8.0.7(@types/node@24.12.2)(jiti@2.6.1)) + clsx: + specifier: ^2.1.1 + version: 2.1.1 + embla-carousel: + specifier: ^8.6.0 + version: 8.6.0 + embla-carousel-react: + specifier: ^8.6.0 + version: 8.6.0(react@19.2.4) + lucide-react: + specifier: ^1.7.0 + version: 1.7.0(react@19.2.4) + motion: + specifier: ^12.38.0 + version: 12.38.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + react: + specifier: ^19.2.4 + version: 19.2.4 + react-dom: + specifier: ^19.2.4 + version: 19.2.4(react@19.2.4) + react-router-dom: + specifier: ^7.14.0 + version: 7.14.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + tailwind-merge: + specifier: ^3.5.0 + version: 3.5.0 + tailwindcss: + specifier: ^4.2.2 + version: 4.2.2 + devDependencies: + '@eslint/js': + specifier: ^9.39.4 + version: 9.39.4 + '@types/node': + specifier: ^24.12.2 + version: 24.12.2 + '@types/react': + specifier: ^19.2.14 + version: 19.2.14 + '@types/react-dom': + specifier: ^19.2.3 + version: 19.2.3(@types/react@19.2.14) + '@vitejs/plugin-react': + specifier: ^6.0.1 + version: 6.0.1(vite@8.0.7(@types/node@24.12.2)(jiti@2.6.1)) + eslint: + specifier: ^9.39.4 + version: 9.39.4(jiti@2.6.1) + eslint-plugin-react-hooks: + specifier: ^7.0.1 + version: 7.0.1(eslint@9.39.4(jiti@2.6.1)) + eslint-plugin-react-refresh: + specifier: ^0.5.2 + version: 0.5.2(eslint@9.39.4(jiti@2.6.1)) + globals: + specifier: ^17.4.0 + version: 17.4.0 + typescript: + specifier: ~6.0.2 + version: 6.0.2 + typescript-eslint: + specifier: ^8.58.0 + version: 8.58.0(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.2) + vite: + specifier: ^8.0.4 + version: 8.0.7(@types/node@24.12.2)(jiti@2.6.1) + +packages: + + '@babel/code-frame@7.29.0': + resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==} + engines: {node: '>=6.9.0'} + + '@babel/compat-data@7.29.0': + resolution: {integrity: sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.29.0': + resolution: {integrity: sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.29.1': + resolution: {integrity: sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-compilation-targets@7.28.6': + resolution: {integrity: sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-globals@7.28.0': + resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.28.6': + resolution: {integrity: sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-transforms@7.28.6': + resolution: {integrity: sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-string-parser@7.27.1': + resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.28.5': + resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-option@7.27.1': + resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.29.2': + resolution: {integrity: sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.29.2': + resolution: {integrity: sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/template@7.28.6': + resolution: {integrity: sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.29.0': + resolution: {integrity: sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.29.0': + resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} + engines: {node: '>=6.9.0'} + + '@emnapi/core@1.9.1': + resolution: {integrity: sha512-mukuNALVsoix/w1BJwFzwXBN/dHeejQtuVzcDsfOEsdpCumXb/E9j8w11h5S54tT1xhifGfbbSm/ICrObRb3KA==} + + '@emnapi/runtime@1.9.1': + resolution: {integrity: sha512-VYi5+ZVLhpgK4hQ0TAjiQiZ6ol0oe4mBx7mVv7IflsiEp0OWoVsp/+f9Vc1hOhE0TtkORVrI1GvzyreqpgWtkA==} + + '@emnapi/wasi-threads@1.2.0': + resolution: {integrity: sha512-N10dEJNSsUx41Z6pZsXU8FjPjpBEplgH24sfkmITrBED1/U2Esum9F3lfLrMjKHHjmi557zQn7kR9R+XWXu5Rg==} + + '@eslint-community/eslint-utils@4.9.1': + resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + + '@eslint-community/regexpp@4.12.2': + resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + '@eslint/config-array@0.21.2': + resolution: {integrity: sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/config-helpers@0.4.2': + resolution: {integrity: sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/core@0.17.0': + resolution: {integrity: sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/eslintrc@3.3.5': + resolution: {integrity: sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/js@9.39.4': + resolution: {integrity: sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/object-schema@2.1.7': + resolution: {integrity: sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/plugin-kit@0.4.1': + resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@humanfs/core@0.19.1': + resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} + engines: {node: '>=18.18.0'} + + '@humanfs/node@0.16.7': + resolution: {integrity: sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==} + engines: {node: '>=18.18.0'} + + '@humanwhocodes/module-importer@1.0.1': + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + + '@humanwhocodes/retry@0.4.3': + resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} + engines: {node: '>=18.18'} + + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + + '@jridgewell/remapping@2.3.5': + resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + + '@napi-rs/wasm-runtime@1.1.2': + resolution: {integrity: sha512-sNXv5oLJ7ob93xkZ1XnxisYhGYXfaG9f65/ZgYuAu3qt7b3NadcOEhLvx28hv31PgX8SZJRYrAIPQilQmFpLVw==} + peerDependencies: + '@emnapi/core': ^1.7.1 + '@emnapi/runtime': ^1.7.1 + + '@oxc-project/types@0.123.0': + resolution: {integrity: sha512-YtECP/y8Mj1lSHiUWGSRzy/C6teUKlS87dEfuVKT09LgQbUsBW1rNg+MiJ4buGu3yuADV60gbIvo9/HplA56Ew==} + + '@rolldown/binding-android-arm64@1.0.0-rc.13': + resolution: {integrity: sha512-5ZiiecKH2DXAVJTNN13gNMUcCDg4Jy8ZjbXEsPnqa248wgOVeYRX0iqXXD5Jz4bI9BFHgKsI2qmyJynstbmr+g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + + '@rolldown/binding-darwin-arm64@1.0.0-rc.13': + resolution: {integrity: sha512-tz/v/8G77seu8zAB3A5sK3UFoOl06zcshEzhUO62sAEtrEuW/H1CcyoupOrD+NbQJytYgA4CppXPzlrmp4JZKA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + + '@rolldown/binding-darwin-x64@1.0.0-rc.13': + resolution: {integrity: sha512-8DakphqOz8JrMYWTJmWA+vDJxut6LijZ8Xcdc4flOlAhU7PNVwo2MaWBF9iXjJAPo5rC/IxEFZDhJ3GC7NHvug==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + + '@rolldown/binding-freebsd-x64@1.0.0-rc.13': + resolution: {integrity: sha512-4wBQFfjDuXYN/SVI8inBF3Aa+isq40rc6VMFbk5jcpolUBTe5cYnMsHZ51nFWsx3PVyyNN3vgoESki0Hmr/4BA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.13': + resolution: {integrity: sha512-JW/e4yPIXLms+jmnbwwy5LA/LxVwZUWLN8xug+V200wzaVi5TEGIWQlh8o91gWYFxW609euI98OCCemmWGuPrw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.13': + resolution: {integrity: sha512-ZfKWpXiUymDnavepCaM6KG/uGydJ4l2nBmMxg60Ci4CbeefpqjPWpfaZM7PThOhk2dssqBAcwLc6rAyr0uTdXg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-arm64-musl@1.0.0-rc.13': + resolution: {integrity: sha512-bmRg3O6Z0gq9yodKKWCIpnlH051sEfdVwt+6m5UDffAQMUUqU0xjnQqqAUm+Gu7ofAAly9DqiQDtKu2nPDEABA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.13': + resolution: {integrity: sha512-8Wtnbw4k7pMYN9B/mOEAsQ8HOiq7AZ31Ig4M9BKn2So4xRaFEhtCSa4ZJaOutOWq50zpgR4N5+L/opnlaCx8wQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.13': + resolution: {integrity: sha512-D/0Nlo8mQuxSMohNJUF2lDXWRsFDsHldfRRgD9bRgktj+EndGPj4DOV37LqDKPYS+osdyhZEH7fTakTAEcW7qg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-x64-gnu@1.0.0-rc.13': + resolution: {integrity: sha512-eRrPvat2YaVQcwwKi/JzOP6MKf1WRnOCr+VaI3cTWz3ZoLcP/654z90lVCJ4dAuMEpPdke0n+qyAqXDZdIC4rA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-x64-musl@1.0.0-rc.13': + resolution: {integrity: sha512-PsdONiFRp8hR8KgVjTWjZ9s7uA3uueWL0t74/cKHfM4dR5zXYv4AjB8BvA+QDToqxAFg4ZkcVEqeu5F7inoz5w==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [musl] + + '@rolldown/binding-openharmony-arm64@1.0.0-rc.13': + resolution: {integrity: sha512-hCNXgC5dI3TVOLrPT++PKFNZ+1EtS0mLQwfXXXSUD/+rGlB65gZDwN/IDuxLpQP4x8RYYHqGomlUXzpO8aVI2w==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@rolldown/binding-wasm32-wasi@1.0.0-rc.13': + resolution: {integrity: sha512-viLS5C5et8NFtLWw9Sw3M/w4vvnVkbWkO7wSNh3C+7G1+uCkGpr6PcjNDSFcNtmXY/4trjPBqUfcOL+P3sWy/g==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + + '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.13': + resolution: {integrity: sha512-Fqa3Tlt1xL4wzmAYxGNFV36Hb+VfPc9PYU+E25DAnswXv3ODDu/yyWjQDbXMo5AGWkQVjLgQExuVu8I/UaZhPQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@rolldown/binding-win32-x64-msvc@1.0.0-rc.13': + resolution: {integrity: sha512-/pLI5kPkGEi44TDlnbio3St/5gUFeN51YWNAk/Gnv6mEQBOahRBh52qVFVBpmrnU01n2yysvBML9Ynu7K4kGAQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + + '@rolldown/pluginutils@1.0.0-rc.13': + resolution: {integrity: sha512-3ngTAv6F/Py35BsYbeeLeecvhMKdsKm4AoOETVhAA+Qc8nrA2I0kF7oa93mE9qnIurngOSpMnQ0x2nQY2FPviA==} + + '@rolldown/pluginutils@1.0.0-rc.7': + resolution: {integrity: sha512-qujRfC8sFVInYSPPMLQByRh7zhwkGFS4+tyMQ83srV1qrxL4g8E2tyxVVyxd0+8QeBM1mIk9KbWxkegRr76XzA==} + + '@tailwindcss/node@4.2.2': + resolution: {integrity: sha512-pXS+wJ2gZpVXqFaUEjojq7jzMpTGf8rU6ipJz5ovJV6PUGmlJ+jvIwGrzdHdQ80Sg+wmQxUFuoW1UAAwHNEdFA==} + + '@tailwindcss/oxide-android-arm64@4.2.2': + resolution: {integrity: sha512-dXGR1n+P3B6748jZO/SvHZq7qBOqqzQ+yFrXpoOWWALWndF9MoSKAT3Q0fYgAzYzGhxNYOoysRvYlpixRBBoDg==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [android] + + '@tailwindcss/oxide-darwin-arm64@4.2.2': + resolution: {integrity: sha512-iq9Qjr6knfMpZHj55/37ouZeykwbDqF21gPFtfnhCCKGDcPI/21FKC9XdMO/XyBM7qKORx6UIhGgg6jLl7BZlg==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [darwin] + + '@tailwindcss/oxide-darwin-x64@4.2.2': + resolution: {integrity: sha512-BlR+2c3nzc8f2G639LpL89YY4bdcIdUmiOOkv2GQv4/4M0vJlpXEa0JXNHhCHU7VWOKWT/CjqHdTP8aUuDJkuw==} + engines: {node: '>= 20'} + cpu: [x64] + os: [darwin] + + '@tailwindcss/oxide-freebsd-x64@4.2.2': + resolution: {integrity: sha512-YUqUgrGMSu2CDO82hzlQ5qSb5xmx3RUrke/QgnoEx7KvmRJHQuZHZmZTLSuuHwFf0DJPybFMXMYf+WJdxHy/nQ==} + engines: {node: '>= 20'} + cpu: [x64] + os: [freebsd] + + '@tailwindcss/oxide-linux-arm-gnueabihf@4.2.2': + resolution: {integrity: sha512-FPdhvsW6g06T9BWT0qTwiVZYE2WIFo2dY5aCSpjG/S/u1tby+wXoslXS0kl3/KXnULlLr1E3NPRRw0g7t2kgaQ==} + engines: {node: '>= 20'} + cpu: [arm] + os: [linux] + + '@tailwindcss/oxide-linux-arm64-gnu@4.2.2': + resolution: {integrity: sha512-4og1V+ftEPXGttOO7eCmW7VICmzzJWgMx+QXAJRAhjrSjumCwWqMfkDrNu1LXEQzNAwz28NCUpucgQPrR4S2yw==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@tailwindcss/oxide-linux-arm64-musl@4.2.2': + resolution: {integrity: sha512-oCfG/mS+/+XRlwNjnsNLVwnMWYH7tn/kYPsNPh+JSOMlnt93mYNCKHYzylRhI51X+TbR+ufNhhKKzm6QkqX8ag==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@tailwindcss/oxide-linux-x64-gnu@4.2.2': + resolution: {integrity: sha512-rTAGAkDgqbXHNp/xW0iugLVmX62wOp2PoE39BTCGKjv3Iocf6AFbRP/wZT/kuCxC9QBh9Pu8XPkv/zCZB2mcMg==} + engines: {node: '>= 20'} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@tailwindcss/oxide-linux-x64-musl@4.2.2': + resolution: {integrity: sha512-XW3t3qwbIwiSyRCggeO2zxe3KWaEbM0/kW9e8+0XpBgyKU4ATYzcVSMKteZJ1iukJ3HgHBjbg9P5YPRCVUxlnQ==} + engines: {node: '>= 20'} + cpu: [x64] + os: [linux] + libc: [musl] + + '@tailwindcss/oxide-wasm32-wasi@4.2.2': + resolution: {integrity: sha512-eKSztKsmEsn1O5lJ4ZAfyn41NfG7vzCg496YiGtMDV86jz1q/irhms5O0VrY6ZwTUkFy/EKG3RfWgxSI3VbZ8Q==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + bundledDependencies: + - '@napi-rs/wasm-runtime' + - '@emnapi/core' + - '@emnapi/runtime' + - '@tybys/wasm-util' + - '@emnapi/wasi-threads' + - tslib + + '@tailwindcss/oxide-win32-arm64-msvc@4.2.2': + resolution: {integrity: sha512-qPmaQM4iKu5mxpsrWZMOZRgZv1tOZpUm+zdhhQP0VhJfyGGO3aUKdbh3gDZc/dPLQwW4eSqWGrrcWNBZWUWaXQ==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [win32] + + '@tailwindcss/oxide-win32-x64-msvc@4.2.2': + resolution: {integrity: sha512-1T/37VvI7WyH66b+vqHj/cLwnCxt7Qt3WFu5Q8hk65aOvlwAhs7rAp1VkulBJw/N4tMirXjVnylTR72uI0HGcA==} + engines: {node: '>= 20'} + cpu: [x64] + os: [win32] + + '@tailwindcss/oxide@4.2.2': + resolution: {integrity: sha512-qEUA07+E5kehxYp9BVMpq9E8vnJuBHfJEC0vPC5e7iL/hw7HR61aDKoVoKzrG+QKp56vhNZe4qwkRmMC0zDLvg==} + engines: {node: '>= 20'} + + '@tailwindcss/vite@4.2.2': + resolution: {integrity: sha512-mEiF5HO1QqCLXoNEfXVA1Tzo+cYsrqV7w9Juj2wdUFyW07JRenqMG225MvPwr3ZD9N1bFQj46X7r33iHxLUW0w==} + peerDependencies: + vite: ^5.2.0 || ^6 || ^7 || ^8 + + '@tybys/wasm-util@0.10.1': + resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} + + '@types/estree@1.0.8': + resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/node@24.12.2': + resolution: {integrity: sha512-A1sre26ke7HDIuY/M23nd9gfB+nrmhtYyMINbjI1zHJxYteKR6qSMX56FsmjMcDb3SMcjJg5BiRRgOCC/yBD0g==} + + '@types/react-dom@19.2.3': + resolution: {integrity: sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==} + peerDependencies: + '@types/react': ^19.2.0 + + '@types/react@19.2.14': + resolution: {integrity: sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==} + + '@typescript-eslint/eslint-plugin@8.58.0': + resolution: {integrity: sha512-RLkVSiNuUP1C2ROIWfqX+YcUfLaSnxGE/8M+Y57lopVwg9VTYYfhuz15Yf1IzCKgZj6/rIbYTmJCUSqr76r0Wg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + '@typescript-eslint/parser': ^8.58.0 + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/parser@8.58.0': + resolution: {integrity: sha512-rLoGZIf9afaRBYsPUMtvkDWykwXwUPL60HebR4JgTI8mxfFe2cQTu3AGitANp4b9B2QlVru6WzjgB2IzJKiCSA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/project-service@8.58.0': + resolution: {integrity: sha512-8Q/wBPWLQP1j16NxoPNIKpDZFMaxl7yWIoqXWYeWO+Bbd2mjgvoF0dxP2jKZg5+x49rgKdf7Ck473M8PC3V9lg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/scope-manager@8.58.0': + resolution: {integrity: sha512-W1Lur1oF50FxSnNdGp3Vs6P+yBRSmZiw4IIjEeYxd8UQJwhUF0gDgDD/W/Tgmh73mxgEU3qX0Bzdl/NGuSPEpQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/tsconfig-utils@8.58.0': + resolution: {integrity: sha512-doNSZEVJsWEu4htiVC+PR6NpM+pa+a4ClH9INRWOWCUzMst/VA9c4gXq92F8GUD1rwhNvRLkgjfYtFXegXQF7A==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/type-utils@8.58.0': + resolution: {integrity: sha512-aGsCQImkDIqMyx1u4PrVlbi/krmDsQUs4zAcCV6M7yPcPev+RqVlndsJy9kJ8TLihW9TZ0kbDAzctpLn5o+lOg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/types@8.58.0': + resolution: {integrity: sha512-O9CjxypDT89fbHxRfETNoAnHj/i6IpRK0CvbVN3qibxlLdo5p5hcLmUuCCrHMpxiWSwKyI8mCP7qRNYuOJ0Uww==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/typescript-estree@8.58.0': + resolution: {integrity: sha512-7vv5UWbHqew/dvs+D3e1RvLv1v2eeZ9txRHPnEEBUgSNLx5ghdzjHa0sgLWYVKssH+lYmV0JaWdoubo0ncGYLA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/utils@8.58.0': + resolution: {integrity: sha512-RfeSqcFeHMHlAWzt4TBjWOAtoW9lnsAGiP3GbaX9uVgTYYrMbVnGONEfUCiSss+xMHFl+eHZiipmA8WkQ7FuNA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/visitor-keys@8.58.0': + resolution: {integrity: sha512-XJ9UD9+bbDo4a4epraTwG3TsNPeiB9aShrUneAVXy8q4LuwowN+qu89/6ByLMINqvIMeI9H9hOHQtg/ijrYXzQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@vitejs/plugin-react@6.0.1': + resolution: {integrity: sha512-l9X/E3cDb+xY3SWzlG1MOGt2usfEHGMNIaegaUGFsLkb3RCn/k8/TOXBcab+OndDI4TBtktT8/9BwwW8Vi9KUQ==} + engines: {node: ^20.19.0 || >=22.12.0} + peerDependencies: + '@rolldown/plugin-babel': ^0.1.7 || ^0.2.0 + babel-plugin-react-compiler: ^1.0.0 + vite: ^8.0.0 + peerDependenciesMeta: + '@rolldown/plugin-babel': + optional: true + babel-plugin-react-compiler: + optional: true + + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn@8.16.0: + resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==} + engines: {node: '>=0.4.0'} + hasBin: true + + ajv@6.14.0: + resolution: {integrity: sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + balanced-match@4.0.4: + resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} + engines: {node: 18 || 20 || >=22} + + baseline-browser-mapping@2.10.16: + resolution: {integrity: sha512-Lyf3aK28zpsD1yQMiiHD4RvVb6UdMoo8xzG2XzFIfR9luPzOpcBlAsT/qfB1XWS1bxWT+UtE4WmQgsp297FYOA==} + engines: {node: '>=6.0.0'} + hasBin: true + + brace-expansion@1.1.13: + resolution: {integrity: sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==} + + brace-expansion@5.0.5: + resolution: {integrity: sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==} + engines: {node: 18 || 20 || >=22} + + browserslist@4.28.2: + resolution: {integrity: sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + + caniuse-lite@1.0.30001786: + resolution: {integrity: sha512-4oxTZEvqmLLrERwxO76yfKM7acZo310U+v4kqexI2TL1DkkUEMT8UijrxxcnVdxR3qkVf5awGRX+4Z6aPHVKrA==} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + clsx@2.1.1: + resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} + engines: {node: '>=6'} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + + cookie@1.1.1: + resolution: {integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==} + engines: {node: '>=18'} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + csstype@3.2.3: + resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} + engines: {node: '>=8'} + + electron-to-chromium@1.5.332: + resolution: {integrity: sha512-7OOtytmh/rINMLwaFTbcMVvYXO3AUm029X0LcyfYk0B557RlPkdpTpnH9+htMlfu5dKwOmT0+Zs2Aw+lnn6TeQ==} + + embla-carousel-react@8.6.0: + resolution: {integrity: sha512-0/PjqU7geVmo6F734pmPqpyHqiM99olvyecY7zdweCw+6tKEXnrE90pBiBbMMU8s5tICemzpQ3hi5EpxzGW+JA==} + peerDependencies: + react: ^16.8.0 || ^17.0.1 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + + embla-carousel-reactive-utils@8.6.0: + resolution: {integrity: sha512-fMVUDUEx0/uIEDM0Mz3dHznDhfX+znCCDCeIophYb1QGVM7YThSWX+wz11zlYwWFOr74b4QLGg0hrGPJeG2s4A==} + peerDependencies: + embla-carousel: 8.6.0 + + embla-carousel@8.6.0: + resolution: {integrity: sha512-SjWyZBHJPbqxHOzckOfo8lHisEaJWmwd23XppYFYVh10bU66/Pn5tkVkbkCMZVdbUE5eTCI2nD8OyIP4Z+uwkA==} + + enhanced-resolve@5.20.1: + resolution: {integrity: sha512-Qohcme7V1inbAfvjItgw0EaxVX5q2rdVEZHRBrEQdRZTssLDGsL8Lwrznl8oQ/6kuTJONLaDcGjkNP247XEhcA==} + engines: {node: '>=10.13.0'} + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + eslint-plugin-react-hooks@7.0.1: + resolution: {integrity: sha512-O0d0m04evaNzEPoSW+59Mezf8Qt0InfgGIBJnpC0h3NH/WjUAR7BIKUfysC6todmtiZ/A0oUVS8Gce0WhBrHsA==} + engines: {node: '>=18'} + peerDependencies: + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 + + eslint-plugin-react-refresh@0.5.2: + resolution: {integrity: sha512-hmgTH57GfzoTFjVN0yBwTggnsVUF2tcqi7RJZHqi9lIezSs4eFyAMktA68YD4r5kNw1mxyY4dmkyoFDb3FIqrA==} + peerDependencies: + eslint: ^9 || ^10 + + eslint-scope@8.4.0: + resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-visitor-keys@4.2.1: + resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint-visitor-keys@5.0.1: + resolution: {integrity: sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + eslint@9.39.4: + resolution: {integrity: sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true + + espree@10.4.0: + resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + esquery@1.7.0: + resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==} + engines: {node: '>=0.10'} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + file-entry-cache@8.0.0: + resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} + engines: {node: '>=16.0.0'} + + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + flat-cache@4.0.1: + resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} + engines: {node: '>=16'} + + flatted@3.4.2: + resolution: {integrity: sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==} + + framer-motion@12.38.0: + resolution: {integrity: sha512-rFYkY/pigbcswl1XQSb7q424kSTQ8q6eAC+YUsSKooHQYuLdzdHjrt6uxUC+PRAO++q5IS7+TamgIw1AphxR+g==} + peerDependencies: + '@emotion/is-prop-valid': '*' + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@emotion/is-prop-valid': + optional: true + react: + optional: true + react-dom: + optional: true + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + + globals@14.0.0: + resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} + engines: {node: '>=18'} + + globals@17.4.0: + resolution: {integrity: sha512-hjrNztw/VajQwOLsMNT1cbJiH2muO3OROCHnbehc8eY5JyD2gqz4AcMHPqgaOR59DjgUjYAYLeH699g/eWi2jw==} + engines: {node: '>=18'} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + hermes-estree@0.25.1: + resolution: {integrity: sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw==} + + hermes-parser@0.25.1: + resolution: {integrity: sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==} + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + ignore@7.0.5: + resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} + engines: {node: '>= 4'} + + import-fresh@3.3.1: + resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} + engines: {node: '>=6'} + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + jiti@2.6.1: + resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} + hasBin: true + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-yaml@4.1.1: + resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} + hasBin: true + + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} + hasBin: true + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + + lightningcss-android-arm64@1.32.0: + resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [android] + + lightningcss-darwin-arm64@1.32.0: + resolution: {integrity: sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [darwin] + + lightningcss-darwin-x64@1.32.0: + resolution: {integrity: sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [darwin] + + lightningcss-freebsd-x64@1.32.0: + resolution: {integrity: sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [freebsd] + + lightningcss-linux-arm-gnueabihf@1.32.0: + resolution: {integrity: sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==} + engines: {node: '>= 12.0.0'} + cpu: [arm] + os: [linux] + + lightningcss-linux-arm64-gnu@1.32.0: + resolution: {integrity: sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + lightningcss-linux-arm64-musl@1.32.0: + resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + libc: [musl] + + lightningcss-linux-x64-gnu@1.32.0: + resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + libc: [glibc] + + lightningcss-linux-x64-musl@1.32.0: + resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + libc: [musl] + + lightningcss-win32-arm64-msvc@1.32.0: + resolution: {integrity: sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [win32] + + lightningcss-win32-x64-msvc@1.32.0: + resolution: {integrity: sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [win32] + + lightningcss@1.32.0: + resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==} + engines: {node: '>= 12.0.0'} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + + lucide-react@1.7.0: + resolution: {integrity: sha512-yI7BeItCLZJTXikmK4KNUGCKoGzSvbKlfCvw44bU4fXAL6v3gYS4uHD1jzsLkfwODYwI6Drw5Tu9Z5ulDe0TSg==} + peerDependencies: + react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + + minimatch@10.2.5: + resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==} + engines: {node: 18 || 20 || >=22} + + minimatch@3.1.5: + resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==} + + motion-dom@12.38.0: + resolution: {integrity: sha512-pdkHLD8QYRp8VfiNLb8xIBJis1byQ9gPT3Jnh2jqfFtAsWUA3dEepDlsWe/xMpO8McV+VdpKVcp+E+TGJEtOoA==} + + motion-utils@12.36.0: + resolution: {integrity: sha512-eHWisygbiwVvf6PZ1vhaHCLamvkSbPIeAYxWUuL3a2PD/TROgE7FvfHWTIH4vMl798QLfMw15nRqIaRDXTlYRg==} + + motion@12.38.0: + resolution: {integrity: sha512-uYfXzeHlgThchzwz5Te47dlv5JOUC7OB4rjJ/7XTUgtBZD8CchMN8qEJ4ZVsUmTyYA44zjV0fBwsiktRuFnn+w==} + peerDependencies: + '@emotion/is-prop-valid': '*' + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@emotion/is-prop-valid': + optional: true + react: + optional: true + react-dom: + optional: true + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + + node-releases@2.0.37: + resolution: {integrity: sha512-1h5gKZCF+pO/o3Iqt5Jp7wc9rH3eJJ0+nh/CIoiRwjRxde/hAHyLPXYN4V3CqKAbiZPSeJFSWHmJsbkicta0Eg==} + + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@4.0.4: + resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} + engines: {node: '>=12'} + + postcss@8.5.9: + resolution: {integrity: sha512-7a70Nsot+EMX9fFU3064K/kdHWZqGVY+BADLyXc8Dfv+mTLLVl6JzJpPaCZ2kQL9gIJvKXSLMHhqdRRjwQeFtw==} + engines: {node: ^10 || ^12 || >=14} + + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + react-dom@19.2.4: + resolution: {integrity: sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==} + peerDependencies: + react: ^19.2.4 + + react-router-dom@7.14.0: + resolution: {integrity: sha512-2G3ajSVSZMEtmTjIklRWlNvo8wICEpLihfD/0YMDxbWK2UyP5EGfnoIn9AIQGnF3G/FX0MRbHXdFcD+rL1ZreQ==} + engines: {node: '>=20.0.0'} + peerDependencies: + react: '>=18' + react-dom: '>=18' + + react-router@7.14.0: + resolution: {integrity: sha512-m/xR9N4LQLmAS0ZhkY2nkPA1N7gQ5TUVa5n8TgANuDTARbn1gt+zLPXEm7W0XDTbrQ2AJSJKhoa6yx1D8BcpxQ==} + engines: {node: '>=20.0.0'} + peerDependencies: + react: '>=18' + react-dom: '>=18' + peerDependenciesMeta: + react-dom: + optional: true + + react@19.2.4: + resolution: {integrity: sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==} + engines: {node: '>=0.10.0'} + + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + + rolldown@1.0.0-rc.13: + resolution: {integrity: sha512-bvVj8YJmf0rq4pSFmH7laLa6pYrhghv3PRzrCdRAr23g66zOKVJ4wkvFtgohtPLWmthgg8/rkaqRHrpUEh0Zbw==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + + scheduler@0.27.0: + resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + semver@7.7.4: + resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==} + engines: {node: '>=10'} + hasBin: true + + set-cookie-parser@2.7.2: + resolution: {integrity: sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==} + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + tailwind-merge@3.5.0: + resolution: {integrity: sha512-I8K9wewnVDkL1NTGoqWmVEIlUcB9gFriAEkXkfCjX5ib8ezGxtR3xD7iZIxrfArjEsH7F1CHD4RFUtxefdqV/A==} + + tailwindcss@4.2.2: + resolution: {integrity: sha512-KWBIxs1Xb6NoLdMVqhbhgwZf2PGBpPEiwOqgI4pFIYbNTfBXiKYyWoTsXgBQ9WFg/OlhnvHaY+AEpW7wSmFo2Q==} + + tapable@2.3.2: + resolution: {integrity: sha512-1MOpMXuhGzGL5TTCZFItxCc0AARf1EZFQkGqMm7ERKj8+Hgr5oLvJOVFcC+lRmR8hCe2S3jC4T5D7Vg/d7/fhA==} + engines: {node: '>=6'} + + tinyglobby@0.2.16: + resolution: {integrity: sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==} + engines: {node: '>=12.0.0'} + + ts-api-utils@2.5.0: + resolution: {integrity: sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==} + engines: {node: '>=18.12'} + peerDependencies: + typescript: '>=4.8.4' + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + + typescript-eslint@8.58.0: + resolution: {integrity: sha512-e2TQzKfaI85fO+F3QywtX+tCTsu/D3WW5LVU6nz8hTFKFZ8yBJ6mSYRpXqdR3mFjPWmO0eWsTa5f+UpAOe/FMA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + typescript@6.0.2: + resolution: {integrity: sha512-bGdAIrZ0wiGDo5l8c++HWtbaNCWTS4UTv7RaTH/ThVIgjkveJt83m74bBHMJkuCbslY8ixgLBVZJIOiQlQTjfQ==} + engines: {node: '>=14.17'} + hasBin: true + + undici-types@7.16.0: + resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} + + update-browserslist-db@1.2.3: + resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + vite@8.0.7: + resolution: {integrity: sha512-P1PbweD+2/udplnThz3btF4cf6AgPky7kk23RtHUkJIU5BIxwPprhRGmOAHs6FTI7UiGbTNrgNP6jSYD6JaRnw==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + '@types/node': ^20.19.0 || >=22.12.0 + '@vitejs/devtools': ^0.1.0 + esbuild: ^0.27.0 || ^0.28.0 + jiti: '>=1.21.0' + less: ^4.0.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + '@vitejs/devtools': + optional: true + esbuild: + optional: true + jiti: + optional: true + less: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + + zod-validation-error@4.0.2: + resolution: {integrity: sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ==} + engines: {node: '>=18.0.0'} + peerDependencies: + zod: ^3.25.0 || ^4.0.0 + + zod@4.3.6: + resolution: {integrity: sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==} + +snapshots: + + '@babel/code-frame@7.29.0': + dependencies: + '@babel/helper-validator-identifier': 7.28.5 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/compat-data@7.29.0': {} + + '@babel/core@7.29.0': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) + '@babel/helpers': 7.29.2 + '@babel/parser': 7.29.2 + '@babel/template': 7.28.6 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + '@jridgewell/remapping': 2.3.5 + convert-source-map: 2.0.0 + debug: 4.4.3 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/generator@7.29.1': + dependencies: + '@babel/parser': 7.29.2 + '@babel/types': 7.29.0 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + jsesc: 3.1.0 + + '@babel/helper-compilation-targets@7.28.6': + dependencies: + '@babel/compat-data': 7.29.0 + '@babel/helper-validator-option': 7.27.1 + browserslist: 4.28.2 + lru-cache: 5.1.1 + semver: 6.3.1 + + '@babel/helper-globals@7.28.0': {} + + '@babel/helper-module-imports@7.28.6': + dependencies: + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-module-imports': 7.28.6 + '@babel/helper-validator-identifier': 7.28.5 + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-string-parser@7.27.1': {} + + '@babel/helper-validator-identifier@7.28.5': {} + + '@babel/helper-validator-option@7.27.1': {} + + '@babel/helpers@7.29.2': + dependencies: + '@babel/template': 7.28.6 + '@babel/types': 7.29.0 + + '@babel/parser@7.29.2': + dependencies: + '@babel/types': 7.29.0 + + '@babel/template@7.28.6': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/parser': 7.29.2 + '@babel/types': 7.29.0 + + '@babel/traverse@7.29.0': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/helper-globals': 7.28.0 + '@babel/parser': 7.29.2 + '@babel/template': 7.28.6 + '@babel/types': 7.29.0 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + '@babel/types@7.29.0': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 + + '@emnapi/core@1.9.1': + dependencies: + '@emnapi/wasi-threads': 1.2.0 + tslib: 2.8.1 + optional: true + + '@emnapi/runtime@1.9.1': + dependencies: + tslib: 2.8.1 + optional: true + + '@emnapi/wasi-threads@1.2.0': + dependencies: + tslib: 2.8.1 + optional: true + + '@eslint-community/eslint-utils@4.9.1(eslint@9.39.4(jiti@2.6.1))': + dependencies: + eslint: 9.39.4(jiti@2.6.1) + eslint-visitor-keys: 3.4.3 + + '@eslint-community/regexpp@4.12.2': {} + + '@eslint/config-array@0.21.2': + dependencies: + '@eslint/object-schema': 2.1.7 + debug: 4.4.3 + minimatch: 3.1.5 + transitivePeerDependencies: + - supports-color + + '@eslint/config-helpers@0.4.2': + dependencies: + '@eslint/core': 0.17.0 + + '@eslint/core@0.17.0': + dependencies: + '@types/json-schema': 7.0.15 + + '@eslint/eslintrc@3.3.5': + dependencies: + ajv: 6.14.0 + debug: 4.4.3 + espree: 10.4.0 + globals: 14.0.0 + ignore: 5.3.2 + import-fresh: 3.3.1 + js-yaml: 4.1.1 + minimatch: 3.1.5 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + '@eslint/js@9.39.4': {} + + '@eslint/object-schema@2.1.7': {} + + '@eslint/plugin-kit@0.4.1': + dependencies: + '@eslint/core': 0.17.0 + levn: 0.4.1 + + '@humanfs/core@0.19.1': {} + + '@humanfs/node@0.16.7': + dependencies: + '@humanfs/core': 0.19.1 + '@humanwhocodes/retry': 0.4.3 + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/retry@0.4.3': {} + + '@jridgewell/gen-mapping@0.3.13': + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/remapping@2.3.5': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/sourcemap-codec@1.5.5': {} + + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + + '@napi-rs/wasm-runtime@1.1.2(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)': + dependencies: + '@emnapi/core': 1.9.1 + '@emnapi/runtime': 1.9.1 + '@tybys/wasm-util': 0.10.1 + optional: true + + '@oxc-project/types@0.123.0': {} + + '@rolldown/binding-android-arm64@1.0.0-rc.13': + optional: true + + '@rolldown/binding-darwin-arm64@1.0.0-rc.13': + optional: true + + '@rolldown/binding-darwin-x64@1.0.0-rc.13': + optional: true + + '@rolldown/binding-freebsd-x64@1.0.0-rc.13': + optional: true + + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.13': + optional: true + + '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.13': + optional: true + + '@rolldown/binding-linux-arm64-musl@1.0.0-rc.13': + optional: true + + '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.13': + optional: true + + '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.13': + optional: true + + '@rolldown/binding-linux-x64-gnu@1.0.0-rc.13': + optional: true + + '@rolldown/binding-linux-x64-musl@1.0.0-rc.13': + optional: true + + '@rolldown/binding-openharmony-arm64@1.0.0-rc.13': + optional: true + + '@rolldown/binding-wasm32-wasi@1.0.0-rc.13': + dependencies: + '@emnapi/core': 1.9.1 + '@emnapi/runtime': 1.9.1 + '@napi-rs/wasm-runtime': 1.1.2(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1) + optional: true + + '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.13': + optional: true + + '@rolldown/binding-win32-x64-msvc@1.0.0-rc.13': + optional: true + + '@rolldown/pluginutils@1.0.0-rc.13': {} + + '@rolldown/pluginutils@1.0.0-rc.7': {} + + '@tailwindcss/node@4.2.2': + dependencies: + '@jridgewell/remapping': 2.3.5 + enhanced-resolve: 5.20.1 + jiti: 2.6.1 + lightningcss: 1.32.0 + magic-string: 0.30.21 + source-map-js: 1.2.1 + tailwindcss: 4.2.2 + + '@tailwindcss/oxide-android-arm64@4.2.2': + optional: true + + '@tailwindcss/oxide-darwin-arm64@4.2.2': + optional: true + + '@tailwindcss/oxide-darwin-x64@4.2.2': + optional: true + + '@tailwindcss/oxide-freebsd-x64@4.2.2': + optional: true + + '@tailwindcss/oxide-linux-arm-gnueabihf@4.2.2': + optional: true + + '@tailwindcss/oxide-linux-arm64-gnu@4.2.2': + optional: true + + '@tailwindcss/oxide-linux-arm64-musl@4.2.2': + optional: true + + '@tailwindcss/oxide-linux-x64-gnu@4.2.2': + optional: true + + '@tailwindcss/oxide-linux-x64-musl@4.2.2': + optional: true + + '@tailwindcss/oxide-wasm32-wasi@4.2.2': + optional: true + + '@tailwindcss/oxide-win32-arm64-msvc@4.2.2': + optional: true + + '@tailwindcss/oxide-win32-x64-msvc@4.2.2': + optional: true + + '@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 + + '@tailwindcss/vite@4.2.2(vite@8.0.7(@types/node@24.12.2)(jiti@2.6.1))': + dependencies: + '@tailwindcss/node': 4.2.2 + '@tailwindcss/oxide': 4.2.2 + tailwindcss: 4.2.2 + vite: 8.0.7(@types/node@24.12.2)(jiti@2.6.1) + + '@tybys/wasm-util@0.10.1': + dependencies: + tslib: 2.8.1 + optional: true + + '@types/estree@1.0.8': {} + + '@types/json-schema@7.0.15': {} + + '@types/node@24.12.2': + dependencies: + undici-types: 7.16.0 + + '@types/react-dom@19.2.3(@types/react@19.2.14)': + dependencies: + '@types/react': 19.2.14 + + '@types/react@19.2.14': + dependencies: + csstype: 3.2.3 + + '@typescript-eslint/eslint-plugin@8.58.0(@typescript-eslint/parser@8.58.0(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.2))(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.2)': + dependencies: + '@eslint-community/regexpp': 4.12.2 + '@typescript-eslint/parser': 8.58.0(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.2) + '@typescript-eslint/scope-manager': 8.58.0 + '@typescript-eslint/type-utils': 8.58.0(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.2) + '@typescript-eslint/utils': 8.58.0(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.2) + '@typescript-eslint/visitor-keys': 8.58.0 + eslint: 9.39.4(jiti@2.6.1) + ignore: 7.0.5 + natural-compare: 1.4.0 + ts-api-utils: 2.5.0(typescript@6.0.2) + typescript: 6.0.2 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@8.58.0(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.2)': + dependencies: + '@typescript-eslint/scope-manager': 8.58.0 + '@typescript-eslint/types': 8.58.0 + '@typescript-eslint/typescript-estree': 8.58.0(typescript@6.0.2) + '@typescript-eslint/visitor-keys': 8.58.0 + debug: 4.4.3 + eslint: 9.39.4(jiti@2.6.1) + typescript: 6.0.2 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/project-service@8.58.0(typescript@6.0.2)': + dependencies: + '@typescript-eslint/tsconfig-utils': 8.58.0(typescript@6.0.2) + '@typescript-eslint/types': 8.58.0 + debug: 4.4.3 + typescript: 6.0.2 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/scope-manager@8.58.0': + dependencies: + '@typescript-eslint/types': 8.58.0 + '@typescript-eslint/visitor-keys': 8.58.0 + + '@typescript-eslint/tsconfig-utils@8.58.0(typescript@6.0.2)': + dependencies: + typescript: 6.0.2 + + '@typescript-eslint/type-utils@8.58.0(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.2)': + dependencies: + '@typescript-eslint/types': 8.58.0 + '@typescript-eslint/typescript-estree': 8.58.0(typescript@6.0.2) + '@typescript-eslint/utils': 8.58.0(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.2) + debug: 4.4.3 + eslint: 9.39.4(jiti@2.6.1) + ts-api-utils: 2.5.0(typescript@6.0.2) + typescript: 6.0.2 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/types@8.58.0': {} + + '@typescript-eslint/typescript-estree@8.58.0(typescript@6.0.2)': + dependencies: + '@typescript-eslint/project-service': 8.58.0(typescript@6.0.2) + '@typescript-eslint/tsconfig-utils': 8.58.0(typescript@6.0.2) + '@typescript-eslint/types': 8.58.0 + '@typescript-eslint/visitor-keys': 8.58.0 + debug: 4.4.3 + minimatch: 10.2.5 + semver: 7.7.4 + tinyglobby: 0.2.16 + ts-api-utils: 2.5.0(typescript@6.0.2) + typescript: 6.0.2 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@8.58.0(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.2)': + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.6.1)) + '@typescript-eslint/scope-manager': 8.58.0 + '@typescript-eslint/types': 8.58.0 + '@typescript-eslint/typescript-estree': 8.58.0(typescript@6.0.2) + eslint: 9.39.4(jiti@2.6.1) + typescript: 6.0.2 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/visitor-keys@8.58.0': + dependencies: + '@typescript-eslint/types': 8.58.0 + eslint-visitor-keys: 5.0.1 + + '@vitejs/plugin-react@6.0.1(vite@8.0.7(@types/node@24.12.2)(jiti@2.6.1))': + dependencies: + '@rolldown/pluginutils': 1.0.0-rc.7 + vite: 8.0.7(@types/node@24.12.2)(jiti@2.6.1) + + acorn-jsx@5.3.2(acorn@8.16.0): + dependencies: + acorn: 8.16.0 + + acorn@8.16.0: {} + + ajv@6.14.0: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + argparse@2.0.1: {} + + balanced-match@1.0.2: {} + + balanced-match@4.0.4: {} + + baseline-browser-mapping@2.10.16: {} + + brace-expansion@1.1.13: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@5.0.5: + dependencies: + balanced-match: 4.0.4 + + browserslist@4.28.2: + dependencies: + baseline-browser-mapping: 2.10.16 + caniuse-lite: 1.0.30001786 + electron-to-chromium: 1.5.332 + node-releases: 2.0.37 + update-browserslist-db: 1.2.3(browserslist@4.28.2) + + callsites@3.1.0: {} + + caniuse-lite@1.0.30001786: {} + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + clsx@2.1.1: {} + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + concat-map@0.0.1: {} + + convert-source-map@2.0.0: {} + + cookie@1.1.1: {} + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + csstype@3.2.3: {} + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + deep-is@0.1.4: {} + + detect-libc@2.1.2: {} + + electron-to-chromium@1.5.332: {} + + embla-carousel-react@8.6.0(react@19.2.4): + dependencies: + embla-carousel: 8.6.0 + embla-carousel-reactive-utils: 8.6.0(embla-carousel@8.6.0) + react: 19.2.4 + + embla-carousel-reactive-utils@8.6.0(embla-carousel@8.6.0): + dependencies: + embla-carousel: 8.6.0 + + embla-carousel@8.6.0: {} + + enhanced-resolve@5.20.1: + dependencies: + graceful-fs: 4.2.11 + tapable: 2.3.2 + + escalade@3.2.0: {} + + escape-string-regexp@4.0.0: {} + + eslint-plugin-react-hooks@7.0.1(eslint@9.39.4(jiti@2.6.1)): + dependencies: + '@babel/core': 7.29.0 + '@babel/parser': 7.29.2 + eslint: 9.39.4(jiti@2.6.1) + hermes-parser: 0.25.1 + zod: 4.3.6 + zod-validation-error: 4.0.2(zod@4.3.6) + transitivePeerDependencies: + - supports-color + + eslint-plugin-react-refresh@0.5.2(eslint@9.39.4(jiti@2.6.1)): + dependencies: + eslint: 9.39.4(jiti@2.6.1) + + eslint-scope@8.4.0: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-visitor-keys@3.4.3: {} + + eslint-visitor-keys@4.2.1: {} + + eslint-visitor-keys@5.0.1: {} + + eslint@9.39.4(jiti@2.6.1): + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.6.1)) + '@eslint-community/regexpp': 4.12.2 + '@eslint/config-array': 0.21.2 + '@eslint/config-helpers': 0.4.2 + '@eslint/core': 0.17.0 + '@eslint/eslintrc': 3.3.5 + '@eslint/js': 9.39.4 + '@eslint/plugin-kit': 0.4.1 + '@humanfs/node': 0.16.7 + '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.4.3 + '@types/estree': 1.0.8 + ajv: 6.14.0 + chalk: 4.1.2 + cross-spawn: 7.0.6 + debug: 4.4.3 + escape-string-regexp: 4.0.0 + eslint-scope: 8.4.0 + eslint-visitor-keys: 4.2.1 + espree: 10.4.0 + esquery: 1.7.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 8.0.0 + find-up: 5.0.0 + glob-parent: 6.0.2 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + json-stable-stringify-without-jsonify: 1.0.1 + lodash.merge: 4.6.2 + minimatch: 3.1.5 + natural-compare: 1.4.0 + optionator: 0.9.4 + optionalDependencies: + jiti: 2.6.1 + transitivePeerDependencies: + - supports-color + + espree@10.4.0: + dependencies: + acorn: 8.16.0 + acorn-jsx: 5.3.2(acorn@8.16.0) + eslint-visitor-keys: 4.2.1 + + esquery@1.7.0: + dependencies: + estraverse: 5.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@5.3.0: {} + + esutils@2.0.3: {} + + fast-deep-equal@3.1.3: {} + + fast-json-stable-stringify@2.1.0: {} + + fast-levenshtein@2.0.6: {} + + fdir@6.5.0(picomatch@4.0.4): + optionalDependencies: + picomatch: 4.0.4 + + file-entry-cache@8.0.0: + dependencies: + flat-cache: 4.0.1 + + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + flat-cache@4.0.1: + dependencies: + flatted: 3.4.2 + keyv: 4.5.4 + + flatted@3.4.2: {} + + framer-motion@12.38.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4): + dependencies: + motion-dom: 12.38.0 + motion-utils: 12.36.0 + tslib: 2.8.1 + optionalDependencies: + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + fsevents@2.3.3: + optional: true + + gensync@1.0.0-beta.2: {} + + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + globals@14.0.0: {} + + globals@17.4.0: {} + + graceful-fs@4.2.11: {} + + has-flag@4.0.0: {} + + hermes-estree@0.25.1: {} + + hermes-parser@0.25.1: + dependencies: + hermes-estree: 0.25.1 + + ignore@5.3.2: {} + + ignore@7.0.5: {} + + import-fresh@3.3.1: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + imurmurhash@0.1.4: {} + + is-extglob@2.1.1: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + isexe@2.0.0: {} + + jiti@2.6.1: {} + + js-tokens@4.0.0: {} + + js-yaml@4.1.1: + dependencies: + argparse: 2.0.1 + + jsesc@3.1.0: {} + + json-buffer@3.0.1: {} + + json-schema-traverse@0.4.1: {} + + json-stable-stringify-without-jsonify@1.0.1: {} + + json5@2.2.3: {} + + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + levn@0.4.1: + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + + lightningcss-android-arm64@1.32.0: + optional: true + + lightningcss-darwin-arm64@1.32.0: + optional: true + + lightningcss-darwin-x64@1.32.0: + optional: true + + lightningcss-freebsd-x64@1.32.0: + optional: true + + lightningcss-linux-arm-gnueabihf@1.32.0: + optional: true + + lightningcss-linux-arm64-gnu@1.32.0: + optional: true + + lightningcss-linux-arm64-musl@1.32.0: + optional: true + + lightningcss-linux-x64-gnu@1.32.0: + optional: true + + lightningcss-linux-x64-musl@1.32.0: + optional: true + + lightningcss-win32-arm64-msvc@1.32.0: + optional: true + + lightningcss-win32-x64-msvc@1.32.0: + optional: true + + lightningcss@1.32.0: + dependencies: + detect-libc: 2.1.2 + 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 + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + lodash.merge@4.6.2: {} + + lru-cache@5.1.1: + dependencies: + yallist: 3.1.1 + + lucide-react@1.7.0(react@19.2.4): + dependencies: + react: 19.2.4 + + magic-string@0.30.21: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + + minimatch@10.2.5: + dependencies: + brace-expansion: 5.0.5 + + minimatch@3.1.5: + dependencies: + brace-expansion: 1.1.13 + + motion-dom@12.38.0: + dependencies: + motion-utils: 12.36.0 + + motion-utils@12.36.0: {} + + motion@12.38.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4): + dependencies: + framer-motion: 12.38.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + tslib: 2.8.1 + optionalDependencies: + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + ms@2.1.3: {} + + nanoid@3.3.11: {} + + natural-compare@1.4.0: {} + + node-releases@2.0.37: {} + + optionator@0.9.4: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + + path-exists@4.0.0: {} + + path-key@3.1.1: {} + + picocolors@1.1.1: {} + + picomatch@4.0.4: {} + + postcss@8.5.9: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + prelude-ls@1.2.1: {} + + punycode@2.3.1: {} + + react-dom@19.2.4(react@19.2.4): + dependencies: + react: 19.2.4 + scheduler: 0.27.0 + + react-router-dom@7.14.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4): + dependencies: + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + react-router: 7.14.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + + react-router@7.14.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4): + dependencies: + cookie: 1.1.1 + react: 19.2.4 + set-cookie-parser: 2.7.2 + optionalDependencies: + react-dom: 19.2.4(react@19.2.4) + + react@19.2.4: {} + + resolve-from@4.0.0: {} + + rolldown@1.0.0-rc.13: + dependencies: + '@oxc-project/types': 0.123.0 + '@rolldown/pluginutils': 1.0.0-rc.13 + optionalDependencies: + '@rolldown/binding-android-arm64': 1.0.0-rc.13 + '@rolldown/binding-darwin-arm64': 1.0.0-rc.13 + '@rolldown/binding-darwin-x64': 1.0.0-rc.13 + '@rolldown/binding-freebsd-x64': 1.0.0-rc.13 + '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-rc.13 + '@rolldown/binding-linux-arm64-gnu': 1.0.0-rc.13 + '@rolldown/binding-linux-arm64-musl': 1.0.0-rc.13 + '@rolldown/binding-linux-ppc64-gnu': 1.0.0-rc.13 + '@rolldown/binding-linux-s390x-gnu': 1.0.0-rc.13 + '@rolldown/binding-linux-x64-gnu': 1.0.0-rc.13 + '@rolldown/binding-linux-x64-musl': 1.0.0-rc.13 + '@rolldown/binding-openharmony-arm64': 1.0.0-rc.13 + '@rolldown/binding-wasm32-wasi': 1.0.0-rc.13 + '@rolldown/binding-win32-arm64-msvc': 1.0.0-rc.13 + '@rolldown/binding-win32-x64-msvc': 1.0.0-rc.13 + + scheduler@0.27.0: {} + + semver@6.3.1: {} + + semver@7.7.4: {} + + set-cookie-parser@2.7.2: {} + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + source-map-js@1.2.1: {} + + strip-json-comments@3.1.1: {} + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + tailwind-merge@3.5.0: {} + + tailwindcss@4.2.2: {} + + tapable@2.3.2: {} + + tinyglobby@0.2.16: + dependencies: + fdir: 6.5.0(picomatch@4.0.4) + picomatch: 4.0.4 + + ts-api-utils@2.5.0(typescript@6.0.2): + dependencies: + typescript: 6.0.2 + + tslib@2.8.1: {} + + type-check@0.4.0: + dependencies: + prelude-ls: 1.2.1 + + typescript-eslint@8.58.0(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.2): + dependencies: + '@typescript-eslint/eslint-plugin': 8.58.0(@typescript-eslint/parser@8.58.0(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.2))(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.2) + '@typescript-eslint/parser': 8.58.0(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.2) + '@typescript-eslint/typescript-estree': 8.58.0(typescript@6.0.2) + '@typescript-eslint/utils': 8.58.0(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.2) + eslint: 9.39.4(jiti@2.6.1) + typescript: 6.0.2 + transitivePeerDependencies: + - supports-color + + typescript@6.0.2: {} + + undici-types@7.16.0: {} + + update-browserslist-db@1.2.3(browserslist@4.28.2): + dependencies: + browserslist: 4.28.2 + escalade: 3.2.0 + picocolors: 1.1.1 + + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + + vite@8.0.7(@types/node@24.12.2)(jiti@2.6.1): + dependencies: + lightningcss: 1.32.0 + picomatch: 4.0.4 + postcss: 8.5.9 + rolldown: 1.0.0-rc.13 + tinyglobby: 0.2.16 + optionalDependencies: + '@types/node': 24.12.2 + fsevents: 2.3.3 + jiti: 2.6.1 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + word-wrap@1.2.5: {} + + yallist@3.1.1: {} + + yocto-queue@0.1.0: {} + + zod-validation-error@4.0.2(zod@4.3.6): + dependencies: + zod: 4.3.6 + + zod@4.3.6: {} diff --git a/public/favicon.svg b/public/favicon.svg new file mode 100644 index 0000000..6893eb1 --- /dev/null +++ b/public/favicon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/registry.json b/registry.json new file mode 100644 index 0000000..cfdb266 --- /dev/null +++ b/registry.json @@ -0,0 +1,1010 @@ +{ + "componentRegistry": { + "navbar": [ + { + "name": "NavbarCentered", + "import": "import NavbarCentered from '@/components/ui/NavbarCentered';", + "path": "@/components/ui/NavbarCentered", + "description": "Centered navigation bar with logo, links and buttons", + "propsSchema": { + "logo": "string", + "navItems": "{ name: string; href: string }[] // href uses \"#sectionId\" format for same-page scroll links", + "ctaButton": "{ text: string; href: string }" + } + } + ] + }, + "sectionRegistry": { + "hero": [ + { + "name": "HeroBillboard", + "import": "import HeroBillboard from '@/components/sections/hero/HeroBillboard';", + "path": "@/components/sections/hero/HeroBillboard", + "description": "Full-width centered hero with media below text content", + "propsSchema": { + "tag": "string", + "title": "string", + "description": "string", + "primaryButton": "{ text: string; href: string }", + "secondaryButton": "{ text: string; href: string }", + "imageSrc | videoSrc": "{ imageSrc: string; videoSrc?: never } | { videoSrc: string; imageSrc?: never }" + } + }, + { + "name": "HeroBillboardGallery", + "import": "import HeroBillboardGallery from '@/components/sections/hero/HeroBillboardGallery';", + "path": "@/components/sections/hero/HeroBillboardGallery", + "description": "Full-width centered hero with image gallery below", + "propsSchema": { + "tag": "string", + "title": "string", + "description": "string", + "primaryButton": "{ text: string; href: string }", + "secondaryButton": "{ text: string; href: string }", + "items": "({ imageSrc: string; videoSrc?: never } | { videoSrc: string; imageSrc?: never })[]" + } + }, + { + "name": "HeroSplit", + "import": "import HeroSplit from '@/components/sections/hero/HeroSplit';", + "path": "@/components/sections/hero/HeroSplit", + "description": "Split layout hero with text on left, media on right", + "propsSchema": { + "tag": "string", + "title": "string", + "description": "string", + "primaryButton": "{ text: string; href: string }", + "secondaryButton": "{ text: string; href: string }", + "imageSrc | videoSrc": "{ imageSrc: string; videoSrc?: never } | { videoSrc: string; imageSrc?: never }" + } + } + ], + "about": [ + { + "name": "AboutFeaturesSplit", + "import": "import AboutFeaturesSplit from '@/components/sections/about/AboutFeaturesSplit';", + "path": "@/components/sections/about/AboutFeaturesSplit", + "description": "About section with feature list on left, media on right", + "propsSchema": { + "tag": "string", + "title": "string", + "description": "string", + "primaryButton?": "{ text: string; href: string }", + "secondaryButton?": "{ text: string; href: string }", + "items": "{ icon: LucideIcon; title: string; description: string }[]", + "imageSrc | videoSrc": "{ imageSrc: string; videoSrc?: never } | { videoSrc: string; imageSrc?: never }" + } + }, + { + "name": "AboutMediaOverlay", + "import": "import AboutMediaOverlay from '@/components/sections/about/AboutMediaOverlay';", + "path": "@/components/sections/about/AboutMediaOverlay", + "description": "About section with text overlaid on media background", + "propsSchema": { + "tag": "string", + "title": "string", + "description": "string", + "primaryButton?": "{ text: string; href: string }", + "secondaryButton?": "{ text: string; href: string }", + "imageSrc | videoSrc": "{ imageSrc: string; videoSrc?: never } | { videoSrc: string; imageSrc?: never }" + } + }, + { + "name": "AboutTestimonial", + "import": "import AboutTestimonial from '@/components/sections/about/AboutTestimonial';", + "path": "@/components/sections/about/AboutTestimonial", + "description": "Testimonial section with quote and author info", + "propsSchema": { + "tag": "string", + "quote": "string", + "author": "string", + "role": "string", + "imageSrc | videoSrc": "{ imageSrc: string; videoSrc?: never } | { videoSrc: string; imageSrc?: never }" + } + }, + { + "name": "AboutTextSplit", + "import": "import AboutTextSplit from '@/components/sections/about/AboutTextSplit';", + "path": "@/components/sections/about/AboutTextSplit", + "description": "Text-only about section with title on left, descriptions on right", + "propsSchema": { + "title": "string", + "descriptions": "string[] // array of text paragraphs, NO imageSrc or media props", + "primaryButton?": "{ text: string; href: string }", + "secondaryButton?": "{ text: string; href: string }" + } + } + ], + "features": [ + { + "name": "FeaturesMediaCards", + "import": "import FeaturesMediaCards from '@/components/sections/features/FeaturesMediaCards';", + "path": "@/components/sections/features/FeaturesMediaCards", + "description": "Features section with media cards in grid or carousel", + "propsSchema": { + "tag": "string", + "title": "string", + "description": "string", + "primaryButton?": "{ text: string; href: string }", + "secondaryButton?": "{ text: string; href: string }", + "items": "({ title: string; description: string } & ({ imageSrc: string; videoSrc?: never } | { videoSrc: string; imageSrc?: never }))[]" + } + }, + { + "name": "FeaturesAlternatingSplit", + "import": "import FeaturesAlternatingSplit from '@/components/sections/features/FeaturesAlternatingSplit';", + "path": "@/components/sections/features/FeaturesAlternatingSplit", + "description": "Features section with numbered alternating left/right split cards", + "propsSchema": { + "tag": "string", + "title": "string", + "description": "string", + "primaryButton?": "{ text: string; href: string }", + "secondaryButton?": "{ text: string; href: string }", + "items": "({ title: string; description: string; primaryButton?: { text: string; href: string }; secondaryButton?: { text: string; href: string } } & ({ imageSrc: string; videoSrc?: never } | { videoSrc: string; imageSrc?: never }))[]" + } + }, + { + "name": "FeaturesLabeledList", + "import": "import FeaturesLabeledList from '@/components/sections/features/FeaturesLabeledList';", + "path": "@/components/sections/features/FeaturesLabeledList", + "description": "Features section with large labels and bullet-separated item lists", + "propsSchema": { + "tag": "string", + "title": "string", + "description": "string", + "primaryButton?": "{ text: string; href: string }", + "secondaryButton?": "{ text: string; href: string }", + "items": "{ label: string; title: string; bullets: string[]; primaryButton: { text: string; href: string }; secondaryButton: { text: string; href: string } }[]" + } + }, + { + "name": "FeaturesComparison", + "import": "import FeaturesComparison from '@/components/sections/features/FeaturesComparison';", + "path": "@/components/sections/features/FeaturesComparison", + "description": "Features comparison section with negative and positive lists side by side", + "propsSchema": { + "tag": "string", + "title": "string", + "description": "string", + "primaryButton?": "{ text: string; href: string }", + "secondaryButton?": "{ text: string; href: string }", + "negativeItems": "string[]", + "positiveItems": "string[]" + } + }, + { + "name": "FeaturesDetailedSteps", + "import": "import FeaturesDetailedSteps from '@/components/sections/features/FeaturesDetailedSteps';", + "path": "@/components/sections/features/FeaturesDetailedSteps", + "description": "Features section with detailed step cards including tag, title, subtitle, description, and tilted media", + "propsSchema": { + "tag": "string", + "title": "string", + "description": "string", + "primaryButton?": "{ text: string; href: string }", + "secondaryButton?": "{ text: string; href: string }", + "steps": "({ tag: string; title: string; subtitle: string; description: string } & ({ imageSrc: string; videoSrc?: never } | { videoSrc: string; imageSrc?: never }))[]" + } + }, + { + "name": "FeaturesTaggedCards", + "import": "import FeaturesTaggedCards from '@/components/sections/features/FeaturesTaggedCards';", + "path": "@/components/sections/features/FeaturesTaggedCards", + "description": "Features section with media cards featuring tag overlay on image and content card below", + "propsSchema": { + "tag": "string", + "title": "string", + "description": "string", + "primaryButton?": "{ text: string; href: string }", + "secondaryButton?": "{ text: string; href: string }", + "items": "({ tag: string; title: string; description: string; primaryButton?: { text: string; href: string }; secondaryButton?: { text: string; href: string } } & ({ imageSrc: string; videoSrc?: never } | { videoSrc: string; imageSrc?: never }))[]" + } + }, + { + "name": "FeaturesArrowCards", + "import": "import FeaturesArrowCards from '@/components/sections/features/FeaturesArrowCards';", + "path": "@/components/sections/features/FeaturesArrowCards", + "description": "Features section with media cards featuring title, tags, and arrow icon for navigation", + "propsSchema": { + "tag": "string", + "title": "string", + "description": "string", + "primaryButton?": "{ text: string; href: string }", + "secondaryButton?": "{ text: string; href: string }", + "items": "({ title: string; tags: string[] } & ({ imageSrc: string; videoSrc?: never } | { videoSrc: string; imageSrc?: never }))[]" + } + }, + { + "name": "FeaturesDetailedCards", + "import": "import FeaturesDetailedCards from '@/components/sections/features/FeaturesDetailedCards';", + "path": "@/components/sections/features/FeaturesDetailedCards", + "description": "Features section with horizontal split cards featuring title, author, tags, description, and media", + "propsSchema": { + "tag": "string", + "title": "string", + "description": "string", + "primaryButton?": "{ text: string; href: string }", + "secondaryButton?": "{ text: string; href: string }", + "items": "({ title: string; description: string; tags: string[] } & ({ imageSrc: string; videoSrc?: never } | { videoSrc: string; imageSrc?: never }))[]" + } + }, + { + "name": "FeaturesDualMedia", + "import": "import FeaturesDualMedia from '@/components/sections/features/FeaturesDualMedia';", + "path": "@/components/sections/features/FeaturesDualMedia", + "description": "Features section with icon cards featuring two media items side by side", + "propsSchema": { + "tag": "string", + "title": "string", + "description": "string", + "primaryButton?": "{ text: string; href: string }", + "secondaryButton?": "{ text: string; href: string }", + "items": "{ icon: LucideIcon; title: string; description: string; mediaItems: [({ imageSrc: string; videoSrc?: never } | { videoSrc: string; imageSrc?: never }), ({ imageSrc: string; videoSrc?: never } | { videoSrc: string; imageSrc?: never })] }[]" + } + }, + { + "name": "FeaturesMediaCarousel", + "import": "import FeaturesMediaCarousel from '@/components/sections/features/FeaturesMediaCarousel';", + "path": "@/components/sections/features/FeaturesMediaCarousel", + "description": "Carousel of cards with media background and text overlay at bottom", + "propsSchema": { + "tag": "string", + "title": "string", + "description": "string", + "primaryButton?": "{ text: string; href: string }", + "secondaryButton?": "{ text: string; href: string }", + "items": "({ title: string; description: string; buttonIcon: LucideIcon; buttonHref?: string; buttonOnClick?: () => void } & ({ imageSrc: string; videoSrc?: never } | { videoSrc: string; imageSrc?: never }))[]" + } + }, + { + "name": "FeaturesFlipCards", + "import": "import FeaturesFlipCards from '@/components/sections/features/FeaturesFlipCards';", + "path": "@/components/sections/features/FeaturesFlipCards", + "description": "Grid of cards that flip on click to reveal descriptions on the back", + "propsSchema": { + "tag": "string", + "title": "string", + "description": "string", + "primaryButton?": "{ text: string; href: string }", + "secondaryButton?": "{ text: string; href: string }", + "items": "({ title: string; descriptions: string[] } & ({ imageSrc: string; videoSrc?: never } | { videoSrc: string; imageSrc?: never }))[]" + } + }, + { + "name": "FeaturesStatisticsCards", + "import": "import FeaturesStatisticsCards from '@/components/sections/features/FeaturesStatisticsCards';", + "path": "@/components/sections/features/FeaturesStatisticsCards", + "description": "Grid of cards displaying title, subtitle, category indicator, and value/statistic", + "propsSchema": { + "tag": "string", + "title": "string", + "description": "string", + "primaryButton?": "{ text: string; href: string }", + "secondaryButton?": "{ text: string; href: string }", + "items": "{ title: string; description: string; label: string; value: string }[]" + } + }, + { + "name": "FeaturesRevealCards", + "import": "import FeaturesRevealCards from '@/components/sections/features/FeaturesRevealCards';", + "path": "@/components/sections/features/FeaturesRevealCards", + "description": "Numbered cards with image background that reveal description on hover", + "propsSchema": { + "tag": "string", + "title": "string", + "description": "string", + "primaryButton?": "{ text: string; href: string }", + "secondaryButton?": "{ text: string; href: string }", + "items": "({ title: string; description: string } & ({ imageSrc: string; videoSrc?: never } | { videoSrc: string; imageSrc?: never }))[]" + } + }, + { + "name": "FeaturesTimelineCards", + "import": "import FeaturesTimelineCards from '@/components/sections/features/FeaturesTimelineCards';", + "path": "@/components/sections/features/FeaturesTimelineCards", + "description": "Horizontal timeline with clickable cards that control a large media display with progress bar animations", + "propsSchema": { + "tag": "string", + "title": "string", + "description": "string", + "primaryButton?": "{ text: string; href: string }", + "secondaryButton?": "{ text: string; href: string }", + "items": "({ title: string; description: string } & ({ imageSrc: string; videoSrc?: never } | { videoSrc: string; imageSrc?: never }))[]" + } + }, + { + "name": "FeaturesIconCards", + "import": "import FeaturesIconCards from '@/components/sections/features/FeaturesIconCards';", + "path": "@/components/sections/features/FeaturesIconCards", + "description": "Grid of cards with icon and interactive hover effect revealing random characters", + "propsSchema": { + "tag": "string", + "title": "string", + "description": "string", + "primaryButton?": "{ text: string; href: string }", + "secondaryButton?": "{ text: string; href: string }", + "features": "{ icon: LucideIcon; title: string; description: string }[]" + } + }, + { + "name": "FeaturesBento", + "import": "import FeaturesBento from '@/components/sections/features/FeaturesBento';", + "path": "@/components/sections/features/FeaturesBento", + "description": "Bento grid with animated card variants including charts, orbiting icons, chat animations, and more", + "propsSchema": { + "tag": "string", + "title": "string", + "description": "string", + "primaryButton?": "{ text: string; href: string }", + "secondaryButton?": "{ text: string; href: string }", + "features": "FeatureCard[] where each FeatureCard = { title: string; description: string } & one of these variants: { bentoComponent: 'animated-bar-chart' } | { bentoComponent: 'checklist-timeline'; heading: string; subheading: string; items: [{ label: string; detail: string }, { label: string; detail: string }, { label: string; detail: string }]; completedLabel: string } | { bentoComponent: 'media-stack'; items: [{ imageSrc?: string; videoSrc?: string }, { imageSrc?: string; videoSrc?: string }, { imageSrc?: string; videoSrc?: string }] }" + } + }, + { + "name": "FeaturesProfileCards", + "import": "import FeaturesProfileCards from '@/components/sections/features/FeaturesProfileCards';", + "path": "@/components/sections/features/FeaturesProfileCards", + "description": "Profile cards with avatar, verified badge, CTA button, and hover-reveal description", + "propsSchema": { + "tag": "string", + "title": "string", + "description": "string", + "primaryButton?": "{ text: string; href: string }", + "secondaryButton?": "{ text: string; href: string }", + "items": "({ title: string; description: string; avatarSrc: string; buttonText: string; buttonHref?: string } & ({ imageSrc: string; videoSrc?: never } | { videoSrc: string; imageSrc?: never }))[]" + } + } + ], + "pricing": [ + { + "name": "PricingSimpleCards", + "import": "import PricingSimpleCards from '@/components/sections/pricing/PricingSimpleCards';", + "path": "@/components/sections/pricing/PricingSimpleCards", + "description": "Simple pricing cards with title, price, description, and feature list", + "propsSchema": { + "tag": "string", + "title": "string", + "description": "string", + "primaryButton?": "{ text: string; href: string }", + "secondaryButton?": "{ text: string; href: string }", + "plans": "{ tag: string; price: string; description: string; features: string[] }[]" + } + }, + { + "name": "PricingCenteredCards", + "import": "import PricingCenteredCards from '@/components/sections/pricing/PricingCenteredCards';", + "path": "@/components/sections/pricing/PricingCenteredCards", + "description": "Centered pricing cards with per-plan buttons above features list", + "propsSchema": { + "tag": "string", + "title": "string", + "description": "string", + "primaryButton?": "{ text: string; href: string }", + "secondaryButton?": "{ text: string; href: string }", + "plans": "{ tag: string; price: string; description: string; features: string[]; primaryButton: { text: string; href: string }; secondaryButton?: { text: string; href: string } }[]" + } + }, + { + "name": "PricingHighlightedCards", + "import": "import PricingHighlightedCards from '@/components/sections/pricing/PricingHighlightedCards';", + "path": "@/components/sections/pricing/PricingHighlightedCards", + "description": "Pricing cards with optional highlight badge above selected cards", + "propsSchema": { + "tag": "string", + "title": "string", + "description": "string", + "primaryButton?": "{ text: string; href: string }", + "secondaryButton?": "{ text: string; href: string }", + "plans": "{ tag: string; price: string; description: string; features: string[]; highlight?: string; primaryButton: { text: string; href: string }; secondaryButton?: { text: string; href: string } }[]" + } + }, + { + "name": "PricingSplitCards", + "import": "import PricingSplitCards from '@/components/sections/pricing/PricingSplitCards';", + "path": "@/components/sections/pricing/PricingSplitCards", + "description": "Split layout pricing cards with price/CTA on left, features on right", + "propsSchema": { + "tag": "string", + "title": "string", + "description": "string", + "primaryButton?": "{ text: string; href: string }", + "secondaryButton?": "{ text: string; href: string }", + "plans": "{ tag: string; price: string; period: string; description: string; primaryButton: { text: string; href: string }; secondaryButton?: { text: string; href: string }; featuresTitle: string; features: string[] }[]" + } + }, + { + "name": "PricingLayeredCards", + "import": "import PricingLayeredCards from '@/components/sections/pricing/PricingLayeredCards';", + "path": "@/components/sections/pricing/PricingLayeredCards", + "description": "Layered card design with highlighted inner section containing price/CTA and features below", + "propsSchema": { + "tag": "string", + "title": "string", + "description": "string", + "primaryButton?": "{ text: string; href: string }", + "secondaryButton?": "{ text: string; href: string }", + "plans": "{ tag: string; price: string; description: string; primaryButton: { text: string; href: string }; secondaryButton?: { text: string; href: string }; features: string[] }[]" + } + }, + { + "name": "PricingMediaCards", + "import": "import PricingMediaCards from '@/components/sections/pricing/PricingMediaCards';", + "path": "@/components/sections/pricing/PricingMediaCards", + "description": "Split layout pricing cards with media on left, pricing info and features on right", + "propsSchema": { + "tag": "string", + "title": "string", + "description": "string", + "primaryButton?": "{ text: string; href: string }", + "secondaryButton?": "{ text: string; href: string }", + "plans": "({ tag: string; price: string; period: string; features: string[]; primaryButton: { text: string; href: string } } & ({ imageSrc: string; videoSrc?: never } | { videoSrc: string; imageSrc?: never }))[]" + } + } + ], + "metrics": [ + { + "name": "MetricsGradientCards", + "import": "import MetricsGradientCards from '@/components/sections/metrics/MetricsGradientCards';", + "path": "@/components/sections/metrics/MetricsGradientCards", + "description": "Metrics cards with large gradient-fading value, overlapping title, and icon in bottom corner", + "propsSchema": { + "tag": "string", + "title": "string", + "description": "string", + "primaryButton?": "{ text: string; href: string }", + "secondaryButton?": "{ text: string; href: string }", + "metrics": "{ value: string; title: string; description: string; icon: LucideIcon }[]" + } + }, + { + "name": "MetricsSimpleCards", + "import": "import MetricsSimpleCards from '@/components/sections/metrics/MetricsSimpleCards';", + "path": "@/components/sections/metrics/MetricsSimpleCards", + "description": "Simple metrics cards with large value and description text", + "propsSchema": { + "tag": "string", + "title": "string", + "description": "string", + "primaryButton?": "{ text: string; href: string }", + "secondaryButton?": "{ text: string; href: string }", + "metrics": "{ value: string; description: string }[]" + } + }, + { + "name": "MetricsIconCards", + "import": "import MetricsIconCards from '@/components/sections/metrics/MetricsIconCards';", + "path": "@/components/sections/metrics/MetricsIconCards", + "description": "Centered metrics cards with icon, title, and large value", + "propsSchema": { + "tag": "string", + "title": "string", + "description": "string", + "primaryButton?": "{ text: string; href: string }", + "secondaryButton?": "{ text: string; href: string }", + "metrics": "{ icon: LucideIcon; title: string; value: string }[]" + } + }, + { + "name": "MetricsFeatureCards", + "import": "import MetricsFeatureCards from '@/components/sections/metrics/MetricsFeatureCards';", + "path": "@/components/sections/metrics/MetricsFeatureCards", + "description": "Metrics cards with large value, title, divider, and feature checklist", + "propsSchema": { + "tag": "string", + "title": "string", + "description": "string", + "primaryButton?": "{ text: string; href: string }", + "secondaryButton?": "{ text: string; href: string }", + "metrics": "{ value: string; title: string; features: string[] }[]" + } + }, + { + "name": "MetricsMediaCards", + "import": "import MetricsMediaCards from '@/components/sections/metrics/MetricsMediaCards';", + "path": "@/components/sections/metrics/MetricsMediaCards", + "description": "Split layout metrics with text card and media side by side, alternating order", + "propsSchema": { + "tag": "string", + "title": "string", + "description": "string", + "primaryButton?": "{ text: string; href: string }", + "secondaryButton?": "{ text: string; href: string }", + "metrics": "({ value: string; title: string; description: string } & ({ imageSrc: string; videoSrc?: never } | { videoSrc: string; imageSrc?: never }))[]" + } + }, + { + "name": "MetricsMinimalCards", + "import": "import MetricsMinimalCards from '@/components/sections/metrics/MetricsMinimalCards';", + "path": "@/components/sections/metrics/MetricsMinimalCards", + "description": "Minimal layout with title, tag, divider, and aspect-video metric cards", + "propsSchema": { + "tag": "string", + "title": "string", + "metrics": "{ value: string; description: string }[]" + } + } + ], + "team": [ + { + "name": "TeamOverlayCards", + "import": "import TeamOverlayCards from '@/components/sections/team/TeamOverlayCards';", + "path": "@/components/sections/team/TeamOverlayCards", + "description": "Team member cards with portrait media and overlay containing name and role badge", + "propsSchema": { + "tag": "string", + "title": "string", + "description": "string", + "primaryButton?": "{ text: string; href: string }", + "secondaryButton?": "{ text: string; href: string }", + "members": "({ name: string; role: string } & ({ imageSrc: string; videoSrc?: never } | { videoSrc: string; imageSrc?: never }))[]" + } + }, + { + "name": "TeamDetailedCards", + "import": "import TeamDetailedCards from '@/components/sections/team/TeamDetailedCards';", + "path": "@/components/sections/team/TeamDetailedCards", + "description": "Full-bleed team cards with detailed overlay including name, role, description, and social links", + "propsSchema": { + "tag": "string", + "title": "string", + "description": "string", + "primaryButton?": "{ text: string; href: string }", + "secondaryButton?": "{ text: string; href: string }", + "members": "({ name: string; role: string; description: string; socialLinks: { icon: LucideIcon; url: string }[] } & ({ imageSrc: string; videoSrc?: never } | { videoSrc: string; imageSrc?: never }))[]" + } + }, + { + "name": "TeamStackedCards", + "import": "import TeamStackedCards from '@/components/sections/team/TeamStackedCards';", + "path": "@/components/sections/team/TeamStackedCards", + "description": "Overlapping team cards with square media, name, and role centered below", + "propsSchema": { + "tag": "string", + "title": "string", + "description": "string", + "primaryButton?": "{ text: string; href: string }", + "secondaryButton?": "{ text: string; href: string }", + "members": "({ name: string; role: string } & ({ imageSrc: string; videoSrc?: never } | { videoSrc: string; imageSrc?: never }))[]" + } + }, + { + "name": "TeamGlassCards", + "import": "import TeamGlassCards from '@/components/sections/team/TeamGlassCards';", + "path": "@/components/sections/team/TeamGlassCards", + "description": "Full-bleed team cards with glassmorphism blur overlay and white text", + "propsSchema": { + "tag": "string", + "title": "string", + "description": "string", + "primaryButton?": "{ text: string; href: string }", + "secondaryButton?": "{ text: string; href: string }", + "members": "({ name: string; role: string } & ({ imageSrc: string; videoSrc?: never } | { videoSrc: string; imageSrc?: never }))[]" + } + }, + { + "name": "TeamMinimalCards", + "import": "import TeamMinimalCards from '@/components/sections/team/TeamMinimalCards';", + "path": "@/components/sections/team/TeamMinimalCards", + "description": "Minimal team cards with media, divider, and name/role text", + "propsSchema": { + "tag": "string", + "title": "string", + "members": "({ name: string; role: string } & ({ imageSrc: string; videoSrc?: never } | { videoSrc: string; imageSrc?: never }))[]" + } + }, + { + "name": "TeamListCards", + "import": "import TeamListCards from '@/components/sections/team/TeamListCards';", + "path": "@/components/sections/team/TeamListCards", + "description": "Grouped team members in list format with image, name, role, and detail", + "propsSchema": { + "tag": "string", + "title": "string", + "description": "string", + "primaryButton?": "{ text: string; href: string }", + "secondaryButton?": "{ text: string; href: string }", + "groups": "{ title: string; members: ({ name: string; role: string; detail: string } & ({ imageSrc: string; videoSrc?: never } | { videoSrc: string; imageSrc?: never }))[] }[]" + } + } + ], + "testimonial": [ + { + "name": "TestimonialOverlayCards", + "import": "import TestimonialOverlayCards from '@/components/sections/testimonial/TestimonialOverlayCards';", + "path": "@/components/sections/testimonial/TestimonialOverlayCards", + "description": "Testimonial cards with full-bleed image and overlay showing rating, name, role, and company", + "propsSchema": { + "tag": "string", + "title": "string", + "description": "string", + "primaryButton?": "{ text: string; href: string }", + "secondaryButton?": "{ text: string; href: string }", + "testimonials": "({ name: string; role: string; company: string; rating: number } & ({ imageSrc: string; videoSrc?: never } | { videoSrc: string; imageSrc?: never }))[]" + } + }, + { + "name": "TestimonialQuoteCards", + "import": "import TestimonialQuoteCards from '@/components/sections/testimonial/TestimonialQuoteCards';", + "path": "@/components/sections/testimonial/TestimonialQuoteCards", + "description": "Testimonial cards with image or icon, name, role, and quote text", + "propsSchema": { + "tag": "string", + "title": "string", + "description": "string", + "primaryButton?": "{ text: string; href: string }", + "secondaryButton?": "{ text: string; href: string }", + "testimonials": "({ name: string; role: string; quote: string } & ({ imageSrc: string; videoSrc?: never } | { videoSrc: string; imageSrc?: never }))[]" + } + }, + { + "name": "TestimonialSplitCards", + "import": "import TestimonialSplitCards from '@/components/sections/testimonial/TestimonialSplitCards';", + "path": "@/components/sections/testimonial/TestimonialSplitCards", + "description": "Split testimonial carousel with text on left and media on right", + "propsSchema": { + "tag": "string", + "title": "string", + "description": "string", + "primaryButton?": "{ text: string; href: string }", + "secondaryButton?": "{ text: string; href: string }", + "testimonials": "({ tag: string; title: string; quote: string; name: string; date: string } & ({ avatarImageSrc: string; avatarVideoSrc?: never } | { avatarVideoSrc: string; avatarImageSrc?: never }) & ({ imageSrc: string; videoSrc?: never } | { videoSrc: string; imageSrc?: never }))[]" + } + }, + { + "name": "TestimonialMetricsCards", + "import": "import TestimonialMetricsCards from '@/components/sections/testimonial/TestimonialMetricsCards';", + "path": "@/components/sections/testimonial/TestimonialMetricsCards", + "description": "Testimonial cards with rating overlay and metrics section below", + "propsSchema": { + "tag": "string", + "title": "string", + "description": "string", + "primaryButton?": "{ text: string; href: string }", + "secondaryButton?": "{ text: string; href: string }", + "testimonials": "({ name: string; role: string; company: string; rating: number } & ({ imageSrc: string; videoSrc?: never } | { videoSrc: string; imageSrc?: never }))[]", + "metrics": "[{ value: string; label: string }, { value: string; label: string }, { value: string; label: string }]" + } + }, + { + "name": "TestimonialMarqueeCards", + "import": "import TestimonialMarqueeCards from '@/components/sections/testimonial/TestimonialMarqueeCards';", + "path": "@/components/sections/testimonial/TestimonialMarqueeCards", + "description": "Dual marquee rows of testimonial cards scrolling in opposite directions", + "propsSchema": { + "tag": "string", + "title": "string", + "description": "string", + "primaryButton?": "{ text: string; href: string }", + "secondaryButton?": "{ text: string; href: string }", + "testimonials": "({ name: string; role: string; quote: string } & ({ imageSrc: string; videoSrc?: never } | { videoSrc: string; imageSrc?: never }))[]" + } + }, + { + "name": "TestimonialDetailedCards", + "import": "import TestimonialDetailedCards from '@/components/sections/testimonial/TestimonialDetailedCards';", + "path": "@/components/sections/testimonial/TestimonialDetailedCards", + "description": "Split layout testimonial with quote card and media, navigated with arrow buttons", + "propsSchema": { + "tag": "string", + "title": "string", + "description": "string", + "primaryButton?": "{ text: string; href: string }", + "secondaryButton?": "{ text: string; href: string }", + "testimonials": "({ title: string; quote: string; name: string; role: string } & ({ imageSrc: string; videoSrc?: never } | { videoSrc: string; imageSrc?: never }))[]" + } + }, + { + "name": "TestimonialAvatarCard", + "import": "import TestimonialAvatarCard from '@/components/sections/testimonial/TestimonialAvatarCard';", + "path": "@/components/sections/testimonial/TestimonialAvatarCard", + "description": "Social proof card with overlapping avatar group and call-to-action", + "propsSchema": { + "tag": "string", + "title": "string", + "primaryButton?": "{ text: string; href: string }", + "secondaryButton?": "{ text: string; href: string }", + "avatars": "({ name: string } & ({ imageSrc: string; videoSrc?: never } | { videoSrc: string; imageSrc?: never }))[]" + } + }, + { + "name": "TestimonialRatingCards", + "import": "import TestimonialRatingCards from '@/components/sections/testimonial/TestimonialRatingCards';", + "path": "@/components/sections/testimonial/TestimonialRatingCards", + "description": "Testimonial cards with star ratings, quote, and author info", + "propsSchema": { + "tag": "string", + "title": "string", + "description": "string", + "primaryButton?": "{ text: string; href: string }", + "secondaryButton?": "{ text: string; href: string }", + "testimonials": "({ name: string; role: string; quote: string; rating: number } & ({ imageSrc: string; videoSrc?: never } | { videoSrc: string; imageSrc?: never }))[]" + } + }, + { + "name": "TestimonialTrustCard", + "import": "import TestimonialTrustCard from '@/components/sections/testimonial/TestimonialTrustCard';", + "path": "@/components/sections/testimonial/TestimonialTrustCard", + "description": "Social proof testimonial with star rating, large quote, author text, and avatar group", + "propsSchema": { + "quote": "string", + "rating": "number", + "author": "string", + "avatars": "({ name: string } & ({ imageSrc: string; videoSrc?: never } | { videoSrc: string; imageSrc?: never }))[]" + } + } + ], + "social-proof": [ + { + "name": "SocialProofMarquee", + "import": "import SocialProofMarquee from '@/components/sections/social-proof/SocialProofMarquee';", + "path": "@/components/sections/social-proof/SocialProofMarquee", + "description": "Scrolling marquee of brand/company names with header section", + "propsSchema": { + "tag": "string", + "title": "string", + "description": "string", + "primaryButton?": "{ text: string; href: string }", + "secondaryButton?": "{ text: string; href: string }", + "names": "string[]" + } + } + ], + "faq": [ + { + "name": "FaqSimple", + "import": "import FaqSimple from '@/components/sections/faq/FaqSimple';", + "path": "@/components/sections/faq/FaqSimple", + "description": "Simple FAQ section with expandable accordion items", + "propsSchema": { + "tag": "string", + "title": "string", + "description": "string", + "primaryButton?": "{ text: string; href: string }", + "secondaryButton?": "{ text: string; href: string }", + "items": "{ question: string; answer: string }[]" + } + }, + { + "name": "FaqTwoColumn", + "import": "import FaqTwoColumn from '@/components/sections/faq/FaqTwoColumn';", + "path": "@/components/sections/faq/FaqTwoColumn", + "description": "Two-column FAQ section with items split across columns", + "propsSchema": { + "tag": "string", + "title": "string", + "description": "string", + "primaryButton?": "{ text: string; href: string }", + "secondaryButton?": "{ text: string; href: string }", + "items": "{ question: string; answer: string }[]" + } + }, + { + "name": "FaqSplitMedia", + "import": "import FaqSplitMedia from '@/components/sections/faq/FaqSplitMedia';", + "path": "@/components/sections/faq/FaqSplitMedia", + "description": "Split layout FAQ with media on left and accordion items on right", + "propsSchema": { + "tag": "string", + "title": "string", + "description": "string", + "primaryButton?": "{ text: string; href: string }", + "secondaryButton?": "{ text: string; href: string }", + "items": "{ question: string; answer: string }[]", + "imageSrc | videoSrc": "{ imageSrc: string; videoSrc?: never } | { videoSrc: string; imageSrc?: never }" + } + } + ], + "blog": [ + { + "name": "BlogSimpleCards", + "import": "import BlogSimpleCards from '@/components/sections/blog/BlogSimpleCards';", + "path": "@/components/sections/blog/BlogSimpleCards", + "description": "Simple blog cards with image at top, category badge, title, excerpt, and author info at bottom", + "propsSchema": { + "tag": "string", + "title": "string", + "description": "string", + "primaryButton?": "{ text: string; href: string }", + "secondaryButton?": "{ text: string; href: string }", + "items": "({ category: string; title: string; excerpt: string; authorName: string; date: string; href?: string; onClick?: () => void } & ({ imageSrc: string; videoSrc?: never } | { videoSrc: string; imageSrc?: never }) & ({ authorImageSrc: string; authorVideoSrc?: never } | { authorVideoSrc: string; authorImageSrc?: never }))[]" + } + }, + { + "name": "BlogTagCards", + "import": "import BlogTagCards from '@/components/sections/blog/BlogTagCards';", + "path": "@/components/sections/blog/BlogTagCards", + "description": "Blog cards with author info at top and tag badges at bottom", + "propsSchema": { + "tag": "string", + "title": "string", + "description": "string", + "primaryButton?": "{ text: string; href: string }", + "secondaryButton?": "{ text: string; href: string }", + "items": "({ title: string; excerpt: string; authorName: string; date: string; tags: string[]; href?: string; onClick?: () => void } & ({ imageSrc: string; videoSrc?: never } | { videoSrc: string; imageSrc?: never }) & ({ authorImageSrc: string; authorVideoSrc?: never } | { authorVideoSrc: string; authorImageSrc?: never }))[]" + } + }, + { + "name": "BlogMediaCards", + "import": "import BlogMediaCards from '@/components/sections/blog/BlogMediaCards';", + "path": "@/components/sections/blog/BlogMediaCards", + "description": "Blog cards with content at top and square media at bottom", + "propsSchema": { + "tag": "string", + "title": "string", + "description": "string", + "primaryButton?": "{ text: string; href: string }", + "secondaryButton?": "{ text: string; href: string }", + "items": "({ category: string; title: string; excerpt: string; authorName: string; date: string; href?: string; onClick?: () => void } & ({ imageSrc: string; videoSrc?: never } | { videoSrc: string; imageSrc?: never }) & ({ authorImageSrc: string; authorVideoSrc?: never } | { authorVideoSrc: string; authorImageSrc?: never }))[]" + } + } + ], + "contact": [ + { + "name": "ContactCenter", + "import": "import ContactCenter from '@/components/sections/contact/ContactCenter';", + "path": "@/components/sections/contact/ContactCenter", + "description": "Centered contact section with email signup form inside a card", + "propsSchema": { + "tag": "string", + "title": "string", + "description": "string", + "inputPlaceholder": "string", + "buttonText": "string", + "termsText?": "string", + "onSubmit?": "(email: string) => void" + } + }, + { + "name": "ContactSplitEmail", + "import": "import ContactSplitEmail from '@/components/sections/contact/ContactSplitEmail';", + "path": "@/components/sections/contact/ContactSplitEmail", + "description": "Split layout contact section with email signup form on left and media on right", + "propsSchema": { + "tag": "string", + "title": "string", + "description": "string", + "inputPlaceholder": "string", + "buttonText": "string", + "termsText?": "string", + "onSubmit?": "(email: string) => void", + "imageSrc | videoSrc": "{ imageSrc: string; videoSrc?: never } | { videoSrc: string; imageSrc?: never }" + } + }, + { + "name": "ContactSplitForm", + "import": "import ContactSplitForm from '@/components/sections/contact/ContactSplitForm';", + "path": "@/components/sections/contact/ContactSplitForm", + "description": "Split layout contact section with multi-field form on left and media on right", + "propsSchema": { + "tag": "string", + "title": "string", + "description": "string", + "inputs": "{ name: string; type: string; placeholder: string; required?: boolean }[]", + "textarea?": "{ name: string; placeholder: string; rows?: number; required?: boolean }", + "buttonText": "string", + "onSubmit?": "(data: Record) => void", + "imageSrc | videoSrc": "{ imageSrc: string; videoSrc?: never } | { videoSrc: string; imageSrc?: never }" + } + }, + { + "name": "ContactCta", + "import": "import ContactCta from '@/components/sections/contact/ContactCta';", + "path": "@/components/sections/contact/ContactCta", + "description": "Centered call-to-action section with tag, large heading and buttons", + "propsSchema": { + "tag": "string", + "text": "string", + "primaryButton": "{ text: string; href: string }", + "secondaryButton": "{ text: string; href: string }" + } + } + ], + "legal": [ + { + "name": "PolicyContent", + "import": "import PolicyContent from '@/components/sections/legal/PolicyContent';", + "path": "@/components/sections/legal/PolicyContent", + "description": "Policy content section for privacy policies, terms of service, etc.", + "propsSchema": { + "title": "string", + "subtitle?": "string", + "sections": "{ heading: string; content: ({ type: 'paragraph'; text: string } | { type: 'list'; items: string[] } | { type: 'numbered-list'; items: string[] })[] }[]" + } + } + ], + "footer": [ + { + "name": "FooterSimple", + "import": "import FooterSimple from '@/components/sections/footer/FooterSimple';", + "path": "@/components/sections/footer/FooterSimple", + "description": "Simple footer with logo, column links, copyright and bottom links", + "propsSchema": { + "brand": "string", + "columns": "{ title: string; items: { label: string; href?: string; onClick?: () => void }[] }[]", + "copyright": "string", + "links": "{ label: string; href?: string; onClick?: () => void }[]" + } + }, + { + "name": "FooterSimpleReveal", + "import": "import FooterSimpleReveal from '@/components/sections/footer/FooterSimpleReveal';", + "path": "@/components/sections/footer/FooterSimpleReveal", + "description": "Simple footer with reveal effect that appears fixed as you scroll", + "propsSchema": { + "brand": "string", + "columns": "{ title: string; items: { label: string; href?: string; onClick?: () => void }[] }[]", + "copyright": "string", + "links": "{ label: string; href?: string; onClick?: () => void }[]" + } + }, + { + "name": "FooterBrand", + "import": "import FooterBrand from '@/components/sections/footer/FooterBrand';", + "path": "@/components/sections/footer/FooterBrand", + "description": "Footer with full-width brand text and chevron icon links", + "propsSchema": { + "brand": "string", + "columns": "{ items: { label: string; href?: string; onClick?: () => void }[] }[]" + } + }, + { + "name": "FooterBrandReveal", + "import": "import FooterBrandReveal from '@/components/sections/footer/FooterBrandReveal';", + "path": "@/components/sections/footer/FooterBrandReveal", + "description": "Footer with full-width brand text and reveal effect", + "propsSchema": { + "brand": "string", + "columns": "{ items: { label: string; href?: string; onClick?: () => void }[] }[]" + } + }, + { + "name": "FooterMinimal", + "import": "import FooterMinimal from '@/components/sections/footer/FooterMinimal';", + "path": "@/components/sections/footer/FooterMinimal", + "description": "Minimal footer with full-width brand text, copyright, and social links", + "propsSchema": { + "brand": "string", + "copyright": "string", + "socialLinks?": "{ icon: LucideIcon; href?: string; onClick?: () => void }[]" + } + }, + { + "name": "FooterSimpleCard", + "import": "import FooterSimpleCard from '@/components/sections/footer/FooterSimpleCard';", + "path": "@/components/sections/footer/FooterSimpleCard", + "description": "Simple footer with columns wrapped in a card container", + "propsSchema": { + "brand": "string", + "columns": "{ title: string; items: { label: string; href?: string; onClick?: () => void }[] }[]", + "copyright": "string", + "links": "{ label: string; href?: string; onClick?: () => void }[]" + } + }, + { + "name": "FooterSimpleMedia", + "import": "import FooterSimpleMedia from '@/components/sections/footer/FooterSimpleMedia';", + "path": "@/components/sections/footer/FooterSimpleMedia", + "description": "Footer with media section above and simple columns below", + "propsSchema": { + "imageSrc | videoSrc": "{ imageSrc: string; videoSrc?: never } | { videoSrc: string; imageSrc?: never }", + "brand": "string", + "columns": "{ title: string; items: { label: string; href?: string; onClick?: () => void }[] }[]", + "copyright": "string", + "links": "{ label: string; href?: string; onClick?: () => void }[]" + } + }, + { + "name": "FooterBasic", + "import": "import FooterBasic from '@/components/sections/footer/FooterBasic';", + "path": "@/components/sections/footer/FooterBasic", + "description": "Basic footer with columns and two text lines at bottom", + "propsSchema": { + "columns": "{ title: string; items: { label: string; href?: string; onClick?: () => void }[] }[]", + "leftText": "string", + "rightText": "string" + } + } + ] + } +} \ No newline at end of file diff --git a/src/App.tsx b/src/App.tsx new file mode 100644 index 0000000..835347a --- /dev/null +++ b/src/App.tsx @@ -0,0 +1,272 @@ +import AboutTextSplit from '@/components/sections/about/AboutTextSplit'; +import ContactCta from '@/components/sections/contact/ContactCta'; +import FeaturesFlipCards from '@/components/sections/features/FeaturesFlipCards'; +import FooterBrandReveal from '@/components/sections/footer/FooterBrandReveal'; +import HeroSplit from '@/components/sections/hero/HeroSplit'; +import NavbarCentered from '@/components/ui/NavbarCentered'; +import PricingHighlightedCards from '@/components/sections/pricing/PricingHighlightedCards'; +import TestimonialMetricsCards from '@/components/sections/testimonial/TestimonialMetricsCards'; + +export default function App() { + return ( + <> + + +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ + + + ); +} diff --git a/src/components/sections/about/AboutTextSplit.tsx b/src/components/sections/about/AboutTextSplit.tsx new file mode 100644 index 0000000..7bf90d1 --- /dev/null +++ b/src/components/sections/about/AboutTextSplit.tsx @@ -0,0 +1,56 @@ +import Button from "@/components/ui/Button"; +import TextAnimation from "@/components/ui/TextAnimation"; + +interface AboutTextSplitProps { + title: string; + descriptions: string[]; + primaryButton?: { text: string; href: string }; + secondaryButton?: { text: string; href: string }; +} + +const AboutTextSplit = ({ + title, + descriptions, + primaryButton, + secondaryButton, +}: AboutTextSplitProps) => { + return ( +
+
+
+
+ +
+ +
+ {descriptions.map((desc, index) => ( + + ))} + + {(primaryButton || secondaryButton) && ( +
+ {primaryButton &&
+ )} +
+
+ +
+
+
+ ); +}; + +export default AboutTextSplit; diff --git a/src/components/sections/contact/ContactCta.tsx b/src/components/sections/contact/ContactCta.tsx new file mode 100644 index 0000000..324e430 --- /dev/null +++ b/src/components/sections/contact/ContactCta.tsx @@ -0,0 +1,47 @@ +import { motion } from "motion/react"; +import TextAnimation from "@/components/ui/TextAnimation"; +import Button from "@/components/ui/Button"; + +const ContactCta = ({ + tag, + text, + primaryButton, + secondaryButton, +}: { + tag: string; + text: string; + primaryButton: { text: string; href: string }; + secondaryButton: { text: string; href: string }; +}) => { + return ( +
+
+ +
+ {tag} + + + +
+
+
+
+
+
+ ); +}; + +export default ContactCta; diff --git a/src/components/sections/features/FeaturesFlipCards.tsx b/src/components/sections/features/FeaturesFlipCards.tsx new file mode 100644 index 0000000..35d29ac --- /dev/null +++ b/src/components/sections/features/FeaturesFlipCards.tsx @@ -0,0 +1,118 @@ +import { useState } from "react"; +import { motion } from "motion/react"; +import { Plus } from "lucide-react"; +import TextAnimation from "@/components/ui/TextAnimation"; +import ImageOrVideo from "@/components/ui/ImageOrVideo"; +import GridOrCarousel from "@/components/ui/GridOrCarousel"; +import Button from "@/components/ui/Button"; + +type FeatureItem = { + title: string; + descriptions: string[]; +} & ({ imageSrc: string; videoSrc?: never } | { videoSrc: string; imageSrc?: never }); + +interface FeaturesFlipCardsProps { + tag: string; + title: string; + description: string; + primaryButton?: { text: string; href: string }; + secondaryButton?: { text: string; href: string }; + items: FeatureItem[]; +} + +const FeatureFlipCard = ({ item }: { item: FeatureItem }) => { + const [isFlipped, setIsFlipped] = useState(false); + + return ( +
setIsFlipped(!isFlipped)} + > +
+
+
+

{item.title}

+
+ +
+
+
+ +
+
+ +
+
+

{item.title}

+
+ +
+
+
+ {item.descriptions.map((desc, index) => ( +

{desc}

+ ))} +
+
+
+
+ ); +}; + +const FeaturesFlipCards = ({ + tag, + title, + description, + primaryButton, + secondaryButton, + items, +}: FeaturesFlipCardsProps) => { + return ( +
+
+
+ {tag} + + + + + + {(primaryButton || secondaryButton) && ( +
+ {primaryButton &&
+ )} +
+ + + + {items.map((item) => ( + + ))} + + +
+
+ ); +}; + +export default FeaturesFlipCards; diff --git a/src/components/sections/footer/FooterBrandReveal.tsx b/src/components/sections/footer/FooterBrandReveal.tsx new file mode 100644 index 0000000..eeb390d --- /dev/null +++ b/src/components/sections/footer/FooterBrandReveal.tsx @@ -0,0 +1,101 @@ +import { useRef, useEffect, useState } from "react"; +import { ChevronRight } from "lucide-react"; +import { useButtonClick } from "@/hooks/useButtonClick"; +import AutoFillText from "@/components/ui/AutoFillText"; +import { cls } from "@/lib/utils"; + +type FooterLink = { + label: string; + href?: string; + onClick?: () => void; +}; + +type FooterColumn = { + items: FooterLink[]; +}; + +const FooterLinkItem = ({ label, href, onClick }: FooterLink) => { + const handleClick = useButtonClick(href, onClick); + + return ( +
+
+ ); +}; + +const FooterBrandReveal = ({ + brand, + columns, +}: { + brand: string; + columns: FooterColumn[]; +}) => { + const footerRef = useRef(null); + const [footerHeight, setFooterHeight] = useState(0); + + useEffect(() => { + const updateHeight = () => { + if (footerRef.current) { + setFooterHeight(footerRef.current.offsetHeight); + } + }; + + updateHeight(); + + const resizeObserver = new ResizeObserver(updateHeight); + if (footerRef.current) { + resizeObserver.observe(footerRef.current); + } + + return () => resizeObserver.disconnect(); + }, []); + + return ( +
+
+
+
+ {brand} + +
+ {columns.map((column, index) => ( +
+ {column.items.map((item) => ( + + ))} +
+ ))} +
+
+
+
+
+ ); +}; + +export default FooterBrandReveal; diff --git a/src/components/sections/hero/HeroSplit.tsx b/src/components/sections/hero/HeroSplit.tsx new file mode 100644 index 0000000..cdc2821 --- /dev/null +++ b/src/components/sections/hero/HeroSplit.tsx @@ -0,0 +1,64 @@ +import { motion } from "motion/react"; +import Button from "@/components/ui/Button"; +import TextAnimation from "@/components/ui/TextAnimation"; +import ImageOrVideo from "@/components/ui/ImageOrVideo"; + +type HeroSplitProps = { + tag: string; + title: string; + description: string; + primaryButton: { text: string; href: string }; + secondaryButton: { text: string; href: string }; +} & ({ imageSrc: string; videoSrc?: never } | { videoSrc: string; imageSrc?: never }); + +const HeroSplit = ({ + tag, + title, + description, + primaryButton, + secondaryButton, + imageSrc, + videoSrc, +}: HeroSplitProps) => { + return ( +
+
+
+
+ {tag} + + + + + +
+
+
+
+ + + + +
+
+ ); +}; + +export default HeroSplit; diff --git a/src/components/sections/pricing/PricingHighlightedCards.tsx b/src/components/sections/pricing/PricingHighlightedCards.tsx new file mode 100644 index 0000000..259b3a6 --- /dev/null +++ b/src/components/sections/pricing/PricingHighlightedCards.tsx @@ -0,0 +1,105 @@ +import { motion } from "motion/react"; +import { Check } from "lucide-react"; +import Button from "@/components/ui/Button"; +import TextAnimation from "@/components/ui/TextAnimation"; +import GridOrCarousel from "@/components/ui/GridOrCarousel"; +import { cls } from "@/lib/utils"; + +type PricingPlan = { + tag: string; + price: string; + description: string; + features: string[]; + highlight?: string; + primaryButton: { text: string; href: string }; + secondaryButton?: { text: string; href: string }; +}; + +const PricingHighlightedCards = ({ + tag, + title, + description, + primaryButton, + secondaryButton, + plans, +}: { + tag: string; + title: string; + description: string; + primaryButton?: { text: string; href: string }; + secondaryButton?: { text: string; href: string }; + plans: PricingPlan[]; +}) => ( +
+
+
+ {tag} + + + + + + {(primaryButton || secondaryButton) && ( +
+ {primaryButton &&
+ )} +
+ + + + {plans.map((plan) => ( +
+
+ {plan.highlight || "placeholder"} +
+ +
+
+ {plan.price} + {plan.tag} +
+ +
+ +
+ {plan.features.map((feature) => ( +
+
+ +
+ {feature} +
+ ))} +
+ +
+
+
+
+ ))} + + +
+
+); + +export default PricingHighlightedCards; diff --git a/src/components/sections/testimonial/TestimonialMetricsCards.tsx b/src/components/sections/testimonial/TestimonialMetricsCards.tsx new file mode 100644 index 0000000..8a3c706 --- /dev/null +++ b/src/components/sections/testimonial/TestimonialMetricsCards.tsx @@ -0,0 +1,126 @@ +import { motion } from "motion/react"; +import { Star } from "lucide-react"; +import Button from "@/components/ui/Button"; +import TextAnimation from "@/components/ui/TextAnimation"; +import ImageOrVideo from "@/components/ui/ImageOrVideo"; +import GridOrCarousel from "@/components/ui/GridOrCarousel"; +import { cls } from "@/lib/utils"; + +type Testimonial = { + name: string; + role: string; + company: string; + rating: number; +} & ({ imageSrc: string; videoSrc?: never } | { videoSrc: string; imageSrc?: never }); + +type Metric = { + value: string; + label: string; +}; + +const TestimonialMetricsCards = ({ + tag, + title, + description, + primaryButton, + secondaryButton, + testimonials, + metrics, +}: { + tag: string; + title: string; + description: string; + primaryButton?: { text: string; href: string }; + secondaryButton?: { text: string; href: string }; + testimonials: Testimonial[]; + metrics: [Metric, Metric, Metric]; +}) => { + return ( +
+
+
+ {tag} + + + + + + {(primaryButton || secondaryButton) && ( +
+ {primaryButton &&
+ )} +
+ +
+ + + {testimonials.map((testimonial) => ( +
+ + +
+
+ {Array.from({ length: 5 }).map((_, index) => ( + + ))} +
+ + {testimonial.name} + +
+ {testimonial.role} + {testimonial.company} +
+
+
+ ))} +
+
+ + + {metrics.map((metric, index) => ( +
+
+ {metric.value} + {metric.label} +
+ {index < 2 && ( +
+ )} +
+ ))} + +
+
+
+ ); +}; + +export default TestimonialMetricsCards; diff --git a/src/components/ui/AnimatedBarChart.tsx b/src/components/ui/AnimatedBarChart.tsx new file mode 100644 index 0000000..65f1c38 --- /dev/null +++ b/src/components/ui/AnimatedBarChart.tsx @@ -0,0 +1,46 @@ +import { useState, useEffect } from "react"; +import { cls } from "@/lib/utils"; + +const BARS = [ + { height: 100, hoverHeight: 40 }, + { height: 84, hoverHeight: 100 }, + { height: 62, hoverHeight: 75 }, + { height: 90, hoverHeight: 50 }, + { height: 70, hoverHeight: 90 }, + { height: 50, hoverHeight: 60 }, + { height: 75, hoverHeight: 85 }, + { height: 80, hoverHeight: 70 }, +]; + +const AnimatedBarChart = () => { + const [active, setActive] = useState(2); + const [isHovered, setIsHovered] = useState(false); + + useEffect(() => { + const interval = setInterval(() => setActive((p) => (p + 1) % BARS.length), 3000); + return () => clearInterval(interval); + }, []); + + return ( +
setIsHovered(true)} + onMouseLeave={() => setIsHovered(false)} + > +
+ {BARS.map((bar, i) => ( +
+
+
+ ))} +
+
+ ); +}; + +export default AnimatedBarChart; diff --git a/src/components/ui/AutoFillText.tsx b/src/components/ui/AutoFillText.tsx new file mode 100644 index 0000000..18eb2aa --- /dev/null +++ b/src/components/ui/AutoFillText.tsx @@ -0,0 +1,67 @@ +import { useRef, useEffect, useState } from "react"; +import { cls } from "@/lib/utils"; + +const AutoFillText = ({ + children, + className = "", + paddingY = "py-10", +}: { + children: string; + className?: string; + paddingY?: string; +}) => { + const containerRef = useRef(null); + const textRef = useRef(null); + const [fontSize, setFontSize] = useState(null); + + const hasDescenders = /[gjpqy]/.test(children); + const lineHeight = hasDescenders ? 1.2 : 0.8; + + useEffect(() => { + const container = containerRef.current; + const text = textRef.current; + if (!container || !text) return; + + const calculateSize = () => { + const containerWidth = container.offsetWidth; + if (containerWidth === 0) return; + + const canvas = document.createElement("canvas"); + const ctx = canvas.getContext("2d"); + if (!ctx) return; + + const styles = getComputedStyle(text); + ctx.font = `${styles.fontWeight} 100px ${styles.fontFamily}`; + const textWidth = ctx.measureText(children).width; + + if (textWidth > 0) { + setFontSize((containerWidth / textWidth) * 100); + } + }; + + calculateSize(); + + const observer = new ResizeObserver(calculateSize); + observer.observe(container); + + return () => observer.disconnect(); + }, [children]); + + return ( +
+

+ {children} +

+
+ ); +}; + +export default AutoFillText; diff --git a/src/components/ui/Button.tsx b/src/components/ui/Button.tsx new file mode 100644 index 0000000..cd3922d --- /dev/null +++ b/src/components/ui/Button.tsx @@ -0,0 +1,44 @@ +"use client"; + +import { motion } from "motion/react"; +import { cls } from "@/lib/utils"; +import { useButtonClick } from "@/hooks/useButtonClick"; + +interface ButtonProps { + text: string; + variant?: "primary" | "secondary"; + href?: string; + onClick?: () => void; + animate?: boolean; + delay?: number; + className?: string; +} + +const Button = ({ text, variant = "primary", href, onClick, animate = false, delay = 0, className = "" }: ButtonProps) => { + const handleClick = useButtonClick(href, onClick); + + const classes = cls( + "flex items-center justify-center h-9 px-6 text-sm rounded cursor-pointer", + variant === "primary" ? "primary-button text-primary-cta-text" : "secondary-button text-secondary-cta-text", + className + ); + + const button = href + ? {text} + : ; + + if (!animate) return button; + + return ( + + {button} + + ); +}; + +export default Button; diff --git a/src/components/ui/ChatMarquee.tsx b/src/components/ui/ChatMarquee.tsx new file mode 100644 index 0000000..a61fb0a --- /dev/null +++ b/src/components/ui/ChatMarquee.tsx @@ -0,0 +1,43 @@ +import type { LucideIcon } from "lucide-react"; +import { Send } from "lucide-react"; +import { cls } from "@/lib/utils"; + +type Exchange = { userMessage: string; aiResponse: string }; + +const ChatMarquee = ({ aiIcon: AiIcon, userIcon: UserIcon, exchanges, placeholder }: { aiIcon: LucideIcon; userIcon: LucideIcon; exchanges: Exchange[]; placeholder: string }) => { + const messages = exchanges.flatMap((e) => [{ content: e.userMessage, isUser: true }, { content: e.aiResponse, isUser: false }]); + const duplicated = [...messages, ...messages]; + + return ( +
+
+
+ {duplicated.map((msg, i) => ( +
+ {msg.isUser ? ( +
+ +
+ ) : ( +
+ +
+ )} +
+ {msg.content} +
+
+ ))} +
+
+
+

{placeholder}

+
+ +
+
+
+ ); +}; + +export default ChatMarquee; diff --git a/src/components/ui/ChecklistTimeline.tsx b/src/components/ui/ChecklistTimeline.tsx new file mode 100644 index 0000000..17d9776 --- /dev/null +++ b/src/components/ui/ChecklistTimeline.tsx @@ -0,0 +1,47 @@ +import { Check, Loader } from "lucide-react"; +import { cls } from "@/lib/utils"; + +type Item = { label: string; detail: string }; + +const DELAYS = [ + ["delay-150", "delay-200", "delay-[250ms]"], + ["delay-[350ms]", "delay-[400ms]", "delay-[450ms]"], + ["delay-[550ms]", "delay-[600ms]", "delay-[650ms]"], +]; + +const ChecklistTimeline = ({ heading, subheading, items, completedLabel }: { heading: string; subheading: string; items: [Item, Item, Item]; completedLabel: string }) => ( +
+
+ {[1, 0.8, 0.6].map((s) =>
)} +
+
+
+ +

{heading}

+

{subheading}

+
+ {items.map((item, i) => ( +
+
+
+
+ +
+
+
+

{item.label}

+

{item.detail}

+
+
+ ))} +
+
+ {[0, 1, 2].map((j) =>
)} +
+

{completedLabel}

+
+
+
+); + +export default ChecklistTimeline; diff --git a/src/components/ui/GridOrCarousel.tsx b/src/components/ui/GridOrCarousel.tsx new file mode 100644 index 0000000..e0723cb --- /dev/null +++ b/src/components/ui/GridOrCarousel.tsx @@ -0,0 +1,64 @@ +import { Children, type ReactNode } from "react"; +import useEmblaCarousel from "embla-carousel-react"; +import { ChevronLeft, ChevronRight } from "lucide-react"; +import { cls } from "@/lib/utils"; +import { useCarouselControls } from "@/hooks/useCarouselControls"; + +interface GridOrCarouselProps { + children: ReactNode; + carouselThreshold?: 2 | 3 | 4; +} + +const GridOrCarousel = ({ children, carouselThreshold = 4 }: GridOrCarouselProps) => { + const [emblaRef, emblaApi] = useEmblaCarousel({ dragFree: true }); + const { prevDisabled, nextDisabled, scrollPrev, scrollNext, scrollProgress } = useCarouselControls(emblaApi); + + const items = Children.toArray(children); + const count = items.length; + + if (count <= carouselThreshold) { + return ( +
+ {children} +
+ ); + } + + return ( +
+
+
+
+ {items.map((child, i) => ( +
{child}
+ ))} +
+
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+ ); +}; + +export default GridOrCarousel; diff --git a/src/components/ui/HoverPattern.tsx b/src/components/ui/HoverPattern.tsx new file mode 100644 index 0000000..fb80031 --- /dev/null +++ b/src/components/ui/HoverPattern.tsx @@ -0,0 +1,61 @@ +import { useRef, useState, useEffect } from "react"; +import { motion, useMotionValue, useMotionTemplate } from "motion/react"; +import { cls } from "@/lib/utils"; + +const CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; +const randomChars = () => Array.from({ length: 1500 }, () => CHARS[Math.floor(Math.random() * 62)]).join(""); + +interface HoverPatternProps { + children: React.ReactNode; + className?: string; +} + +const HoverPattern = ({ children, className = "" }: HoverPatternProps) => { + const ref = useRef(null); + const x = useMotionValue(0); + const y = useMotionValue(0); + const [chars, setChars] = useState(randomChars); + const [isMobile, setIsMobile] = useState(false); + + useEffect(() => { + const checkMobile = () => setIsMobile(window.innerWidth < 768); + checkMobile(); + window.addEventListener("resize", checkMobile); + return () => window.removeEventListener("resize", checkMobile); + }, []); + + useEffect(() => { + if (isMobile && ref.current) { + x.set(ref.current.offsetWidth / 2); + y.set(ref.current.offsetHeight / 2); + } + }, [isMobile, x, y]); + + const mask = useMotionTemplate`radial-gradient(${isMobile ? 110 : 250}px at ${x}px ${y}px, white, transparent)`; + const base = "absolute inset-0 rounded-[inherit] transition-opacity duration-300"; + + return ( +
{ + if (!ref.current) return; + const rect = ref.current.getBoundingClientRect(); + x.set(e.clientX - rect.left); + y.set(e.clientY - rect.top); + setChars(randomChars()); + }} + > + {children} +
+
+ + +

{chars}

+
+
+
+ ); +}; + +export default HoverPattern; diff --git a/src/components/ui/IconTextMarquee.tsx b/src/components/ui/IconTextMarquee.tsx new file mode 100644 index 0000000..706332f --- /dev/null +++ b/src/components/ui/IconTextMarquee.tsx @@ -0,0 +1,27 @@ +import type { LucideIcon } from "lucide-react"; +import { cls } from "@/lib/utils"; + +const IconTextMarquee = ({ centerIcon: CenterIcon, texts }: { centerIcon: LucideIcon; texts: string[] }) => { + const items = [...texts, ...texts]; + + return ( +
+
+ {Array.from({ length: 10 }).map((_, row) => ( +
+ {items.map((text, i) => ( +
+

{text}

+
+ ))} +
+ ))} +
+
+ +
+
+ ); +}; + +export default IconTextMarquee; diff --git a/src/components/ui/ImageOrVideo.tsx b/src/components/ui/ImageOrVideo.tsx new file mode 100644 index 0000000..a6b19a3 --- /dev/null +++ b/src/components/ui/ImageOrVideo.tsx @@ -0,0 +1,41 @@ +import { cls } from "@/lib/utils"; + +interface ImageOrVideoProps { + imageSrc?: string; + videoSrc?: string; + className?: string; +} + +const ImageOrVideo = ({ + imageSrc, + videoSrc, + className = "", +}: ImageOrVideoProps) => { + if (videoSrc) { + return ( +