Files
roi-theme/_planificacion/01-design-system/06-ESTRUCTURA-LAYOUT.md
FrankZamora 0f6387ab46 refactor: reorganizar openspec y planificacion con spec recaptcha
- renombrar openspec/ a _openspec/ (carpeta auxiliar)
- mover specs de features a changes/
- crear specs base: arquitectura-limpia, estandares-codigo, nomenclatura
- migrar _planificacion/ con design-system y roi-theme-template
- agregar especificacion recaptcha anti-spam (proposal, tasks, spec)
- corregir rutas y referencias en todas las specs

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-08 15:30:45 -06:00

11 KiB

📐 ESTRUCTURA DE LAYOUT

Container Principal

<div class="container-fluid py-4" style="max-width: 1400px;">
    <!-- Todo el contenido del admin panel va aquí -->
</div>

Características:

  • container-fluid: Ancho flexible con padding
  • py-4: 1.5rem (24px) padding vertical
  • max-width: 1400px: Limita el ancho máximo para legibilidad

Header del Tab (OBLIGATORIO EN TODOS LOS COMPONENTES)

Estructura Completa

<div class="rounded p-4 mb-4 shadow text-white"
     style="background: linear-gradient(135deg, #0E2337 0%, #1e3a5f 100%);
            border-left: 4px solid #FF8600;">
    <div class="d-flex align-items-center justify-content-between flex-wrap gap-3">
        <div>
            <h3 class="h4 mb-1 fw-bold">
                <i class="bi bi-[ICON] me-2" style="color: #FF8600;"></i>
                [TÍTULO DEL COMPONENTE]
            </h3>
            <p class="mb-0 small" style="opacity: 0.85;">
                [Descripción breve del componente]
            </p>
        </div>
        <button type="button" class="btn btn-sm btn-outline-light" id="reset[Component]Defaults">
            <i class="bi bi-arrow-counterclockwise me-1"></i>
            Restaurar valores por defecto
        </button>
    </div>
</div>

Elementos Clave

  • Gradiente navy como fondo: #0E2337#1e3a5f
  • Border-left orange de 4px: #FF8600
  • Icono orange en el título: color: #FF8600
  • Botón de reset alineado a la derecha
  • Responsive: flex-wrap con gap-3 para mobile

Iconos Comunes por Tipo de Componente

Tipo de Componente Icono Sugerido Clase Bootstrap Icons
Notificaciones/Anuncios Megáfono bi-megaphone-fill
Navegación/Menú Barras bi-layout-text-window
Colores/Estilos Paleta bi-palette
Textos/Contenido Texto bi-chat-text
Configuración General Engranaje bi-gear-fill
Imágenes/Media Imagen bi-image
Formularios Portapapeles bi-clipboard-check

Sistema de Grid

Layout de 2 Columnas (Estándar)

<div class="row g-3">
    <!-- COLUMNA IZQUIERDA -->
    <div class="col-lg-6">
        <!-- Card 1 -->
        <div class="card shadow-sm mb-3">...</div>

        <!-- Card 2 -->
        <div class="card shadow-sm mb-3">...</div>
    </div>

    <!-- COLUMNA DERECHA -->
    <div class="col-lg-6">
        <!-- Card 3 -->
        <div class="card shadow-sm mb-3">...</div>

        <!-- Card 4 -->
        <div class="card shadow-sm mb-3">...</div>
    </div>

    <!-- FILA COMPLETA (opcional) -->
    <div class="col-12">
        <!-- Card de Vista Previa -->
        <div class="card shadow-sm mb-3">...</div>
    </div>
</div>

Breakpoints:

  • col-lg-6: 2 columnas en pantallas ≥992px
  • Stack vertical automático en pantallas <992px
  • g-3: Gap de 1rem (16px) entre columnas

Layout de 3 Columnas (Menos Común)

<div class="row g-3">
    <div class="col-lg-4">Card 1</div>
    <div class="col-lg-4">Card 2</div>
    <div class="col-lg-4">Card 3</div>
</div>

Layout Full Width

<div class="row g-3">
    <div class="col-12">
        <!-- Card de Vista Previa, Sección Especial -->
    </div>
</div>

Estructura Completa de un Admin Panel

<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Admin: [Component Name]</title>

    <!-- CDN Links -->
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/Css/bootstrap.min.css" rel="stylesheet">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/Font/bootstrap-icons.min.css">
    <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap" rel="stylesheet">
    <link rel="stylesheet" href="../../Css/style.css">

    <style>
    body {
        font-family: 'Poppins', sans-serif;
        background-color: #f8f9fa;
    }

    /* Sobreescribir max-width de WordPress */
    body .card {
        max-width: none !important;
    }
    </style>
</head>
<body>
    <!-- CONTAINER PRINCIPAL -->
    <div class="container-fluid py-4" style="max-width: 1400px;">

        <!-- HEADER DEL TAB -->
        <div class="rounded p-4 mb-4 shadow text-white"
             style="background: linear-gradient(135deg, #0E2337 0%, #1e3a5f 100%);
                    border-left: 4px solid #FF8600;">
            <div class="d-flex align-items-center justify-content-between flex-wrap gap-3">
                <div>
                    <h3 class="h4 mb-1 fw-bold">
                        <i class="bi bi-megaphone-fill me-2" style="color: #FF8600;"></i>
                        [TÍTULO DEL COMPONENTE]
                    </h3>
                    <p class="mb-0 small" style="opacity: 0.85;">
                        [Descripción breve]
                    </p>
                </div>
                <button type="button" class="btn btn-sm btn-outline-light" id="resetDefaults">
                    <i class="bi bi-arrow-counterclockwise me-1"></i>
                    Restaurar valores por defecto
                </button>
            </div>
        </div>

        <!-- GRID DE CONTENIDO -->
        <div class="row g-3">

            <!-- COLUMNA IZQUIERDA -->
            <div class="col-lg-6">
                <!-- Card de configuración 1 -->
                <div class="card shadow-sm mb-3" style="border-left: 4px solid #1e3a5f;">
                    <div class="card-body">
                        <h5 class="fw-bold mb-3" style="color: #1e3a5f;">
                            <i class="bi bi-palette me-2" style="color: #FF8600;"></i>
                            Sección 1
                        </h5>
                        <!-- Campos -->
                    </div>
                </div>
            </div>

            <!-- COLUMNA DERECHA -->
            <div class="col-lg-6">
                <!-- Card de configuración 2 -->
                <div class="card shadow-sm mb-3" style="border-left: 4px solid #1e3a5f;">
                    <div class="card-body">
                        <h5 class="fw-bold mb-3" style="color: #1e3a5f;">
                            <i class="bi bi-gear me-2" style="color: #FF8600;"></i>
                            Sección 2
                        </h5>
                        <!-- Campos -->
                    </div>
                </div>
            </div>

            <!-- VISTA PREVIA (Full Width) -->
            <div class="col-12">
                <div class="card shadow-sm mb-3" style="border-left: 4px solid #FF8600;">
                    <div class="card-body">
                        <h5 class="fw-bold mb-3" style="color: #1e3a5f;">
                            <i class="bi bi-eye me-2" style="color: #FF8600;"></i>
                            Vista Previa en Tiempo Real
                        </h5>

                        <!-- Preview del componente -->
                        <div id="componentPreview" class="[component-class]">
                            <!-- HTML idéntico al front-end -->
                        </div>

                        <div class="d-flex justify-content-between align-items-center mt-3">
                            <small class="text-muted">
                                <i class="bi bi-info-circle me-1"></i>
                                Los cambios se reflejan en tiempo real
                            </small>
                            <div class="btn-group btn-group-sm" role="group">
                                <button type="button" class="btn btn-outline-secondary active" id="previewDesktop">
                                    <i class="bi bi-display"></i> Desktop
                                </button>
                                <button type="button" class="btn btn-outline-secondary" id="previewMobile">
                                    <i class="bi bi-phone"></i> Mobile
                                </button>
                            </div>
                        </div>
                    </div>
                </div>
            </div>

        </div>
    </div>

    <!-- Bootstrap JS -->
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/Js/bootstrap.bundle.min.js"></script>

    <script>
    // JavaScript del componente
    document.addEventListener('DOMContentLoaded', function() {
        console.log('✅ Admin Panel cargado');
        loadConfig();
        updatePreview();
        initializeEventListeners();
    });
    </script>
</body>
</html>

Cards de Configuración

Card Estándar

<div class="card shadow-sm mb-3" style="border-left: 4px solid #1e3a5f;">
    <div class="card-body">
        <h5 class="fw-bold mb-3" style="color: #1e3a5f;">
            <i class="bi bi-palette me-2" style="color: #FF8600;"></i>
            [TÍTULO DE LA SECCIÓN]
        </h5>

        <!-- Campos de formulario -->
        <div class="mb-2">
            <!-- Campo 1 -->
        </div>
        <div class="mb-2">
            <!-- Campo 2 -->
        </div>
    </div>
</div>

Card de Vista Previa

<div class="card shadow-sm mb-3" style="border-left: 4px solid #FF8600;">
    <div class="card-body">
        <h5 class="fw-bold mb-3" style="color: #1e3a5f;">
            <i class="bi bi-eye me-2" style="color: #FF8600;"></i>
            Vista Previa en Tiempo Real
        </h5>

        <!-- Preview -->
        <div id="componentPreview" class="[component-class]">
            <!-- HTML idéntico al front-end -->
        </div>

        <!-- Controles -->
        <div class="d-flex justify-content-between align-items-center mt-3">
            <small class="text-muted">
                <i class="bi bi-info-circle me-1"></i>
                Los cambios se reflejan en tiempo real
            </small>
            <div class="btn-group btn-group-sm" role="group">
                <button type="button" class="btn btn-outline-secondary active" id="previewDesktop">
                    <i class="bi bi-display"></i> Desktop
                </button>
                <button type="button" class="btn btn-outline-secondary" id="previewMobile">
                    <i class="bi bi-phone"></i> Mobile
                </button>
            </div>
        </div>
    </div>
</div>

Diferencia clave: Border-left ORANGE (#FF8600) en lugar de navy


Responsive Behavior

Desktop (≥992px)

  • Grid de 2 columnas activo
  • Header con layout horizontal
  • Espaciado completo

Tablet (768px - 991px)

  • Stack vertical de columnas
  • Header con layout horizontal (flex-wrap si es necesario)
  • Espaciado completo

Mobile (<768px)

  • Stack vertical completo
  • Header con botón debajo del título (flex-wrap)
  • Espaciado reducido
@media (max-width: 991px) {
    .tab-header {
        padding: 0.75rem;
    }

    .tab-header h3 {
        font-size: 1.1rem;
    }
}

@media (max-width: 575px) {
    .tab-header h3 {
        font-size: 1rem;
    }

    .card-body {
        padding: 0.75rem !important;
    }
}

Volver al Índice

← Volver al README