Módulo del sitio · Menú de secciones

El Menú de secciones: la franja que convierte

La barra de botones grandes que va justo bajo el hero. Son los atajos a las secciones clave del sitio y, al final, la acción —Cotizar por WhatsApp—. La regla canónica del proyecto se lee aquí en voz alta: el hero presenta, esta franja convierte.

Esta página no es una ficha técnica: es el módulo entero, abierto y explicado. Qué problema resuelve y por qué se ganó su lugar pegado al hero, de qué piezas se compone, cómo se comporta en el teléfono, dónde encaja en el armado de la página y, al final, cómo está construido por dentro —del criterio de diseño a la línea de código—.

Con una particularidad que conviene marcar desde el principio: no es un menú alternativo, es un MÓDULO de navegación que se reutiliza. En la home se alimenta de NAV —la misma fuente que el header— para que el menú y la franja nunca se desincronicen; en otras páginas se reusa como cierre/interlinking con otros datos. Una sola pieza, dos trabajos: arriba reparte hacia las secciones; abajo, hacia las páginas internas.

Definición

¿Qué es el menú de secciones?

La franja de botones de borde a borde que se asienta justo bajo el hero. Son atajos a las secciones grandes del sitio y, al final, el botón de conversión —destacado en color de marca—.

El menú de secciones (o «section nav») es la barra horizontal que aparece pegada al hero, ocupando todo el ancho del viewport. Cada botón es un destino —Productos, Servicios, Cobertura, Blog—; el último, en color de marca, es la acción: Cotizar por WhatsApp. Vista de lejos, parece una continuación del hero; vista de cerca, hace un trabajo propio: enseñar el camino y acortar el siguiente paso.

No se inventó aquí: es un patrón consolidado de los catálogos profesionales —el visitante entra, lee la promesa del hero y, sin volver al header, ya tiene a la vista por dónde moverse o cómo escribir—. En esta plantilla, esa franja sustituyó a la antigua «banda de garantías» con badges (⚡/📝/📈/💬/✔): en vez de presumir cualidades, ofrece navegación útil. Más profesional, más orientada al negocio.

Función e importancia

¿Para qué sirve?

Hace tres trabajos a la vez: ofrece atajos a las secciones clave, mantiene la conversión a un clic y refuerza el patrón de lectura «hero arriba, acción debajo».

Su función es cerrar la brecha entre la promesa y el siguiente paso. El hero engancha; pero entre el hero y el contenido suele haber un espacio en blanco donde el visitante decide si baja, vuelve al menú o se va. Esta franja es lo que llena ese espacio con utilidad: «si te interesó, esto es lo que hay; y si ya decidiste, escribe aquí». Resume el sitio en una línea de botones.

Y por eso pesa fuera de proporción a su tamaño. Es la primera oportunidad real de conversión —el CTA queda a un clic del primer pantallazo— y, a la vez, el primer reparto de tráfico a las secciones internas, lo que mejora las páginas vistas por sesión y reduce el rebote. En proyectos donde el catálogo es el corazón del sitio, esta franja suele mover más clics que cualquier botón del header.

Atajo a la sección que busca

En lugar de obligar a volver al menú del header, el visitante encuentra los destinos clave —catálogo, servicios, blog— justo donde el ojo ya bajó después del hero. Menos pasos, menos rebote, más páginas vistas por sesión.

Conversión a un clic

El último botón es Cotizar por WhatsApp, destacado en color de marca. La regla canónica del sitio se aplica literalmente aquí: «el hero presenta, la franja convierte». Si el visitante decidió, no tiene que bajar a buscar dónde escribir.

Una sola fuente, cero desincronización

En la home los botones nacen de NAV —el mismo array que alimenta el header—. Agregar una sección al menú la añade automáticamente a la franja; quitarla la borra. El menú y la franja siempre dicen lo mismo, sin mantenerse a mano.

Anatomía

¿Qué lleva la franja?

Cuatro piezas: los botones de sección (con su etiqueta y sublabel), los divisores que los separan y el CTA de conversión que cierra la fila.

Cada pieza cumple un papel claro. El botón ofrece el atajo a una sección; el sublabel matiza el destino en dos o tres palabras; los divisores marcan que es una barra continua —no una lista de chips suelta—; y el CTA cierra la fila con la acción de marca. Nada sobra, y el orden de lectura se mantiene: secciones, después conversión.

Abajo, el ejemplo en vivo —réplica anotada a escala del componente—. Cada punto numerado se desglosa en su tarjeta: qué resuelve y de qué prop del componente sale. A diferencia del hero, en la home los textos no son inventados: vienen de NAV, la misma fuente del header, así que actualizar el menú actualiza esta franja automáticamente.

1

Botón de sección

Un atajo a una de las secciones grandes del sitio (Productos, Servicios, Cobertura, Blog…). Llena su celda, se centra y muestra el destino con una sola etiqueta corta. En la home, esta lista de botones se genera desde NAV: el mismo array que alimenta el header.

Dato items[].label · href

2

Sublabel

Una micro-descripción debajo de la etiqueta («Catálogo del sitio», «Lo que ofreces»). Aclara qué hay detrás del botón sin obligar a entrar; es opcional, pero hace mucho con dos o tres palabras.

Dato items[].sub

3

Divisores

Las líneas que separan los botones. En móvil son horizontales (apilados); en escritorio (≥768 px), verticales (una sola fila). Se dibujan con border de las celdas, sin pintar el botón mismo: la barra queda continua.

Dato .secmenu__cell · border

4

CTA de conversión

El último botón, en color de marca. No es una sección más: es la acción —Cotizar por WhatsApp—. Su enlace no se teclea: lo arma waUrl() con el mensaje precargado de WA_MESSAGES, para que la conversación empiece con contexto.

Dato cta · waUrl(WA_MESSAGES.cotizar)

Variantes

Otros diseños y aplicaciones

La de esta plantilla son cuatro secciones + un CTA, pero la franja cambia de cara según lo que la página necesita repartir: catálogo, contenido, anclas, doble acción.

No hay un único modelo: hay una misma idea —una franja de atajos bajo el hero con la acción al final— que cada tipo de proyecto ajusta a su intención. Una tienda añade iconos por sección; un blog quita el CTA y deja solo enlaces editoriales; una landing convierte los hrefs en anclas para usarla como índice; un SaaS suma una segunda acción al final.

Abajo, seis variantes —cinco son configuraciones REALES del componente (cambiando solo los props items y cta), y la última es una extensión propuesta que requeriría añadir un prop al componente—. Cada una con su réplica en vivo y el tipo de proyecto donde rinde mejor.

  • Cuádruple con CTA (esta plantilla)

    Negocio · Servicios

    El de la home: cuatro botones de sección + un CTA al final en color de marca, repartidos por igual en una sola fila en escritorio y apilados en móvil. Configuración real del componente: items (4) + cta. Es la más segura y la que mejor cumple la regla «el hero presenta, la franja convierte».

  • Con icono por sección

    E-commerce · Catálogo

    Cada botón añade el prop opcional icon (emoji o glifo) a la izquierda de la etiqueta. Refuerza el reconocimiento visual sin texto extra; útil cuando los destinos son tipos distintos (producto, servicio, cita, soporte). Configuración real: items[].icon = "🛒" / "🛠" / "📍" / "📰".

  • Solo enlaces (sin CTA)

    Editorial · Blog · Marca

    Cuando la página no busca una acción inmediata, se omite la prop cta y la franja queda 100% navegacional: cinco o seis atajos a destinos editoriales. El componente lo soporta de fábrica —cta es opcional—. Patrón típico de sitios de contenido.

  • Anclas a secciones (scroll)

    Landing · One-page

    Los hrefs apuntan a anclas de la propia página (#catalogo, #servicios, #faq, #contacto) en vez de a otras rutas. Convierte la franja en un índice rápido para landings largas. Configuración real: items[].href = "#id-de-la-sección".

  • Cierre (interlinking)

    Todas las páginas

    El MISMO componente, OTROS datos: se usa al final de una página para repartir hacia las páginas internas que el menú del hero no toca (fichas, contacto), con un CTA distinto (WA_MESSAGES.contacto). Patrón real, ya en producción en la home.

  • Sub-CTA (acción secundaria)

    SaaS · Captura

    Extensión propuesta: en lugar de un único CTA al final, dos —uno principal (color de marca) y uno secundario (fantasma)—. Hoy el componente solo acepta un cta; para esta variante habría que añadir un prop ctaSecundario o aceptar un array. Pensada para landings con doble intención (Cotizar / Ver demo).

Responsive y móvil

Cómo se comporta en el teléfono

En móvil la franja no se encoge: cambia de modo. Apilados a ancho completo de fábrica, o —si la página lo pide— scroll horizontal, grid 2×2, o sticky bajo el header.

En escritorio la franja vive cómoda como una sola fila de cinco celdas. En el teléfono, esa misma fila no cabe sin apretar los botones a tamaños no tocables, así que el componente cambia de modo: por defecto se apila —cada botón al 100 % del ancho, con divisores horizontales—. Es lo más seguro cuando hay 4–5 botones cortos, y lo que ya hace el componente de la plantilla.

A partir de ahí, hay tres patrones que conviene conocer y aplicar como capa adicional según el caso: scroll horizontal con snap (cuando la lista es larga), grid 2×2 (cuando hay justo 4 secciones + CTA y quieres ahorrar altura) y sticky bajo el header (en landings largas, para mantenerla siempre a la vista). Las cuatro están abajo, cada una con su vista en el teléfono y una receta comentada lista para adaptar.

1 · Apilado a ancho completo

Es lo que ya hace el componente de fábrica. Mobile-first: la barra es flex-direction: column y cada celda ocupa el ancho. Los divisores horizontales se dibujan con el border-bottom de la celda; en la última, se quita. A 768 px y más, pasa a una sola fila con divisores verticales.

CSS · apilado a una sola fila (default)
/* MÓVIL · APILADO (lo que ya hace el componente)
   Mobile-first: la barra es column, cada botón al 100 %.
   Los divisores se vuelven horizontales (border-bottom de
   la celda) y se quitan en la última. */

.secmenu__bar {
  display: flex;
  flex-direction: column;       /* apilados en móvil */
}
.secmenu__cell {
  display: flex;
  border-bottom: 1px solid var(--c-border);
}
.secmenu__cell:last-child { border-bottom: none; }

/* A 768 px y más, pasa a una sola fila con divisores verticales. */
@media (min-width: 768px) {
  .secmenu__bar  { flex-direction: row; }
  .secmenu__cell { flex: 1 1 0; min-width: 0;
                   border-bottom: none;
                   border-right: 1px solid var(--c-border); }
  .secmenu__cell:last-child { border-right: none; }
}

2 · Scroll horizontal con snap (extensión)

Cuando la franja tiene 5–6 botones y apilarlos haría la pantalla demasiado alta, conviene una sola fila scrollable —tipo chips—. El scroll-snap-type: x mandatory alinea cada botón al soltar el dedo; la barra de scroll se oculta para que el efecto quede como en una app.

CSS · una fila scrollable + snap
/* MÓVIL · SCROLL HORIZONTAL (extensión opcional)
   Cuando hay 5–6 botones y no caben apilados sin que la
   página se haga muy alta, los convertimos en una sola fila
   scrollable —tipo chips—. Snap para que cada botón se
   alinee al soltar el dedo. La barra de scroll se oculta. */

@media (max-width: 767px) {
  .secmenu__bar {
    flex-direction: row;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;     /* inercia iOS */
    scrollbar-width: none;                 /* Firefox */
  }
  .secmenu__bar::-webkit-scrollbar { display: none; }

  .secmenu__cell {
    flex: 0 0 60vw;             /* cada botón ≈ 60 % del ancho */
    scroll-snap-align: start;
    border-bottom: none;
    border-right: 1px solid var(--c-border);
  }
}

3 · Grid 2×2 con CTA debajo (extensión)

Cuando hay exactamente 4 secciones + CTA, en móvil conviene una cuadrícula de 2 columnas (los 4 botones de sección) y el CTA ocupando la fila de abajo a ancho completo. Ahorra altura sin tocar nada a nivel componente: solo CSS por encima.

CSS · grid 2 columnas + CTA full
/* MÓVIL · GRID 2×2 (extensión opcional)
   Cuando hay exactamente 4 secciones + CTA, en móvil
   convienen 2 columnas (4 botones en cuadrícula) y el CTA
   ocupa la fila completa de abajo. Ahorra altura sin tocar
   ningún botón a nivel componente. */

@media (max-width: 640px) {
  .secmenu__bar {
    display: grid;
    grid-template-columns: 1fr 1fr;
  }
  .secmenu__cell {
    border-right: 1px solid var(--c-border);
    border-bottom: 1px solid var(--c-border);
  }
  /* Filas: 2 columnas; última fila (el CTA) ocupa las 2. */
  .secmenu__cell--cta {
    grid-column: 1 / -1;
    border-right: none;
    border-bottom: none;
  }
}

4 · Sticky bajo el header (extensión)

En landings largas, la franja se queda pegada al borde superior una vez la página empieza a hacer scroll. Combinada con la variante «anclas», convierte la barra en un índice persistente. Se desactiva con prefers-reduced-motion para no incomodar a quienes prefieren menos animación.

CSS · sticky + reduced-motion
/* SCROLL · STICKY BAJO EL HEADER (extensión opcional)
   En landings largas, la franja se queda fija al borde
   superior una vez la página ha hecho scroll. Useful como
   índice persistente; combina bien con la variante «anclas». */

.secmenu {
  position: sticky;
  top: var(--header-height, 64px);      /* justo bajo el header */
  z-index: var(--z-sticky, 20);
  background: var(--c-white);           /* opaco para que tape */
  box-shadow: 0 1px 0 var(--c-border);
}

/* Si el usuario prefiere menos movimiento, no flotamos. */
@media (prefers-reduced-motion: reduce) {
  .secmenu { position: static; }
}

Posición

¿Dónde se coloca?

Una sola vez por página, justo debajo del hero, antes del contenido del cuerpo. De borde a borde —no respeta el container del 90 %—, para que parezca una continuación del hero.

El orden del armado es deliberado y se respeta en todo el sitio. PageLayout apila el chrome siempre igual: topbar, header, migas (en internas) y hero. Esta franja entra inmediatamente después del hero, como su réplica de acción —el visitante baja un milímetro y ya tiene a la vista por dónde moverse o cómo escribir—. En el cuerpo siguiente vive el catálogo, las reseñas, FAQ y todo lo demás.

A diferencia del resto del sitio, esta franja va FULL-WIDTH (100 % del viewport, sin contenedor central). Es una decisión visual: si la dejaras dentro del container del 90 %, parecería un elemento más del cuerpo; al borde, el ojo la lee como continuación del hero. Y, salvo el patrón sticky de la sección anterior, no es fija: se desplaza con el contenido. En la home aparece dos veces —arriba bajo el hero, abajo como cierre/interlinking—; en otras páginas, basta con una.

Módulos cercanos: hero (lo que viene encima), tarjeta de categoría (la vitrina que aparece debajo) y CTA banner (el mismo patrón al cierre de la página).

Implementación

Cómo está construido

Un componente reutilizable de tres props: items, cta y ariaLabel. En la home se alimenta de NAV; el CTA se arma con waUrl. Misma pieza, dos usos: arriba reparte hacia secciones, abajo hacia páginas internas.

El componente vive en SectionMenu.astro y expone una API pequeña a propósito: items (la lista de botones), cta (el de conversión, opcional) y ariaLabel (la etiqueta accesible del <nav>). El responsive lo resuelve el propio componente —apila en móvil, una fila en escritorio—, y el CTA se distingue solo cuando llega la prop. No hace falta más para los tres usos habituales (atajos del hero, anclas, cierre).

La regla canónica está cableada en el diseño, no en la documentación: la prop cta nunca se teclea como wa.me; siempre se arma con waUrl(WA_MESSAGES.cotizar) (regla D4 del proyecto). Y en la home, items no se escribe a mano: se filtra y mapea desde NAV —la misma fuente del header—. Así, agregar una sección al menú principal la añade automáticamente a esta franja; quitarla la elimina. Una sola edición, dos sitios actualizados.

Astro · uso básico desde una página
---
// USO BÁSICO · pásale items + cta y listo. El componente
// se encarga del responsive (apilados en móvil, una fila
// en escritorio) y del destacado del CTA. No necesita más.
import SectionMenu from '@components/SectionMenu.astro'
import { WA_MESSAGES, waUrl } from '@config/site'

const items = [
  { label: 'Productos', href: '/productos', sub: 'Catálogo del sitio' },
  { label: 'Servicios', href: '/servicios', sub: 'Lo que ofreces' },
  { label: 'Cobertura', href: '/cobertura', sub: 'Zonas que atiendes' },
  { label: 'Blog',      href: '/blog',      sub: 'Guías y artículos' },
]
const cta = {
  label: 'Cotizar por WhatsApp',
  href: waUrl(WA_MESSAGES.cotizar),     // regla D4 · nunca wa.me a mano
  sub: 'Respuesta inmediata',
  external: true,
}
---

<SectionMenu items={items} cta={cta} ariaLabel="Secciones del sitio" />
Astro · data-driven desde NAV (la home)
---
// DATA-DRIVEN DESDE NAV · cómo lo hace la home (src/pages/index.astro).
// Una sola fuente (NAV en site.ts) alimenta el HEADER y esta FRANJA, así
// que agregar una sección al menú la añade aquí también, sin tocar nada.
import { NAV, WA_MESSAGES, waUrl } from '@config/site'
import SectionMenu from '@components/SectionMenu.astro'

// Quitamos "Contacto" (vive en el CTA) y mapeamos al formato del menú.
const items = NAV
  .filter((n) => n.label !== 'Contacto')
  .map((n) => ({
    label: n.label,
    href:  n.href,
    sub:   n.allLabel ?? undefined,    // p. ej. "Ver catálogo completo"
  }))

const cta = {
  label: 'Cotizar por WhatsApp',
  href:  waUrl(WA_MESSAGES.cotizar),
  sub:   'Respuesta inmediata',
  external: true,
}
---

<SectionMenu items={items} cta={cta} />
Astro · anclas a secciones (landing one-page)
---
// ANCLAS A SECCIONES · convierte la franja en índice de la propia página.
// Útil en landings largas: el botón hace scroll suave a la sección con ese id.
// Recuerda poner el id en cada <section> destino (id="catalogo", etc.).
const indice = [
  { label: 'Catálogo',  href: '#catalogo',  sub: 'Lo que ofrecemos' },
  { label: 'Servicios', href: '#servicios', sub: 'Cómo lo hacemos' },
  { label: 'Reseñas',   href: '#resenas',   sub: 'Lo que dicen' },
  { label: 'FAQ',       href: '#faq',       sub: 'Dudas comunes' },
]
---

<SectionMenu items={indice} cta={cta} />

<style is:global>
  /* Scroll suave para todos los anchors de la página. */
  html { scroll-behavior: smooth; }

  /* Compensa el header si lo tienes sticky, para que el ancla
     no quede tapada por la barra al hacer el salto. */
  :target { scroll-margin-top: var(--header-height, 64px); }
</style>

En concreto: el componente recorre items con Array.prototype.map y emite un <li> por cada uno, con su <a> centrado y, si tiene sub, una segunda línea por debajo. Si llega la prop cta, añade una última celda con .secbtn--cta que cambia el fondo a var(--c-primary) y el texto a blanco. Para enlaces externos (external: true), se añade target="_blank" y rel="noopener" de oficio.

La accesibilidad es de fábrica: el contenedor es un <nav aria-label>, cada botón es un <a> con foco visible (:focus-visible) y los iconos van con aria-hidden="true". El SVG de WhatsApp del CTA está inline en el componente y se colorea con currentColor, así sigue al color del texto del botón en todos los estados (hover, focus). Para usuarios con prefers-reduced-motion, se desactivan las transiciones de fondo. Cero JavaScript: es HTML + CSS estático, generado en build.

Buenas prácticas

Qué hacer y qué evitar

La diferencia entre una franja que convierte y una que estorba cabe en un puñado de hábitos —empezando por no duplicar el menú del header—.

Ninguno de estos hábitos es capricho: salen de mirar dónde tropieza el equipo cuando reusa el componente. Una franja útil mantiene 4–6 botones, tiene un único CTA al final y se alimenta de la misma fuente que el header. Una que estorba acumula botones, compite con el menú principal o duplica el wa.me a mano (y rompe la regla D4 del proyecto al primer cambio de número).

La buena noticia es que casi todo se sostiene solo cuando se respeta la fuente única (NAV) y waUrl(). Abajo, lo que conviene y lo que conviene evitar, enfrentados.

Sí conviene

  • Deriva los botones de la MISMA fuente que el header (NAV en site.ts); no escribas una segunda lista a mano.
  • Mantén el CTA de conversión como ÚLTIMO botón y arma su enlace con waUrl() (regla D4).
  • Limita la franja a 4–6 botones: si la lista crece, gana ruido y pierde atajo.
  • Mantén la etiqueta corta y reconocible («Productos», no «Nuestro catálogo de productos»).
  • Apila en móvil de fábrica: una fila a ancho completo por botón, con buen objetivo táctil.

Mejor evita

  • No metas el logotipo ni el menú principal aquí: este módulo NO sustituye al header.
  • No conviertas la franja en un mini-menú con todas las secciones del sitio: son ATAJOS, no un mapa.
  • No pongas dos CTAs de conversión compitiendo: uno solo, al final, con color de marca.
  • No tecles el wa.me a mano en el CTA: usa waUrl(WA_MESSAGES.cotizar) (regla D4).
  • No la dupliques inmediatamente bajo el header: su sitio es debajo del hero, no encima de él.
¿Necesitas ayuda?