Initial commit

This commit is contained in:
DK
2026-02-07 15:52:32 +00:00
commit ccfea52c8e
656 changed files with 77300 additions and 0 deletions

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

@@ -0,0 +1,98 @@
"use client";
import ReactLenis from "lenis/react";
import BlogCardThree from '@/components/sections/blog/BlogCardThree';
import FooterBaseReveal from '@/components/sections/footer/FooterBaseReveal';
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
import NavbarLayoutFloatingInline from '@/components/navbar/NavbarLayoutFloatingInline';
import { useBlogPosts } from "@/hooks/useBlogPosts";
export default function BlogPage() {
const { posts, isLoading } = useBlogPosts();
return (
<ThemeProvider
defaultButtonVariant="shift-hover"
defaultTextAnimation="background-highlight"
borderRadius="sharp"
contentWidth="smallMedium"
sizing="mediumLargeSizeLargeTitles"
background="circleGradient"
cardStyle="gradient-mesh"
primaryButtonStyle="primary-glow"
secondaryButtonStyle="radial-glow"
headingFontWeight="extrabold"
>
<ReactLenis root>
<div id="nav" data-section="nav">
<NavbarLayoutFloatingInline
brandName="Omakase Niseko"
navItems={[
{ name: "Home", id: "/" },
{ name: "Experience", id: "experience" },
{ name: "About", id: "about" },
{ name: "Reservations", id: "contact" },
{ name: "Gallery", id: "testimonials" }
]}
button={{ text: "Book Now", href: "#contact" }}
className="backdrop-blur-md bg-black/40 border border-red-900/30"
navItemClassName="text-white hover:text-red-400 transition-colors"
buttonClassName="bg-red-600 hover:bg-red-700 text-white"
buttonTextClassName="font-bold"
/>
</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">
<BlogCardThree
blogs={posts}
title="Culinary Stories"
description="Discover the artistry behind our omakase experience through stories of tradition, innovation, and seasonal mastery"
tag="Journal"
textboxLayout="default"
useInvertedBackground="noInvert"
carouselMode="buttons"
animationType="slide-up"
/>
</div>
)}
<div id="footer" data-section="footer">
<FooterBaseReveal
columns={[
{
title: "Experience", items: [
{ label: "The Omakase", href: "#experience" },
{ label: "Our Philosophy", href: "#about" },
{ label: "Reservations", href: "#contact" }
]
},
{
title: "Location", items: [
{ label: "Niseko, Hokkaido", href: "#" },
{ label: "Hours: 5:00 PM - 11:00 PM", href: "#" },
{ label: "Closed Mondays", href: "#" }
]
},
{
title: "Connect", items: [
{ label: "Instagram", href: "https://instagram.com" },
{ label: "Contact", href: "#contact" },
{ label: "Inquiries", href: "mailto:info@omakaseniseko.com" }
]
}
]}
copyrightText="© 2025 Omakase Niseko. All rights reserved."
className="w-full"
columnTitleClassName="text-white font-extrabold text-lg mb-4"
columnItemClassName="text-gray-400 hover:text-red-400 transition-colors text-sm mb-2"
/>
</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";

1261
src/app/layout.tsx Normal file

File diff suppressed because it is too large Load Diff

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

@@ -0,0 +1,249 @@
"use client"
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
import NavbarLayoutFloatingInline from '@/components/navbar/NavbarLayoutFloatingInline';
import HeroLogoBillboard from '@/components/sections/hero/HeroLogoBillboard';
import MediaSplitTabsAbout from '@/components/sections/about/MediaSplitTabsAbout';
import FeatureCardTwentyThree from '@/components/sections/feature/FeatureCardTwentyThree';
import MetricCardOne from '@/components/sections/metrics/MetricCardOne';
import TestimonialCardSix from '@/components/sections/testimonial/TestimonialCardSix';
import ContactSplitForm from '@/components/sections/contact/ContactSplitForm';
import FooterBaseReveal from '@/components/sections/footer/FooterBaseReveal';
import { Award, ChefHat, Users, Sparkles } from "lucide-react";
export default function LandingPage() {
return (
<ThemeProvider
defaultButtonVariant="shift-hover"
defaultTextAnimation="background-highlight"
borderRadius="sharp"
contentWidth="smallMedium"
sizing="mediumLargeSizeLargeTitles"
background="circleGradient"
cardStyle="gradient-mesh"
primaryButtonStyle="primary-glow"
secondaryButtonStyle="radial-glow"
headingFontWeight="extrabold"
>
<div id="nav" data-section="nav">
<NavbarLayoutFloatingInline
brandName="Omakase Niseko"
navItems={[
{ name: "Experience", id: "experience" },
{ name: "About", id: "about" },
{ name: "Reservations", id: "contact" },
{ name: "Gallery", id: "testimonials" }
]}
button={{
text: "Book Now", href: "#contact"
}}
className="backdrop-blur-md bg-black/40 border border-red-900/30"
navItemClassName="text-white hover:text-red-400 transition-colors"
buttonClassName="bg-red-600 hover:bg-red-700 text-white"
buttonTextClassName="font-bold"
/>
</div>
<div id="hero" data-section="hero">
<HeroLogoBillboard
logoText="Omakase Niseko"
description="Experience the pinnacle of Japanese culinary artistry. An intimate omakase journey featuring the finest seasonal ingredients, expertly prepared by our master sushi chef in the heart of Niseko's mountain paradise."
buttons={[
{ text: "Reserve Your Seat", href: "#contact" },
{ text: "Our Philosophy", href: "#about" }
]}
background={{ variant: "glowing-orb" }}
imageSrc="https://img.b2bpic.net/free-photo/sushi-roll_1203-3647.jpg"
imageAlt="Premium omakase sushi presentation"
frameStyle="card"
className="w-full"
logoClassName="text-white text-7xl md:text-8xl font-extrabold"
descriptionClassName="text-red-100 text-base md:text-xl"
buttonClassName="bg-red-600 hover:bg-red-700 text-white font-bold"
buttonTextClassName="font-extrabold"
/>
</div>
<div id="about" data-section="about">
<MediaSplitTabsAbout
title="The Omakase Experience"
description="Discover what makes Omakase Niseko an unforgettable culinary destination."
tabs={[
{
id: "craftsmanship", label: "Master Craftsmanship", description: "Our chef trained for over 20 years in Tokyo's most prestigious omakase restaurants. Every piece is crafted with meticulous attention to detail, showcasing decades of tradition and innovation combined."
},
{
id: "ingredients", label: "Finest Ingredients", description: "We source premium fish daily from Japan's leading distributors, ensuring only the finest seasonal ingredients reach your plate. Each piece is selected for texture, flavor, and perfection."
},
{
id: "philosophy", label: "Our Philosophy", description: "Omakase means 'trust the chef.' We believe in creating an intimate experience where the chef's expertise guides you through a carefully curated journey of flavors, textures, and traditions."
}
]}
imageSrc="https://img.b2bpic.net/free-photo/sushi-set-with-gold-color-table_140725-5505.jpg"
imageAlt="Master sushi chef in preparation"
imagePosition="right"
useInvertedBackground="noInvert"
className="w-full"
titleClassName="text-white text-4xl md:text-5xl font-extrabold"
descriptionClassName="text-gray-300 text-base md:text-lg"
tabClassName="text-gray-400 hover:text-red-400 transition-colors px-4 py-2 font-semibold border-b border-transparent hover:border-red-600"
activeTabClassName="text-red-500 border-b-2 border-red-600"
/>
</div>
<div id="experience" data-section="experience">
<FeatureCardTwentyThree
title="The Journey"
description="Each course is a masterpiece, carefully orchestrated to showcase the season's finest ingredients and the chef's creative vision."
features={[
{
id: "1", title: "Seasonal Selection", tags: ["Premium", "Curated"],
imageSrc: "https://img.b2bpic.net/free-photo/vertical-shot-fresh-tuna-salmon-scallop-nigiri-shrimp-sushi-chopsticks_181624-50855.jpg", imageAlt: "Fresh premium ingredients"
},
{
id: "2", title: "Intimate Counter Seating", tags: ["Exclusive", "Limited"],
imageSrc: "https://img.b2bpic.net/free-photo/empty-wood-chair_1339-6717.jpg", imageAlt: "Intimate restaurant counter"
},
{
id: "3", title: "Personalized Menu", tags: ["Bespoke", "Chef's Choice"],
imageSrc: "https://img.b2bpic.net/free-photo/sushi-set-with-gold-color-table_140725-5505.jpg", imageAlt: "Chef preparing personalized selection"
}
]}
animationType="slide-up"
textboxLayout="default"
useInvertedBackground="noInvert"
tag="Experience"
tagIcon={Sparkles}
className="w-full"
titleClassName="text-white text-4xl md:text-5xl font-extrabold"
descriptionClassName="text-gray-300 text-base md:text-lg"
cardTitleClassName="text-white font-bold text-xl"
tagClassName="text-red-400 bg-red-950/30 px-3 py-1 rounded-full text-sm font-semibold"
/>
</div>
<div id="metrics" data-section="metrics">
<MetricCardOne
metrics={[
{
id: "1", value: "20+", title: "Years", description: "Master chef experience in Tokyo's finest restaurants", icon: Award
},
{
id: "2", value: "15", title: "Courses", description: "Average omakase journey with premium selections", icon: ChefHat
},
{
id: "3", value: "8", title: "Seats", description: "Exclusive counter seating for intimate experiences", icon: Users
}
]}
title="By The Numbers"
description="Excellence defined by precision and tradition"
gridVariant="uniform-all-items-equal"
animationType="slide-up"
textboxLayout="default"
useInvertedBackground="noInvert"
className="w-full"
titleClassName="text-white text-2xl font-bold -mt-4"
descriptionClassName="text-gray-400 text-sm mt-2"
valueClassName="text-red-500 text-8xl font-extrabold"
/>
</div>
<div id="testimonials" data-section="testimonials">
<TestimonialCardSix
title="Guest Experiences"
description="What our guests say about their omakase journey with us"
testimonials={[
{
id: "1", name: "Sarah Mitchell", handle: "Tokyo, Japan", testimonial: "An absolutely transcendent experience. The chef's knowledge and passion for every piece was evident. This is omakase at its finest.", imageSrc: "https://img.b2bpic.net/free-photo/lifestyle-people-learning-make-sushi_23-2149865319.jpg", imageAlt: "Sarah Mitchell"
},
{
id: "2", name: "Takeshi Yamamoto", handle: "Osaka, Japan", testimonial: "I've enjoyed omakase across Japan, and this is exceptional. The quality of the fish is outstanding and the presentation is impeccable.", imageSrc: "https://img.b2bpic.net/free-photo/side-view-man-cutting-eggplant-into-slices-cutting-board-with-knife-white-table_176474-1565.jpg", imageAlt: "Takeshi Yamamoto"
},
{
id: "3", name: "Emma Richardson", handle: "London, UK", testimonial: "Worth every penny. The intimate setting, the masterful preparation, and the personalized attention made this unforgettable.", imageSrc: "https://img.b2bpic.net/free-photo/sushi-set-with-soybean-sauce_140725-4084.jpg", imageAlt: "Emma Richardson"
},
{
id: "4", name: "James Chen", handle: "Singapore", testimonial: "A true celebration of Japanese culinary art. Each course tells a story. Highly recommend for anyone seeking an authentic omakase experience.", imageSrc: "https://img.b2bpic.net/free-photo/view-people-learning-how-make-traditional-sushi-dish_23-2151186430.jpg", imageAlt: "James Chen"
},
{
id: "5", name: "Yuki Nakamura", handle: "Hokkaido, Japan", testimonial: "The chef's technique is flawless. Every ingredient is treated with the respect it deserves. This is true omakase.", imageSrc: "https://img.b2bpic.net/free-photo/lifestyle-people-learning-make-sushi_23-2149865319.jpg", imageAlt: "Yuki Nakamura"
},
{
id: "6", name: "Alexandra Petrov", handle: "Moscow, Russia", testimonial: "An extraordinary dining experience in a stunning mountain setting. The combination of culinary excellence and ambiance is perfect.", imageSrc: "https://img.b2bpic.net/free-photo/side-view-man-cutting-eggplant-into-slices-cutting-board-with-knife-white-table_176474-1565.jpg", imageAlt: "Alexandra Petrov"
}
]}
animationType="slide-up"
textboxLayout="default"
useInvertedBackground="noInvert"
speed={40}
topMarqueeDirection="left"
className="w-full"
titleClassName="text-white text-4xl md:text-5xl font-extrabold"
descriptionClassName="text-gray-300 text-base md:text-lg"
cardClassName="bg-red-950/20 border border-red-900/50 rounded-lg p-6"
testimonialClassName="text-gray-100 text-sm line-clamp-2"
nameClassName="text-white font-bold text-sm"
handleClassName="text-red-400 text-xs"
/>
</div>
<div id="contact" data-section="contact">
<ContactSplitForm
title="Reserve Your Experience"
description="Book your intimate omakase journey. Our team will contact you to confirm your reservation and discuss any dietary preferences or special occasions."
inputs={[
{ name: "name", type: "text", placeholder: "Your Name", required: true },
{ name: "email", type: "email", placeholder: "Email Address", required: true },
{ name: "phone", type: "tel", placeholder: "Phone Number", required: true },
{ name: "date", type: "date", placeholder: "Preferred Date", required: true }
]}
textarea={{
name: "message", placeholder: "Dietary preferences, special occasions, or questions...", rows: 5,
required: false
}}
useInvertedBackground="noInvert"
imageSrc="https://img.b2bpic.net/free-photo/empty-wood-chair_1339-6716.jpg"
imageAlt="Restaurant ambiance and setting"
mediaPosition="right"
buttonText="Confirm Reservation"
className="w-full"
titleClassName="text-white text-4xl md:text-5xl font-extrabold"
descriptionClassName="text-gray-300 text-base md:text-lg mb-8"
buttonClassName="bg-red-600 hover:bg-red-700 text-white font-bold w-full py-3 rounded-lg transition-all duration-300"
/>
</div>
<div id="footer" data-section="footer">
<FooterBaseReveal
columns={[
{
title: "Experience", items: [
{ label: "The Omakase", href: "#experience" },
{ label: "Our Philosophy", href: "#about" },
{ label: "Reservations", href: "#contact" }
]
},
{
title: "Location", items: [
{ label: "Niseko, Hokkaido", href: "#" },
{ label: "Hours: 5:00 PM - 11:00 PM", href: "#" },
{ label: "Closed Mondays", href: "#" }
]
},
{
title: "Connect", items: [
{ label: "Instagram", href: "https://instagram.com" },
{ label: "Contact", href: "#contact" },
{ label: "Inquiries", href: "mailto:info@omakaseniseko.com" }
]
}
]}
copyrightText="© 2025 Omakase Niseko. All rights reserved."
className="w-full"
columnTitleClassName="text-white font-extrabold text-lg mb-4"
columnItemClassName="text-gray-400 hover:text-red-400 transition-colors text-sm mb-2"
/>
</div>
</ThemeProvider>
);
}

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

@@ -0,0 +1,231 @@
"use client";
import { use, useCallback } from "react";
import { useRouter } from "next/navigation";
import ReactLenis from "lenis/react";
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
import NavbarLayoutFloatingInline from '@/components/navbar/NavbarLayoutFloatingInline';
import FooterBaseReveal from '@/components/sections/footer/FooterBaseReveal';
import ProductDetailCard from "@/components/ecommerce/productDetail/ProductDetailCard";
import ProductCart from "@/components/ecommerce/cart/ProductCart";
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="shift-hover"
defaultTextAnimation="background-highlight"
borderRadius="sharp"
contentWidth="smallMedium"
sizing="mediumLargeSizeLargeTitles"
background="circleGradient"
cardStyle="gradient-mesh"
primaryButtonStyle="primary-glow"
secondaryButtonStyle="radial-glow"
headingFontWeight="extrabold"
>
<ReactLenis root>
<div id="navbar" data-section="navbar">
<NavbarLayoutFloatingInline
brandName="Omakase Niseko"
navItems={[
{"name":"Home","id":"/"},
{"name":"Shop","id":"/shop"}
]}
button={{ text: "Cart", onClick: () => setCartOpen(true) }}
className="backdrop-blur-md bg-black/40 border border-red-900/30"
navItemClassName="text-white hover:text-red-400 transition-colors"
buttonClassName="bg-red-600 hover:bg-red-700 text-white"
buttonTextClassName="font-bold"
/>
</div>
<main className="min-h-screen flex items-center justify-center pt-20">
<p className="text-foreground">Loading product...</p>
</main>
</ReactLenis>
</ThemeProvider>
);
}
if (!product) {
return (
<ThemeProvider
defaultButtonVariant="shift-hover"
defaultTextAnimation="background-highlight"
borderRadius="sharp"
contentWidth="smallMedium"
sizing="mediumLargeSizeLargeTitles"
background="circleGradient"
cardStyle="gradient-mesh"
primaryButtonStyle="primary-glow"
secondaryButtonStyle="radial-glow"
headingFontWeight="extrabold"
>
<ReactLenis root>
<div id="navbar" data-section="navbar">
<NavbarLayoutFloatingInline
brandName="Omakase Niseko"
navItems={[
{"name":"Home","id":"/"},
{"name":"Shop","id":"/shop"}
]}
button={{ text: "Cart", onClick: () => setCartOpen(true) }}
className="backdrop-blur-md bg-black/40 border border-red-900/30"
navItemClassName="text-white hover:text-red-400 transition-colors"
buttonClassName="bg-red-600 hover:bg-red-700 text-white"
buttonTextClassName="font-bold"
/>
</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>
</ReactLenis>
</ThemeProvider>
);
}
return (
<ThemeProvider
defaultButtonVariant="shift-hover"
defaultTextAnimation="background-highlight"
borderRadius="sharp"
contentWidth="smallMedium"
sizing="mediumLargeSizeLargeTitles"
background="circleGradient"
cardStyle="gradient-mesh"
primaryButtonStyle="primary-glow"
secondaryButtonStyle="radial-glow"
headingFontWeight="extrabold"
>
<ReactLenis root>
<div id="navbar" data-section="navbar">
<NavbarLayoutFloatingInline
brandName="Omakase Niseko"
navItems={[
{"name":"Home","id":"/"},
{"name":"Shop","id":"/shop"}
]}
button={{ text: "Cart", onClick: () => setCartOpen(true) }}
className="backdrop-blur-md bg-black/40 border border-red-900/30"
navItemClassName="text-white hover:text-red-400 transition-colors"
buttonClassName="bg-red-600 hover:bg-red-700 text-white"
buttonTextClassName="font-bold"
/>
</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">
<FooterBaseReveal
columns={[
{"title":"Experience","items":[{"label":"The Omakase","href":"#experience"},{"label":"Our Philosophy","href":"#about"},{"label":"Reservations","href":"#contact"}]},
{"title":"Location","items":[{"label":"Niseko, Hokkaido","href":"#"},{"label":"Hours: 5:00 PM - 11:00 PM","href":"#"},{"label":"Closed Mondays","href":"#"}]},
{"title":"Connect","items":[{"label":"Instagram","href":"https://instagram.com"},{"label":"Contact","href":"#contact"},{"label":"Inquiries","href":"mailto:info@omakaseniseko.com"}]}
]}
copyrightText="© 2025 Omakase Niseko. All rights reserved."
className="w-full"
columnTitleClassName="text-white font-extrabold text-lg mb-4"
columnItemClassName="text-gray-400 hover:text-red-400 transition-colors text-sm mb-2"
/>
</div>
</ReactLenis>
</ThemeProvider>
);
}

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

@@ -0,0 +1,114 @@
"use client";
import ReactLenis from "lenis/react";
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
import NavbarLayoutFloatingInline from '@/components/navbar/NavbarLayoutFloatingInline';
import FooterBaseReveal from '@/components/sections/footer/FooterBaseReveal';
import ProductCatalog from "@/components/ecommerce/productCatalog/ProductCatalog";
import { useProductCatalog } from "@/hooks/useProductCatalog";
import { useState } from "react";
export default function ShopPage() {
const {
products,
isLoading,
search,
setSearch,
filters,
} = useProductCatalog({ basePath: "/shop" });
const [cartOpen, setCartOpen] = useState(false);
if (isLoading) {
return (
<ThemeProvider
defaultButtonVariant="shift-hover"
defaultTextAnimation="background-highlight"
borderRadius="sharp"
contentWidth="smallMedium"
sizing="mediumLargeSizeLargeTitles"
background="circleGradient"
cardStyle="gradient-mesh"
primaryButtonStyle="primary-glow"
secondaryButtonStyle="radial-glow"
headingFontWeight="extrabold"
>
<ReactLenis root>
<div id="navbar" data-section="navbar">
<NavbarLayoutFloatingInline
brandName="Omakase Niseko"
navItems={[
{"name":"Home","id":"/"},
{"name":"Shop","id":"/shop"}
]}
button={{ text: "Cart", onClick: () => setCartOpen(true) }}
className="backdrop-blur-md bg-black/40 border border-red-900/30"
navItemClassName="text-white hover:text-red-400 transition-colors"
buttonClassName="bg-red-600 hover:bg-red-700 text-white"
buttonTextClassName="font-bold"
/>
</div>
<main className="min-h-screen flex items-center justify-center pt-20">
<p className="text-foreground">Loading products...</p>
</main>
</ReactLenis>
</ThemeProvider>
);
}
return (
<ThemeProvider
defaultButtonVariant="shift-hover"
defaultTextAnimation="background-highlight"
borderRadius="sharp"
contentWidth="smallMedium"
sizing="mediumLargeSizeLargeTitles"
background="circleGradient"
cardStyle="gradient-mesh"
primaryButtonStyle="primary-glow"
secondaryButtonStyle="radial-glow"
headingFontWeight="extrabold"
>
<ReactLenis root>
<div id="navbar" data-section="navbar">
<NavbarLayoutFloatingInline
brandName="Omakase Niseko"
navItems={[
{"name":"Home","id":"/"},
{"name":"Shop","id":"/shop"}
]}
button={{ text: "Cart", onClick: () => setCartOpen(true) }}
className="backdrop-blur-md bg-black/40 border border-red-900/30"
navItemClassName="text-white hover:text-red-400 transition-colors"
buttonClassName="bg-red-600 hover:bg-red-700 text-white"
buttonTextClassName="font-bold"
/>
</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="footer" data-section="footer">
<FooterBaseReveal
columns={[
{"title":"Experience","items":[{"label":"The Omakase","href":"#experience"},{"label":"Our Philosophy","href":"#about"},{"label":"Reservations","href":"#contact"}]},
{"title":"Location","items":[{"label":"Niseko, Hokkaido","href":"#"},{"label":"Hours: 5:00 PM - 11:00 PM","href":"#"},{"label":"Closed Mondays","href":"#"}]},
{"title":"Connect","items":[{"label":"Instagram","href":"https://instagram.com"},{"label":"Contact","href":"#contact"},{"label":"Inquiries","href":"mailto:info@omakaseniseko.com"}]}
]}
copyrightText="© 2025 Omakase Niseko. All rights reserved."
className="w-full"
columnTitleClassName="text-white font-extrabold text-lg mb-4"
columnItemClassName="text-gray-400 hover:text-red-400 transition-colors text-sm mb-2"
/>
</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-mulish), sans-serif;
position: relative;
min-height: 100vh;
overscroll-behavior: none;
overscroll-behavior-y: none;
}
h1,
h2,
h3,
h4,
h5,
h6 {
font-family: var(--font-mulish), 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: #0a0a0a;;
--card: #1a1a1a;;
--foreground: #ffffff;;
--primary-cta: #e63946;;
--secondary-cta: #1a1a1a;;
--accent: #ff6b6b;;
--background-accent: #c92a2a;; */
--background: #0a0a0a;;
--card: #1a1a1a;;
--foreground: #ffffff;;
--primary-cta: #e63946;;
--secondary-cta: #1a1a1a;;
--accent: #ff6b6b;;
--background-accent: #c92a2a;;
/* 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;
}
}