@php
use App\Helpers\SeoHelper;
$currentLocale = app()->getLocale();
$currentLanguage = config('seo.languages.' . $currentLocale, config('seo.languages.en'));
$siteUrl = config('seo.site_url', url('/'));
$siteName = SeoHelper::decodePlainText(config('seo.site_name', __('messages.meta.author')));
$defaultDescription = SeoHelper::decodePlainText(__('messages.meta.description'));
$defaultKeywords = SeoHelper::decodePlainText(__('messages.meta.keywords'));
// Helper function to generate localized routes (English has no prefix)
$localizedRoute = function($routeName, $params = []) use ($currentLocale) {
return SeoHelper::localizedRoute($routeName, $params, $currentLocale);
};
// Get dynamic SEO data from views (default title translated)
$pageTitle = SeoHelper::decodePlainText(View::getSection('title', $siteName . ' - ' . __('messages.meta.marketing_agency')));
$pageDescription = SeoHelper::decodePlainText(View::getSection('meta_description', $defaultDescription));
$pageKeywords = SeoHelper::decodePlainText(View::getSection('meta_keywords', $defaultKeywords));
$pageImage = View::getSection('og_image', asset('images/og-default.jpg'));
// Absolute URL required for WhatsApp, Twitter, Facebook etc.
$pageImageUrl = (str_starts_with($pageImage, 'http') || str_starts_with($pageImage, '//')) ? $pageImage : url($pageImage);
$pageType = View::getSection('og_type', 'website');
$canonicalUrl = View::getSection('canonical', SeoHelper::getCanonicalUrl());
$robots = View::getSection('robots', 'index, follow');
if ($currentLocale !== 'en' && !SeoHelper::hasLocaleTranslationsForIndexing($currentLocale)) {
$robots = 'noindex, follow';
}
@endphp
{{-- Security & Performance Headers --}}
{{-- Primary Meta Tags --}}
{{ $pageTitle }}
{{-- Per-locale geo: /pt → Portugal, /fr → France, etc. English (/) = none (international) --}}
@if(!empty($geo_region))
@if(!empty($geo_position))
@endif
@endif
{{-- Canonical URL --}}
{{-- Hreflang Tags for Multilingual SEO --}}
{!! SeoHelper::generateHreflangTags() !!}
{{-- Open Graph / Facebook (use canonical URL so shares point to preferred version) --}}
@foreach(array_intersect_key(config('seo.languages', []), array_flip(config('markets.enabled', ['en', 'us', 'pt', 'br', 'es', 'fr']))) as $locale => $lang)
@if($locale !== $currentLocale && !empty($lang['og_locale']))
@elseif($locale !== $currentLocale)
@endif
@endforeach
{{-- Twitter Card (use canonical URL for consistency) --}}
{{-- Favicon & App Icons --}}
{{-- Resource Hints for Performance --}}
{{-- Preload Critical Resources --}}
{{-- Critical CSS - Inlined for fastest FCP/LCP --}}
{{-- TailwindCSS CDN --}}
{{-- Custom Tailwind Config - light mode only, dark variant disabled --}}
{{-- Custom Styles --}}
@stack('styles')
@stack('head')
@stack('meta')
@if(!empty($dynamicNavEnabled))
@endif
{{-- Organization Schema --}}
{{-- WebSite Schema --}}
{{-- Site Navigation Schema (helps Google show sitelinks) --}}
@php $navSchema = SeoHelper::generateSiteNavigationSchema(); @endphp
@if(!empty($navSchema))
@endif
{{-- Page-specific Schema --}}
@stack('schema')
@if(!empty($footerBreadcrumbs) && count($footerBreadcrumbs) > 0)
@php
$breadcrumbSchemaItems = array_map(function ($item) {
return ['name' => $item['name'], 'url' => $item['url'] ?? SeoHelper::getCanonicalUrl()];
}, $footerBreadcrumbs);
@endphp
@endif
{{-- Microsoft Clarity --}}
@if(app()->environment('production'))
@endif
{{-- Google Analytics (gtag.js) --}}
@if(app()->environment('production'))
@endif
@php
// Show banner only when: not dismissed AND browser preferred language differs from current site
$locale = app()->getLocale();
$supportedLocales = config('markets.enabled', ['en', 'us', 'pt', 'br', 'es', 'fr']);
$browserPreferred = $supportedLocales ? request()->getPreferredLanguage($supportedLocales) : null;
$browserMatchesSite = $browserPreferred !== null && (
$browserPreferred === $locale
|| ($locale === 'en' && in_array($browserPreferred, ['en', 'us'], true))
|| (in_array($locale, ['pt', 'br'], true) && in_array($browserPreferred, ['pt', 'br'], true))
);
$showRegionBanner = !request()->cookie('region_banner_dismissed') && ($browserPreferred !== null && !$browserMatchesSite);
@endphp
{{-- Skip to Content Link for Accessibility (WCAG 2.4.1) --}}
{{ __('messages.accessibility.skip_to_content') }}
{{-- Banner + Nav in one sticky block so they never misalign --}}
@if(!empty($dynamicNavEnabled))
@include('components.dynamic-navigation.production-shell', [
'navState' => $navState ?? null,
'megaNavData' => $megaNavData ?? null,
])
@endif
@stack('nav-overlay')
{{-- Main Content --}}
@yield('content')
{{-- Footer --}}
@include('components.footer')
{{-- Back to Top Button (Accessibility) --}}
{{-- Main Scripts - Deferred for Performance --}}
{{-- JavaScript Translations --}}
{{-- Lead Tracking Script - Deferred (disabled when leads/contact are paused) --}}
@unless(config('leads.paused', false))
@endunless
{{-- Service Worker Registration for Caching --}}
@stack('scripts')
@if(!empty($dynamicNavEnabled))
@if(($navState['mode'] ?? 'default') === 'context')
@endif
@endif
{{-- Prefetch likely next pages --}}