Initial commit

This commit is contained in:
vitalijmulika
2026-01-23 16:43:14 +02:00
commit 2b152966a7
297 changed files with 57770 additions and 0 deletions

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

@@ -0,0 +1,162 @@
"use client";
import { useEffect, useState } from "react";
import ReactLenis from "lenis/react";
import BlogCardThree from '@/components/sections/blog/BlogCardThree';
import FooterLogoEmphasis from '@/components/sections/footer/FooterLogoEmphasis';
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
import NavbarStyleMinimal from '@/components/navbar/NavbarStyleMinimal';
type BlogPost = {
id: string;
category: string;
title: string;
excerpt: string;
imageSrc: string;
imageAlt?: string;
authorName: string;
authorAvatar: string;
date: string;
onBlogClick?: () => void;
};
const defaultPosts: BlogPost[] = [
{
id: "1", category: "Design", title: "UX review presentations", excerpt: "How do you create compelling presentations that wow your colleagues and impress your managers?", imageSrc: "/placeholders/placeholder3.avif", imageAlt: "Abstract design with purple and silver tones", authorName: "Olivia Rhye", authorAvatar: "/placeholders/placeholder3.avif", date: "20 Jan 2025", onBlogClick: () => console.log("Blog 1 clicked"),
},
{
id: "2", category: "Development", title: "Building scalable applications", excerpt: "Learn the best practices for building applications that can handle millions of users.", imageSrc: "/placeholders/placeholder4.webp", imageAlt: "Development workspace", authorName: "John Smith", authorAvatar: "/placeholders/placeholder4.webp", date: "18 Jan 2025", onBlogClick: () => console.log("Blog 2 clicked"),
},
{
id: "3", category: "Marketing", title: "Content strategy essentials", excerpt: "Discover how to create a content strategy that drives engagement and conversions.", imageSrc: "/placeholders/placeholder3.avif", imageAlt: "Marketing strategy board", authorName: "Sarah Johnson", authorAvatar: "/placeholders/placeholder3.avif", date: "15 Jan 2025", onBlogClick: () => console.log("Blog 3 clicked"),
},
{
id: "4", category: "Product", title: "Product management 101", excerpt: "Everything you need to know to become an effective product manager in 2025.", imageSrc: "/placeholders/placeholder4.webp", imageAlt: "Product planning session", authorName: "Mike Davis", 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="text-shift"
defaultTextAnimation="reveal-blur"
borderRadius="pill"
contentWidth="medium"
sizing="largeSizeMediumTitles"
background="circleGradient"
cardStyle="gradient-radial"
primaryButtonStyle="double-inset"
secondaryButtonStyle="solid"
headingFontWeight="medium"
>
<ReactLenis root>
<div className="min-h-screen bg-background">
<NavbarStyleMinimal
brandName="PawsHaven"
button={{
text: "Adopt Today", href: "contact"
}}
navItems={[
{ name: "Home", id: "/" }
]}
/>
{isLoading ? (
<div className="w-content-width mx-auto py-20 text-center">
<p className="text-foreground">Loading posts...</p>
</div>
) : (
<BlogCardThree
blogs={posts}
title="Featured Stories"
description="Discover heartwarming tales of rescue, rehabilitation, and forever homes from PawsHaven"
textboxLayout="default"
useInvertedBackground="noInvert"
animationType="slide-up"
carouselMode="buttons"
tag="Blog"
/>
)}
<FooterLogoEmphasis
logoText="PawsHaven"
columns={[
{
items: [
{ label: "Adoptable Pets", href: "products" },
{ label: "Adoption Process", href: "features" },
{ label: "Success Stories", href: "testimonials" }
]
},
{
items: [
{ label: "About Us", href: "about" },
{ label: "Our Impact", href: "metrics" },
{ label: "Contact", href: "contact" }
]
},
{
items: [
{ label: "FAQ", href: "faq" },
{ label: "Volunteer", href: "contact" },
{ label: "Donate", href: "contact" }
]
},
{
items: [
{ label: "Privacy Policy", href: "https://example.com/privacy" },
{ label: "Terms of Service", href: "https://example.com/terms" }
]
}
]}
/>
</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: #1c1c1c;;
--secondary-cta: #ffffff;;
--accent: #15479c;;
--background-accent: #a8cce8;; */
--background: #f5f5f5;;
--card: #ffffff;;
--foreground: #1c1c1c;;
--primary-cta: #1c1c1c;;
--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-poppins), sans-serif;
position: relative;
min-height: 100vh;
overscroll-behavior: none;
overscroll-behavior-y: none;
}
h1,
h2,
h3,
h4,
h5,
h6 {
font-family: var(--font-poppins), sans-serif;
}

1263
src/app/layout.tsx Normal file

File diff suppressed because it is too large Load Diff

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

@@ -0,0 +1,281 @@
"use client"
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
import NavbarStyleMinimal from '@/components/navbar/NavbarStyleMinimal';
import HeroSplit from '@/components/sections/hero/HeroSplit';
import TextAbout from '@/components/sections/about/TextAbout';
import ProductCardTwo from '@/components/sections/product/ProductCardTwo';
import FeatureCardSeven from '@/components/sections/feature/FeatureCardSeven';
import TestimonialCardSix from '@/components/sections/testimonial/TestimonialCardSix';
import MetricCardThree from '@/components/sections/metrics/MetricCardThree';
import FaqSplitMedia from '@/components/sections/faq/FaqSplitMedia';
import ContactFaq from '@/components/sections/contact/ContactFaq';
import FooterLogoEmphasis from '@/components/sections/footer/FooterLogoEmphasis';
import { Heart, Sparkles, Zap, Star, TrendingUp, Users, Home, Award, HelpCircle, Phone } from "lucide-react";
export default function LandingPage() {
return (
<ThemeProvider
defaultButtonVariant="text-shift"
defaultTextAnimation="reveal-blur"
borderRadius="pill"
contentWidth="medium"
sizing="largeSizeMediumTitles"
background="circleGradient"
cardStyle="gradient-radial"
primaryButtonStyle="double-inset"
secondaryButtonStyle="solid"
headingFontWeight="medium"
>
<div id="nav" data-section="nav">
<NavbarStyleMinimal
brandName="PawsHaven"
button={{
text: "Adopt Today", href: "contact"
}}
/>
</div>
<div id="hero" data-section="hero">
<HeroSplit
title="Give a Pet a Loving Home"
description="Find your perfect companion and change a life. Browse adoptable dogs, cats, and other animals ready to join your family today."
tag="Open for Adoptions"
tagIcon={Heart}
background={{ variant: "glowing-orb" }}
imageSrc="https://img.b2bpic.net/free-photo/happy-boy-posing-park-with-dog-parents_23-2148647786.jpg"
imageAlt="Happy family with adopted pets"
imagePosition="right"
buttons={[
{ text: "Start Adoption", href: "contact" },
{ text: "Learn More", href: "about" }
]}
/>
</div>
<div id="about" data-section="about">
<TextAbout
title="At PawsHaven, we believe every animal deserves a loving home. Since 2015, we've rescued, rehabilitated, and rehomed over 5,000 pets. Our dedicated team works tirelessly to ensure every animal receives the care, attention, and love they need before finding their forever families."
useInvertedBackground="invertDefault"
buttons={[
{ text: "Meet Our Team", href: "contact" }
]}
/>
</div>
<div id="products" data-section="products">
<ProductCardTwo
title="Available for Adoption"
description="Meet the wonderful animals waiting for their forever homes. Each pet has been health-checked and is ready to brighten your life."
tag="Featured Pets"
tagIcon={Sparkles}
products={[
{
id: "1", brand: "Golden Hearts", name: "Max - Golden Retriever", price: "Adoption Fee: $150", rating: 5,
reviewCount: "47 loves", imageSrc: "https://img.b2bpic.net/free-photo/beautiful-shot-two-young-golden-retrievers_181624-27654.jpg", imageAlt: "Max, friendly golden retriever"
},
{
id: "2", brand: "Feline Friends", name: "Whiskers - Tabby Cat", price: "Adoption Fee: $75", rating: 5,
reviewCount: "32 loves", imageSrc: "https://img.b2bpic.net/free-photo/close-up-woman-posing-with-dog_23-2148928955.jpg", imageAlt: "Whiskers, playful tabby kitten"
},
{
id: "3", brand: "Puppy Pals", name: "Shadow - Lab Mix", price: "Adoption Fee: $125", rating: 5,
reviewCount: "28 loves", imageSrc: "https://img.b2bpic.net/free-photo/girl-with-two-irish-setters-home_1398-4891.jpg", imageAlt: "Shadow, energetic black puppy"
}
]
textboxLayout="default"
gridVariant="three-columns-all-equal-width"
animationType="slide-up"
useInvertedBackground="noInvert"
buttons={[
{ text: "Browse All Pets", href: "contact" }
]}
/>
</div>
<div id="features" data-section="features">
<FeatureCardSeven
title="Our Adoption Process"
description="We make adoption straightforward and transparent. Follow these simple steps to welcome your new family member home."
tag="Easy Steps"
tagIcon={Zap}
textboxLayout="default"
animationType="blur-reveal"
useInvertedBackground="invertDefault"
features={[
{
id: 1,
title: "Submit Application", description: "Tell us about your home, lifestyle, and what kind of pet you're looking for. Our team reviews applications within 24 hours.", imageSrc: "https://img.b2bpic.net/free-photo/young-happy-couple-signing-document-while-having-meeting-with-real-estate-agent-office-focus-is-man_637285-2814.jpg", imageAlt: "Application form for pet adoption"
},
{
id: 2,
title: "Meet Your Match", description: "Visit our shelter to meet potential pets. Spend time with them to ensure it's the perfect fit for your family.", imageSrc: "https://img.b2bpic.net/free-photo/smiling-couple-with-dog-talking-their-insurance-agent-meeting-office_637285-2832.jpg", imageAlt: "Family meeting their future pet"
},
{
id: 3,
title: "Complete the Process", description: "Finalize paperwork, pay the adoption fee, and receive care instructions. We provide ongoing support for life.", imageSrc: "https://img.b2bpic.net/free-photo/team-creative-business-colleagues-having-fun-while-giving-headphones-dog-office-focus-is-dog_637285-2006.jpg", imageAlt: "Happy family bringing pet home"
}
]}
/>
</div>
<div id="testimonials" data-section="testimonials">
<TestimonialCardSix
title="Adoption Success Stories"
description="Hear from families who found their perfect companions through PawsHaven"
tag="Real Stories"
tagIcon={Star}
textboxLayout="default"
animationType="slide-up"
useInvertedBackground="noInvert"
testimonials={[
{
id: "1", name: "Sarah Johnson", handle: "@sarahjohns", testimonial: "Adopting Max changed our lives. He's brought so much joy and love to our family. The team at PawsHaven made everything seamless!", imageSrc: "https://img.b2bpic.net/free-photo/man-woman-posing-together_23-2148618938.jpg", imageAlt: "Sarah Johnson"
},
{
id: "2", name: "Michael Chen", handle: "@mchen_pets", testimonial: "We weren't sure about adoption at first, but the staff was incredibly helpful. Whiskers is the sweetest addition to our home.", imageSrc: "https://img.b2bpic.net/free-photo/self-portrait-cheerful-modern-couple-love_1262-12888.jpg", imageAlt: "Michael Chen"
},
{
id: "3", name: "Emily Rodriguez", handle: "@emilyrodrig", testimonial: "The adoption process was so easy and transparent. Shadow is now part of our family, and we couldn't imagine life without him.", imageSrc: "https://img.b2bpic.net/free-photo/happy-couple-posing_23-2147644354.jpg", imageAlt: "Emily Rodriguez"
},
{
id: "4", name: "David & Lisa Williams", handle: "@williamspets", testimonial: "PawsHaven's commitment to animal welfare is evident in everything they do. Our new furry friend is healthy, happy, and loved.", imageSrc: "https://img.b2bpic.net/free-photo/portrait-smiling-beautiful-girl-her-handsome-boyfriend-woman-casual-summer-jeans-clothes_158538-5514.jpg", imageAlt: "David and Lisa Williams"
},
{
id: "5", name: "Jessica Martinez", handle: "@jmartinez_love", testimonial: "Incredible organization with incredible people. They genuinely care about matching the right pet with the right family.", imageSrc: "https://img.b2bpic.net/free-photo/man-woman-posing-together_23-2148618938.jpg", imageAlt: "Jessica Martinez"
},
{
id: "6", name: "Tom Anderson", handle: "@tander_dogs", testimonial: "Best decision we ever made. The support from PawsHaven didn't end after adoption - they're always there to help.", imageSrc: "https://img.b2bpic.net/free-photo/self-portrait-cheerful-modern-couple-love_1262-12888.jpg", imageAlt: "Tom Anderson"
}
]}
/>
</div>
<div id="metrics" data-section="metrics">
<MetricCardThree
title="Our Impact by Numbers"
description="See the difference we're making in animal welfare and community engagement"
tag="Impact Metrics"
tagIcon={TrendingUp}
textboxLayout="default"
animationType="scale-rotate"
useInvertedBackground="invertDefault"
metrics={[
{
id: "1", icon: Heart,
title: "Pets Adopted", value: "5,200+"
},
{
id: "2", icon: Home,
title: "Happy Homes", value: "98%"
},
{
id: "3", icon: Users,
title: "Community Members", value: "12,500+"
},
{
id: "4", icon: Award,
title: "Years of Service", value: "9"
}
]}
/>
</div>
<div id="faq" data-section="faq">
<FaqSplitMedia
title="Frequently Asked Questions"
description="Get answers to common questions about pet adoption and our services"
tag="Help & Support"
tagIcon={HelpCircle}
textboxLayout="default"
imageSrc="https://img.b2bpic.net/free-photo/beautiful-sad-woman-saying-goodbye-her-old-german-shepherd-professional-male-veterinarian-preparing-ready-put-down-sick-dog_662251-2307.jpg"
imageAlt="Pet care and adoption support"
mediaPosition="left"
faqs={[
{
id: "1", title: "What's the age range of available pets?", content: "We have pets of all ages, from young puppies and kittens to senior animals. Each pet's age and health information is listed on their profile."
},
{
id: "2", title: "What's included in the adoption fee?", content: "The adoption fee covers spaying/neutering, microchipping, initial vaccinations, health examination, and a one-month pet insurance trial. Our team can discuss any additional services."
},
{
id: "3", title: "Can I return a pet if it doesn't work out?", content: "Yes, we have a 30-day return policy. If adjustment issues arise, we work with you to resolve them or welcome the pet back. Your satisfaction and the pet's wellbeing are our priorities."
},
{
id: "4", title: "Do you provide post-adoption support?", content: "Absolutely. Our team provides ongoing support for the life of your pet. We're available for behavioral questions, health concerns, and training tips."
},
{
id: "5", title: "What if I'm renting? Can I still adopt?", content: "Yes, renters can adopt. During the application process, we ask for landlord approval documentation if required. We work with all responsible pet owners."
},
{
id: "6", title: "How can I volunteer or donate?", content: "We welcome volunteers and donations! You can contact our team directly, or visit our website for various volunteer opportunities and donation options that support our mission."
}
]
useInvertedBackground="noInvert"
/>
</div>
<div id="contact" data-section="contact">
<ContactFaq
ctaTitle="Ready to Adopt?"
ctaDescription="Start your adoption journey today. Our team is excited to help you find the perfect pet companion."
ctaButton={{
text: "Begin Application", href: "https://example.com/apply"
}}
ctaIcon={Heart}
faqs={[
{
id: "1", title: "How long does the adoption process take?", content: "Typically 3-7 days from application to adoption. We review applications within 24 hours and can arrange meetings quickly."
},
{
id: "2", title: "What documents do I need for adoption?", content: "Valid ID, proof of address, and veterinary references if you've owned pets before. We may request additional information based on your situation."
},
{
id: "3", title: "Do you offer payment plans for adoption fees?", content: "Yes, we offer flexible payment options. Please contact our team to discuss payment plans that work for your budget."
},
{
id: "4", title: "What if my chosen pet gets adopted before I finalize?", content: "We recommend applying quickly. Our staff can place a hold on pets for qualified applicants. Contact us for more details."
}
]
useInvertedBackground="invertDefault"
animationType="slide-up"
/>
</div>
<div id="footer" data-section="footer">
<FooterLogoEmphasis
logoText="PawsHaven"
columns={[
{
items: [
{ label: "Adoptable Pets", href: "products" },
{ label: "Adoption Process", href: "features" },
{ label: "Success Stories", href: "testimonials" }
]
},
{
items: [
{ label: "About Us", href: "about" },
{ label: "Our Impact", href: "metrics" },
{ label: "Contact", href: "contact" }
]
},
{
items: [
{ label: "FAQ", href: "faq" },
{ label: "Volunteer", href: "contact" },
{ label: "Donate", href: "contact" }
]
},
{
items: [
{ label: "Privacy Policy", href: "https://example.com/privacy" },
{ label: "Terms of Service", href: "https://example.com/terms" }
]
}
]}
/>
</div>
</ThemeProvider>
);
}