Initial commit

This commit is contained in:
Nikolay Pecheniev
2026-01-29 18:30:13 +02:00
commit 98062cc122
296 changed files with 57281 additions and 0 deletions

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

@@ -0,0 +1,169 @@
"use client";
import { useEffect, useState } from "react";
import ReactLenis from "lenis/react";
import BlogCardTwo from '@/components/sections/blog/BlogCardTwo';
import FooterBaseCard from '@/components/sections/footer/FooterBaseCard';
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
import NavbarLayoutFloatingOverlay from '@/components/navbar/NavbarLayoutFloatingOverlay/NavbarLayoutFloatingOverlay';
type BlogPost = {
id: string;
category: string | string[];
title: string;
excerpt: string;
imageSrc: string;
imageAlt?: string;
authorName: string;
authorAvatar?: string;
date: string;
onBlogClick?: () => void;
};
const defaultPosts: BlogPost[] = [
{
id: "1", category: ["Coffee", "Brewing"],
title: "The Art of Coffee Brewing", excerpt: "Discover the perfect brewing techniques to extract the best flavors from your coffee beans.", imageSrc: "/placeholders/placeholder3.avif", imageAlt: "Coffee brewing process", authorName: "Maria Santos", authorAvatar: "/placeholders/placeholder3.avif", date: "20 Jan 2025", onBlogClick: () => console.log("Blog 1 clicked"),
},
{
id: "2", category: "Sustainability", title: "Sustainable Coffee Practices", excerpt: "Learn how we source our beans ethically and support coffee farming communities worldwide.", imageSrc: "/placeholders/placeholder4.webp", imageAlt: "Coffee farm sustainability", authorName: "James Rodriguez", authorAvatar: "/placeholders/placeholder4.webp", date: "18 Jan 2025", onBlogClick: () => console.log("Blog 2 clicked"),
},
{
id: "3", category: ["Recipes", "Barista"],
title: "Signature Latte Recipes", excerpt: "Master the craft of creating perfect lattes with our signature recipes and techniques.", imageSrc: "/placeholders/placeholder3.avif", imageAlt: "Latte art creation", authorName: "Sophie Chen", authorAvatar: "/placeholders/placeholder3.avif", date: "15 Jan 2025", onBlogClick: () => console.log("Blog 3 clicked"),
},
{
id: "4", category: "Culture", title: "Coffee Culture Around the World", excerpt: "Explore the rich traditions and unique coffee cultures from different countries and regions.", imageSrc: "/placeholders/placeholder4.webp", imageAlt: "Global coffee culture", authorName: "Alex Thompson", authorAvatar: "/placeholders/placeholder4.webp", date: "12 Jan 2025", onBlogClick: () => console.log("Blog 4 clicked"),
},
];
export default function BlogPage() {
const [posts, setPosts] = useState<BlogPost[]>(defaultPosts);
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
const fetchPosts = async () => {
try {
const apiUrl = process.env.NEXT_PUBLIC_API_URL;
const projectId = process.env.NEXT_PUBLIC_PROJECT_ID;
if (!apiUrl || !projectId) {
console.warn("NEXT_PUBLIC_API_URL or NEXT_PUBLIC_PROJECT_ID not configured, using default posts");
setIsLoading(false);
return;
}
const url = `${apiUrl}/posts/${projectId}?status=published`;
const response = await fetch(url, {
method: "GET", headers: {
"Content-Type": "application/json"},
});
if (response.ok) {
const resp = await response.json();
const data = resp.data;
if (Array.isArray(data) && data.length > 0) {
const mappedPosts = data.map((post: any) => ({
id: post.id || String(Math.random()),
category: post.category || "General", title: post.title || "Untitled", excerpt: post.excerpt || post.content.slice(0, 30) || "", imageSrc: post.imageUrl || "/placeholders/placeholder3.avif", imageAlt: post.imageAlt || post.title || "", authorName: post.author?.name || "Anonymous", authorAvatar: post.author?.avatar || "/placeholders/placeholder3.avif", date: post.date || post.createdAt || new Date().toLocaleDateString("en-GB", { day: "numeric", month: "short", year: "numeric" }),
onBlogClick: () => console.log(`Blog ${post.id} clicked`),
}));
setPosts(mappedPosts);
}
} else {
console.warn(`API request failed with status ${response.status}, using default posts`);
}
} catch (error) {
console.error("Error fetching posts:", error);
} finally {
setIsLoading(false);
}
};
fetchPosts();
}, []);
return (
<ThemeProvider
defaultButtonVariant="hover-bubble"
defaultTextAnimation="entrance-slide"
borderRadius="rounded"
contentWidth="smallMedium"
sizing="largeSmallSizeLargeTitles"
background="floatingGradient"
cardStyle="solid"
primaryButtonStyle="gradient"
secondaryButtonStyle="layered"
headingFontWeight="light"
>
<ReactLenis root>
<div className="min-h-screen bg-background">
<NavbarLayoutFloatingOverlay
brandName="Morn Ing"
navItems={[
{ name: "Home", id: "/" },
{ name: "About", id: "about" },
{ name: "Menu", id: "products" },
{ name: "Testimonials", id: "testimonials" },
{ name: "Contact", id: "contact" }
]}
button={{ text: "Order Now", href: "#contact" }}
/>
{isLoading ? (
<div className="w-content-width mx-auto py-20 text-center">
<p className="text-foreground">Loading posts...</p>
</div>
) : (
<BlogCardTwo
blogs={posts}
title="Coffee Chronicles"
description="Discover the world of coffee through our expert insights, brewing guides, and stories from our passionate team."
tag="Blog"
textboxLayout="default"
useInvertedBackground="noInvert"
carouselMode="buttons"
animationType="slide-up"
/>
)}
<FooterBaseCard
logoText="Morn Ing"
columns={[
{
title: "Company", items: [
{ label: "About Us", href: "#about" },
{ label: "Our Story", href: "#about" },
{ label: "Sustainability", href: "#" }
]
},
{
title: "Menu", items: [
{ label: "Coffee Drinks", href: "#products" },
{ label: "Pastries", href: "#" },
{ label: "Beans & Gear", href: "#" }
]
},
{
title: "Connect", items: [
{ label: "Contact", href: "#contact" },
{ label: "Instagram", href: "https://instagram.com" },
{ label: "Events", href: "#" }
]
},
{
title: "Visit", items: [
{ label: "123 Coffee Street, Downtown", href: "#" },
{ label: "hello@morning-coffee.com", href: "mailto:hello@morning-coffee.com" },
{ label: "(555) COFFEE-1", href: "tel:+15556633335" }
]
}
]}
copyrightText="© 2025 Morn Ing Coffee Shop. All rights reserved."
onPrivacyClick={null}
/>
</div>
</ReactLenis>
</ThemeProvider>
);
}

BIN
src/app/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

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

@@ -0,0 +1,595 @@
@import "tailwindcss";
:root {
/* Base units */
/* --vw is set by ThemeProvider */
/* --background: #f5f5f5;;
--card: #ffffff;;
--foreground: #1c1c1c;;
--primary-cta: #1f3251;;
--secondary-cta: #ffffff;;
--accent: #15479c;;
--background-accent: #a8cce8;; */
--background: #f5f5f5;;
--card: #ffffff;;
--foreground: #1c1c1c;;
--primary-cta: #1f3251;;
--secondary-cta: #ffffff;;
--accent: #15479c;;
--background-accent: #a8cce8;;
/* 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;
}
}
@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);
}
@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-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;
}
}
}
* {
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-roboto), sans-serif;
position: relative;
min-height: 100vh;
overscroll-behavior: none;
overscroll-behavior-y: none;
}
h1,
h2,
h3,
h4,
h5,
h6 {
font-family: var(--font-roboto), sans-serif;
}

1266
src/app/layout.tsx Normal file

File diff suppressed because it is too large Load Diff

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

@@ -0,0 +1,211 @@
"use client"
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
import NavbarLayoutFloatingOverlay from '@/components/navbar/NavbarLayoutFloatingOverlay/NavbarLayoutFloatingOverlay';
import HeroOverlay from '@/components/sections/hero/HeroOverlay';
import TextSplitAbout from '@/components/sections/about/TextSplitAbout';
import ProductCardThree from '@/components/sections/product/ProductCardThree';
import MetricCardFourteen from '@/components/sections/metrics/MetricCardFourteen';
import TestimonialCardTen from '@/components/sections/testimonial/TestimonialCardTen';
import ContactFaq from '@/components/sections/contact/ContactFaq';
import FooterBaseCard from '@/components/sections/footer/FooterBaseCard';
import { Coffee, MessageCircle } from "lucide-react";
export default function LandingPage() {
return (
<ThemeProvider
defaultButtonVariant="hover-bubble"
defaultTextAnimation="entrance-slide"
borderRadius="rounded"
contentWidth="smallMedium"
sizing="largeSmallSizeLargeTitles"
background="floatingGradient"
cardStyle="solid"
primaryButtonStyle="gradient"
secondaryButtonStyle="layered"
headingFontWeight="light"
>
<div id="nav" data-section="nav">
<NavbarLayoutFloatingOverlay
brandName="Morn Ing"
navItems={[
{ name: "Home", id: "hero" },
{ name: "About", id: "about" },
{ name: "Menu", id: "products" },
{ name: "Testimonials", id: "testimonials" },
{ name: "Contact", id: "contact" }
]}
button={{ text: "Order Now", href: "#contact" }}
/>
</div>
<div id="hero" data-section="hero">
<HeroOverlay
title="Awaken Your Senses at Morn Ing"
description="Premium specialty coffee crafted with passion. Experience the perfect cup every morning."
tag="Artisan Coffee Since 2015"
tagIcon={Coffee}
imageSrc="https://img.b2bpic.net/free-photo/parisian-coffee-shop-style-with-tasty-coffee-served-wooden-table-coffee-shop-design_482257-18283.jpg"
imageAlt="Cozy coffee shop interior with warm lighting"
textPosition="bottom-left"
showBlur={true}
showDimOverlay={true}
buttons={[
{ text: "Explore Menu", href: "#products" },
{ text: "Visit Us", href: "#contact" }
]}
/>
</div>
<div id="about" data-section="about">
<TextSplitAbout
title="Our Story"
description={[
"At Morn Ing, we believe that every cup of coffee tells a story. Since 2015, we've been dedicated to sourcing the finest beans from sustainable farms around the world, roasting them to perfection in small batches to preserve their unique character and flavor profiles.", "Our baristas are passionate experts who treat coffee-making as an art form. Whether you're looking for your daily caffeine fix or a moment of quiet reflection, Morn Ing is your sanctuary. We're committed to creating a welcoming community space where connections are made, conversations flow, and exceptional coffee brings people together."
]}
showBorder={true}
useInvertedBackground="noInvert"
buttons={[
{ text: "Learn More", href: "#testimonials" }
]}
/>
</div>
<div id="products" data-section="products">
<ProductCardThree
title="Our Signature Menu"
description="Discover our carefully curated selection of premium coffee beverages"
products={[
{
id: "1", name: "Artisan Espresso", price: "$4.50", imageSrc: "https://img.b2bpic.net/free-photo/yellow-cup-with-beverage-near-coffee-beans_23-2148180237.jpg", imageAlt: "Double shot of perfect espresso", initialQuantity: 1
},
{
id: "2", name: "Signature Cappuccino", price: "$5.50", imageSrc: "https://img.b2bpic.net/free-photo/man-enjoying-cup-hot-coffee-cafe_53876-88441.jpg", imageAlt: "Cappuccino with beautiful latte art", initialQuantity: 1
},
{
id: "3", name: "Cold Brew Deluxe", price: "$6.00", imageSrc: "https://img.b2bpic.net/free-photo/top-view-cup-coffee-half-empty-inside-black-cup-brown-wooden-table-drink-coffee-liquid_140725-27964.jpg", imageAlt: "Refreshing cold brew over ice", initialQuantity: 1
}
]}
gridVariant="three-columns-all-equal-width"
animationType="slide-up"
textboxLayout="default"
useInvertedBackground="noInvert"
/>
</div>
<div id="metrics" data-section="metrics">
<MetricCardFourteen
title="Morn Ing by the numbers: celebrating our commitment to excellence and community impact."
tag="Why Choose Us"
metrics={[
{
id: "1", value: "50K+", description: "Happy customers served annually, each one part of our coffee community"
},
{
id: "2", value: "15+", description: "Specialty coffee origins sourced from ethical, sustainable farms worldwide"
},
{
id: "3", value: "99%", description: "Customer satisfaction rate reflecting our dedication to quality and service"
},
{
id: "4", value: "8", description: "Expert baristas trained in the art of coffee perfection and customer care"
}
]}
useInvertedBackground="noInvert"
/>
</div>
<div id="testimonials" data-section="testimonials">
<TestimonialCardTen
title="What Our Coffee Lovers Say"
description="Real stories from our community of passionate coffee enthusiasts"
testimonials={[
{
id: "1", title: "My Daily Ritual", quote: "Morn Ing has become an essential part of my morning routine. The quality is unmatched, and the atmosphere makes me feel right at home. I've tried many coffee shops, but this one truly stands out.", name: "Sarah Mitchell", role: "Marketing Manager", imageSrc: "https://img.b2bpic.net/free-photo/close-up-portrait-young-handsome-successful-man_1163-5475.jpg", imageAlt: "Sarah Mitchell"
},
{
id: "2", title: "Exceptional Craft", quote: "The baristas here understand coffee like artists understand their medium. Every drink is crafted with precision and care. I recommend Morn Ing to everyone I know.", name: "James Chen", role: "Coffee Enthusiast", imageSrc: "https://img.b2bpic.net/free-photo/happy-businessman-smiling-camera_1163-4660.jpg", imageAlt: "James Chen"
},
{
id: "3", title: "A Community Hub", quote: "What started as a quick coffee stop became my favorite meeting place. The welcoming staff and cozy ambiance make it perfect for both work and catching up with friends.", name: "Emma Rodriguez", role: "Freelance Designer", imageSrc: "https://img.b2bpic.net/free-photo/portrait-smiley-business-woman_23-2148603029.jpg", imageAlt: "Emma Rodriguez"
},
{
id: "4", title: "Worth Every Penny", quote: "I was skeptical about the premium pricing at first, but after my first visit, I understood completely. The sourcing, roasting, and preparation justify every cent. Now I'm a regular!", name: "David Park", role: "Software Developer", imageSrc: "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", imageAlt: "David Park"
}
]}
textboxLayout="default"
useInvertedBackground="noInvert"
/>
</div>
<div id="contact" data-section="contact">
<ContactFaq
ctaTitle="Get In Touch"
ctaDescription="Have questions about our coffee or want to visit us? Reach out anytime. We'd love to hear from you!"
ctaButton={{ text: "Send a Message", href: "mailto:hello@morning-coffee.com" }}
ctaIcon={MessageCircle}
faqs={[
{
id: "1", title: "What are your operating hours?", content: "Monday - Friday: 6:00 AM - 8:00 PM<br/>Saturday: 7:00 AM - 9:00 PM<br/>Sunday: 8:00 AM - 6:00 PM<br/>We're closed on major holidays."
},
{
id: "2", title: "Do you offer online ordering?", content: "Yes! You can order ahead through our website or mobile app for convenient pickup. Orders placed before 15 minutes of our closing time are guaranteed for the next day."
},
{
id: "3", title: "Are your beans ethically sourced?", content: "Absolutely. We work exclusively with certified fair-trade and sustainable farms. Each bag includes detailed information about the origin and the farmers who grew your coffee."
},
{
id: "4", title: "Do you have a loyalty program?", content: "Yes! Join our Morn Ing Rewards program and earn points on every purchase. Every 10 purchases, you get a free coffee. Sign up at the counter or through our app!"
},
{
id: "5", title: "Can I host private events?", content: "We offer our space for small private events, team meetings, and special occasions. Contact us at events@morning-coffee.com for custom packages and availability."
},
{
id: "6", title: "What payment methods do you accept?", content: "We accept all major credit cards, debit cards, digital wallets (Apple Pay, Google Pay), and cash. We also offer gift cards for the perfect present!"
}
]}
useInvertedBackground="noInvert"
animationType="slide-up"
accordionAnimationType="smooth"
/>
</div>
<div id="footer" data-section="footer">
<FooterBaseCard
logoText="Morn Ing"
columns={[
{
title: "Company", items: [
{ label: "About Us", href: "#about" },
{ label: "Our Story", href: "#about" },
{ label: "Sustainability", href: "#" }
]
},
{
title: "Menu", items: [
{ label: "Coffee Drinks", href: "#products" },
{ label: "Pastries", href: "#" },
{ label: "Beans & Gear", href: "#" }
]
},
{
title: "Connect", items: [
{ label: "Contact", href: "#contact" },
{ label: "Instagram", href: "https://instagram.com" },
{ label: "Events", href: "#" }
]
},
{
title: "Visit", items: [
{ label: "123 Coffee Street, Downtown", href: "#" },
{ label: "hello@morning-coffee.com", href: "mailto:hello@morning-coffee.com" },
{ label: "(555) COFFEE-1", href: "tel:+15556633335" }
]
}
]}
copyrightText="© 2025 Morn Ing Coffee Shop. All rights reserved."
/>
</div>
</ThemeProvider>
);
}