@use('Core\Contracts\Clock') @use('Core\Localization\Locales') @use('Illuminate\Support\Facades\Vite') @use('Layout\Engine\A11yPreferences') @use('Layout\Engine\LayoutPreset') @use('Layout\Engine\SlotRegistry') @use('Layout\Engine\ThemeResolver') @use('Services\Layout\Contracts\LayoutProfileReader') @props([ 'title' => null, 'description' => null, 'preset' => 'padrao', 'canonical' => null, 'robots' => 'index, follow', 'image' => null, 'breadcrumbs' => [], 'schemas' => [], ]) @php $presetEnum = LayoutPreset::tryFrom($preset) ?? LayoutPreset::PADRAO; $regions = $presetEnum->config(); $a11y = A11yPreferences::fromRequest(request()); $slots = app(SlotRegistry::class); $layout = app(LayoutProfileReader::class); $currentYear = app(Clock::class)->now()->format('Y'); $routeName = request()->route()?->getName(); // Região existe no preset **e** tem conteúdo (provedor de slot **ou** widget do perfil): // regiões vazias colapsam (sem buraco no grid). $hasLeft = $regions->hasLeft && ($slots->has('main.left') || $layout->hasPlacements('main.left', $routeName)); $hasRight = $regions->hasRight && ($slots->has('main.right') || $layout->hasPlacements('main.right', $routeName)); @endphp attributes() as $a11yAttribute => $a11yValue) {{ $a11yAttribute }}="{{ $a11yValue }}" @endforeach > {{-- Sem ``: token por request no HTML público varia o corpo (quebra `ETag`/cache) e abre sessão anônima — ADR-022. As páginas com formulário `POST` (LGPD) usam `@csrf` (input oculto), que não depende desta meta. --}} @include('portal::partials.metadata', [ 'title' => $title, 'description' => $description, 'canonical' => $canonical, 'robots' => $robots, 'image' => $image, 'schemas' => $schemas, 'breadcrumbs' => $breadcrumbs, ]) {{-- Google Analytics — opt-in: só emite quando há ID configurado (ADR-002). --}} @include('portal::partials.analytics') {{-- Preload da tipografia de conteúdo (ADR-011). --}} @vite(['src/layout/Portal/Assets/css/app.css', 'src/layout/Portal/Assets/js/app.js']) {{-- Tema do tenant (painel de suporte): só existe quando há overrides; nunca inline (ADR-022). --}} @if (app(ThemeResolver::class)->hasConfiguredOverrides()) @endif @stack('styles') @include('portal::partials.skip-links')
@if ($regions->showHeader) @include('portal::partials.header') @endif @if ($regions->showMainHeader) @include('portal::regions.main-header', ['breadcrumbs' => $breadcrumbs]) @endif
@if ($hasLeft) @endif
{{-- Slots editoriais antes/depois do conteúdo (banners/destaques — ADR-016). Slot vazio não emite nada (o componente só renderiza widget resolvido). --}} {{ $slot }}
@if ($hasRight) @endif
@if ($regions->showMainFooter) @include('portal::regions.main-footer') @endif @if ($regions->showFooter) @include('portal::partials.footer', ['currentYear' => $currentYear]) @endif
@stack('scripts')