Organismos
Bloques grandes con identidad propia: el topbar, el launcher, el panel de ayuda, el tablero Kanban, el encabezado y el pie del sitio.
Sidebar
Navegación principal: workspace, acción destacada, secciones plegables y el usuario al pie.
starter/components/sidebar.php
<?php include 'components/sidebar.php'; ?> <!-- 1º include del <body> -->
<!-- El menú se declara en config.php, no en el markup: -->
$GM_NAV = [
['type' => 'links', 'items' => [
['label' => 'Dashboard', 'icon' => 'fa-th-large', 'href' => 'index.php'],
]],
['type' => 'group', 'id' => 'grpOperacion', 'title' => 'Operación', 'items' => [
['label' => 'Listado', 'icon' => 'fa-list', 'href' => 'pages/listado.php'],
]],
];
localStorage) y pasa a cajón con overlay en móvil. Acá se muestra contenida; en la app ocupa el alto completo.Topbar
60 px de alto: hamburguesa y migas a la izquierda, buscador al centro, launcher, ayuda, campana y avatar a la derecha.
starter/components/header.php
<?php
$GM_BREADCRUMB = ['Comercial', 'Ofertas']; // App › Comercial › Ofertas
include 'components/header.php'; // trae launcher + ayuda + tema
?>
$GM_BREADCRUMB, no del markup.Launcher de sistemas
El menú waffle que salta entre los 13 sistemas del ecosistema. Autocontenido en un archivo.
starter/components/gm_launcher.php
<div class="topbar-right">
<?php include __DIR__ . '/gm_launcher.php'; ?>
...
</div>
$GM_SISTEMAS en este archivo y se copia a las apps.Panel de ayuda
Ayuda de la pantalla actual. Se incluye una vez desde el header y aparece en todas las páginas.
starter/components/help.php
// components/help.php — una entrada por pantalla, con el archivo como clave
$helpContent = [
'ofertas.php' => [
'titulo' => 'Ofertas',
'resumen' => 'Cotizaciones a clientes: cabecera, líneas y consecutivo.',
'puntos' => [
'El código se genera solo al guardar.',
'El IVA depende del ámbito del servicio.',
],
'tip' => 'Una oferta enviada a revisión queda congelada.',
],
];
Modal
Para una acción corta que no merece pantalla propia. Si tiene más de un paso, hacé una pantalla.
styles/app-shell.css
<div class="modal-content" style="max-width:520px">
<div class="modal-header">
<h5 class="modal-title">Nuevo cliente</h5>
<button type="button" class="btn-close"></button>
</div>
<div class="modal-body">
<div class="mb-3">
<label class="form-label">Nombre</label>
<input class="form-control" placeholder="Razón social">
</div>
<div class="mb-0">
<label class="form-label">Cédula jurídica</label>
<input class="form-control" placeholder="3-101-000000">
</div>
</div>
<div class="modal-footer">
<button class="btn btn-gm-secondary">Cancelar</button>
<button class="btn btn-gm-primary">Guardar</button>
</div>
</div>
Tablero Kanban
Columna por estado y tarjeta por registro; se arrastra entre columnas y se guarda solo.
GrupoMecsaProyectos/pages/kanban.php
<div class="kanban-board" style="display:flex;gap:1rem;align-items:flex-start">
<div class="kanban-col">
<div class="stage-header">
<span>En ejecución</span>
<span class="badge bg-primary rounded-pill">2</span>
</div>
<div class="kanban-items">
<div class="kanban-card" style="border-left-color:#013483">
<div class="d-flex justify-content-between align-items-start mb-1">
<div class="fw-bold text-dark-gm" style="font-size:.95rem;">Mantenimiento planta norte</div>
<span class="badge bg-light text-secondary border small">#1042</span>
</div>
<div class="small text-secondary mb-1"><i class="fas fa-tag me-1"></i> Mantenimiento</div>
<div class="small text-muted mb-2"><i class="fas fa-user me-1"></i> Constructora del Sur</div>
<div class="small text-muted"><i class="fas fa-calendar-plus me-1"></i> Ingreso: 12/08/2026</div>
</div>
<div class="kanban-card" style="border-left-color:#013483">
<div class="d-flex justify-content-between align-items-start mb-1">
<div class="fw-bold text-dark-gm" style="font-size:.95rem;">Instalación de bombas</div>
<span class="badge bg-light text-secondary border small">#1043</span>
</div>
<div class="small text-muted mb-2"><i class="fas fa-user me-1"></i> Agroindustrias CR</div>
</div>
</div>
</div>
<div class="kanban-col">
<div class="stage-header">
<span>Pendiente informe</span>
<span class="badge bg-warning rounded-pill">1</span>
</div>
<div class="kanban-items">
<div class="kanban-card" style="border-left-color:#f7941d">
<div class="d-flex justify-content-between align-items-start mb-1">
<div class="fw-bold text-dark-gm" style="font-size:.95rem;">Inspección anual</div>
<span class="badge bg-light text-secondary border small">#1039</span>
</div>
<div class="small text-muted mb-2"><i class="fas fa-user me-1"></i> Municipalidad de Alajuela</div>
</div>
</div>
</div>
</div>
Cabecera de ficha
Encabezado del detalle de un registro: volver, identificador, título, chips y acciones.
GrupoMecsaProyectos/pages/proyecto.php
<div class="pd-head">
<div class="pd-head-main">
<a href="#" class="pd-back" title="Volver a la lista"><i class="fas fa-arrow-left"></i></a>
<div>
<div class="pd-eyebrow">Proyecto #1042 · Tarea 88431</div>
<h1 class="pd-title">Mantenimiento planta norte</h1>
<div class="pd-chips">
<span class="pd-chip pd-chip-state">En ejecución</span>
<span class="pd-chip">Mantenimiento industrial</span>
</div>
</div>
</div>
<div class="pd-head-actions">
<button class="pd-btn"><i class="fas fa-pen"></i> Editar</button>
<button class="pd-btn pd-btn-primary"><i class="fas fa-file-invoice"></i> Facturar</button>
</div>
</div>
Carrusel de portada
La apertura de la home: video de fondo por diapositiva, titular y dos llamados a la acción.
GrupoMecsa/index.php
<div id="carouselHome" class="carousel slide" data-bs-ride="carousel">
<div class="carousel-inner">
<div class="carousel-item active carousel-item-gm">
<!-- En producción acá va el <iframe> de Vimeo; se simula con un fondo plano -->
<div class="video-background-wrapper" style="position:absolute;inset:0;background:#112542;"></div>
<div class="carousel-caption carousel-caption-gm d-none d-md-block">
<h2 class="h2 h2-gm animate-text">Torres libres de rayos son una realidad</h2>
<h3 class="h1 h1-gm animate-text">PARARRAYOS PARA TORRES DE <br> TELECOMUNICACIÓN</h3>
<div>
<a href="#" class="btn btn-primary btn-gm-primary">Conocer Más</a>
<a href="#" class="btn btn-outline-light btn-gm-outline-light">Contáctenos</a>
</div>
</div>
</div>
</div>
<button class="carousel-control-prev" type="button" data-bs-target="#carouselHome" data-bs-slide="prev">
<span class="carousel-control-prev-icon"></span><span class="visually-hidden">Anterior</span>
</button>
<button class="carousel-control-next" type="button" data-bs-target="#carouselHome" data-bs-slide="next">
<span class="carousel-control-next-icon"></span><span class="visually-hidden">Siguiente</span>
</button>
</div>
<iframe> de Vimeo en .video-background-wrapper (acá va en plano para poder verlo). El video es decorativo: sin sonido, en bucle y sin controles, y el texto nunca depende de él.Tarjeta de colaborador
El equipo en /nosotros. El orden lo define el campo orden del departamento en KoraCMS.
GrupoMecsa/components/Colaboradores.php
<div class="row" style="max-width:560px">
<div class="col-6 empleado-card mt-gm-colaboradores">
<div class="card text-center mb-3 card-gm-primary border-0 h-100">
<div class="card-body card-body-gm-primary d-flex flex-column align-items-center">
<div class="avatar-container">
<img src="../../assets/ph-avatar.svg" alt="Colaborador" loading="lazy" decoding="async">
</div>
<h5 class="h4 h4-gm mt-4 mb-1">María Rodríguez</h5>
<p class="p-gm text-light mb-2">Jefatura de Operaciones</p>
</div>
</div>
</div>
<div class="col-6 empleado-card mt-gm-colaboradores">
<div class="card text-center mb-3 card-gm-primary border-0 h-100">
<div class="card-body card-body-gm-primary d-flex flex-column align-items-center">
<div class="avatar-container">
<img src="../../assets/ph-avatar.svg" alt="Colaborador" loading="lazy" decoding="async">
</div>
<h5 class="h4 h4-gm mt-4 mb-1">Jorge Sánchez</h5>
<p class="p-gm text-light mb-2">Ingeniería de Proyectos</p>
</div>
</div>
</div>
</div>
.mt-gm-colaboradores, que reserva ese espacio. Sin esa clase la foto se corta.Testimonios
Carrusel de testimonios de clientes: dos por diapositiva en escritorio, uno en móvil.
GrupoMecsa/components/testimonios.php
<section class="py-5">
<div class="container text-center">
<h2 class="mb-4 text-dark-gm">
Testimonio <span class="text-primary-gm fw-bold">de nuestros clientes</span>
</h2>
<div id="carouselTestimonios" class="carousel slide" data-bs-ride="carousel">
<div class="carousel-inner">
<div class="carousel-item active">
<div class="row justify-content-center g-4 row-carousel-testimonios-gm">
<div class="col-md-6">
<div class="card border-0 h-100">
<div class="card-body p-4 card-body-gm">
<blockquote class="blockquote mb-4">
<p class="mb-4 text-secondary">“ Resolvieron la protección de toda la planta en tiempo récord y con el informe al día. ”</p>
<footer class="blockquote-footer mt-3">
<strong>María Rodríguez</strong><br>
<span class="text-primary-gm">Jefatura de Mantenimiento, Constructora del Sur</span>
</footer>
</blockquote>
</div>
</div>
</div>
<div class="col-md-6">
<div class="card border-0 h-100">
<div class="card-body p-4 card-body-gm">
<blockquote class="blockquote mb-4">
<p class="mb-4 text-secondary">“ La demarcación quedó impecable y no tuvimos que cerrar la vía más de un día. ”</p>
<footer class="blockquote-footer mt-3">
<strong>Jorge Sánchez</strong><br>
<span class="text-primary-gm">Dirección de Obras, Municipalidad de Alajuela</span>
</footer>
</blockquote>
</div>
</div>
</div>
</div>
</div>
</div>
<button class="carousel-control-prev carousel-control-gm" type="button" data-bs-target="#carouselTestimonios" data-bs-slide="prev">
<span class="carousel-control-prev-icon bg-primary rounded-circle p-2"></span>
<span class="visually-hidden">Anterior</span>
</button>
<button class="carousel-control-next carousel-control-gm" type="button" data-bs-target="#carouselTestimonios" data-bs-slide="next">
<span class="carousel-control-next-icon bg-primary rounded-circle p-2"></span>
<span class="visually-hidden">Siguiente</span>
</button>
</div>
</div>
</section>
d-none d-md-block y d-block d-md-none) porque cambia la cantidad de tarjetas por diapositiva. El contenido sale de la tabla testimoniales.Acordeón de servicios
Navegación lateral de la página de servicios: categorías plegables con sus subcategorías.
GrupoMecsa/pages/servicios.php
<div class="accordion submenu-gm-servicios-categorias" id="accordionCategorias" style="max-width:360px">
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button accordion-button-gm-categorias" type="button"
data-bs-toggle="collapse" data-bs-target="#cat-electrico" aria-expanded="true">
Eléctrico
</button>
</h2>
<div id="cat-electrico" class="accordion-collapse collapse show" data-bs-parent="#accordionCategorias">
<div class="accordion-body p-0">
<ul class="list-group list-group-flush">
<li class="list-group-item list-group-item-gm active">
<a class="text-decoration-none text-white" href="#">Protección contra rayos</a>
</li>
<li class="list-group-item list-group-item-gm">
<a class="text-decoration-none" href="#">Puestas a tierra</a>
</li>
<li class="list-group-item list-group-item-gm">
<a class="text-decoration-none" href="#">Estudios eléctricos</a>
</li>
</ul>
</div>
</div>
</div>
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button accordion-button-gm-categorias collapsed" type="button"
data-bs-toggle="collapse" data-bs-target="#cat-vial" aria-expanded="false">
Vialidad
</button>
</h2>
<div id="cat-vial" class="accordion-collapse collapse" data-bs-parent="#accordionCategorias">
<div class="accordion-body p-0">
<ul class="list-group list-group-flush">
<li class="list-group-item list-group-item-gm">
<a class="text-decoration-none" href="#">Asfalto</a>
</li>
<li class="list-group-item list-group-item-gm">
<a class="text-decoration-none" href="#">Demarcación</a>
</li>
</ul>
</div>
</div>
</div>
</div>
Hero del blog
La apertura del blog: titular, bajada e ilustración a la derecha.
GrupoMecsa/pages/blog.php
<div class="gm-hero-new">
<div class="container-lg">
<div class="row align-items-center">
<div class="col-md-6">
<h1 class="gm-hero-title-new display-4 mb-3">Grupo Mecsa Blog</h1>
<p class="gm-hero-subtitle-new lead mb-4">Descubre las últimas noticias, consejos y tendencias sobre protección eléctrica y pararrayos.</p>
</div>
<div class="col-md-6 text-center d-none d-md-block">
<img src="../../assets/ph-wide.svg" alt="Ilustración" class="img-fluid gm-hero-image" style="max-height:260px;">
</div>
</div>
</div>
</div>