Files
roi-theme/_planeacion/theme-template/THEME-DOCUMENTATION.md
FrankZamora ea38a12055 [NIVEL 2 AVANCE] Issues #49-#53 - Componentes Principales Verificados
Todos los componentes del NIVEL 2 ya están implementados correctamente:
-  Notification Bar (#49)
-  Navbar (#50)
-  Hero Section (#51)
-  Sidebar (#52)
-  Footer (#53)

Solo se actualizó notification-bar.css para usar variables CSS.

Próximo paso: NIVEL 3 (Refinamientos visuales)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-04 20:01:07 -06:00

2159 lines
63 KiB
Markdown

# Documentación del Tema WordPress - Análisis de Precios Unitarios
## 📋 Índice
1. [Visión General](#visión-general)
2. [Estructura de Archivos del Tema](#estructura-de-archivos-del-tema)
3. [Componentes del Diseño](#componentes-del-diseño)
4. [Implementación en WordPress](#implementación-en-wordpress)
5. [Funcionalidades Especiales](#funcionalidades-especiales)
6. [Optimizaciones SEO](#optimizaciones-seo)
7. [Guía de Desarrollo](#guía-de-desarrollo)
8. [Nuevas Funcionalidades de Conversión](#nuevas-funcionalidades-de-conversión)
---
## 📖 Visión General
### Propósito del Tema
Tema WordPress personalizado para un sitio de consulta de Análisis de Precios Unitarios (APUs) en el sector de construcción en México. El tema está diseñado para artículos de blog con contenido técnico denso, tablas de datos complejas y optimización SEO avanzada.
### Características Principales
- **Idioma:** Español (México) - `es-MX`
- **Framework CSS:** Bootstrap 5.3.2
- **Iconos:** Bootstrap Icons 1.11.3
- **Tipografía:** Poppins (Google Fonts)
- **Arquitectura:** Single Page Application con navegación mejorada
- **SEO:** Schema.org completo (Article, HowTo, FAQ, Video, BreadcrumbList)
- **A/B Testing:** Sistema integrado para CTAs
### Público Objetivo
Profesionales de la construcción: ingenieros civiles, arquitectos, constructores, presupuestistas que necesitan consultar estructuras de APUs, insumos y dosificaciones.
---
## 📁 Estructura de Archivos del Tema
```
wp-content/themes/apu-mexico/
├── style.css # Hoja de estilos principal (requerido por WP)
├── functions.php # Funciones del tema
├── index.php # Template principal
├── single.php # Template para posts individuales (usar aquí el diseño)
├── header.php # Encabezado del sitio
├── footer.php # Pie de página
├── sidebar.php # Sidebar (si se usa layout 2 columnas)
├── screenshot.png # Captura del tema (1200x900px)
├── assets/
│ ├── css/
│ │ └── custom-style.css # Estilos personalizados (del archivo style.css actual)
│ ├── js/
│ │ └── main.js # JavaScript personalizado (del archivo actual)
│ └── images/
│ └── (imágenes del tema)
├── template-parts/
│ ├── content-single.php # Contenido del post individual
│ ├── content-hero.php # Sección hero con título
│ ├── content-toc.php # Tabla de contenidos
│ ├── content-categories.php # Badges de categorías
│ ├── content-share.php # Botones de compartir
│ ├── content-cta.php # CTA con A/B testing
│ └── content-related-posts.php # Posts relacionados
└── inc/
├── schema-markup.php # Generación de Schema.org
├── ab-testing.php # Lógica de A/B testing
└── custom-widgets.php # Widgets personalizados
```
---
## 🎨 Componentes del Diseño
### 1. **NAVBAR (Navegación Superior)**
**Ubicación:** `header.php`
**Características:**
- Sticky (fijo al hacer scroll)
- Fondo blanco con sombra dinámica
- Logo/Título del sitio
- Menú de navegación con dropdowns
- Responsive con hamburger menu en móvil
**Estilos CSS:**
```css
.navbar {
position: sticky;
top: 0;
z-index: 1030;
background: white;
box-shadow: 0 2px 4px rgba(0,0,0,0.08);
}
.navbar.scrolled {
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
}
.nav-link {
position: relative;
transition: all 0.3s ease;
}
.nav-link::after {
/* Animación de línea inferior en hover */
content: '';
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%) scaleX(0);
width: 80%;
height: 2px;
background: linear-gradient(90deg, #0d6efd, #0dcaf0);
transition: transform 0.3s ease;
}
.nav-link:hover::after {
transform: translateX(-50%) scaleX(1);
}
```
**JavaScript:**
```javascript
// Añadir clase 'scrolled' al hacer scroll
window.addEventListener('scroll', function() {
const navbar = document.querySelector('.navbar');
if (window.scrollY > 50) {
navbar.classList.add('scrolled');
} else {
navbar.classList.remove('scrolled');
}
});
```
**Implementación WordPress:**
```php
// En functions.php
register_nav_menus(array(
'primary' => __('Menú Principal', 'apu-mexico'),
));
// En header.php
wp_nav_menu(array(
'theme_location' => 'primary',
'container' => false,
'menu_class' => 'navbar-nav mb-2 mb-lg-0',
'walker' => new Bootstrap_Nav_Walker(), // Custom walker para Bootstrap
));
```
---
### 2. **HERO SECTION (Sección de Título Principal)**
**Ubicación:** `template-parts/content-hero.php`
**Características:**
- Fondo degradado azul oscuro (#1e3a5f#2c5282)
- Badges de categorías en la parte superior
- H1 del artículo centrado
- Texto blanco con sombra para legibilidad
**Estructura HTML:**
```html
<div class="container-fluid py-5 mb-4 hero-title">
<div class="container">
<!-- Categories Section -->
<div class="mb-3 d-flex justify-content-center">
<div class="d-flex gap-2 flex-wrap justify-content-center">
<!-- Badges de categorías -->
<a href="#" class="category-badge category-badge-hero">
<i class="bi bi-folder-fill me-1"></i>
Análisis de Precios
</a>
<!-- Repetir para cada categoría -->
</div>
</div>
<!-- Título del Post -->
<h1 class="display-5 fw-bold text-center">
<?php the_title(); ?>
</h1>
</div>
</div>
```
**Estilos CSS:**
```css
.hero-title {
background: linear-gradient(135deg, #1e3a5f 0%, #2c5282 100%);
box-shadow: 0 4px 16px rgba(30, 58, 95, 0.25);
}
.hero-title h1 {
color: #ffffff !important;
font-weight: 700;
line-height: 1.4;
text-shadow: 1px 1px 2px rgba(0,0,0,0.2);
}
.category-badge-hero {
background: rgba(255, 255, 255, 0.15);
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.2);
color: rgba(255, 255, 255, 0.95);
padding: 0.375rem 0.875rem;
border-radius: 20px;
font-size: 0.813rem;
font-weight: 500;
pointer-events: none; /* No clicable, solo visual */
}
```
**Implementación WordPress:**
```php
// En template-parts/content-hero.php
<div class="container-fluid py-5 mb-4 hero-title">
<div class="container">
<!-- Categorías del post -->
<div class="mb-3 d-flex justify-content-center">
<div class="d-flex gap-2 flex-wrap justify-content-center">
<?php
$categories = get_the_category();
foreach ($categories as $category) {
echo '<span class="category-badge category-badge-hero">';
echo '<i class="bi bi-folder-fill me-1"></i>';
echo esc_html($category->name);
echo '</span>';
}
?>
</div>
</div>
<!-- Título -->
<h1 class="display-5 fw-bold text-center">
<?php the_title(); ?>
</h1>
</div>
</div>
```
---
### 3. **LAYOUT PRINCIPAL (Contenido + Sidebar)**
**Ubicación:** `single.php`
**Características:**
- Grid de Bootstrap: 9 columnas (contenido) + 3 columnas (sidebar)
- Responsive: En móvil el sidebar va abajo
- Sidebar con TOC sticky
**Estructura HTML:**
```html
<div class="container">
<div class="row">
<!-- Columna de Contenido (9/12) -->
<div class="col-lg-9">
<!-- Imagen destacada -->
<div class="featured-image-container my-4">
<?php the_post_thumbnail('large', ['class' => 'img-fluid']); ?>
</div>
<!-- Contenido del post -->
<div class="post-content">
<?php the_content(); ?>
</div>
<!-- Compartir en redes -->
<?php get_template_part('template-parts/content', 'share'); ?>
<!-- CTA con A/B Testing -->
<?php get_template_part('template-parts/content', 'cta'); ?>
<!-- Posts relacionados -->
<?php get_template_part('template-parts/content', 'related-posts'); ?>
</div>
<!-- Sidebar / TOC (3/12) -->
<div class="col-lg-3">
<?php get_template_part('template-parts/content', 'toc'); ?>
</div>
</div>
</div>
```
---
### 4. **TABLA DE CONTENIDOS (TOC)**
**Ubicación:** `template-parts/content-toc.php`
**Características:**
- Sticky (se mantiene visible al hacer scroll)
- Generación automática desde los H2 del contenido
- Resaltado del elemento activo con ScrollSpy
- Smooth scroll al hacer clic
**Estructura HTML:**
```html
<div class="toc-container position-sticky" style="top: 5rem;">
<h4>Tabla de Contenido</h4>
<ol class="list-unstyled">
<li><a href="#introduccion">Introducción</a></li>
<li><a href="#alternativas">Alternativas</a></li>
<li><a href="#proceso">Proceso de Elaboración</a></li>
<!-- Generado automáticamente desde H2s -->
</ol>
</div>
```
**Estilos CSS:**
```css
.toc-container {
top: 5rem;
background: #f8f9fa;
border: 1px solid #e9ecef;
border-radius: 12px;
box-shadow: 0 4px 16px rgba(0,0,0,0.08);
padding: 1rem 1.25rem;
}
.toc-container h4 {
color: #2c3e50;
padding-bottom: 12px;
border-bottom: 3px solid #0d6efd;
margin-bottom: 1rem;
font-weight: 700;
text-align: center;
font-style: normal;
}
.toc-container li {
margin-bottom: 0.25rem;
}
.toc-container a {
display: block;
padding: 0.375rem 1rem;
color: #495057;
text-decoration: none;
border-left: 3px solid transparent;
transition: all 0.3s ease;
border-radius: 4px;
}
.toc-container a:hover {
background: linear-gradient(90deg, rgba(13, 110, 253, 0.08), transparent);
border-left-color: #0d6efd;
color: #0d6efd;
padding-left: 1.5rem;
}
.toc-container a.active {
background: linear-gradient(90deg, rgba(13, 110, 253, 0.12), transparent);
border-left-color: #0d6efd;
color: #0d6efd;
font-weight: 600;
}
```
**JavaScript (ScrollSpy Mejorado):**
```javascript
// ScrollSpy mejorado para TOC
function updateActiveSection() {
const tocLinks = document.querySelectorAll('.toc-container a');
const navbar = document.querySelector('.navbar');
const navbarHeight = navbar ? navbar.offsetHeight : 0;
// Obtener todas las secciones referenciadas en el TOC
const sectionIds = Array.from(tocLinks).map(link => {
const href = link.getAttribute('href');
return href ? href.substring(1) : null;
}).filter(id => id !== null);
const sections = sectionIds.map(id => document.getElementById(id)).filter(el => el !== null);
// Punto de activación: navbar + 100px
const scrollPosition = window.scrollY + navbarHeight + 100;
let activeSection = null;
// Recorrer secciones de arriba hacia abajo
for (let i = 0; i < sections.length; i++) {
const section = sections[i];
const sectionTop = section.offsetTop;
if (scrollPosition >= sectionTop) {
activeSection = section.getAttribute('id');
} else {
break;
}
}
// Actualizar clases active
tocLinks.forEach(link => {
link.classList.remove('active');
const href = link.getAttribute('href');
if (href === '#' + activeSection) {
link.classList.add('active');
}
});
}
// Smooth scroll para TOC links
document.querySelectorAll('.toc-container a').forEach(anchor => {
anchor.addEventListener('click', function (e) {
e.preventDefault();
const targetId = this.getAttribute('href');
const targetElement = document.querySelector(targetId);
if (targetElement) {
const navbarHeight = document.querySelector('.navbar').offsetHeight;
const offsetTop = targetElement.offsetTop - navbarHeight - 40;
window.scrollTo({
top: offsetTop,
behavior: 'smooth'
});
}
});
});
window.addEventListener('scroll', updateActiveSection);
document.addEventListener('DOMContentLoaded', updateActiveSection);
```
**Implementación WordPress:**
```php
// En functions.php - Generar TOC automáticamente
function generate_table_of_contents($content) {
preg_match_all('/<h2[^>]*id="([^"]*)"[^>]*>(.*?)<\/h2>/i', $content, $matches);
if (empty($matches[1])) {
return '';
}
$toc = '<div class="toc-container position-sticky" style="top: 5rem;">';
$toc .= '<h4>Tabla de Contenido</h4>';
$toc .= '<ol class="list-unstyled">';
foreach ($matches[1] as $index => $id) {
$title = strip_tags($matches[2][$index]);
$toc .= '<li><a href="#' . esc_attr($id) . '">' . esc_html($title) . '</a></li>';
}
$toc .= '</ol></div>';
return $toc;
}
// En template-parts/content-toc.php
<?php
global $post;
$toc = generate_table_of_contents($post->post_content);
echo $toc;
?>
```
---
### 5. **TABLAS DE ANÁLISIS DE PRECIOS UNITARIOS**
**CARACTERÍSTICAS CRÍTICAS:**
**Estructura HTML Semántica:**
```html
<div class="analisis">
<table>
<thead>
<tr>
<th scope="col">Clave</th>
<th scope="col">Descripción</th>
<th scope="col">Unidad</th>
<th scope="col">Cantidad</th>
<th scope="col">Costo</th>
<th scope="col">Importe</th>
</tr>
</thead>
<tbody>
<!-- Encabezado de sección -->
<tr class="section-header">
<td></td>
<td>Material</td>
<td class="c3"></td>
<td class="c4"></td>
<td class="c5"></td>
<td class="c6"></td>
</tr>
<!-- Fila de datos -->
<tr>
<td>AGRE-016</td>
<td>Agua potable</td>
<td class="c3">m3</td>
<td class="c4">0.237500</td>
<td class="c5">$19.14</td>
<td class="c6">$4.55</td>
</tr>
<!-- Subtotal -->
<tr class="subtotal-row">
<td></td>
<td>Suma de Material</td>
<td class="c3"></td>
<td class="c4"></td>
<td class="c5"></td>
<td class="c6">$2,956.51</td>
</tr>
<!-- Total final -->
<tr class="total-row">
<td></td>
<td>Costo Directo</td>
<td class="c3"></td>
<td class="c4"></td>
<td class="c5"></td>
<td class="c6">$3,283.52</td>
</tr>
</tbody>
</table>
</div>
```
**Estilos CSS (MUY IMPORTANTE - NO MODIFICAR SIN CUIDADO):**
```css
.analisis {
margin: 2rem 0;
overflow-x: auto;
}
.analisis table {
width: 100%;
border-collapse: collapse;
background: #ffffff;
box-shadow: 0 2px 8px rgba(0,0,0,0.08);
border-radius: 8px;
overflow: hidden;
border: none;
border-spacing: 0;
}
/* CRÍTICO: Eliminar todos los bordes */
.analisis table td,
.analisis table tbody,
.analisis table tr {
border: none;
}
/* Anchos fijos para columnas */
.analisis table td:nth-child(1) { width: 150px; } /* Clave */
.analisis table td:nth-child(2) { width: auto; min-width: 300px; } /* Descripción */
.analisis table td:nth-child(3) { width: 80px; } /* Unidad */
.analisis table td:nth-child(4) { width: 110px; } /* Cantidad */
.analisis table td:nth-child(5) { width: 120px; } /* Costo */
.analisis table td:nth-child(6) { width: 120px; } /* Importe */
/* Encabezados (thead) con fondo azul oscuro */
.analisis table thead tr th {
background: linear-gradient(135deg, #1e3a5f 0%, #2c5282 100%);
color: #ffffff;
font-weight: 600;
text-align: center !important;
padding: 1rem;
border: none;
}
/* Filas de datos normales */
.analisis table tbody td {
padding: 0.75rem 1rem;
border: none;
}
/* Zebra striping (filas alternadas) */
.analisis table tbody tr:nth-child(even):not(.section-header):not(.subtotal-row):not(.total-row) {
background-color: #f8f9fa;
}
.analisis table tbody tr:nth-child(odd):not(.section-header):not(.subtotal-row):not(.total-row) {
background-color: #ffffff;
}
/* Alineación de columnas */
.analisis table td:nth-child(1),
.analisis table td:nth-child(2) {
text-align: left;
}
/* Columna Unidad (3) centrada */
.analisis table td:nth-child(3),
.analisis table td.c3 {
text-align: center !important;
color: #6c757d;
}
/* Columnas monetarias a la derecha */
.analisis table td:nth-child(4),
.analisis table td.c4,
.analisis table td:nth-child(5),
.analisis table td.c5,
.analisis table td:nth-child(6),
.analisis table td.c6 {
text-align: right !important;
font-family: 'Courier New', monospace;
font-weight: 500;
}
/* Hover en filas de datos */
.analisis table tbody tr:not(.section-header):not(.subtotal-row):not(.total-row):hover {
background-color: #fff3cd !important;
transition: background-color 0.2s ease;
cursor: pointer;
}
/* Encabezados de sección (Material, Mano de Obra, etc.) */
.analisis table tr.section-header {
background-color: #e9ecef !important;
}
.analisis table tr.section-header td {
font-weight: 600;
color: #1e3a5f;
padding: 0.75rem 1rem;
border: none !important;
}
/* Filas de subtotales */
.analisis table tr.subtotal-row {
background-color: #d1e7fd !important;
}
.analisis table tr.subtotal-row td {
font-weight: 700;
color: #0d47a1;
padding: 0.875rem 1rem;
border: none !important;
}
.analisis table tr.subtotal-row td.c6 {
font-size: 1.05rem;
}
/* Fila de Costo Directo (Total final) */
.analisis table tr.total-row {
background: linear-gradient(135deg, #1e3a5f 0%, #2c5282 100%) !important;
}
.analisis table tr.total-row td {
color: #ffffff !important;
font-weight: 700;
font-size: 1.1rem;
padding: 1.125rem 1rem !important;
border: none !important;
}
.analisis table tr.total-row td.c6 {
font-size: 1.25rem;
letter-spacing: 0.5px;
}
/* Responsive para móviles */
@media (max-width: 768px) {
.analisis {
font-size: 0.85rem;
}
.analisis table td {
padding: 0.5rem !important;
}
.analisis table tr.total-row td {
font-size: 1rem !important;
}
}
```
**⚠️ IMPORTANTE PARA EL DESARROLLADOR:**
- **NO usar `<caption>`** - arruina el diseño
- Los encabezados solo van en `<thead>`, no en `<tbody>`
- Las clases `c3`, `c4`, `c5`, `c6` son para alineación específica
- `section-header`, `subtotal-row`, `total-row` son clases especiales
---
### 6. **COMPARTIR EN REDES SOCIALES**
**Ubicación:** `template-parts/content-share.php`
**Características:**
- Botones para: Facebook, Instagram, LinkedIn, WhatsApp, X (Twitter), Email
- Iconos de Bootstrap Icons
- Estilo outline con colores de marca
**Estructura HTML:**
```html
<div class="my-5 py-4 border-top">
<p class="mb-3 text-muted">Compartir:</p>
<div class="d-flex gap-2 flex-wrap share-buttons">
<a href="#" class="btn btn-outline-primary btn-sm" aria-label="Compartir en Facebook">
<i class="bi bi-facebook"></i>
</a>
<a href="#" class="btn btn-outline-danger btn-sm" aria-label="Compartir en Instagram">
<i class="bi bi-instagram"></i>
</a>
<a href="#" class="btn btn-outline-info btn-sm" aria-label="Compartir en LinkedIn">
<i class="bi bi-linkedin"></i>
</a>
<a href="#" class="btn btn-outline-success btn-sm" aria-label="Compartir en WhatsApp">
<i class="bi bi-whatsapp"></i>
</a>
<a href="#" class="btn btn-outline-dark btn-sm" aria-label="Compartir en X">
<i class="bi bi-twitter-x"></i>
</a>
<a href="#" class="btn btn-outline-secondary btn-sm" aria-label="Compartir por Email">
<i class="bi bi-envelope"></i>
</a>
</div>
</div>
```
**Estilos CSS:**
```css
.share-buttons .btn {
transition: all 0.3s ease;
border-width: 2px;
}
.share-buttons .btn:hover {
transform: translateY(-3px) scale(1.1);
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
}
```
**Implementación WordPress (URLs dinámicas):**
```php
<?php
$post_url = urlencode(get_permalink());
$post_title = urlencode(get_the_title());
?>
<div class="my-5 py-4 border-top">
<p class="mb-3 text-muted">Compartir:</p>
<div class="d-flex gap-2 flex-wrap share-buttons">
<a href="https://www.facebook.com/sharer/sharer.php?u=<?php echo $post_url; ?>"
target="_blank"
class="btn btn-outline-primary btn-sm">
<i class="bi bi-facebook"></i>
</a>
<a href="https://www.linkedin.com/sharing/share-offsite/?url=<?php echo $post_url; ?>"
target="_blank"
class="btn btn-outline-info btn-sm">
<i class="bi bi-linkedin"></i>
</a>
<a href="https://wa.me/?text=<?php echo $post_title . ' ' . $post_url; ?>"
target="_blank"
class="btn btn-outline-success btn-sm">
<i class="bi bi-whatsapp"></i>
</a>
<a href="https://twitter.com/intent/tweet?text=<?php echo $post_title; ?>&url=<?php echo $post_url; ?>"
target="_blank"
class="btn btn-outline-dark btn-sm">
<i class="bi bi-twitter-x"></i>
</a>
<a href="mailto:?subject=<?php echo $post_title; ?>&body=<?php echo $post_url; ?>"
class="btn btn-outline-secondary btn-sm">
<i class="bi bi-envelope"></i>
</a>
</div>
</div>
```
---
### 7. **CTA CON A/B TESTING**
**Ubicación:** `template-parts/content-cta.php`
**Características:**
- **Test A/B con 2 variantes:**
- **Variante A:** Enfoque en catálogo (200,000+ APUs)
- **Variante B:** Enfoque en membresía
- Rotación aleatoria 50/50 en cada carga de página
- Tracking de clics para Google Analytics
- Fondo degradado naranja-amarillo
**Estructura HTML:**
```html
<!-- Variante A -->
<div class="my-5 p-4 rounded cta-section cta-variant-a" data-variant="A" style="display: none;">
<div class="row align-items-center">
<div class="col-md-8">
<h3 class="h4 fw-bold text-white mb-2">Accede a 200,000+ Análisis de Precios Unitarios</h3>
<p class="text-white mb-md-0">Consulta estructuras completas, insumos y dosificaciones de los APUs más utilizados en construcción en México.</p>
</div>
<div class="col-md-4 text-md-end mt-3 mt-md-0">
<a href="#" class="btn btn-light btn-lg cta-button" data-cta-variant="A">
Ver Catálogo Completo <i class="bi bi-arrow-right ms-2"></i>
</a>
</div>
</div>
</div>
<!-- Variante B -->
<div class="my-5 p-4 rounded cta-section cta-variant-b" data-variant="B" style="display: none;">
<div class="row align-items-center">
<div class="col-md-8">
<h3 class="h4 fw-bold text-white mb-2">¿Necesitas Consultar Más APUs?</h3>
<p class="text-white mb-md-0">Accede a nuestra biblioteca de 200,000 análisis de precios unitarios con estructuras detalladas y listados de insumos.</p>
</div>
<div class="col-md-4 text-md-end mt-3 mt-md-0">
<a href="#" class="btn btn-light btn-lg cta-button" data-cta-variant="B">
Conocer Planes de Membresía <i class="bi bi-arrow-right ms-2"></i>
</a>
</div>
</div>
</div>
```
**Estilos CSS:**
```css
.cta-section {
background: linear-gradient(135deg, #FF8600 0%, #FFB800 100%);
box-shadow: 0 8px 24px rgba(255, 133, 0, 0.3);
}
```
**JavaScript A/B Testing:**
```javascript
// A/B Test para CTA - Rotación en cada carga de página
document.addEventListener('DOMContentLoaded', function() {
// Selección aleatoria 50/50 entre A y B
const ctaVariant = Math.random() < 0.5 ? 'A' : 'B';
// Mostrar la variante seleccionada
if (ctaVariant === 'A') {
document.querySelector('.cta-variant-a').style.display = 'block';
} else {
document.querySelector('.cta-variant-b').style.display = 'block';
}
// Tracking de clicks para Google Analytics
document.querySelectorAll('.cta-button').forEach(button => {
button.addEventListener('click', function(e) {
const variant = this.getAttribute('data-cta-variant');
if (typeof gtag !== 'undefined') {
gtag('event', 'cta_click', {
'event_category': 'CTA',
'event_label': 'Variant_' + variant,
'value': variant
});
}
console.log('CTA clicked - Variant: ' + variant);
});
});
});
```
**Implementación WordPress:**
```php
// En template-parts/content-cta.php
<div class="my-5 p-4 rounded cta-section cta-variant-a" data-variant="A" style="background: linear-gradient(135deg, #FF8600 0%, #FFB800 100%); display: none;">
<div class="row align-items-center">
<div class="col-md-8">
<h3 class="h4 fw-bold text-white mb-2">Accede a 200,000+ Análisis de Precios Unitarios</h3>
<p class="text-white mb-md-0">Consulta estructuras completas, insumos y dosificaciones de los APUs más utilizados en construcción en México.</p>
</div>
<div class="col-md-4 text-md-end mt-3 mt-md-0">
<a href="<?php echo home_url('/catalogo'); ?>" class="btn btn-light btn-lg cta-button" data-cta-variant="A">
Ver Catálogo Completo <i class="bi bi-arrow-right ms-2"></i>
</a>
</div>
</div>
</div>
<div class="my-5 p-4 rounded cta-section cta-variant-b" data-variant="B" style="background: linear-gradient(135deg, #FF8600 0%, #FFB800 100%); display: none;">
<div class="row align-items-center">
<div class="col-md-8">
<h3 class="h4 fw-bold text-white mb-2">¿Necesitas Consultar Más APUs?</h3>
<p class="text-white mb-md-0">Accede a nuestra biblioteca de 200,000 análisis de precios unitarios con estructuras detalladas y listados de insumos.</p>
</div>
<div class="col-md-4 text-md-end mt-3 mt-md-0">
<a href="<?php echo home_url('/membresia'); ?>" class="btn btn-light btn-lg cta-button" data-cta-variant="B">
Conocer Planes de Membresía <i class="bi bi-arrow-right ms-2"></i>
</a>
</div>
</div>
</div>
```
---
### 8. **POSTS RELACIONADOS**
**Ubicación:** `template-parts/content-related-posts.php`
**Características:**
- Grid de 3 columnas (4 en desktop, 6 en tablet, 12 en móvil)
- 12 posts relacionados
- Cards con diseño minimalista gris
- Borde izquierdo de 4px que cambia a azul en hover
- Paginación con Bootstrap
**Estructura HTML:**
```html
<div class="my-5 related-posts">
<h2 class="h3 mb-4">Descubre Más Contenido</h2>
<div class="row g-4">
<!-- Card de post relacionado -->
<div class="col-md-4">
<div class="card h-100">
<div class="card-body">
<h3 class="card-title">Título del Post</h3>
<p class="card-text text-muted small">Breve descripción...</p>
</div>
</div>
</div>
<!-- Repetir 12 veces -->
</div>
<!-- Paginación -->
<nav aria-label="Navegación de posts relacionados" class="mt-5">
<ul class="pagination justify-content-center">
<li class="page-item"><a class="page-link" href="#">Inicio</a></li>
<li class="page-item active"><a class="page-link" href="#">1</a></li>
<li class="page-item"><a class="page-link" href="#">2</a></li>
<li class="page-item"><a class="page-link" href="#">3</a></li>
<li class="page-item"><a class="page-link" href="#">4</a></li>
<li class="page-item"><a class="page-link" href="#">5</a></li>
<li class="page-item"><a class="page-link" href="#">Ver más</a></li>
<li class="page-item"><a class="page-link" href="#">Fin</a></li>
</ul>
</nav>
</div>
```
**Estilos CSS:**
```css
.related-posts .card {
cursor: pointer;
background: #f8f9fa !important;
border: 1px solid #dee2e6 !important;
border-left: 4px solid #6c757d !important;
transition: all 0.3s ease;
}
.related-posts .card:hover {
background: #ffffff !important;
box-shadow: 0 4px 12px rgba(0,0,0,0.1) !important;
border-left-color: #0d6efd !important;
}
.related-posts .card-body {
padding: 2rem !important;
}
.related-posts .card-title {
color: #495057 !important;
font-weight: 600;
font-size: 0.95rem;
}
/* Paginación */
.pagination .page-link {
color: #495057;
border: 1px solid #dee2e6;
padding: 0.5rem 1rem;
margin: 0 0.25rem;
border-radius: 4px;
font-weight: 500;
transition: all 0.3s ease;
}
.pagination .page-link:hover {
background-color: #f8f9fa;
border-color: #0d6efd;
color: #0d6efd;
}
.pagination .page-item.active .page-link {
background-color: #1e3a5f;
border-color: #1e3a5f;
color: #ffffff;
}
```
**Implementación WordPress:**
```php
<?php
// Obtener posts relacionados por categoría
$categories = get_the_category();
$category_ids = array();
foreach($categories as $category) {
$category_ids[] = $category->term_id;
}
$args = array(
'category__in' => $category_ids,
'post__not_in' => array(get_the_ID()),
'posts_per_page' => 12,
'orderby' => 'rand'
);
$related_posts = new WP_Query($args);
if ($related_posts->have_posts()) : ?>
<div class="my-5 related-posts">
<h2 class="h3 mb-4">Descubre Más Contenido</h2>
<div class="row g-4">
<?php while ($related_posts->have_posts()) : $related_posts->the_post(); ?>
<div class="col-md-4">
<div class="card h-100">
<div class="card-body">
<h3 class="card-title">
<a href="<?php the_permalink(); ?>">
<?php the_title(); ?>
</a>
</h3>
<p class="card-text text-muted small">
<?php echo wp_trim_words(get_the_excerpt(), 15); ?>
</p>
</div>
</div>
</div>
<?php endwhile; ?>
</div>
</div>
<?php endif; wp_reset_postdata(); ?>
```
---
## 🔍 Optimizaciones SEO
### **1. Schema.org / JSON-LD**
**Ubicación:** `inc/schema-markup.php`
**Schemas implementados:**
1. **Article** - Información básica del artículo
2. **HowTo** - Proceso paso a paso (para sección de elaboración)
3. **FAQPage** - Preguntas frecuentes
4. **VideoObject** - Videos relacionados
5. **BreadcrumbList** - Navegación jerárquica
**Implementación WordPress:**
```php
<?php
// En inc/schema-markup.php
function apu_generate_article_schema() {
if (!is_single()) return;
global $post;
$schema = array(
'@context' => 'https://schema.org',
'@type' => 'Article',
'headline' => get_the_title(),
'description' => get_the_excerpt(),
'image' => get_the_post_thumbnail_url($post->ID, 'full'),
'datePublished' => get_the_date('c'),
'dateModified' => get_the_modified_date('c'),
'author' => array(
'@type' => 'Organization',
'name' => get_bloginfo('name')
),
'publisher' => array(
'@type' => 'Organization',
'name' => get_bloginfo('name'),
'logo' => array(
'@type' => 'ImageObject',
'url' => get_site_icon_url()
)
),
'mainEntityOfPage' => array(
'@type' => 'WebPage',
'@id' => get_permalink()
),
'articleSection' => 'Análisis de Precios Unitarios',
'keywords' => implode(', ', wp_get_post_tags($post->ID, array('fields' => 'names')))
);
echo '<script type="application/ld+json">' . json_encode($schema, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . '</script>';
}
add_action('wp_head', 'apu_generate_article_schema');
function apu_generate_breadcrumb_schema() {
if (!is_single()) return;
$categories = get_the_category();
$category = !empty($categories) ? $categories[0] : null;
$schema = array(
'@context' => 'https://schema.org',
'@type' => 'BreadcrumbList',
'itemListElement' => array(
array(
'@type' => 'ListItem',
'position' => 1,
'name' => 'Inicio',
'item' => home_url('/')
),
array(
'@type' => 'ListItem',
'position' => 2,
'name' => 'Blog',
'item' => home_url('/blog')
)
)
);
if ($category) {
$schema['itemListElement'][] = array(
'@type' => 'ListItem',
'position' => 3,
'name' => $category->name,
'item' => get_category_link($category->term_id)
);
}
$schema['itemListElement'][] = array(
'@type' => 'ListItem',
'position' => 4,
'name' => get_the_title(),
'item' => get_permalink()
);
echo '<script type="application/ld+json">' . json_encode($schema, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . '</script>';
}
add_action('wp_head', 'apu_generate_breadcrumb_schema');
// FAQ Schema
function apu_generate_faq_schema() {
if (!is_single()) return;
// Buscar H3 que contengan "?" en el contenido
global $post;
preg_match_all('/<h3[^>]*>(.*?\?[^<]*)<\/h3>\s*<p>(.*?)<\/p>/is', $post->post_content, $matches);
if (empty($matches[1])) return;
$faq_items = array();
for ($i = 0; $i < count($matches[1]); $i++) {
$faq_items[] = array(
'@type' => 'Question',
'name' => strip_tags($matches[1][$i]),
'acceptedAnswer' => array(
'@type' => 'Answer',
'text' => strip_tags($matches[2][$i])
)
);
}
if (empty($faq_items)) return;
$schema = array(
'@context' => 'https://schema.org',
'@type' => 'FAQPage',
'mainEntity' => $faq_items
);
echo '<script type="application/ld+json">' . json_encode($schema, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . '</script>';
}
add_action('wp_head', 'apu_generate_faq_schema');
```
### **2. Meta Tags**
**En `header.php`:**
```php
<head>
<meta charset="<?php bloginfo('charset'); ?>">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<?php if (is_single()) : ?>
<meta name="description" content="<?php echo esc_attr(wp_trim_words(get_the_excerpt(), 30)); ?>">
<meta property="og:type" content="article">
<meta property="og:title" content="<?php the_title(); ?>">
<meta property="og:description" content="<?php echo esc_attr(get_the_excerpt()); ?>">
<meta property="og:image" content="<?php echo get_the_post_thumbnail_url(get_the_ID(), 'large'); ?>">
<meta property="og:url" content="<?php the_permalink(); ?>">
<link rel="canonical" href="<?php the_permalink(); ?>">
<?php endif; ?>
<?php wp_head(); ?>
</head>
```
---
## ⚙️ Implementación en WordPress
### **1. Enqueue de Assets**
**En `functions.php`:**
```php
function apu_enqueue_assets() {
// Bootstrap CSS
wp_enqueue_style('bootstrap', 'https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css');
// Bootstrap Icons
wp_enqueue_style('bootstrap-icons', 'https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css');
// Google Fonts
wp_enqueue_style('google-fonts-poppins', 'https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap');
// Custom CSS
wp_enqueue_style('apu-custom-style', get_template_directory_uri() . '/assets/css/custom-style.css', array(), '1.0.0');
// Bootstrap JS
wp_enqueue_script('bootstrap-js', 'https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js', array(), '5.3.2', true);
// Custom JS
wp_enqueue_script('apu-main-js', get_template_directory_uri() . '/assets/js/main.js', array(), '1.0.0', true);
}
add_action('wp_enqueue_scripts', 'apu_enqueue_assets');
```
### **2. Soporte de Características**
**En `functions.php`:**
```php
function apu_theme_support() {
// Título dinámico
add_theme_support('title-tag');
// Imagen destacada
add_theme_support('post-thumbnails');
set_post_thumbnail_size(1200, 630, true);
// HTML5
add_theme_support('html5', array('search-form', 'comment-form', 'comment-list', 'gallery', 'caption'));
// Menús
register_nav_menus(array(
'primary' => __('Menú Principal', 'apu-mexico'),
'footer' => __('Menú Footer', 'apu-mexico')
));
}
add_action('after_setup_theme', 'apu_theme_support');
```
### **3. Custom Post Meta (si necesitas)**
```php
function apu_add_custom_meta_boxes() {
add_meta_box(
'apu_details',
'Detalles del APU',
'apu_meta_box_callback',
'post',
'normal',
'high'
);
}
add_action('add_meta_boxes', 'apu_add_custom_meta_boxes');
function apu_meta_box_callback($post) {
// Campos personalizados para el APU
$apu_code = get_post_meta($post->ID, '_apu_code', true);
$apu_unit = get_post_meta($post->ID, '_apu_unit', true);
?>
<p>
<label>Código APU:</label>
<input type="text" name="apu_code" value="<?php echo esc_attr($apu_code); ?>" />
</p>
<p>
<label>Unidad:</label>
<input type="text" name="apu_unit" value="<?php echo esc_attr($apu_unit); ?>" />
</p>
<?php
}
```
---
## 📝 Guía de Desarrollo
### **Paso 1: Configuración Inicial**
1. Crear carpeta del tema en `wp-content/themes/apu-mexico/`
2. Crear `style.css` con header requerido:
```css
/*
Theme Name: APU México
Theme URI: https://analisisdepreciosunitarios.com
Author: Tu Nombre
Description: Tema personalizado para análisis de precios unitarios
Version: 1.0
License: GNU General Public License v2 or later
Text Domain: apu-mexico
*/
```
3. Crear `functions.php` e `index.php` básicos
### **Paso 2: Estructura HTML Base**
1. Crear `header.php` con:
- Meta tags
- Enqueue de assets
- Navbar
2. Crear `footer.php` con:
- Footer content
- `wp_footer()`
3. Crear `single.php` como template principal para posts
### **Paso 3: Template Parts**
Crear todos los archivos en `template-parts/`:
- `content-hero.php`
- `content-toc.php`
- `content-share.php`
- `content-cta.php`
- `content-related-posts.php`
### **Paso 4: Assets**
1. Copiar todos los estilos CSS del archivo actual a `assets/css/custom-style.css`
2. Copiar JavaScript a `assets/js/main.js`
3. Asegurar que los paths sean correctos
### **Paso 5: Schema.org**
Crear `inc/schema-markup.php` con todas las funciones de generación de schemas
### **Paso 6: Testing**
1. Validar HTML: https://validator.w3.org/
2. Validar Schema: https://search.google.com/test/rich-results
3. Test responsive con DevTools
4. Test A/B del CTA
5. Test ScrollSpy del TOC
### **Paso 7: Optimizaciones Finales**
1. Minificar CSS y JS para producción
2. Optimizar imágenes
3. Configurar cache
4. Test de velocidad con PageSpeed Insights
---
## 🚨 Notas Importantes para el Desarrollador
### **CRÍTICO - NO MODIFICAR:**
1. **Estructura de tablas:** Los estilos CSS de `.analisis table` son muy específicos y fueron ajustados múltiples veces. NO cambiar sin probar exhaustivamente.
2. **A/B Testing:** El JavaScript debe ejecutarse en `DOMContentLoaded` y NO usar `sessionStorage` (debe rotar en cada carga).
3. **TOC ScrollSpy:** El algoritmo de detección de sección activa es específico y funciona correctamente. No simplificar.
4. **Schema.org:** Todos los schemas deben ser JSON-LD, NO microdata.
5. **Idioma:** Siempre `es-MX`, no `es` genérico.
### **RECOMENDACIONES:**
1. Usar un child theme para customizaciones futuras
2. Implementar cache de Schema.org para mejorar performance
3. Considerar lazy loading para imágenes de posts relacionados
4. Implementar sistema de comentarios con Disqus o similar
5. Agregar breadcrumbs visuales opcionales (actualmente solo están en Schema)
---
## 📊 Métricas de Éxito
### **SEO:**
- Schema.org validado sin errores
- Core Web Vitals en verde
- Meta descriptions únicas en todos los posts
### **UX:**
- TOC funcional con smooth scroll
- Tables responsive en móvil
- Tiempo de carga < 3 segundos
### **Conversión:**
- CTR del CTA > 5%
- Tasa de rebote < 60%
- Tiempo en página > 3 minutos
---
## 🆕 Nuevas Funcionalidades Implementadas
### **1. Botón "Let's Talk" en Navbar**
**Descripción:**
Botón CTA (Call-to-Action) destacado en color naranja/coral ubicado en el navbar que abre un modal de contacto.
**Ubicación en el código:**
- HTML: `index.html` - línea 304-306
- CSS: `css/style.css` - líneas 491-516
- JS: `js/main.js` - líneas 122-143
**Características:**
- Color naranja vibrante (#FF6B35) que contrasta con la paleta azul del sitio
- Icono de rayo para llamar la atención
- Efecto hover con elevación y cambio de sombra
- Responsive: se adapta a móvil (width: 100%)
- Abre modal de contacto al hacer click
**Código HTML:**
```html
<button class="btn btn-lets-talk ms-lg-3" data-bs-toggle="modal" data-bs-target="#contactModal">
<i class="bi bi-lightning-charge-fill me-2"></i>Let's Talk
</button>
```
---
### **2. CTA Box "¿Listo para potenciar tus proyectos?" en Sidebar**
**Descripción:**
Caja de llamada a la acción ubicada debajo de la Tabla de Contenidos (TOC) en el sidebar derecho, con diseño atractivo en gradiente naranja-amarillo.
**Ubicación en el código:**
- HTML: `index.html` - líneas 1175-1185
- CSS: `css/style.css` - líneas 554-649
**Características:**
- Gradiente naranja-amarillo (#FF8600#FFB800) alineado con industria de construcción
- Animación de pulso sutil en el fondo
- Icono animado con efecto bounce
- Botón blanco con texto naranja que invierte colores al hover
- Efecto elevación al pasar el mouse
- Sticky junto con la TOC
**Código HTML:**
```html
<div class="cta-box-sidebar mt-4">
<div class="cta-box-icon">
<i class="bi bi-lightning-charge-fill"></i>
</div>
<h5 class="cta-box-title">¿Listo para potenciar tus proyectos?</h5>
<p class="cta-box-text">Accede a nuestra biblioteca completa de APUs y herramientas profesionales.</p>
<button class="btn btn-cta-box w-100" data-bs-toggle="modal" data-bs-target="#contactModal">
<i class="bi bi-calendar-check me-2"></i>Solicitar Demo
</button>
</div>
```
---
### **3. Modal de Contacto con Envío a Webhook**
**Descripción:**
Formulario de contacto en modal emergente que se carga dinámicamente desde un archivo independiente y envía datos a un webhook mediante JavaScript.
**Archivos:**
- **Modal HTML:** `modal-contact.html` (archivo independiente)
- **JavaScript:** `js/main.js` - líneas 145-256
- **CSS:** `css/style.css` - líneas 651-735
- **Contenedor:** `index.html` - línea 1240
**Características del formulario:**
- **Campos:**
- Nombre completo* (requerido)
- Empresa (opcional)
- WhatsApp* (requerido)
- Correo electrónico* (requerido)
- Comentarios (opcional)
- **Validaciones:**
- Campos obligatorios
- Formato de email válido
- Formato de WhatsApp válido (10-15 dígitos)
- Mensajes de error descriptivos
- **Envío a Webhook:**
- Método: POST con fetch API
- Headers: Content-Type: application/json
- Body: JSON con todos los datos del formulario + timestamp + source
- Manejo de errores con try/catch
- Spinner en botón durante envío
- Cierre automático del modal tras éxito (2 segundos)
**Configuración del Webhook:**
1. Abre el archivo `js/main.js`
2. Busca la línea 198:
```javascript
const WEBHOOK_URL = 'https://tu-webhook.com/contacto';
```
3. Reemplaza con tu URL de webhook real
**Ejemplo de datos enviados al webhook:**
```json
{
"fullName": "Juan Pérez",
"company": "Constructora XYZ",
"whatsapp": "+52 55 1234 5678",
"email": "juan@ejemplo.com",
"comments": "Me interesa conocer más sobre sus servicios",
"timestamp": "2025-01-15T10:30:00.000Z",
"source": "APU Website - Let's Talk Button"
}
```
**Servicios de Webhook recomendados:**
- **Make (Integromat):** https://www.make.com
- **Zapier:** https://zapier.com
- **Webhook.site** (para testing): https://webhook.site
- **n8n** (self-hosted): https://n8n.io
- **Pipedream:** https://pipedream.com
---
### **4. Optimización de la Tabla de Contenidos (TOC)**
**Mejoras implementadas:**
**A) Max-height con scroll:**
- Altura máxima: 450px (desktop), 300px (móvil)
- Scroll vertical automático cuando el contenido excede
- Scrollbar personalizado:
- Ancho: 6px
- Color: azul Bootstrap (#0d6efd)
- Track: gris claro
- Hover: azul más oscuro
**B) Reducción de espaciado:**
- Margin entre items: 0.15rem (antes: 0.25rem)
- Padding de links: 0.3rem 0.85rem (antes: 0.375rem 1rem)
- Font-size: 0.9rem (antes: 0.95rem)
- Clase agregada: `toc-list` en el `<ol>`
**Ubicación en el código:**
- HTML: `index.html` - línea 1155 (clase `toc-list` agregada)
- CSS: `css/style.css` - líneas 518-552
**Código CSS clave:**
```css
.toc-list {
max-height: 450px;
overflow-y: auto;
padding-right: 0.5rem;
}
.toc-list::-webkit-scrollbar {
width: 6px;
}
.toc-list::-webkit-scrollbar-thumb {
background: #0d6efd;
border-radius: 3px;
}
```
---
### **Paleta de Colores para CTAs**
**Decisión de diseño:**
Se eligieron colores naranjas/cálidos para los CTAs por las siguientes razones:
1. **Contraste visual:** Destacan perfectamente sobre la base azul-gris del sitio
2. **Industria de construcción:** El naranja es el color universal de la construcción en México (Cemex, señalización, equipos de seguridad)
3. **Psicología del color:** Naranja = acción, urgencia, energía (ideal para CTAs)
4. **Consistencia:** El template ya tenía un gradiente naranja-amarillo existente
**Colores específicos:**
- **Botón "Let's Talk":** `#FF6B35` → `#FF8C42` (gradiente)
- **CTA Box:** `#FF8600` → `#FFB800` (gradiente existente)
- **Botón Submit:** `#FF5722` → `#FF6B35` (gradiente)
---
### **Integración con Google Analytics**
Las nuevas funcionalidades incluyen tracking automático si tienes Google Analytics instalado:
**Eventos rastreados:**
1. **Click en botón "Let's Talk":** No requiere código adicional
2. **Click en botón CTA Box:** Event name: `cta_click`
3. **Envío de formulario:** Event name: `form_submission`
**Código de ejemplo en `main.js`:**
```javascript
if (typeof gtag !== 'undefined') {
gtag('event', 'form_submission', {
'event_category': 'Contact Form',
'event_label': 'Contact Form Submitted',
'value': 1
});
}
```
---
### **Testing y Debugging**
**Para probar el formulario sin webhook real:**
1. Usa Webhook.site para testing:
- Ve a https://webhook.site
- Copia la URL única que te dan
- Pégala en `main.js` línea 198
- Envía el formulario y verás los datos en tiempo real
2. **Console logs:**
- Abre DevTools (F12) → Console
- Verás mensajes de carga del modal
- Verás errores si el webhook falla
3. **Testing de validación:**
- Intenta enviar formulario vacío
- Intenta con email inválido
- Intenta con WhatsApp inválido
- Verifica mensajes de error
---
### **Responsive Design**
Todas las funcionalidades son completamente responsive:
**Mobile (<768px):**
- Botón "Let's Talk": width 100%, margin-top
- CTA Box: fuentes más pequeñas
- TOC: max-height reducido a 300px
- Modal: padding reducido, fuentes ajustadas
**Tablet (768px - 991px):**
- Layout intermedio con ajustes específicos
**Desktop (>992px):**
- Diseño completo con todas las animaciones
---
## 🆕 Nuevas Funcionalidades de Conversión
### Resumen
Se implementaron funcionalidades clave para mejorar la conversión y captura de leads en el sitio, basadas en el diseño de referencia de RDash. Estas funcionalidades incluyen múltiples puntos de contacto estratégicos a lo largo de la página.
### **Funcionalidades Implementadas**
#### 1. **Top Notification Bar**
Barra de notificaciones delgada ubicada en la parte superior del sitio, antes del navbar.
**Ubicación:** Arriba del navbar en `index.html` (líneas 253-262)
**Características:**
- Color de fondo: `#4C5C6B` (gris azulado - RDash style)
- Texto destacado en color turquesa: `#61c7cd`
- Icono de megáfono con Bootstrap Icons
- Link subrayado con hover effect
- Sin botón de login (removido por solicitud del usuario)
**Código HTML:**
```html
<div class="top-notification-bar">
<div class="container">
<div class="d-flex align-items-center justify-content-center">
<i class="bi bi-megaphone-fill me-2"></i>
<span><strong>Nuevo:</strong> Accede a más de 200,000 Análisis de Precios Unitarios actualizados para 2025.</span>
<a href="#" class="ms-2 text-white text-decoration-underline">Ver Catálogo</a>
</div>
</div>
</div>
```
**Estilos CSS:** (`style.css` líneas 8-32)
```css
.top-notification-bar {
background-color: #4C5C6B;
color: #ffffff;
padding: 0.5rem 0;
font-size: 0.9rem;
text-align: center;
}
.top-notification-bar strong {
color: #61c7cd;
}
.top-notification-bar i {
color: #61c7cd;
}
.top-notification-bar a:hover {
color: #61c7cd;
}
```
---
#### 2. **Navbar Actualizado con Nuevo Esquema de Colores**
El navbar fue actualizado siguiendo la paleta de colores de RDash para mantener consistencia visual profesional.
**Paleta de Colores RDash:**
- **Navbar Background:** `#0E2337` (azul navy oscuro)
- **Notification Bar:** `#4C5C6B` (gris azulado)
- **Acentos/Hover:** `#61c7cd` (turquesa/cyan)
- **Texto:** `#ffffff` (blanco)
**Cambios Realizados:**
1. **Fondo del Navbar:**
- Antes: Gradiente `#2C3E50#34495E`
- Ahora: Color sólido `#0E2337`
2. **Hover en Links:**
- Antes: `#FFB800` (naranja)
- Ahora: `#61c7cd` (turquesa)
3. **Underline Animation:**
- Antes: Gradiente naranja
- Ahora: `#61c7cd` sólido
4. **Dropdown Hover:**
- Antes: Fondo naranja con transparencia
- Ahora: `rgba(97, 199, 205, 0.1)` con texto `#61c7cd`
**Razón del Cambio:**
Los colores naranja/amarillo eran apropiados para CTAs (industria de construcción en México), pero para el navbar principal se adoptó la paleta RDash que proporciona:
- Mayor profesionalismo
- Mejor contraste con el fondo oscuro
- Coherencia con sitios de software/SaaS modernos
- El turquesa/cyan es un color que transmite tecnología y confianza
---
#### 3. **Botón "Let's Talk" en Navbar**
Botón CTA prominente en el navbar que abre un modal de contacto.
**Ubicación:** Navbar, al lado derecho (después de los menús)
**Características:**
- Gradiente naranja/coral para destacar: `#FF6B35#FF8C42`
- Icono de rayo (lightning) de Bootstrap Icons
- Abre modal de contacto con `data-bs-toggle="modal"`
- Animaciones en hover (elevación + brillo)
- Responsive: 100% width en móviles
**Código HTML:** (`index.html` líneas 315-317)
```html
<button class="btn btn-lets-talk ms-lg-3" data-bs-toggle="modal" data-bs-target="#contactModal">
<i class="bi bi-lightning-charge-fill me-2"></i>Let's Talk
</button>
```
**Estilos CSS:** (`style.css` líneas 491-516)
```css
.btn-lets-talk {
background: linear-gradient(135deg, #FF6B35 0%, #FF8C42 100%);
color: #ffffff;
font-weight: 600;
padding: 0.5rem 1.5rem;
border: none;
border-radius: 6px;
transition: all 0.3s ease;
box-shadow: 0 4px 12px rgba(255, 107, 53, 0.3);
}
.btn-lets-talk:hover {
transform: translateY(-2px);
box-shadow: 0 6px 16px rgba(255, 107, 53, 0.4);
}
```
**Razón del Esquema de Color:**
- **Naranja para CTAs:** Se mantiene el naranja/coral para todos los botones de llamada a la acción (CTAs) porque es el color de la industria de construcción en México (Cemex, cascos de seguridad, señalización)
- **Alto Contraste:** El naranja crea un contraste fuerte contra el navbar oscuro `#0E2337`
- **Jerarquía Visual:** Separa claramente la navegación (turquesa) de las acciones de conversión (naranja)
---
#### 4. **CTA Box "Ready to Supercharge" Debajo de TOC**
Caja de llamada a la acción ubicada estratégicamente debajo de la tabla de contenidos en el sidebar.
**Ubicación:** Sidebar, inmediatamente debajo del TOC
**Características:**
- Gradiente naranja/amarillo vibrante: `#FF8600#FFB800`
- Sticky junto con el TOC (ambos en contenedor `.sidebar-sticky`)
- Botón con icono de calendario
- Sin icono superior (removido para ahorrar espacio)
- Diseño compacto con padding reducido
**Código HTML:** (`index.html` líneas 1176-1185)
```html
<div class="sidebar-sticky position-sticky" style="top: 5rem;">
<div class="toc-container">
<!-- TOC content -->
</div>
<div class="cta-box-sidebar mt-3">
<h5 class="cta-box-title">¿Listo para potenciar tus proyectos?</h5>
<p class="cta-box-text">Accede a nuestra biblioteca completa de APUs y herramientas profesionales.</p>
<button class="btn btn-cta-box w-100" data-bs-toggle="modal" data-bs-target="#contactModal">
<i class="bi bi-calendar-check me-2"></i>Solicitar Demo
</button>
</div>
</div>
```
**Comportamiento Sticky:**
- Tanto el TOC como el CTA Box están dentro del mismo contenedor `.sidebar-sticky`
- Esto asegura que se muevan juntos al hacer scroll
- El CTA Box **siempre** permanece debajo del TOC
- `top: 5rem` proporciona espacio para el navbar sticky
**Estilos CSS:** (`style.css` líneas 564-620)
```css
.cta-box-sidebar {
background: linear-gradient(135deg, #FF8600 0%, #FFB800 100%);
border-radius: 10px;
padding: 1.25rem;
text-align: center;
box-shadow: 0 6px 20px rgba(255, 133, 0, 0.3);
}
.btn-cta-box {
background-color: rgba(255, 255, 255, 0.95);
color: #FF8600;
font-weight: 600;
border: 2px solid rgba(255, 255, 255, 0.3);
}
.btn-cta-box:hover {
background-color: #ffffff;
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
}
```
**Optimización del TOC:**
Para evitar que el TOC sea demasiado alto y necesite scroll vertical, se aplicaron los siguientes ajustes:
```css
.toc-container {
padding: 0.75rem 1rem !important;
}
.toc-container li {
margin-bottom: 0.1rem !important;
}
.toc-container a {
padding: 0.25rem 0.75rem !important;
font-size: 0.875rem !important;
line-height: 1.3 !important;
}
.toc-list {
max-height: 600px;
overflow-y: auto;
}
```
---
#### 5. **Modal de Contacto (Archivo Independiente)**
Modal de Bootstrap 5 cargado dinámicamente desde archivo HTML separado.
**Archivo:** `modal-contact.html` (nuevo archivo)
**Carga Dinámica:**
El modal se carga mediante JavaScript al cargar la página:
```javascript
function loadContactModal() {
fetch('modal-contact.html')
.then(response => response.text())
.then(html => {
document.getElementById('modalContainer').innerHTML = html;
initContactForm();
})
.catch(error => {
console.error('Error cargando el modal:', error);
});
}
```
**Campos del Formulario:**
| Campo | Tipo | Requerido | Validación |
|-------|------|-----------|------------|
| Nombre completo | text | ✅ Sí | No vacío |
| Empresa | text | ❌ No | - |
| WhatsApp | tel | ✅ Sí | 10-15 dígitos, formato internacional |
| Correo | email | ✅ Sí | Formato email válido (regex) |
| Comentarios | textarea | ❌ No | - |
**Validaciones Implementadas:**
```javascript
// Email validation
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!emailRegex.test(formData.email)) {
showFormMessage('Por favor ingresa un correo electrónico válido', 'danger');
return;
}
// WhatsApp validation
const whatsappRegex = /^\+?[0-9]{10,15}$/;
if (!whatsappRegex.test(formData.whatsapp.replace(/\s/g, ''))) {
showFormMessage('Por favor ingresa un número de WhatsApp válido', 'danger');
return;
}
```
**Datos Enviados al Webhook:**
```json
{
"fullName": "Juan Pérez",
"company": "Constructora XYZ",
"whatsapp": "+52 55 1234 5678",
"email": "juan@ejemplo.com",
"comments": "Comentarios opcionales",
"timestamp": "2025-01-15T10:30:00.000Z",
"source": "APU Website - Let's Talk Button"
}
```
**Método:** `POST`
**Content-Type:** `application/json`
**Estados del Botón Submit:**
- Normal: "Enviar Mensaje"
- Enviando: "Enviando..." con spinner de Bootstrap
- Éxito: Mensaje verde, formulario se resetea, modal se cierra después de 2 segundos
- Error: Mensaje rojo, botón se rehabilita
---
#### 6. **Formulario de Contacto en Footer**
Sección adicional de contacto antes del footer con diseño limpio y consistente.
**Ubicación:** Antes del footer principal
**Diseño:**
- Fondo: `bg-secondary bg-opacity-25` (Bootstrap class)
- Layout: 2 columnas en desktop (información + formulario)
- Iconos naranja para información de contacto
- Mismo sistema de validación que el modal
**Código HTML:** (`index.html` líneas 1188-1251)
**Características Especiales:**
- Campo `source` diferente: `"APU Website - Footer Contact Form"`
- Permite trackear de dónde viene cada lead
- Diseño más simple y directo que el modal
- No requiere interacción de abrir modal
**Razón del Diseño:**
Después de varias iteraciones, se llegó a este diseño porque:
1. No modifica el footer original (requisito del usuario)
2. Usa colores de Bootstrap consistentes con el resto del tema
3. Fondo gris claro que contrasta con el footer oscuro
4. Iconos naranja mantienen coherencia con los CTAs
---
### **Configuración del Webhook**
**Paso 1: Configurar URL del Webhook**
Abre `js/main.js` y busca la línea 203 (modal) y línea 316 (footer):
```javascript
const WEBHOOK_URL = 'https://tu-webhook.com/contacto';
```
Reemplaza con tu URL de webhook real.
**Paso 2: Testing Rápido con Webhook.site**
Para probar sin webhook real:
1. Ve a https://webhook.site
2. Copia la URL única que te proporciona
3. Pégala en `main.js` (líneas 203 y 316)
4. Abre `index.html` en el navegador
5. Click en "Let's Talk" → completa formulario → Submit
6. Verifica los datos en tiempo real en Webhook.site
**Servicios de Webhook Recomendados:**
| Servicio | Tipo | Precio | URL |
|----------|------|--------|-----|
| **Webhook.site** | Testing | Gratis | https://webhook.site |
| **Make (Integromat)** | Automatización | Gratis/Pago | https://www.make.com |
| **Zapier** | Automatización | Gratis/Pago | https://zapier.com |
| **n8n** | Self-hosted | Gratis | https://n8n.io |
| **Pipedream** | Serverless | Gratis/Pago | https://pipedream.com |
**Integración con CRM:**
Puedes usar Make.com o Zapier para conectar el webhook con:
- Google Sheets
- HubSpot
- Salesforce
- Zoho CRM
- Mailchimp
- Notion
- Airtable
---
### **Google Analytics Tracking**
El código incluye tracking automático para Google Analytics (si está instalado).
**Eventos Trackeados:**
1. **form_submission** - Cuando se envía exitosamente un formulario
```javascript
gtag('event', 'form_submission', {
'event_category': 'Contact Form',
'event_label': 'Contact Form Submitted',
'value': 1
});
```
2. **cta_click** - Cuando se hace click en cualquier CTA
```javascript
gtag('event', 'cta_click', {
'event_category': 'CTA',
'event_label': 'Variant_A', // o 'Variant_B'
'value': 'A'
});
```
**No requiere configuración adicional** si ya tienes Google Analytics (gtag) instalado globalmente.
---
### **Responsive Design**
Todas las funcionalidades son 100% responsive:
**Mobile (<768px):**
- Top notification bar: texto más compacto
- Navbar: hamburger menu
- Botón "Let's Talk": width 100%, margin-top
- CTA Box: fuentes más pequeñas, padding reducido
- TOC: max-height reducido a 300px
- Modal: padding reducido, fuentes ajustadas
- Footer form: columna única
**Tablet (768px - 991px):**
- Layout intermedio con ajustes específicos
- TOC y CTA Box comienzan a aparecer en sidebar
- Footer form mantiene 2 columnas
**Desktop (>992px):**
- Diseño completo con todas las animaciones
- Sidebar sticky con TOC + CTA Box
- Footer form en 2 columnas (40% info, 60% form)
---
### **Archivos Modificados/Creados**
**Archivos nuevos:**
- ✨ `modal-contact.html` - Modal de formulario de contacto
**Archivos modificados:**
- 📝 `index.html` - Top notification bar + Navbar + Botón Let's Talk + CTA box + Footer form + contenedor modal
- 🎨 `css/style.css` - 500+ líneas agregadas con todos los estilos
- ⚡ `js/main.js` - 200+ líneas agregadas para carga de modal y envío a webhook
---
### **Paleta de Colores Final**
**Navbar y Navegación (RDash Style):**
- 🔵 Navbar Background: `#0E2337` (azul navy oscuro)
- 🔵 Top Notification Bar: `#4C5C6B` (gris azulado)
- 💎 Hover/Acentos: `#61c7cd` (turquesa/cyan)
- ⚪ Texto: `#ffffff` (blanco)
**CTAs y Botones de Conversión (Construcción):**
- 🟠 Botón Let's Talk: `#FF6B35#FF8C42` (gradiente naranja/coral)
- 🟡 CTA Box: `#FF8600#FFB800` (gradiente naranja/amarillo)
- 🔴 Botón Submit: `#FF5722#FF6B35` (gradiente coral/rojo)
**Razón de la Separación:**
- **Navegación (turquesa):** Transmite tecnología, profesionalismo, modernidad
- **CTAs (naranja):** Color de la industria de construcción en México, alta visibilidad, urgencia
---
### **Troubleshooting**
**El modal no aparece:**
- Verifica que Bootstrap JS esté cargado correctamente
- Abre Console (F12) y busca errores
- Verifica que `modal-contact.html` exista en la misma carpeta que `index.html`
**El formulario no envía:**
- Verifica la URL del webhook en `main.js` líneas 203 y 316
- Abre DevTools → Network tab y busca el request POST
- Verifica CORS si el webhook está en otro dominio
- Usa Webhook.site para testing inicial
**Los estilos no se aplican:**
- Haz Ctrl+Shift+R para refrescar sin caché
- Verifica que `css/style.css` esté vinculado correctamente en el `<head>`
- Verifica que no haya errores de sintaxis en CSS
**El botón "Let's Talk" no se ve:**
- Verifica que Bootstrap Icons esté cargado
- Busca `.btn-lets-talk` en DevTools → Elements
- Verifica que el navbar tenga clase `navbar-dark`
**TOC con demasiado scroll vertical:**
- Reduce el `margin-bottom` de los items del TOC
- Ajusta `max-height` del `.toc-list`
- Reduce `padding` de los links `<a>` dentro del TOC
---
### **Próximos Pasos Recomendados**
1. ✅ Configura el webhook real (paso 1)
2. ✅ Prueba en local con Webhook.site (paso 2)
3. ✅ Verifica responsive en mobile con DevTools
4. ✅ Integra con tu backend/CRM real
5. ✅ Activa Google Analytics tracking
6. ✅ Monitorea conversiones y ajusta copy según resultados
7. ✅ Realiza A/B testing del copy de los CTAs
8. ✅ Considera agregar reCAPTCHA para prevenir spam
---
## 🔗 Referencias
- Bootstrap 5 Docs: https://getbootstrap.com/docs/5.3/
- Bootstrap Icons: https://icons.getbootstrap.com/
- Schema.org: https://schema.org/
- WordPress Template Hierarchy: https://developer.wordpress.org/themes/basics/template-hierarchy/
- Google Rich Results Test: https://search.google.com/test/rich-results
- Webhook.site (Testing): https://webhook.site
- Make.com (Automatización): https://www.make.com
- RDash (Referencia de diseño): https://rdash.io
---
**Versión:** 2.1
**Última actualización:** Enero 2025
**Última funcionalidad agregada:** Navbar y Notification Bar con colores RDash
**Versión del documento:** 2.0 (Nuevas funcionalidades: Let's Talk Button + CTA Box + Modal de Contacto)