# Checklist de Integración Demo ↔ Módulos
> Guía definitiva para adaptar cualquier demo al sistema de módulos
> Validado con 11 demos: accounting-1, accounting-2, marketing-1, creative-agency-2, architecture-2, construction-2, restaurant, law-firm-2, construction, insurance, digital-agency-2
> Revisión: 2026-04-05

---

## Resumen

Cada demo necesita **3 capas** para funcionar perfectamente con todos los módulos:

```
CAPA 1: ARCHIVOS DEL DEMO (estructura)
    → Header, footer, page-header, welcome, about, contact
    → CSS del demo + skin de colores
    → Registro en los 10 dynamic-headers

CAPA 2: CSS GLOBAL OVERRIDES (visual)
    → Remapear clases Porto al estilo del demo
    → Unificar cards, sidebars, filtros, forms
    → Light mode vs Dark mode

CAPA 3: CONFIGURACIÓN DB (contenido)
    → Títulos de módulos, SEO, contacto, assets
    → Módulos activos + navegación
    → Seeds de contenido
```

---

## CAPA 1: Archivos del Demo

### Checklist de archivos requeridos

```
resources/views/
├── layout/front/
│   ├── headers/demo-{name}.blade.php        ← Navegación dinámica
│   ├── footers/demo-{name}.blade.php        ← Footer con newsletter, social, copyright
│   └── partials/
│       └── page-header-{name}.blade.php     ← Banner compartido para TODOS los módulos
│
├── modules/cd-base/frontend/demos/demo-{name}/
│   ├── welcome.blade.php                    ← Homepage con secciones dinámicas
│   ├── about.blade.php                      ← Storytelling del proyecto
│   └── contact.blade.php                    ← Formulario de contacto
│
public/template/css/
├── demos/demo-{name}.css                    ← Estilos + Module Theme Overrides
└── skins/skin-{name}.css                    ← Paleta de colores (--primary-rgb obligatorio)

resources/views/admin/site-data/              ← Admin partials (refactorizado 2026-04-05)
├── welcome/demo-{name}.blade.php            ← Campos Welcome numerados
├── about/demo-{name}.blade.php              ← Campos About (si únicos)
└── contact/demo-{name}.blade.php            ← Campos Contact (si únicos)

database/seeders/products/core/seeds/
├── config-{core}.json                       ← Auto-seed welcome/about/contact
└── services-{core}.json                     ← Services con SVG/FA icons
```

### Header — Requisitos mínimos

```blade
✅ Navegación dinámica: get_dynamic_navigation('header')
✅ Active state: is_nav_item_active()
✅ CTA button: config('site.header.cta_button.title')
✅ Logo dinámico: site_asset_url('main_logo')
✅ Mobile responsive (hamburger/offcanvas)
✅ Social icons condicionales
✅ Sin URLs hardcodeadas
```

### Footer — Requisitos mínimos

```blade
✅ Logo dinámico: site_asset_url('footer_logo')
✅ Descripción: config('site.footer.description')
✅ Navegación dinámica: get_dynamic_navigation('footer')
✅ Social icons condicionales
✅ Newsletter form condicional (@if newsletter activo)
✅ Contacto: config('site.contact.email/phone')
✅ Copyright dinámico: date('Y') + config('site.author')
✅ "Potenciado por BewPro" (opcional)
✅ Hover states en CSS (no onmouseover inline)
✅ Newsletter alert auto-hide (setTimeout 5s)
```

### Page-Header Partial — Requisitos mínimos

```blade
✅ Variables: $pageTitle, $pageLabel, $pageBreadcrumb, $pageSubtitle
✅ Null coalescing con defaults: $pageBreadcrumb ?? $breadcrumbItems ?? [...]
✅ Breadcrumb con links funcionales
✅ Título + subtítulo separados
✅ CTA button dinámico: config('site.header.cta_button.title')
✅ Phone condicional: @if(config('site.contact.phone'))
✅ Registrado en los 10 dynamic-headers de módulos
✅ MISMO estilo que about.blade.php y contact.blade.php (derivar del Porto HTML)
```

**REGLA CRÍTICA (lección marketing-1):** El page-header partial se deriva del estilo
de las páginas internas del demo original (about/contact de Porto). About, Contact y
módulos DEBEN usar el mismo estilo de page header. NO inventar uno distinto.

### Registro en Dynamic Headers (10 archivos)

Cada módulo tiene un `partials/dynamic-header.blade.php` donde se registra el demo:

```blade
@elseif($activeDemo === 'demo-{name}')
    @include('layout.front.partials.page-header-{name}', [
        'pageTitle' => $pageTitle,
        'pageLabel' => 'LABEL',
        'pageBreadcrumb' => $breadcrumbItems,
        'pageSubtitle' => $pageSubtitle ?? null,
    ])
```

Los 10 archivos:
1. `modules/services/frontend/partials/dynamic-header.blade.php`
2. `modules/projects/frontend/partials/dynamic-header.blade.php`
3. `modules/blog/frontend/partials/dynamic-header.blade.php`
4. `modules/cd-base/faqs/frontend/partials/dynamic-header.blade.php`
5. `modules/gallery/frontend/partials/dynamic-header.blade.php`
6. `modules/products/frontend/partials/dynamic-header.blade.php`
7. `modules/team-members/frontend/partials/dynamic-header.blade.php`
8. `modules/references/frontend/partials/dynamic-header.blade.php`
9. `modules/cd-base/frontend/partials/dynamic-header.blade.php` (contact)
10. `modules/menu/frontend/partials/dynamic-header.blade.php`

### Welcome — Requisitos mínimos

```blade
✅ SEO meta tags (title, description, og, twitter)
✅ Hero section con config dinámico
✅ Secciones condicionales: @if(is_module_active('services'))
✅ Datos del HomepageController: $services, $featuredProjects, $featuredPosts, etc.
✅ CTAs: config('site.booking_url') — no hardcodeados
✅ WhatsApp condicional: @if(config('site.social_media.whatsapp.active'))
✅ Empty states para módulos sin datos
```

---

## CAPA 2: CSS Global Overrides

### Estructura del archivo demo-{name}.css

```css
/* 1. Foundation (tipografía, body) */
/* 2. Custom elements del demo (posiciones, avatars, gallery) */
/* 3. Header styling (sticky, dropdowns, nav) */
/* 4. GLOBAL OVERRIDES — conversión de clases Porto */
/* 5. MODULE UI UNIFICATION */
/* 6. CYAN → {ACCENT} override (si los módulos tienen inline styles) */
/* 7. Border radius unification */
/* 8. Loader dark/light mode */
```

### Bloques CSS obligatorios para dark mode

```css
/* --- FOUNDATION --- */
html, body, .body { background-color: var(--secondary) !important; color: var(--light) !important; }

/* --- PORTO CLASS REMAPPING --- */
.bg-light, .bg-color-light { background-color: var(--secondary) !important; }
.bg-color-grey-scale-1 { background-color: var(--secondary) !important; }
.text-dark, .text-color-dark { color: var(--light) !important; }
.text-muted, .text-color-grey { color: var(--quaternary) !important; }
.card { background-color: var(--dark) !important; }
.form-control { background-color: var(--dark) !important; color: var(--light) !important; }

/* --- HEADER --- */
#header .header-body { background-color: var(--secondary) !important; }
.sticky-header-active #header .header-body { backdrop-filter: blur(10px); background-color: rgba(X,X,X, 0.95) !important; }

/* --- SIDEBAR UNIFICATION --- */
aside .card, .sidebar > div { background-color: var(--dark) !important; border-radius: var(--border-radius2x) !important; }

/* --- CARD UNIFICATION --- */
.card, .blog-card, .project-card { background-color: var(--dark) !important; border-radius: var(--border-radius2x) !important; }

/* --- FILTER PILLS --- */
.nav-pills .nav-link { background-color: var(--dark) !important; }
.nav-pills .nav-link.active { background-color: var(--primary) !important; color: var(--secondary) !important; }

/* --- LOADER --- */
.loading-overlay { background-color: var(--secondary) !important; }

/* --- ALERTS --- */
.alert-success { background-color: rgba(40, 167, 69, 0.15) !important; }
.alert-danger { background-color: rgba(220, 53, 69, 0.15) !important; }
```

### Bloques CSS obligatorios para light mode

```css
/* Light mode: los módulos ya usan clases Porto correctas */
/* Solo necesitás: tipografía, border-radius, header sticky, card hover */
```

### Override de inline colors (módulos con hardcoded rgba)

Los módulos que se refactorizaron para accounting-1 tienen `rgba(0, 240, 255, X)` (cyan) inline. Para otros demos:

```css
/* Selector por atributo — captura inline styles */
[style*="rgba(0, 240, 255, 0.1)"] { border-color: rgba(YOUR_R, YOUR_G, YOUR_B, 0.1) !important; }
[style*="rgba(0, 240, 255, 0.08)"] { background-color: rgba(YOUR_R, YOUR_G, YOUR_B, 0.08) !important; }
```

---

## CAPA 3: Configuración DB

### Settings mínimos por proyecto

```
# Marca
site.name
site.tagline
site.author
site.description
site.url

# Contacto
site.contact.email
site.contact.phone (opcional)
site.contact.address (opcional)
site.booking_url (opcional)

# Social
site.social_media.{platform}.active
site.social_media.{platform}.url
site.social_media.{platform}.icon

# Assets
site.assets.main_logo
site.assets.footer_logo
site.assets.loader_logo
site.assets.favicon
site.og.image
site.twitter.image

# SEO
site.seo.title
site.seo.description
site.seo.keywords
site.seo.schema.type (Organization/Person)

# Visual
cd-system.theme.demo
cd-system.theme.skin
cd-system.theme.fonts.primary
cd-system.theme.fonts.secondary
cd-system.theme.fonts.tertiary

# Footer
site.footer.description
site.footer.tagline (si el demo lo usa)

# CTA
site.header.cta_button.active
site.header.cta_button.title
site.header.cta_button.url
```

### Títulos de módulos (estratégicos por proyecto)

```
site.modules.services.page_header.title
site.modules.services.page_header.subtitle
site.modules.projects.page_header.title
site.modules.projects.page_header.subtitle
site.modules.blog.page_header.title
site.modules.blog.page_header.subtitle
site.modules.gallery.page_header.title
site.modules.gallery.page_header.subtitle
site.modules.faqs.page_header.title
site.modules.faqs.page_header.subtitle
site.modules.references.page_header.title
site.modules.references.page_header.subtitle
site.modules.menu.page_header.title (si aplica)
```

### Módulos — Activación + Navegación

```
cd-system.modules.{module}.active = 1/0
cd-system.modules.{module}.navigation.header = 1/0
cd-system.modules.{module}.navigation.footer = 1/0
```

---

## CAPA 4: Validación (Recorrido de páginas)

### Checklist por página

```
□ / (welcome)      — Hero, módulos dinámicos, CTAs, empty states
□ /about            — Storytelling, counters, cards, CTA
□ /contact          — Formulario funcional, meta tags, datos dinámicos
□ /services         — Cards estilo del demo, sidebar, empty state
□ /services/{slug}  — Detail con dynamic-header, sidebar, CTA
□ /projects         — Cards, filtros, paginación
□ /projects/{slug}  — Detail con dynamic-header
□ /blog             — Cards estilo del demo, sidebar categorías
□ /blog/{slug}      — Post detail, sidebar, share buttons
□ /gallery          — Grid, categorías, lightbox
□ /faqs             — Accordion, sidebar categorías
□ /references       — Cards, categorías
□ /404              — Dynamic-header, CTAs
□ /maintenance      — Dynamic-header, CTAs
```

### Checklist visual por módulo

```
□ Page header muestra título + subtítulo + breadcrumb correcto
□ Cards tienen border-radius del demo
□ Cards tienen colores del demo (dark/light)
□ Sidebar tiene el mismo estilo que las cards
□ Filtros/pills tienen estilo unificado
□ Links de hover usan --primary
□ Empty states son limpios
□ Spacing uniforme después del page-header
□ Responsive funciona (mobile)
□ No hay flash de color blanco al cargar (loader)
```

### Checklist de código

```
□ 0 URLs hardcodeadas (todo via config() o route())
□ 0 colores hardcodeados en vistas (todo via CSS variables)
□ 0 teléfonos/emails hardcodeados (todo via config())
□ 0 @if($demo === 'X') en vistas de módulos
□ Todos los títulos usan @section('title', ...) sin duplicar site.name
□ Todos los módulos usan @include dynamic-header (no should_use_modern)
□ Footer sin onmouseover/onmouseout inline
□ Newsletter con auto-hide de alerts
□ Contact form guarda en DB + envía email si SMTP configurado
```

---

## Skin — Estructura de variables

```css
:root {
    /* Primary — Color de acento principal */
    --primary: #HEXVALUE;
    --primary-rgb: R, G, B;                       /* ← OBLIGATORIO (lección marketing-1) */
    --primary-rgba-{10-90}: rgba(R, G, B, 0.{1-9});

    /* Secondary — Fondo base */
    --secondary: #HEXVALUE;
    --secondary-rgb: R, G, B;                     /* ← Recomendado */

    /* Tertiary — Fondo alternativo */
    --tertiary: #HEXVALUE;

    /* Quaternary — Texto secundario/muted */
    --quaternary: #HEXVALUE;

    /* Dark — Fondo de cards/elementos */
    --dark: #HEXVALUE;

    /* Light — Texto principal */
    --light: #HEXVALUE;

    /* Inverses */
    --primary-inverse: #HEXVALUE;

    /* Greys — Escala de grises para UI elements */
    --grey-{100-1000}: #HEXVALUE;

    /* Border radius */
    --border-radius: Xpx;
    --border-radius2x: Xpx;
}
```

**`--primary-rgb` es OBLIGATORIO.** Sin esto, los módulos muestran cyan en icon circles
y decoraciones (fallback de `rgba(var(--primary-rgb, 0,240,255), 0.08)`).

### Mapeo de roles por modo

| Variable | Light Mode | Dark Mode |
|----------|-----------|-----------|
| --secondary | #FFFFFF o claro | #1A1A1A o oscuro |
| --dark | #111111 o muy oscuro | #111111 o muy oscuro |
| --light | #FFFFFF | #FFFFFF |
| --quaternary | #777777 (gris) | #A0A0A0 (gris claro) |
| --grey-{100-1000} | Claros → oscuros | Oscuros → claros (invertido) |

---

## Seeders — Defaults genéricos

```
database/seeders/project-data/defaults/
├── services.json     → 3 services, 1 category
├── faqs.json         → 8 FAQs, 2 categories
├── blog.json         → 2 posts, 2 categories
├── references.json   → 3 references, 2 categories
├── gallery.json      → 3 items con img placeholder
├── projects.json     → 3 projects placeholder
├── team.json         → 2 members placeholder
└── menu.json         → estructura de menú
```

### Seeds específicos por core

```
database/seeders/products/core/seeds/
├── services-{core}.json
├── faqs-{core}.json
├── blog-{core}.json
└── (futuros: gallery-{core}.json, references-{core}.json)
```

---

## Features Core (disponibles para todos los proyectos)

| Feature | Tabla | Admin | Vista |
|---------|-------|-------|-------|
| CompanyLogo | company_logos | /admin/company-logos | Slider en welcome |
| ContactMessage | contact_messages | /admin/contact-messages | Form → DB + email |
| Newsletter | newsletter_subscribers | /subscribers | Form footer → DB |
| WelcomeCarousel | welcome_carousels | /admin/welcomecarousel | Hero slider/crossfade |

---

---

## Lecciones adicionales (creative-agency-2 + architecture-2)

### Variables del HomepageController
Verificar nombres EXACTOS en `compact()` de `HomepageController.php`:
```
$services, $featuredPosts, $recentPosts, $carouselImages, $companyLogos,
$menuSections, $featuredProjects, $kpis, $featuredReferences, $testimonials,
$teamMembers, $recentNews, $galleryImages, $featuredFaqs, $seoData
```
**CUIDADO:** `$companyLogos` (NO `$clientLogos`), `$featuredReferences` (NO `$references`).

### Iconos de servicios: SVG vs FontAwesome
El campo `icon` en la tabla `services` puede contener:
- **FontAwesome class:** `fas fa-code` → blade renderiza con `<i class="{{ $service->icon }}">`
- **SVG file path:** `cd-project/img/demos/{name}/icons/icon.svg` → blade renderiza con `<img src="{{ asset($service->icon) }}" data-icon>`

Depende de cómo la welcome blade del demo renderiza los iconos. Verificar antes de seedear.

### Admin panel por demo
Cada demo con secciones únicas necesita:
1. Feature flag propio en `config/demos.php` (ej: `architecture_welcome`, `stats_welcome`)
2. Bloque condicional `@if(demo_has_feature('flag'))` en admin
3. Exclusión de campos de otros demos: `&& !demo_has_feature('otro_flag')`
4. Campos numerados en mismo orden visual que la página

### Services seed: columna correcta
La tabla `services` usa `service_category_id` (NO `category_id`). El seed JSON debe usar formato:
```json
{ "service_categories": [...], "services": [{ "category_slug": "...", ... }] }
```

### Config keys: seedear en UNA pasada
Hacer múltiples `SiteConfigService::setMany()` con keys parecidos genera duplicados vacíos
(ej: `process_step1_title` vs `process_1_title`). Definir TODOS los keys antes y seedear una sola vez.

### Config keys vacíos
Si `config('site.key')` retorna `''` (empty string en DB), el fallback `config('key', 'default')` NO se activa. Soluciones:
- Seedear con valores reales (preferido)
- Usar `config('key') ?: 'default'` en la blade
- DELETE del key vacío en DB

### Admin exclusion cascading (lección law-firm-2)
Cada demo nuevo agrega `!demo_has_feature('flag')` en MÚLTIPLES bloques del admin:
- Tab Welcome: bloques corporate, stats, about_inline
- Tab About: bloques corporate (Culture/Values/Gradient), counters genéricos
- Tab Contact: CTA pie de contacto, Office Photos

Verificar TODOS los tabs del admin, no solo el de Welcome. Un cambio puede afectar otro demo.

*Documento validado con 8 demos. Actualizar cuando se agreguen nuevos patrones.*
