Initial commit

This commit is contained in:
DK
2026-02-06 18:09:05 +00:00
commit 0a1ca8ce6e
656 changed files with 77252 additions and 0 deletions

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

@@ -0,0 +1,69 @@
"use client";
import ReactLenis from "lenis/react";
import BlogCardTwo from '@/components/sections/blog/BlogCardTwo';
import FooterLogoReveal from '@/components/sections/footer/FooterLogoReveal';
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
import NavbarStyleApple from '@/components/navbar/NavbarStyleApple/NavbarStyleApple';
import { useBlogPosts } from "@/hooks/useBlogPosts";
export default function BlogPage() {
const { posts, isLoading } = useBlogPosts();
return (
<ThemeProvider
defaultButtonVariant="text-stagger"
defaultTextAnimation="background-highlight"
borderRadius="pill"
contentWidth="medium"
sizing="largeSizeMediumTitles"
background="aurora"
cardStyle="outline"
primaryButtonStyle="primary-glow"
secondaryButtonStyle="radial-glow"
headingFontWeight="normal"
>
<ReactLenis root>
<div id="nav" data-section="nav">
<NavbarStyleApple
brandName="Josiah Hestad"
navItems={[
{ name: "Home", id: "/" },
{ name: "About", id: "about" },
{ name: "Achievements", id: "achievements" },
{ name: "Goals", id: "goals" },
{ 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">
<BlogCardTwo
blogs={posts}
title="My Blog"
description="Thoughts, insights, and experiences from my journey"
textboxLayout="default"
useInvertedBackground="noInvert"
carouselMode="buttons"
animationType="slide-up"
tag="Articles"
/>
</div>
)}
<div id="footer" data-section="footer">
<FooterLogoReveal
logoText="Josiah Hestad"
leftLink={{ text: "Privacy", href: "#" }}
rightLink={{ text: "Connect", 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";

1270
src/app/layout.tsx Normal file

File diff suppressed because it is too large Load Diff

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

@@ -0,0 +1,179 @@
"use client"
import NavbarStyleApple from '@/components/navbar/NavbarStyleApple/NavbarStyleApple';
import HeroOverlay from '@/components/sections/hero/HeroOverlay';
import MediaAbout from '@/components/sections/about/MediaAbout';
import MetricCardThree from '@/components/sections/metrics/MetricCardThree';
import FeatureCardTwentyFour from '@/components/sections/feature/FeatureCardTwentyFour';
import ProductCardThree from '@/components/sections/product/ProductCardThree';
import TestimonialCardTwelve from '@/components/sections/testimonial/TestimonialCardTwelve';
import ContactCTA from '@/components/sections/contact/ContactCTA';
import FooterLogoReveal from '@/components/sections/footer/FooterLogoReveal';
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
import { Trophy, Clock, Target, Award, Zap, Star, Mail } from "lucide-react";
export default function LandingPage() {
return (
<ThemeProvider
defaultButtonVariant="text-stagger"
defaultTextAnimation="background-highlight"
borderRadius="pill"
contentWidth="medium"
sizing="largeSizeMediumTitles"
background="aurora"
cardStyle="outline"
primaryButtonStyle="primary-glow"
secondaryButtonStyle="radial-glow"
headingFontWeight="normal"
>
<div id="nav" data-section="nav">
<NavbarStyleApple
brandName="Josiah Hestad"
navItems={[
{ name: "About", id: "about" },
{ name: "Achievements", id: "achievements" },
{ name: "Goals", id: "goals" },
{ name: "Contact", id: "contact" }
]}
/>
</div>
<div id="hero" data-section="hero">
<HeroOverlay
title="Josiah Hestad"
description="2x Ironman. Future ParaRescue. Kinesiology Student. Pushing limits through discipline, resilience, and relentless training."
tag="Elite Athlete"
tagIcon={Zap}
imageSrc="https://img.b2bpic.net/free-photo/man-running-water_23-2151909679.jpg"
imageAlt="Josiah Hestad training with intensity and focus"
textPosition="bottom-left"
showBlur={true}
showDimOverlay={false}
buttons={[
{ text: "Explore My Journey", href: "about" },
{ text: "Get in Touch", href: "contact" }
]}
/>
</div>
<div id="about" data-section="about">
<MediaAbout
title="Who I Am"
description="I'm Josiah Hestad, an athlete and professional dedicated to excellence in every pursuit. With two Ironman finishes, I've proven my capacity for endurance, discipline, and mental toughness. Currently training for ParaRescue with the U.S. Air Force, I'm pursuing the highest standards of physical and mental resilience. As a Kinesiology student at San Diego State University, I'm combining practical athletic experience with scientific understanding of human movement and performance. My journey exemplifies the power of setting audacious goals and maintaining unwavering commitment to achieving them."
tag="About"
imageSrc="https://img.b2bpic.net/free-photo/smiling-athletic-man-black-background_613910-9870.jpg"
imageAlt="Josiah Hestad professional portrait"
useInvertedBackground="noInvert"
buttons={[
{ text: "Learn More", href: "achievements" }
]}
/>
</div>
<div id="achievements" data-section="achievements">
<MetricCardThree
title="Athletic Achievements"
description="Quantifiable proof of dedication and excellence across multiple disciplines."
tag="Track Record"
textboxLayout="default"
animationType="slide-up"
useInvertedBackground="invertDefault"
metrics={[
{ id: "1", icon: Trophy, title: "Ironman Finishes", value: "2x" },
{ id: "2", icon: Clock, title: "Hours of Training", value: "2000+" },
{ id: "3", icon: Target, title: "ParaRescue Candidate", value: "Elite Track" },
{ id: "4", icon: Award, title: "Peak Performance", value: "365 Days/Year" }
]}
/>
</div>
<div id="features" data-section="features">
<FeatureCardTwentyFour
title="My Excellence Across Disciplines"
description="Mastering multiple domains through focused intensity and scientific approach."
tag="Core Competencies"
textboxLayout="default"
animationType="slide-up"
useInvertedBackground="noInvert"
features={[
{
id: "1", title: "Ironman Endurance", author: "2x Finisher", description: "Completed two full Ironman distance triathlons, mastering 2.4-mile swim, 112-mile bike, and marathon run. Demonstrated exceptional aerobic capacity, mental fortitude, and race strategy execution under extreme physical stress.", tags: ["Triathlon", "Endurance", "Fitness"],
imageSrc: "https://img.b2bpic.net/free-photo/man-running-water_23-2151909679.jpg", imageAlt: "Ironman triathlon competition"
},
{
id: "2", title: "ParaRescue Training", author: "Active Candidate", description: "Currently training for U.S. Air Force ParaRescue qualification. Maintaining elite physical standards including advanced swimming, mountain operations, medical training, and tactical operations. Pursuing one of the military's most challenging career fields.", tags: ["Military", "Rescue", "Leadership"],
imageSrc: "https://img.b2bpic.net/free-photo/off-duty-military-man-enjoying-family-moments_342744-378.jpg", imageAlt: "Military pararescue training operations"
},
{
id: "3", title: "Kinesiology Studies", author: "San Diego State University", description: "Pursuing degree in Kinesiology while applying practical athletic knowledge. Studying human movement science, biomechanics, exercise physiology, and sports medicine. Combining academic excellence with real-world athletic experience to deepen understanding of performance optimization.", tags: ["Science", "Education", "Performance"],
imageSrc: "https://img.b2bpic.net/free-photo/patient-doing-physical-rehabilitation-helped-by-therapists_23-2149227880.jpg", imageAlt: "Sports science and kinesiology studies"
}
]}
/>
</div>
<div id="training" data-section="training">
<ProductCardThree
title="Training Excellence"
description="My commitment to peak physical and mental performance through specialized training protocols."
tag="Discipline"
textboxLayout="default"
animationType="slide-up"
useInvertedBackground="invertDefault"
gridVariant="three-columns-all-equal-width"
products={[
{
id: "1", name: "Aerobic Conditioning", price: "Elite Level", imageSrc: "https://img.b2bpic.net/free-photo/cool-man-with-tattoos-ultra-trail-runner_346278-119.jpg", imageAlt: "Mountain training and endurance conditioning", initialQuantity: 1
},
{
id: "2", name: "Strength Development", price: "Advanced", imageSrc: "https://img.b2bpic.net/free-photo/off-duty-military-man-enjoying-family-moments_342744-378.jpg", imageAlt: "Strength training and functional fitness", initialQuantity: 1
},
{
id: "3", name: "Mental Resilience", price: "Mastered", imageSrc: "https://img.b2bpic.net/free-photo/man-running-water_23-2151909679.jpg", imageAlt: "Mental toughness and performance psychology", initialQuantity: 1
}
]}
/>
</div>
<div id="testimonials" data-section="testimonials">
<TestimonialCardTwelve
cardTitle="Trusted by peers, coaches, and mentors who recognize unwavering commitment to excellence"
cardTag="Recognition"
cardTagIcon={Star}
useInvertedBackground="noInvert"
testimonials={[
{ id: "1", name: "Coach Davis", imageSrc: "https://img.b2bpic.net/free-vector/spartan-helmet-logo-design_23-2150367201.jpg" },
{ id: "2", name: "Team Ironman", imageSrc: "https://img.b2bpic.net/free-vector/athletes-logo-design_742173-19764.jpg" },
{ id: "3", name: "SDSU Faculty", imageSrc: "https://img.b2bpic.net/free-vector/spartan-helmet-logo-design_23-2150367204.jpg" },
{ id: "4", name: "Military Mentors", imageSrc: "https://img.b2bpic.net/free-vector/detailed-bike-logo-cycling-concept_23-2148830901.jpg" },
{ id: "5", name: "Performance Team", imageSrc: "https://img.b2bpic.net/free-vector/athletic-logo-template-design_742173-19853.jpg" },
{ id: "6", name: "Training Partners", imageSrc: "https://img.b2bpic.net/free-vector/hand-drawn-viking-logo-template_23-2150824823.jpg" }
]}
/>
</div>
<div id="contact" data-section="contact">
<ContactCTA
tag="Connect"
tagIcon={Mail}
title="Ready to Connect?"
description="Whether you're interested in training collaboration, sponsorship opportunities, or simply want to learn more about my journey, I'd love to hear from you. Let's discuss how we can work together."
background={{ variant: "plain" }}
useInvertedBackground="noInvert"
buttons={[
{ text: "Send Message", href: "mailto:josiah@example.com" },
{ text: "Follow My Journey", href: "https://instagram.com" }
]}
/>
</div>
<div id="footer" data-section="footer">
<FooterLogoReveal
logoText="Josiah Hestad"
leftLink={{ text: "Privacy", href: "#" }}
rightLink={{ text: "Connect", href: "#contact" }}
/>
</div>
</ThemeProvider>
);
}

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

@@ -0,0 +1,237 @@
"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 FooterLogoReveal from '@/components/sections/footer/FooterLogoReveal';
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="background-highlight"
borderRadius="pill"
contentWidth="medium"
sizing="largeSizeMediumTitles"
background="aurora"
cardStyle="outline"
primaryButtonStyle="primary-glow"
secondaryButtonStyle="radial-glow"
headingFontWeight="normal"
>
<ReactLenis root>
<div id="navbar" data-section="navbar">
<NavbarStyleApple
brandName="Josiah Hestad"
navItems={[
{ name: "Home", id: "/" },
{ name: "About", id: "about" },
{ name: "Achievements", id: "achievements" },
{ name: "Goals", id: "goals" },
{ name: "Contact", id: "contact" },
{ 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">
<FooterLogoReveal
logoText="Josiah Hestad"
leftLink={{ text: "Privacy", href: "#" }}
rightLink={{ text: "Connect", href: "#contact" }}
/>
</div>
</ReactLenis>
</ThemeProvider>
);
}
if (!product) {
return (
<ThemeProvider
defaultButtonVariant="text-stagger"
defaultTextAnimation="background-highlight"
borderRadius="pill"
contentWidth="medium"
sizing="largeSizeMediumTitles"
background="aurora"
cardStyle="outline"
primaryButtonStyle="primary-glow"
secondaryButtonStyle="radial-glow"
headingFontWeight="normal"
>
<ReactLenis root>
<div id="navbar" data-section="navbar">
<NavbarStyleApple
brandName="Josiah Hestad"
navItems={[
{ name: "Home", id: "/" },
{ name: "About", id: "about" },
{ name: "Achievements", id: "achievements" },
{ name: "Goals", id: "goals" },
{ name: "Contact", id: "contact" },
{ 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">
<FooterLogoReveal
logoText="Josiah Hestad"
leftLink={{ text: "Privacy", href: "#" }}
rightLink={{ text: "Connect", href: "#contact" }}
/>
</div>
</ReactLenis>
</ThemeProvider>
);
}
return (
<ThemeProvider
defaultButtonVariant="text-stagger"
defaultTextAnimation="background-highlight"
borderRadius="pill"
contentWidth="medium"
sizing="largeSizeMediumTitles"
background="aurora"
cardStyle="outline"
primaryButtonStyle="primary-glow"
secondaryButtonStyle="radial-glow"
headingFontWeight="normal"
>
<ReactLenis root>
<div id="navbar" data-section="navbar">
<NavbarStyleApple
brandName="Josiah Hestad"
navItems={[
{ name: "Home", id: "/" },
{ name: "About", id: "about" },
{ name: "Achievements", id: "achievements" },
{ name: "Goals", id: "goals" },
{ name: "Contact", id: "contact" },
{ name: "Shop", id: "/shop" }
]}
button={{ text: "Cart", onClick: () => setCartOpen(true) }}
/>
</div>
<div id="product-detail" data-section="product-detail">
<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>
<ProductCart
isOpen={cartOpen}
onClose={() => setCartOpen(false)}
items={cartItems}
onQuantityChange={updateQuantity}
onRemove={removeItem}
total={`$${cartTotal}`}
buttons={[
{
text: isCheckoutLoading ? "Processing..." : "Check Out", onClick: handleCheckout,
},
]}
/>
<div id="footer" data-section="footer">
<FooterLogoReveal
logoText="Josiah Hestad"
leftLink={{ text: "Privacy", href: "#" }}
rightLink={{ text: "Connect", href: "#contact" }}
/>
</div>
</ReactLenis>
</ThemeProvider>
);
}

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

@@ -0,0 +1,150 @@
"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 FooterLogoReveal from '@/components/sections/footer/FooterLogoReveal';
import { useProductCatalog } from "@/hooks/useProductCatalog";
import { useState } from "react";
import ProductCart from "@/components/ecommerce/cart/ProductCart";
import { useCart } from "@/hooks/useCart";
import { useCheckout } from "@/hooks/useCheckout";
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 = async () => {
if (cartItems.length === 0) return;
const currentUrl = new URL(window.location.href);
currentUrl.searchParams.set("success", "true");
await checkout(getCheckoutItems(), { successUrl: currentUrl.toString() });
};
if (isLoading) {
return (
<ThemeProvider
defaultButtonVariant="text-stagger"
defaultTextAnimation="background-highlight"
borderRadius="pill"
contentWidth="medium"
sizing="largeSizeMediumTitles"
background="aurora"
cardStyle="outline"
primaryButtonStyle="primary-glow"
secondaryButtonStyle="radial-glow"
headingFontWeight="normal"
>
<ReactLenis root>
<div id="navbar" data-section="navbar">
<NavbarStyleApple
brandName="Josiah Hestad"
navItems={[
{ name: "Home", id: "/" },
{ name: "About", id: "about" },
{ name: "Achievements", id: "achievements" },
{ name: "Goals", id: "goals" },
{ name: "Contact", id: "contact" },
{ 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">
<FooterLogoReveal
logoText="Josiah Hestad"
leftLink={{ text: "Privacy", href: "#" }}
rightLink={{ text: "Connect", href: "#contact" }}
/>
</div>
</ReactLenis>
</ThemeProvider>
);
}
return (
<ThemeProvider
defaultButtonVariant="text-stagger"
defaultTextAnimation="background-highlight"
borderRadius="pill"
contentWidth="medium"
sizing="largeSizeMediumTitles"
background="aurora"
cardStyle="outline"
primaryButtonStyle="primary-glow"
secondaryButtonStyle="radial-glow"
headingFontWeight="normal"
>
<ReactLenis root>
<div id="navbar" data-section="navbar">
<NavbarStyleApple
brandName="Josiah Hestad"
navItems={[
{ name: "Home", id: "/" },
{ name: "About", id: "about" },
{ name: "Achievements", id: "achievements" },
{ name: "Goals", id: "goals" },
{ name: "Contact", id: "contact" },
{ 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>
<ProductCart
isOpen={cartOpen}
onClose={() => setCartOpen(false)}
items={cartItems}
onQuantityChange={updateQuantity}
onRemove={removeItem}
total={`$${cartTotal}`}
buttons={[
{
text: isCheckoutLoading ? "Processing..." : "Check Out", onClick: handleCheckout,
},
]}
/>
<div id="footer" data-section="footer">
<FooterLogoReveal
logoText="Josiah Hestad"
leftLink={{ text: "Privacy", href: "#" }}
rightLink={{ text: "Connect", 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-dm-sans), sans-serif;
position: relative;
min-height: 100vh;
overscroll-behavior: none;
overscroll-behavior-y: none;
}
h1,
h2,
h3,
h4,
h5,
h6 {
font-family: var(--font-manrope), 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: #fcf6ec;;
--card: #f3ede2;;
--foreground: #2e2521;;
--primary-cta: #2e2521;;
--secondary-cta: #ffffff;;
--accent: #b2a28b;;
--background-accent: #b2a28b;; */
--background: #fcf6ec;;
--card: #f3ede2;;
--foreground: #2e2521;;
--primary-cta: #2e2521;;
--secondary-cta: #ffffff;;
--accent: #b2a28b;;
--background-accent: #b2a28b;;
/* 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;
}
}