{{-- Layout de páginas de servicio — consume UN array $serviceData definido al inicio de cada vista de servicio (services///main.blade.php) y le reparte a cada componente interno su key correspondiente. La ESTRUCTURA (orden y componentes) es la del mockup aprobado (service-mockup.blade.php, que queda como REFERENCIA visual — la data quemada de ahí ahora vive en la página de paver-driveways como array). Condicionales: cada sección se renderiza SOLO si su key existe en el array (@isset). Los sub-elementos opcionales dentro de una sección (badge, intro, checklist, footerContent, background, cta) usan `?? default` — los propios componentes ya toleran listas vacías / null. Shape de $serviceData (todas las secciones opcionales salvo hero): hero: image, alt, title(HTML), subtitle, badge? transform: eyebrow, title(HTML), paragraphs[], images[3], cta?=true → x-home.why-choose-us installation: eyebrow, title(HTML), paragraphs[], images[], background? → x-home.centered-photo-feature whyChoose: eyebrow, lead+emph | title(HTML), paragraphs[], checklistHeading, checklist[], background? → x-home.pitch-with-checklist features: eyebrow, title(HTML), intro?, items[{image,alt,title,body}] → x-home.centered-feature-list renovation: eyebrow, title(HTML), paragraphs[], images[], checklistHeading?, checklist[]? → x-home.centered-photo-feature design: eyebrow, title(HTML), paragraphs[], checklistHeading, checklist[], background? → x-home.pitch-with-checklist outdoorMatch: eyebrow, title(HTML), image, alt, paragraphs[], checklistHeading?, checklist[], footerContent? → x-home.image-with-checklist Las rutas de imagen del array son paths de resources/ (strings) — Vite::asset() se resuelve ACÁ, la data no conoce URLs compiladas. ANCLAS: cada sección lleva un id fijo derivado de su key del array, para poder nombrarlas y linkearlas por URL (#hero, #transform, #installation, #why-choose, #features, #renovation, #design, #outdoor-match). Se definen UNA vez acá, así que valen igual para las páginas generales de servicio y las de servicio×localidad. El id viaja como atributo al
raíz de cada componente vía $attributes. --}} @extends('layouts.landing') @php // URL de las imágenes de sección: en páginas de LOCALIDAD el path lleva el slug // de la ciudad (mismo archivo físico detrás, vía ImageAliasController) para que // la foto aporte señal SEO local; en la general, el path del servicio. Las // imágenes que siguen en resources/ (slots `pending`, features) caen solas al // Vite::asset() de siempre. Ver App\Services\ServiceImageUrl. $imageCity = $localityCity ?? null; $imageUrl = fn(string $path) => \App\Services\ServiceImageUrl::resolve($path, $imageCity); @endphp @section('hero') {!! $serviceData['hero']['title'] !!} @endsection @section('content') {{-- 1. Intro con collage de 3 fotos (mockup sección 1). --}} @isset($serviceData['transform']) @php $block = $serviceData['transform']; @endphp
{!! $block['title'] !!} @foreach ($block['paragraphs'] as $paragraph)

$loop->first, 'mt-4' => !$loop->first])> {!! $paragraph !!}

@endforeach @if ($block['cta'] ?? true) @endif
@endisset {{-- 2. Foto-feature centrado (mockup sección 2). --}} @isset($serviceData['installation']) @php $block = $serviceData['installation']; @endphp {!! $block['title'] !!} @foreach ($block['paragraphs'] as $paragraph)

{!! $paragraph !!}

@endforeach
@endisset {{-- 3. Pitch con checklist (mockup sección 3). --}} @isset($serviceData['whyChoose']) @php $block = $serviceData['whyChoose']; @endphp @isset($block['title']) {!! $block['title'] !!} @endisset @foreach ($block['paragraphs'] as $paragraph)

$loop->first, 'mt-4' => !$loop->first, 'md:mb-12' => $loop->last, ])> {!! $paragraph !!}

@endforeach
@endisset {{-- 4. Lista de features con foto (mockup sección 4). --}} @isset($serviceData['features']) @php $block = $serviceData['features']; @endphp {!! $block['title'] !!} @endisset {{-- 5. Foto-feature con checklist (mockup sección 5). v2 acepta contentSections (bloques title+body extra antes del checklist-box) — usado por pool-renovation. --}} @isset($serviceData['renovation']) @php $block = $serviceData['renovation']; @endphp {!! $block['title'] !!} @foreach ($block['paragraphs'] as $paragraph)

{!! $paragraph !!}

@endforeach
@endisset {{-- 6. Pitch con checklist, variante de diseño (mockup sección 6). --}} @isset($serviceData['design']) @php $block = $serviceData['design']; @endphp @isset($block['title']) {!! $block['title'] !!} @endisset @foreach ($block['paragraphs'] as $paragraph)

$loop->last, ])> {!! $paragraph !!}

@endforeach
@endisset {{-- 7. Imagen con checklist a 2 columnas (mockup sección 7). --}} @isset($serviceData['outdoorMatch']) @php $block = $serviceData['outdoorMatch']; @endphp {!! $block['title'] !!} @foreach ($block['paragraphs'] as $paragraph)

{!! $paragraph !!}

@endforeach
@endisset {{-- Páginas servicio×localidad: si el data file trae `localityIntro`, se muestra el bloque intro+mapa de la ciudad (content izq / Google Map der) EN LUGAR de Service Areas. PILOTO: hoy solo pool-renovation/boca-raton tiene la key, así que solo esa combinación estrena el bloque; el resto sigue con Service Areas. Cuando se propaguen los 220 data files, este bloque las cubre a todas. --}} @if (isset($localityService) && isset($serviceData['localityIntro'])) @else {{-- Service Areas con interlinking. Este layout lo comparten las páginas de servicio GENERALES (services.*) y las de LOCALIDAD (service-areas.*). $contextService (del View::composer) es el ServiceItem activo en ambos casos → las ciudades linkean a sus derivaciones /-. En páginas de localidad, $localityCity oculta la ciudad actual, y el flag de config apaga toda la sección (solo en localidad; el general no lleva $localityService). --}} @if (!isset($localityService) || config('company.show_service_areas_on_locality_pages')) @endif @endif @endsection {{-- FAQs: última sección de la página, pegada al footer (slot `pre-footer` de layouts/landing). Va acá y NO en @section('content') porque desde ahí quedaría por encima de las globales Reviews + Quote. Declarado UNA vez en el layout: lo heredan las 11 páginas de servicio generales (`.main`) y las 220 de servicio×localidad (`.area`). Mismo dato que alimenta el nodo FAQPage del JSON-LD (PageFaqMap → $seoPage['faqs']), así el schema nunca declara preguntas que la página no muestra. El componente se auto-oculta cuando la vista no tiene FAQs en el mapa — hoy es el caso de las de localidad, que reciben las suyas en la fase 2 sin tocar este layout. --}} @section('pre-footer') @endsection