# Demo: demo-law-firm-2

> **Estado:** ✅ Production-ready (2026-04-28)
> **Producto:** [law-firm-digital](../products/law-firm-digital.md)
> **Es el primer demo certificado y sirve de referencia para los próximos 7.**

---

## 1. Identidad

| Campo | Valor |
|-------|-------|
| **Slug del demo** | `demo-law-firm-2` |
| **Slug base** | `law-firm-2` |
| **Source Porto** | https://www.okler.net/previews/porto/13.0.0/demo-law-firm-2.html |
| **Demo de referencia (look)** | https://dpolegal.com |
| **Producto que lo usa** | `law-firm-digital` (5 shop slugs mapeados) |
| **Patrón welcome** | **A — config-heavy** (42 keys de welcome editables en admin) |
| **Skin asociado** | `skin-law-firm-2.css` |
| **Brand defaults del producto** | primary `#1A325D` (azul), secondary `#B8960C` (dorado), Poppins+Lora |

---

## 2. Las 7 piezas

| # | Pieza | Archivo | Líneas |
|---|-------|---------|--------|
| 1 | Header | `resources/views/layout/front/headers/demo-law-firm-2.blade.php` | 81 |
| 2 | Footer | `resources/views/layout/front/footers/demo-law-firm-2.blade.php` | — |
| 3 | Page-header | `resources/views/layout/front/partials/page-header-law-firm-2.blade.php` | 47 |
| 4 | Welcome | `resources/views/modules/cd-base/frontend/demos/demo-law-firm-2/welcome.blade.php` | 832 |
| 5 | About | `.../demo-law-firm-2/about.blade.php` | 285 |
| 6 | Contact | `.../demo-law-firm-2/contact.blade.php` | 209 |
| 7 | Demo CSS | `public/template/css/demos/demo-law-firm-2.css` | — |

Skin: `public/template/css/skins/skin-law-firm-2.css`
Imágenes: `public/cd-project/img/demos/law-firm-2/` (backgrounds, banner, blog, cases, generic, icons, slides, team, signature)

---

## 3. Registros en código

| Registro | Archivo | Detalle |
|----------|---------|---------|
| Layout mapping | `app/helpers.php::get_demo_layout_mapping()` | `header → demo-law-firm-2`, `footer → demo-law-firm-2`, `page_header → page-header-law-firm-2` |
| Skin mapping | `app/helpers.php::get_demo_skin_mapping()` | `demo-law-firm-2 → skin-law-firm-2` |
| Page headers config | `config/page-headers.php` | partial registrado |
| Dynamic-headers | 10 partials | `@elseif($currentDemo === 'demo-law-firm-2')` cases en services, blog, gallery, projects, team-members, references, faqs, cd-base, etc. |

---

## 4. Cómo el demo embebe módulos en welcome.blade

11 secciones identificadas (numeradas en el archivo):

| Sec | Sección | Módulo | Markup específico |
|-----|---------|--------|-------------------|
| 1 | Hero carousel | welcomeCarousel (opcional) | 2 slides 845px con kenburns + CTA centrado |
| 2 | Services / Practice Areas | services | Owl carousel 5 items, cards `custom-card-style-1` con SVG icons + min-height 380px scoped |
| 3 | About + signature | (config) | 2 cols con shape-1 SVG y founder image |
| 4 | Client logos | companyLogos (CdBase) | 6 logos en row 2x3 con animations |
| 5 | Testimonials | references (fallback de testimonials) | overlay oscuro + carousel quotes + 4 stats counters |
| 6 | FAQ + Form | faqs + (form contacto) | 2 cols: accordion FAQ izquierda + form derecha |
| 7 | Team carousel | team | overlay header + carousel cards 510px scoped + img-top 230px object-fit cover |
| 8 | Extended services + checklist | (config + services rotativo) | checklist 5 items + carousel circular 3 items |
| 9 | CTA bar | (config + contacto) | bg-primary-darken con phone+email+schedule + CTA button |
| 9b | Success stories | references | carousel cases 2x columnas |
| 10 | Parallax quote | (config) | scrollable parallax 8% offset → 100vw |
| 11 | Blog featured | blog | 2 cards background-image-style + Ver Blog button |

---

## 5. Customizaciones específicas

### CSS scoped en welcome.blade

```css
.law-firm-services-carousel .owl-stage { display: flex; align-items: stretch; }
.law-firm-services-carousel .card.custom-card-style-1 { width: 100%; height: 100%; }

.law-firm-team-carousel .owl-stage { display: flex; align-items: stretch; }
.law-firm-team-carousel .card.custom-card-style-1 { min-height: 510px; display: flex; flex-direction: column; }
.law-firm-team-carousel .card.custom-card-style-1 .card-img-top { height: 230px; object-fit: cover; }
```

→ Soluciona el bug de cards con altura variable en owl-carousel.

### Page-header breadcrumb

`text-color-light opacity-8` (links inactivos) + `text-color-secondary` (link activo) sobre overlay oscuro. **NO** `text-color-primary` que sería azul ilegible.

### CTA "Porque elegirnos"

Iconos en `text-color-secondary` (dorado) sobre `bg-primary-darken` (azul oscuro) — alto contraste. Antes era `text-color-primary` (azul sobre azul = ilegible).

### Header CTA button

Default del producto: "Solicitar Consulta" → `/contact`. Editable en admin `/site-data?tab=welcome` → "Botón CTA del Header (visible en todas las páginas)".

### Header nav titles override

El producto declara en `seeds/config-law-firm-digital.json`:
```json
"footer.navegacion_principal": {
    "services": { "title": "Áreas de Actuación", ... }
    "team": { "title": "Equipo", ... }
    "blog": { "title": "Novedades", ... }
    "about": { "title": "El Estudio", ... }
    "contact": { "title": "Contacto", ... }
}
```

→ Override del label "Servicios" → "Áreas de Actuación" (terminología legal).

### Dropdown header services

`<x-header-nav>` con auto-fetch inline de `$serviceCategories` y `$headerServices` (post-fix 2026-04-27, antes el dropdown salía vacío). Renderiza 5 services + categoría "Áreas de Práctica" + "Ver Todos".

### Testimonios usa references como fallback

Como el módulo `testimonials` no está activo en law-firm-digital, el bloque de testimonials del welcome usa `$featuredReferences` como fallback automático (post-fix 2026-04-28). Renderiza con `description` (testimonio del cliente) + `name` + `company`.

### Team images

`$member->image` con fallback a `cd-project/img/defaults/team/team-{1..6}.jpg` (cycle por loop index). El bug del campo inexistente `$member->photo` ya fue corregido.

### Blog covers

`$post->header` (no `$post->image`) — el modelo Post usa el campo `header` para covers. BlogSeeder hace upload automático a Cloudinary del tenant cuando detecta path local.

---

## 6. Auditoría — 30 items

| Bloque | Items | Estado |
|--------|-------|--------|
| 1. Anatomía y registros (5) | 5/5 | ✅ |
| 2. Header / Footer / Page-header (6) | 6/6 | ✅ |
| 3. Welcome / About / Contact (6) | 6/6 | ✅ (cero placeholders, español, sin John Doe, FAQs renderizan) |
| 4. CSS (demo + skin) (5) | 5/5 | ✅ |
| 5. Integración con módulos (4) | 4/4 | ✅ |
| 6. QA visual (4) | 4/4 | ✅ (smoke test 7/7 URLs HTTP 200) |
| **TOTAL** | **30/30** | ✅ |

**Veredicto**: ✅ Production-ready

---

## 7. Bugs específicos del demo arreglados

| Archivo | Bug | Fix |
|---------|-----|-----|
| `welcome.blade.php` L26-79 hero fallback | Slides `slides/slide-1.jpg` y `slide-2.jpg` eran placeholders 2KB vacíos | Cambiados a `banner/banner-1.jpg` y `banner-2.jpg` (134-142KB reales) |
| `welcome.blade.php` L209-244 client logos | Path `img/logos/logo-X.png` (404) | Path corregido a `cd-project/img/logos/logo-X.png` (existen) |
| `welcome.blade.php` L260-280 testimonios | `@forelse($testimonials)` con `$testimonials` undefined → @empty con "John Doe" inglés | Refactor: usa `featuredReferences` mapeado como fallback con español |
| `welcome.blade.php` L463-490 team fallback | Hardcoded "John Doe / Janice Doe / Matt Doe / Ashley Doe / Chuck Doe" | Reemplazado por nombres genéricos en español |
| `welcome.blade.php` L797-803 blog fallback | "John Doe" hardcoded en card placeholder | Reemplazado por "Equipo Editorial" con fecha actual |
| `welcome.blade.php` múltiples | Strings inglés "READ MORE / LEARN MORE / VIEW PROFILE / VIEW DETAILS / VIEW BLOG / CONTACT US / REQUEST CONSULTATION" | Traducidos a español |
| `welcome.blade.php` L253 testimonials badge | `text-color-primary` (azul) sobre fondo oscuro = ilegible | `text-color-secondary` (dorado) |
| `welcome.blade.php` L429 team badge | idem | idem |
| `welcome.blade.php` L599-609 CTA "Porque elegirnos" | iconos `text-color-primary` sobre `bg-primary-darken` (azul sobre azul) | `text-color-secondary` (dorado) |
| `about.blade.php` L96-101 signature image | `<img src="signature.png">` mostraba firma genérica del template Porto | Removida la `<img>`, queda solo `signature_name` editable |
| `about.blade.php` L194-200 team avatars | Usaba `$member->photo` (campo inexistente — modelo tiene `image`) | Cambiado a `$member->image` con fallback a `defaults/team/` |
| `about.blade.php` L221 testimonials section | `bg-color-grey-scale-1` clase no fiable + `text-color-primary` sobre fondo claro | Quitado bg explícito (queda con var(--grey-100) post-fix transversal) + badge `text-color-secondary text-uppercase positive-ls-3` |
| `about.blade.php` múltiples headings | "OUR MISSION / CLIENTS AND COLLEAGUES / WE HAVE EARNED THE TRUST / OUR DIFFERENCE / TESTIMONIALS" | Traducido a español |
| `contact.blade.php` múltiples | "Get In Touch / Address and Mail / Address / Assistance Hours / Work Inquiries / ANY QUESTIONS? / LET'S TALK / REQUEST CONSULTATION / Loading..." + form placeholders | Traducidos a español + `Sendmail/null` config |
| `contact.blade.php` (controller) | HomepageController no pasaba `$faqs` → accordion vacío | `Faq::featured()->orderBy('order')->limit(8)` con fallback |
| `page-header-law-firm-2.blade.php` | Breadcrumb azul sobre overlay oscuro (ilegible) | `text-color-light opacity-8` (links) + `text-color-secondary` (activo) |
| `core/law-firm-digital.json` | CTA header `"Free Consultation"` | `"Solicitar Consulta"` |
| `seeds/config-law-firm-digital.json` | 6 placeholders `[NOMBRE DEL ESTUDIO]` etc. | Reemplazados por textos demo realistas en español |

→ Detalle completo en [`../products/law-firm-digital.md`](../products/law-firm-digital.md) sección 11.

---

## 8. Pendientes / Out of scope

- **Migración Tipo A → B**: el welcome.blade tiene 42 keys de config-heavy. Migrar a Tipo B (data-driven con 7 campos universales + datos de módulos) es prerequisito para el "template selector" del cliente. Trabajo grande, fuera de scope de la release inicial.
- **Vista detail del módulo team** (`team-profile.blade.php`) no auditada en profundidad — funcional pero podría tener fallback similar al listing.
- Comandos `bewpro:clean-team`, `bewpro:refresh-team`, etc. no testeados en esta sesión.

---

## 9. Referencias

- Producto: [`../products/law-firm-digital.md`](../products/law-firm-digital.md)
- Módulos consumidos: [services](../modules/services.md), [team](../modules/team.md), [blog](../modules/blog.md), [faqs](../modules/faqs.md), [references](../modules/references.md)
- Estándar canónico de demos: [`../product-readiness/estandar-demo.md`](../product-readiness/estandar-demo.md)
- Demo overrides pattern: [`DEMO-OVERRIDES-PATTERN.md`](DEMO-OVERRIDES-PATTERN.md)
- Demo checklist: [`DEMO-CHECKLIST.md`](DEMO-CHECKLIST.md)
- Bugs transversales del core: [`../products/CORE-TRANSVERSAL.md`](../products/CORE-TRANSVERSAL.md)
