Initial commit

This commit is contained in:
2026-02-09 18:24:37 +02:00
commit 7f27a7122a
656 changed files with 77361 additions and 0 deletions

103
src/app/blog/page.tsx Normal file
View File

@@ -0,0 +1,103 @@
"use client";
import ReactLenis from "lenis/react";
import BlogCardTwo from '@/components/sections/blog/BlogCardTwo';
import FooterBaseCard from '@/components/sections/footer/FooterBaseCard';
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
import NavbarLayoutFloatingOverlay from '@/components/navbar/NavbarLayoutFloatingOverlay/NavbarLayoutFloatingOverlay';
import { useBlogPosts } from "@/hooks/useBlogPosts";
export default function BlogPage() {
const { posts, isLoading } = useBlogPosts();
return (
<ThemeProvider
defaultButtonVariant="icon-arrow"
defaultTextAnimation="background-highlight"
borderRadius="soft"
contentWidth="mediumSmall"
sizing="largeSmallSizeMediumTitles"
background="aurora"
cardStyle="glass-elevated"
primaryButtonStyle="radial-glow"
secondaryButtonStyle="solid"
headingFontWeight="medium"
>
<ReactLenis root>
<div id="nav" data-section="nav">
<NavbarLayoutFloatingOverlay
brandName="FitFlow"
navItems={[
{ name: "Home", id: "/" },
{ name: "Workout Plans", id: "features" },
{ name: "Success Stories", id: "testimonial" },
{ name: "About", id: "about" },
{ name: "Contact", id: "contact" }
]}
button={{ text: "Download Now", href: "#download" }}
/>
</div>
{isLoading ? (
<div className="w-content-width mx-auto py-20 text-center">
<p className="text-foreground">Loading posts...</p>
</div>
) : (
<div id="blog" data-section="blog">
<BlogCardTwo
blogs={posts}
title="FitFlow Blog"
description="Discover expert fitness tips, workout guides, and success stories to transform your fitness journey"
tag="Fitness"
textboxLayout="default"
useInvertedBackground="noInvert"
carouselMode="buttons"
animationType="slide-up"
/>
</div>
)}
<div id="footer" data-section="footer">
<FooterBaseCard
logoText="FitFlow"
copyrightText="© 2025 FitFlow. All rights reserved. Transforming fitness journeys."
columns={[
{
title: "Product", items: [
{ label: "Features", href: "#features" },
{ label: "Pricing", href: "#pricing" },
{ label: "Download", href: "#download" },
{ label: "What's New", href: "#blog" }
]
},
{
title: "Company", items: [
{ label: "About Us", href: "#about" },
{ label: "Careers", href: "#careers" },
{ label: "Blog", href: "#blog" },
{ label: "Press", href: "#press" }
]
},
{
title: "Resources", items: [
{ label: "Help Center", href: "#faq" },
{ label: "Community", href: "#community" },
{ label: "Coaches", href: "#coaches" },
{ label: "API Docs", href: "#api" }
]
},
{
title: "Legal", items: [
{ label: "Privacy Policy", href: "#privacy" },
{ label: "Terms of Service", href: "#terms" },
{ label: "Cookie Policy", href: "#cookies" },
{ label: "Contact", href: "#contact" }
]
}
]}
/>
</div>
</ReactLenis>
</ThemeProvider>
);
}

BIN
src/app/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

5
src/app/globals.css Normal file
View File

@@ -0,0 +1,5 @@
@import "tailwindcss";
@import "./styles/variables.css";
@import "./styles/theme.css";
@import "./styles/utilities.css";
@import "./styles/base.css";

1268
src/app/layout.tsx Normal file

File diff suppressed because it is too large Load Diff

285
src/app/page.tsx Normal file
View File

@@ -0,0 +1,285 @@
"use client"
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
import NavbarLayoutFloatingOverlay from '@/components/navbar/NavbarLayoutFloatingOverlay/NavbarLayoutFloatingOverlay';
import HeroCentered from '@/components/sections/hero/HeroCentered';
import FeatureCardEight from '@/components/sections/feature/FeatureCardEight';
import TextAbout from '@/components/sections/about/TextAbout';
import MetricCardOne from '@/components/sections/metrics/MetricCardOne';
import TestimonialCardFifteen from '@/components/sections/testimonial/TestimonialCardFifteen';
import ContactFaq from '@/components/sections/contact/ContactFaq';
import FaqDouble from '@/components/sections/faq/FaqDouble';
import FooterBaseCard from '@/components/sections/footer/FooterBaseCard';
import { Download, Star, Target, TrendingUp, Users } from "lucide-react";
export default function FitnessApp() {
return (
<ThemeProvider
defaultButtonVariant="icon-arrow"
defaultTextAnimation="background-highlight"
borderRadius="soft"
contentWidth="mediumSmall"
sizing="largeSmallSizeMediumTitles"
background="aurora"
cardStyle="glass-elevated"
primaryButtonStyle="radial-glow"
secondaryButtonStyle="solid"
headingFontWeight="medium"
>
<div id="nav" data-section="nav">
<NavbarLayoutFloatingOverlay
brandName="FitFlow"
navItems={[
{ name: "Home", id: "hero" },
{ name: "Workout Plans", id: "features" },
{ name: "Success Stories", id: "testimonial" },
{ name: "About", id: "about" },
{ name: "Contact", id: "contact" }
]}
button={{
text: "Download Now", href: "#download"
}}
/>
</div>
<div id="hero" data-section="hero">
<HeroCentered
title="Transform Your Fitness Journey"
description="Personalized workout plans, expert guidance, and a supportive community to help you reach your fitness goals faster than ever before"
background={{ variant: "downward-rays-animated" }}
avatars={[
{
src: "https://img.b2bpic.net/free-photo/closeup-smiling-beautiful-adult-businesswoman_1262-1760.jpg", alt: "User 1"
},
{
src: "https://img.b2bpic.net/free-photo/portrait-smiley-business-woman_23-2148603029.jpg", alt: "User 2"
},
{
src: "https://img.b2bpic.net/free-photo/close-up-good-looking-smiling-friendly-female-trainee-ready-tackle-assignments-smiling-broadly-feeling-lucky-day-work-self-assured-encouraged-achieve-success-goal-white-wall_176420-35567.jpg", alt: "User 3"
}
]}
avatarText="Join 50K+ active members"
buttons={[
{
text: "Start Free Trial", href: "#download"
},
{
text: "Watch Demo", href: "#about"
}
]}
/>
</div>
<div id="features" data-section="features">
<FeatureCardEight
title="Your Personalized Workout Plans"
description="Choose from adaptive workout programs designed by certified fitness trainers, tailored to your fitness level and goals"
tag="Workout Plans"
features={[
{
id: 1,
title: "Cardio Blast", description: "High-intensity cardiovascular training designed to boost endurance and burn calories effectively with guided routines", imageSrc: "https://img.b2bpic.net/free-photo/close-up-athletic-woman-exercising-rowing-machine-while-having-sports-training-fitness-center_637285-516.jpg", imageAlt: "cardio running exercise workout training"
},
{
id: 2,
title: "Strength Build", description: "Progressive resistance training to build muscle, increase strength, and sculpt your physique with expert form guidance", imageSrc: "https://img.b2bpic.net/free-photo/sportswoman-doing-hyperextension-exercise_651396-754.jpg", imageAlt: "strength weightlifting gym workout training"
},
{
id: 3,
title: "Flexibility Flow", description: "Yoga and stretching programs to improve mobility, reduce stress, and enhance recovery between intense workouts", imageSrc: "https://img.b2bpic.net/free-photo/happy-female-athlete-doing-relaxation-exercises-while-warming-up-n-gym_637285-8484.jpg", imageAlt: "yoga flexibility stretching wellness exercise"
},
{
id: 4,
title: "HIIT Express", description: "Time-efficient interval workouts that maximize results in minimal time with scientifically-proven training methods", imageSrc: "https://img.b2bpic.net/free-photo/woman-lifting-weights-doing-chest-work-gym_169016-57291.jpg", imageAlt: "fitness workout gym exercise training"
}
]}
textboxLayout="default"
useInvertedBackground="invertDefault"
buttons={[
{
text: "Explore All Plans", href: "#download"
}
]}
/>
</div>
<div id="about" data-section="about">
<TextAbout
tag="About FitFlow"
title="Your personal trainer, nutrition coach, and fitness community all in one intelligent app. We use advanced AI algorithms to adapt your workouts based on your progress, recovery needs, and personal preferences."
useInvertedBackground="noInvert"
buttons={[
{
text: "Learn How It Works", href: "#features"
}
]}
/>
</div>
<div id="metrics" data-section="metrics">
<MetricCardOne
title="Our Community Impact"
description="See the remarkable results our members are achieving with consistent training and personalized guidance"
gridVariant="uniform-all-items-equal"
animationType="slide-up"
useInvertedBackground="invertDefault"
textboxLayout="default"
metrics={[
{
id: "1", value: "50K", title: "Active Users", description: "Growing fitness community worldwide", icon: Users
},
{
id: "2", value: "100M", title: "Workouts Completed", description: "Total training sessions logged", icon: TrendingUp
},
{
id: "3", value: "85%", title: "Success Rate", description: "Members achieve their fitness goals", icon: Target
},
{
id: "4", value: "4.9", title: "Star Rating", description: "App store user satisfaction score", icon: Star
}
]}
/>
</div>
<div id="testimonial" data-section="testimonial">
<TestimonialCardFifteen
testimonial="FitFlow completely transformed my fitness routine. The personalized plans adapted to my schedule and the community support kept me motivated. I've never felt this confident about my fitness journey."
rating={5}
author="Sarah Mitchell, Fitness Enthusiast"
avatars={[
{
src: "https://img.b2bpic.net/free-photo/closeup-smiling-beautiful-adult-businesswoman_1262-1760.jpg", alt: "Sarah Mitchell"
},
{
src: "https://img.b2bpic.net/free-photo/portrait-smiley-business-woman_23-2148603029.jpg", alt: "User 2"
},
{
src: "https://img.b2bpic.net/free-photo/close-up-good-looking-smiling-friendly-female-trainee-ready-tackle-assignments-smiling-broadly-feeling-lucky-day-work-self-assured-encouraged-achieve-success-goal-white-wall_176420-35567.jpg", alt: "User 3"
},
{
src: "https://img.b2bpic.net/free-photo/blond-business-woman-blue-shirt_23-2148095792.jpg", alt: "User 4"
},
{
src: "https://img.b2bpic.net/free-photo/business-woman-banner-concept-with-copy-space_23-2149601533.jpg", alt: "User 5"
},
{
src: "https://img.b2bpic.net/free-photo/close-up-positive-businesswoman_1098-3531.jpg", alt: "User 6"
}
]
useInvertedBackground="noInvert"
/>
</div>
<div id="download" data-section="download">
<ContactFaq
ctaTitle="Ready to Transform Your Fitness?"
ctaDescription="Download FitFlow now and start your personalized fitness journey with a free 7-day trial. No credit card required."
ctaButton={{
text: "Download App", href: "https://appstore.example.com/fitflow"
}}
ctaIcon={Download}
useInvertedBackground="invertDefault"
animationType="scale-rotate"
faqs={[
{
id: "1", title: "Is there a free trial?", content: "Yes! All new users get a 7-day free trial with full access to all workout plans, coaching features, and community. No payment method required to start."
},
{
id: "2", title: "Can I cancel anytime?", content: "Absolutely. You can cancel your subscription anytime from your account settings. No hidden fees or long-term contracts required."
},
{
id: "3", title: "What equipment do I need?", content: "FitFlow offers workouts for all fitness levels. We have programs requiring no equipment, bodyweight only, or gym access. Choose what works for you."
},
{
id: "4", title: "How personalized are the plans?", content: "Our AI analyzes your fitness level, goals, recovery data, and preferences to continuously adapt your workouts and nutrition recommendations."
},
{
id: "5", title: "Is there coach support?", content: "Premium members get access to certified fitness coaches for form checks, motivation, and personalized guidance via the app."
},
{
id: "6", title: "Works on all devices?", content: "FitFlow is available on iOS and Android. Sync your workouts across all devices and pick up where you left off anytime."
}
]}
/>
</div>
<div id="faq" data-section="faq">
<FaqDouble
title="Frequently Asked Questions"
description="Find answers to common questions about FitFlow, our plans, and how to get the most from your fitness app"
tag="Help Center"
textboxLayout="default"
useInvertedBackground="noInvert"
animationType="smooth"
faqs={[
{
id: "1", title: "How does the AI personalization work?", content: "Our algorithm analyzes your workout history, recovery metrics, body composition data, and personal preferences. It then generates customized plans that evolve as you progress, ensuring continuous challenge and improvement."
},
{
id: "2", title: "Can I track my nutrition?", content: "Yes! FitFlow includes an integrated nutrition tracker with a database of 500K+ foods. Log your meals, track macros, and receive AI-powered meal suggestions aligned with your fitness goals."
},
{
id: "3", title: "What if I'm a complete beginner?", content: "Perfect! We have beginner-friendly programs with detailed video tutorials and form cues. Your workout difficulty automatically scales as you build strength and confidence."
},
{
id: "4", title: "How often should I work out?", content: "FitFlow adapts to your schedule. Whether you prefer 3, 5, or 6 days per week, we'll create a plan that fits your lifestyle while maximizing results and recovery."
},
{
id: "5", title: "Can I share workouts with friends?", content: "Absolutely! Our social features let you create group challenges, share your progress, compete on leaderboards, and keep each other accountable with your fitness community."
},
{
id: "6", title: "How detailed are the video tutorials?", content: "Every exercise includes HD videos from multiple angles showing proper form, common mistakes, and modifications for different fitness levels. Form guidance videos help prevent injuries."
},
{
id: "7", title: "Is the app available offline?", content: "Yes! Download workouts to your phone and access them anywhere without internet. Your data syncs once you're back online."
},
{
id: "8", title: "How do I contact support?", content: "Our support team is available 24/7 via in-app chat, email, or phone. Premium members get priority support with response times under 1 hour."
}
]}
/>
</div>
<div id="footer" data-section="footer">
<FooterBaseCard
logoText="FitFlow"
copyrightText="© 2025 FitFlow. All rights reserved. Transforming fitness journeys."
columns={[
{
title: "Product", items: [
{ label: "Features", href: "#features" },
{ label: "Pricing", href: "#pricing" },
{ label: "Download", href: "#download" },
{ label: "What's New", href: "#blog" }
]
},
{
title: "Company", items: [
{ label: "About Us", href: "#about" },
{ label: "Careers", href: "#careers" },
{ label: "Blog", href: "#blog" },
{ label: "Press", href: "#press" }
]
},
{
title: "Resources", items: [
{ label: "Help Center", href: "#faq" },
{ label: "Community", href: "#community" },
{ label: "Coaches", href: "#coaches" },
{ label: "API Docs", href: "#api" }
]
},
{
title: "Legal", items: [
{ label: "Privacy Policy", href: "#privacy" },
{ label: "Terms of Service", href: "#terms" },
{ label: "Cookie Policy", href: "#cookies" },
{ label: "Contact", href: "#contact" }
]
}
]}
/>
</div>
</ThemeProvider>
);
}

242
src/app/shop/[id]/page.tsx Normal file
View File

@@ -0,0 +1,242 @@
"use client";
import { use, useCallback } from "react";
import { useRouter } from "next/navigation";
import ReactLenis from "lenis/react";
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
import NavbarLayoutFloatingOverlay from '@/components/navbar/NavbarLayoutFloatingOverlay/NavbarLayoutFloatingOverlay';
import ProductDetailCard from "@/components/ecommerce/productDetail/ProductDetailCard";
import ProductCart from "@/components/ecommerce/cart/ProductCart";
import FooterBaseCard from '@/components/sections/footer/FooterBaseCard';
import { useProductDetail } from "@/hooks/useProductDetail";
import { useCart } from "@/hooks/useCart";
import { useCheckout } from "@/hooks/useCheckout";
interface ProductPageProps {
params: Promise<{ id: string }>;
}
export default function ProductPage({ params }: ProductPageProps) {
const { id } = use(params);
const router = useRouter();
const {
product,
isLoading,
images,
meta,
variants,
quantityVariant,
selectedQuantity,
createCartItem,
} = useProductDetail(id);
const {
items: cartItems,
isOpen: cartOpen,
setIsOpen: setCartOpen,
addItem,
updateQuantity,
removeItem,
total: cartTotal,
getCheckoutItems,
} = useCart();
const { buyNow, checkout, isLoading: isCheckoutLoading } = useCheckout();
const handleAddToCart = useCallback(() => {
const item = createCartItem();
if (item) {
addItem(item);
}
}, [createCartItem, addItem]);
const handleBuyNow = useCallback(() => {
if (product) {
buyNow(product, selectedQuantity);
}
}, [product, selectedQuantity, buyNow]);
const handleCheckout = useCallback(async () => {
if (cartItems.length === 0) return;
const currentUrl = new URL(window.location.href);
currentUrl.searchParams.set("success", "true");
await checkout(getCheckoutItems(), { successUrl: currentUrl.toString() });
}, [cartItems, checkout, getCheckoutItems]);
if (isLoading) {
return (
<ThemeProvider
defaultButtonVariant="icon-arrow"
defaultTextAnimation="background-highlight"
borderRadius="soft"
contentWidth="mediumSmall"
sizing="largeSmallSizeMediumTitles"
background="aurora"
cardStyle="glass-elevated"
primaryButtonStyle="radial-glow"
secondaryButtonStyle="solid"
headingFontWeight="medium"
>
<ReactLenis root>
<div id="navbar" data-section="navbar">
<NavbarLayoutFloatingOverlay
brandName="FitFlow"
navItems={[
{"name":"Home","id":"/"},
{"name":"Shop","id":"/shop"}
]}
button={{ text: "Cart", onClick: () => setCartOpen(true) }}
/>
</div>
<main className="min-h-screen flex items-center justify-center pt-20">
<p className="text-foreground">Loading product...</p>
</main>
<div id="footer" data-section="footer">
<FooterBaseCard
logoText="FitFlow"
copyrightText="© 2025 FitFlow. All rights reserved. Transforming fitness journeys."
columns={[
{"title":"Product","items":[{"label":"Features","href":"#features"},{"label":"Pricing","href":"#pricing"},{"label":"Download","href":"#download"},{"label":"What's New","href":"#blog"}]},
{"title":"Company","items":[{"label":"About Us","href":"#about"},{"label":"Careers","href":"#careers"},{"label":"Blog","href":"#blog"},{"label":"Press","href":"#press"}]},
{"title":"Resources","items":[{"label":"Help Center","href":"#faq"},{"label":"Community","href":"#community"},{"label":"Coaches","href":"#coaches"},{"label":"API Docs","href":"#api"}]},
{"title":"Legal","items":[{"label":"Privacy Policy","href":"#privacy"},{"label":"Terms of Service","href":"#terms"},{"label":"Cookie Policy","href":"#cookies"},{"label":"Contact","href":"#contact"}]}
]}
/>
</div>
</ReactLenis>
</ThemeProvider>
);
}
if (!product) {
return (
<ThemeProvider
defaultButtonVariant="icon-arrow"
defaultTextAnimation="background-highlight"
borderRadius="soft"
contentWidth="mediumSmall"
sizing="largeSmallSizeMediumTitles"
background="aurora"
cardStyle="glass-elevated"
primaryButtonStyle="radial-glow"
secondaryButtonStyle="solid"
headingFontWeight="medium"
>
<ReactLenis root>
<div id="navbar" data-section="navbar">
<NavbarLayoutFloatingOverlay
brandName="FitFlow"
navItems={[
{"name":"Home","id":"/"},
{"name":"Shop","id":"/shop"}
]}
button={{ text: "Cart", onClick: () => setCartOpen(true) }}
/>
</div>
<main className="min-h-screen flex items-center justify-center pt-20">
<div className="text-center">
<p className="text-foreground mb-4">Product not found</p>
<button
onClick={() => router.push("/shop")}
className="primary-button px-6 py-2 rounded-theme"
>
Back to Shop
</button>
</div>
</main>
<div id="footer" data-section="footer">
<FooterBaseCard
logoText="FitFlow"
copyrightText="© 2025 FitFlow. All rights reserved. Transforming fitness journeys."
columns={[
{"title":"Product","items":[{"label":"Features","href":"#features"},{"label":"Pricing","href":"#pricing"},{"label":"Download","href":"#download"},{"label":"What's New","href":"#blog"}]},
{"title":"Company","items":[{"label":"About Us","href":"#about"},{"label":"Careers","href":"#careers"},{"label":"Blog","href":"#blog"},{"label":"Press","href":"#press"}]},
{"title":"Resources","items":[{"label":"Help Center","href":"#faq"},{"label":"Community","href":"#community"},{"label":"Coaches","href":"#coaches"},{"label":"API Docs","href":"#api"}]},
{"title":"Legal","items":[{"label":"Privacy Policy","href":"#privacy"},{"label":"Terms of Service","href":"#terms"},{"label":"Cookie Policy","href":"#cookies"},{"label":"Contact","href":"#contact"}]}
]}
/>
</div>
</ReactLenis>
</ThemeProvider>
);
}
return (
<ThemeProvider
defaultButtonVariant="icon-arrow"
defaultTextAnimation="background-highlight"
borderRadius="soft"
contentWidth="mediumSmall"
sizing="largeSmallSizeMediumTitles"
background="aurora"
cardStyle="glass-elevated"
primaryButtonStyle="radial-glow"
secondaryButtonStyle="solid"
headingFontWeight="medium"
>
<ReactLenis root>
<div id="navbar" data-section="navbar">
<NavbarLayoutFloatingOverlay
brandName="FitFlow"
navItems={[
{"name":"Home","id":"/"},
{"name":"Shop","id":"/shop"}
]}
button={{ text: "Cart", onClick: () => setCartOpen(true) }}
/>
</div>
<div id="product-detail-card" data-section="product-detail-card">
<ProductDetailCard
layout="page"
name={product.name}
price={product.price}
salePrice={meta.salePrice}
rating={product.rating || 0}
description={product.description}
images={images}
variants={variants.length > 0 ? variants : undefined}
quantity={quantityVariant}
ribbon={meta.ribbon}
inventoryStatus={meta.inventoryStatus}
inventoryQuantity={meta.inventoryQuantity}
sku={meta.sku}
buttons={[
{ text: "Add To Cart", onClick: handleAddToCart },
{ text: "Buy Now", onClick: handleBuyNow },
]}
/>
</div>
<div id="product-cart" data-section="product-cart">
<ProductCart
isOpen={cartOpen}
onClose={() => setCartOpen(false)}
items={cartItems}
onQuantityChange={updateQuantity}
onRemove={removeItem}
total={`$${cartTotal}`}
buttons={[
{
text: isCheckoutLoading ? "Processing..." : "Check Out", onClick: handleCheckout,
},
]}
/>
</div>
<div id="footer" data-section="footer">
<FooterBaseCard
logoText="FitFlow"
copyrightText="© 2025 FitFlow. All rights reserved. Transforming fitness journeys."
columns={[
{"title":"Product","items":[{"label":"Features","href":"#features"},{"label":"Pricing","href":"#pricing"},{"label":"Download","href":"#download"},{"label":"What's New","href":"#blog"}]},
{"title":"Company","items":[{"label":"About Us","href":"#about"},{"label":"Careers","href":"#careers"},{"label":"Blog","href":"#blog"},{"label":"Press","href":"#press"}]},
{"title":"Resources","items":[{"label":"Help Center","href":"#faq"},{"label":"Community","href":"#community"},{"label":"Coaches","href":"#coaches"},{"label":"API Docs","href":"#api"}]},
{"title":"Legal","items":[{"label":"Privacy Policy","href":"#privacy"},{"label":"Terms of Service","href":"#terms"},{"label":"Cookie Policy","href":"#cookies"},{"label":"Contact","href":"#contact"}]}
]}
/>
</div>
</ReactLenis>
</ThemeProvider>
);
}

116
src/app/shop/page.tsx Normal file
View File

@@ -0,0 +1,116 @@
"use client";
import ReactLenis from "lenis/react";
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
import NavbarLayoutFloatingOverlay from '@/components/navbar/NavbarLayoutFloatingOverlay/NavbarLayoutFloatingOverlay';
import ProductCatalog from "@/components/ecommerce/productCatalog/ProductCatalog";
import FooterBaseCard from '@/components/sections/footer/FooterBaseCard';
import { useProductCatalog } from "@/hooks/useProductCatalog";
import { useState } from "react";
export default function ShopPage() {
const [cartOpen, setCartOpen] = useState(false);
const {
products,
isLoading,
search,
setSearch,
filters,
} = useProductCatalog({ basePath: "/shop" });
if (isLoading) {
return (
<ThemeProvider
defaultButtonVariant="icon-arrow"
defaultTextAnimation="background-highlight"
borderRadius="soft"
contentWidth="mediumSmall"
sizing="largeSmallSizeMediumTitles"
background="aurora"
cardStyle="glass-elevated"
primaryButtonStyle="radial-glow"
secondaryButtonStyle="solid"
headingFontWeight="medium"
>
<ReactLenis root>
<div id="navbar" data-section="navbar">
<NavbarLayoutFloatingOverlay
brandName="FitFlow"
navItems={[
{"name":"Home","id":"/"},
{"name":"Shop","id":"/shop"}
]}
button={{ text: "Cart", onClick: () => setCartOpen(true) }}
/>
</div>
<main className="min-h-screen flex items-center justify-center pt-20">
<p className="text-foreground">Loading products...</p>
</main>
<div id="footer" data-section="footer">
<FooterBaseCard
logoText="FitFlow"
copyrightText="© 2025 FitFlow. All rights reserved. Transforming fitness journeys."
columns={[
{"title":"Product","items":[{"label":"Features","href":"#features"},{"label":"Pricing","href":"#pricing"},{"label":"Download","href":"#download"},{"label":"What's New","href":"#blog"}]},
{"title":"Company","items":[{"label":"About Us","href":"#about"},{"label":"Careers","href":"#careers"},{"label":"Blog","href":"#blog"},{"label":"Press","href":"#press"}]},
{"title":"Resources","items":[{"label":"Help Center","href":"#faq"},{"label":"Community","href":"#community"},{"label":"Coaches","href":"#coaches"},{"label":"API Docs","href":"#api"}]},
{"title":"Legal","items":[{"label":"Privacy Policy","href":"#privacy"},{"label":"Terms of Service","href":"#terms"},{"label":"Cookie Policy","href":"#cookies"},{"label":"Contact","href":"#contact"}]}
]}
/>
</div>
</ReactLenis>
</ThemeProvider>
);
}
return (
<ThemeProvider
defaultButtonVariant="icon-arrow"
defaultTextAnimation="background-highlight"
borderRadius="soft"
contentWidth="mediumSmall"
sizing="largeSmallSizeMediumTitles"
background="aurora"
cardStyle="glass-elevated"
primaryButtonStyle="radial-glow"
secondaryButtonStyle="solid"
headingFontWeight="medium"
>
<ReactLenis root>
<div id="navbar" data-section="navbar">
<NavbarLayoutFloatingOverlay
brandName="FitFlow"
navItems={[
{"name":"Home","id":"/"},
{"name":"Shop","id":"/shop"}
]}
button={{ text: "Cart", onClick: () => setCartOpen(true) }}
/>
</div>
<div id="product-catalog" data-section="product-catalog">
<ProductCatalog
layout="page"
products={products}
searchValue={search}
onSearchChange={setSearch}
searchPlaceholder="Search products..."
filters={filters}
emptyMessage="No products found"
/>
</div>
<div id="footer" data-section="footer">
<FooterBaseCard
logoText="FitFlow"
copyrightText="© 2025 FitFlow. All rights reserved. Transforming fitness journeys."
columns={[
{"title":"Product","items":[{"label":"Features","href":"#features"},{"label":"Pricing","href":"#pricing"},{"label":"Download","href":"#download"},{"label":"What's New","href":"#blog"}]},
{"title":"Company","items":[{"label":"About Us","href":"#about"},{"label":"Careers","href":"#careers"},{"label":"Blog","href":"#blog"},{"label":"Press","href":"#press"}]},
{"title":"Resources","items":[{"label":"Help Center","href":"#faq"},{"label":"Community","href":"#community"},{"label":"Coaches","href":"#coaches"},{"label":"API Docs","href":"#api"}]},
{"title":"Legal","items":[{"label":"Privacy Policy","href":"#privacy"},{"label":"Terms of Service","href":"#terms"},{"label":"Cookie Policy","href":"#cookies"},{"label":"Contact","href":"#contact"}]}
]}
/>
</div>
</ReactLenis>
</ThemeProvider>
);
}

28
src/app/styles/base.css Normal file
View File

@@ -0,0 +1,28 @@
* {
scrollbar-width: thin;
scrollbar-color: rgba(255, 255, 255, 1) rgba(255, 255, 255, 0);
}
html {
overscroll-behavior: none;
overscroll-behavior-y: none;
}
body {
background-color: var(--background);
color: var(--foreground);
font-family: var(--font-inter), sans-serif;
position: relative;
min-height: 100vh;
overscroll-behavior: none;
overscroll-behavior-y: none;
}
h1,
h2,
h3,
h4,
h5,
h6 {
font-family: var(--font-plus-jakarta-sans), sans-serif;
}

174
src/app/styles/theme.css Normal file
View File

@@ -0,0 +1,174 @@
@theme inline {
--color-background: var(--background);
--color-card: var(--card);
--color-foreground: var(--foreground);
--color-primary-cta: var(--primary-cta);
--color-secondary-cta: var(--secondary-cta);
--color-accent: var(--accent);
--color-background-accent: var(--background-accent);
/* theme border radius */
--radius-theme: var(--theme-border-radius);
--radius-theme-capped: var(--theme-border-radius-capped);
/* text */
--text-2xs: var(--text-2xs);
--text-xs: var(--text-xs);
--text-sm: var(--text-sm);
--text-base: var(--text-base);
--text-lg: var(--text-lg);
--text-xl: var(--text-xl);
--text-2xl: var(--text-2xl);
--text-3xl: var(--text-3xl);
--text-4xl: var(--text-4xl);
--text-5xl: var(--text-5xl);
--text-6xl: var(--text-6xl);
--text-7xl: var(--text-7xl);
--text-8xl: var(--text-8xl);
--text-9xl: var(--text-9xl);
/* height */
--height-4: var(--height-4);
--height-5: var(--height-5);
--height-6: var(--height-6);
--height-7: var(--height-7);
--height-8: var(--height-8);
--height-9: var(--height-9);
--height-11: var(--height-11);
--height-12: var(--height-12);
--height-10: var(--height-10);
--height-30: var(--height-30);
--height-90: var(--height-90);
--height-100: var(--height-100);
--height-110: var(--height-110);
--height-120: var(--height-120);
--height-130: var(--height-130);
--height-140: var(--height-140);
--height-150: var(--height-150);
--height-page-padding: calc(2.25rem+var(--vw-1_5)+var(--vw-1_5));
/* width */
--width-5: var(--width-5);
--width-7_5: var(--width-7_5);
--width-10: var(--width-10);
--width-12_5: var(--width-12_5);
--width-15: var(--width-15);
--width-17: var(--width-17);
--width-17_5: var(--width-17_5);
--width-20: var(--width-20);
--width-21: var(--width-21);
--width-22_5: var(--width-22_5);
--width-25: var(--width-25);
--width-26: var(--width-26);
--width-27_5: var(--width-27_5);
--width-30: var(--width-30);
--width-32_5: var(--width-32_5);
--width-35: var(--width-35);
--width-37_5: var(--width-37_5);
--width-40: var(--width-40);
--width-42_5: var(--width-42_5);
--width-45: var(--width-45);
--width-47_5: var(--width-47_5);
--width-50: var(--width-50);
--width-52_5: var(--width-52_5);
--width-55: var(--width-55);
--width-57_5: var(--width-57_5);
--width-60: var(--width-60);
--width-62_5: var(--width-62_5);
--width-65: var(--width-65);
--width-67_5: var(--width-67_5);
--width-70: var(--width-70);
--width-72_5: var(--width-72_5);
--width-75: var(--width-75);
--width-77_5: var(--width-77_5);
--width-80: var(--width-80);
--width-82_5: var(--width-82_5);
--width-85: var(--width-85);
--width-87_5: var(--width-87_5);
--width-90: var(--width-90);
--width-92_5: var(--width-92_5);
--width-95: var(--width-95);
--width-97_5: var(--width-97_5);
--width-100: var(--width-100);
--width-content-width: var(--width-content-width);
--width-carousel-padding: var(--width-carousel-padding);
--width-carousel-padding-controls: var(--width-carousel-padding-controls);
--width-carousel-padding-expanded: var(--width-carousel-padding-expanded);
--width-carousel-padding-controls-expanded: var(--width-carousel-padding-controls-expanded);
--width-carousel-item-3: var(--width-carousel-item-3);
--width-carousel-item-4: var(--width-carousel-item-4);
--width-x-padding-mask-fade: var(--width-x-padding-mask-fade);
--width-content-width-expanded: var(--width-content-width-expanded);
/* gap */
--spacing-1: var(--vw-0_25);
--spacing-2: var(--vw-0_5);
--spacing-3: var(--vw-0_75);
--spacing-4: var(--vw-1);
--spacing-5: var(--vw-1_25);
--spacing-6: var(--vw-1_5);
--spacing-7: var(--vw-1_75);
--spacing-8: var(--vw-2);
--spacing-x-1: var(--vw-0_25);
--spacing-x-2: var(--vw-0_5);
--spacing-x-3: var(--vw-0_75);
--spacing-x-4: var(--vw-1);
--spacing-x-5: var(--vw-1_25);
--spacing-x-6: var(--vw-1_5);
/* border radius */
--radius-none: 0;
--radius-sm: var(--vw-0_5);
--radius: var(--vw-0_75);
--radius-md: var(--vw-1);
--radius-lg: var(--vw-1_25);
--radius-xl: var(--vw-1_75);
--radius-full: 999px;
/* padding */
--padding-1: var(--vw-0_25);
--padding-2: var(--vw-0_5);
--padding-2.5: var(--vw-0_625);
--padding-3: var(--vw-0_75);
--padding-4: var(--vw-1);
--padding-5: var(--vw-1_25);
--padding-6: var(--vw-1_5);
--padding-7: var(--vw-1_75);
--padding-8: var(--vw-2);
--padding-x-1: var(--vw-0_25);
--padding-x-2: var(--vw-0_5);
--padding-x-3: var(--vw-0_75);
--padding-x-4: var(--vw-1);
--padding-x-5: var(--vw-1_25);
--padding-x-6: var(--vw-1_5);
--padding-x-7: var(--vw-1_75);
--padding-x-8: var(--vw-2);
--padding-hero-page-padding-half: var(--padding-hero-page-padding-half);
--padding-hero-page-padding: var(--padding-hero-page-padding);
--padding-hero-page-padding-1_5: var(--padding-hero-page-padding-1_5);
--padding-hero-page-padding-double: var(--padding-hero-page-padding-double);
/* margin */
--margin-1: var(--vw-0_25);
--margin-2: var(--vw-0_5);
--margin-3: var(--vw-0_75);
--margin-4: var(--vw-1);
--margin-5: var(--vw-1_25);
--margin-6: var(--vw-1_5);
--margin-7: var(--vw-1_75);
--margin-8: var(--vw-2);
--margin-x-1: var(--vw-0_25);
--margin-x-2: var(--vw-0_5);
--margin-x-3: var(--vw-0_75);
--margin-x-4: var(--vw-1);
--margin-x-5: var(--vw-1_25);
--margin-x-6: var(--vw-1_5);
--margin-x-7: var(--vw-1_75);
--margin-x-8: var(--vw-2);
}

View File

@@ -0,0 +1,178 @@
@layer components {}
@layer utilities {
/* Card, primary-button, and secondary-button styles are now dynamically injected via ThemeProvider */
/* .card {
@apply backdrop-blur-sm bg-gradient-to-br from-card/80 to-card/40 shadow-sm border border-card;
}
.primary-button {
@apply bg-gradient-to-b from-primary-cta/83 to-primary-cta;
box-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;
}
.secondary-button {
@apply backdrop-blur-sm bg-gradient-to-br from-secondary-cta/80 to-secondary-cta shadow-sm border border-secondary-cta;
} */
.tag-card {
@apply backdrop-blur-sm bg-gradient-to-br from-card/80 to-card/40 shadow-sm border border-card;
}
.mask-fade-x {
-webkit-mask-image: linear-gradient(to right, transparent 0%, transparent calc((100vw - var(--width-content-width)) / 4), black calc((100vw - var(--width-content-width)) / 2 + 5vw), black calc(100% - (100vw - var(--width-content-width)) / 2 - 5vw), transparent calc(100% - (100vw - var(--width-content-width)) / 4), transparent 100%);
mask-image: linear-gradient(to right, transparent 0%, transparent calc((100vw - var(--width-content-width)) / 4), black calc((100vw - var(--width-content-width)) / 2 + 5vw), black calc(100% - (100vw - var(--width-content-width)) / 2 - 5vw), transparent calc(100% - (100vw - var(--width-content-width)) / 4), transparent 100%);
}
.mask-padding-x {
-webkit-mask-image: linear-gradient(to right, transparent 0%, black var(--width-x-padding-mask-fade), black calc(100% - var(--width-x-padding-mask-fade)), transparent 100%);
mask-image: linear-gradient(to right, transparent 0%, black var(--width-x-padding-mask-fade), black calc(100% - var(--width-x-padding-mask-fade)), transparent 100%);
}
.mask-fade-bottom {
-webkit-mask-image: linear-gradient(to bottom, black 0%, black 50%, transparent 100%);
mask-image: linear-gradient(to bottom, black 0%, black 50%, transparent 100%);
}
.mask-fade-y {
mask-image: linear-gradient(to bottom,
transparent 0%,
black var(--vw-1_5),
black calc(100% - var(--vw-1_5)),
transparent 100%);
}
.mask-fade-bottom-large {
-webkit-mask-image: linear-gradient(to bottom, black 0%, black 50%, transparent 75%, transparent 100%);
mask-image: linear-gradient(to bottom, black 0%, black 50%, transparent 75%, transparent 100%);
}
.mask-fade-bottom-long {
-webkit-mask-image: linear-gradient(to bottom, black 0%, black 5%, transparent 100%);
mask-image: linear-gradient(to bottom, black 0%, black 5%, transparent 100%);
}
.mask-fade-top-long {
-webkit-mask-image: linear-gradient(to top, black 0%, black 5%, transparent 100%);
mask-image: linear-gradient(to top, black 0%, black 5%, transparent 100%);
}
.mask-fade-xy {
-webkit-mask-image:
linear-gradient(to right, transparent 0%, black 20%, black 80%, transparent 100%),
linear-gradient(to bottom, transparent 0%, black 20%, black 80%, transparent 100%);
mask-image:
linear-gradient(to right, transparent 0%, black 20%, black 80%, transparent 100%),
linear-gradient(to bottom, transparent 0%, black 20%, black 80%, transparent 100%);
-webkit-mask-composite: source-in;
mask-composite: intersect;
}
/* ANIMATION */
.animation-container {
animation:
fadeInOpacity 0.8s ease-in-out forwards,
fadeInTranslate 0.6s forwards;
}
.animation-container-fade {
animation: fadeInOpacity 0.8s ease-in-out forwards;
}
@keyframes fadeInOpacity {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes fadeInTranslate {
from {
transform: translateY(0.75vh);
}
to {
transform: translateY(0vh);
}
}
@keyframes aurora {
from {
background-position: 50% 50%, 50% 50%;
}
to {
background-position: 350% 50%, 350% 50%;
}
}
@keyframes spin-slow {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
@keyframes spin-reverse {
from {
transform: rotate(0deg);
}
to {
transform: rotate(-360deg);
}
}
.animate-spin-slow {
animation: spin-slow 15s linear infinite;
}
.animate-spin-reverse {
animation: spin-reverse 10s linear infinite;
}
@keyframes marquee-vertical {
from {
transform: translateY(0);
}
to {
transform: translateY(-50%);
}
}
.animate-marquee-vertical {
animation: marquee-vertical 20s linear infinite;
}
@keyframes orbit {
from {
transform: rotate(var(--initial-position, 0deg)) translateX(var(--translate-position, 120px)) rotate(calc(-1 * var(--initial-position, 0deg)));
}
to {
transform: rotate(calc(var(--initial-position, 0deg) + 360deg)) translateX(var(--translate-position, 120px)) rotate(calc(-1 * (var(--initial-position, 0deg) + 360deg)));
}
}
@keyframes map-dot-pulse {
0%, 100% {
transform: scale(0.4);
opacity: 0.6;
}
50% {
transform: scale(1.4);
opacity: 1;
}
}
}

View File

@@ -0,0 +1,215 @@
:root {
/* Base units */
/* --vw is set by ThemeProvider */
/* --background: #f7f6f7;;
--card: #ffffff;;
--foreground: #0c1325;;
--primary-cta: #0b07ff;;
--secondary-cta: #ffffff;;
--accent: #93b7ff;;
--background-accent: #a8bae8;; */
--background: #f7f6f7;;
--card: #ffffff;;
--foreground: #0c1325;;
--primary-cta: #0b07ff;;
--secondary-cta: #ffffff;;
--accent: #93b7ff;;
--background-accent: #a8bae8;;
/* text sizing - set by ThemeProvider */
/* --text-2xs: clamp(0.465rem, 0.62vw, 0.62rem);
--text-xs: clamp(0.54rem, 0.72vw, 0.72rem);
--text-sm: clamp(0.615rem, 0.82vw, 0.82rem);
--text-base: clamp(0.69rem, 0.92vw, 0.92rem);
--text-lg: clamp(0.75rem, 1vw, 1rem);
--text-xl: clamp(0.825rem, 1.1vw, 1.1rem);
--text-2xl: clamp(0.975rem, 1.3vw, 1.3rem);
--text-3xl: clamp(1.2rem, 1.6vw, 1.6rem);
--text-4xl: clamp(1.5rem, 2vw, 2rem);
--text-5xl: clamp(2.025rem, 2.75vw, 2.75rem);
--text-6xl: clamp(2.475rem, 3.3vw, 3.3rem);
--text-7xl: clamp(3rem, 4vw, 4rem);
--text-8xl: clamp(3.5rem, 4.5vw, 4.5rem);
--text-9xl: clamp(5.25rem, 7vw, 7rem); */
/* Base spacing units */
--vw-0_25: calc(var(--vw) * 0.25);
--vw-0_5: calc(var(--vw) * 0.5);
--vw-0_625: calc(var(--vw) * 0.625);
--vw-0_75: calc(var(--vw) * 0.75);
--vw-1: calc(var(--vw) * 1);
--vw-1_25: calc(var(--vw) * 1.25);
--vw-1_5: calc(var(--vw) * 1.5);
--vw-1_75: calc(var(--vw) * 1.75);
--vw-2: calc(var(--vw) * 2);
--vw-2_25: calc(var(--vw) * 2.25);
--vw-2_5: calc(var(--vw) * 2.5);
--vw-2_75: calc(var(--vw) * 2.75);
--vw-3: calc(var(--vw) * 3);
/* width */
--width-5: clamp(4rem, 5vw, 6rem);
--width-7_5: clamp(5.625rem, 7.5vw, 7.5rem);
--width-10: clamp(7.5rem, 10vw, 10rem);
--width-12_5: clamp(9.375rem, 12.5vw, 12.5rem);
--width-15: clamp(11.25rem, 15vw, 15rem);
--width-17: clamp(12.75rem, 17vw, 17rem);
--width-17_5: clamp(13.125rem, 17.5vw, 17.5rem);
--width-20: clamp(15rem, 20vw, 20rem);
--width-21: clamp(15.75rem, 21vw, 21rem);
--width-22_5: clamp(16.875rem, 22.5vw, 22.5rem);
--width-25: clamp(18.75rem, 25vw, 25rem);
--width-26: clamp(19.5rem, 26vw, 26rem);
--width-27_5: clamp(20.625rem, 27.5vw, 27.5rem);
--width-30: clamp(22.5rem, 30vw, 30rem);
--width-32_5: clamp(24.375rem, 32.5vw, 32.5rem);
--width-35: clamp(26.25rem, 35vw, 35rem);
--width-37_5: clamp(28.125rem, 37.5vw, 37.5rem);
--width-40: clamp(30rem, 40vw, 40rem);
--width-42_5: clamp(31.875rem, 42.5vw, 42.5rem);
--width-45: clamp(33.75rem, 45vw, 45rem);
--width-47_5: clamp(35.625rem, 47.5vw, 47.5rem);
--width-50: clamp(37.5rem, 50vw, 50rem);
--width-52_5: clamp(39.375rem, 52.5vw, 52.5rem);
--width-55: clamp(41.25rem, 55vw, 55rem);
--width-57_5: clamp(43.125rem, 57.5vw, 57.5rem);
--width-60: clamp(45rem, 60vw, 60rem);
--width-62_5: clamp(46.875rem, 62.5vw, 62.5rem);
--width-65: clamp(48.75rem, 65vw, 65rem);
--width-67_5: clamp(50.625rem, 67.5vw, 67.5rem);
--width-70: clamp(52.5rem, 70vw, 70rem);
--width-72_5: clamp(54.375rem, 72.5vw, 72.5rem);
--width-75: clamp(56.25rem, 75vw, 75rem);
--width-77_5: clamp(58.125rem, 77.5vw, 77.5rem);
--width-80: clamp(60rem, 80vw, 80rem);
--width-82_5: clamp(61.875rem, 82.5vw, 82.5rem);
--width-85: clamp(63.75rem, 85vw, 85rem);
--width-87_5: clamp(65.625rem, 87.5vw, 87.5rem);
--width-90: clamp(67.5rem, 90vw, 90rem);
--width-92_5: clamp(69.375rem, 92.5vw, 92.5rem);
--width-95: clamp(71.25rem, 95vw, 95rem);
--width-97_5: clamp(73.125rem, 97.5vw, 97.5rem);
--width-100: clamp(75rem, 100vw, 100rem);
/* --width-content-width and --width-content-width-expanded are set by ThemeProvider */
--width-carousel-padding: calc((100vw - var(--width-content-width)) / 2 + 1px - var(--vw-1_5));
--width-carousel-padding-controls: calc((100vw - var(--width-content-width)) / 2 + 1px);
--width-carousel-padding-expanded: calc((var(--width-content-width-expanded) - var(--width-content-width)) / 2 + 1px - var(--vw-1_5));
--width-carousel-padding-controls-expanded: calc((var(--width-content-width-expanded) - var(--width-content-width)) / 2 + 1px);
--width-carousel-item-3: calc(var(--width-content-width) / 3 - var(--vw-1_5) / 3 * 2);
--width-carousel-item-4: calc(var(--width-content-width) / 4 - var(--vw-1_5) / 4 * 3);
--width-x-padding-mask-fade: clamp(1.5rem, 4vw, 4rem);
--height-4: 1rem;
--height-5: 1.25rem;
--height-6: 1.5rem;
--height-7: 1.75rem;
--height-8: 2rem;
--height-9: 2.25rem;
--height-10: 2.5rem;
--height-11: 2.75rem;
--height-12: 3rem;
--height-30: 7.5rem;
--height-90: 22.5rem;
--height-100: 25rem;
--height-110: 27.5rem;
--height-120: 30rem;
--height-130: 32.5rem;
--height-140: 35rem;
--height-150: 37.5rem;
/* hero page padding */
--padding-hero-page-padding-half: calc((var(--height-10) + var(--vw-1_5) + var(--vw-1_5) + var(--height-10)) / 2);
--padding-hero-page-padding: calc(var(--height-10) + var(--vw-1_5) + var(--vw-1_5) + var(--height-10));
--padding-hero-page-padding-1_5: calc(1.5 * (var(--height-10) + var(--vw-1_5) + var(--vw-1_5) + var(--height-10)));
--padding-hero-page-padding-double: calc(2 * (var(--height-10) + var(--vw-1_5) + var(--vw-1_5) + var(--height-10)));
}
@media (max-width: 767px) {
:root {
/* --vw and text sizing are set by ThemeProvider */
/* --vw: 3vw;
--text-2xs: 2.5vw;
--text-xs: 2.75vw;
--text-sm: 3vw;
--text-base: 3.25vw;
--text-lg: 3.5vw;
--text-xl: 4.25vw;
--text-2xl: 5vw;
--text-3xl: 6vw;
--text-4xl: 7vw;
--text-5xl: 7.5vw;
--text-6xl: 8.5vw;
--text-7xl: 10vw;
--text-8xl: 12vw;
--text-9xl: 14vw; */
--width-5: 5vw;
--width-7_5: 7.5vw;
--width-10: 10vw;
--width-12_5: 12.5vw;
--width-15: 15vw;
--width-17_5: 17.5vw;
--width-20: 20vw;
--width-22_5: 22.5vw;
--width-25: 25vw;
--width-27_5: 27.5vw;
--width-30: 30vw;
--width-32_5: 32.5vw;
--width-35: 35vw;
--width-37_5: 37.5vw;
--width-40: 40vw;
--width-42_5: 42.5vw;
--width-45: 45vw;
--width-47_5: 47.5vw;
--width-50: 50vw;
--width-52_5: 52.5vw;
--width-55: 55vw;
--width-57_5: 57.5vw;
--width-60: 60vw;
--width-62_5: 62.5vw;
--width-65: 65vw;
--width-67_5: 67.5vw;
--width-70: 70vw;
--width-72_5: 72.5vw;
--width-75: 75vw;
--width-77_5: 77.5vw;
--width-80: 80vw;
--width-82_5: 82.5vw;
--width-85: 85vw;
--width-87_5: 87.5vw;
--width-90: 90vw;
--width-92_5: 92.5vw;
--width-95: 95vw;
--width-97_5: 97.5vw;
--width-100: 100vw;
/* --width-content-width and --width-content-width-expanded are set by ThemeProvider */
--width-carousel-padding: calc((100vw - var(--width-content-width)) / 2 + 1px - var(--vw-1_5));
--width-carousel-padding-controls: calc((100vw - var(--width-content-width)) / 2 + 1px);
--width-carousel-padding-expanded: calc((var(--width-content-width-expanded) - var(--width-content-width)) / 2 + 1px - var(--vw-1_5));
--width-carousel-padding-controls-expanded: calc((var(--width-content-width-expanded) - var(--width-content-width)) / 2 + 1px);
--width-carousel-item-3: var(--width-content-width);
--width-carousel-item-4: var(--width-content-width);
--width-x-padding-mask-fade: 10vw;
--height-4: 3.5vw;
--height-5: 4.5vw;
--height-6: 5.5vw;
--height-7: 6.5vw;
--height-8: 7.5vw;
--height-9: 8.5vw;
--height-10: 9vw;
--height-11: 10vw;
--height-12: 11vw;
--height-30: 25vw;
--height-90: 81vw;
--height-100: 90vw;
--height-110: 99vw;
--height-120: 108vw;
--height-130: 117vw;
--height-140: 126vw;
--height-150: 135vw;
}
}