b2in/resources/views/web/layouts/web-master.blade.php

185 lines
8.1 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
@php
// Farbpalette der Interior-Welt (Nachtrag 18): ohne Schalter setzt der Server die Klasse aus
// config('app.palette'); mit Schalter entscheidet das Skript im <head> anhand des localStorage.
$paletteFixed = config('app.theme', 'b2in') === 'b2in'
&& b2in_world() === 'interior'
&& ! config('app.palette_switch')
&& b2in_palette() === ''
&& config('app.palette') === 'modern';
@endphp
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}"{!! $paletteFixed ? ' class="palette-modern"' : '' !!}>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="csrf-token" content="{{ csrf_token() }}">
@unless (config('app.indexable'))
{{-- Vorschau-/Testinstanz: darf nicht in den Suchindex. --}}
<meta name="robots" content="noindex, nofollow">
@endunless
<title>@yield('title', $domainName ?? config('app.name', 'Laravel'))</title>
<meta name="description" content="@yield('meta_description', 'B2in Interior verbindet starke Einrichtungsmarken mit persönlicher Beratung – von der Maßanfertigung bis zur vollständigen Ausstattung für Zuhause und Projekte.')">
@hasSection('meta_image')
<meta property="og:image" content="@yield('meta_image')">
@else
<meta property="og:image" content="{{ asset('img/assets/b2in-og-default.jpg') }}">
@endif
<meta property="og:title" content="@yield('title', $domainName ?? config('app.name', 'Laravel'))">
<meta property="og:description" content="@yield('meta_description', 'B2in Interior verbindet starke Einrichtungsmarken mit persönlicher Beratung – von der Maßanfertigung bis zur vollständigen Ausstattung für Zuhause und Projekte.')">
<meta property="og:type" content="website">
<meta property="og:url" content="{{ url()->current() }}">
<link rel="canonical" href="{{ url()->current() }}">
<meta property="og:locale" content="de_DE">
<meta name="twitter:card" content="summary_large_image">
@stack('meta')
<!-- Favicons (wie Backend) -->
<link rel="apple-touch-icon" sizes="57x57" href="/favicon/apple-icon-57x57.png">
<link rel="apple-touch-icon" sizes="60x60" href="/favicon/apple-icon-60x60.png">
<link rel="apple-touch-icon" sizes="72x72" href="/favicon/apple-icon-72x72.png">
<link rel="apple-touch-icon" sizes="76x76" href="/favicon/apple-icon-76x76.png">
<link rel="apple-touch-icon" sizes="114x114" href="/favicon/apple-icon-114x114.png">
<link rel="apple-touch-icon" sizes="120x120" href="/favicon/apple-icon-120x120.png">
<link rel="apple-touch-icon" sizes="144x144" href="/favicon/apple-icon-144x144.png">
<link rel="apple-touch-icon" sizes="152x152" href="/favicon/apple-icon-152x152.png">
<link rel="apple-touch-icon" sizes="180x180" href="/favicon/apple-icon-180x180.png">
<link rel="icon" type="image/png" sizes="192x192" href="/favicon/android-icon-192x192.png">
<link rel="icon" type="image/png" sizes="96x96" href="/favicon/favicon-96x96.png">
<link rel="icon" type="image/png" sizes="32x32" href="/favicon/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/favicon/favicon-16x16.png">
<link rel="shortcut icon" href="{{ asset(\App\Helpers\ThemeHelper::getFaviconPath()) }}">
<link rel="manifest" href="/favicon/manifest.json">
<meta name="msapplication-TileColor" content="#f7f4ef">
<meta name="msapplication-TileImage" content="/favicon/ms-icon-144x144.png">
<meta name="theme-color" content="#f7f4ef">
@php
$theme = config('app.theme', 'b2in');
// Farb-Schalter nur auf den Interior-Seiten von b2in, solange die Palette abgestimmt wird.
$showPaletteSwitch = $theme === 'b2in' && b2in_world() === 'interior' && config('app.palette_switch');
// Entwurf /entwurf (Nachtrag 19): feste Palette „greige“ am Body, kein Browser-Schalter.
$paletteDraft = b2in_palette() === 'greige';
$hideAnnouncementBar = trim($__env->yieldContent('announcement_bar', 'on')) === 'off';
@endphp
@if ($showPaletteSwitch && ! $paletteDraft)
{{-- Läuft vor dem Stylesheet: setzt die gemerkte Palette, bevor die Seite gezeichnet wird.
?palette=modern|classic in der URL überschreibt und merkt sich die Wahl; ohne
gemerkte Wahl gilt config('app.palette'). --}}
<script>
(function () {
var fromUrl = new URLSearchParams(window.location.search).get('palette');
var palette = null;
try {
if (fromUrl === 'modern' || fromUrl === 'classic') {
localStorage.setItem('b2in-palette', fromUrl);
}
palette = localStorage.getItem('b2in-palette');
} catch (e) {
palette = fromUrl;
}
if (palette === null) {
palette = @js(config('app.palette'));
}
if (palette === 'modern') {
document.documentElement.classList.add('palette-modern');
}
})();
</script>
@endif
@vite([
\App\Helpers\ThemeHelper::getThemeCssPath(),
'resources/js/app.js'
], 'build/' . $theme)
<!-- Sticky Header Script -->
<script>
document.addEventListener('DOMContentLoaded', function() {
const topbar = document.getElementById('topbar');
const header = document.getElementById('header');
if (!topbar || !header) return;
let topbarHeight = topbar.offsetHeight;
let isHeaderSticky = false;
let ticking = false;
function updateHeaderPosition() {
const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
if (scrollTop >= topbarHeight && !isHeaderSticky) {
header.classList.remove('header-normal');
header.classList.add('header-sticky');
isHeaderSticky = true;
} else if (scrollTop < topbarHeight && isHeaderSticky) {
header.classList.remove('header-sticky');
header.classList.add('header-normal');
isHeaderSticky = false;
}
ticking = false;
}
updateHeaderPosition();
window.addEventListener('scroll', function() {
if (!ticking) {
requestAnimationFrame(updateHeaderPosition);
ticking = true;
}
}, { passive: true });
window.addEventListener('resize', function() {
topbarHeight = topbar.offsetHeight;
updateHeaderPosition();
}, { passive: true });
});
</script>
{{-- Gilt für alle Seiten: das Terminanfrage-Widget im Layout nutzt x-cloak, die einzelnen
Seiten bringen die Regel bisher nur teilweise selbst mit. --}}
<style>
[x-cloak] {
display: none !important;
}
</style>
<!-- Additional Styles -->
@stack('styles')
</head>
<body class="antialiased bg-background text-foreground world-{{ b2in_world() }}{{ $paletteDraft ? ' palette-greige' : '' }}">
{{-- GTM noscript (nur bei GTM-Nutzung) --}}
<x-cookie-consent::gtm-noscript />
{{-- Ankündigungsleiste – eine Seite kann sie mit @section('announcement_bar', 'off') abschalten --}}
@unless ($hideAnnouncementBar)
<livewire:web.components.ui.announcement-bar />
@endunless
{{-- TopBar (Backup: Sprachwechsel & Social Icons – folgt später) --}}
{{-- <livewire:web.components.ui.top-bar /> --}}
@yield('content')
{{-- Terminanfrage: schwebend unten rechts, auf allen Seiten --}}
<livewire:web.components.ui.appointment-widget />
@if ($showPaletteSwitch)
<x-palette-switch :draft="$paletteDraft" />
@endif
{{-- Cookie Consent Manager (vor Livewire-Scripts) --}}
<x-cookie-consent::manager />
<!-- Additional Scripts -->
@stack('scripts')
</body>
</html>