38 Commits

Author SHA1 Message Date
1ba2908279 Merge version_19_1781563648361 into main
Merge version_19_1781563648361 into main
2026-06-15 22:47:46 +00:00
040a7fd535 Update src/pages/HomePage/sections/Hero.tsx 2026-06-15 22:47:42 +00:00
15c6856558 Merge version_18_1781563623180 into main
Merge version_18_1781563623180 into main
2026-06-15 22:47:10 +00:00
9fb1e00c11 Update theme colors 2026-06-15 22:47:03 +00:00
e32e760e99 Merge version_17_1781563616874 into main
Merge version_17_1781563616874 into main
2026-06-15 22:47:00 +00:00
8b201cbe6c Update theme colors 2026-06-15 22:46:57 +00:00
283adff54f Merge version_16_1781519540042 into main
Merge version_16_1781519540042 into main
2026-06-15 10:53:42 +00:00
c49e96a7c3 Add analytics tracking script 2026-06-15 10:53:39 +00:00
8a3d08ed7f Merge version_16_1781519540042 into main
Merge version_16_1781519540042 into main
2026-06-15 10:34:36 +00:00
kudinDmitriyUp
4bd9d5f39b Bob AI: Populate src/pages/BlogPage.tsx (snippet builder, 2 sections) 2026-06-15 10:33:53 +00:00
kudinDmitriyUp
c4d2a0b52d Bob AI: Add blog page 2026-06-15 10:33:03 +00:00
21f2c691bb Merge version_15_1781419601769 into main
Merge version_15_1781419601769 into main
2026-06-15 10:29:46 +00:00
d4ad543155 Update src/components/Layout.tsx 2026-06-15 10:29:36 +00:00
061ef09376 Merge version_15_1781419601769 into main
Merge version_15_1781419601769 into main
2026-06-15 10:29:30 +00:00
558ac5ef57 Update src/App.tsx 2026-06-15 10:29:21 +00:00
8c930d8c2c Merge version_15_1781419601769 into main
Merge version_15_1781419601769 into main
2026-06-14 21:14:25 +00:00
51817f8b8a Add public/favicon.png 2026-06-14 21:14:13 +00:00
900e502413 Update index.html 2026-06-14 21:14:13 +00:00
0c0da7d82f Merge version_15_1781419601769 into main
Merge version_15_1781419601769 into main
2026-06-14 06:50:00 +00:00
kudinDmitriyUp
54ebac3115 Bob AI: Added a fourth carousel of testimonial cards to the testimon 2026-06-14 06:49:18 +00:00
354cdc7a53 Merge version_14_1781418721165 into main
Merge version_14_1781418721165 into main
2026-06-14 06:32:18 +00:00
9d36ba87f6 Update src/pages/HomePage/sections/Hero.tsx 2026-06-14 06:32:11 +00:00
79bc470c0f Merge version_13_1781412111677 into main
Merge version_13_1781412111677 into main
2026-06-14 04:44:21 +00:00
kudinDmitriyUp
006a6229a0 Bob AI: Revert accidental button addition on HomePage Projects secti 2026-06-14 04:43:25 +00:00
e851769a06 Merge version_12_1781411627540 into main
Merge version_12_1781411627540 into main
2026-06-14 04:40:52 +00:00
kudinDmitriyUp
c1e727a163 Bob AI: Add View Project buttons to portfolio cards 2026-06-14 04:40:05 +00:00
kudinDmitriyUp
1bc8f87a62 Bob AI: Remove buttons from home page projects section 2026-06-14 04:37:54 +00:00
9c5793758d Merge version_11_1781411395189 into main
Merge version_11_1781411395189 into main
2026-06-14 04:31:52 +00:00
kudinDmitriyUp
3e1a113d0d Bob AI: add buttons to portfolio cards and link penthouse project 2026-06-14 04:31:11 +00:00
43afe69979 Merge version_10_1781411138455 into main
Merge version_10_1781411138455 into main
2026-06-14 04:27:48 +00:00
kudinDmitriyUp
d1e35626bd Bob AI: Populate src/pages/BarrioDeSalamancaPenthousePage.tsx (snippet builder, 3 sections) 2026-06-14 04:27:13 +00:00
kudinDmitriyUp
c6e6f46f09 Bob AI: Add barrio-de-salamanca-penthouse page 2026-06-14 04:26:32 +00:00
448a58d8e7 Merge version_9_1781411001435 into main
Merge version_9_1781411001435 into main
2026-06-14 04:24:34 +00:00
kudinDmitriyUp
ae98bd05d7 Bob AI: Connect projects page to navigation bar 2026-06-14 04:23:54 +00:00
fc1ec4482f Merge version_8_1781410851390 into main
Merge version_8_1781410851390 into main
2026-06-14 04:22:47 +00:00
kudinDmitriyUp
cc81d23459 Bob AI: Populate src/pages/ProjectsPage.tsx (snippet builder, 2 sections) 2026-06-14 04:22:12 +00:00
kudinDmitriyUp
901829923e Bob AI: Add projects page 2026-06-14 04:21:34 +00:00
d7f653d26a Merge version_7_1781410560553 into main
Merge version_7_1781410560553 into main
2026-06-14 04:19:02 +00:00
12 changed files with 281 additions and 69 deletions

View File

@@ -5,7 +5,7 @@
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Geist:wght@100..900&family=Inter+Tight:ital,wght@0,100..900;1,100..900&family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&family=Playfair+Display:ital,wght@0,400..900;1,400..900&display=swap" rel="stylesheet">
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Studio Madrid | Luxury Interior Design</title>
<meta property="og:title" content="Studio Madrid | Luxury Interior Design" />
@@ -13,9 +13,13 @@
<meta name="description" content="Studio Madrid specializes in high-end interior design for luxury residences, flats, and villas throughout Madrid. Transform your home today." />
<meta property="og:description" content="Studio Madrid specializes in high-end interior design for luxury residences, flats, and villas throughout Madrid. Transform your home today." />
<meta name="twitter:description" content="Studio Madrid specializes in high-end interior design for luxury residences, flats, and villas throughout Madrid. Transform your home today." />
<meta property="og:image" content="https://storage.googleapis.com/webild/users/user_3AFDRpptPx4buwNV34xBpWy9jNG/uploaded-1781471648940-wopf0ep1.png" />
<meta name="twitter:image" content="https://storage.googleapis.com/webild/users/user_3AFDRpptPx4buwNV34xBpWy9jNG/uploaded-1781471648940-wopf0ep1.png" />
<link rel="icon" type="image/png" href="/favicon.png" />
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
<script defer src="https://analytics.webild.io/wb" data-website-id="118223fc-0bc0-49da-a4b4-fc8388d2274c" data-webild-analytics></script>
</body>
</html>

BIN
public/favicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 527 KiB

View File

@@ -2,11 +2,19 @@ import { Routes, Route } from 'react-router-dom';
import Layout from './components/Layout';
import HomePage from './pages/HomePage';
import BlogPage from './pages/blog/BlogPage';
import BlogPostPage from './pages/blog/BlogPostPage';
import ProjectsPage from "@/pages/ProjectsPage";
import BarrioDeSalamancaPenthousePage from "@/pages/BarrioDeSalamancaPenthousePage";
export default function App() {
return (
<Routes>
<Route element={<Layout />}>
<Route path="/" element={<HomePage />} />
<Route path="/projects" element={<ProjectsPage />} />
<Route path="/barrio-de-salamanca-penthouse" element={<BarrioDeSalamancaPenthousePage />} />
<Route path="/blog" element={<BlogPage />} />
<Route path="/blog/:slug" element={<BlogPostPage />} />
</Route>
</Routes>
);

View File

@@ -7,13 +7,16 @@ import { StyleProvider } from "@/components/ui/StyleProvider";
export default function Layout() {
const navItems = [
{ name: "About", href: "#about" },
{ name: "Projects", href: "#projects" },
{ name: "Contact", href: "#contact" },
{ name: "Hero", href: "#hero" },
{ name: "Features", href: "#features" },
{ name: "Metrics", href: "#metrics" },
{ name: "Testimonials", href: "#testimonials" }
{ name: "About", href: "/#about" },
{ name: "Projects", href: "/projects" },
{ name: "Features", href: "/#features" },
{ name: "Metrics", href: "/#metrics" },
{ name: "Testimonials", href: "/#testimonials" },
{ name: "Contact", href: "/#contact" },
{ name: "Barrio De Salamanca Penthouse", href: "/barrio-de-salamanca-penthouse" },
{ name: "Blog", href: "/blog" },
];
return (

View File

@@ -5,15 +5,15 @@
:root {
/* @colorThemes/lightTheme/grayNavyBlue */
--background: #f6f0e9;
--card: #efe7dd;
--foreground: #2b180a;
--primary-cta: #2b180a;
--primary-cta-text: #f6f0e9;
--secondary-cta: #efe7dd;
--secondary-cta-text: #2b180a;
--accent: #94877c;
--background-accent: #afa094;
--background: #f5faff;
--card: #ffffff;
--foreground: #001122;
--primary-cta: #15479c;
--primary-cta-text: #f5faff;
--secondary-cta: #ffffff;
--secondary-cta-text: #001122;
--accent: #a8cce8;
--background-accent: #7ba3cf;
/* @layout/border-radius/rounded */
--radius: 1rem;

View File

@@ -0,0 +1,25 @@
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";
import AvatarGroup from "@/components/ui/AvatarGroup";
import { cls } from "@/lib/utils";
export default function BarrioDeSalamancaPenthousePage() {
return (
<>
<div data-webild-section="HeroBillboard"><section aria-label="Hero section" className="relative pt-25 pb-20 md:pt-30"><HeroBackgroundSlot /><div className="flex flex-col gap-12 md:gap-15 w-content-width mx-auto"><div className="flex flex-col items-center gap-3 text-center"><div className="px-3 py-1 mb-1 text-sm card rounded w-fit"><p>Residential Portfolio</p></div><TextAnimation text="Barrio de Salamanca Penthouse" variant="fade-blur" gradientText={true} tag="h1" className="md:max-w-8/10 text-7xl 2xl:text-8xl leading-[1.15] font-semibold text-center text-balance" /><TextAnimation text="A bespoke sanctuary in the heart of Madrid. We transformed this penthouse into a sophisticated retreat, blending natural textures with abundant light to tell a unique personal story." variant="fade-blur" gradientText={false} tag="p" className="md:max-w-7/10 text-lg md:text-xl leading-snug text-balance" /><div className="flex flex-wrap justify-center gap-3 mt-2 md:mt-3"><Button text="Explore Project" href="#details" variant="primary" /><Button text="All Projects" href="/projects" variant="secondary" animationDelay={0.1} /></div></div><ScrollReveal variant="fade-blur" delay={0.2} className="w-full p-2 xl:p-3 2xl:p-4 card rounded overflow-hidden"><ImageOrVideo imageSrc="https://img.freepik.com/free-photo/3d-rendering-modern-dining-room-living-room-with-luxury-decor_105762-2216.jpg" className="aspect-4/5 md:aspect-video" /></ScrollReveal></div></section></div>
<div data-webild-section="AboutTextSplit"><section aria-label="About section" className="py-20"><div className="flex flex-col gap-20 mx-auto w-content-width"><div className="flex flex-col md:flex-row gap-3 md:gap-15"><div className="w-full md:w-1/2"><TextAnimation text="A Sanctuary Above Salamanca" variant="fade-blur" gradientText={true} tag="h2" className="text-7xl 2xl:text-8xl leading-[1.15] font-semibold text-balance" /></div><div className="flex flex-col gap-2 w-full md:w-1/2"><TextAnimation key={0} text="Perched high above Madrid's most exclusive district, this penthouse is a masterclass in understated luxury. We transformed a classic layout into a fluid, light-filled sanctuary." variant="fade-blur" gradientText={false} tag="p" className="text-xl md:text-2xl leading-snug text-balance" />
<TextAnimation key={1} text="Rich textures of natural stone and bespoke oak cabinetry anchor the space. Expansive windows invite the golden Spanish sun to dance across the minimalist forms." variant="fade-blur" gradientText={false} tag="p" className="text-xl md:text-2xl leading-snug text-balance" />
<TextAnimation key={2} text="Every detail was selected to reflect the client's refined taste, creating a personal narrative woven through bespoke design and timeless elegance." variant="fade-blur" gradientText={false} tag="p" className="text-xl md:text-2xl leading-snug text-balance" /><div className="flex flex-wrap gap-3 mt-2 md:mt-3"><Button text="Back to Projects" href="/projects" variant="primary" /><Button text="Inquire Now" href="/contact" variant="secondary" animationDelay={0.1} /></div></div></div><div className="w-full border-b border-foreground/5" /></div></section></div>
<div data-webild-section="FeaturesImageBento"><section aria-label="Features image bento section" className="py-20"><div className="flex flex-col gap-8 md:gap-10"><div className="flex flex-col items-center w-content-width mx-auto gap-2"><div className="px-3 py-1 mb-1 text-sm card rounded w-fit"><p>Featured Project</p></div><TextAnimation text="Barrio de Salamanca Penthouse" variant="fade-blur" gradientText={true} tag="h2" className="md:max-w-8/10 text-6xl 2xl:text-7xl leading-[1.15] font-semibold text-center text-balance" /><TextAnimation text="A masterclass in bespoke luxury, blending classic Madrid architecture with contemporary elegance and curated textures." variant="fade-blur" gradientText={false} tag="p" className="md:max-w-7/10 text-lg md:text-xl leading-snug text-center text-balance" /><div className="flex flex-wrap justify-center gap-3 mt-2 md:mt-3"><Button text="View Gallery" href="#gallery" variant="primary" /><Button text="All Projects" href="/projects" variant="secondary" animationDelay={0.1} /></div></div><div className="w-content-width mx-auto grid grid-cols-1 md:grid-cols-6 gap-3"><ScrollReveal key={0} variant="fade" delay={0} className="col-span-1 group md:col-span-2"><div className="overflow-hidden rounded"></div></ScrollReveal>
<ScrollReveal key={1} variant="fade" delay={0.1} className="col-span-1 group md:col-span-4"><div className="overflow-hidden rounded"></div></ScrollReveal>
<ScrollReveal key={2} variant="fade" delay={0} className="col-span-1 group md:col-span-3"><div className="overflow-hidden rounded"></div></ScrollReveal>
<ScrollReveal key={3} variant="fade" delay={0.1} className="col-span-1 group md:col-span-3"><div className="overflow-hidden rounded"></div></ScrollReveal>
<ScrollReveal key={4} variant="fade" delay={0} className="col-span-1 group md:col-span-2"><div className="overflow-hidden rounded"></div></ScrollReveal>
<ScrollReveal key={5} variant="fade" delay={0.1} className="col-span-1 group md:col-span-2"><div className="overflow-hidden rounded"></div></ScrollReveal>
<ScrollReveal key={6} variant="fade" delay={0.2} className="col-span-1 group md:col-span-2"><div className="overflow-hidden rounded"></div></ScrollReveal></div></div></section></div>
</>
);
}

19
src/pages/BlogPage.tsx Normal file
View File

@@ -0,0 +1,19 @@
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";
import AvatarGroup from "@/components/ui/AvatarGroup";
import { ArrowUpRight, Loader2 } from "lucide-react";
import GridOrCarousel from "@/components/ui/GridOrCarousel";
import { useButtonClick } from "@/hooks/useButtonClick";
import useBlogPosts from "@/hooks/useBlogPosts";
export default function BlogPage() {
return (
<>
<div data-webild-section="HeroBillboard"><section aria-label="Hero section" className="relative pt-25 pb-20 md:pt-30"><HeroBackgroundSlot /><div className="flex flex-col gap-12 md:gap-15 w-content-width mx-auto"><div className="flex flex-col items-center gap-3 text-center"><div className="px-3 py-1 mb-1 text-sm card rounded w-fit"><p>Design Journal</p></div><TextAnimation text="Stories of Space and Light" variant="fade-blur" gradientText={true} tag="h1" className="md:max-w-8/10 text-7xl 2xl:text-8xl leading-[1.15] font-semibold text-center text-balance" /><TextAnimation text="Explore our latest thoughts on bespoke interiors, architectural trends, and the art of curating spaces that reflect your personal essence." variant="fade-blur" gradientText={false} tag="p" className="md:max-w-7/10 text-lg md:text-xl leading-snug text-balance" /><div className="flex flex-wrap justify-center gap-3 mt-2 md:mt-3"><Button text="Read Latest" href="#latest" variant="primary" /><Button text="Explore Topics" href="#topics" variant="secondary" animationDelay={0.1} /></div></div><ScrollReveal variant="fade-blur" delay={0.2} className="w-full p-2 xl:p-3 2xl:p-4 card rounded overflow-hidden"><ImageOrVideo imageSrc="https://picsum.photos/seed/2089910226/1200/800" className="aspect-4/5 md:aspect-video" /></ScrollReveal></div></section></div>
<div data-webild-section="BlogMediaCards"><section aria-label="Blog section" className="py-20"><div className="w-content-width mx-auto flex justify-center"><Loader2 className="size-8 animate-spin text-foreground" strokeWidth={1.5} /></div></section></div>
</>
);
}

View File

@@ -36,7 +36,7 @@ export default function HeroSection(): React.JSX.Element {
"Bilbao",
"Malaga",
]}
imageSrc="http://img.b2bpic.net/free-photo/close-up-happy-healthy-young-woman-with-dark-curly-hair-lying-comfortable-sofa-terrace_197531-22796.jpg"
imageSrc="https://images.pexels.com/photos/28484958/pexels-photo-28484958.jpeg?auto=compress&cs=tinysrgb&h=650&w=940&id=28484958"
/>
</SectionErrorBoundary>
</div>

View File

@@ -1,57 +1,159 @@
// AUTO-GENERATED by per-section-migrate. Edit freely — Bob will treat this
// file as the canonical source for the "projects" section.
/* eslint-disable */
// @ts-nocheck — generated by catalog-eject; runtime-correct but TS strict-mode false-positives on inlined catalog body
import Button from "@/components/ui/Button";
import TextAnimation from "@/components/ui/TextAnimation";
import ImageOrVideo from "@/components/ui/ImageOrVideo";
import ScrollReveal from "@/components/ui/ScrollReveal";
import { cls } from "@/lib/utils";
import React from 'react';
import FeaturesImageBento from '@/components/sections/features/FeaturesImageBento';
import SectionErrorBoundary from "@/components/ui/SectionErrorBoundary";
const items = [
{
title: "Luxury Flat",
description: "Barrio de Salamanca penthouse",
imageSrc: "http://img.b2bpic.net/free-photo/woman-reading-book-reading-club-library_23-2150293528.jpg",
href: "/barrio-de-salamanca-penthouse"
},
{
title: "Urban Oasis",
description: "Modern terrace concept",
imageSrc: "http://img.b2bpic.net/free-photo/modern-spacious-room-with-large-panoramic-window_7502-7289.jpg"
},
{
title: "Boutique Villa",
description: "Contemporary architecture",
imageSrc: "http://img.b2bpic.net/free-photo/young-coworkers-gathering-table-office_23-2147668778.jpg"
},
{
title: "Townhouse Staging",
description: "Modern living transformation",
imageSrc: "http://img.b2bpic.net/free-photo/side-view-blurry-man-walking_23-2150378941.jpg"
},
{
title: "Minimalist Loft",
description: "Open plan urban living",
imageSrc: "http://img.b2bpic.net/free-photo/ai-generated-house-design_23-2150666254.jpg"
},
{
title: "Traditional Fusion",
description: "Renovating history",
imageSrc: "http://img.b2bpic.net/free-photo/bathroom-interior-background-white-spa-towels-wood_1258-111485.jpg"
},
{
title: "Private Residence",
description: "Custom luxury detail",
imageSrc: "http://img.b2bpic.net/free-photo/abstract-blur-furniture-shop-store-interior_74190-4976.jpg"
}
];
type FeatureItem = {
title: string;
description: string;
href?: string;
} & ({ imageSrc: string; videoSrc?: never } | { videoSrc: string; imageSrc?: never });
interface FeaturesImageBentoProps {
tag: string;
title: string;
description: string;
primaryButton?: { text: string; href: string };
secondaryButton?: { text: string; href: string };
items: [FeatureItem, FeatureItem, FeatureItem, FeatureItem, FeatureItem, FeatureItem, FeatureItem];
}
const ProjectsInline = () => {
const gridClasses = [
"md:col-span-2",
"md:col-span-4",
"md:col-span-3",
"md:col-span-3",
"md:col-span-2",
"md:col-span-2",
"md:col-span-2",
];
const staggerDelays = [
0,
0.1,
0,
0.1,
0,
0.1,
0.2,
];
export default function ProjectsSection(): React.JSX.Element {
return (
<div id="projects" data-section="projects">
<SectionErrorBoundary name="projects">
<FeaturesImageBento
tag="Featured Work"
title="Selected Projects in Madrid"
description="Discover our latest transformations across the city."
items={[
{
title: "Luxury Flat",
description: "Barrio de Salamanca renovation",
imageSrc: "http://img.b2bpic.net/free-photo/woman-reading-book-reading-club-library_23-2150293528.jpg",
},
{
title: "Urban Oasis",
description: "Modern terrace concept",
imageSrc: "http://img.b2bpic.net/free-photo/modern-spacious-room-with-large-panoramic-window_7502-7289.jpg",
},
{
title: "Boutique Villa",
description: "Contemporary architecture",
imageSrc: "http://img.b2bpic.net/free-photo/young-coworkers-gathering-table-office_23-2147668778.jpg",
},
{
title: "Townhouse Staging",
description: "Modern living transformation",
imageSrc: "http://img.b2bpic.net/free-photo/side-view-blurry-man-walking_23-2150378941.jpg",
},
{
title: "Minimalist Loft",
description: "Open plan urban living",
imageSrc: "http://img.b2bpic.net/free-photo/ai-generated-house-design_23-2150666254.jpg",
},
{
title: "Traditional Fusion",
description: "Renovating history",
imageSrc: "http://img.b2bpic.net/free-photo/bathroom-interior-background-white-spa-towels-wood_1258-111485.jpg",
},
{
title: "Private Residence",
description: "Custom luxury detail",
imageSrc: "http://img.b2bpic.net/free-photo/abstract-blur-furniture-shop-store-interior_74190-4976.jpg",
},
]}
/>
</SectionErrorBoundary>
<section aria-label="Features image bento section" className="py-20">
<div className="flex flex-col gap-8 md:gap-10">
<div className="flex flex-col items-center w-content-width mx-auto gap-2">
<div className="px-3 py-1 mb-1 text-sm card rounded w-fit">
<p>{"Featured Work"}</p>
</div>
<TextAnimation
text={"Selected Projects in Madrid"}
variant="fade-blur"
gradientText={true}
tag="h2"
className="md:max-w-8/10 text-6xl 2xl:text-7xl leading-[1.15] font-semibold text-center text-balance"
/>
<TextAnimation
text={"Discover our latest transformations across the city."}
variant="fade-blur"
gradientText={false}
tag="p"
className="md:max-w-7/10 text-lg md:text-xl leading-snug text-center text-balance"
/>
{(undefined || undefined) && (
<div className="flex flex-wrap justify-center gap-3 mt-2 md:mt-3">
{undefined && <Button text={undefined.text} href={undefined.href} variant="primary"/>}
{undefined && <Button text={undefined.text} href={undefined.href} variant="secondary" animationDelay={0.1} />}
</div>
)}
</div>
<div className="w-content-width mx-auto grid grid-cols-1 md:grid-cols-6 gap-3">
{items.map((item, index) => {
const content = (
<div className="relative h-80 xl:h-100 2xl:h-120 overflow-hidden">
<ImageOrVideo
imageSrc={item.imageSrc}
videoSrc={item.videoSrc}
className="rounded group-hover:scale-105 transition-transform duration-500"
/>
<div className="absolute inset-x-5 bottom-5 xl:inset-x-6 xl:bottom-6 2xl:inset-x-7 2xl:bottom-7 flex flex-col text-background">
<span className="text-2xl font-semibold leading-snug truncate">{item.title}</span>
<span className="text-base leading-snug truncate">{item.description}</span>
</div>
</div>
);
return (
<ScrollReveal key={index} variant="fade" delay={staggerDelays[index]} className={cls("col-span-1 group", gridClasses[index])}>
{item.href ? (
<a href={item.href} className="block overflow-hidden rounded">
{content}
</a>
) : (
<div className="overflow-hidden rounded">
{content}
</div>
)}
</ScrollReveal>
);
})}
</div>
</div>
</section>
);
};
export default function ProjectsSection() {
return (
<div data-webild-section="projects" id="projects">
<ProjectsInline />
</div>
);
}

View File

@@ -309,6 +309,36 @@ const TestimonialsInline = () => {
</div>
</div>
</ScrollReveal>
<ScrollReveal variant="fade-blur" delay={0.4}>
<div className="relative w-full overflow-hidden flex group mt-5">
<div className="flex animate-marquee group-hover:[animation-play-state:paused]">
{[...testimonials, ...testimonials].map((testimonial, index) => (
<div key={`fourth-${index}`} className="flex flex-col justify-between gap-4 xl:gap-5 2xl:gap-6 shrink-0 w-72 md:w-80 mr-5 p-6 xl:p-7 2xl:p-8 rounded card">
<p className="text-lg leading-snug line-clamp-3">{testimonial.quote}</p>
<div className="flex flex-col gap-4">
<div className="flex items-center gap-3">
<ImageOrVideo
imageSrc={testimonial.imageSrc}
videoSrc={testimonial.videoSrc}
className="size-10 md:size-11 2xl:size-12 rounded-full object-cover"
/>
<div className="flex flex-col min-w-0">
<div className="flex items-center gap-1">
<span className="text-base text-foreground font-semibold leading-snug truncate">{testimonial.name}</span>
<BadgeCheck className="size-4 text-blue-500 shrink-0" />
</div>
<span className="text-base text-foreground/75 leading-snug truncate">{testimonial.role}</span>
</div>
</div>
<Button text="Contact" variant="secondary" className="w-full py-2 text-sm" />
</div>
</div>
))}
</div>
</div>
</ScrollReveal>
</div>
</section>
);

View File

@@ -0,0 +1,18 @@
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";
import GridOrCarousel from "@/components/ui/GridOrCarousel";
export default function ProjectsPage() {
return (
<>
<div data-webild-section="HeroSplit"><section aria-label="Hero section" className="relative flex items-center h-fit md:h-svh pt-25 pb-20 md:py-0"><HeroBackgroundSlot /><div className="flex flex-col md:flex-row items-center gap-12 md:gap-20 w-content-width mx-auto"><div className="w-full md:w-1/2"><div className="flex flex-col items-center md:items-start gap-3"><div className="px-3 py-1 mb-1 text-sm card rounded w-fit"><p>Selected Works</p></div><TextAnimation text="Curated Madrid Interiors" variant="fade" gradientText={true} tag="h1" className="text-7xl 2xl:text-8xl leading-[1.15] font-semibold text-center md:text-left text-balance" /><TextAnimation text="Explore our portfolio of high-end residential and commercial projects. Each space is a testament to our dedication to texture, light, and personal storytelling." variant="fade" gradientText={false} tag="p" className="md:max-w-8/10 text-lg md:text-xl leading-snug text-center md:text-left text-balance" /><div className="flex flex-wrap max-md:justify-center gap-3 mt-2 md:mt-3"><Button text="View Catalogue" href="#catalogue" variant="primary" /><Button text="Discuss a Project" href="/contact" variant="secondary" animationDelay={0.1} /></div></div></div><ScrollReveal variant="fade-blur" delay={0.2} className="w-full md:w-1/2 h-100 md:h-[65vh] md:max-h-[75svh] p-2 xl:p-3 2xl:p-4 card rounded overflow-hidden"><ImageOrVideo imageSrc="https://img.freepik.com/free-photo/modern-luxury-living-room-interior-design_53876-128916.jpg" /></ScrollReveal></div></section></div>
<div data-webild-section="FeaturesMediaGrid"><section aria-label="Features section" className="py-20"><div className="flex flex-col gap-8 md:gap-10"><div className="flex flex-col items-center w-content-width mx-auto gap-2"><div className="px-3 py-1 mb-1 text-sm card rounded w-fit"><p>Portfolio</p></div><TextAnimation text="Curated Spaces" variant="slide-up" gradientText={true} tag="h2" className="md:max-w-8/10 text-6xl 2xl:text-7xl leading-[1.15] font-semibold text-center text-balance" /><TextAnimation text="Explore our collection of bespoke interiors and architectural transformations across Madrid. Each project is a unique narrative of light, texture, and form." variant="slide-up" gradientText={false} tag="p" className="md:max-w-7/10 text-lg md:text-xl leading-snug text-center text-balance" /><div className="flex flex-wrap justify-center gap-3 mt-2 md:mt-3"><Button text="Start Your Project" href="/contact" variant="primary" /><Button text="Our Process" href="/about" variant="secondary" animationDelay={0.1} /></div></div><ScrollReveal variant="slide-up"><GridOrCarousel><div key="Barrio de Salamanca Penthouse" className="flex flex-col gap-4 xl:gap-5 2xl:gap-6 h-full"><div className="aspect-square overflow-hidden"><ImageOrVideo imageSrc="https://picsum.photos/seed/2066822201/1200/800" className="rounded-none" /></div><div className="flex flex-col gap-1"><h3 className="text-3xl font-semibold leading-snug text-balance">Barrio de Salamanca Penthouse</h3><p className="text-base leading-snug text-balance">A sunlit sanctuary blending classic moldings with contemporary minimalism.</p></div></div>
<div key="Chamberí Townhouse" className="flex flex-col gap-4 xl:gap-5 2xl:gap-6 h-full"><div className="aspect-square overflow-hidden"><ImageOrVideo imageSrc="https://img.freepik.com/free-photo/3d-rendering-modern-dining-room-living-room-with-luxury-decor_105762-2009.jpg" className="rounded-none" /></div><div className="flex flex-col gap-1"><h3 className="text-3xl font-semibold leading-snug text-balance">Chamberí Townhouse</h3><p className="text-base leading-snug text-balance">Restoring historical elegance while introducing fluid, modern living spaces.</p></div></div>
<div key="Retiro Park Loft" className="flex flex-col gap-4 xl:gap-5 2xl:gap-6 h-full"><div className="aspect-square overflow-hidden"><ImageOrVideo imageSrc="https://img.freepik.com/free-photo/interior-design-with-photoframes-couch_23-2149385435.jpg" className="rounded-none" /></div><div className="flex flex-col gap-1"><h3 className="text-3xl font-semibold leading-snug text-balance">Retiro Park Loft</h3><p className="text-base leading-snug text-balance">An open-concept haven featuring raw textures and panoramic park views.</p></div></div>
<div key="Justicia Studio" className="flex flex-col gap-4 xl:gap-5 2xl:gap-6 h-full"><div className="aspect-square overflow-hidden"><ImageOrVideo imageSrc="https://img.freepik.com/free-photo/minimalist-living-room-interior-design_23-2150794655.jpg" className="rounded-none" /></div><div className="flex flex-col gap-1"><h3 className="text-3xl font-semibold leading-snug text-balance">Justicia Studio</h3><p className="text-base leading-snug text-balance">Maximizing natural light and bespoke joinery in a compact, elegant footprint.</p></div></div></GridOrCarousel></ScrollReveal></div></section></div>
</>
);
}

View File

@@ -6,4 +6,7 @@ export interface Route {
export const routes: Route[] = [
{ path: '/', label: 'Home', pageFile: 'HomePage' },
{ path: '/projects', label: 'Projects', pageFile: 'ProjectsPage' },
{ path: '/barrio-de-salamanca-penthouse', label: 'Barrio De Salamanca Penthouse', pageFile: 'BarrioDeSalamancaPenthousePage' },
{ path: '/blog', label: 'Blog', pageFile: 'BlogPage' },
];