Initial commit

This commit is contained in:
dk
2026-01-30 18:19:18 +02:00
commit b9a03d8d7b
297 changed files with 57763 additions and 0 deletions

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

@@ -0,0 +1,186 @@
"use client";
import { useEffect, useState } from "react";
import ReactLenis from "lenis/react";
import BlogCardTwo from '@/components/sections/blog/BlogCardTwo';
import FooterBase from '@/components/sections/footer/FooterBase';
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
import type { FooterColumn } from "@/components/shared/FooterColumns";
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: ["Design", "UX"],
title: "Cozy Living: Design Tips for Your Home", excerpt: "Transform your space into a cozy sanctuary with these essential design tips and blanket styling ideas.", imageSrc: "/placeholders/placeholder3.avif", imageAlt: "Cozy living room with blankets", authorName: "Sarah Williams", authorAvatar: "/placeholders/placeholder3.avif", date: "20 Jan 2025", onBlogClick: () => console.log("Blog 1 clicked"),
},
{
id: "2", category: "Home Decor", title: "Seasonal Comfort: Choosing the Right Blanket", excerpt: "Discover how to select the perfect blanket for every season and create year-round comfort in your home.", imageSrc: "/placeholders/placeholder4.webp", imageAlt: "Seasonal blanket collection", authorName: "Emily Chen", authorAvatar: "/placeholders/placeholder4.webp", date: "18 Jan 2025", onBlogClick: () => console.log("Blog 2 clicked"),
},
{
id: "3", category: ["Lifestyle", "Wellness"],
title: "The Science of Comfort: Why Blankets Matter", excerpt: "Explore the psychology and science behind why blankets make us feel secure and comfortable.", imageSrc: "/placeholders/placeholder3.avif", imageAlt: "Person wrapped in blanket", authorName: "Dr. Michael Johnson", authorAvatar: "/placeholders/placeholder3.avif", date: "15 Jan 2025", onBlogClick: () => console.log("Blog 3 clicked"),
},
{
id: "4", category: "Care Tips", title: "Blanket Care 101: Keeping Your Comfort Fresh", excerpt: "Learn the best practices for washing, storing, and maintaining your favorite blankets to ensure they last.", imageSrc: "/placeholders/placeholder4.webp", imageAlt: "Clean folded blankets", authorName: "Lisa Rodriguez", authorAvatar: "/placeholders/placeholder4.webp", date: "12 Jan 2025", onBlogClick: () => console.log("Blog 4 clicked"),
},
];
const footerColumns: FooterColumn[] = [
{
title: "Shop", items: [
{ label: "All Products", href: "products" },
{ label: "Best Sellers", href: "products" },
{ label: "New Arrivals", href: "products" },
],
},
{
title: "Company", items: [
{ label: "About Us", href: "about" },
{ label: "Contact", href: "contact" },
{ label: "Blog", href: "#" },
],
},
{
title: "Support", items: [
{ label: "FAQ", href: "faq" },
{ label: "Shipping Info", href: "#" },
{ label: "Returns", href: "#" },
],
},
];
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="shift-hover"
defaultTextAnimation="reveal-blur"
borderRadius="pill"
contentWidth="smallMedium"
sizing="large"
background="floatingGradient"
cardStyle="gradient-radial"
primaryButtonStyle="primary-glow"
secondaryButtonStyle="glass"
headingFontWeight="bold"
>
<ReactLenis root>
<div className="min-h-screen bg-background">
<NavbarLayoutFloatingOverlay
brandName="Cozy Blankets"
navItems={[
{"name":"Home","id":"/home"},
{"name":"Products","id":"products"},
{"name":"About","id":"about"},
{"name":"Features","id":"features"},
{"name":"Reviews","id":"testimonials"},
{"name":"FAQ","id":"faq"}
]}
button={{"text":"Shop Now","href":"products"}}
/>
{isLoading ? (
<div className="w-content-width mx-auto py-20 text-center">
<p className="text-foreground">Loading posts...</p>
</div>
) : (
<BlogCardTwo
blogs={posts}
title="Comfort & Style Blog"
description="Discover tips, insights, and stories about creating the perfect cozy environment with our premium blankets"
textboxLayout="default"
useInvertedBackground="noInvert"
animationType="slide-up"
carouselMode="buttons"
/>
)}
<FooterBase
logoText="Cozy Blankets"
copyrightText="© 2025 Cozy Blankets. All rights reserved."
columns={[
{
"title":"Shop", "items":[
{"label":"All Products","href":"products"},
{"label":"Best Sellers","href":"products"},
{"label":"New Arrivals","href":"products"}
]
},
{
"title":"Company", "items":[
{"label":"About Us","href":"about"},
{"label":"Contact","href":"contact"},
{"label":"Blog","href":"#"}
]
},
{
"title":"Support", "items":[
{"label":"FAQ","href":"faq"},
{"label":"Shipping Info","href":"#"},
{"label":"Returns","href":"#"}
]
}
]}
/>
</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: #fbfaff;;
--card: #f7f5ff;;
--foreground: #0f0022;;
--primary-cta: #8b5cf6;;
--secondary-cta: #ffffff;;
--accent: #d8cef5;;
--background-accent: #c4a8f9;; */
--background: #fbfaff;;
--card: #f7f5ff;;
--foreground: #0f0022;;
--primary-cta: #8b5cf6;;
--secondary-cta: #ffffff;;
--accent: #d8cef5;;
--background-accent: #c4a8f9;;
/* 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-outfit), sans-serif;
position: relative;
min-height: 100vh;
overscroll-behavior: none;
overscroll-behavior-y: none;
}
h1,
h2,
h3,
h4,
h5,
h6 {
font-family: var(--font-outfit), sans-serif;
}

1265
src/app/layout.tsx Normal file

File diff suppressed because it is too large Load Diff

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

@@ -0,0 +1,248 @@
"use client"
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
import NavbarLayoutFloatingOverlay from '@/components/navbar/NavbarLayoutFloatingOverlay/NavbarLayoutFloatingOverlay';
import HeroLogo from '@/components/sections/hero/HeroLogo';
import ProductCardTwo from '@/components/sections/product/ProductCardTwo';
import TextSplitAbout from '@/components/sections/about/TextSplitAbout';
import FeatureCardTwelve from '@/components/sections/feature/FeatureCardTwelve';
import TestimonialCardTwelve from '@/components/sections/testimonial/TestimonialCardTwelve';
import FaqSplitMedia from '@/components/sections/faq/FaqSplitMedia';
import ContactSplit from '@/components/sections/contact/ContactSplit';
import FooterBase from '@/components/sections/footer/FooterBase';
import { Sparkles, Heart } from "lucide-react";
export default function LandingPage() {
return (
<ThemeProvider
defaultButtonVariant="shift-hover"
defaultTextAnimation="reveal-blur"
borderRadius="pill"
contentWidth="smallMedium"
sizing="large"
background="floatingGradient"
cardStyle="gradient-radial"
primaryButtonStyle="primary-glow"
secondaryButtonStyle="glass"
headingFontWeight="bold"
>
<div id="nav" data-section="nav">
<NavbarLayoutFloatingOverlay
brandName="Cozy Blankets"
navItems={[
{ name: "Products", id: "products" },
{ name: "About", id: "about" },
{ name: "Features", id: "features" },
{ name: "Reviews", id: "testimonials" },
{ name: "FAQ", id: "faq" }
]}
button={{
text: "Shop Now", href: "products"
}}
/>
</div>
<div id="hero" data-section="hero">
<HeroLogo
logoText="Cozy Blankets"
description="Premium comfort for every home. Experience the ultimate softness and warmth with our curated collection of quality blankets."
buttons={[
{ text: "Shop Collection", href: "products" },
{ text: "Learn More", href: "about" }
]}
imageSrc="https://img.b2bpic.net/free-photo/close-up-person-near-heater_23-2149284101.jpg"
imageAlt="Cozy blanket draped over a comfortable bed"
showDimOverlay={true}
logoLineHeight={1.2}
/>
</div>
<div id="products" data-section="products">
<ProductCardTwo
title="Featured Blankets"
description="Discover our bestselling blankets trusted by thousands of satisfied customers"
tag="Best Sellers"
tagIcon={Sparkles}
textboxLayout="default"
useInvertedBackground="invertDefault"
gridVariant="three-columns-all-equal-width"
animationType="slide-up"
products={[
{
id: "1", brand: "Cozy Luxe", name: "Premium Fleece Blanket", price: "$49.99", rating: 5,
reviewCount: "2.3k", imageSrc: "https://img.b2bpic.net/free-photo/medium-shot-smiley-woman-with-tea-cup_23-2149172493.jpg", imageAlt: "Premium fleece blanket in soft purple"
},
{
id: "2", brand: "Cozy Luxe", name: "Merino Wool Throw", price: "$79.99", rating: 5,
reviewCount: "1.8k", imageSrc: "https://img.b2bpic.net/free-photo/woman-drinking-tea_23-2148832346.jpg", imageAlt: "Merino wool throw blanket"
},
{
id: "3", brand: "Cozy Luxe", name: "Organic Cotton Bedding", price: "$69.99", rating: 5,
reviewCount: "2.1k", imageSrc: "https://img.b2bpic.net/free-photo/full-shot-woman-holding-device_23-2149160989.jpg", imageAlt: "Organic cotton blanket"
},
{
id: "4", brand: "Cozy Luxe", name: "Weighted Sleep Blanket", price: "$129.99", rating: 5,
reviewCount: "3.5k", imageSrc: "https://img.b2bpic.net/free-photo/portrait-blonde-woman-pointing-bed_114579-57128.jpg", imageAlt: "Weighted blanket for better sleep"
},
{
id: "5", brand: "Cozy Luxe", name: "Decorative Throw Blanket", price: "$39.99", rating: 5,
reviewCount: "1.5k", imageSrc: "https://img.b2bpic.net/free-photo/look-from-woman-lying-colorful-plaids-with-cup-latte_1304-3358.jpg", imageAlt: "Decorative throw blanket for sofa"
},
{
id: "6", brand: "Cozy Luxe", name: "Microfiber Comfort Wrap", price: "$44.99", rating: 5,
reviewCount: "2.7k", imageSrc: "https://img.b2bpic.net/free-photo/medium-shot-smiley-woman-with-tea-cup_23-2149172493.jpg", imageAlt: "Microfiber comfort wrap blanket"
}
]}
/>
</div>
<div id="about" data-section="about">
<TextSplitAbout
title="About Cozy Blankets"
description={[
"We believe everyone deserves to experience the comfort of premium quality blankets. With over a decade of experience in textile sourcing, we partner directly with the finest manufacturers worldwide to bring you exceptional comfort at competitive prices.", "Our mission is simple: deliver the coziest, most durable blankets to homes everywhere. Every product is carefully selected and tested to ensure it meets our high standards for softness, warmth, and longevity. Your comfort is our priority."
]}
useInvertedBackground="noInvert"
showBorder={true}
buttons={[
{ text: "View All Products", href: "products" }
]}
/>
</div>
<div id="features" data-section="features">
<FeatureCardTwelve
title="Why Choose Our Blankets"
description="Discover what makes our blankets the preferred choice for comfort seekers"
textboxLayout="default"
useInvertedBackground="invertDefault"
features={[
{
id: "premium", label: "Premium", title: "Sourced from finest manufacturers worldwide", items: [
"100% ethically sourced materials", "Rigorous quality control standards", "Sustainable production practices"
]
},
{
id: "comfort", label: "Comfort", title: "Designed for ultimate relaxation", items: [
"Ultra-soft textures", "Temperature regulating fabrics", "Hypoallergenic materials"
]
},
{
id: "durable", label: "Durable", title: "Built to last for years", items: [
"Heavy-duty stitching", "Fade-resistant colors", "Easy care and maintenance"
]
}
]}
animationType="opacity"
/>
</div>
<div id="testimonials" data-section="testimonials">
<TestimonialCardTwelve
cardTitle="Trusted by over 50,000 happy customers worldwide"
cardTag="See what our customers say"
cardTagIcon={Heart}
useInvertedBackground="noInvert"
testimonials={[
{
id: "1", name: "Sarah Johnson", imageSrc: "https://img.b2bpic.net/free-photo/portrait-young-woman_23-2148574874.jpg", imageAlt: "Sarah Johnson"
},
{
id: "2", name: "Michael Chen", imageSrc: "https://img.b2bpic.net/free-photo/caucasion-woman-casual-confident-concept_53876-137678.jpg", imageAlt: "Michael Chen"
},
{
id: "3", name: "Emma Davis", imageSrc: "https://img.b2bpic.net/free-photo/positive-blond-girl-shows-tongue-winks-camera-makes-happy-funny-face-stands-against-white-background_176420-46979.jpg", imageAlt: "Emma Davis"
},
{
id: "4", name: "James Wilson", imageSrc: "https://img.b2bpic.net/free-photo/close-up-attractive-african-american-woman-smiling-looking-happy-standing-yellow-background_1258-54850.jpg", imageAlt: "James Wilson"
},
{
id: "5", name: "Lisa Martinez", imageSrc: "https://img.b2bpic.net/free-photo/young-woman-smiling_176474-95672.jpg", imageAlt: "Lisa Martinez"
},
{
id: "6", name: "David Thompson", imageSrc: "https://img.b2bpic.net/free-photo/outdoors-portrait-smiley-woman_23-2148486217.jpg", imageAlt: "David Thompson"
}
]}
/>
</div>
<div id="faq" data-section="faq">
<FaqSplitMedia
title="Frequently Asked Questions"
description="Everything you need to know about our blankets and services"
textboxLayout="default"
useInvertedBackground="invertDefault"
faqs={[
{
id: "1", title: "What materials are your blankets made from?", content: "Our blankets are crafted from premium materials including organic cotton, merino wool, polyester fleece, and microfiber. Each material is selected for its comfort, durability, and breathability. We provide detailed product descriptions so you can choose the perfect blanket for your needs."
},
{
id: "2", title: "Are your blankets hypoallergenic?", content: "Yes, many of our blanket options are hypoallergenic, particularly our organic cotton and wool collections. All materials are thoroughly tested for allergens. Check individual product pages for specific hypoallergenic certifications."
},
{
id: "3", title: "How should I care for my blanket?", content: "Most of our blankets are machine washable in cold water with mild detergent. We recommend tumble drying on low heat. Detailed care instructions are included with every order. Proper care will extend the life of your blanket significantly."
},
{
id: "4", title: "What is your return policy?", content: "We offer a 30-day money-back guarantee on all purchases. If you're not completely satisfied with your blanket, simply return it for a full refund. We want you to be completely happy with your Cozy Blankets purchase."
},
{
id: "5", title: "How quickly will my order arrive?", content: "We offer fast shipping with most orders arriving within 5-7 business days. We also provide express shipping options for faster delivery. All orders include tracking information so you can monitor your package."
},
{
id: "6", title: "Do you offer wholesale or bulk orders?", content: "Yes! We offer competitive wholesale pricing for bulk orders. Contact our sales team at wholesale@cozyblankets.com for special quotes and partnership opportunities."
}
]}
imageSrc="https://img.b2bpic.net/free-photo/cup-tea-cookies_23-2148832311.jpg"
imageAlt="Cozy home setting with comfort blankets"
mediaPosition="left"
animationType="smooth"
/>
</div>
<div id="contact" data-section="contact">
<ContactSplit
tag="Newsletter"
title="Stay Cozy and Updated"
description="Subscribe to our newsletter for exclusive deals, new product launches, and comfort tips delivered to your inbox."
useInvertedBackground="noInvert"
imageSrc="https://img.b2bpic.net/free-photo/croissant-wooden-box-front-loving-young-couple-lying-bed_23-2147966415.jpg"
imageAlt="Newsletter signup illustration"
mediaPosition="right"
inputPlaceholder="Your email address"
buttonText="Subscribe"
termsText="We respect your privacy. You can unsubscribe anytime."
/>
</div>
<div id="footer" data-section="footer">
<FooterBase
logoText="Cozy Blankets"
copyrightText="© 2025 Cozy Blankets. All rights reserved."
columns={[
{
title: "Shop", items: [
{ label: "All Products", href: "products" },
{ label: "Best Sellers", href: "products" },
{ label: "New Arrivals", href: "products" }
]
},
{
title: "Company", items: [
{ label: "About Us", href: "about" },
{ label: "Contact", href: "contact" },
{ label: "Blog", href: "#" }
]
},
{
title: "Support", items: [
{ label: "FAQ", href: "faq" },
{ label: "Shipping Info", href: "#" },
{ label: "Returns", href: "#" }
]
}
]}
/>
</div>
</ThemeProvider>
);
}