1258 lines
78 KiB
PHP
1258 lines
78 KiB
PHP
@extends('web.layouts.web-master')
|
|
|
|
@php
|
|
$ui = data_get($content, 'ui', []);
|
|
$modalUi = data_get($ui, 'modal', []);
|
|
$lightboxUi = data_get($ui, 'lightbox', []);
|
|
$dev = $dev ?? false;
|
|
$devQuery = $devQuery ?? false;
|
|
$overviewRouteName = $overviewRouteName ?? ($dev ? 'dev.immobilien-azizi' : 'immobilien');
|
|
$detailRouteName = $detailRouteName ?? ($dev ? 'dev.immobilien-azizi.show' : 'immobilien.show');
|
|
$detailUrl = fn(string $slug): string => route(
|
|
$detailRouteName,
|
|
$devQuery ? ['slug' => $slug, 'dev' => 1] : ['slug' => $slug],
|
|
);
|
|
$projects = collect($content['projects'] ?? []);
|
|
$featured = $content['featured'] ?? [];
|
|
$featuredProject = $projects->firstWhere('slug', $featured['slug'] ?? '');
|
|
$categories = collect($content['categories'] ?? []);
|
|
$districts = collect(data_get($content, 'districts.items', []));
|
|
$featuredSlug = data_get($featured, 'slug');
|
|
$gridProjects = $projects->reject(fn($project) => $project['slug'] === $featuredSlug);
|
|
$gridProjectsCount = $gridProjects->count();
|
|
$anchorId = fn(string $prefix, string $value): string => $prefix . '-' . \Illuminate\Support\Str::slug($value);
|
|
$categoryNavItems = $categories
|
|
->map(function (array $category) use ($gridProjects, $anchorId): array {
|
|
$categoryProjects = $gridProjects->where('category', $category['key']);
|
|
|
|
return [
|
|
'id' => $anchorId('category', $category['key']),
|
|
'title' => $category['title'],
|
|
'count' => $categoryProjects->count(),
|
|
];
|
|
})
|
|
->filter(fn(array $item): bool => $item['count'] > 0)
|
|
->values();
|
|
$districtAliases = [
|
|
'Dubai South' => ['Dubai South', 'Azizi Venice'],
|
|
'Dubailand / Azizi Milan' => ['Dubailand', 'Dubai Land', 'Azizi Milan'],
|
|
'Dubai Healthcare City / Al Jaddaf' => ['Dubai Healthcare City', 'Healthcare City', 'Al Jaddaf', 'DHCC'],
|
|
'Dubai Studio City' => ['Dubai Studio City', 'Studio City'],
|
|
'Meydan' => ['Meydan', 'MBR City', 'Riviera'],
|
|
'Palm Jumeirah' => ['Palm Jumeirah'],
|
|
'Al Furjan' => ['Al Furjan'],
|
|
'Dubai Islands' => ['Dubai Islands'],
|
|
'Jebel Ali' => ['Jebel Ali'],
|
|
'Jumeirah Village Circle' => ['Jumeirah Village Circle', 'JVC'],
|
|
];
|
|
$districtProjectGroups = $districts
|
|
->map(function (array $district) use ($gridProjects, $districtAliases, $anchorId): array {
|
|
$name = $district['name'] ?? '';
|
|
$aliases = $districtAliases[$name] ?? [$name];
|
|
$districtProjects = $gridProjects
|
|
->filter(function (array $project) use ($aliases): bool {
|
|
$location = $project['location'] ?? '';
|
|
|
|
foreach ($aliases as $alias) {
|
|
if (str_contains(strtolower($location), strtolower($alias))) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
})
|
|
->values();
|
|
|
|
return [
|
|
'id' => $anchorId('district', $name),
|
|
'name' => $name,
|
|
'description' => $district['description'] ?? '',
|
|
'projects_label' => $district['projects'] ?? '',
|
|
'projects' => $districtProjects,
|
|
'count' => $districtProjects->count(),
|
|
];
|
|
})
|
|
->filter(fn(array $group): bool => $group['count'] > 0)
|
|
->values();
|
|
$statusLabels = data_get($ui, 'status_labels', []);
|
|
$statusClasses = [
|
|
'ready' => 'bg-emerald-500',
|
|
'construction' => 'bg-sky-500',
|
|
'offplan' => 'bg-amber-400 text-zinc-950',
|
|
];
|
|
$projectUnitType = fn(array $project): string => $project['official_unit_type'] ??
|
|
($project['overview_bedrooms'] ??
|
|
($project['units'] ?? data_get($ui, 'fallbacks.unit_type', 'Einheitentypen prüfen')));
|
|
$parseAedPrice = function (?string $value): ?int {
|
|
if (!is_string($value) || !preg_match('/AED\s*([0-9][0-9.,]*)\s*([KkMm])?/u', $value, $matches)) {
|
|
return null;
|
|
}
|
|
|
|
$number = $matches[1];
|
|
$suffix = strtolower($matches[2] ?? '');
|
|
|
|
if ($suffix === 'm') {
|
|
return (int) round((float) str_replace(',', '.', $number) * 1_000_000);
|
|
}
|
|
|
|
if ($suffix === 'k') {
|
|
return (int) round((float) str_replace(',', '.', $number) * 1_000);
|
|
}
|
|
|
|
return (int) preg_replace('/\D+/', '', $number);
|
|
};
|
|
$priceFallback = data_get($ui, 'show_page.stat_price_fallback', 'Auf Anfrage');
|
|
$formatProjectPrice = function (array $project) use ($parseAedPrice, $priceFallback): string {
|
|
$price = $project['official_starting_price'] ?? ($project['price_from'] ?? null);
|
|
$aed = $parseAedPrice($price);
|
|
|
|
if ($aed === null || $aed <= 0) {
|
|
return $project['price_from'] ?? $priceFallback;
|
|
}
|
|
|
|
return \App\Helpers\PriceHelper::formatAed($aed, 'ab');
|
|
};
|
|
$projectImages = function (array $project): array {
|
|
$slug = $project['slug'] ?? '';
|
|
$fallbackImage = theme_image_url($project['image'] ?? 'b2in/hero-immobilien.jpg');
|
|
$basePath = storage_path('app/public/immobile/dubai/' . $slug);
|
|
$paths = collect([
|
|
glob($basePath . '/image/*.{webp,jpg,jpeg,png}', GLOB_BRACE) ?: [],
|
|
glob($basePath . '/official-website/*.{webp,jpg,jpeg,png}', GLOB_BRACE) ?: [],
|
|
])
|
|
->flatten()
|
|
->all();
|
|
|
|
sort($paths, SORT_NATURAL);
|
|
|
|
$urls = collect($paths)
|
|
->map(fn(string $path): string => theme_image_url(str_replace(storage_path('app/public') . '/', '', $path)))
|
|
->values();
|
|
|
|
return [
|
|
'hero' => $urls->first() ?? $fallbackImage,
|
|
'gallery' => $urls->take(6)->values()->all(),
|
|
];
|
|
};
|
|
$modalProjects = $projects->mapWithKeys(function (array $project) use (
|
|
$formatProjectPrice,
|
|
$detailUrl,
|
|
$projectImages,
|
|
$projectUnitType,
|
|
$statusClasses,
|
|
): array {
|
|
$images = $projectImages($project);
|
|
|
|
return [
|
|
$project['slug'] => [
|
|
'slug' => $project['slug'],
|
|
'title' => $project['title'] ?? '',
|
|
'location' => $project['location'] ?? '',
|
|
'status' => $project['status'] ?? '',
|
|
'status_class' => $statusClasses[$project['status_group'] ?? 'ready'] ?? 'bg-secondary',
|
|
'price_from' => $formatProjectPrice($project),
|
|
'handover' => $project['handover'] ?? data_get($ui, 'fallbacks.handover'),
|
|
'units' => $projectUnitType($project),
|
|
'image_url' => $images['hero'],
|
|
'gallery_images' => $images['gallery'],
|
|
'short' => $project['short'] ?? '',
|
|
'marcel_take' => $project['marcel_take'] ?? '',
|
|
'official_description_de' => $project['official_description_de'] ?? '',
|
|
'buyer_profile' => $project['buyer_profile'] ?? '',
|
|
'highlights' => $project['highlights'] ?? [],
|
|
'official_url' => $project['official_url'] ?? '',
|
|
'detail_url' => $detailUrl($project['slug']),
|
|
],
|
|
];
|
|
});
|
|
@endphp
|
|
|
|
@section('title', data_get($content, 'meta.title', 'Dubai Immobilien - B2in'))
|
|
@section('meta_description', data_get($content, 'meta.description', 'Kuratierte Immobilienprojekte in Dubai.'))
|
|
|
|
@section('content')
|
|
<div class="bg-background">
|
|
<livewire:web.components.ui.header />
|
|
|
|
<main class="variante-glass-flow" x-data="{
|
|
view: 'categories',
|
|
showBackToTop: false,
|
|
selectedProject: null,
|
|
galleryLightboxIndex: null,
|
|
modalHistoryActive: false,
|
|
projects: {{ \Illuminate\Support\Js::from($modalProjects) }},
|
|
syncProjectContactForm(project) {
|
|
const payload = {
|
|
slug: project.slug,
|
|
title: project.title,
|
|
}
|
|
const dispatchProject = () => {
|
|
window.dispatchEvent(new CustomEvent('azizi-project-selected', { detail: payload }))
|
|
|
|
if (window.Livewire) {
|
|
window.Livewire.dispatch('azizi-project-selected', payload)
|
|
}
|
|
}
|
|
|
|
this.$nextTick(dispatchProject)
|
|
window.setTimeout(dispatchProject, 150)
|
|
},
|
|
openProject(slug) {
|
|
const project = this.projects[slug] || null
|
|
|
|
if (!project) {
|
|
return
|
|
}
|
|
|
|
this.selectedProject = project
|
|
this.galleryLightboxIndex = null
|
|
this.syncProjectContactForm(project)
|
|
|
|
if (this.modalHistoryActive) {
|
|
history.replaceState({ aziziProjectModal: slug }, '', window.location.href)
|
|
|
|
return
|
|
}
|
|
|
|
history.pushState({ aziziProjectModal: slug }, '', window.location.href)
|
|
this.modalHistoryActive = true
|
|
},
|
|
closeProject(fromPopstate = false) {
|
|
if (!this.selectedProject) {
|
|
return
|
|
}
|
|
|
|
this.selectedProject = null
|
|
this.galleryLightboxIndex = null
|
|
|
|
if (this.modalHistoryActive) {
|
|
this.modalHistoryActive = false
|
|
|
|
if (!fromPopstate) {
|
|
history.back()
|
|
}
|
|
}
|
|
},
|
|
handleBrowserBack() {
|
|
if (!this.selectedProject || !this.modalHistoryActive) {
|
|
return
|
|
}
|
|
|
|
this.modalHistoryActive = false
|
|
this.closeProject(true)
|
|
},
|
|
openGallery(index) {
|
|
this.galleryLightboxIndex = index
|
|
},
|
|
closeGallery() {
|
|
this.galleryLightboxIndex = null
|
|
},
|
|
showPreviousGalleryImage() {
|
|
const length = this.selectedProject?.gallery_images?.length || 0
|
|
|
|
if (!length || this.galleryLightboxIndex === null) {
|
|
return
|
|
}
|
|
|
|
this.galleryLightboxIndex = (this.galleryLightboxIndex - 1 + length) % length
|
|
},
|
|
showNextGalleryImage() {
|
|
const length = this.selectedProject?.gallery_images?.length || 0
|
|
|
|
if (!length || this.galleryLightboxIndex === null) {
|
|
return
|
|
}
|
|
|
|
this.galleryLightboxIndex = (this.galleryLightboxIndex + 1) % length
|
|
},
|
|
updateBackToTop() {
|
|
this.showBackToTop = this.$refs.projectFilter ?
|
|
this.$refs.projectFilter.getBoundingClientRect().bottom < 0 :
|
|
false
|
|
},
|
|
}" x-init="updateBackToTop()
|
|
$watch('selectedProject', value => document.body.classList.toggle('overflow-hidden', Boolean(value)))
|
|
window.addEventListener('scroll', () => updateBackToTop(), { passive: true })
|
|
window.addEventListener('resize', () => updateBackToTop())
|
|
window.addEventListener('popstate', () => handleBrowserBack())"
|
|
@keydown.escape.window="galleryLightboxIndex !== null ? closeGallery() : closeProject()"
|
|
@keydown.arrow-left.window="galleryLightboxIndex !== null && showPreviousGalleryImage()"
|
|
@keydown.arrow-right.window="galleryLightboxIndex !== null && showNextGalleryImage()">
|
|
|
|
@php
|
|
$sidebarSections = collect(data_get($ui, 'sidebar.sections', []))
|
|
->map(function (array $section) use ($featured) {
|
|
if (($section['id'] ?? null) === 'featured' && !empty($featured['title'])) {
|
|
$section['label'] = $featured['title'];
|
|
}
|
|
|
|
return $section;
|
|
})
|
|
->values()
|
|
->all();
|
|
@endphp
|
|
|
|
<nav x-show="!selectedProject" x-cloak x-transition.opacity x-data="{
|
|
open: false,
|
|
active: '',
|
|
navTop: 12,
|
|
panelTop: 64,
|
|
sections: @js($sidebarSections),
|
|
update() {
|
|
const offset = window.innerHeight * 0.35
|
|
let current = ''
|
|
for (const s of this.sections) {
|
|
const el = document.getElementById(s.id)
|
|
if (el && el.getBoundingClientRect().top - offset <= 0) {
|
|
current = s.id
|
|
}
|
|
}
|
|
this.active = current
|
|
},
|
|
updatePosition() {
|
|
const header = document.getElementById('header')
|
|
if (!header) {
|
|
this.navTop = 12
|
|
this.panelTop = 64
|
|
return
|
|
}
|
|
|
|
const rect = header.getBoundingClientRect()
|
|
this.navTop = Math.max(12, rect.top + 12)
|
|
this.panelTop = Math.max(64, rect.bottom + 8)
|
|
},
|
|
scrollToSection(id) {
|
|
const el = document.getElementById(id)
|
|
if (!el) {
|
|
return
|
|
}
|
|
el.scrollIntoView({ behavior: 'smooth', block: 'start' })
|
|
this.open = false
|
|
},
|
|
activeLabel() {
|
|
return this.sections.find(section => section.id === this.active)?.label || this.sections[0]?.label || ''
|
|
},
|
|
}" x-init="update();
|
|
updatePosition();
|
|
window.addEventListener('scroll', () => update(), { passive: true });
|
|
window.addEventListener('scroll', () => updatePosition(), { passive: true });
|
|
window.addEventListener('resize', () => { update(); updatePosition(); }, { passive: true });"
|
|
@keydown.escape.window="open = false" aria-label="{{ data_get($ui, 'sidebar.toggle_open') }}"
|
|
class="fixed right-[3.25rem] z-[60] md:hidden" :style="`top: ${navTop}px`">
|
|
<div x-show="open" x-cloak x-transition.origin.top.right @click.outside="open = false"
|
|
class="fixed inset-x-3 rounded-2xl border border-border bg-background p-3 shadow-2xl shadow-zinc-950/25"
|
|
:style="`top: ${panelTop}px`">
|
|
<div class="mb-3 flex items-center justify-between gap-3 border-b border-border pb-3">
|
|
<p class="text-xs font-semibold uppercase tracking-[0.16em] text-muted-foreground">
|
|
{{ data_get($ui, 'sidebar.mobile_label', 'Abschnitt') }}
|
|
</p>
|
|
<p class="min-w-0 truncate text-sm font-semibold text-foreground" x-text="activeLabel()"></p>
|
|
</div>
|
|
|
|
<ul class="sidebar-nav grid max-h-[58vh] grid-cols-2 gap-2 overflow-y-auto sm:grid-cols-3">
|
|
<template x-for="s in sections" :key="s.id">
|
|
<li>
|
|
<button type="button" @click="scrollToSection(s.id)"
|
|
class="flex min-h-11 w-full items-center gap-2 rounded-xl border px-3 py-2 text-left text-sm font-medium transition"
|
|
:class="active === s.id ?
|
|
'border-secondary bg-secondary/10 text-secondary' :
|
|
'border-border bg-card text-foreground hover:border-secondary/50 hover:text-secondary'"
|
|
:aria-current="active === s.id ? 'true' : 'false'">
|
|
<span class="flex h-3 w-3 shrink-0 items-center justify-center">
|
|
<span class="block rounded-full"
|
|
:class="active === s.id ? 'h-2 w-2 bg-secondary' : 'h-1.5 w-1.5 bg-muted-foreground/45'"></span>
|
|
</span>
|
|
<span class="min-w-0 truncate" x-text="s.label"></span>
|
|
</button>
|
|
</li>
|
|
</template>
|
|
</ul>
|
|
</div>
|
|
|
|
<button type="button" @click="open = !open" :aria-expanded="open.toString()"
|
|
title="{{ data_get($ui, 'sidebar.toggle_open') }}"
|
|
class="sidebar-nav inline-flex h-10 w-10 items-center justify-center rounded-full border border-border bg-background text-foreground shadow-lg shadow-zinc-950/10 transition hover:border-secondary hover:text-secondary focus:outline-none focus:ring-2 focus:ring-secondary focus:ring-offset-2 focus:ring-offset-background">
|
|
<span class="sr-only">{{ data_get($ui, 'sidebar.mobile_label', 'Abschnitt') }}: <span
|
|
x-text="activeLabel()"></span></span>
|
|
<span class="transition" :class="open ? 'rotate-90 text-secondary' : ''">
|
|
@svg('heroicon-o-list-bullet', 'h-5 w-5')
|
|
</span>
|
|
</button>
|
|
</nav>
|
|
|
|
<aside x-show="!selectedProject" x-cloak x-transition.opacity x-data="{
|
|
expanded: false,
|
|
active: '',
|
|
sections: @js($sidebarSections),
|
|
update() {
|
|
const offset = window.innerHeight * 0.35
|
|
let current = ''
|
|
for (const s of this.sections) {
|
|
const el = document.getElementById(s.id)
|
|
if (el && el.getBoundingClientRect().top - offset <= 0) {
|
|
current = s.id
|
|
}
|
|
}
|
|
this.active = current
|
|
},
|
|
scrollToSection(id) {
|
|
const el = document.getElementById(id)
|
|
if (!el) {
|
|
return
|
|
}
|
|
el.scrollIntoView({ behavior: 'smooth', block: 'start' })
|
|
},
|
|
}" x-init="update();
|
|
window.addEventListener('scroll', () => update(), { passive: true });
|
|
window.addEventListener('resize', () => update(), { passive: true });"
|
|
@mouseenter="expanded = true" @mouseleave="expanded = false"
|
|
aria-label="{{ data_get($ui, 'sidebar.toggle_open') }}"
|
|
class="fixed right-4 top-1/2 z-30 hidden -translate-y-1/2 lg:block">
|
|
<ul class="sidebar-nav flex flex-col rounded-2xl border border-border/60 bg-background/80 p-2 backdrop-blur-sm transition-[width] duration-300 ease-out"
|
|
:class="expanded ? 'w-56' : 'w-10'">
|
|
<template x-for="s in sections" :key="s.id">
|
|
<li>
|
|
<button type="button" @click="scrollToSection(s.id)"
|
|
class="group/sb flex w-full items-center gap-3 py-1.5 text-left focus:outline-none"
|
|
:aria-current="active === s.id ? 'true' : 'false'">
|
|
<span class="flex h-3 w-3 shrink-0 items-center justify-center">
|
|
<span class="block rounded-full transition-all duration-200"
|
|
:class="active === s.id ? 'h-2 w-2 bg-secondary' :
|
|
'h-1 w-1 bg-muted-foreground/40 group-hover/sb:bg-muted-foreground'"></span>
|
|
</span>
|
|
<span class="overflow-hidden whitespace-nowrap text-sm transition-all duration-200"
|
|
:class="[
|
|
expanded ? 'max-w-[180px] opacity-100' : 'max-w-0 opacity-0',
|
|
active === s.id ? 'font-medium text-secondary' :
|
|
'text-muted-foreground group-hover/sb:text-foreground'
|
|
]"
|
|
x-text="s.label"></span>
|
|
</button>
|
|
</li>
|
|
</template>
|
|
</ul>
|
|
</aside>
|
|
|
|
<section id="hero" class="relative min-h-[76vh] flex items-center overflow-hidden">
|
|
<x-web-picture src="{{ theme_image_url(data_get($content, 'hero.image')) }}"
|
|
alt="Dubai Skyline - kuratierte Immobilienprojekte" class="absolute inset-0 h-full w-full object-cover"
|
|
loading="" />
|
|
<div class="absolute inset-0 bg-gradient-to-r from-black/85 via-black/65 to-black/35"></div>
|
|
|
|
<div class="relative z-10 container-padding py-24 lg:py-32">
|
|
<div class="max-w-4xl">
|
|
<p class="mb-5 text-sm font-semibold uppercase tracking-[0.24em] text-secondary">
|
|
{{ data_get($content, 'hero.eyebrow') }}
|
|
</p>
|
|
<h1 class="max-w-3xl text-4xl font-bold leading-tight text-white lg:text-6xl">
|
|
{{ data_get($content, 'hero.title') }}
|
|
</h1>
|
|
<p class="mt-6 max-w-2xl text-lg leading-relaxed text-white/80 lg:text-xl">
|
|
{{ data_get($content, 'hero.subtitle') }}
|
|
</p>
|
|
|
|
<div class="mt-10 flex flex-col gap-3 sm:flex-row">
|
|
<a href="#projekte" class="btn-primary-accent px-8 py-4 text-lg">
|
|
{{ data_get($content, 'hero.cta_primary') }}
|
|
</a>
|
|
<a href="/contact" class="btn-secondary-accent px-8 py-4 text-lg">
|
|
{{ data_get($content, 'hero.cta_secondary') }}
|
|
</a>
|
|
</div>
|
|
|
|
<p class="mt-5 max-w-xl text-sm font-medium text-white/70">
|
|
{{ data_get($content, 'hero.microcopy') }}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section id="intro" class="section-padding scroll-mt-24">
|
|
<div class="container-padding">
|
|
<div class="grid items-center gap-12 lg:grid-cols-[0.9fr_1.1fr]">
|
|
<div class="card-elevated overflow-hidden rounded-3xl">
|
|
<x-web-picture src="{{ theme_image_url(data_get($content, 'intro.image')) }}"
|
|
alt="Marcel Scheibe - B2in Immobilienberatung" class="h-[460px] w-full object-cover" />
|
|
</div>
|
|
|
|
<div>
|
|
<p class="mb-4 text-sm font-semibold uppercase tracking-[0.22em] text-secondary">
|
|
{{ data_get($ui, 'intro_eyebrow') }}
|
|
</p>
|
|
<h2 class="text-section-title">{{ data_get($content, 'intro.title') }}</h2>
|
|
<blockquote
|
|
class="mt-6 border-l-4 border-secondary pl-5 text-xl font-medium leading-relaxed text-foreground">
|
|
"{{ data_get($content, 'intro.quote') }}"
|
|
</blockquote>
|
|
<div class="mt-6 space-y-4 text-large leading-relaxed text-muted-foreground">
|
|
@foreach (data_get($content, 'intro.paragraphs', []) as $paragraph)
|
|
<p>{{ $paragraph }}</p>
|
|
@endforeach
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section id="featured"
|
|
class="section-padding relative isolate overflow-hidden bg-zinc-950 text-white scroll-mt-24">
|
|
<x-web-picture src="{{ theme_image_url($featured['image'] ?? 'b2in/hero-immobilien.jpg') }}"
|
|
alt="{{ $featured['title'] ?? data_get($ui, 'featured_default_alt') }}"
|
|
class="absolute inset-0 -z-20 h-full w-full object-cover" loading="" />
|
|
<div class="absolute inset-0 -z-10 bg-gradient-to-r from-zinc-950 via-zinc-950/90 to-zinc-950/65"></div>
|
|
<div class="absolute inset-x-0 top-0 -z-10 h-28 bg-gradient-to-b from-zinc-950 to-transparent"></div>
|
|
<div class="absolute inset-x-0 bottom-0 -z-10 h-28 bg-gradient-to-t from-zinc-950 to-transparent"></div>
|
|
|
|
<div class="container-padding">
|
|
<div class="grid gap-10 lg:grid-cols-[1.05fr_0.95fr] lg:items-center">
|
|
<div
|
|
class="relative overflow-hidden rounded-3xl border border-white/10 bg-[#142f34] shadow-2xl shadow-black/20">
|
|
<x-web-picture src="{{ theme_image_url($featured['image'] ?? 'b2in/hero-immobilien.jpg') }}"
|
|
alt="{{ $featured['title'] ?? data_get($ui, 'featured_default_alt') }}"
|
|
class="h-[520px] w-full object-cover opacity-75" />
|
|
<div
|
|
class="absolute inset-0 bg-gradient-to-t from-[#071316]/95 via-[#071316]/35 to-[#071316]/10">
|
|
</div>
|
|
<div class="absolute bottom-6 left-6 right-6">
|
|
<span
|
|
class="inline-flex rounded-full bg-white px-3 py-1 text-xs font-semibold text-[#0e2226]">
|
|
{{ data_get($ui, 'featured_label') }}
|
|
</span>
|
|
<h2 class="mt-4 text-3xl font-bold lg:text-5xl">{{ $featured['title'] ?? '' }}</h2>
|
|
<p class="mt-2 text-white/75">{{ $featured['location'] ?? '' }}</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div>
|
|
<p
|
|
class="inline-flex rounded-full bg-white px-3 py-1 text-xs font-semibold uppercase tracking-[0.18em] text-[#0e2226]">
|
|
{{ $featured['status'] ?? '' }}
|
|
</p>
|
|
<h2 class="mt-4 text-3xl font-bold leading-tight lg:text-5xl">
|
|
{{ $featured['headline'] ?? '' }}
|
|
</h2>
|
|
<p class="mt-6 text-lg leading-relaxed text-white/90">
|
|
{{ $featured['text'] ?? '' }}
|
|
</p>
|
|
|
|
<div class="mt-6 rounded-2xl border border-white/10 bg-black/40 p-6">
|
|
<p class="text-sm font-semibold text-white">{{ data_get($ui, 'featured_marcel_heading') }}
|
|
</p>
|
|
<p class="mt-3 leading-relaxed text-white/80">{{ $featured['marcel_take'] ?? '' }}</p>
|
|
</div>
|
|
|
|
<dl class="mt-8 grid gap-3 sm:grid-cols-2">
|
|
<div class="rounded-2xl bg-white/5 p-4">
|
|
<dt class="text-xs uppercase tracking-wider text-white/80">
|
|
{{ data_get($ui, 'featured_stat_price') }}</dt>
|
|
<dd class="mt-1 font-semibold">{{ $featured['price_from'] ?? '' }}</dd>
|
|
</div>
|
|
<div class="rounded-2xl bg-white/5 p-4">
|
|
<dt class="text-xs uppercase tracking-wider text-white/80">
|
|
{{ data_get($ui, 'featured_stat_handover') }}</dt>
|
|
<dd class="mt-1 font-semibold">{{ $featured['handover'] ?? '' }}</dd>
|
|
</div>
|
|
</dl>
|
|
|
|
<ul class="mt-6 grid gap-2 text-sm text-white/90 sm:grid-cols-2">
|
|
@foreach ($featured['facts'] ?? [] as $fact)
|
|
<li class="flex gap-2">
|
|
@svg('heroicon-o-check-circle', 'mt-0.5 h-4 w-4 shrink-0 text-secondary')
|
|
<span>{{ $fact }}</span>
|
|
</li>
|
|
@endforeach
|
|
</ul>
|
|
|
|
@if ($featuredProject)
|
|
<div class="mt-8">
|
|
<a href="{{ $detailUrl($featuredProject['slug']) }}"
|
|
class="btn-primary-accent px-7 py-3"
|
|
@click.prevent="openProject('{{ $featuredProject['slug'] }}')">
|
|
{{ str_replace(':title', $featured['title'] ?? data_get($ui, 'fallbacks.project_default'), data_get($ui, 'featured_cta_detail', '')) }}
|
|
</a>
|
|
</div>
|
|
@endif
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
{{-- TODO: Karte Muss noch richtig entwickelt werden
|
|
<section id="karte" class="section-padding bg-accent">
|
|
<div class="container-padding">
|
|
<div class="mb-10 max-w-3xl">
|
|
<h2 class="text-section-title">{{ data_get($content, 'map.title') }}</h2>
|
|
<p class="mt-4 text-large leading-relaxed text-muted-foreground">
|
|
{{ data_get($content, 'map.subtitle') }}
|
|
</p>
|
|
</div>
|
|
|
|
<div class="grid gap-8 lg:grid-cols-[1.2fr_0.8fr]">
|
|
<div class="relative min-h-[520px] overflow-hidden rounded-3xl border border-border bg-gradient-to-br from-sky-100 via-white to-emerald-50 p-6 shadow-sm dark:from-slate-900 dark:via-slate-950 dark:to-emerald-950">
|
|
<div class="absolute left-[8%] top-[10%] h-[78%] w-[62%] rotate-[-18deg] rounded-[55%] border border-sky-400/30 bg-sky-300/20"></div>
|
|
<div class="absolute right-[8%] top-[5%] h-[86%] w-[32%] rounded-[48%] border border-emerald-500/20 bg-emerald-300/20"></div>
|
|
<div class="absolute bottom-[8%] left-[24%] h-[26%] w-[46%] rounded-[48%] border border-secondary/20 bg-secondary/10"></div>
|
|
|
|
<span class="absolute left-[56%] top-[44%] text-xs font-semibold uppercase tracking-wider text-zinc-500">Downtown</span>
|
|
<span class="absolute left-[34%] top-[70%] text-xs font-semibold uppercase tracking-wider text-zinc-500">Al Furjan</span>
|
|
<span class="absolute left-[29%] top-[87%] text-xs font-semibold uppercase tracking-wider text-zinc-500">Dubai South</span>
|
|
<span class="absolute left-[21%] top-[42%] text-xs font-semibold uppercase tracking-wider text-zinc-500">Palm</span>
|
|
<span class="absolute left-[70%] top-[24%] text-xs font-semibold uppercase tracking-wider text-zinc-500">Dubai Islands</span>
|
|
|
|
@foreach (data_get($content, 'map.pins', []) as $pin)
|
|
@php
|
|
$pinProject = $projects->firstWhere('slug', $pin['slug']);
|
|
$group = $pinProject['status_group'] ?? 'ready';
|
|
@endphp
|
|
@if ($pinProject)
|
|
<a href="{{ $detailUrl($pinProject['slug']) }}"
|
|
title="{{ $pinProject['title'] }}"
|
|
@click.prevent="openProject('{{ $pinProject['slug'] }}')"
|
|
class="group absolute flex h-8 w-8 -translate-x-1/2 -translate-y-1/2 items-center justify-center rounded-full border-2 border-white shadow-lg transition hover:z-20 hover:scale-110 {{ $statusClasses[$group] ?? 'bg-secondary' }}"
|
|
style="left: {{ $pin['x'] }}%; top: {{ $pin['y'] }}%;">
|
|
<span class="h-2.5 w-2.5 rounded-full bg-white/90"></span>
|
|
<span class="pointer-events-none absolute bottom-full left-1/2 mb-3 hidden w-56 -translate-x-1/2 rounded-xl bg-zinc-950 p-3 text-left text-xs text-white shadow-xl group-hover:block">
|
|
<strong class="block text-sm">{{ $pinProject['title'] }}</strong>
|
|
<span class="mt-1 block text-white/70">{{ $pinProject['location'] }}</span>
|
|
<span class="mt-2 block text-secondary">{{ $statusLabels[$group] ?? $pinProject['status'] }}</span>
|
|
</span>
|
|
</a>
|
|
@endif
|
|
@endforeach
|
|
</div>
|
|
|
|
<div class="grid content-start gap-4">
|
|
@foreach ($statusLabels as $key => $label)
|
|
<div class="card-elevated rounded-2xl p-5">
|
|
<div class="flex items-center gap-3">
|
|
<span class="h-4 w-4 rounded-full {{ $statusClasses[$key] ?? 'bg-secondary' }}"></span>
|
|
<h3 class="font-semibold text-foreground">{{ $label }}</h3>
|
|
</div>
|
|
<p class="mt-2 text-sm text-muted-foreground">
|
|
{{ $projects->where('status_group', $key)->count() }} Projekte in dieser Auswahl.
|
|
</p>
|
|
</div>
|
|
@endforeach
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
--}}
|
|
@if ($districts->isNotEmpty())
|
|
<section id="stadtteile" class="section-padding scroll-mt-24">
|
|
<div class="container-padding">
|
|
<div class="mb-10 max-w-3xl">
|
|
<p class="mb-4 text-sm font-semibold uppercase tracking-[0.22em] text-secondary">
|
|
{{ data_get($ui, 'districts_eyebrow') }}
|
|
</p>
|
|
<h2 class="text-section-title">{{ data_get($content, 'districts.title') }}</h2>
|
|
<p class="mt-4 text-large leading-relaxed text-muted-foreground">
|
|
{{ data_get($content, 'districts.subtitle') }}
|
|
</p>
|
|
</div>
|
|
|
|
<div class="grid gap-5 md:grid-cols-2 xl:grid-cols-3">
|
|
@foreach ($districts as $district)
|
|
<article class="card-elevated rounded-2xl p-6">
|
|
<p class="text-xs font-semibold uppercase tracking-[0.18em] text-secondary">
|
|
{{ $district['projects'] ?? '' }}
|
|
</p>
|
|
<h3 class="mt-3 text-xl font-semibold text-foreground">{{ $district['name'] ?? '' }}
|
|
</h3>
|
|
<p class="mt-3 text-sm leading-relaxed text-muted-foreground">
|
|
{{ $district['description'] ?? '' }}
|
|
</p>
|
|
</article>
|
|
@endforeach
|
|
</div>
|
|
</div>
|
|
</section>
|
|
@endif
|
|
|
|
<section id="projekte" class="section-padding scroll-mt-24" style="background: #e1e5e7;">
|
|
<div class="container-padding">
|
|
<div class="mb-12 max-w-3xl">
|
|
<p class="mb-4 text-sm font-semibold uppercase tracking-[0.22em] text-secondary">
|
|
{{ data_get($ui, 'grid_eyebrow') }}
|
|
</p>
|
|
<h2 class="text-section-title">
|
|
{{ str_replace(':count', $gridProjectsCount, data_get($ui, 'grid_title', '')) }}</h2>
|
|
<p class="mt-4 text-large text-muted-foreground">
|
|
{{ data_get($ui, 'grid_intro') }}
|
|
</p>
|
|
</div>
|
|
|
|
<div x-ref="projectFilter"
|
|
class="mb-12 rounded-3xl border border-border bg-card p-4 shadow-sm md:p-6">
|
|
<div class="flex flex-col gap-5 lg:flex-row lg:items-center lg:justify-between">
|
|
<div class="inline-flex w-full rounded-2xl bg-accent p-1 sm:w-auto">
|
|
<button type="button"
|
|
class="flex-1 rounded-xl px-5 py-3 text-sm font-semibold transition sm:flex-none"
|
|
:class="view === 'categories' ? 'bg-background text-foreground shadow-sm' :
|
|
'text-muted-foreground hover:text-foreground'"
|
|
@click="view = 'categories'">
|
|
{{ data_get($ui, 'filter_categories') }}
|
|
</button>
|
|
<button type="button"
|
|
class="flex-1 rounded-xl px-5 py-3 text-sm font-semibold transition sm:flex-none"
|
|
:class="view === 'districts' ? 'bg-background text-foreground shadow-sm' :
|
|
'text-muted-foreground hover:text-foreground'"
|
|
@click="view = 'districts'">
|
|
{{ data_get($ui, 'filter_districts') }}
|
|
</button>
|
|
</div>
|
|
|
|
<p class="text-sm font-medium text-muted-foreground">
|
|
{{ str_replace([':categories', ':districts'], [$categoryNavItems->count(), $districtProjectGroups->count()], data_get($ui, 'filter_summary', '')) }}
|
|
</p>
|
|
</div>
|
|
|
|
<div class="mt-6" x-show="view === 'categories'">
|
|
<div class="grid gap-3 sm:grid-cols-2 lg:grid-cols-4">
|
|
@foreach ($categoryNavItems as $item)
|
|
<a href="#{{ $item['id'] }}"
|
|
@click.prevent="document.getElementById('{{ $item['id'] }}')?.scrollIntoView({ behavior: 'smooth', block: 'start' })"
|
|
class="group flex min-h-24 flex-col justify-between rounded-2xl border border-border bg-background p-4 transition hover:border-secondary hover:shadow-sm">
|
|
<span class="text-sm font-semibold text-foreground">{{ $item['title'] }}</span>
|
|
<span
|
|
class="mt-4 inline-flex w-fit rounded-full bg-secondary/10 px-3 py-1 text-xs font-semibold text-secondary">
|
|
{{ str_replace(':count', $item['count'], data_get($ui, 'filter_count', '')) }}
|
|
</span>
|
|
</a>
|
|
@endforeach
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mt-6" x-show="view === 'districts'" x-cloak>
|
|
<div class="grid gap-3 sm:grid-cols-2 lg:grid-cols-4">
|
|
@foreach ($districtProjectGroups as $group)
|
|
<a href="#{{ $group['id'] }}"
|
|
@click.prevent="document.getElementById('{{ $group['id'] }}')?.scrollIntoView({ behavior: 'smooth', block: 'start' })"
|
|
class="group flex min-h-24 flex-col justify-between rounded-2xl border border-border bg-background p-4 transition hover:border-secondary hover:shadow-sm">
|
|
<span class="text-sm font-semibold text-foreground">{{ $group['name'] }}</span>
|
|
<span
|
|
class="mt-4 inline-flex w-fit rounded-full bg-secondary/10 px-3 py-1 text-xs font-semibold text-secondary">
|
|
{{ str_replace(':count', $group['count'], data_get($ui, 'filter_count', '')) }}
|
|
</span>
|
|
</a>
|
|
@endforeach
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="space-y-16" x-show="view === 'categories'">
|
|
@foreach ($categories as $category)
|
|
@php
|
|
$categoryProjects = $gridProjects->where('category', $category['key'])->values();
|
|
@endphp
|
|
@if ($categoryProjects->isNotEmpty())
|
|
<section id="{{ $anchorId('category', $category['key']) }}" class="scroll-mt-28"
|
|
style="background: transparent;">
|
|
<div class="mb-6 max-w-3xl">
|
|
<h3 class="text-2xl font-semibold text-foreground">{{ $category['title'] }}</h3>
|
|
<p class="mt-2 text-muted-foreground">{{ $category['intro'] }}</p>
|
|
</div>
|
|
|
|
<div class="grid gap-6 md:grid-cols-2 xl:grid-cols-3">
|
|
@foreach ($categoryProjects as $project)
|
|
<article
|
|
class="card-elevated group/card flex h-full cursor-pointer flex-col overflow-hidden rounded-2xl transition duration-300 hover:-translate-y-1 hover:shadow-xl focus:outline-none focus:ring-2 focus:ring-secondary focus:ring-offset-2 focus:ring-offset-[#e1e5e7]"
|
|
role="link" tabindex="0"
|
|
aria-label="{{ str_replace(':title', $project['title'], data_get($ui, 'card_aria_open', '')) }}"
|
|
@click="openProject('{{ $project['slug'] }}')"
|
|
@keydown.enter.prevent="openProject('{{ $project['slug'] }}')"
|
|
@keydown.space.prevent="openProject('{{ $project['slug'] }}')">
|
|
<div class="relative h-52 overflow-hidden">
|
|
<x-web-picture src="{{ theme_image_url($project['image']) }}"
|
|
alt="{{ $project['title'] }}"
|
|
class="h-full w-full object-cover transition duration-500 group-hover/card:scale-105" />
|
|
<span
|
|
class="absolute left-4 top-4 rounded-full px-3 py-1 text-xs font-semibold text-white {{ $statusClasses[$project['status_group']] ?? 'bg-secondary' }}">
|
|
{{ $project['status'] }}
|
|
</span>
|
|
</div>
|
|
|
|
<div class="flex flex-1 flex-col p-6">
|
|
<p class="text-sm text-muted-foreground">{{ $project['location'] }}
|
|
</p>
|
|
<h4 class="mt-1 text-xl font-semibold text-foreground">
|
|
{{ $project['title'] }}</h4>
|
|
<p class="mt-4 text-sm leading-relaxed text-muted-foreground">
|
|
{{ $project['short'] }}</p>
|
|
|
|
<dl class="mt-5 grid gap-3 text-sm">
|
|
<div>
|
|
<dt class="font-medium text-foreground">
|
|
{{ data_get($ui, 'card_label_buyer') }}</dt>
|
|
<dd class="text-muted-foreground">
|
|
{{ $project['buyer_profile'] }}</dd>
|
|
</div>
|
|
<div>
|
|
<dt class="font-medium text-foreground">
|
|
{{ data_get($ui, 'card_label_price') }}
|
|
</dt>
|
|
<dd class="text-secondary">{{ $project['price_from'] }}</dd>
|
|
</div>
|
|
<div>
|
|
<dt class="font-medium text-foreground">
|
|
{{ data_get($ui, 'card_label_unit') }}</dt>
|
|
<dd class="text-muted-foreground">
|
|
{{ $projectUnitType($project) }}</dd>
|
|
</div>
|
|
</dl>
|
|
|
|
<div class="mt-auto pt-6">
|
|
<a href="{{ $detailUrl($project['slug']) }}"
|
|
class="group/detail inline-flex items-center gap-1.5 rounded-full bg-secondary/10 px-3 py-1.5 text-sm font-semibold text-secondary transition duration-200 hover:-translate-y-0.5 hover:bg-secondary hover:text-white hover:shadow-md hover:shadow-secondary/20 focus:outline-none focus:ring-2 focus:ring-secondary focus:ring-offset-2 focus:ring-offset-background"
|
|
@click.stop.prevent="openProject('{{ $project['slug'] }}')">
|
|
{{ data_get($ui, 'card_cta') }}
|
|
@svg('heroicon-o-arrow-right', 'h-3.5 w-3.5 transition duration-200 group-hover/detail:translate-x-0.5')
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</article>
|
|
@endforeach
|
|
</div>
|
|
</section>
|
|
@endif
|
|
@endforeach
|
|
</div>
|
|
|
|
<div class="space-y-16" x-show="view === 'districts'" x-cloak>
|
|
@foreach ($districtProjectGroups as $group)
|
|
<section id="{{ $group['id'] }}" class="scroll-mt-28" style="background: transparent;">
|
|
<div class="mb-6 max-w-3xl">
|
|
<p class="mb-3 text-xs font-semibold uppercase tracking-[0.18em] text-secondary">
|
|
{{ $group['projects_label'] }}
|
|
</p>
|
|
<h3 class="text-2xl font-semibold text-foreground">{{ $group['name'] }}</h3>
|
|
<p class="mt-2 text-muted-foreground">{{ $group['description'] }}</p>
|
|
</div>
|
|
|
|
<div class="grid gap-6 md:grid-cols-2 xl:grid-cols-3">
|
|
@foreach ($group['projects'] as $project)
|
|
<article
|
|
class="card-elevated group/card flex h-full cursor-pointer flex-col overflow-hidden rounded-2xl transition duration-300 hover:-translate-y-1 hover:shadow-xl focus:outline-none focus:ring-2 focus:ring-secondary focus:ring-offset-2 focus:ring-offset-[#e1e5e7]"
|
|
role="link" tabindex="0"
|
|
aria-label="{{ str_replace(':title', $project['title'], data_get($ui, 'card_aria_open', '')) }}"
|
|
@click="openProject('{{ $project['slug'] }}')"
|
|
@keydown.enter.prevent="openProject('{{ $project['slug'] }}')"
|
|
@keydown.space.prevent="openProject('{{ $project['slug'] }}')">
|
|
<div class="relative h-52 overflow-hidden">
|
|
<x-web-picture src="{{ theme_image_url($project['image']) }}"
|
|
alt="{{ $project['title'] }}"
|
|
class="h-full w-full object-cover transition duration-500 group-hover/card:scale-105" />
|
|
<span
|
|
class="absolute left-4 top-4 rounded-full px-3 py-1 text-xs font-semibold text-white {{ $statusClasses[$project['status_group']] ?? 'bg-secondary' }}">
|
|
{{ $project['status'] }}
|
|
</span>
|
|
</div>
|
|
|
|
<div class="flex flex-1 flex-col p-6">
|
|
<p class="text-sm text-muted-foreground">{{ $project['location'] }}</p>
|
|
<h4 class="mt-1 text-xl font-semibold text-foreground">
|
|
{{ $project['title'] }}</h4>
|
|
<p class="mt-4 text-sm leading-relaxed text-muted-foreground">
|
|
{{ $project['short'] }}</p>
|
|
|
|
<dl class="mt-5 grid gap-3 text-sm">
|
|
<div>
|
|
<dt class="font-medium text-foreground">
|
|
{{ data_get($ui, 'card_label_buyer') }}</dt>
|
|
<dd class="text-muted-foreground">{{ $project['buyer_profile'] }}
|
|
</dd>
|
|
</div>
|
|
<div>
|
|
<dt class="font-medium text-foreground">
|
|
{{ data_get($ui, 'card_label_price') }}</dt>
|
|
<dd class="text-secondary">{{ $project['price_from'] }}</dd>
|
|
</div>
|
|
<div>
|
|
<dt class="font-medium text-foreground">
|
|
{{ data_get($ui, 'card_label_unit') }}</dt>
|
|
<dd class="text-muted-foreground">{{ $projectUnitType($project) }}
|
|
</dd>
|
|
</div>
|
|
</dl>
|
|
|
|
<div class="mt-auto pt-6">
|
|
<a href="{{ $detailUrl($project['slug']) }}"
|
|
class="group/detail inline-flex items-center gap-1.5 rounded-full bg-secondary/10 px-3 py-1.5 text-sm font-semibold text-secondary transition duration-200 hover:-translate-y-0.5 hover:bg-secondary hover:text-white hover:shadow-md hover:shadow-secondary/20 focus:outline-none focus:ring-2 focus:ring-secondary focus:ring-offset-2 focus:ring-offset-background"
|
|
@click.stop.prevent="openProject('{{ $project['slug'] }}')">
|
|
{{ data_get($ui, 'card_cta') }}
|
|
@svg('heroicon-o-arrow-right', 'h-3.5 w-3.5 transition duration-200 group-hover/detail:translate-x-0.5')
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</article>
|
|
@endforeach
|
|
</div>
|
|
</section>
|
|
@endforeach
|
|
</div>
|
|
|
|
<div class="pointer-events-none sticky bottom-6 z-30 mt-10 flex justify-end">
|
|
<button type="button" aria-label="{{ data_get($ui, 'back_to_top') }}"
|
|
title="{{ data_get($ui, 'back_to_top_short') }}"
|
|
class="pointer-events-auto inline-flex h-12 w-12 items-center justify-center rounded-full bg-zinc-950 text-white shadow-xl shadow-zinc-950/20 transition hover:-translate-y-0.5 hover:bg-secondary focus:outline-none focus:ring-2 focus:ring-secondary focus:ring-offset-2 focus:ring-offset-[#e1e5e7]"
|
|
x-show="showBackToTop" x-transition.opacity x-cloak
|
|
@click="document.getElementById('projekte')?.scrollIntoView({ behavior: 'smooth', block: 'start' })">
|
|
@svg('heroicon-o-arrow-up', 'h-5 w-5')
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section id="markt" class="section-padding bg-accent scroll-mt-24">
|
|
<div class="container-padding">
|
|
<div class="mx-auto max-w-3xl text-center">
|
|
<h2 class="text-section-title">{{ data_get($content, 'market_context.title') }}</h2>
|
|
<p class="mt-4 text-large text-muted-foreground">
|
|
{{ data_get($content, 'market_context.subtitle') }}</p>
|
|
</div>
|
|
|
|
<div class="mx-auto mt-12 grid max-w-6xl gap-6 sm:grid-cols-2 lg:grid-cols-3">
|
|
@foreach (data_get($content, 'market_context.facts', []) as $fact)
|
|
<div class="card-elevated rounded-2xl p-6">
|
|
<div
|
|
class="mb-5 inline-flex h-12 w-12 items-center justify-center rounded-full bg-secondary/10 text-secondary">
|
|
@svg('heroicon-o-' . $fact['icon'], 'h-6 w-6')
|
|
</div>
|
|
<h3 class="font-semibold text-foreground">{{ $fact['title'] }}</h3>
|
|
<p class="mt-2 text-sm leading-relaxed text-muted-foreground">{{ $fact['description'] }}
|
|
</p>
|
|
</div>
|
|
@endforeach
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section id="prozess" class="section-padding scroll-mt-24">
|
|
<div class="container-padding">
|
|
<div class="mx-auto max-w-4xl">
|
|
<div class="mb-10 text-center">
|
|
<h2 class="text-section-title">{{ data_get($content, 'process.title') }}</h2>
|
|
</div>
|
|
<div class="grid gap-5 md:grid-cols-2">
|
|
@foreach (data_get($content, 'process.steps', []) as $step)
|
|
<div class="card-elevated rounded-2xl p-6">
|
|
<div class="flex gap-5">
|
|
<span
|
|
class="flex h-12 w-12 shrink-0 items-center justify-center rounded-full bg-secondary text-lg font-bold text-white">
|
|
{{ $step['number'] }}
|
|
</span>
|
|
<div>
|
|
<h3 class="font-semibold text-foreground">{{ $step['title'] }}</h3>
|
|
<p class="mt-2 text-sm leading-relaxed text-muted-foreground">
|
|
{{ $step['description'] }}</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
@endforeach
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section id="mindset" class="section-padding scroll-mt-24" style="background: #e1e5e7;">
|
|
<div class="container-padding">
|
|
<div
|
|
class="mx-auto max-w-5xl rounded-3xl border border-white/70 bg-white/80 p-6 text-center shadow-sm backdrop-blur lg:p-10">
|
|
<h2 class="text-section-title">{{ data_get($content, 'mindset.title') }}</h2>
|
|
<div class="mt-8 grid gap-5 text-left md:grid-cols-2">
|
|
<article class="rounded-3xl border border-emerald-200/80 bg-emerald-50 p-6 shadow-sm">
|
|
<div class="flex items-center gap-3">
|
|
<span
|
|
class="inline-flex h-11 w-11 shrink-0 items-center justify-center rounded-full bg-emerald-600 text-white">
|
|
@svg('heroicon-o-check', 'h-5 w-5')
|
|
</span>
|
|
<div>
|
|
<p class="text-xs font-semibold uppercase tracking-[0.18em] text-emerald-700">
|
|
{{ data_get($ui, 'mindset_positive_pill') }}</p>
|
|
<h3 class="mt-1 text-lg font-semibold text-foreground">
|
|
{{ data_get($ui, 'mindset_positive_title') }}</h3>
|
|
</div>
|
|
</div>
|
|
<p class="mt-5 leading-relaxed text-foreground">
|
|
{{ data_get($content, 'mindset.positive') }}
|
|
</p>
|
|
</article>
|
|
|
|
<article class="rounded-3xl border border-amber-200/80 bg-amber-50 p-6 shadow-sm">
|
|
<div class="flex items-center gap-3">
|
|
<span
|
|
class="inline-flex h-11 w-11 shrink-0 items-center justify-center rounded-full bg-amber-500 text-zinc-950">
|
|
@svg('heroicon-o-exclamation-triangle', 'h-5 w-5')
|
|
</span>
|
|
<div>
|
|
<p class="text-xs font-semibold uppercase tracking-[0.18em] text-amber-700">
|
|
{{ data_get($ui, 'mindset_negative_pill') }}</p>
|
|
<h3 class="mt-1 text-lg font-semibold text-foreground">
|
|
{{ data_get($ui, 'mindset_negative_title') }}</h3>
|
|
</div>
|
|
</div>
|
|
<p class="mt-5 leading-relaxed text-foreground">
|
|
{{ data_get($content, 'mindset.negative') }}
|
|
</p>
|
|
</article>
|
|
</div>
|
|
<div class="mt-8">
|
|
<a href="/contact" class="btn-primary-accent px-8 py-4 text-lg">
|
|
{{ data_get($content, 'mindset.cta') }}
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section id="einrichtung" class="section-padding bg-accent scroll-mt-24">
|
|
<div class="container-padding">
|
|
<div class="mx-auto max-w-3xl text-center">
|
|
<h2 class="text-section-title">{{ data_get($content, 'furniture.title') }}</h2>
|
|
<p class="mt-4 text-large text-muted-foreground">{{ data_get($content, 'furniture.text') }}</p>
|
|
<div class="mt-8">
|
|
<a href="/netzwerk" class="btn-secondary-accent">
|
|
{{ data_get($content, 'furniture.button') }}
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<div id="kontakt" class="scroll-mt-24">
|
|
<livewire:web.components.sections.c-t-a-section />
|
|
</div>
|
|
|
|
<div x-show="selectedProject" x-transition.opacity x-cloak
|
|
class="fixed inset-0 z-50 overflow-y-auto bg-zinc-950/75 px-4 py-6 backdrop-blur-sm sm:px-6 lg:px-8"
|
|
role="dialog" aria-modal="true" @click.self="closeProject()">
|
|
<template x-if="selectedProject">
|
|
<div class="mx-auto max-w-6xl overflow-hidden rounded-3xl bg-background shadow-2xl">
|
|
<div
|
|
class="flex items-center justify-between gap-4 border-b border-border bg-background px-5 py-4">
|
|
<p class="text-sm font-semibold text-muted-foreground">{{ data_get($modalUi, 'header') }}</p>
|
|
<button type="button" aria-label="{{ data_get($modalUi, 'close') }}"
|
|
class="inline-flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-zinc-950 text-white transition hover:bg-secondary focus:outline-none focus:ring-2 focus:ring-secondary focus:ring-offset-2 focus:ring-offset-background"
|
|
@click="closeProject()">
|
|
@svg('heroicon-o-x-mark', 'h-5 w-5')
|
|
</button>
|
|
</div>
|
|
|
|
<div class="relative min-h-[360px] overflow-hidden bg-zinc-950">
|
|
<img :src="selectedProject.image_url" :alt="selectedProject.title"
|
|
class="absolute inset-0 h-full w-full object-cover opacity-80">
|
|
<div class="absolute inset-0 bg-gradient-to-t from-black/85 via-black/35 to-black/5"></div>
|
|
|
|
<div class="absolute bottom-0 left-0 right-0 p-6 lg:p-8">
|
|
<span class="inline-flex rounded-full px-3 py-1 text-xs font-semibold text-white"
|
|
:class="selectedProject.status_class" x-text="selectedProject.status"></span>
|
|
<h2 class="mt-4 max-w-4xl text-3xl font-bold leading-tight text-white lg:text-5xl"
|
|
x-text="selectedProject.title"></h2>
|
|
<p class="mt-2 text-lg text-white/80" x-text="selectedProject.location"></p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="grid gap-6 bg-[#e1e5e7] p-5 md:grid-cols-3 lg:p-6">
|
|
<div class="rounded-2xl bg-white/85 p-4 shadow-sm">
|
|
<p class="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
|
|
{{ data_get($modalUi, 'stat_price') }}</p>
|
|
<p class="mt-2 flex flex-wrap gap-x-1 font-semibold text-secondary"
|
|
x-html="selectedProject.price_from"></p>
|
|
</div>
|
|
<div class="rounded-2xl bg-white/85 p-4 shadow-sm">
|
|
<p class="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
|
|
{{ data_get($modalUi, 'stat_handover') }}
|
|
</p>
|
|
<p class="mt-2 font-semibold text-foreground" x-text="selectedProject.handover"></p>
|
|
</div>
|
|
<div class="rounded-2xl bg-white/85 p-4 shadow-sm">
|
|
<p class="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
|
|
{{ data_get($modalUi, 'stat_units') }}
|
|
</p>
|
|
<p class="mt-2 font-semibold text-foreground" x-text="selectedProject.units"></p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="space-y-8 p-6 lg:p-8">
|
|
<article class="max-w-5xl">
|
|
<p class="mb-4 text-sm font-semibold uppercase tracking-[0.22em] text-secondary">
|
|
{{ data_get($modalUi, 'section_investment') }}
|
|
</p>
|
|
<h3 class="text-2xl font-semibold leading-tight text-foreground lg:text-3xl"
|
|
x-text="selectedProject.short"></h3>
|
|
|
|
<blockquote
|
|
class="mt-6 border-l-4 border-secondary/60 pl-5 text-base italic leading-relaxed text-foreground/85 lg:text-lg"
|
|
x-text="selectedProject.marcel_take"></blockquote>
|
|
|
|
<template x-if="selectedProject.official_description_de">
|
|
<div class="mt-8 border-t border-border/70 pt-6">
|
|
<p
|
|
class="mb-2 text-xs font-medium uppercase tracking-[0.18em] text-muted-foreground/80">
|
|
{{ data_get($modalUi, 'official_description_label') }}
|
|
</p>
|
|
<p class="text-sm leading-relaxed text-muted-foreground"
|
|
x-text="selectedProject.official_description_de"></p>
|
|
</div>
|
|
</template>
|
|
</article>
|
|
|
|
<div x-show="selectedProject.gallery_images.length" class="space-y-4">
|
|
<div class="flex items-end justify-between gap-4">
|
|
<h4 class="text-xl font-semibold text-foreground">
|
|
{{ data_get($modalUi, 'gallery_heading') }}</h4>
|
|
<p class="text-sm text-muted-foreground"
|
|
x-text="`${selectedProject.gallery_images.length} {{ data_get($modalUi, 'gallery_count_word') }}`">
|
|
</p>
|
|
</div>
|
|
|
|
<div class="grid gap-3 sm:grid-cols-2 lg:grid-cols-3">
|
|
<template x-for="(image, index) in selectedProject.gallery_images"
|
|
:key="image">
|
|
<button type="button"
|
|
class="group/gallery overflow-hidden rounded-2xl bg-accent text-left focus:outline-none focus:ring-2 focus:ring-secondary focus:ring-offset-2 focus:ring-offset-background"
|
|
@click="openGallery(index)">
|
|
<img :src="image"
|
|
:alt="`${selectedProject.title} {{ data_get($modalUi, 'gallery_image_word') }} ${index + 1}`"
|
|
class="aspect-[16/9] w-full object-cover transition duration-500 group-hover/gallery:scale-105"
|
|
loading="lazy">
|
|
<span class="sr-only"
|
|
x-text="`${selectedProject.title} {{ data_get($modalUi, 'gallery_image_word') }} ${index + 1} {{ data_get($modalUi, 'gallery_zoom_suffix') }}`"></span>
|
|
</button>
|
|
</template>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="grid gap-8 lg:grid-cols-[0.68fr_0.32fr]">
|
|
<article class="space-y-6">
|
|
<div class="rounded-2xl border border-secondary/20 bg-secondary/5 p-5">
|
|
<h4 class="text-lg font-semibold text-foreground">
|
|
{{ data_get($modalUi, 'for_whom') }}
|
|
</h4>
|
|
<p class="mt-3 leading-relaxed text-muted-foreground"
|
|
x-text="selectedProject.buyer_profile"></p>
|
|
</div>
|
|
|
|
<div>
|
|
<h4 class="text-xl font-semibold text-foreground">
|
|
{{ data_get($modalUi, 'hard_facts') }}
|
|
</h4>
|
|
<ul class="mt-4 grid gap-3">
|
|
<template x-for="highlight in selectedProject.highlights"
|
|
:key="highlight">
|
|
<li class="flex gap-3 rounded-xl bg-accent p-4 text-muted-foreground">
|
|
@svg('heroicon-o-check-circle', 'mt-0.5 h-5 w-5 shrink-0 text-secondary')
|
|
<span x-text="highlight"></span>
|
|
</li>
|
|
</template>
|
|
</ul>
|
|
</div>
|
|
</article>
|
|
|
|
<aside class="space-y-5">
|
|
@if ($dev)
|
|
<div class="card-elevated rounded-2xl p-6">
|
|
<h4 class="font-semibold text-foreground">
|
|
{{ data_get($modalUi, 'source_heading') }}</h4>
|
|
<p class="mt-2 text-sm text-muted-foreground">
|
|
{{ data_get($modalUi, 'source_text') }}
|
|
</p>
|
|
<a x-show="selectedProject.official_url" :href="selectedProject.official_url"
|
|
target="_blank" rel="noopener"
|
|
class="mt-5 inline-flex items-center gap-2 font-semibold text-secondary hover:text-secondary/80">
|
|
{{ data_get($modalUi, 'azizi_link') }}
|
|
@svg('heroicon-o-arrow-up-right', 'h-4 w-4')
|
|
</a>
|
|
</div>
|
|
<div class="card-elevated rounded-2xl p-6">
|
|
<a :href="selectedProject.detail_url"
|
|
class="inline-flex items-center gap-2 text-sm font-semibold text-muted-foreground hover:text-foreground">
|
|
{{ data_get($modalUi, 'seo_link') }}
|
|
@svg('heroicon-o-arrow-right', 'h-4 w-4')
|
|
</a>
|
|
</div>
|
|
@endif
|
|
|
|
|
|
|
|
<div class="card-elevated rounded-2xl p-6">
|
|
<h4 class="font-semibold text-foreground">
|
|
{{ data_get($modalUi, 'next_step_heading') }}</h4>
|
|
<p class="mt-2 text-sm text-muted-foreground">
|
|
{{ data_get($modalUi, 'next_step_text') }}
|
|
</p>
|
|
</div>
|
|
</aside>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="border-t border-border px-6 py-8 lg:px-8 lg:py-10">
|
|
<div
|
|
class="mx-auto max-w-3xl rounded-2xl border border-secondary/20 bg-secondary/5 p-5 md:p-8">
|
|
<div class="text-center">
|
|
<p class="mb-3 text-sm font-semibold uppercase tracking-[0.22em] text-secondary">
|
|
{{ data_get($modalUi, 'request_eyebrow') }}</p>
|
|
<h3 class="text-2xl font-semibold text-foreground lg:text-3xl">
|
|
{{ data_get($modalUi, 'request_heading') }}</h3>
|
|
<p class="mt-3 text-muted-foreground">
|
|
{{ data_get($modalUi, 'request_text') }}
|
|
</p>
|
|
</div>
|
|
|
|
<div class="mt-8">
|
|
<livewire:web.components.sections.immobilien-contact-form projectSlug=""
|
|
projectTitle="" :showInterest="false" :submitLabel="data_get($modalUi, 'request_submit')" :syncFromAlpineProject="true"
|
|
wire:key="azizi-project-modal-contact-form" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<template x-teleport="body">
|
|
<div x-show="galleryLightboxIndex !== null" x-transition.opacity x-cloak
|
|
class="fixed inset-0 z-[60] isolate bg-black/92" role="dialog" aria-modal="true"
|
|
aria-label="{{ data_get($lightboxUi, 'label') }}" @click.self="closeGallery()">
|
|
<div class="absolute inset-0 z-0 flex items-center justify-center p-4 sm:p-8">
|
|
<img x-show="galleryLightboxIndex !== null"
|
|
:src="selectedProject.gallery_images[galleryLightboxIndex]"
|
|
:alt="`${selectedProject.title} {{ data_get($modalUi, 'gallery_image_word') }} ${galleryLightboxIndex + 1}`"
|
|
class="max-h-[85vh] max-w-[92vw] rounded-xl object-contain shadow-2xl"
|
|
loading="lazy">
|
|
</div>
|
|
|
|
<button type="button" aria-label="{{ data_get($lightboxUi, 'close') }}"
|
|
class="absolute left-auto right-5 top-5 z-10 inline-flex h-11 w-11 items-center justify-center rounded-full border border-white/20 bg-white/10 text-white transition hover:bg-white/20 focus:outline-none focus:ring-2 focus:ring-white/70"
|
|
style="position: absolute; left: auto; right: 1.25rem;" @click="closeGallery()">
|
|
@svg('heroicon-o-x-mark', 'h-5 w-5')
|
|
</button>
|
|
|
|
<button type="button" aria-label="{{ data_get($lightboxUi, 'previous') }}"
|
|
x-show="selectedProject.gallery_images.length > 1"
|
|
class="absolute left-5 top-1/2 z-10 inline-flex h-12 w-12 -translate-y-1/2 items-center justify-center rounded-full border border-white/20 bg-white/10 text-white transition hover:bg-white/20 focus:outline-none focus:ring-2 focus:ring-white/70 sm:h-14 sm:w-14"
|
|
style="position: absolute; left: 1.25rem; right: auto;"
|
|
@click="showPreviousGalleryImage()">
|
|
@svg('heroicon-o-chevron-left', 'h-6 w-6')
|
|
</button>
|
|
|
|
<button type="button" aria-label="{{ data_get($lightboxUi, 'next') }}"
|
|
x-show="selectedProject.gallery_images.length > 1"
|
|
class="absolute left-auto right-5 top-1/2 z-10 inline-flex h-12 w-12 -translate-y-1/2 items-center justify-center rounded-full border border-white/20 bg-white/10 text-white transition hover:bg-white/20 focus:outline-none focus:ring-2 focus:ring-white/70 sm:h-14 sm:w-14"
|
|
style="position: absolute; left: auto; right: 1.25rem;"
|
|
@click="showNextGalleryImage()">
|
|
@svg('heroicon-o-chevron-right', 'h-6 w-6')
|
|
</button>
|
|
|
|
<div
|
|
class="absolute bottom-5 left-1/2 z-10 -translate-x-1/2 rounded-full bg-white/10 px-4 py-2 text-sm font-medium text-white/75">
|
|
<span x-text="galleryLightboxIndex + 1"></span>
|
|
<span>/</span>
|
|
<span x-text="selectedProject.gallery_images.length"></span>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
</div>
|
|
</template>
|
|
</div>
|
|
</main>
|
|
|
|
<livewire:web.components.ui.footer />
|
|
</div>
|
|
@endsection
|