@php $sharedBranding = data_get($page ?? [], 'props.branding', []); $siteTitle = data_get($sharedBranding, 'site_title', config('branding.site_title', config('app.name', 'Pitchbar'))); $customFavicon = data_get($sharedBranding, 'favicon_url'); $initialFavicon = $customFavicon ?: asset('favicon.ico'); $initialTouchIcon = $customFavicon ?: asset('apple-touch-icon.png'); // SEO payload — per-page seo[] from the controller, or a sane // fallback so every render gets + canonical // + Open Graph + Twitter Card + JSON-LD even when a page didn't // declare its own. Pure-PHP, hot-path safe. $seo = data_get($page ?? [], 'props.seo') ?: \App\Support\SeoMeta::defaults(); $seoTitle = (string) ($seo['title'] ?? $siteTitle); $seoDescription = (string) ($seo['description'] ?? ''); $seoCanonical = (string) ($seo['canonical'] ?? ''); $seoSiteName = (string) ($seo['site_name'] ?? $siteTitle); $seoImage = $seo['image_url'] ?? null; $seoTwitterCard = (string) ($seo['twitter_card'] ?? 'summary_large_image'); $seoTwitterHandle = $seo['twitter_handle'] ?? null; $seoNoindex = (bool) ($seo['noindex'] ?? false); $seoJsonLd = (array) ($seo['json_ld'] ?? []); // Resolve locale metadata once per render so , lang // attributes, and the locale picker can all read from the same // source without re-instantiating the catalog lookup three times. $_localeEntry = \App\Services\I18n\LocaleCatalog::entryFor(app()->getLocale()); @endphp ($appearance ?? 'system') == 'dark'])> {{-- We ship our own translations via /settings/locale + the geo-suggested banner. Browser auto-translate (Chrome's Google Translate prompt, Edge Translator) competes with our React render — once it rewrites the DOM, our useT() updates stop applying because the text nodes have been replaced. `notranslate` tells the browser to leave the page alone. --}} {{-- SEO --}} @if($seoDescription !== '') @endif @if($seoCanonical !== '') @endif @if($seoNoindex) @endif {{-- Open Graph --}} @if($seoDescription !== '') @endif @if($seoCanonical !== '') @endif @if($seoImage) @endif {{-- Twitter Card --}} @if($seoDescription !== '') @endif @if($seoImage) @endif @if($seoTwitterHandle) @endif {{-- JSON-LD structured data — Organization on every page, plus per-route blocks (SoftwareApplication on home, FAQPage from buyer-edited content, BreadcrumbList on docs). --}} @foreach($seoJsonLd as $jsonLdBlock) @endforeach {{-- Inline script to detect system dark mode preference and apply it immediately --}} {{-- Inline style to set the HTML background color based on our theme in app.css --}} {{-- D1: PWA manifest + theme-color so installed admins look native on mobile + desktop. The manifest is generated dynamically so the white-label site title flows through (operators rebranding the site don't ship Pitchbar's name to install prompts). --}} {{-- Geist (Vercel's typeface) served via Bunny Fonts — applies to admin + customer + auth + marketing because this is the only root blade template. --}} @fonts @viteReactRefresh @vite(['resources/css/app.css', 'resources/js/app.tsx', "resources/js/pages/{$page['component']}.tsx"]) {{ $seoTitle }} @php $component = $page['component'] ?? null; $isMarketingComponent = $component === 'welcome' || str_starts_with((string) $component, 'marketing/') || str_starts_with((string) $component, 'marketing-themes/'); // Auth check is the safety net — even if a future page is // mis-categorised as "marketing", the demo widget never // mounts for authed admin / customer surfaces. A signed-in // workspace owner sitting on /dashboard should never see // their own marketing site's demo bot watching them. $isAuthenticated = auth()->check(); // First-paint emission uses the same resolver the Inertia // shared prop calls, so Blade and React agree on which // agent should mount. After first paint, the React-side // mount component (resources/js/components/marketing-widget-mount.tsx) // owns the script tag — it watches the shared prop and // tears down / remounts on changes so the marketing tab // doesn't go stale when the operator toggles the setting. $marketingWidgetPayload = ($isMarketingComponent && ! $isAuthenticated) ? \App\Support\MarketingWidget::payload($isAuthenticated) : ['enabled' => false, 'agent_id' => null, 'is_demo' => false, 'version' => 'dev', 'src' => '']; @endphp @if($marketingWidgetPayload['enabled']) {{-- data-marketing-widget marks the tag as React-managed so the mount component can find + replace it on prop change. data-demo="true" renders a "Demo" pill so reviewers / visitors can tell this is a sandbox. Auth-gated above so a signed-in admin never sees their own marketing site's widget watching them. --}} @endif