18 Commits

Author SHA1 Message Date
3725ad3848 Merge version_9_1778243332321 into main
Merge version_9_1778243332321 into main
2026-05-08 12:29:03 +00:00
d675c9ecb9 Update src/pages/HomePage.tsx 2026-05-08 12:28:59 +00:00
2df8393f10 Merge version_8_1778243296769 into main
Merge version_8_1778243296769 into main
2026-05-08 12:28:31 +00:00
ef145c3109 Update src/pages/HomePage.tsx 2026-05-08 12:28:25 +00:00
82036cbaa9 Update src/components/ui/ImageOrVideo.tsx 2026-05-08 12:28:23 +00:00
eaf279df67 Update src/components/sections/hero/HeroBillboardTestimonial.tsx 2026-05-08 12:28:20 +00:00
540b38bb6a Merge version_7_1778243142143 into main
Merge version_7_1778243142143 into main
2026-05-08 12:25:51 +00:00
e5ddb4d853 Update src/pages/HomePage.tsx 2026-05-08 12:25:48 +00:00
9921470c2f Merge version_6_1778242615138 into main
Merge version_6_1778242615138 into main
2026-05-08 12:17:05 +00:00
93b2154327 Update src/pages/HomePage.tsx 2026-05-08 12:17:02 +00:00
1b69b8f5cc Merge version_5_1778242555728 into main
Merge version_5_1778242555728 into main
2026-05-08 12:16:06 +00:00
641e6f56f6 Update src/pages/HomePage.tsx 2026-05-08 12:16:02 +00:00
b4d66af090 Merge version_4_1778242064540 into main
Merge version_4_1778242064540 into main
2026-05-08 12:07:57 +00:00
27e4490b23 Update src/pages/HomePage.tsx 2026-05-08 12:07:50 +00:00
f1efb7cebe Merge version_3_1778236059408 into main
Merge version_3_1778236059408 into main
2026-05-08 10:27:52 +00:00
a9f142cad6 Update src/pages/HomePage.tsx 2026-05-08 10:27:46 +00:00
2a73a486c1 Merge version_2_1778231058337 into main
Merge version_2_1778231058337 into main
2026-05-08 09:07:56 +00:00
kudinDmitriyUp
007e0f8bb6 feat: update color theme and branding 2026-05-08 09:07:33 +00:00
5 changed files with 18 additions and 183 deletions

View File

@@ -1,7 +1,7 @@
import FooterSimpleCard from '@/components/sections/footer/FooterSimpleCard'; import FooterSimpleCard from '@/components/sections/footer/FooterSimpleCard';
import NavbarFloating from '@/components/ui/NavbarFloating'; import NavbarFloating from '@/components/ui/NavbarFloating';
import SiteBackgroundSlot from "@/components/ui/SiteBackgroundSlot"; import SiteBackgroundSlot from "@/components/ui/SiteBackgroundSlot";
import { Outlet } from 'react-router-dom'; import HomePage from '@/pages/HomePage';
import { StyleProvider } from "@/components/ui/StyleProvider"; import { StyleProvider } from "@/components/ui/StyleProvider";
export default function Layout() { export default function Layout() {
@@ -47,7 +47,7 @@ export default function Layout() {
}} }}
navItems={navItems} /> navItems={navItems} />
<main className="flex-grow"> <main className="flex-grow">
<Outlet /> <HomePage />
</main> </main>
<FooterSimpleCard <FooterSimpleCard
brand="The Grand Hotel" brand="The Grand Hotel"

View File

@@ -1,124 +0,0 @@
import { useEffect, useState } from "react";
import { Star } from "lucide-react";
import { motion, AnimatePresence } from "motion/react";
import { cls } from "@/lib/utils";
import Button from "@/components/ui/Button";
import HeroBackgroundSlot from "@/components/ui/HeroBackgroundSlot";
import TextAnimation from "@/components/ui/TextAnimation";
import ImageOrVideo from "@/components/ui/ImageOrVideo";
import ScrollReveal from "@/components/ui/ScrollReveal";
type Testimonial = {
name: string;
handle: string;
text: string;
rating: number;
} & ({ imageSrc: string; videoSrc?: never } | { videoSrc: string; imageSrc?: never });
type HeroBillboardTestimonialProps = {
tag: string;
title: string;
description: string;
primaryButton: { text: string; href: string };
secondaryButton: { text: string; href: string };
testimonials: Testimonial[];
} & ({ imageSrc: string; videoSrc?: never } | { videoSrc: string; imageSrc?: never });
const INTERVAL = 5000;
const HeroBillboardTestimonial = ({
tag,
title,
description,
primaryButton,
secondaryButton,
imageSrc,
videoSrc,
testimonials,
}: HeroBillboardTestimonialProps) => {
const [currentIndex, setCurrentIndex] = useState(0);
useEffect(() => {
if (testimonials.length <= 1) return;
const interval = setInterval(() => {
setCurrentIndex((prev) => (prev + 1) % testimonials.length);
}, INTERVAL);
return () => clearInterval(interval);
}, [currentIndex, testimonials.length]);
const testimonial = testimonials[currentIndex];
return (
<section aria-label="Hero section" className="relative pt-25 pb-20 md:py-30 mb-20">
<HeroBackgroundSlot />
<div className="flex flex-col gap-10 w-content-width mx-auto">
<div className="flex flex-col items-center gap-2 text-center">
<span className="px-3 py-1 mb-1 text-sm card rounded">{tag}</span>
<TextAnimation
text={title}
variant="fade-blur"
gradientText={true}
tag="h1"
className="text-6xl font-medium text-balance"
/>
<TextAnimation
text={description}
variant="fade-blur"
gradientText={false}
tag="p"
className="text-base md:text-lg leading-tight text-balance"
/>
<div className="flex flex-wrap justify-center gap-3 mt-3">
<Button text={primaryButton.text} href={primaryButton.href} variant="primary"/>
<Button text={secondaryButton.text} href={secondaryButton.href} variant="secondary"animationDelay={0.1} />
</div>
</div>
<ScrollReveal variant="slide-up" delay={0.2} className="relative w-full p-3 xl:p-4 2xl:p-5 card rounded overflow-hidden">
<ImageOrVideo imageSrc={imageSrc} videoSrc={videoSrc} className="aspect-3/4 md:aspect-video" />
<AnimatePresence mode="wait">
<motion.div
key={currentIndex}
initial={{ opacity: 0, y: 10 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: -10 }}
transition={{ duration: 0.3 }}
className="absolute bottom-6 left-6 right-6 md:left-10 md:bottom-10 md:right-auto md:max-w-sm p-3 xl:p-4 2xl:p-5 card rounded flex flex-col gap-3 xl:gap-4 2xl:gap-5"
>
<div className="flex gap-1">
{Array.from({ length: 5 }).map((_, index) => (
<Star
key={index}
className={cls("size-5 text-accent", index < testimonial.rating ? "fill-accent" : "fill-transparent")}
strokeWidth={1.5}
/>
))}
</div>
<p className="text-lg leading-tight text-balance">{testimonial.text}</p>
<div className="flex items-center gap-3">
<ImageOrVideo
imageSrc={testimonial.imageSrc}
videoSrc={testimonial.videoSrc}
className="size-10 rounded-full object-cover"
/>
<div className="flex flex-col">
<span className="text-sm font-medium">{testimonial.name}</span>
<span className="text-sm text-foreground/60">{testimonial.handle}</span>
</div>
</div>
</motion.div>
</AnimatePresence>
</ScrollReveal>
</div>
</section>
);
};
export default HeroBillboardTestimonial;

View File

@@ -1,41 +0,0 @@
import { cls } from "@/lib/utils";
interface ImageOrVideoProps {
imageSrc?: string;
videoSrc?: string;
className?: string;
}
const ImageOrVideo = ({
imageSrc,
videoSrc,
className = "",
}: ImageOrVideoProps) => {
if (videoSrc) {
return (
<video
src={videoSrc}
aria-label={videoSrc}
className={cls("w-full h-full min-h-0 object-cover rounded", className)}
autoPlay
loop
muted
playsInline
/>
);
}
if (imageSrc) {
return (
<img
src={imageSrc}
alt={imageSrc}
className={cls("w-full h-full min-h-0 object-cover rounded", className)}
/>
);
}
return null;
};
export default ImageOrVideo;

View File

@@ -5,15 +5,15 @@
:root { :root {
/* @colorThemes/lightTheme/grayNavyBlue */ /* @colorThemes/lightTheme/grayNavyBlue */
--background: #0a0a0a; --background: #0D0D0D;
--card: #1a1a1a; --card: #1A1A1A;
--foreground: #f5f5f5; --foreground: #E5E5E5;
--primary-cta: #ffdf7d; --primary-cta: #D4AF37;
--primary-cta-text: #0a0a0a; --primary-cta-text: #0D0D0D;
--secondary-cta: #1a1a1a; --secondary-cta: #1A1A1A;
--secondary-cta-text: #ffffff; --secondary-cta-text: #E5E5E5;
--accent: #b8860b; --accent: #D4AF37;
--background-accent: #8b6914; --background-accent: #B8860B;
/* @layout/border-radius/rounded */ /* @layout/border-radius/rounded */
--radius: 1rem; --radius: 1rem;
@@ -159,14 +159,14 @@ h6 {
.card { .card {
/* WEBILD_CARD_STYLE */ /* WEBILD_CARD_STYLE */
/* @cards/gradient-radial */ /* @cards/gradient-radial */
background: radial-gradient(circle at center, color-mix(in srgb, var(--color-card) 100%, var(--color-accent) 20%) 0%, var(--color-card) 90%); background: radial-gradient(circle at center, color-mix(in srgb, var(--color-card) 90%, var(--color-accent) 2%) 0%, var(--color-card) 70%);
} }
.primary-button { .primary-button {
/* WEBILD_PRIMARY_BUTTON */ /* WEBILD_PRIMARY_BUTTON */
/* @primaryButtons/diagonal-gradient */ /* @primaryButtons/diagonal-gradient */
background: linear-gradient(to bottom right, color-mix(in srgb, var(--color-primary-cta) 80%, transparent), var(--color-foreground)); background: var(--color-primary-cta);
box-shadow: 2.10837px 3.16256px 9.48767px color-mix(in srgb, var(--color-accent) 30%, transparent); box-shadow: 2.10837px 3.16256px 9.48767px color-mix(in srgb, var(--color-accent) 10%, transparent);
} }
.secondary-button { .secondary-button {

View File

@@ -13,15 +13,15 @@ export default function HomePage() {
<div id="hero" data-section="hero"> <div id="hero" data-section="hero">
<HeroSplit <HeroSplit
tag="Welcome to Unforgettable Stays" tag="Welcome to Unforgettable Stays"
title="Experience Unrivaled Luxury at The Grand Hotel" title="kkkkkkkkkkkk"
description="Nestled in the heart of the city, The Grand Hotel offers an exquisite blend of classic elegance and modern comfort. Discover a sanctuary where every detail is crafted for your perfect stay." description="Nestled in the heart of the cikkkk"
primaryButton={{ primaryButton={{
text: "Explore Rooms", text: "Explore Rooms",
href: "#products", href: "#products",
}} }}
secondaryButton={{ secondaryButton={{
text: "Book Your Stay", text: "Book Your Staykjjkkkkk",
href: "#contact", href: "https://www.instagram.com/rainerahi/",
}} }}
imageSrc="http://img.b2bpic.net/free-photo/wooden-sauna-with-mountain-view-panoramic-calm_169016-70823.jpg" imageSrc="http://img.b2bpic.net/free-photo/wooden-sauna-with-mountain-view-panoramic-calm_169016-70823.jpg"
/> />