# Producto: Construction

> **Estado:** ✅ Production-ready (validado 2026-04-28)
> **Tenant demo público:** `bp-demo-construction`
> **Última auditoría:** 2026-04-28 — paridad admin↔front 100% (64/64 keys)
> **2do producto certificado** después de law-firm-digital.

---

## 1. Identidad

| Campo | Valor |
|-------|-------|
| **Core slug** | `construction` |
| **Demo asignado** | `demo-construction` |
| **Tagline** | Constructora |
| **Descripción** | Empresa constructora con experiencia en proyectos residenciales, comerciales e industriales |
| **Schema.org type** | `HomeAndConstructionBusiness` |
| **Idioma SEO** | `es_AR` |
| **Demo de referencia** | https://constructoragama.com.ar (referente visual del template Porto) |
| **Industria (alias-matrix)** | `construction` |

---

## 2. Catálogo — shop products que mapean a este core

Definido en `database/seeders/products/catalog.json`:

| Shop slug | Nombre comercial |
|-----------|------------------|
| `construction` | Construction |
| `construction-company` | Construction Company |
| `construction-classic` | Construction Classic |

→ Cualquiera de estos 3 slugs en `bewpro:new` resuelve al mismo core preset.

---

## 3. Módulos activos

8 módulos totales (5 declarados + 3 auto-activos del sistema):

| Módulo | Header label | Header | Footer | Origen |
|--------|--------------|--------|--------|--------|
| `services` | "Servicios" | ✅ | ✅ | declarado |
| `projects` | "Obras" | ✅ | ✅ | declarado |
| `gallery` | — | ❌ | ✅ | declarado |
| `blog` | "Novedades" | ✅ | ✅ | declarado |
| `faqs` | — | ❌ | ✅ | declarado |
| `about` | "Nosotros" | ✅ | ✅ | auto (cd-base) |
| `contact` | "Contacto" | ✅ | ✅ | auto (cd-base) |
| `project-setup` | — | — | — | auto (sistema) |

Header titles overrides definidos en `seeds/config-construction.json` → bloque `footer.navegacion_principal.*.title`.

---

## 4. Branding

### Brand defaults

Definidos en `database/seeders/products/core/construction.json` → `brand_defaults`. **Paleta derivada del logo del producto** (badge estrella burgundy + wordmark rosa pastel):

| Slot | Hex | Uso visual |
|------|-----|-----------|
| `primary` | `#651A38` | **Burgundy oscuro** del badge estrella del logo — CTAs, contadores, highlights, marker del mapa |
| `secondary` | `#F2B5BA` | **Rosa pastel** del wordmark "CONSTRUCTION" — acentos, badges suaves |
| `tertiary` | `#FBEEEF` | Rosa muy claro — superficies (faq-question, badge-count, card-header, fondos suaves) |
| `quaternary` | `#2D0B19` | Burgundy ultra dark casi negro — overlays profundos |
| `dark` | `#212529` | Gris oscuro neutral — texto principal |
| `light` | `#FFFFFF` | Blanco — fondos, texto sobre dark/burgundy |

**Racional**: el logo del producto (`logo.png`, `logo-2.png`, `logo-alternative.png`) usa burgundy + rosa pastel — paleta femenina/contemporánea que rompe con el cliché rojo terracota + dorado de las constructoras tradicionales. El brand_defaults se alinea al logo para evitar clash visual al provisionar.

`SkinColorService` deriva ~120 variables CSS de estos 6 hex (escalas hover/lighter/darker, opacities, etc.). Las superficies del demo (`demo-construction.css`) usan `var(--tertiary)` (no hex hardcoded) → cualquier `/brand-kit` del cliente repinta todo en runtime.

### Fonts

| Slot | Font | Pesos | Uso |
|------|------|-------|-----|
| `primary` | Poppins | 300, 400, 500, 600, 700 | Body + headings (acompaña la geometría del wordmark) |
| `secondary` | Poppins | 700, 800 | Big text del hero |
| `tertiary` | Caveat | 400, 700 | Decorativa (testimonios, frases destacadas, alternative-font-4) |

**Cambio respecto al template Porto**: el demo original usaba "Shadows Into Light" (manuscrita rígida tipo letra de niño) — reemplazada por **Caveat** (manuscrita más fluida y contemporánea, mejor match con el espíritu friendly del logo).

### Logo pack

Asignado vía `brand_defaults.logo_pack = "construction"` → resuelve a `public/cd-project/assets/construction/`.

| Asset | Archivo | Uso |
|-------|---------|-----|
| `main_logo` | `logo.png` | Header light |
| `main_logo_sticky` | `logo.png` | Header sticky |
| `footer_logo` | `logo-alternative.png` | Footer dark |
| `loader_logo` | `logo.png` | Loader inicial |
| `favicon` | `favicon.ico` + 4 PNGs | Browser tab |
| `apple_touch_icon` | `apple-touch-icon.png` | iOS home |
| `manifest` | `site.webmanifest` | PWA |

---

## 5. Asset pack físico

`public/cd-project/assets/construction/` — 10 archivos:

```
logo.png                  logo-alternative.png       logo-2.png
favicon.ico               favicon-16x16.png          favicon-32x32.png
apple-touch-icon.png      android-chrome-192x192.png android-chrome-512x512.png
site.webmanifest
```

### Imágenes del demo (no editables, son del template Porto)

`public/cd-project/img/demos/construction/` — descargadas del CDN público de Okler (`okler.net/previews/porto/13.0.0/img/demos/construction/`) el 2026-04-28:

```
about/about-1.jpg                  (171KB)
authors/author-1-big.png           (325KB)
backgrounds/background-1.jpg, background-2.jpg
blog/blog-thumb-1.jpg ... blog-thumb-3.jpg
generic/generic-1.jpg ... generic-7-small.jpg  (10 variantes para diamond grid)
icons/faucet.svg, winch.svg, paint-brush.svg, pushcart.svg, arrow-right.svg, phone.svg, email.svg, location.svg
logos/logo-1.png ... logo-4.png
slides/slide-1.jpg, slide-2.jpg, slide-1-engineer.png  (hero carousel + overlay PNG transparente)
```

Backup pre-reemplazo: `public/cd-project/img/demos/construction.bak-20260428-2222/` (assets viejos del demo Constructora Gama).

---

## 6. CTA del Header

Definido en `core/construction.json`:

```json
{ "cta_button": { "title": "Solicitar Presupuesto", "url": "/contact" } }
```

Editable post-entrega en `/site-data?tab=welcome` → "Botón CTA del Header".

---

## 7. Seeds de contenido

| Archivo | Contenido | Ubicación |
|---------|-----------|-----------|
| `services-construction.json` | 4 servicios + 1 categoría | `seeds/` |
| `projects-construction.json` | 7 proyectos + 2 categorías + 2 tags (paths a `generic-1..7.jpg`) | `seeds/` |
| `gallery-construction.json` | 6 items + 3 categorías | `seeds/` |
| `blog-construction.json` | 3 posts + 2 categorías | `seeds/` |
| `faqs-construction.json` | 10 FAQs + categorías | `seeds/` |
| `config-construction.json` | welcome (22 keys) + about (28 keys) + contact (14 keys) + footer.navegacion_principal | `seeds/` |

Total contenido seedeado: **30 ítems** + **64 keys de config**.

---

## 8. Vistas blade del producto

### Frontend (visitante)

| Archivo | Líneas | Contenido |
|---------|--------|-----------|
| `resources/views/modules/cd-base/frontend/demos/demo-construction/welcome.blade.php` | 530 | Home: Hero carousel 700px (2 slides + engineer overlay PNG), Who We Are, Services (4 con SVG icons stroke-animated), Projects (diamond grid 7), Testimonials parallax, Client logos, Blog (3 cards) |
| `resources/views/modules/cd-base/frontend/demos/demo-construction/about.blade.php` | 290 | Page header, sidebar sticky scrollspy, Who We Are + 3 counters, History (carousel 3 hitos), Misión/Visión (3 tabs), Team grid, Partners logos, Form lateral |
| `resources/views/modules/cd-base/frontend/demos/demo-construction/contact.blade.php` | 207 | Page header, Info row (LLAMANOS/ESCRIBINOS/VISITANOS con iconos SVG), Form izq + Map Google Maps API derecha |

### Layout

| Archivo | Contenido |
|---------|-----------|
| `resources/views/layout/front/headers/demo-construction.blade.php` | Header dark con logo + nav (5 items) + CTA "Solicitar Presupuesto" |
| `resources/views/layout/front/footers/demo-construction.blade.php` | Footer dark con logo + nav + datos contacto |
| `resources/views/layout/front/partials/page-header-construction.blade.php` | Page header de about/contact (parallax `background-2.jpg` + breadcrumb) |

### Admin (`/site-data`)

| Archivo | Tab | Inputs |
|---------|-----|--------|
| `resources/views/admin/site-data/welcome/demo-construction.blade.php` | Welcome | 22 inputs en 6 secciones (Hero, Who We Are, Services, Projects, Testimonial, Blog) |
| `resources/views/admin/site-data/about/demo-construction.blade.php` | About | 28 inputs en 6 secciones (SEO, Who We Are, Counters loop ×3, History loop ×3, Misión/Visión/Manifiesto, Leadership+Partners) |
| `resources/views/admin/site-data/contact/demo-construction.blade.php` | Contact | 11 inputs propios (page_title, page_subtitle, form_subtitle, headquarters_*, phone_number, latitude, longitude, map_zoom, google_maps_*) + 3 vía `_common` (phone, email, address) |

---

## 9. Editabilidad — paridad admin↔front

| Tab admin | Keys del front | Inputs admin | Cobertura |
|-----------|---------------:|-------------:|-----------|
| `/site-data?tab=welcome` | 22 | 22 | ✅ 100% |
| `/site-data?tab=about` | 28 | 28 (12 fijos + 6 counter loop + 9 history loop + 1 page_title) | ✅ 100% |
| `/site-data?tab=contact` | 14 | 14 (11 propios + 3 `_common`) | ✅ 100% |
| `/site-data?tab=branding` | colors, fonts, logos | sistema base | ✅ |
| `/site-data?tab=seo` | meta tags, OG, Twitter | sistema base | ✅ |
| **TOTAL textos vista** | **64** | **64** | ✅ 0 gaps |

### Lo que el cliente puede personalizar post-entrega

- **Brand kit wizard** (`/brand-kit`): logos × 3 + 6 colores + 3 fonts → repinta toda la vista en runtime via CSS variables
- **`/site-data`**: 64 textos editables de welcome/about/contact + datos de contacto + CTA del header + SEO + redes sociales + analytics
- **CRUD admin** de cada módulo: `/admin/services`, `/admin/projects`, `/admin/gallery`, `/admin/blog`, `/admin/faqs` (incluye títulos, descripciones, imágenes, íconos, categorías)
- **Header navigation**: titles + orden + activo/inactivo en `/site-data?tab=footer-nav`
- **Carousel del home**: editar slides desde `/admin/welcome-carousel`
- **Logos clientes** (sección Partners): desde `/admin/welcome-carousel` tipo logo

---

## 10. Comando de provisión

```bash
php artisan bewpro:new EMAIL "Nombre Constructora" construction --db=bp-CLIENTE [--fresh] [--no-email]
```

Acepta cualquiera de los 3 shop slugs (`construction`, `construction-company`, `construction-classic`) — todos resuelven al mismo core.

**Steps que ejecuta** (`ProvisionProject::doProvision()` + `ProvisionNew::handle()`):
1. Resuelve shop slug → core preset → escribe `users.json` temporal con admin
2. Conecta/crea DB del tenant
3. Migrate fresh (si `--fresh`) o incremental
4. Escribe `cd-system.theme.demo = demo-construction` + módulos activos
5. Seed permissions/roles/users
6. Aplica `brand_defaults` → `site.theme.colors.*` + `cd-system.theme.fonts.*` + `brand_kit.core_defaults.*`
7. Escribe `site.*` data (welcome/about/contact/header/seo/og/twitter — todo desde JSON merged)
8. Escribe analytics (vacío por defecto)
9. Sube asset pack a Cloudinary tenant + reescribe paths a URLs absolutas
10. Seed contenido módulos (services, projects con paths a generic-N.jpg que se suben a Cloudinary, gallery, blog, faqs)
11. Seed CdBase
12. Clear caches
13. Email credenciales (skip con `--no-email`)

---

## 11. Changelog del pulido (2026-04-28)

### Bugs específicos del producto arreglados

| Archivo | Bug | Fix |
|---------|-----|-----|
| `core/construction.json` | CTA `"Get a Quote"` (inglés) | `"Solicitar Presupuesto"` |
| `seeds/config-construction.json` | 5 placeholders `[Nombre del Cliente]`, `[Empresa]`, `[TU TELÉFONO]`, `[tu@email.com]`, `[TU DIRECCIÓN]` | Reemplazados por textos demo realistas en español |
| `seeds/config-construction.json` | Faltaban 8 keys en about + 8 en contact que el front leía → fallback en inglés/Lorem se renderizaba | Agregadas las 16 keys con textos demo coherentes |
| `seeds/config-construction.json` | Sin `footer.navegacion_principal` | Agregado con titles override (Servicios/Obras/Novedades/Nosotros/Contacto) |
| `seeds/projects-construction.json` | 5 proyectos con `image: ""` → diamond grid renderizaba fallback estático | 7 proyectos con paths a `cd-project/img/demos/construction/generic/generic-1..7.jpg` (diamond grid completo) |
| `welcome.blade.php` L218 | `src="{{ asset($service->icon && Str::startsWith(...)) }}"` pasaba boolean a `asset()` → service icon roto, alt text duplicaba el title | `src="{{ asset($service->icon) }}"` |
| `welcome.blade.php` | Strings inglesas `View More` (3x) y `View Projects` | "Conocé más" / "Ver proyectos" |
| `about.blade.php` | "Founded in 2001 by John Doe" + 8 párrafos Lorem ipsum hardcoded como fallback | Fallbacks reemplazados por textos demo en español |
| `about.blade.php` | Headers en inglés ("Who We Are", "History", "Mission & Vision", "Leadership", "Partners") | Traducidos a español |
| `about.blade.php` | Tabs Manifesto/Vision/Mission en inglés | "Manifiesto/Visión/Misión" |
| `about.blade.php` | @empty fallback "John Doe" + "Monica Doe" en team | Removido (queda vacío si no hay team — el cliente carga desde admin) |
| `about.blade.php` | Sidebar nav scrollspy en inglés (Who We Are/History/etc.) | Traducidos |
| `about.blade.php` | Form labels y mensajes en inglés | Traducidos a español |
| `about.blade.php` | Team avatars fallback path obsoleto | `cd-project/img/defaults/team/team-{1..6}.jpg` rotativo |
| `contact.blade.php` | "CALL US" / "SEND AN EMAIL" / "FIND US" en inglés | "LLAMANOS" / "ESCRIBINOS" / "VISITANOS" |
| `contact.blade.php` | "Send Us a Message" / "Corporate Headquarters" / Form labels | Traducidos |
| `contact.blade.php` | Hex hardcoded `#e36159` en JS del PinElement de Google Maps | Lee `var(--primary)` con fallback `#E04622` |
| `contact.blade.php` | Phone/email/address fallbacks con datos del template Porto | Datos demo en español |
| `assets/construction/` | Faltaba `site.webmanifest` | Copiado |
| `img/demos/construction/` | Assets leftover de Constructora Gama (slides/2.jpg 226KB, generic/gallery-6.jpg) | Reemplazados por imágenes genéricas Porto descargadas del CDN público de Okler (26 archivos) |
| `admin/site-data/welcome/demo-construction.blade.php` | Solo `@include('_default')` (no demo-específico) | Reescrito con 22 inputs propios en 6 secciones |
| `admin/site-data/about/demo-construction.blade.php` | No existía | Creado con 28 inputs en 6 secciones |
| `admin/site-data/contact/demo-construction.blade.php` | No existía | Creado con 7 inputs propios + heredados de `_common` |
| `admin/site-data/contact/demo-construction.blade.php` | 4 inputs gap detectados en auditoría: `page_title`, `page_subtitle`, `latitude`, `longitude` (usados en blade pero ocultos detrás de condicional `_common` para corporate+demo-specific) | Agregados explícitamente al demo-specific → parity 14/14 |
| `core/construction.json` `brand_defaults` | Paleta rojo terracota `#E04622` + dorado `#EEAB26` + grisáceo `#EAEFF3` no coincidía con el logo del producto (badge burgundy + wordmark rosa pastel) → clash visual en cada provisión | Paleta realineada al logo: primary `#651A38` burgundy + secondary `#F2B5BA` rosa pastel + tertiary `#FBEEEF` + quaternary `#2D0B19` |
| `core/construction.json` `fonts.tertiary` | "Shadows Into Light" no acompañaba el wordmark geométrico-friendly del logo | Cambiado a `Caveat` (manuscrita contemporánea) |
| `demos/demo-construction/contact.blade.php` L181 | Fallback hardcoded `#E04622` (rojo terracota viejo) en JS PinElement de Google Maps | Fallback `#651A38` (burgundy nuevo) |
| `template/css/demos/demo-construction.css` ×6 | Superficies con `background-color: #EAEFF3 !important` hardcoded (faq-question, badge-count, card-header, .main aside, etc.) → no respondían a brand_kit del cliente | Reemplazadas por `var(--tertiary)` → repintan runtime con cualquier paleta |

### Bugs transversales aprovechados (ya resueltos en law-firm)

Construction se beneficia de los fixes que se hicieron durante el pulido de law-firm-digital, sin trabajo adicional:
- `SkinColorService` greys scale invertida + `--default` ilegible → arreglado globalmente
- `ProvisionProject::buildSiteData` ignoraba subdir del producto → resuelto con `prefixAssetPath()`
- `AssetsSeeder` path canónico con subdir → resuelto
- `header-nav.blade.php` sin auto-fetch de service categories → arreglado
- `HomepageController::contact()` no pasaba `$faqs` → arreglado
- `AirtableService` falla con país no enumerado → typecast + retry
- `StripeWebhookController` notif Slack contradictoria → arreglado

---

## 12. QA checklist (verificado 2026-04-28)

```bash
# 1. Provisionar tenant fresco
php artisan bewpro:new admin@bewpro.com "Demo Construction" construction --db=bp-demo-construction --fresh --no-email

# 2. Verificar Cloudinary
mysql bp-demo-construction -e "SELECT \`key\`, value FROM settings WHERE \`key\` LIKE 'site.assets.%' AND value LIKE 'https://res.cloudinary.com%'"
# Esperado: 6+ filas (main_logo, footer_logo, loader_logo, favicon, apple_touch_icon, main_logo_sticky)

# 3. Verificar brand colors (Constructora roja)
mysql bp-demo-construction -e "SELECT \`key\`, value FROM settings WHERE \`key\` LIKE 'site.theme.colors.%'"
# Esperado: primary #E04622, secondary #EEAB26, tertiary #EAEFF3

# 4. Verificar conteo de seeds
mysql bp-demo-construction -e "SELECT (SELECT COUNT(*) FROM services) services, (SELECT COUNT(*) FROM projects) projects, (SELECT COUNT(*) FROM gallery_items) gallery, (SELECT COUNT(*) FROM posts) posts, (SELECT COUNT(*) FROM faqs) faqs"
# Esperado: services 4, projects 7, gallery 6, posts 3, faqs 10

# 5. Smoke test front (8 URLs)
for url in / /about /contact /services /projects /gallery /blog /faqs; do
  curl -s -o /dev/null -w "%{http_code} $url\n" http://demo-construction.bewpro.com$url
done
# Esperado: 200 en las 8

# 6. Cero placeholders/inglés residual en home
curl -s http://demo-construction.bewpro.com/ | grep -oE '\[Nombre [^]]+\]|>John Doe<|>Lorem |Get a Quote|View More'
# Esperado: vacío

# 7. Diamond grid renderiza 7 proyectos
curl -s http://demo-construction.bewpro.com/ | grep -c 'class="diamond'
# Esperado: 7+

# 8. Service icons (SVG stroke-animated)
curl -s http://demo-construction.bewpro.com/ | grep -oE 'icons/(faucet|winch|paint-brush|pushcart)\.svg' | sort -u | wc -l
# Esperado: 4

# 9. Header CTA "Solicitar Presupuesto" presente
curl -s http://demo-construction.bewpro.com/ | grep -c 'Solicitar Presupuesto'
# Esperado: 1+

# 10. Editabilidad admin↔front (paridad)
# Abrir /site-data?tab=welcome , ?tab=about , ?tab=contact y verificar que cada
# texto del front tiene un input correspondiente. Total esperado: 64 inputs.
```

---

## 13. Problemas conocidos / fuera de scope

- **`_common.blade.php` de contact tiene 8 campos extra** (`card_subtitle`, `city`, `map_url`, `page_badge`, `page_heading`, `secondary_address`, `secondary_city`, `hours`) que demo-construction no consume — pero al ser `corporate + hasDemoSpecificContact` esos campos están dentro de un `@if` que no se renderiza. El cliente no los ve → no hay ruido en el admin. Otros demos sí los usan → no se borran globalmente.
- **CTA del Header vive en el tab "Welcome" del admin** pero aparece en TODAS las páginas. Para esta release solo se clarificó en el label. Refactor a tab "Header" propio queda pendiente (compartido con law-firm).
- **Vista `gallery` no tiene blade dedicado** para demo-construction — usa el genérico del módulo. Si se quiere look custom (galería diamond/masonry como home), agregar `resources/views/modules/gallery/frontend/demos/demo-construction/index.blade.php`.
- **Diamond grid hardcoded 7 slots** con tamaños asignados por índice (índices 3, 5, 6 = `diamond-sm`). Si el cliente carga menos de 7 proyectos, el grid queda incompleto. Si carga más de 7, se truncan via `take(7)`. Decisión deliberada: el demo se ve consistente; carga > 7 va a `/projects` listado.
- **Hero carousel hardcoded 2 slides** con copy distinto por slide (slide 2 usa `hero_slide2_title/badge`). Si el cliente sube > 2 slides desde `/admin/welcome-carousel`, solo los 2 primeros respetan la composición demo; los siguientes se renderizan como fallback.

---

## 14. Referencias cruzadas

- Demo: [`../demos/demo-construction.md`](../demos/demo-construction.md)
- Producto referencia (1ro certificado): [`law-firm-digital.md`](law-firm-digital.md)
- Bugs transversales beneficiados: ver [`law-firm-digital.md` §11](law-firm-digital.md#11-changelog-del-pulido-2026-04-27) "Bugs transversales arreglados"
- Patrón de provisión: `docs/bewpro2.0/branding/pipeline-provision.md`
- Patrón de vistas: `docs/bewpro2.0/arquitectura-vistas-base.md` (este demo está en **Patrón A** — config-heavy, 64 keys de site.* + ViewComposer para módulos)
- Catálogo completo: `database/seeders/products/catalog.json`
- Checklist canónico: [`PRODUCT-CHECKLIST.md`](PRODUCT-CHECKLIST.md)
- Estado de productos: `docs/bewpro2.0/product-readiness/estado-productos.md`
