Initial commit
This commit is contained in:
74
src/app/blog/page.tsx
Normal file
74
src/app/blog/page.tsx
Normal file
@@ -0,0 +1,74 @@
|
||||
"use client";
|
||||
|
||||
import ReactLenis from "lenis/react";
|
||||
import BlogCardOne from "@/components/sections/blog/BlogCardOne";
|
||||
import FooterCard from '@/components/sections/footer/FooterCard';
|
||||
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
|
||||
import NavbarStyleApple from '@/components/navbar/NavbarStyleApple/NavbarStyleApple';
|
||||
import { useBlogPosts } from "@/hooks/useBlogPosts";
|
||||
import { Twitter, Linkedin, Github } from 'lucide-react';
|
||||
|
||||
export default function BlogPage() {
|
||||
const { posts, isLoading } = useBlogPosts();
|
||||
|
||||
return (
|
||||
<ThemeProvider
|
||||
defaultButtonVariant="text-stagger"
|
||||
defaultTextAnimation="reveal-blur"
|
||||
borderRadius="pill"
|
||||
contentWidth="small"
|
||||
sizing="mediumLargeSizeLargeTitles"
|
||||
background="circleGradient"
|
||||
cardStyle="glass-depth"
|
||||
primaryButtonStyle="diagonal-gradient"
|
||||
secondaryButtonStyle="solid"
|
||||
headingFontWeight="light"
|
||||
>
|
||||
<ReactLenis root>
|
||||
<div id="nav" data-section="nav">
|
||||
<NavbarStyleApple
|
||||
brandName="SaaS Pro"
|
||||
navItems={[
|
||||
{ name: "Home", id: "/" },
|
||||
{ name: "Features", id: "features" },
|
||||
{ name: "Pricing", id: "pricing" },
|
||||
{ name: "Testimonials", id: "testimonials" },
|
||||
{ name: "Contact", id: "contact" }
|
||||
]}
|
||||
/>
|
||||
</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">
|
||||
<BlogCardOne
|
||||
blogs={posts}
|
||||
title="Latest Articles"
|
||||
description="Stay updated with our latest insights and best practices"
|
||||
textboxLayout="default"
|
||||
useInvertedBackground="noInvert"
|
||||
animationType="slide-up"
|
||||
carouselMode="buttons"
|
||||
tag="Blog"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div id="footer" data-section="footer">
|
||||
<FooterCard
|
||||
logoText="SaaS Pro"
|
||||
copyrightText="© 2025 SaaS Pro. All rights reserved."
|
||||
socialLinks={[
|
||||
{ icon: Twitter, href: "https://twitter.com/saaspro", ariaLabel: "Twitter" },
|
||||
{ icon: Linkedin, href: "https://linkedin.com/company/saaspro", ariaLabel: "LinkedIn" },
|
||||
{ icon: Github, href: "https://github.com/saaspro", ariaLabel: "GitHub" }
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
</ReactLenis>
|
||||
</ThemeProvider>
|
||||
);
|
||||
}
|
||||
BIN
src/app/favicon.ico
Normal file
BIN
src/app/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 25 KiB |
5
src/app/globals.css
Normal file
5
src/app/globals.css
Normal file
@@ -0,0 +1,5 @@
|
||||
@import "tailwindcss";
|
||||
@import "./styles/variables.css";
|
||||
@import "./styles/theme.css";
|
||||
@import "./styles/utilities.css";
|
||||
@import "./styles/base.css";
|
||||
1267
src/app/layout.tsx
Normal file
1267
src/app/layout.tsx
Normal file
File diff suppressed because it is too large
Load Diff
202
src/app/page.tsx
Normal file
202
src/app/page.tsx
Normal file
@@ -0,0 +1,202 @@
|
||||
"use client"
|
||||
|
||||
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
|
||||
import NavbarStyleApple from '@/components/navbar/NavbarStyleApple/NavbarStyleApple';
|
||||
import HeroBillboardCarousel from '@/components/sections/hero/HeroBillboardCarousel';
|
||||
import FeatureCardTen from '@/components/sections/feature/FeatureCardTen';
|
||||
import MetricCardThree from '@/components/sections/metrics/MetricCardThree';
|
||||
import PricingCardNine from '@/components/sections/pricing/PricingCardNine';
|
||||
import TestimonialCardFifteen from '@/components/sections/testimonial/TestimonialCardFifteen';
|
||||
import ContactText from '@/components/sections/contact/ContactText';
|
||||
import FooterCard from '@/components/sections/footer/FooterCard';
|
||||
import { Award, BarChart3, Brain, Building2, CheckCircle, Cpu, DollarSign, Download, Github, Globe, Linkedin, Lock, Plug, Share2, Shield, Sparkles, TrendingUp, Twitter, Users, Webhook, Zap } from "lucide-react";
|
||||
|
||||
export default function LandingPage() {
|
||||
return (
|
||||
<ThemeProvider
|
||||
defaultButtonVariant="text-stagger"
|
||||
defaultTextAnimation="reveal-blur"
|
||||
borderRadius="pill"
|
||||
contentWidth="small"
|
||||
sizing="mediumLargeSizeLargeTitles"
|
||||
background="circleGradient"
|
||||
cardStyle="glass-depth"
|
||||
primaryButtonStyle="diagonal-gradient"
|
||||
secondaryButtonStyle="solid"
|
||||
headingFontWeight="light"
|
||||
>
|
||||
<div id="nav" data-section="nav">
|
||||
<NavbarStyleApple
|
||||
brandName="SaaS Pro"
|
||||
navItems={[
|
||||
{ name: "Features", id: "features" },
|
||||
{ name: "Pricing", id: "pricing" },
|
||||
{ name: "Testimonials", id: "testimonials" },
|
||||
{ name: "Contact", id: "contact" }
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div id="hero" data-section="hero">
|
||||
<HeroBillboardCarousel
|
||||
title="Powerful SaaS Platform for Modern Teams"
|
||||
description="Automate your workflow, scale your business, and achieve more with our intelligent platform designed for productivity"
|
||||
tag="Next-Gen Solution"
|
||||
tagIcon={Zap}
|
||||
background={{ variant: "sparkles-gradient" }}
|
||||
buttons={[
|
||||
{ text: "Start Free Trial", href: "contact" },
|
||||
{ text: "View Demo", href: "https://example.com/demo" }
|
||||
]}
|
||||
mediaItems={[
|
||||
{ imageSrc: "https://img.b2bpic.net/free-photo/luxurious-boardroom-space-within-multinational-company-used-meetings_482257-124520.jpg", imageAlt: "Dashboard analytics interface" },
|
||||
{ imageSrc: "https://img.b2bpic.net/free-vector/user-panel-business-dashboard_23-2148358960.jpg", imageAlt: "Workflow automation" },
|
||||
{ imageSrc: "https://img.b2bpic.net/free-vector/user-panel-business-dashboard_23-2148359901.jpg", imageAlt: "Data visualization metrics" },
|
||||
{ imageSrc: "https://img.b2bpic.net/free-vector/user-panel-dashboard-template_23-2148375533.jpg", imageAlt: "Team collaboration workspace" },
|
||||
{ imageSrc: "https://img.b2bpic.net/free-vector/dashboard-user-panel-template_52683-31485.jpg", imageAlt: "API integrations" }
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div id="features" data-section="features">
|
||||
<FeatureCardTen
|
||||
title="Everything You Need to Succeed"
|
||||
description="Packed with powerful features designed to streamline your workflow, enhance collaboration, and drive results"
|
||||
tag="Core Features"
|
||||
tagIcon={Sparkles}
|
||||
textboxLayout="default"
|
||||
animationType="slide-up"
|
||||
useInvertedBackground="invertDefault"
|
||||
features={[
|
||||
{
|
||||
id: "1", title: "AI-Powered Automation", description: "Let intelligent automation handle repetitive tasks so your team can focus on strategic work and innovation", media: { imageSrc: "https://img.b2bpic.net/free-photo/computer-scientist-updating-ai-systems_482257-91183.jpg", imageAlt: "AI automation interface" },
|
||||
items: [
|
||||
{ icon: Zap, text: "Instant task processing" },
|
||||
{ icon: Brain, text: "Smart recommendations" },
|
||||
{ icon: Cpu, text: "Machine learning optimization" }
|
||||
],
|
||||
reverse: false
|
||||
},
|
||||
{
|
||||
id: "2", title: "Enterprise-Grade Security", description: "Your data is protected with industry-leading security protocols, encryption, and compliance standards", media: { imageSrc: "https://img.b2bpic.net/free-photo/data-center-programmers-collaborating-working-neural-networks-ai-databases_482257-129796.jpg", imageAlt: "Security and protection" },
|
||||
items: [
|
||||
{ icon: Shield, text: "Military-grade encryption" },
|
||||
{ icon: Lock, text: "Multi-factor authentication" },
|
||||
{ icon: CheckCircle, text: "SOC 2 certified" }
|
||||
],
|
||||
reverse: true
|
||||
},
|
||||
{
|
||||
id: "3", title: "Seamless Integrations", description: "Connect with your favorite tools and services to create a unified workflow ecosystem", media: { imageSrc: "https://img.b2bpic.net/free-photo/engineers-brainstorming-ways-use-ai_482257-84889.jpg", imageAlt: "API and integrations" },
|
||||
items: [
|
||||
{ icon: Plug, text: "500+ native integrations" },
|
||||
{ icon: Share2, text: "REST API access" },
|
||||
{ icon: Webhook, text: "Real-time webhooks" }
|
||||
],
|
||||
reverse: false
|
||||
},
|
||||
{
|
||||
id: "4", title: "Advanced Analytics & Reporting", description: "Gain actionable insights with comprehensive analytics, custom reports, and real-time dashboards", media: { imageSrc: "https://img.b2bpic.net/free-photo/man-requesting-help-from-coworkers-after-finding-bug-data-center-systems_482257-110863.jpg", imageAlt: "Analytics dashboard" },
|
||||
items: [
|
||||
{ icon: BarChart3, text: "Real-time dashboards" },
|
||||
{ icon: TrendingUp, text: "Predictive analytics" },
|
||||
{ icon: Download, text: "Custom report exports" }
|
||||
],
|
||||
reverse: true
|
||||
}
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div id="metrics" data-section="metrics">
|
||||
<MetricCardThree
|
||||
title="Trusted by Industry Leaders"
|
||||
description="Join thousands of companies scaling their operations with SaaS Pro"
|
||||
tag="Impact"
|
||||
tagIcon={Award}
|
||||
textboxLayout="default"
|
||||
animationType="slide-up"
|
||||
useInvertedBackground="noInvert"
|
||||
metrics={[
|
||||
{ id: "1", icon: Users, title: "Active Users", value: "50,000+" },
|
||||
{ id: "2", icon: Building2, title: "Enterprise Clients", value: "1,200+" },
|
||||
{ id: "3", icon: TrendingUp, title: "Success Rate", value: "98.9%" },
|
||||
{ id: "4", icon: Globe, title: "Countries", value: "85+" }
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div id="pricing" data-section="pricing">
|
||||
<PricingCardNine
|
||||
title="Simple, Transparent Pricing"
|
||||
description="Choose the perfect plan for your team. Upgrade or downgrade anytime with no hidden fees"
|
||||
tag="Pricing Plans"
|
||||
tagIcon={DollarSign}
|
||||
textboxLayout="default"
|
||||
animationType="slide-up"
|
||||
useInvertedBackground="invertDefault"
|
||||
plans={[
|
||||
{
|
||||
id: "starter", title: "Starter", price: "$29", period: "/month", imageSrc: "https://img.b2bpic.net/free-photo/start-up-business-goals-strategy_53876-124798.jpg", imageAlt: "Starter plan", button: { text: "Get Started", href: "contact" },
|
||||
features: [
|
||||
"Up to 5 team members", "Core automation features", "Basic analytics dashboard", "Email support", "5 GB storage"
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "professional", title: "Professional", price: "$99", period: "/month", imageSrc: "https://img.b2bpic.net/free-vector/startup-word-concept_23-2147839490.jpg", imageAlt: "Professional plan", button: { text: "Start Free Trial", href: "contact" },
|
||||
features: [
|
||||
"Up to 25 team members", "Advanced automation workflows", "Real-time analytics & reporting", "Priority support", "100 GB storage", "API access"
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "enterprise", title: "Enterprise", price: "Custom", period: "pricing", imageSrc: "https://img.b2bpic.net/free-vector/startup-landing-page-concept_23-2148311866.jpg", imageAlt: "Enterprise plan", button: { text: "Contact Sales", href: "contact" },
|
||||
features: [
|
||||
"Unlimited team members", "Custom integrations", "Dedicated analytics team", "24/7 phone & email support", "Unlimited storage", "Advanced security features"
|
||||
]
|
||||
}
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div id="testimonials" data-section="testimonials">
|
||||
<TestimonialCardFifteen
|
||||
testimonial="SaaS Pro transformed how we manage our operations. We've saved over 40 hours per month on automation alone, and the platform's intuitive design means our entire team was productive within days. It's been a game-changer for our business growth."
|
||||
rating={5}
|
||||
author="Sarah Chen, Chief Operations Officer at TechVenture"
|
||||
useInvertedBackground="noInvert"
|
||||
avatars={[
|
||||
{ src: "https://img.b2bpic.net/free-photo/close-up-portrait-young-handsome-successful-man_1163-5475.jpg", alt: "Customer testimonial avatar 1" },
|
||||
{ src: "https://img.b2bpic.net/free-photo/smiling-homosexual-man-official-suit-looking-camera-close-up-shot-happy-gay-getting-dressed-wedding-ceremony-standing-hotel-room-with-his-partner-background-love-emotion-concept_74855-22675.jpg", alt: "Customer testimonial avatar 2" },
|
||||
{ src: "https://img.b2bpic.net/free-photo/close-up-competitive-employee_1098-2870.jpg", alt: "Customer testimonial avatar 3" },
|
||||
{ src: "https://img.b2bpic.net/free-photo/closeup-handsome-middle-aged-business-leader_1262-4822.jpg", alt: "Customer testimonial avatar 4" }
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div id="contact" data-section="contact">
|
||||
<ContactText
|
||||
text="Ready to transform your workflow? Start your free trial today and experience the power of intelligent automation"
|
||||
animationType="reveal-blur"
|
||||
background={{ variant: "radial-gradient" }}
|
||||
useInvertedBackground="invertDefault"
|
||||
buttons={[
|
||||
{ text: "Start Free Trial", href: "contact" },
|
||||
{ text: "Schedule Demo", href: "https://example.com/demo" }
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div id="footer" data-section="footer">
|
||||
<FooterCard
|
||||
logoText="SaaS Pro"
|
||||
copyrightText="© 2025 SaaS Pro. All rights reserved."
|
||||
socialLinks={[
|
||||
{ icon: Twitter, href: "https://twitter.com/saaspro", ariaLabel: "Twitter" },
|
||||
{ icon: Linkedin, href: "https://linkedin.com/company/saaspro", ariaLabel: "LinkedIn" },
|
||||
{ icon: Github, href: "https://github.com/saaspro", ariaLabel: "GitHub" }
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
</ThemeProvider>
|
||||
);
|
||||
}
|
||||
240
src/app/shop/[id]/page.tsx
Normal file
240
src/app/shop/[id]/page.tsx
Normal file
@@ -0,0 +1,240 @@
|
||||
"use client";
|
||||
|
||||
import { use, useCallback } from "react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import ReactLenis from "lenis/react";
|
||||
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
|
||||
import NavbarStyleApple from "@/components/navbar/NavbarStyleApple/NavbarStyleApple";
|
||||
import ProductDetailCard from "@/components/ecommerce/productDetail/ProductDetailCard";
|
||||
import ProductCart from "@/components/ecommerce/cart/ProductCart";
|
||||
import FooterCard from "@/components/sections/footer/FooterCard";
|
||||
import { Twitter, Linkedin, Github } from "lucide-react";
|
||||
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="text-stagger"
|
||||
defaultTextAnimation="reveal-blur"
|
||||
borderRadius="pill"
|
||||
contentWidth="small"
|
||||
sizing="mediumLargeSizeLargeTitles"
|
||||
background="circleGradient"
|
||||
cardStyle="glass-depth"
|
||||
primaryButtonStyle="diagonal-gradient"
|
||||
secondaryButtonStyle="solid"
|
||||
headingFontWeight="light"
|
||||
>
|
||||
<ReactLenis root>
|
||||
<div id="navbar" data-section="navbar">
|
||||
<NavbarStyleApple
|
||||
brandName="SaaS Pro"
|
||||
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">
|
||||
<FooterCard
|
||||
logoText="SaaS Pro"
|
||||
copyrightText="© 2025 SaaS Pro. All rights reserved."
|
||||
socialLinks={[
|
||||
{ icon: Twitter, href: "https://twitter.com/saaspro", ariaLabel: "Twitter" },
|
||||
{ icon: Linkedin, href: "https://linkedin.com/company/saaspro", ariaLabel: "LinkedIn" },
|
||||
{ icon: Github, href: "https://github.com/saaspro", ariaLabel: "GitHub" }
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
</ReactLenis>
|
||||
</ThemeProvider>
|
||||
);
|
||||
}
|
||||
|
||||
if (!product) {
|
||||
return (
|
||||
<ThemeProvider
|
||||
defaultButtonVariant="text-stagger"
|
||||
defaultTextAnimation="reveal-blur"
|
||||
borderRadius="pill"
|
||||
contentWidth="small"
|
||||
sizing="mediumLargeSizeLargeTitles"
|
||||
background="circleGradient"
|
||||
cardStyle="glass-depth"
|
||||
primaryButtonStyle="diagonal-gradient"
|
||||
secondaryButtonStyle="solid"
|
||||
headingFontWeight="light"
|
||||
>
|
||||
<ReactLenis root>
|
||||
<div id="navbar" data-section="navbar">
|
||||
<NavbarStyleApple
|
||||
brandName="SaaS Pro"
|
||||
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">
|
||||
<FooterCard
|
||||
logoText="SaaS Pro"
|
||||
copyrightText="© 2025 SaaS Pro. All rights reserved."
|
||||
socialLinks={[
|
||||
{ icon: Twitter, href: "https://twitter.com/saaspro", ariaLabel: "Twitter" },
|
||||
{ icon: Linkedin, href: "https://linkedin.com/company/saaspro", ariaLabel: "LinkedIn" },
|
||||
{ icon: Github, href: "https://github.com/saaspro", ariaLabel: "GitHub" }
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
</ReactLenis>
|
||||
</ThemeProvider>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<ThemeProvider
|
||||
defaultButtonVariant="text-stagger"
|
||||
defaultTextAnimation="reveal-blur"
|
||||
borderRadius="pill"
|
||||
contentWidth="small"
|
||||
sizing="mediumLargeSizeLargeTitles"
|
||||
background="circleGradient"
|
||||
cardStyle="glass-depth"
|
||||
primaryButtonStyle="diagonal-gradient"
|
||||
secondaryButtonStyle="solid"
|
||||
headingFontWeight="light"
|
||||
>
|
||||
<ReactLenis root>
|
||||
<div id="navbar" data-section="navbar">
|
||||
<NavbarStyleApple
|
||||
brandName="SaaS Pro"
|
||||
navItems={[
|
||||
{ name: "Home", id: "/" },
|
||||
{ name: "Shop", id: "/shop" }
|
||||
]}
|
||||
button={{ text: "Cart", onClick: () => setCartOpen(true) }}
|
||||
/>
|
||||
</div>
|
||||
<div id="productDetailCard" data-section="productDetailCard">
|
||||
<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="productCart" data-section="productCart">
|
||||
<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">
|
||||
<FooterCard
|
||||
logoText="SaaS Pro"
|
||||
copyrightText="© 2025 SaaS Pro. All rights reserved."
|
||||
socialLinks={[
|
||||
{ icon: Twitter, href: "https://twitter.com/saaspro", ariaLabel: "Twitter" },
|
||||
{ icon: Linkedin, href: "https://linkedin.com/company/saaspro", ariaLabel: "LinkedIn" },
|
||||
{ icon: Github, href: "https://github.com/saaspro", ariaLabel: "GitHub" }
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
</ReactLenis>
|
||||
</ThemeProvider>
|
||||
);
|
||||
}
|
||||
153
src/app/shop/page.tsx
Normal file
153
src/app/shop/page.tsx
Normal file
@@ -0,0 +1,153 @@
|
||||
"use client";
|
||||
|
||||
import ReactLenis from "lenis/react";
|
||||
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
|
||||
import NavbarStyleApple from "@/components/navbar/NavbarStyleApple/NavbarStyleApple";
|
||||
import ProductCatalog from "@/components/ecommerce/productCatalog/ProductCatalog";
|
||||
import ProductCart from "@/components/ecommerce/cart/ProductCart";
|
||||
import FooterCard from "@/components/sections/footer/FooterCard";
|
||||
import { Twitter, Linkedin, Github } from "lucide-react";
|
||||
import { useProductCatalog } from "@/hooks/useProductCatalog";
|
||||
import { useCart } from "@/hooks/useCart";
|
||||
import { useCheckout } from "@/hooks/useCheckout";
|
||||
import { useCallback } from "react";
|
||||
|
||||
export default function ShopPage() {
|
||||
const {
|
||||
products,
|
||||
isLoading,
|
||||
search,
|
||||
setSearch,
|
||||
filters,
|
||||
} = useProductCatalog({ basePath: "/shop" });
|
||||
|
||||
const {
|
||||
items: cartItems,
|
||||
isOpen: cartOpen,
|
||||
setIsOpen: setCartOpen,
|
||||
updateQuantity,
|
||||
removeItem,
|
||||
total: cartTotal,
|
||||
getCheckoutItems,
|
||||
} = useCart();
|
||||
|
||||
const { checkout, isLoading: isCheckoutLoading } = useCheckout();
|
||||
|
||||
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="text-stagger"
|
||||
defaultTextAnimation="reveal-blur"
|
||||
borderRadius="pill"
|
||||
contentWidth="small"
|
||||
sizing="mediumLargeSizeLargeTitles"
|
||||
background="circleGradient"
|
||||
cardStyle="glass-depth"
|
||||
primaryButtonStyle="diagonal-gradient"
|
||||
secondaryButtonStyle="solid"
|
||||
headingFontWeight="light"
|
||||
>
|
||||
<ReactLenis root>
|
||||
<div id="navbar" data-section="navbar">
|
||||
<NavbarStyleApple
|
||||
brandName="SaaS Pro"
|
||||
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">
|
||||
<FooterCard
|
||||
logoText="SaaS Pro"
|
||||
copyrightText="© 2025 SaaS Pro. All rights reserved."
|
||||
socialLinks={[
|
||||
{ icon: Twitter, href: "https://twitter.com/saaspro", ariaLabel: "Twitter" },
|
||||
{ icon: Linkedin, href: "https://linkedin.com/company/saaspro", ariaLabel: "LinkedIn" },
|
||||
{ icon: Github, href: "https://github.com/saaspro", ariaLabel: "GitHub" }
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
</ReactLenis>
|
||||
</ThemeProvider>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<ThemeProvider
|
||||
defaultButtonVariant="text-stagger"
|
||||
defaultTextAnimation="reveal-blur"
|
||||
borderRadius="pill"
|
||||
contentWidth="small"
|
||||
sizing="mediumLargeSizeLargeTitles"
|
||||
background="circleGradient"
|
||||
cardStyle="glass-depth"
|
||||
primaryButtonStyle="diagonal-gradient"
|
||||
secondaryButtonStyle="solid"
|
||||
headingFontWeight="light"
|
||||
>
|
||||
<ReactLenis root>
|
||||
<div id="navbar" data-section="navbar">
|
||||
<NavbarStyleApple
|
||||
brandName="SaaS Pro"
|
||||
navItems={[
|
||||
{ name: "Home", id: "/" },
|
||||
{ name: "Shop", id: "/shop" }
|
||||
]}
|
||||
button={{ text: "Cart", onClick: () => setCartOpen(true) }}
|
||||
/>
|
||||
</div>
|
||||
<div id="productCatalog" data-section="productCatalog">
|
||||
<ProductCatalog
|
||||
layout="page"
|
||||
products={products}
|
||||
searchValue={search}
|
||||
onSearchChange={setSearch}
|
||||
searchPlaceholder="Search products..."
|
||||
filters={filters}
|
||||
emptyMessage="No products found"
|
||||
/>
|
||||
</div>
|
||||
<div id="productCart" data-section="productCart">
|
||||
<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">
|
||||
<FooterCard
|
||||
logoText="SaaS Pro"
|
||||
copyrightText="© 2025 SaaS Pro. All rights reserved."
|
||||
socialLinks={[
|
||||
{ icon: Twitter, href: "https://twitter.com/saaspro", ariaLabel: "Twitter" },
|
||||
{ icon: Linkedin, href: "https://linkedin.com/company/saaspro", ariaLabel: "LinkedIn" },
|
||||
{ icon: Github, href: "https://github.com/saaspro", ariaLabel: "GitHub" }
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
</ReactLenis>
|
||||
</ThemeProvider>
|
||||
);
|
||||
}
|
||||
28
src/app/styles/base.css
Normal file
28
src/app/styles/base.css
Normal 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-montserrat), sans-serif;
|
||||
position: relative;
|
||||
min-height: 100vh;
|
||||
overscroll-behavior: none;
|
||||
overscroll-behavior-y: none;
|
||||
}
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
font-family: var(--font-montserrat), sans-serif;
|
||||
}
|
||||
174
src/app/styles/theme.css
Normal file
174
src/app/styles/theme.css
Normal 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);
|
||||
}
|
||||
178
src/app/styles/utilities.css
Normal file
178
src/app/styles/utilities.css
Normal 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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
215
src/app/styles/variables.css
Normal file
215
src/app/styles/variables.css
Normal file
@@ -0,0 +1,215 @@
|
||||
:root {
|
||||
/* Base units */
|
||||
/* --vw is set by ThemeProvider */
|
||||
|
||||
/* --background: #f5f5f5;;
|
||||
--card: #ffffff;;
|
||||
--foreground: #1c1c1c;;
|
||||
--primary-cta: #341f51;;
|
||||
--secondary-cta: #ffffff;;
|
||||
--accent: #6139e6;;
|
||||
--background-accent: #b3a8e8;; */
|
||||
|
||||
--background: #f5f5f5;;
|
||||
--card: #ffffff;;
|
||||
--foreground: #1c1c1c;;
|
||||
--primary-cta: #341f51;;
|
||||
--secondary-cta: #ffffff;;
|
||||
--accent: #6139e6;;
|
||||
--background-accent: #b3a8e8;;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user