/**
 * Hoja de estilo — Virtual Space CR (VSCR-02C).
 *
 * Implementa docs/Handoff/design_handoff_virtual_space_cr/README.md +
 * Home.dc.html + Sistema Visual.dc.html + Patrones de Pagina.dc.html.
 * Sin librerías de utilidades, sin bundler: un solo archivo enlazado
 * junto a tokens.css desde views/_cabecera.php.
 */

/* ---------------------------------------------------------------
   1. Reset y base
   --------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  background: var(--blanco);
  color: var(--tinta);
  font-family: var(--fuente-texto);
  font-size: var(--cuerpo-mobile);
  line-height: 1.6;
}
img, svg, video, iframe { max-width: 100%; display: block; }
a { color: var(--azul-senal); text-decoration: none; }
a:hover { color: var(--azul-profundo); }
button { font: inherit; cursor: pointer; }
ul, ol { margin: 0; padding: 0; list-style: none; }
h1, h2, h3, h4, p { margin: 0; }

h1, h2, h3, h4 { font-family: var(--fuente-titulos); color: var(--tinta); }
h1 { font-weight: 700; font-size: var(--h1-mobile); line-height: 1.10; letter-spacing: -.02em; text-wrap: balance; }
h2 { font-weight: 700; font-size: var(--h2-mobile); line-height: 1.15; letter-spacing: -.015em; text-wrap: balance; }
h3 { font-weight: 600; font-size: var(--h3-mobile); line-height: 1.20; }
h4 { font-weight: 600; font-size: var(--h4-mobile); line-height: 1.30; }
p { text-wrap: pretty; }

.vs-lead { font-size: var(--lead-mobile); line-height: 1.65; color: var(--tinta-60); max-width: 56ch; }
.vs-mono {
  font-family: var(--fuente-mono);
  font-size: var(--mono-mobile);
  letter-spacing: .14em;
  text-transform: uppercase;
}
.vs-medida { max-width: 62ch; }

/* Enlace "saltar al contenido" — primer elemento enfocable de cada plantilla. */
.vs-saltar {
  position: absolute;
  left: 8px;
  top: -48px;
  z-index: 100;
  background: var(--azul-profundo);
  color: var(--blanco);
  font-family: var(--fuente-titulos);
  font-weight: 600;
  font-size: 14px;
  padding: 12px 18px;
  transition: top var(--dur-hover) var(--curva);
}
.vs-saltar:focus {
  top: 8px;
  color: var(--blanco);
}

/* Foco visible en todo elemento interactivo — nunca outline:none. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible {
  outline: 3px solid var(--azul-senal);
  outline-offset: 2px;
}

/* PRR-056: sobre navy el azul señal da 2,97:1 y 1.4.11 pide 3:1. En las
   superficies oscuras el anillo pasa al dorado de la marca (~10:1 sobre
   #0B1157), como ya hacían el visor ampliado y el chrome del panel. Sólo
   cambia el color: grosor y separación siguen siendo los del sistema. */
:is(.vs-topbar, .vs-menu-movil, .vs-seccion--oscura, .vs-cta-banda--oscura, .vs-barra-datos, .vs-tarjeta-servicio--destacada,
    .vs-s1__cta, .vs-retail__cta, .vs-arq-a__cta, .vs-arq-b__cta, .vs-arq-c__cta, .vs-indice-cta, .vs-pie, .vs-consentimiento,
    .vs-ferias__concepto, .vs-ferias__seccion--oscura, .vs-ferias__cta) :focus-visible {
  outline-color: var(--dorado);
}

.vs-contenedor {
  max-width: var(--contenedor-max);
  margin: 0 auto;
  padding: 0 var(--contenedor-margen-mobile);
}
@media (max-width: 359.98px) {
  .vs-contenedor { padding: 0 var(--contenedor-margen-mobile-360); }
}
@media (min-width: 768px) {
  .vs-contenedor { padding: 0 var(--contenedor-margen-tablet); }
}
@media (min-width: 1120px) {
  .vs-contenedor { padding: 0 var(--contenedor-margen-desktop); }
}

.vs-seccion { padding: var(--seccion-py-mobile) 0; }
@media (min-width: 768px) { .vs-seccion { padding: var(--seccion-py-tablet) 0; } }
@media (min-width: 1120px) { .vs-seccion { padding: var(--seccion-py-desktop) 0; } }
.vs-seccion--suave { background: var(--fondo-suave); }
.vs-seccion--oscura { background: var(--azul-profundo); }
.vs-seccion--borde { border-bottom: var(--borde-estructura); }

/* ---------------------------------------------------------------
   2. Malla de escaneo y placeholders (únicas piezas decorativas)
   --------------------------------------------------------------- */
.vs-placeholder {
  position: relative;
  background-image: repeating-linear-gradient(135deg, #D9DDE4 0 9px, #E4E7EC 9px 18px);
}
.vs-placeholder--oscuro {
  background-image: repeating-linear-gradient(135deg, #1B2470 0 10px, #161E60 10px 20px);
}
.vs-malla {
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(rgba(11, 17, 87, .13) 1px, transparent 1px),
    linear-gradient(90deg, rgba(11, 17, 87, .13) 1px, transparent 1px);
  background-size: 26px 26px;
  pointer-events: none;
}
.vs-malla--oscura {
  background-image:
    linear-gradient(rgba(46, 155, 230, .28) 1px, transparent 1px),
    linear-gradient(90deg, rgba(46, 155, 230, .28) 1px, transparent 1px);
  background-size: 34px 34px;
}
.vs-malla--enmascarada {
  mask-image: radial-gradient(120% 90% at 70% 40%, #000 20%, transparent 78%);
  -webkit-mask-image: radial-gradient(120% 90% at 70% 40%, #000 20%, transparent 78%);
}
.vs-placeholder__etiqueta {
  position: absolute;
  left: 0;
  top: 0;
  font-family: var(--fuente-mono);
  font-size: 10px;
  letter-spacing: .12em;
  text-transform: uppercase;
  background: var(--tinta);
  color: var(--blanco);
  padding: 5px 9px;
  z-index: 1;
}
.vs-placeholder__etiqueta--dorada { background: var(--dorado); color: var(--tinta); }
.vs-placeholder__texto {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: var(--sp-6);
  font-family: var(--fuente-mono);
  font-size: 12px;
  color: #5A6270;
  z-index: 1;
}
.vs-placeholder--oscuro .vs-placeholder__texto { color: #9FB6DA; }

/* ---------------------------------------------------------------
   3. Botones
   --------------------------------------------------------------- */
.vs-boton {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-3);
  font-family: var(--fuente-titulos);
  font-weight: 600;
  font-size: var(--boton-mobile);
  min-height: var(--sp-13);
  padding: 0 var(--sp-8);
  border: 0;
  border-radius: var(--radio);
  transition: background var(--dur-hover) var(--curva), border-color var(--dur-hover) var(--curva), color var(--dur-hover) var(--curva);
}
@media (min-width: 1120px) { .vs-boton { font-size: var(--boton-desktop); } }
.vs-boton--primario { background: var(--azul-profundo); color: var(--blanco); }
.vs-boton--primario:hover { background: var(--azul-profundo-900); color: var(--blanco); }
.vs-boton--secundario { background: transparent; color: var(--azul-profundo); border: var(--borde-boton-secundario); }
.vs-boton--secundario:hover { background: var(--fondo-suave); color: var(--azul-profundo); }
.vs-boton--dorado { background: var(--dorado); color: var(--tinta); }
.vs-boton--dorado:hover { background: #FFD24A; color: var(--tinta); }
.vs-boton--sobre-dorado { background: transparent; color: var(--tinta); border: 1.5px solid var(--tinta); }
.vs-boton--sobre-dorado:hover { background: rgba(0, 0, 0, .06); }
.vs-boton--ancho-completo { width: 100%; }
.vs-boton--deshabilitado,
.vs-boton:disabled { background: #C6CBD4; color: var(--tinta-45); cursor: not-allowed; }

/* ---------------------------------------------------------------
   4. Topbar + header + navegación
   --------------------------------------------------------------- */
.vs-topbar {
  background: var(--azul-profundo);
  color: #C9D3E8;
  font-size: 13px;
}
.vs-topbar .vs-contenedor {
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-6);
}
.vs-topbar__info { display: flex; gap: var(--sp-6); align-items: center; flex-wrap: wrap; }
.vs-topbar a { color: #C9D3E8; }
.vs-topbar a:hover { color: var(--blanco); }
.vs-topbar__cobertura { font-family: var(--fuente-mono); font-size: 11px; letter-spacing: .12em; color: var(--sobre-oscuro-3); }
@media (max-width: 767.98px) { .vs-topbar { display: none; } }

.vs-encabezado {
  /* Alto del contenedor en cada estado, en px sin unidad para poder dividir
     (VSCR-78; congelados en VSCR-15C como 117/69 con el borde). 68 es lo
     que necesita el isotipo a 52px con aire arriba y abajo. */
  --vs-encabezado-alto: 68;
  --vs-encabezado-alto-compacto: 68;
  position: sticky;
  top: 0;
  z-index: 50;
  /* El borde conserva su grosor para que la caja siga midiendo 117/69,
     pero su color lo pinta `::after`, igual que `::before` pinta el fondo. */
  border-bottom: var(--borde-estructura);
  border-bottom-color: transparent;
}
.vs-encabezado .vs-contenedor {
  height: calc(var(--vs-encabezado-alto) * 1px);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-6);
}
.vs-encabezado--compacto .vs-contenedor { height: calc(var(--vs-encabezado-alto-compacto) * 1px); }
@media (min-width: 768px) {
  /* 116px es la altura que exige el mínimo oficial del lockup (VSCR-78):
     300px de ancho a la proporción real 2,985:1 dan ~101px de caja, y el
     SVG trae 14px de aire propio por lado a esa escala. Por debajo de esto
     el lockup no cabe sin bajar del mínimo de marca. */
  .vs-encabezado { --vs-encabezado-alto: 116; }
}

/* H-STICKY-A (VSCR-98). El header es sticky y vive en el flujo: al
   compactarse, sus 48px de menos subían toda la página, el anclaje de
   scroll del navegador lo compensaba devolviendo `scrollY` por debajo del
   umbral, y el header oscilaba a ritmo de fotograma entre 81 y 128. El
   margen devuelve la diferencia al flujo: la huella queda constante y el
   contenido no se mueve. Por debajo de 768 la diferencia es 0. */
.vs-encabezado--compacto {
  margin-bottom: calc((var(--vs-encabezado-alto) - var(--vs-encabezado-alto-compacto)) * 1px);
}

/* H-STICKY-B. El fondo blanco y el filete inferior son capas propias con
   el alto del estado expandido. El compacto las reduce con `transform`
   (escala del fondo, desplazamiento del filete), así que la transición
   entre los dos estados aprobados no mueve ninguna caja. */
.vs-encabezado::before,
.vs-encabezado::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  z-index: -1;
  pointer-events: none;
}
.vs-encabezado::before {
  top: 0;
  height: calc(var(--vs-encabezado-alto) * 1px);
  background: var(--blanco);
  transform-origin: top;
}
.vs-encabezado::after {
  top: calc(var(--vs-encabezado-alto) * 1px);
  border-top: var(--borde-estructura);
}
.vs-encabezado--compacto::before { transform: scaleY(calc(var(--vs-encabezado-alto-compacto) / var(--vs-encabezado-alto))); }
.vs-encabezado--compacto::after { transform: translateY(calc((var(--vs-encabezado-alto-compacto) - var(--vs-encabezado-alto)) * 1px)); }

/* Marca (VSCR-76) — logo oficial, no reconstruido.
   Hasta esta unidad el "logo" eran un cuadrado hecho con pseudo-elementos y
   el nombre tecleado a mano; se sustituyó por el lockup horizontal oficial.
   El alto manda (el header tiene altura fija y se compacta al hacer scroll) y
   el ancho lo deriva el SVG por su relación de aspecto, así que la proporción
   no puede deformarse aunque cambie la altura del encabezado. */
/* Frente D (VSCR-97, lámina «Header con siete ítems»): nada de la fila se
   comprime. Marca, navegación, ítems, selector y CTA son `flex: none`; si no
   cabe, se cambia de franja, nunca se encoge el lockup ni se parte el CTA. */
.vs-marca { display: flex; align-items: center; position: relative; flex: none; }

/* Dos archivos oficiales, no uno escalado (VSCR-78). El lockup horizontal
   tiene un mínimo digital de 290px de ancho; por debajo de eso la guía dice
   que el trazo se rompe. Donde no caben 290px —móvil y encabezado compacto—
   se usa el isotipo oficial, que tiene su propio mínimo de 48px de alto.
   El lockup NUNCA se reduce por debajo de su mínimo: se cambia de archivo.
   CSS no puede cambiar un `src`, así que ambos van en el marcado y aquí se
   decide cuál se muestra. */
.vs-marca__logo { width: 300px; height: auto; }
.vs-marca__isotipo { height: 52px; width: auto; }

/* Móvil: 290 (lockup) + 44 (botón de menú) + 2×20 (márgenes) = 374px en un
   viewport de 375. No cabe. Manda el isotipo. */
.vs-marca__logo { display: none; }
.vs-marca__isotipo { display: block; }
@media (min-width: 768px) {
  .vs-marca__logo { display: block; }
  /* El archivo que no toca espera superpuesto e invisible:
     - fuera del flujo, para no alterar la composición;
     - con `pointer-events: none`, para no tapar el primer enlace de la
       navegación;
     - listo para el fundido de H-STICKY-B (VSCR-98). */
  .vs-marca__isotipo,
  .vs-encabezado--compacto .vs-marca__logo {
    position: absolute;
    left: 0;
    top: 50%;
    translate: 0 -50%;
    /* Superpuesto, el lockup no debe heredar el `max-width: 100%` de las
       imágenes: la marca mide lo que el isotipo, y lo encogería a 49px. */
    max-width: none;
    opacity: 0;
    pointer-events: none;
  }
  /* Compacto/sticky: 68px de alto no admiten el lockup a su mínimo, así
     que manda el isotipo a 52px (D-6D). En móvil ya es el único visible. */
  .vs-encabezado--compacto .vs-marca__isotipo { position: static; translate: none; opacity: 1; pointer-events: auto; }
}
/* Franjas exactas de la lámina D. 1120–1399,98: el expandido cambia de
   archivo al isotipo de 52 px, el mismo del compacto; con siete ítems el
   lockup no cabe a 300 sin comprimirse. ≥ 1400: vuelve el lockup a 300
   fijo en el expandido. Es un cambio de archivo por media query —sin escala
   ni animación nueva— y no toca H-STICKY-A/B, 117/69 ni el umbral 80/81.
   Por debajo de 1120 no cambia nada. */
@media (min-width: 1120px) {
  .vs-marca__logo { position: absolute; left: 0; top: 50%; translate: 0 -50%; max-width: none; opacity: 0; pointer-events: none; }
  .vs-marca__isotipo { position: static; translate: none; opacity: 1; pointer-events: auto; }
}
@media (min-width: 1400px) {
  .vs-marca__logo { position: static; translate: none; opacity: 1; pointer-events: auto; }
  .vs-marca__isotipo { position: absolute; translate: 0 -50%; opacity: 0; pointer-events: none; }
}

/* H-STICKY-B · transiciones:
   - Sólo desde que `sitio.js` marca el header como animable: una carga o
     una restauración de historial a mitad de página nacen ya en su estado,
     sin animar.
   - Sólo sin `prefers-reduced-motion`: el reset global usa `*`, que no
     alcanza a los pseudoelementos.
   - Las piezas de la fila (marca, navegación, acciones) las desliza
     `sitio.js` con transform. */
@media (prefers-reduced-motion: no-preference) {
  .vs-encabezado--animado::before,
  .vs-encabezado--animado::after { transition: transform var(--dur-hover) var(--curva); }
  .vs-encabezado--animado .vs-marca__logo,
  .vs-encabezado--animado .vs-marca__isotipo { transition: opacity var(--dur-hover) var(--curva); }
}

/* Siete ítems (lámina D): gap 24 entre 1120 y 1279,98 y 30 desde 1280. Con
   30 a 1120 faltaría 1 px (960 + 49 > 1008). */
.vs-nav-principal { display: none; align-items: center; gap: var(--sp-8); flex: none; }
@media (min-width: 1120px) { .vs-nav-principal { display: flex; } }
@media (min-width: 1280px) { .vs-nav-principal { gap: 30px; } }
.vs-nav-principal__enlace {
  flex: none;
  white-space: nowrap;
  font-family: var(--fuente-titulos);
  font-weight: 500;
  font-size: var(--nav-desktop);
  color: #3A4152;
  padding: 30px 0 28px;
  border-bottom: 2px solid transparent;
  transition: color var(--dur-hover) var(--curva), border-color var(--dur-hover) var(--curva);
}
.vs-nav-principal__enlace:hover { color: var(--azul-profundo); border-bottom-color: var(--borde); }
/* `true` marca la sección sin ser su índice: Blog en un artículo (lámina D,
   «aria-current="page" sólo en el índice»). Se ve igual que `page`. */
.vs-nav-principal__enlace[aria-current="page"],
.vs-nav-principal__enlace[aria-current="true"] {
  font-weight: 600;
  color: var(--azul-profundo);
  border-bottom-color: var(--azul-senal);
}
/* PRR-068: el enlace mide 82 px y el header compacto 68, así que el subrayado
   quedaba 6 px por debajo del header, pintado sobre el contenido. En modo
   compacto el enlace conserva la misma relación que en el alto —centrado,
   con el subrayado ~10 px por encima del borde— reduciendo sólo el padding. */
.vs-encabezado--compacto .vs-nav-principal__enlace { padding: 12px 0 10px; }
.vs-nav-idiomas { display: flex; flex: none; align-items: center; gap: var(--sp-2); padding-left: var(--sp-2); border-left: var(--borde-estructura); }
.vs-nav-idiomas a {
  font-family: var(--fuente-mono);
  font-size: 12px;
  min-height: 44px;
  min-width: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--tinta-45);
}
.vs-nav-idiomas a[aria-current="true"] { color: var(--azul-profundo); font-weight: 500; }
.vs-encabezado__acciones { display: flex; flex: none; align-items: center; gap: var(--sp-4); }
/* El CTA a su ancho natural en una línea (193 en ES): sin `flex-shrink` que
   lo lleve a 181 ni a dos líneas. */
.vs-encabezado__acciones .vs-boton { display: none; flex: none; white-space: nowrap; }
@media (min-width: 1120px) { .vs-encabezado__acciones .vs-boton { display: inline-flex; } }

.vs-hamburguesa {
  width: 44px;
  height: 44px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  background: none;
  border: 0;
  padding: 0 10px;
}
@media (min-width: 1120px) { .vs-hamburguesa { display: none; } }
.vs-hamburguesa span { height: 2px; background: var(--tinta); }

.vs-menu-movil {
  background: var(--azul-profundo);
  padding: 12px 0 24px;
}
@media (min-width: 1120px) { .vs-menu-movil { display: none; } }
.vs-menu-movil[hidden] { display: none; }
.vs-menu-movil__enlace {
  display: flex;
  align-items: center;
  min-height: 52px;
  font-family: var(--fuente-titulos);
  font-weight: 500;
  font-size: var(--nav-mobile);
  color: var(--sobre-oscuro);
  border-bottom: 1px solid var(--borde-oscuro-2);
}
.vs-menu-movil__enlace[aria-current="page"],
.vs-menu-movil__enlace[aria-current="true"] { font-weight: 600; color: var(--blanco); }
.vs-menu-movil__idiomas { display: flex; align-items: center; gap: var(--sp-4); padding: var(--sp-4) 0; }
.vs-menu-movil__idiomas a {
  font-family: var(--fuente-mono);
  font-size: 13px;
  min-height: 44px;
  min-width: 44px;
  display: flex;
  align-items: center;
  color: var(--sobre-oscuro);
}
.vs-menu-movil__idiomas a[aria-current="true"] { color: var(--blanco); font-weight: 600; }
.vs-menu-movil .vs-boton { margin-top: var(--sp-6); }

/* ---------------------------------------------------------------
   5. Hero
   --------------------------------------------------------------- */
.vs-hero {
  display: grid;
  grid-template-columns: 1fr;
  border-bottom: var(--borde-estructura);
}
/* VSCR-86 · H-02 (2026-09-12): la retícula de dos columnas arranca en 1120,
   no en 768. `Patrones de Pagina.dc.html` → REGLAS DEL SISTEMA → 768–1119:
   «Hero se apila, pero el visual conserva 16:9». Con el corte en 768 la
   columna de texto quedaba en 369px de caja y 249px útiles —unos 30
   caracteres—, medido en Chrome real. 1120 es la banda canónica ya existente
   del sistema; no se introduce ningún breakpoint nuevo. */
@media (min-width: 1120px) {
  .vs-hero { grid-template-columns: minmax(0, 1fr) minmax(0, 1.08fr); align-items: stretch; }
}
.vs-hero__texto {
  padding: var(--sp-9) var(--contenedor-margen-mobile) var(--sp-9);
  display: flex;
  flex-direction: column;
  justify-content: center;
}
/* Apilado (768–1119): el texto ocupa el ancho completo con el margen de
   tablet que fijan las REGLAS (32px) y el ritmo vertical de sección (56px).
   Sin `max-width`: aquí ya no compite con un visual a su derecha. */
@media (min-width: 768px) and (max-width: 1119px) {
  .vs-hero__texto { padding: var(--seccion-py-tablet) var(--contenedor-margen-tablet); }
}
@media (min-width: 1120px) {
  .vs-hero__texto { padding: var(--sp-16) var(--sp-15) var(--sp-16) var(--sp-14); max-width: 720px; }
}
.vs-hero__eyebrow { display: flex; align-items: center; gap: var(--sp-3); margin-bottom: var(--sp-7); }
.vs-hero__eyebrow-linea { width: 26px; height: 2px; background: var(--dorado); }
.vs-hero__eyebrow .vs-mono { color: var(--azul-senal); }
.vs-hero__titulo { font-size: var(--h1-mobile); margin-bottom: var(--sp-6); }
@media (min-width: 1120px) { .vs-hero__titulo { font-size: var(--h1-desktop); line-height: 1.08; } }
.vs-hero__lead { margin-bottom: var(--sp-9); }
.vs-hero__acciones { display: flex; flex-direction: column; gap: var(--sp-3); margin-bottom: var(--sp-9); }
.vs-hero__acciones .vs-boton { min-height: 52px; }
@media (min-width: 768px) {
  .vs-hero__acciones { flex-direction: row; flex-wrap: wrap; }
  .vs-hero__acciones .vs-boton { min-height: 44px; width: auto; }
}
/* CTA → filete de la franja: 34 / 30 / 28 (VSCR-95 B, «Geometría»). */
@media (min-width: 768px) and (max-width: 1119px) { .vs-hero__acciones { margin-bottom: 30px; } }
@media (min-width: 1120px) { .vs-hero__acciones { margin-bottom: 34px; } }

/* Franja inferior del hero con 9+ (VSCR-95 B, lámina aprobada · D-6C.1).
   Móvil (< 768): dos bloques en columna, separados por un filete de 1 px.
   Tablet (768–1119) y escritorio (≥ 1120): una fila con separador vertical;
   `flex-wrap` deja bajar el segundo bloque si el EN no cabe, sin solaparse.
   Sin borde, contorno, fondo ni caja (B-R1): sólo el filete superior. */
.vs-hero__pie {
  display: flex;
  flex-direction: column;
  gap: var(--sp-6);
  border-top: var(--borde-estructura);
  padding-top: 18px;
}
.vs-hero__pie p { margin: 0; }
.vs-hero__pie-sectores { display: flex; align-items: center; gap: var(--sp-4); }
.vs-hero__pie-numeral {
  font-family: var(--fuente-titulos);
  font-weight: 700;
  font-size: 28px;
  line-height: 1;
  letter-spacing: -.03em;
  color: var(--azul-profundo);
  min-width: 40px;
}
/* El «+» es el que dice «o más»: recibe el acento, en ámbar de texto
   (#8A5E00, 5,3:1). Nunca #F0BF2E, que como texto no alcanza contraste. */
.vs-hero__pie-mas { color: #8A5E00; }
.vs-hero__pie-etiqueta {
  font-family: var(--fuente-mono);
  font-size: var(--mono-mobile);
  line-height: 1.45;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--tinta-60);
}
.vs-hero__pie-separador { display: none; }
.vs-hero__pie-entrega {
  display: flex;
  flex-direction: column;
  gap: var(--sp-1);
  padding-top: var(--sp-5);
  border-top: var(--borde-estructura);
}
.vs-hero__pie-triada {
  font-family: var(--fuente-titulos);
  font-weight: 600;
  font-size: 15px;
  color: var(--tinta);
}
.vs-hero__pie-triada span { color: var(--tinta-30); }
@media (min-width: 768px) {
  .vs-hero__pie { flex-direction: row; flex-wrap: wrap; align-items: center; gap: var(--sp-8); padding-top: var(--sp-7); }
  .vs-hero__pie-numeral { font-size: 32px; min-width: 0; }
  .vs-hero__pie-etiqueta { font-size: var(--mono-desktop); }
  .vs-hero__pie-etiqueta--sectores { max-width: 17ch; }
  :lang(en) .vs-hero__pie-etiqueta--sectores { max-width: 19ch; }
  .vs-hero__pie-separador { display: block; width: 1px; height: 40px; background: var(--borde); }
  .vs-hero__pie-entrega { padding-top: 0; border-top: 0; }
}
@media (min-width: 1120px) {
  .vs-hero__pie { gap: var(--sp-9); padding-top: 22px; }
  .vs-hero__pie-sectores { gap: var(--sp-5); }
  .vs-hero__pie-numeral { font-size: 36px; }
  .vs-hero__pie-separador { height: 44px; }
}
.vs-hero__visual {
  position: relative;
  min-height: 300px;
  background: var(--azul-profundo);
}
/* VSCR-86 · H-02: apilado, el visual conserva 16:9 (REGLAS 768–1119). La
   altura fija de 560px sólo tiene sentido cuando el visual es una columna
   que debe igualar al texto, es decir a partir de 1120. */
@media (min-width: 768px) and (max-width: 1119px) { .vs-hero__visual { aspect-ratio: 16 / 9; } }
@media (min-width: 1120px) { .vs-hero__visual { min-height: 560px; } }
.vs-hero__visual-contenido {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: var(--sp-8);
  z-index: 1;
}
.vs-hero__visual-etiqueta {
  align-self: flex-start;
  font-family: var(--fuente-mono);
  font-size: 11px;
  letter-spacing: .14em;
  color: var(--tinta);
  background: var(--dorado);
  padding: 6px 10px;
}
.vs-hero__visual-imagen {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.vs-hero__visual-degradado {
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(11, 17, 87, .45) 0%, rgba(11, 17, 87, 0) 32%, rgba(11, 17, 87, .6) 100%);
}
.vs-hero__visual-pie { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-6); flex-wrap: wrap; }
.vs-hero__visual-pie .vs-mono { color: var(--sobre-oscuro-3); text-transform: uppercase; letter-spacing: .12em; }
@media (max-width: 767.98px) {
  .vs-hero__visual .vs-boton { position: absolute; left: 16px; right: 16px; bottom: 16px; }
  /* VSCR-104 · OBS-VIS-04: el botón (16 + 48) tapaba el nombre del
     recorrido. El nombre sube a 16 + 48 + 12 = 76 sobre un degradado de
     132 px que se suma al vigente; el botón, el IDLE y el visor no cambian. */
  .vs-hero__visual-pie .vs-mono {
    position: absolute;
    left: 16px;
    right: 16px;
    bottom: 76px;
    font-size: 11px;
    line-height: 1.4;
    letter-spacing: .12em;
    color: var(--sobre-oscuro);
  }
  .vs-hero__visual-degradado {
    background:
      linear-gradient(to top, rgba(7, 11, 54, .9) 59.4px, rgba(7, 11, 54, 0) 132px),
      linear-gradient(180deg, rgba(11, 17, 87, .45) 0%, rgba(11, 17, 87, 0) 32%, rgba(11, 17, 87, .6) 100%);
  }
}

/* Hero variante B (páginas internas: un solo CTA, sin pie de estadísticas) */
.vs-hero-interno { display: grid; grid-template-columns: 1fr; border-bottom: var(--borde-estructura); }
@media (min-width: 768px) { .vs-hero-interno { grid-template-columns: 1fr 1.05fr; } }
.vs-hero-interno__texto { padding: var(--sp-9) var(--contenedor-margen-mobile); }
@media (min-width: 768px) { .vs-hero-interno__texto { padding: var(--sp-14) var(--sp-11); } }
.vs-hero-interno__visual { position: relative; min-height: 220px; }
@media (min-width: 768px) { .vs-hero-interno__visual { min-height: 340px; } }
.vs-hero-interno__titulo { font-size: var(--h1-mobile); margin-bottom: var(--sp-6); }
@media (min-width: 1120px) { .vs-hero-interno__titulo { font-size: var(--h1-interna-desktop); } }

.vs-migas {
  font-family: var(--fuente-mono);
  font-size: 12px;
  color: var(--tinta-45);
  margin-bottom: var(--sp-6);
}
.vs-migas a { color: var(--azul-senal); }
.vs-migas--sobre-oscuro,
.vs-migas--sobre-oscuro a { color: var(--sobre-oscuro-3); }
.vs-migas--sobre-oscuro a { color: var(--dorado); }

/* ---------------------------------------------------------------
   6. Bloques de valor
   --------------------------------------------------------------- */
.vs-valores { display: flex; flex-direction: column; gap: var(--sp-8); }
.vs-valor { padding-left: var(--sp-6); border-left: 2px solid var(--borde); }
.vs-valor--primero { border-left-color: var(--azul-senal); }
.vs-valor__numero { font-family: var(--fuente-mono); font-size: 12px; color: var(--azul-senal); margin-bottom: var(--sp-4); }
.vs-valor h2 { margin-bottom: var(--sp-3); }
.vs-valor p { color: var(--tinta-60); }
@media (min-width: 1120px) {
  .vs-valores { flex-direction: row; border-left: var(--borde-estructura); }
  .vs-valor { flex: 1; padding: 0 var(--sp-9); border-left: 0; border-right: var(--borde-estructura); }
}

/* ---------------------------------------------------------------
   7. Servicios + card de servicio
   --------------------------------------------------------------- */
.vs-seccion__cabecera {
  display: flex;
  flex-direction: column;
  gap: var(--sp-6);
  margin-bottom: var(--sp-10);
}
@media (min-width: 768px) {
  .vs-seccion__cabecera { flex-direction: row; align-items: flex-end; justify-content: space-between; }
}
.vs-seccion__enlace { font-family: var(--fuente-titulos); font-weight: 600; font-size: 15px; color: var(--azul-profundo); border-bottom: 2px solid var(--dorado); padding-bottom: 4px; align-self: flex-start; }
.vs-seccion--oscura .vs-seccion__enlace { color: var(--blanco); }

.vs-rejilla-servicios {
  display: flex;
  flex-direction: column;
  gap: 1px;
  background: var(--borde);
  border: var(--borde-estructura);
}
@media (min-width: 768px) { .vs-rejilla-servicios { display: grid; grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1120px) { .vs-rejilla-servicios { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 1120px) { .vs-rejilla-servicios--2col { grid-template-columns: repeat(2, 1fr); } }

/* Rejillas con menos elementos que columnas (VSCR-05D: los bloques de
   relación traen 1, 2 o 3). La rejilla dibuja sus filetes con
   `gap: 1px` sobre un fondo de color de borde, así que un track vacío
   no queda en blanco: se ve como un bloque gris. Estos modificadores
   ajustan el número de tracks al número real de tarjetas. Van después
   de las reglas base a propósito — misma especificidad, gana el orden
   de aparición, y así también sobrescriben el breakpoint de 1120px. */
@media (min-width: 768px) {
  .vs-rejilla-servicios--1col,
  .vs-rejilla-servicios--2col { width: fit-content; max-width: 100%; }
  .vs-rejilla-servicios--1col { grid-template-columns: minmax(0, 420px); }
  .vs-rejilla-servicios--2col { grid-template-columns: repeat(2, minmax(0, 420px)); }
}

/* Cuatro tarjetas (VSCR-76). Es el mismo defecto que describe el comentario
   de arriba, pero por el otro lado: con 4 servicios y 3 columnas la segunda
   fila deja DOS celdas vacías, y el fondo de la rejilla se ve como un gran
   rectángulo gris — el hallazgo del Product Owner. `--1col`/`--2col` no
   servían aquí porque están pensados para rejillas más angostas que el
   contenedor (`fit-content`, tope de 420px); con 4 tarjetas sí queremos
   ocupar todo el ancho. Se comparó en Chrome contra una fila de 4: a partir
   del breakpoint de 1120px esa opción deja las tarjetas en 251px y parte los
   títulos en inglés en tres líneas, así que 2×2 es la que aguanta todo el
   rango de escritorio. Va después del bloque de 768px para ganarle por orden
   de aparición. */
@media (min-width: 1120px) {
  .vs-rejilla-servicios--2x2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.vs-tarjeta-servicio {
  background: var(--blanco);
  padding: var(--sp-8) var(--sp-7) var(--sp-7);
  display: flex;
  flex-direction: column;
  min-height: 220px;
  transition: box-shadow var(--dur-hover) var(--curva);
}
@media (min-width: 1120px) { .vs-tarjeta-servicio { padding: var(--sp-9) var(--sp-8) var(--sp-8); min-height: 250px; } }
.vs-tarjeta-servicio:hover,
.vs-tarjeta-servicio:focus-within { box-shadow: inset 0 -3px 0 var(--azul-senal); }
.vs-tarjeta-servicio:hover h2,
.vs-tarjeta-servicio:hover h3,
.vs-tarjeta-servicio:focus-within h2,
.vs-tarjeta-servicio:focus-within h3 { color: var(--azul-profundo); }
.vs-tarjeta-servicio h2,
.vs-tarjeta-servicio h3 { font-size: 18px; margin-bottom: var(--sp-3); transition: color var(--dur-hover) var(--curva); }
@media (min-width: 1120px) {
  .vs-tarjeta-servicio h2,
  .vs-tarjeta-servicio h3 { font-size: 21px; }
}
.vs-tarjeta-servicio p { color: var(--tinta-60); margin-bottom: var(--sp-7); }
.vs-tarjeta-servicio__enlace { margin-top: auto; font-family: var(--fuente-titulos); font-weight: 600; font-size: 14px; color: var(--azul-senal); }
.vs-tarjeta-servicio__icono { width: 32px; height: 32px; border: 1.5px solid var(--azul-senal); margin-bottom: var(--sp-6); position: relative; flex: none; }
@media (min-width: 1120px) { .vs-tarjeta-servicio__icono { width: 38px; height: 38px; } }
/* Variante Tabler (VSCR-93): misma caja y misma separación al título que
   el marcador que sustituye —32 en móvil, 38 desde 1120—, pero sin
   contorno ni relleno: el glifo queda en trazo sobre la tarjeta, igual
   que en Soluciones. El dorado no entra en el glifo; sigue reservado a
   superficie de acción y acentos.

   Estas tres reglas se perdieron entre la edición y la limpieza de los
   marcadores muertos, y el panel de pruebas no lo vio: contar los `path`
   del HTML no dice a qué tamaño se dibujan. Lo encontró la CUA, midiendo
   el render — 36 px dentro del recuadro azul en vez de 24 sin recuadro. */
.vs-tarjeta-servicio__icono--tabler { border: none; display: flex; align-items: center; justify-content: center; color: var(--azul-profundo); }
.vs-tarjeta-servicio__icono-svg { width: 20px; height: 20px; }
@media (min-width: 1120px) { .vs-tarjeta-servicio__icono-svg { width: 24px; height: 24px; } }
.vs-tarjeta-servicio--destacada { background: var(--azul-profundo); color: var(--blanco); }
.vs-tarjeta-servicio--destacada h3 { color: var(--blanco); }
.vs-tarjeta-servicio--destacada p { color: var(--sobre-oscuro); }
.vs-tarjeta-servicio--destacada .vs-tarjeta-servicio__enlace { color: var(--dorado); }
.vs-tarjeta-servicio--destacada .vs-mono { color: var(--dorado); }
/* VSCR-104 · OBS-VIS-03: la regla común de las tarjetas de Servicios pinta el
   título de azul profundo en hover y foco, y sobre la destacada lo borraba
   (1,00:1). Aquí el título se queda blanco y el filete inferior pasa del azul,
   imperceptible sobre navy, al dorado. Es una sombra interior de 2 px, el
   mismo mecanismo que el resto de tarjetas, así que la caja no cambia. */
.vs-tarjeta-servicio--destacada:hover,
.vs-tarjeta-servicio--destacada:focus-within { box-shadow: inset 0 -2px 0 var(--dorado); }
.vs-tarjeta-servicio--destacada:hover h3,
.vs-tarjeta-servicio--destacada:focus-within h3 { color: var(--blanco); }

/* VSCR-109 · P-109-B1: el CTA de cierre de Home absorbe las celdas que quedan
   en su fila, según el número real de Servicios (`serviciosSpanCtaHome()`).
   Con dos o más columnas pasa a horizontal: el texto a la izquierda, con su
   medida de lectura, y el enlace a la derecha, centrado en vertical (gana
   al `align-self` del enlace dorado). Sólo la tarjeta destacada
   recibe estas clases, y con el catálogo de cuatro no se emite ninguna. En
   móvil la rejilla es una columna y nada cambia. */
@media (min-width: 768px) and (max-width: 1119px) {
  .vs-tarjeta-servicio--cta-768-2 { grid-column: span 2; flex-direction: row; align-items: center; justify-content: space-between; gap: var(--sp-7) 48px; min-height: 0; }
  .vs-tarjeta-servicio--cta-768-2 .vs-tarjeta-servicio__texto { max-width: 62ch; }
  .vs-tarjeta-servicio--cta-768-2 .vs-tarjeta-servicio__texto p { margin-bottom: 0; }
  .vs-tarjeta-servicio--cta-768-2 .vs-tarjeta-servicio__enlace { align-self: center; margin-top: 0; flex: none; }
}
@media (min-width: 1120px) {
  .vs-tarjeta-servicio--cta-1120-2 { grid-column: span 2; }
  .vs-tarjeta-servicio--cta-1120-3 { grid-column: span 3; }
  :is(.vs-tarjeta-servicio--cta-1120-2, .vs-tarjeta-servicio--cta-1120-3) { flex-direction: row; align-items: center; justify-content: space-between; gap: var(--sp-7) 48px; min-height: 0; }
  :is(.vs-tarjeta-servicio--cta-1120-2, .vs-tarjeta-servicio--cta-1120-3) .vs-tarjeta-servicio__texto { max-width: 62ch; }
  :is(.vs-tarjeta-servicio--cta-1120-2, .vs-tarjeta-servicio--cta-1120-3) .vs-tarjeta-servicio__texto p { margin-bottom: 0; }
  :is(.vs-tarjeta-servicio--cta-1120-2, .vs-tarjeta-servicio--cta-1120-3) .vs-tarjeta-servicio__enlace { align-self: center; margin-top: 0; flex: none; }
}

/* VSCR-104 · OBS-VIS-01 y 03: enlace editorial dorado sobre las tarjetas navy
   de Home («Ver proyecto →» y «Conversemos sobre su proyecto →»). El color no
   cambia nunca: declara su propio :hover y :focus-visible y deja de heredar la
   regla global de hover (azul profundo, 1,08:1 sobre #0F1766), que no se toca.
   El anillo de foco dorado lo pone PRR-056 en las superficies oscuras. */
.vs-enlace-dorado {
  display: inline-flex;
  align-items: center;
  align-self: flex-start;
  gap: 6px;
  font-family: var(--fuente-titulos);
  font-weight: 600;
  font-size: 14px;
  line-height: 18px;
  color: var(--dorado);
  padding-bottom: 3px;
  border-bottom: 2px solid transparent;
  transition: border-color var(--dur-hover) var(--curva);
}
.vs-enlace-dorado:hover,
.vs-enlace-dorado:focus-visible { color: var(--dorado); border-bottom-color: var(--dorado); }
.vs-enlace-dorado__flecha { display: inline-block; transition: transform var(--dur-hover) var(--curva); }
.vs-enlace-dorado:hover .vs-enlace-dorado__flecha,
.vs-enlace-dorado:focus-visible .vs-enlace-dorado__flecha { transform: translateX(4px); }
@media (prefers-reduced-motion: reduce) {
  .vs-enlace-dorado__flecha { transition: none; }
  .vs-enlace-dorado:hover .vs-enlace-dorado__flecha,
  .vs-enlace-dorado:focus-visible .vs-enlace-dorado__flecha { transform: none; }
}

/* ---------------------------------------------------------------
   8. Índice de sectores (tablist desktop / accordion móvil)
   --------------------------------------------------------------- */
/* Un solo índice por banda (PRR-027): el tablist de escritorio desde 1120 y
   el acordeón por debajo. Antes, bajo 1120 se ocultaba sólo la lista de
   pestañas y el panel del sector 1 seguía visible encima del acordeón, así
   que el sector 1 salía dos veces. */
.vs-indice-sectores { display: none; border-top: var(--borde-estructura); }
@media (min-width: 1120px) {
  .vs-indice-sectores { display: grid; grid-template-columns: minmax(300px, 380px) minmax(0, 1fr); }
  .vs-indice-sectores__lista { display: block; border-right: var(--borde-estructura); }
}
.vs-indice-sectores__tab {
  width: 100%;
  display: flex;
  align-items: center;
  gap: var(--sp-5);
  text-align: left;
  background: transparent;
  border: 0;
  border-bottom: var(--borde-estructura);
  border-left: 3px solid transparent;
  padding: 0 var(--sp-7);
  min-height: 56px;
  color: #3A4152;
}
.vs-indice-sectores__tab[aria-selected="true"] {
  background: var(--fondo-suave);
  border-left-color: var(--azul-senal);
  color: var(--azul-profundo);
}
.vs-indice-sectores__tab .vs-mono { color: var(--tinta-30); text-transform: none; letter-spacing: 0; font-size: 11px; }
.vs-indice-sectores__tab-nombre { font-family: var(--fuente-titulos); font-weight: 600; font-size: 16px; }
@media (min-width: 1120px) { .vs-indice-sectores__tab-nombre { font-size: 17px; } }
.vs-indice-sectores__tab-flecha { margin-left: auto; color: var(--azul-senal); }

.vs-indice-sectores__panel {
  padding: var(--sp-8) 0;
  display: grid;
  gap: var(--sp-8);
  border-bottom: var(--borde-estructura);
}
.vs-indice-sectores__panel[hidden] { display: none; }
@media (min-width: 1120px) {
  .vs-indice-sectores__panel { grid-template-columns: minmax(0, 1fr) 320px; padding: 38px 0 38px 46px; align-items: start; }
}
.vs-indice-sectores__panel h3 { font-size: 22px; margin-bottom: var(--sp-6); }
@media (min-width: 1120px) { .vs-indice-sectores__panel h3 { font-size: 28px; } }
.vs-indice-sectores__panel > div > p { color: var(--tinta-60); margin-bottom: var(--sp-8); max-width: 52ch; }
.vs-indice-sectores__usos { display: flex; flex-direction: column; gap: var(--sp-3); margin: var(--sp-4) 0 var(--sp-8); }
.vs-indice-sectores__usos li { display: flex; gap: var(--sp-4); align-items: flex-start; font-size: 15px; color: var(--tinta); }
.vs-indice-sectores__usos li::before { content: ""; width: 7px; height: 7px; background: var(--dorado); margin-top: 8px; flex: none; }
.vs-indice-sectores__imagen { position: relative; height: 260px; background: var(--fondo-suave); }
/* Fotografías de sector (VSCR-92): el master 4:3 cubre el hueco sin
   deformarse; el recorte es centrado. */
.vs-indice-sectores__imagen picture,
.vs-acordeon-sectores__imagen picture { display: block; height: 100%; }
.vs-indice-sectores__imagen img,
.vs-acordeon-sectores__imagen img { display: block; width: 100%; height: 100%; object-fit: cover; }

/* Acordeón móvil */
.vs-acordeon-sectores { border-top: var(--borde-estructura); }
@media (min-width: 1120px) { .vs-acordeon-sectores { display: none; } }
.vs-acordeon-sectores__item { border-bottom: var(--borde-estructura); }
.vs-acordeon-sectores__disparador {
  width: 100%;
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  background: transparent;
  border: 0;
  padding: 0 var(--sp-1);
  min-height: 56px;
  color: #3A4152;
  text-align: left;
}
.vs-acordeon-sectores__disparador[aria-expanded="true"] { color: var(--azul-profundo); }
.vs-acordeon-sectores__signo { margin-left: auto; color: var(--azul-senal); font-size: 16px; }
/* Por defecto abierto (degradación sin JS: se ve como una lista de
   secciones); JS colapsa todos menos el primero al iniciar. */
.vs-acordeon-sectores__panel { overflow: hidden; transition: grid-template-rows var(--dur-acordeon) var(--curva); display: grid; grid-template-rows: 1fr; }
.vs-acordeon-sectores__panel > div { overflow: hidden; }
.vs-acordeon-sectores__panel[data-abierto="false"] { grid-template-rows: 0fr; }
.vs-acordeon-sectores__contenido {
  padding: 0 var(--sp-1) var(--sp-7);
  transition: padding-bottom var(--dur-acordeon) var(--curva), visibility 0s linear 0s;
}
/* Cerrado de verdad (PRR-027, «sin texto recortado»): la fila a 0fr no
   colapsaba el padding inferior, y por esos 20 px asomaba la primera línea
   del contexto de cada sector cerrado. `visibility` lo saca además del
   orden de tabulación y del árbol de accesibilidad mientras está cerrado;
   al cerrar espera a que termine la transición. */
.vs-acordeon-sectores__panel[data-abierto="false"] .vs-acordeon-sectores__contenido {
  padding-bottom: 0;
  visibility: hidden;
  transition: padding-bottom var(--dur-acordeon) var(--curva), visibility 0s linear var(--dur-acordeon);
}
.vs-acordeon-sectores__contenido p { color: var(--tinta-60); margin-bottom: var(--sp-6); }
.vs-acordeon-sectores__imagen { position: relative; height: 170px; margin-bottom: var(--sp-6); background: var(--fondo-suave); }

/* ---------------------------------------------------------------
   9. Proyectos + card de proyecto (3 densidades)
   --------------------------------------------------------------- */
/* `minmax(0, …)` y no `1fr` a secas: el mínimo implícito de `1fr` es el
   `min-content` del contenido, así que con títulos y ubicaciones reales el
   track crecía por encima del contenedor y la portada se salía de la pantalla
   en móvil. Con el contenido inventado de VSCR-02C no se notaba. */
.vs-proyectos-destacados { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--sp-8); }
@media (min-width: 1120px) { .vs-proyectos-destacados { grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr); } }
.vs-proyectos-destacados__secundarios { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--sp-8); }
@media (min-width: 640px) { .vs-proyectos-destacados__secundarios { grid-template-rows: 1fr 1fr; } }

.vs-tarjeta-proyecto { background: #0F1766; border: 1px solid var(--borde-oscuro); }
.vs-tarjeta-proyecto--claro { background: var(--blanco); border-color: var(--borde); }
.vs-tarjeta-proyecto__medio { position: relative; height: 180px; }
.vs-tarjeta-proyecto--grande .vs-tarjeta-proyecto__medio { height: 220px; }
@media (min-width: 1120px) { .vs-tarjeta-proyecto--grande .vs-tarjeta-proyecto__medio { height: 340px; } }
.vs-tarjeta-proyecto--horizontal { display: grid; grid-template-columns: 140px minmax(0, 1fr); }
@media (min-width: 480px) { .vs-tarjeta-proyecto--horizontal { grid-template-columns: 180px minmax(0, 1fr); } }
.vs-tarjeta-proyecto--horizontal .vs-tarjeta-proyecto__medio { height: auto; }
/* Portada real de Proyecto (VSCR-06D). Los tres assets se prepararon en
   1600x900, así que el medio se reserva en 16:9 y la imagen lo cubre sin
   deformarse. `aspect-ratio` sustituye a la altura fija del placeholder:
   el hueco queda reservado antes de que la imagen cargue, sin salto de
   layout, y la proporción se conserva en cualquier ancho. */
/* Selector con dos clases a propósito: las alturas fijas del placeholder
   viven en `.vs-tarjeta-proyecto--grande .vs-tarjeta-proyecto__medio`, que
   tiene mayor especificidad. Con una altura definida y `aspect-ratio`, el
   ancho se calculaba a partir de ella (220 × 16/9 = 391px) y la portada se
   salía del contenedor en móvil. Aquí manda la relación, no la altura. */
.vs-tarjeta-proyecto .vs-tarjeta-proyecto__medio--imagen { height: auto; aspect-ratio: 16 / 9; overflow: hidden; background: var(--tinta-05, #0F1766); }
/* La variante horizontal también respeta 16:9. Dejarla estirarse a la
   altura de la tarjeta convertía una portada apaisada en un recorte
   vertical de ~0.58, que es justo lo que estos assets no deben sufrir. */
.vs-tarjeta-proyecto.vs-tarjeta-proyecto--horizontal .vs-tarjeta-proyecto__medio--imagen { aspect-ratio: 16 / 9; height: auto; align-self: start; }
.vs-tarjeta-proyecto__medio img { display: block; width: 100%; height: 100%; object-fit: cover; }

/* Lote A (reauditoría forense VSCR-85, 2026-09-02, PF-01/PF-02): marco
   propio del Índice de Proyectos — misma fórmula que `.vs-indice-servicios-marco`
   (1160 + `--sp-6`×2, ~140px de margen real a 1440), scoped a esta única
   superficie. No se reutiliza la clase de Índice Servicios ni se extrae una
   utilidad compartida: ambos índices llegaron a la misma fórmula de forma
   independiente (como ya hacían antes `.vs-fam__marco`/`.vs-s1__marco`/
   `.vs-indice-sol`) y no existe una abstracción de familia ya extraída que
   tocar sin acoplar innecesariamente superficies ya cerradas. Encabezado
   flush-left (sin `margin-inline:auto`) porque antecede a la rejilla y debe
   compartir su borde izquierdo, mismo criterio que el resto de la familia. */
/* VSCR-88 · PO-IDX-01 (2026-09-09): margen lateral responsive 140/32/20.
   La fórmula anterior congelaba el inset en `--sp-6` (16px) por debajo del
   `max-width`, que es el margen reservado a viewports <360px, no el del
   contrato: `Familia Indices.dc.html` F.3 fija 140 · 32 · 20 y remite a
   `Familia Servicios.dc.html` A.2/A.6, que lo declara para todo el sistema.
   Se expresa como custom property —mismo patrón que `.vs-indice-sol`, ya en
   producción y conforme— para que el margen escale con la banda existente de
   768px sin inventar breakpoint. A 1440 el resultado no cambia: 1160/140. */
.vs-indice-proyectos-marco { --idx-proy-margen: var(--sp-7); max-width: calc(1160px + var(--idx-proy-margen) * 2); margin-inline: auto; padding-inline: var(--idx-proy-margen); box-sizing: border-box; }
@media (min-width: 768px) { .vs-indice-proyectos-marco { --idx-proy-margen: var(--sp-10); } }
/* VSCR-88 · PO-IDX-01 (2026-09-09): F.3 fija el encabezado en 820/640/335 y
   el `max-width` fijo sólo resolvía el corte de escritorio — en tablet se
   estiraba al ancho entero del marco. Se estrecha a 640 en la misma banda
   768–1119 que ya usan los marcos editoriales de los arquetipos (`515703c`,
   VSCR-84). A 375 lo clampa el marco, que ya rinde 335. */
.vs-indice-proyectos-editorial { max-width: 820px; }
@media (min-width: 768px) and (max-width: 1119px) { .vs-indice-proyectos-editorial { max-width: 640px; } }

/* Rejilla del índice de Proyectos. Comparte el modificador de conteo=1 de
   `vs-rejilla-servicios` (`rejillaModificadorPorConteo()`) para centrar una
   sola tarjeta.
   Con dos tarjetas NO se centra ni se angosta (microgate forense VSCR-85,
   2026-09-03): `Indice Proyectos.dc.html`, sección 1440, muestra el grid a
   los 1160px completos del marco con `grid-template-columns:1fr 1fr`,
   llenando ambas columnas por igual — el propio archivo aclara que el
   tratamiento de "no estirar" es sólo para una fila IMPAR («con un número
   impar, la última card ocupa una columna y no se estira»), nunca para dos
   tarjetas completas. La regla anterior (`minmax(0,460px)`, heredada de
   VSCR-06D, 2026-08-13 — anterior a que existiera esta lámina) angostaba el
   grid a 940px por analogía con el `--2col` de Índice Servicios; una
   auditoría previa (Parte XXXVII) ya había leído la lámina correctamente
   pero la conservó como "VARIANTE JUSTIFICADA" sin evidencia de fuente ni
   decisión del PO que la respaldara — reclasificada aquí como DELTA
   MECÁNICO y corregida.
   El gap de escritorio (≥1120px) es 32px en la lámina («mismo gap» para
   2, 4 o 12 tarjetas — no depende del conteo), exactamente `--sp-10`. A
   768/375 la lámina usa 24px/20px — no tocados aquí, fuera del alcance de
   este microgate y ya heredaban el `--sp-7` (20px) de la regla base sin
   que ninguna ronda lo haya señalado como defecto. */
.vs-rejilla-proyectos { display: grid; gap: var(--sp-7); grid-template-columns: minmax(0, 1fr); }
/* VSCR-88 · PO-IDX-01 (2026-09-09): en tablet el gap se quedaba en los 20 de
   la regla base; F.3 y `Indice Proyectos.dc.html` fijan 24, que es lo que da
   la card de 340 sobre la retícula de 704. El corte de 1120 ya era correcto. */
@media (min-width: 768px) { .vs-rejilla-proyectos { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-8); } }
@media (min-width: 1120px) { .vs-rejilla-proyectos { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--sp-10); } }
@media (min-width: 1120px) { .vs-rejilla-proyectos.vs-rejilla-servicios--2col { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 768px) {
  .vs-rejilla-proyectos.vs-rejilla-servicios--1col { width: fit-content; max-width: 100%; margin-inline: auto; grid-template-columns: minmax(0, 520px); }
}

.vs-tarjeta-proyecto__etiquetas { position: absolute; left: 12px; top: 12px; display: flex; gap: var(--sp-2); flex-wrap: wrap; z-index: 1; }
.vs-tarjeta-proyecto__etiqueta {
  font-family: var(--fuente-mono);
  font-size: 9px;
  letter-spacing: .12em;
  text-transform: uppercase;
  background: var(--dorado);
  color: var(--tinta);
  padding: 4px 8px;
}
.vs-tarjeta-proyecto__cuerpo { padding: var(--sp-6); }
.vs-tarjeta-proyecto--grande .vs-tarjeta-proyecto__cuerpo { padding: var(--sp-8) var(--sp-8) var(--sp-9); }
.vs-tarjeta-proyecto__meta { font-family: var(--fuente-mono); font-size: 10px; letter-spacing: .12em; text-transform: uppercase; color: var(--sobre-oscuro-3); margin-bottom: var(--sp-2); }

/* Card C · Índice Proyectos (VSCR-85 / V3.2-B) — evidencia 4:3, pestaña de
   procedencia ámbar, ubicación y tags de Servicio. Sólo aplica dentro del
   índice: el resto de superficies que reutilizan la card de Proyecto (Home,
   fichas) conservan su 16:9 y su línea `meta` combinada. */
.vs-rejilla-proyectos .vs-tarjeta-proyecto .vs-tarjeta-proyecto__medio--imagen { aspect-ratio: 4 / 3; }
/* VSCR-86 · H-04 (2026-09-12): `--tinta-60` es tinta de contexto claro y
   estaba en la regla base, que es la del contexto OSCURO — de ahí un ratio
   medido de 1,98:1 sobre `rgb(15,23,102)` en la portada. El resto del bloque
   ya resolvía esto (h2/h3 `--blanco`, p `--sobre-oscuro`, meta
   `--sobre-oscuro-3`): estas dos declaraciones eran la excepción. La base
   pasa a valores de fondo oscuro y `--claro` restituye los de fondo claro,
   de modo que el Índice de Proyectos (VSCR-85, cerrado) no cambia un píxel. */
.vs-tarjeta-proyecto__ubicacion { font-family: var(--fuente-mono); font-size: 12px; color: var(--sobre-oscuro-3); margin-top: var(--sp-2); }
.vs-tarjeta-proyecto--claro .vs-tarjeta-proyecto__ubicacion { color: var(--tinta-60); }
.vs-tarjeta-proyecto__tags { display: flex; flex-wrap: wrap; gap: var(--sp-2); list-style: none; margin: var(--sp-4) 0 0; padding: 0; }
.vs-tarjeta-proyecto__tag {
  font-family: var(--fuente-mono); font-size: 11px; letter-spacing: .04em;
  color: var(--sobre-oscuro); border: 1px solid var(--borde-oscuro);
  padding: var(--sp-1) var(--sp-3);
}
.vs-tarjeta-proyecto--claro .vs-tarjeta-proyecto__tag { color: var(--tinta-60); border-color: var(--borde); }
.vs-tarjeta-proyecto--claro .vs-tarjeta-proyecto__meta { color: var(--tinta-45); }
.vs-tarjeta-proyecto__cuerpo h2,
.vs-tarjeta-proyecto__cuerpo h3 { font-size: 17px; color: var(--blanco); margin-bottom: var(--sp-2); }
.vs-tarjeta-proyecto--grande .vs-tarjeta-proyecto__cuerpo h2,
.vs-tarjeta-proyecto--grande .vs-tarjeta-proyecto__cuerpo h3 { font-size: 22px; }
@media (min-width: 1120px) {
  .vs-tarjeta-proyecto--grande .vs-tarjeta-proyecto__cuerpo h2,
  .vs-tarjeta-proyecto--grande .vs-tarjeta-proyecto__cuerpo h3 { font-size: 26px; }
}
.vs-tarjeta-proyecto--claro .vs-tarjeta-proyecto__cuerpo h2,
.vs-tarjeta-proyecto--claro .vs-tarjeta-proyecto__cuerpo h3 { color: var(--tinta); }
.vs-tarjeta-proyecto__cuerpo p { color: var(--sobre-oscuro); margin-bottom: var(--sp-5); }
.vs-tarjeta-proyecto__enlace { font-family: var(--fuente-titulos); font-weight: 600; font-size: 14px; color: var(--dorado); }
.vs-tarjeta-proyecto--claro .vs-tarjeta-proyecto__enlace { color: var(--azul-senal); }
/* Lote B (reauditoría forense VSCR-85, 2026-09-02, PF-14): filete ámbar de
   Card C sobre fondo claro (`Familia Indices.dc.html` F.2) — scoped a la
   rejilla del índice para no alcanzar ninguna otra card clara futura que no
   lo pida, mismo patrón ya usado en `.vs-indice-servicios__card`. */
.vs-rejilla-proyectos .vs-tarjeta-proyecto--claro .vs-tarjeta-proyecto__enlace { border-bottom: 2px solid var(--dorado); padding-bottom: 3px; }

/* ---------------------------------------------------------------
   10. Componente Matterport (click-to-load)
   --------------------------------------------------------------- */
/* VSCR-07G: relación de aspecto en vez de altura fija. Antes convivían
   `min-height: 320px` y `height: 240px`, y la primera anulaba a la segunda —
   la altura declarada nunca se aplicaba. A 375 px un 16/9 daría ~187 px, muy
   poco para recorrer un espacio, así que móvil va en 4/3. */
.vs-matterport {
  position: relative;
  margin: 0;
  /* Sólo relación de aspecto: **sin `min-height`**. Un mínimo de altura junto
     a `aspect-ratio` se *transfiere* por la razón y se convierte en un ancho
     mínimo (280 × 4/3 ≈ 373 px), que a 375 px desbordaba el contenedor —
     medido: el documento llegaba a 393 px, y `min-width: 0` no lo corrige
     porque el mínimo transferido no depende de `min-width`. La proporción ya
     garantiza una altura razonable a cualquier ancho. */
  aspect-ratio: 4 / 3;
  min-width: 0;
  border: var(--borde-campo-normal);
  border-top: 4px solid var(--dorado);
  overflow: hidden;
}
@media (min-width: 768px) { .vs-matterport { aspect-ratio: 16 / 9; } }
/* Corrección de fidelidad (VSCR-84, 2026-08-25): este selector traía un
   `border: 1px dashed` de una revisión anterior al disclosure corto de
   VSCR-82, nunca parte de ningún contrato de procedencia aprobado — el
   único acento del sistema es el filete superior. Se retira; el
   demostrativo vuelve a heredar el borde neutro de `.vs-matterport` en
   los otros tres lados, igual que el propio. */
.vs-matterport--demo { border-top: 4px solid var(--azul-senal); }
/* El botón inicial de un demostrativo («Ver demostración») se lee sobre
   la fotografía de portada, no sobre un fondo controlado: `--boton-secundario`
   con fondo transparente podía desaparecer contra portadas oscuras (hallazgo
   de fidelidad VSCR-84, 2026-08-25). Superficie clara opaca, sólo aquí —
   el resto de los usos de `.vs-boton--secundario` en el sitio ya vive
   sobre fondos propios y no cambia. */
.vs-matterport__estado-inicial .vs-boton--secundario { background: rgba(255, 255, 255, .94); }
.vs-matterport__estado-inicial .vs-boton--secundario:hover { background: var(--blanco); }
/* Filete superior a 2px/3px: contrato propio de los arquetipos A/B/C
   (Claude Design), más fino que el 4px histórico que Retail/S1/Biblioteca
   ya tenían aprobado y conservan sin cambios — sólo estas tres páginas
   adoptan el valor nuevo (corrección de fidelidad VSCR-84, 2026-08-25). */
.vs-arq-a .vs-matterport,
.vs-arq-b .vs-matterport,
.vs-arq-c .vs-matterport { border-top-width: 2px; }
@media (min-width: 1120px) {
  .vs-arq-a .vs-matterport,
  .vs-arq-b .vs-matterport,
  .vs-arq-c .vs-matterport { border-top-width: 3px; }
}
/* VSCR-07K: por debajo de 768px, una tarjeta demostrativa necesitaba más
   alto que una propia para no superponer su badge con el título/botón
   centrados, medido en Chrome real a 375px — hasta VSCR-82 el bloque
   persistente llevaba además un párrafo de disclosure que agravaba el
   problema; ese párrafo se retiró, pero la proporción 1/1 se conserva sin
   cambios porque revisarla no es parte de esa unidad. Sólo el demo gana
   una proporción más alta; el propio conserva 4/3. Sigue sin
   `min-height` — es aspect-ratio puro, no repite el bug de VSCR-07G. */
@media (max-width: 767px) { .vs-matterport--demo { aspect-ratio: 1 / 1; } }
.vs-matterport__inicial { position: absolute; inset: 0; }
.vs-matterport__imagen { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.vs-matterport__placeholder { position: absolute; inset: 0; }
/* Velo sobre la portada: el botón y las etiquetas tienen que leerse encima de
   cualquier fotografía, clara u oscura. */
.vs-matterport__inicial::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(10, 14, 30, .18) 0%, rgba(10, 14, 30, .62) 100%);
}
.vs-matterport__titulo {
  font-family: var(--fuente-titulos);
  font-weight: 600;
  font-size: 18px;
  color: var(--blanco);
  margin: 0;
  max-width: 28ch;
  text-shadow: 0 1px 3px rgba(10, 14, 30, .5);
}
/* Grupo título+subtítulo: un único hijo del flex de `.vs-matterport__estado-inicial`,
   con su propio espaciado interno más corto que el que separa el bloque del
   botón. */
.vs-matterport__estado-inicial > div { display: flex; flex-direction: column; gap: var(--sp-2); }
/* Línea corta opcional bajo el título, sobre la propia portada — p. ej. la
   evidencia propia del arquetipo A (corrección de fidelidad VSCR-84,
   2026-08-25: antes se imprimía como texto corriente debajo de toda la
   figura, nunca dentro de ella como fija el diseño aprobado). */
.vs-matterport__subtitulo {
  font-size: 15px;
  color: var(--sobre-oscuro);
  margin: 0;
  max-width: 32ch;
  text-shadow: 0 1px 3px rgba(10, 14, 30, .5);
}
/* CUA-01 (VSCR-79): esta era la única superficie del componente capaz de
   producir una navegación externa al pulsar. Con scripting activo el
   contenido de `<noscript>` no se parsea como DOM — sigue inerte y esta
   regla no aplica a nadie. El riesgo real es el visitante genuino sin
   JS: `.vs-matterport__estado-inicial` sigue presente en el marcado (su
   botón, sin listener, no hace nada) en la MISMA franja inferior donde
   antes vivía este fallback con z-index más alto — el enlace que sí
   funciona quedaba compitiendo por el mismo punto que el botón decorativo
   e inerte. Se reubica a una esquina propia (arriba-derecha, la única
   libre: no compite con la insignia arriba-izquierda ni con el bloque
   inferior) para que nunca vuelva a compartir zona de clic con el botón
   real, sin depender de z-index para resolverlo. Desde VSCR-103 el
   recorrido abre en el visor común, nunca dentro de la tarjeta. */
.vs-matterport__noscript { position: absolute; top: 0; right: 0; z-index: 1; padding: var(--sp-4); }
/* Aloja el badge de procedencia (D-MODEL-06) en un bloque posicionado que
   sigue visible con el visor abierto. Hasta VSCR-82 agrupaba también el
   párrafo de disclosure largo — retirado; el nombre de la clase se conserva
   porque sigue siendo el contenedor persistente del badge, no del bloque
   inicial que el JS oculta. */
.vs-matterport__persistente {
  position: absolute;
  left: 0;
  top: 0;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--sp-3);
  max-width: calc(100% - 28px);
}
.vs-matterport__etiquetas { display: flex; flex-wrap: wrap; }
.vs-matterport__etiqueta {
  font-family: var(--fuente-mono);
  font-size: 11px;
  letter-spacing: .12em;
  text-transform: uppercase;
  padding: 7px 11px;
}
.vs-matterport__etiqueta--dorada { background: var(--dorado); color: var(--tinta); }
.vs-matterport__etiqueta--azul { background: var(--azul-senal); color: var(--blanco); }
/* Anclado abajo, no centrado (VSCR-07K): centrado verticalmente, el título
   y el botón podían quedar detrás del bloque persistente (badge, y hasta
   VSCR-82 también el párrafo de disclosure) de una tarjeta demostrativa en
   tarjetas angostas —medido en Chrome real a 375px y en la rejilla de dos
   columnas de la Biblioteca—. Abajo nunca compite con
   `.vs-matterport__persistente`, que vive arriba; se conserva sin cambios
   aunque el disclosure ya no crezca en altura. */
.vs-matterport__estado-inicial {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  gap: var(--sp-6);
  text-align: center;
  padding: var(--sp-6);
  z-index: 1;
}
/* Microgate de CUA (VSCR-84, corrección de fidelidad): los tres
   `.dc.html` de A/B/C componen la portada como un bloque inferior
   anclado a la izquierda, nunca como una tarjeta hero centrada.
   Scoped a los tres arquetipos: Retail/S1/Proyecto/Biblioteca
   conservan la composición centrada (VSCR-07K la afinó para tarjetas
   angostas, y ninguno de ellos pasó por esta ronda de diseño).

   La primera pasada de este microgate se limitó a >=1120px porque la
   CUA de 768/375 seguía pendiente. Con la CUA móvil del Product
   Owner ya hecha, las tres láminas confirman el mismo bloque inferior
   en los tres anchos, con una sola diferencia de disposición:

     · 1440 y 768 — fila: identidad a la izquierda, CTA a la derecha
       (`align-items:flex-end; justify-content:space-between`,
       `padding:18px 20px` en la portada grande de cada lámina 768);
     · 375 — columna anclada abajo a la izquierda, CTA bajo la
       identidad (`padding:14px`), nunca centrada.

   Medido en Chrome real a 375 y 768 px (`innerWidth` verificado). */
.vs-arq-a .vs-matterport__estado-inicial,
.vs-arq-b .vs-matterport__estado-inicial,
.vs-arq-c .vs-matterport__estado-inicial {
  align-items: flex-start;
  text-align: left;
}
@media (max-width: 767px) {
  .vs-arq-a .vs-matterport__estado-inicial,
  .vs-arq-b .vs-matterport__estado-inicial,
  .vs-arq-c .vs-matterport__estado-inicial {
    gap: var(--sp-3);
    padding: var(--sp-5);
    /* Velo inferior propio, el mismo `rgba(7,11,54,.88)` que las tres
       láminas 375 ponen bajo la identidad. El velo del componente
       compartido (`.vs-matterport__inicial::after`, .18 -> .62) se
       reparte por toda la portada y, con el bloque anclado abajo, deja
       la línea corta bajo el título sobre la zona clara de la foto.
       Aditivo y scoped: los demás llamantes conservan sólo el suyo. */
    background: linear-gradient(to top, rgba(7, 11, 54, .88) 0%, rgba(7, 11, 54, .55) 46%, rgba(7, 11, 54, 0) 100%);
  }
}
@media (min-width: 768px) {
  .vs-arq-a .vs-matterport__estado-inicial,
  .vs-arq-b .vs-matterport__estado-inicial,
  .vs-arq-c .vs-matterport__estado-inicial {
    flex-direction: row;
    align-items: flex-end;
    justify-content: space-between;
  }
}
/* El espaciado interno de >=1120px es el que el Product Owner ya aprobó
   en el microgate de escritorio y no se toca en esta ronda; sólo la
   franja de tablet recibe el suyo, contrastado contra las láminas 768. */
@media (min-width: 768px) and (max-width: 1119px) {
  .vs-arq-a .vs-matterport__estado-inicial,
  .vs-arq-b .vs-matterport__estado-inicial,
  .vs-arq-c .vs-matterport__estado-inicial {
    gap: var(--sp-5);
    padding: var(--sp-6) var(--sp-7);
  }
}
/* Botón «Ver recorrido» de una evidencia PROPIA, sólo dentro de A/B/C: los
   tres `.dc.html` documentan el botón ámbar de marca para este caso
   —el único CTA ámbar de un visor en todo el sistema, nunca sobre un
   MODELO DEMOSTRATIVO—, distinto del `.vs-boton--primario` (azul
   profundo) que el componente usa en el resto de sus llamantes (Home,
   Proyecto, Biblioteca, Servicio S1), donde no cambia. */
.vs-arq-a .vs-matterport__estado-inicial .vs-boton--primario,
.vs-arq-b .vs-matterport__estado-inicial .vs-boton--primario,
.vs-arq-c .vs-matterport__estado-inicial .vs-boton--primario {
  background: var(--dorado);
  color: var(--tinta);
}
.vs-arq-a .vs-matterport__estado-inicial .vs-boton--primario:hover,
.vs-arq-b .vs-matterport__estado-inicial .vs-boton--primario:hover,
.vs-arq-c .vs-matterport__estado-inicial .vs-boton--primario:hover {
  background: #FFD24A;
  color: var(--tinta);
}
/* VSCR-103: el componente ya no abre un visor dentro de la tarjeta. Al
   pulsar se abre el visor común (`.vs-visor`, más abajo), así que las reglas
   del visor en tarjeta, su cierre y su aviso de carga se retiraron. */

/* Marco propio de Biblioteca (auditoría resolutiva VSCR-85, 2026-09-04):
   `Indice Modelos 3D.dc.html` + `Familia Indices.dc.html` F.1/F.3 exigen un
   marco de 1160px (encabezado a 820, mismo eje que la rejilla) — Biblioteca
   vivía en el `.vs-contenedor` genérico de 1440, mismo defecto ya corregido
   en Índice Servicios e Índice Proyectos. Clase independiente, misma
   fórmula ya probada, sin acoplar a esas superficies ya cerradas. */
/* VSCR-88 · PO-IDX-01 (2026-09-09): margen lateral responsive 140/32/20.
   La fórmula anterior congelaba el inset en `--sp-6` (16px) por debajo del
   `max-width`, que es el margen reservado a viewports <360px, no el del
   contrato: `Familia Indices.dc.html` F.3 fija 140 · 32 · 20 y remite a
   `Familia Servicios.dc.html` A.2/A.6, que lo declara para todo el sistema.
   Se expresa como custom property —mismo patrón que `.vs-indice-sol`, ya en
   producción y conforme— para que el margen escale con la banda existente de
   768px sin inventar breakpoint. A 1440 el resultado no cambia: 1160/140. */
.vs-indice-modelos3d-marco { --idx-bib-margen: var(--sp-7); max-width: calc(1160px + var(--idx-bib-margen) * 2); margin-inline: auto; padding-inline: var(--idx-bib-margen); box-sizing: border-box; }
@media (min-width: 768px) { .vs-indice-modelos3d-marco { --idx-bib-margen: var(--sp-10); } }
/* VSCR-88 · PO-IDX-01 (2026-09-09): F.3 fija el encabezado en 820/640/335 y
   el `max-width` fijo sólo resolvía el corte de escritorio — en tablet se
   estiraba al ancho entero del marco. Se estrecha a 640 en la misma banda
   768–1119 que ya usan los marcos editoriales de los arquetipos (`515703c`,
   VSCR-84). A 375 lo clampa el marco, que ya rinde 335. */
.vs-indice-modelos3d-editorial { max-width: 820px; }
@media (min-width: 768px) and (max-width: 1119px) { .vs-indice-modelos3d-editorial { max-width: 640px; } }

/* Biblioteca pública de Modelos 3D (VSCR-07K) — dos tarjetas de Trabajo
   propio y hasta doce de Modelos demostrativos. Columnas y gap según F.3
   de `Familia Indices.dc.html` («Modelos 3D: 3 columnas · n items»,
   «Soluciones y Modelos 3D pasan de 3 a 2 col en 768»): 1 columna en 375px
   (gap 20, `--sp-7`), 2 desde 768px (gap 24, `--sp-8`), 3 desde 1120px
   (gap 32, `--sp-10`) — antes fijo en 2 columnas con gap 28 en todos los
   cortes, nunca reconciliado contra esta lámina. */
.vs-rejilla-modelos3d { display: grid; grid-template-columns: 1fr; gap: var(--sp-7); }
@media (min-width: 768px) { .vs-rejilla-modelos3d { grid-template-columns: repeat(2, 1fr); gap: var(--sp-8); } }
@media (min-width: 1120px) { .vs-rejilla-modelos3d { grid-template-columns: repeat(3, 1fr); gap: var(--sp-10); } }
.vs-modelos3d-chips { display: flex; align-items: center; gap: var(--sp-4); flex-wrap: wrap; margin-top: var(--sp-4); }

/* ---------------------------------------------------------------
   10.b Tarjeta de modelo de la Biblioteca — Card D · V2.2/V2.4
        (VSCR-85, PO-BIB-05)

   Variante propia de esta página: `_matterport.php` sigue sirviendo el
   visor-en-tarjeta al resto de superficies (Home, Solución, Proyecto, S1,
   S2, Retail), todas con Gate Visual cerrado. Aquí la tarjeta es un
   launcher y el recorrido abre en `.vs-visor`.
   --------------------------------------------------------------- */
.vs-card-modelo3d {
  /* Primera de las tres declaraciones que alinean las acciones entre
     tarjetas vecinas. Sin ella, `margin-top:auto` ancla dentro de la altura
     propia del cuerpo y no de la altura estirada por el grid. */
  display: flex;
  flex-direction: column;
  background: var(--blanco);
  border: 1px solid var(--borde);
  border-top: 2px solid var(--dorado);
}
.vs-card-modelo3d--demo { border-top-color: var(--azul-senal); }
@media (min-width: 1120px) { .vs-card-modelo3d { border-top-width: 3px; } }

.vs-card-modelo3d__media { position: relative; aspect-ratio: 16 / 9; }
.vs-card-modelo3d__imagen,
.vs-card-modelo3d__placeholder { position: absolute; inset: 0; width: 100%; height: 100%; }
.vs-card-modelo3d__imagen { object-fit: cover; display: block; }

.vs-card-modelo3d__etiqueta {
  position: absolute;
  left: 0;
  top: 0;
  z-index: 1;
  padding: 6px 9px;
  font-size: 10px;
  letter-spacing: .12em;
  background: var(--dorado);
  color: var(--tinta);
}
.vs-card-modelo3d--demo .vs-card-modelo3d__etiqueta { background: var(--azul-senal); color: var(--blanco); }
@media (min-width: 1120px) { .vs-card-modelo3d__etiqueta { padding: var(--sp-2) var(--sp-4); font-size: 11px; } }

.vs-card-modelo3d__cuerpo {
  /* Segunda declaración: el cuerpo estira hasta el fondo de la tarjeta. */
  display: flex;
  flex-direction: column;
  flex: 1;
  padding: 18px var(--sp-7) var(--sp-7);
}
@media (min-width: 1120px) { .vs-card-modelo3d__cuerpo { padding: var(--sp-7) var(--sp-8) var(--sp-8); } }

.vs-card-modelo3d__titulo {
  font-family: var(--fuente-titulos);
  font-weight: 700;
  font-size: 18px;
  line-height: 1.3;
  color: var(--tinta);
  margin: 0 0 var(--sp-4);
  /* Reserva de dos líneas: estabiliza el caso de una sola línea para que las
     acciones de una misma fila caigan al mismo nivel. 2 × 18 × 1.3 ≈ 46,8.
     No recorta nada — un título de tres líneas hace crecer la tarjeta. */
  min-height: 47px;
}
@media (min-width: 1120px) {
  .vs-card-modelo3d__titulo { font-size: 19px; margin-bottom: var(--sp-5); min-height: 50px; }
}

.vs-card-modelo3d__accion {
  /* Tercera declaración. Las tres juntas, o las acciones se desalinean en
     cuanto dos títulos de la misma fila tienen distinto número de líneas. */
  margin-top: auto;
  padding: 0 18px;
}
/* Móvil: acción amplia. En una columna no hay tarjeta vecina con la que
   alinear, así que el centrado horizontal no aporta y el target táctil sí. */
@media (max-width: 767px) { .vs-card-modelo3d__accion { width: 100%; min-height: 52px; } }
@media (min-width: 768px) { .vs-card-modelo3d__accion { align-self: center; } }
.vs-card-modelo3d__accion.vs-boton--secundario { background: rgba(255, 255, 255, .94); }
.vs-card-modelo3d__accion.vs-boton--secundario:hover { background: var(--blanco); }

/* ---------------------------------------------------------------
   10.c Control «Mostrar más modelos» — divisor de rejilla V2-A
        (VSCR-85, PO-BIB-04 + PO-BIB-05)

   No es un botón con superficie: es un filete que cierra la rejilla, con
   la etiqueta en azul de señal y un chevron. Cero ámbar — reservado a
   conversión y a procedencia propia. `margin-top` = distancia a la última
   fila; sin `margin-bottom`: el cierre de sección lo aporta `.vs-seccion`,
   de modo que retirar el control no altera el ritmo de cierre.
   --------------------------------------------------------------- */
.vs-modelos3d-mas {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  width: 100%;
  min-height: 56px;
  margin-top: var(--sp-8);
  padding: 0;
  background: transparent;
  border: 0;
  border-top: 1px solid var(--borde);
  border-radius: var(--radio);
  color: var(--azul-senal);
  font-family: var(--fuente-titulos);
  font-weight: 600;
  font-size: var(--boton-mobile);
  cursor: pointer;
  transition: background var(--dur-hover) var(--curva), border-color var(--dur-hover) var(--curva);
}
/* `display:flex` de arriba gana por especificidad a la regla `[hidden]` de la
   hoja del navegador, así que hay que restituirla explícitamente: el control
   se sirve `hidden` y sin JS tiene que quedar invisible, no sólo inerte. */
.vs-modelos3d-mas[hidden] { display: none; }
.vs-modelos3d-mas__chevron { width: 18px; height: 18px; flex: none; transition: transform var(--dur-hover) var(--curva); }
.vs-modelos3d-mas:hover { background: var(--fondo-suave); border-top-color: var(--azul-senal); }
.vs-modelos3d-mas:hover .vs-modelos3d-mas__etiqueta { text-decoration: underline; text-underline-offset: 4px; }
.vs-modelos3d-mas:hover .vs-modelos3d-mas__chevron { transform: translateY(2px); }
/* El sistema usa 3px para el foco; aquí la pieza aprobada pide 2px, porque
   el control es una franja de 56–60px de alto y un anillo de 3px sobre el
   filete de 1px lo engorda visualmente. */
.vs-modelos3d-mas:focus-visible { outline: 2px solid var(--azul-senal); outline-offset: 2px; }
@media (min-width: 768px) {
  .vs-modelos3d-mas { min-height: 58px; margin-top: var(--sp-9); gap: var(--sp-3); }
  .vs-modelos3d-mas__chevron { width: 20px; height: 20px; }
}
@media (min-width: 1120px) { .vs-modelos3d-mas { min-height: 60px; margin-top: var(--sp-10); } }

/* Recorte de la rejilla: sólo lo aplica el JS. Si el JS no corre, la clase
   nunca se añade y las tarjetas 10+ quedan visibles. */
.vs-rejilla-modelos3d--recortada > *:nth-child(n + 10) { display: none; }

/* Cierre del último tramo de la Biblioteca — 56/40/28 (V2.4, secciones H y
   J.1; vinculante por PO-BIB-05). Prevalece sobre el ritmo general de
   `.vs-seccion` (88/56/36), que es una regla histórica más amplia: la fuente
   específica de esta superficie manda aquí, y sólo aquí.

   Es la MISMA distancia con control y sin él: el botón no aporta
   `margin-bottom`, así que al retirarse se van con él su bloque y los
   32/28/24 que lo precedían, nunca este cierre. Sin doble spacing. */
.vs-seccion--cierre-biblioteca { padding-bottom: var(--sp-9); }
@media (min-width: 768px) { .vs-seccion--cierre-biblioteca { padding-bottom: var(--sp-11); } }
@media (min-width: 1120px) { .vs-seccion--cierre-biblioteca { padding-bottom: var(--sp-14); } }
/* ---------------------------------------------------------------
   10.d Visor Matterport ampliado de la Biblioteca — V2.4 secciones N–T
        (VSCR-85, PO-BIB-05)

   Geometría por viewport, nunca por ratio: a 1366×768 una caja 16:9 de
   1160 pediría 653px sólo de vídeo más la cabecera, y se saldría. Por eso
   el alto se define con `100vh − margen` y el modelo recibe lo que queda.
   --------------------------------------------------------------- */
.vs-visor {
  /* Margen lateral de la fórmula horizontal (V2.6.2 · W). Escala con el
     viewport en vez de saltar por breakpoint. */
  --vs-visor-margen: clamp(16px, 4.5vw, 64px);
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
}
/* Misma razón que en el control: sin esta regla el overlay taparía la página
   entera desde la carga, porque `.vs-visor { display:flex }` vence a `[hidden]`. */
.vs-visor[hidden] { display: none; }
/* Backdrop sin tinte (prueba autorizada por el Product Owner tras la CUA).
   Cero color: la página detrás conserva sus colores reales y sólo pierde
   nitidez. El desenfoque es deliberadamente tenue —lo justo para que el
   fondo deje de competir— y la separación la aportan la cabecera navy y la
   sombra del shell, no una capa cromática.

   La capa sigue existiendo aunque sea transparente: es la que impide
   interactuar con la página de debajo. */
.vs-visor__fondo {
  position: absolute;
  inset: 0;
  background: transparent;
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
}
/* Sin soporte de desenfoque no se sustituye por tinte: la página queda
   normal detrás. Se declara explícitamente para que ningún valor cromático
   sobreviva por herencia si alguien cambia la regla de arriba. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .vs-visor__fondo { background: transparent; }
}

.vs-visor__shell {
  position: relative;
  display: flex;
  flex-direction: column;
  /* Fórmula horizontal única y continua (V2.6.2 · W). Sin breakpoint de
     ancho en modo estándar: el margen escala con el viewport en vez de
     cambiar de valor, así que el ancho crece de forma monótona y desaparece
     el salto regresivo de 1023→1024. Los 1240/932/698 de la tabla son
     resultados de esta fórmula, no cifras que haya que escribir. */
  width: min(1240px, calc(100vw - 2 * var(--vs-visor-margen)));
  animation: vs-visor-entrada 160ms var(--curva);
}
@keyframes vs-visor-entrada {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) { .vs-visor__shell { animation: none; } }

/* ---------------------------------------------------------------
   Toolbar flotante externa (V2.6.2 · V.1)

   Las cápsulas van FUERA del rectángulo del iframe. Matterport ocupa tres
   zonas de su propio lienzo —marca arriba izquierda, navegación abajo
   izquierda, acciones abajo derecha— y cualquier cápsula dentro chocaba con
   la primera. Mover la cápsula a otra esquina del iframe no valía: es UI de
   un tercero que puede cambiarla sin avisar.

   La franja no resta área útil al modelo, pero sí cuenta en el footprint
   vertical del modal: 52 + 16 + 700 = 768 a 1440×900.
   --------------------------------------------------------------- */
.vs-visor__toolbar {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--sp-4);
  margin-bottom: var(--sp-6);
}
.vs-visor__capsula {
  display: flex;
  align-items: center;
  margin: 0;
  height: 48px;
  background: rgba(11, 17, 87, .82);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  box-sizing: border-box;
}
.vs-visor__capsula--info { gap: var(--sp-4); min-width: 0; padding: 0 var(--sp-5); }
/* Se contrae al único control que existe hoy. No hay hueco reservado para
   un futuro botón de sonido: no existe campo de audio en el modelo. */
.vs-visor__capsula--acciones { gap: var(--sp-1); flex: none; padding: 0 6px; }
@media (min-width: 1024px) { .vs-visor__capsula { height: 52px; } }

.vs-visor__isotipo { width: 18px; height: 18px; flex: none; display: block; }
@media (min-width: 1024px) { .vs-visor__isotipo { width: 20px; height: 20px; } }
.vs-visor__separador { width: 1px; height: 18px; background: rgba(255, 255, 255, .22); flex: none; }

.vs-visor__procedencia {
  flex: none;
  font-family: var(--fuente-mono);
  font-size: 10px;
  letter-spacing: .1em;
  /* La lámina la dibuja en versales. La cadena de i18n se guarda en caja
     normal y se comparte con la pestaña de la tarjeta, que la sube con
     `vs-mono`; aquí se hace lo mismo en vez de duplicar la clave. */
  text-transform: uppercase;
  color: #8FB6D6;
}
/* V2.6.3 · J/K. El azul de señal es correcto sobre blanco, pero dentro de
   una cápsula translúcida sobre fondo variable daba 3,03:1 en el mejor caso
   y 1,77:1 sobre página clara. `#A8C6DE` es un aclarado del mismo azul del
   sistema: 5,7:1 sobre claro y 8,9:1 sobre oscuro. Sólo cambia el token de
   texto — ni la cápsula ni el tamaño se tocan, no se esquiva el criterio
   agrandando la tipografía. `#146AA8` sigue vigente en el resto del sitio. */
.vs-visor__procedencia--demo { color: #A8C6DE; }

.vs-visor__titulo {
  /* `min-width:0` + ellipsis: un título largo no puede empujar el botón de
     cierre ni el iframe. El truncamiento es SÓLO del shell — los H3 de las
     cards siguen creciendo sin recortar. */
  min-width: 0;
  font-family: var(--fuente-titulos);
  font-weight: 600;
  font-size: 13px;
  color: var(--blanco);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
@media (min-width: 1024px) { .vs-visor__titulo { font-size: 14px; } }

.vs-visor__cerrar {
  /* Target real de 44×44 en el propio botón, no completado con el padding de
     la cápsula: por eso la cápsula mide 52 y no 44 en escritorio. */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  flex: none;
  padding: 0;
  background: none;
  border: 0;
  border-radius: var(--radio);
  color: var(--blanco);
  cursor: pointer;
}
.vs-visor__cerrar:hover { background: rgba(255, 255, 255, .12); }

/* El azul de señal no tiene contraste suficiente sobre la superficie navy
   de las cápsulas: dentro del visor el anillo de foco es ámbar. */
.vs-visor :focus-visible { outline: 2px solid var(--dorado); outline-offset: 2px; }

.vs-visor__area {
  position: relative;
  background: var(--azul-profundo-900);
  box-shadow: 0 24px 80px rgba(3, 6, 26, .5);
  /* Fórmula vertical (V2.6.2 · W). 188 = 120 de contexto inferior + 52 de
     cápsula + 16 de gap en escritorio; entre 640 y 1023 la cápsula baja a 48
     y el contexto sube a 124 con la MISMA constante, así que no hay
     breakpoint que romper aquí. */
  height: min(700px, calc(100vh - 188px));
}
@supports (height: 100dvh) {
  .vs-visor__area { height: min(700px, calc(100dvh - 188px)); }
}
/* El iframe TIENE que ir posicionado y por encima de la portada.
   `.vs-visor__portada` es `position:absolute`, y en el orden de pintado un
   elemento posicionado va por encima de uno estático aunque esté antes en el
   DOM: con el iframe en `static` la portada lo tapaba entero y además se
   quedaba con los clics —`elementFromPoint` devolvía la portada—, así que
   Matterport cargaba (200, 1160×780) pero nunca era visible ni navegable.
   Era el mismo criterio del antiguo visor en tarjeta, también posicionado
   (retirado en VSCR-103). Orden de capas:
   portada → iframe → estados de carga y error. */
.vs-visor__area iframe {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
}

/* Base de los estados: la portada del propio modelo, para que el visitante
   vea el espacio que pidió y no una ventana vacía ni un destello blanco. */
.vs-visor__portada {
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center;
  filter: blur(10px) brightness(.42);
  transform: scale(1.06);
}

.vs-visor__estado {
  position: absolute;
  inset: 0;
  /* Por encima del iframe: la carga y el error tapan al visor, no al revés. */
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--sp-4);
  padding: var(--sp-8);
  text-align: center;
}
.vs-visor__estado[hidden] { display: none; }
.vs-visor__estado-kicker {
  margin: 0;
  font-family: var(--fuente-mono);
  font-size: 11px;
  letter-spacing: .14em;
  color: var(--dorado);
}
.vs-visor__estado-titulo {
  margin: 0;
  font-family: var(--fuente-titulos);
  font-weight: 700;
  font-size: 19px;
  color: var(--blanco);
}
.vs-visor__estado-apoyo { margin: 0; max-width: 46ch; font-size: 15px; line-height: 1.6; color: var(--sobre-oscuro); }
.vs-visor__estado-acciones { display: flex; flex-wrap: wrap; gap: var(--sp-4); justify-content: center; margin-top: var(--sp-4); }
.vs-visor__estado-acciones .vs-boton--secundario { color: var(--blanco); border-color: var(--sobre-oscuro); }
.vs-visor__estado-acciones .vs-boton--secundario:hover { background: var(--borde-oscuro); color: var(--blanco); }

.vs-visor__spinner {
  width: 40px;
  height: 40px;
  border: 3px solid rgba(240, 191, 46, .25);
  border-top-color: var(--dorado);
  border-radius: 50%;
  animation: vs-visor-giro 900ms linear infinite;
}
@keyframes vs-visor-giro { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .vs-visor__spinner { animation-duration: 3s; } }

/* ---------------------------------------------------------------
   Full-screen — dos condiciones (V2.6.2 · W)

   Por ancho, y también en «landscape sin alto»: 812×375 es ancho pero no
   tiene alto, y con la fórmula estándar el iframe mediría 375 − 188 = 187px,
   inservible para un recorrido. Son dos reglas distintas a propósito; una
   sola no cubre ambos casos.

   Aquí sí hay solape con el iframe —no hay aire externo que usar—, así que
   las cápsulas pasan a inset 12 sobre el lienzo.
   --------------------------------------------------------------- */
@media (max-width: 639px), (orientation: landscape) and (max-height: 540px) {
  .vs-visor__fondo { display: none; }
  /* El modal a sangre sí tiene superficie propia: las cápsulas flotan sobre
     el navy del modal, no sobre la página. En modo estándar el shell sigue
     sin fondo, porque ahí flotan sobre el desenfoque del backdrop. */
  .vs-visor__shell { width: 100vw; height: 100vh; background: var(--azul-profundo); }
  /* «Full-screen» describe el MODAL, nunca el iframe. El modal va a sangre y
     reserva arriba una zona de shell; el iframe empieza justo debajo. La
     excepción de V2.6.2 —cápsulas superpuestas «esquivando las zonas
     observadas»— queda supersedida: hacía depender nuestra UI de que una zona
     del lienzo de un tercero siguiera libre, y el CUA la refutó. */
  .vs-visor__toolbar {
    flex: none;
    height: 64px;
    /* Cápsula de 56 centrada en 64 = 4 de holgura por lado, dentro de la
       zona. Sin gap adicional: el iframe empieza al terminar la zona. */
    align-items: center;
    padding: 0 12px;
    margin-bottom: 0;
  }
  /* DELTA B (V2.6.4 · Y·F/H). La shell-zone es `#0B1157` sólido y la cápsula
     era el MISMO navy con alpha: componer un color sobre un fondo idéntico
     devuelve ese color, así que el contraste de superficie era 0 por
     construcción, no «sutil». El `blur(10px)` tampoco separaba — detrás hay
     un plano uniforme y no queda información que desenfocar.
     `#232B6E` es ese mismo navy aclarado un 10 % hacia blanco, y el filete
     superior da el filo de luz que convierte la superficie en objeto.
     En modo estándar el rgba+blur SÍ funciona, porque detrás hay página y
     backdrop desenfocado: por eso no se toca. */
  .vs-visor__capsula {
    height: 56px;
    background: #232B6E;
    border-top: 1px solid rgba(255, 255, 255, .16);
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }
  /* DELTA A (V2.6.4 · Y·C). Regla única para todo el modo full-screen, en sus
     dos condiciones: la procedencia textual es la pieza que cede. A 375 la
     cápsula mide 283 y el contenido previo al título ya consume 321 —238 de
     ellos son «PROYECTO PROPIO · VIRTUAL SPACE CR»—, así que no caben ambos
     completos y hay que elegir. Sin ella quedan 216 para el título, que es lo
     que identifica QUÉ se está explorando; la procedencia sigue en la tarjeta
     de origen, en el encabezado del tramo y, en demostrativos, dentro del
     propio viewer.
     Sin breakpoint intermedio: ni a 639 entra el título propio completo —le
     faltan 8px—, así que cualquier frontera por debajo de 640 dejaría el caso
     largo truncado en medio del rango. */
  .vs-visor__procedencia { display: none; }
  .vs-visor__area { height: calc(100vh - 64px); box-shadow: none; }
}
@supports (height: 100dvh) {
  @media (max-width: 639px), (orientation: landscape) and (max-height: 540px) {
    .vs-visor__shell { height: 100dvh; }
    .vs-visor__area { height: calc(100dvh - 64px); }
  }
}
/* Landscape bajo · variante compact. La zona baja a 52 —el mínimo que aloja
   un target de 44 con 4 de holgura por lado— y cede la procedencia textual,
   que es la única pieza que la prioridad de §9 deja caer: no desaparece del
   sistema, vive en la tarjeta de origen y en la etiqueta de la sección. Lo
   que no cede: cerrar, su target de 44 y el área del iframe.

   Va después del bloque de 1024 para ganarle a un landscape corto en una
   pantalla ancha. */
@media (orientation: landscape) and (max-height: 540px) {
  .vs-visor__toolbar { height: 52px; }
  .vs-visor__capsula { height: 44px; }
  .vs-visor__area { height: calc(100vh - 52px); }
}
@supports (height: 100dvh) {
  @media (orientation: landscape) and (max-height: 540px) {
    .vs-visor__area { height: calc(100dvh - 52px); }
  }
}

/* Bloqueo del scroll de fondo mientras el visor está abierto. */
.vs-scroll-bloqueado { overflow: hidden; }

/* ---------------------------------------------------------------
   11. Metodología
   --------------------------------------------------------------- */
.vs-metodologia { display: grid; grid-template-columns: 1fr; gap: var(--sp-8); }
@media (min-width: 640px) { .vs-metodologia { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1120px) { .vs-metodologia { grid-template-columns: repeat(4, 1fr); } }
.vs-metodologia__paso { padding-top: var(--sp-6); border-top: 3px solid var(--borde); }
.vs-metodologia__paso--primero { border-top-color: var(--azul-profundo); }
.vs-metodologia__paso .vs-mono { color: var(--azul-senal); text-transform: uppercase; margin-bottom: var(--sp-4); display: block; }
.vs-metodologia__paso h3 { font-size: 18px; margin-bottom: var(--sp-2); }
.vs-metodologia__paso p { color: var(--tinta-60); }

/* ---------------------------------------------------------------
   12. Banda CTA
   --------------------------------------------------------------- */
.vs-cta-banda {
  background: var(--dorado);
  padding: var(--sp-10) 0;
  display: flex;
  flex-direction: column;
  gap: var(--sp-8);
}
@media (min-width: 768px) { .vs-cta-banda { flex-direction: row; align-items: center; justify-content: space-between; flex-wrap: wrap; } }
.vs-cta-banda--oscura { background: var(--azul-profundo); }
.vs-cta-banda__texto h2 { color: var(--tinta); font-size: 24px; margin-bottom: var(--sp-3); max-width: 34ch; }
/* La ficha de Proyecto cierra sólo con titular y botón: sin párrafo detrás, el
   margen inferior descentraría el titular dentro de la banda flex. */
.vs-cta-banda__texto h2:last-child { margin-bottom: 0; }
.vs-cta-banda__texto p { color: #3A3320; }
.vs-cta-banda--oscura .vs-cta-banda__texto h2 { color: var(--blanco); }
.vs-cta-banda--oscura .vs-cta-banda__texto p { color: var(--sobre-oscuro); }
@media (min-width: 1120px) { .vs-cta-banda__texto h2 { font-size: 34px; } }
.vs-cta-banda__acciones { display: flex; gap: var(--sp-5); flex-wrap: wrap; }

/* ---------------------------------------------------------------
   13. Formulario
   --------------------------------------------------------------- */
.vs-campo { display: flex; flex-direction: column; gap: var(--sp-2); }
.vs-campo__etiqueta { font-family: var(--fuente-titulos); font-weight: 600; font-size: 14px; color: var(--tinta); }
.vs-campo__control {
  min-height: var(--sp-13);
  padding: 0 var(--sp-5);
  border: var(--borde-campo-normal);
  background: var(--blanco);
  font-family: var(--fuente-texto);
  font-size: 15px;
  color: var(--tinta);
  width: 100%;
}
textarea.vs-campo__control { min-height: 120px; padding-top: var(--sp-5); resize: vertical; }
select.vs-campo__control { appearance: none; background-image: linear-gradient(45deg, transparent 50%, var(--azul-senal) 50%), linear-gradient(135deg, var(--azul-senal) 50%, transparent 50%); background-position: calc(100% - 20px) center, calc(100% - 15px) center; background-size: 6px 6px; background-repeat: no-repeat; }
.vs-campo__control::placeholder { color: var(--tinta-30); }
.vs-campo__control:focus {
  border-color: var(--azul-senal);
  outline: 3px solid rgba(20, 106, 168, .35);
  outline-offset: 2px;
}
.vs-campo__ayuda { font-size: 13px; color: var(--tinta-45); }
.vs-campo__contador { font-size: 12px; color: var(--tinta-45); text-align: right; }
.vs-campo--error .vs-campo__etiqueta { color: var(--tinta); }
.vs-campo--error .vs-campo__control { border-color: var(--error); background: var(--error-fondo); }
.vs-campo--error .vs-campo__ayuda { color: var(--error); }
.vs-campo--exito .vs-campo__control { border-color: var(--exito); background: var(--exito-fondo); }
.vs-campo--exito .vs-campo__ayuda { color: var(--exito); }

.vs-checkbox { display: flex; gap: var(--sp-4); align-items: flex-start; }
.vs-checkbox input { width: 22px; height: 22px; flex: none; margin-top: 2px; accent-color: var(--azul-profundo); }
.vs-checkbox label { font-size: 14px; line-height: 1.55; color: var(--tinta-60); }
.vs-campo--error .vs-checkbox input { outline: 1.5px solid var(--error); }

.vs-resumen-errores {
  border-left: 3px solid var(--error);
  background: var(--error-fondo);
  padding: var(--sp-5) var(--sp-6);
  font-size: 14px;
  color: var(--error);
  margin-bottom: var(--sp-7);
}
.vs-resumen-errores[hidden] { display: none; }
.vs-resumen-errores--exito { border-left-color: var(--exito); background: var(--exito-fondo); color: var(--exito); }

/* Honeypot antispam (VSCR-08C): oculto fuera de pantalla, nunca con
   display:none/visibility:hidden — algunos bots ignoran esas dos
   propiedades al rellenar formularios. Invisible e inalcanzable por
   teclado (tabindex="-1" + aria-hidden en el HTML). */
.vs-campo-senuelo { position: absolute; left: -9999px; top: -9999px; width: 1px; height: 1px; overflow: hidden; }

.vs-formulario__grupo { display: flex; flex-direction: column; gap: var(--sp-7); }
.vs-formulario__fila { display: grid; grid-template-columns: 1fr; gap: var(--sp-6); }
@media (min-width: 480px) { .vs-formulario__fila { grid-template-columns: 1fr 1fr; } }
.vs-formulario__nota { font-size: 13px; color: var(--tinta-45); text-align: center; }

/* ---------------------------------------------------------------
   14. Chips, ficha aside, reto/solución, galería (patrones internos)
   --------------------------------------------------------------- */
.vs-rejilla-3col { display: grid; grid-template-columns: 1fr; gap: var(--sp-7); }
@media (min-width: 768px) { .vs-rejilla-3col { grid-template-columns: repeat(3, 1fr); } }

.vs-chips { display: flex; gap: var(--sp-3); flex-wrap: wrap; }
.vs-chip {
  font-family: var(--fuente-titulos);
  font-weight: 600;
  font-size: 14px;
  border: var(--borde-campo-normal);
  background: var(--blanco);
  color: var(--tinta);
  padding: 0 var(--sp-6);
  min-height: 44px;
  display: flex;
  align-items: center;
}
.vs-chip--sobre-oscuro { background: transparent; border-color: var(--borde-oscuro); color: var(--blanco); font-size: 13px; padding: 0 var(--sp-4); min-height: 36px; }

.vs-ficha { background: var(--fondo-suave); padding: var(--sp-7); }
.vs-ficha__titulo { font-family: var(--fuente-mono); font-size: 11px; letter-spacing: .14em; text-transform: uppercase; color: var(--tinta-45); margin-bottom: var(--sp-5); }
.vs-ficha__filas { display: flex; flex-direction: column; gap: var(--sp-4); font-size: 15px; }
.vs-ficha__fila { display: flex; justify-content: space-between; gap: var(--sp-4); border-bottom: 1px solid #DCE0E7; padding-bottom: var(--sp-3); }
.vs-ficha__fila:last-child { border-bottom: 0; padding-bottom: 0; }
.vs-ficha__fila span:first-child { color: var(--tinta-45); }
.vs-ficha__fila span:last-child { font-weight: 600; }

.vs-reto-solucion { display: grid; grid-template-columns: 1fr; gap: var(--sp-6); border-top: var(--borde-estructura); margin-top: var(--sp-8); padding-top: var(--sp-6); }
@media (min-width: 640px) { .vs-reto-solucion { grid-template-columns: 1fr 1fr; } }
.vs-reto-solucion__bloque .vs-mono { display: block; margin-bottom: var(--sp-3); text-transform: uppercase; }
.vs-reto-solucion__bloque--reto .vs-mono { color: var(--error); }
.vs-reto-solucion__bloque--solucion .vs-mono { color: var(--exito); }
.vs-reto-solucion__bloque p { color: var(--tinta-60); }

.vs-galeria {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  grid-auto-rows: 130px;
  gap: var(--sp-5);
}
@media (min-width: 768px) { .vs-galeria { grid-template-columns: repeat(4, 1fr); grid-auto-rows: 150px; } }
.vs-galeria__item { position: relative; }
.vs-galeria__item--grande { grid-column: span 2; grid-row: span 2; }
.vs-galeria__item--video { grid-column: span 2; }

.vs-narrativa { display: grid; grid-template-columns: 1fr; gap: var(--sp-9); }
@media (min-width: 1120px) { .vs-narrativa { grid-template-columns: minmax(0, 1fr) 360px; } }

.vs-contacto-grid { display: grid; grid-template-columns: 1fr; }
@media (min-width: 1120px) { .vs-contacto-grid { grid-template-columns: 1.15fr 1fr; } }

/*
 * El padding lateral extra (a un solo lado) solo tiene sentido en el
 * layout de 2 columnas de escritorio, donde crea el respiro entre
 * ambas sin duplicar el margen del contenedor. Antes de 1120px las
 * columnas se apilan a ancho completo y ese padding de un solo lado
 * dejaba el contenido (y la tarjeta blanca) visiblemente descentrado
 * — bug reportado por el Product Owner en VSCR-02D.
 */
.vs-contacto-grid__info { padding: var(--sp-9) 0; }
@media (min-width: 1120px) { .vs-contacto-grid__info { padding: var(--sp-9) var(--sp-9) var(--sp-9) 0; } }

/*
 * PO-04 (VSCR-15C §3.18, medido en §7.3): la tarjeta ocupa el ancho útil
 * de la columna gris. Antes tenía `max-width: 560px` y la columna un
 * padding lateral de un solo lado (28/0): a 1440 la tarjeta quedaba
 * descentrada (43/14 px de gris) y a 768 desaprovechaba 72 px por lado.
 * En escritorio la columna gris enmarca la tarjeta con el mismo respiro
 * en los cuatro lados; al apilarse, como ya ocurría en móvil, la tarjeta
 * llega a los márgenes del contenedor.
 */
.vs-contacto-grid__form { background: var(--fondo-suave); padding: var(--sp-9) 0; }
@media (min-width: 1120px) {
  .vs-contacto-grid__form { border-left: var(--borde-estructura); padding: var(--sp-9); }
}

.vs-contacto-grid__card { background: var(--blanco); border: var(--borde-estructura); padding: var(--sp-9); }

/* PRR-029: destino del ancla `#confirmacion`. El margen deja la tarjeta entera
   bajo el header fijo (68 px compacto). Recibe el foco sólo para mover el punto
   de lectura —no es un control—, así que no se le dibuja anillo: el resultado
   lo anuncian el `role="status"` y el título de la página. */
.vs-contacto-confirmacion { scroll-margin-top: calc(68px + var(--sp-7) + var(--sp-9)); }
.vs-contacto-confirmacion:focus { outline: none; }

/* Rejilla Correo/WhatsApp/Cobertura/Idiomas: una columna en mobile
   angosto para que un número de teléfono no se parta en dos líneas (bug
   reportado por el Product Owner en VSCR-02D sobre el teléfono de voz de
   entonces; hoy la rejilla muestra el de WhatsApp, de la misma longitud);
   2 columnas desde 480px, igual que .vs-formulario__fila. */
.vs-contacto-info-grid { display: grid; grid-template-columns: 1fr; gap: var(--sp-8); }
@media (min-width: 480px) { .vs-contacto-info-grid { grid-template-columns: 1fr 1fr; } }

.vs-barra-datos { background: var(--azul-profundo); padding: var(--sp-9) 0; }
.vs-barra-datos__interior { display: grid; grid-template-columns: 1fr; gap: var(--sp-8); align-items: end; }
@media (min-width: 1120px) { .vs-barra-datos__interior { grid-template-columns: minmax(0, 1fr) 380px; } }
.vs-barra-datos h1 { color: var(--blanco); font-size: 30px; margin-bottom: var(--sp-3); }
@media (min-width: 1120px) { .vs-barra-datos h1 { font-size: var(--h1-interna-desktop); } }
.vs-barra-datos p { color: var(--sobre-oscuro); max-width: 52ch; }
.vs-barra-datos__ficha {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--sp-6);
  border-top: 1px solid var(--borde-oscuro);
  padding-top: var(--sp-6);
}
@media (min-width: 1120px) { .vs-barra-datos__ficha { border-top: 0; border-left: 1px solid var(--borde-oscuro); padding-top: 0; padding-left: var(--sp-8); } }
.vs-barra-datos__ficha .vs-mono { color: var(--sobre-oscuro-3); display: block; margin-bottom: var(--sp-2); }
.vs-barra-datos__ficha strong { font-family: var(--fuente-titulos); font-size: 16px; color: var(--blanco); font-weight: 600; }
.vs-barra-datos__servicios { grid-column: 1 / -1; }

.vs-portada { position: relative; height: 220px; }
@media (min-width: 768px) { .vs-portada { height: 420px; } }
.vs-portada--minima { height: 160px; }
@media (min-width: 768px) { .vs-portada--minima { height: 200px; } }

/* ---------------------------------------------------------------
   15. Footer
   --------------------------------------------------------------- */
.vs-pie { background: var(--azul-profundo-900); padding: var(--sp-10) 0 var(--sp-8); color: var(--sobre-oscuro-2); }
.vs-pie__rejilla { display: grid; grid-template-columns: 1fr; gap: var(--sp-8); padding-bottom: var(--sp-9); border-bottom: 1px solid var(--borde-oscuro-2); }
@media (min-width: 768px) { .vs-pie__rejilla { grid-template-columns: 1.4fr 1fr 1fr 1fr; gap: var(--sp-10); } }
.vs-pie__marca { display: flex; align-items: center; margin-bottom: var(--sp-6); }
/* Variante oficial de fondo oscuro; sin `filter: invert()` ni recolores (VSCR-76). */
/* El pie sí tiene ancho de sobra: el lockup va a su mínimo oficial (VSCR-78). */
.vs-pie__logo { width: 290px; max-width: 100%; height: auto; }
.vs-pie__descripcion { max-width: 38ch; margin-bottom: var(--sp-6); font-size: 15px; }
.vs-pie__columna-titulo { font-family: var(--fuente-titulos); font-weight: 600; font-size: 14px; color: var(--blanco); margin-bottom: var(--sp-6); }
.vs-pie__enlaces { display: flex; flex-direction: column; }
.vs-pie__enlaces a { color: var(--sobre-oscuro-2); font-size: 15px; padding: var(--sp-2) 0; }
@media (max-width: 767.98px) {
  .vs-pie__enlaces a { min-height: 48px; display: flex; align-items: center; border-bottom: 1px solid var(--borde-oscuro-2); }
}
.vs-pie__idiomas { display: flex; gap: var(--sp-3); margin-top: var(--sp-2); }
.vs-pie__idiomas a {
  font-family: var(--fuente-mono);
  font-size: 12px;
  min-height: 44px;
  min-width: 44px; /* PRR-104: 40 × 44 → 44 × 44, como las fichas de la cabecera. */
  padding: 0 var(--sp-4);
  display: flex;
  align-items: center;
  justify-content: center;
}
.vs-pie__idiomas a[aria-current="true"] { background: var(--dorado); color: var(--azul-profundo); }
.vs-pie__idiomas a:not([aria-current="true"]) { border: 1px solid var(--borde-oscuro-2); color: var(--sobre-oscuro-2); }
.vs-pie__legal { padding-top: var(--sp-6); display: flex; flex-direction: column; gap: var(--sp-4); font-size: 13px; color: #7A86AE; }
@media (min-width: 768px) { .vs-pie__legal { flex-direction: row; justify-content: space-between; } }
.vs-pie__legal-enlaces { display: flex; gap: var(--sp-6); align-items: center; flex-wrap: wrap; }
.vs-pie__legal a { color: #7A86AE; }
.vs-pie__enlace-boton {
  background: none;
  border: none;
  padding: 0;
  color: #7A86AE;
  font-size: 13px;
  font-family: inherit;
  text-decoration: underline;
  cursor: pointer;
}
.vs-pie__enlace-boton:hover { color: var(--sobre-oscuro-2); }

/* ---------------------------------------------------------------
   15b. Consentimiento de analítica (VSCR-10C)
   --------------------------------------------------------------- */
/*
 * PRR-035/050 (§21): el banner se superponía a todo sin reservar espacio.
 * - Por encima del contenido y del header, pero por debajo de los diálogos
 *   modales (el visor de la Biblioteca, z-index 200): antes compartía el 200
 *   y, por ir después en el DOM, tapaba el tercio inferior del visor.
 * - Mientras está a la vista, la página le reserva su alto (lo mide
 *   `analytics.js` en `--vs-consentimiento-alto`): el final del pie ya no
 *   queda debajo, y `scroll-padding-bottom` hace que el desplazamiento por
 *   foco lo esquive (WCAG 2.4.11).
 * - Con el menú móvil abierto se oculta: el foco está atrapado en el menú y
 *   su CTA quedaba debajo. Vuelve al cerrarlo; la decisión sigue pendiente.
 */
.vs-consentimiento {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 150;
  background: var(--azul-profundo);
  color: var(--sobre-oscuro-2);
  box-shadow: var(--sombra-overlay);
}
html { scroll-padding-bottom: var(--vs-consentimiento-alto, 0px); }
body { padding-bottom: var(--vs-consentimiento-alto, 0px); }
@media (max-width: 1119px) {
  .vs-menu-abierto .vs-consentimiento { visibility: hidden; }
}
.vs-consentimiento__interior {
  display: flex;
  flex-direction: column;
  gap: var(--sp-5);
  padding-top: var(--sp-6);
  padding-bottom: var(--sp-6);
}
@media (min-width: 768px) {
  .vs-consentimiento__interior { flex-direction: row; align-items: center; justify-content: space-between; gap: var(--sp-7); }
}
.vs-consentimiento__texto { font-size: 14px; line-height: 1.5; margin: 0; }
.vs-consentimiento__texto a { color: var(--dorado); }
.vs-consentimiento__acciones { display: flex; gap: var(--sp-4); flex-shrink: 0; flex-wrap: wrap; }
.vs-consentimiento .vs-boton--secundario { background: transparent; color: var(--sobre-oscuro-2); border-color: var(--borde-oscuro-2); }
.vs-consentimiento .vs-boton--secundario:hover { background: rgba(255, 255, 255, .08); color: var(--sobre-oscuro-2); }

/* ---------------------------------------------------------------
   16. Movimiento y accesibilidad
   --------------------------------------------------------------- */
.vs-reveal { opacity: 1; transform: none; }
@media (prefers-reduced-motion: no-preference) {
  .vs-reveal[data-oculto="true"] { opacity: 0; transform: translateY(8px); }
  .vs-reveal { transition: opacity var(--dur-reveal) var(--curva), transform var(--dur-reveal) var(--curva); }
}
@media (prefers-reduced-motion: reduce) {
  * { animation-duration: .001ms !important; transition-duration: .001ms !important; }
}

.vs-visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
}

/* ---------------------------------------------------------------
   17. Página institucional genérica (VSCR-03A)
   --------------------------------------------------------------- */
.vs-pagina { max-width: 900px; }
.vs-pagina h1 { margin-bottom: var(--sp-8); }
.vs-pagina-contenido { max-width: var(--medida-editorial); color: var(--tinta-60); }

/* Bloque de lectura editorial centrado (VSCR-74).
   `.vs-pagina` ya centraba su marco de 900px, pero el cuerpo se quedaba
   anclado a la izquierda con su medida de lectura: en 1920px eso dejaba
   566px de aire a la izquierda y 822px a la derecha, y un escalón de 256px
   entre el H1 (788px) y el texto. El PO lo leyó —con razón— como contenido
   contraído y cargado a la izquierda.
   La medida de lectura no es el problema: 532px son 74 caracteres por línea,
   dentro del objetivo 65-80. Ensancharla a los 720-780px de referencia la
   llevaría a 102-105 caracteres, muy fuera de ese objetivo. Así que lo que
   se corrige es la composición: migas, H1 y cuerpo comparten una sola medida
   y el bloque entero se centra, de modo que el vacío queda repartido.
   Sólo se aplica a las páginas de lectura larga; los índices conservan su
   eje izquierdo compartido con el grid (ver `.vs-intro-indice`).

   La medida se pone en el bloque, no en cada hijo, por una razón concreta:
   `ch` se resuelve contra el tamaño de fuente del propio elemento, así que
   `64ch` sobre el H1 (32px) daría ~1390px y no limitaría nada — migas, H1 y
   cuerpo acabarían centrados pero con anchos distintos y sin compartir eje
   izquierdo. Limitando el bloque —que hereda los 15px del cuerpo— los tres
   comparten exactamente la misma caja. El `calc()` recupera el padding del
   contenedor en cada breakpoint para que la medida útil sea la de lectura y
   no la del marco. */
.vs-pagina--editorial { max-width: calc(var(--medida-editorial) + 2 * var(--contenedor-margen-mobile)); }
@media (min-width: 768px) {
  .vs-pagina--editorial { max-width: calc(var(--medida-editorial) + 2 * var(--contenedor-margen-tablet)); }
}
@media (min-width: 1120px) {
  .vs-pagina--editorial { max-width: calc(var(--medida-editorial) + 2 * var(--contenedor-margen-desktop)); }
}
.vs-pagina-contenido > * + * { margin-top: var(--sp-6); }
.vs-pagina-contenido h2 { color: var(--tinta); margin-top: var(--sp-11); }
.vs-pagina-contenido h3 { color: var(--tinta); margin-top: var(--sp-9); }
.vs-pagina-contenido ul,
.vs-pagina-contenido ol { padding-left: 1.25em; display: flex; flex-direction: column; gap: var(--sp-3); }
.vs-pagina-contenido a { text-decoration: underline; }
.vs-pagina-contenido blockquote {
  margin: 0;
  padding-left: var(--sp-6);
  border-left: 3px solid var(--dorado);
  color: var(--tinta-45);
}

/* ---------------------------------------------------------------
   18. Utilidades de tipografía y espaciado
   (VSCR-12B — externaliza los estilos inline que bloqueaban una CSP
   real sin `style-src-attr: 'unsafe-inline''. Cada regla es el valor
   exacto que ya estaba en línea en las vistas públicas; ninguna
   cambia el diseño aprobado, sólo le da nombre y la saca del HTML.)
   --------------------------------------------------------------- */

/* Espaciado suelto, sin rol tipográfico propio — mismo criterio que
   la ya existente .vs-medida (62ch): un valor de la escala con nombre,
   reutilizable donde haga falta exactamente ese hueco. */
.vs-mb-6 { margin-bottom: var(--sp-6); }
.vs-mb-7 { margin-bottom: var(--sp-7); }
.vs-mb-9 { margin-bottom: var(--sp-9); }
.vs-mt-4 { margin-top: var(--sp-4); }
.vs-mt-6 { margin-top: var(--sp-6); }
.vs-mt-7 { margin-top: var(--sp-7); }
.vs-mt-8 { margin-top: var(--sp-8); }
.vs-rejilla-10 { display: grid; gap: var(--sp-10); }

/* Títulos: el "h2 + margen inferior" que precede a una rejilla o lista
   de tarjetas en Servicio/Solución/Proyecto/Biblioteca comparten un
   único rol pese a vivir en páginas distintas. */
.vs-titulo-seccion { margin-bottom: var(--sp-8); }
.vs-titulo-compacto { margin: var(--sp-4) 0 var(--sp-4); }
/* 22ch dejaba el H1 de un índice en 478px y tres líneas justo encima de un
   grid de 1328px: el encabezado se leía apretado contra el catálogo. A 30ch
   cae en dos líneas y el bloque de cabecera acompaña mejor al grid, sin
   tocar tipografía ni copy (VSCR-74). */
.vs-titulo-indice { margin: var(--sp-4) 0 var(--sp-6); max-width: 30ch; }
.vs-titulo-biblioteca { margin: var(--sp-4) 0 var(--sp-6); max-width: 26ch; }
.vs-titulo-contacto { font-size: 28px; margin-bottom: var(--sp-6); }
.vs-titulo-matterport { margin: var(--sp-4) 0 var(--sp-5); }
.vs-titulo-cta-pregunta { max-width: 34ch; }
.vs-titulo-resultado { font-size: 22px; margin-bottom: 6px; }
.vs-titulo-sobre-oscuro { color: var(--blanco); }

/* Cabecera de sección dentro de una página (rótulo mono + H2 + lead).
   Gobierna dónde parte el H2, no una medida de prosa: por eso conserva su
   ancho propio y no comparte token con las medidas de lectura. Sólo lo usa
   Home, que compone secciones; los índices usan `.vs-intro-indice`. */
.vs-intro-bloque { max-width: 620px; margin-bottom: var(--sp-9); }

/* Intro de índice/listado (VSCR-74).
   Mismo rol en Servicios, Soluciones, Proyectos y Biblioteca, pero cada una
   había heredado un ancho distinto — 620px, 532px, 532px y 640px— porque
   reutilizaban clases pensadas para otra cosa (`.vs-intro-bloque`,
   `.vs-pagina-contenido`, `.vs-medida-70`). Se unifican en una sola medida.
   A diferencia del cuerpo editorial, la intro NO se centra: comparte el eje
   izquierdo con el grid que viene justo debajo, que es lo que mantiene la
   lectura de arriba abajo. Al expresarse en `ch` funciona igual sobre el
   cuerpo (15px) que sobre el lead (16px). */
.vs-intro-indice { max-width: var(--medida-intro); color: var(--tinta-60); }
.vs-intro-indice > * + * { margin-top: var(--sp-4); }
.vs-lead--contacto { margin-bottom: var(--sp-9); max-width: 48ch; }
.vs-lead--disclosure { max-width: 70ch; margin-bottom: var(--sp-8); }

/* Etiquetas pequeñas sobre un valor (sector, aplicaciones…). */
.vs-subetiqueta { color: var(--tinta-45); margin-bottom: var(--sp-4); }
.vs-etiqueta-dorada { color: var(--dorado); }
.vs-chip-etiqueta { font-size: 12px; color: var(--tinta-45); }

/* Ficha de contacto (Contacto — VSCR-08C): correo/WhatsApp/cobertura/idiomas. */
.vs-campo-etiqueta { color: var(--tinta-45); margin-bottom: var(--sp-2); }
.vs-texto-dato { font-size: 16px; }
.vs-enlace-contacto-dato { font-family: var(--fuente-titulos); font-weight: 600; font-size: 16px; }
.vs-nota-formulario { font-size: 14px; color: var(--tinta-45); margin-bottom: var(--sp-8); }
.vs-boton--alto { min-height: 52px; }

/* Lista de pasos numerados (Contacto — "Cómo trabajamos"). */
.vs-pasos-lista { display: flex; flex-direction: column; border-top: var(--borde-estructura); margin-bottom: var(--sp-9); }
.vs-paso-item { display: flex; gap: var(--sp-6); padding: var(--sp-7) 0; border-bottom: var(--borde-estructura); }
.vs-paso-numero { flex: none; width: 28px; color: var(--azul-senal); }
.vs-paso-titulo { font-family: var(--fuente-titulos); font-weight: 600; font-size: 17px; margin-bottom: 4px; }
.vs-paso-descripcion { color: var(--tinta-60); font-size: 15px; }

/* Lista de capacidades del visor Matterport propio (Home). VSCR-104 ·
   OBS-VIS-02: las tres líneas pasan a leerse como lista, con un marcador
   dorado de 7 × 7 en una columna de 18 px. El marcador es decorativo: un
   pseudoelemento sin contenido no se anuncia. */
.vs-lista-beneficios {
  display: flex;
  flex-direction: column;
  gap: 12px;
  border-top: var(--borde-estructura);
  padding-top: 18px;
  color: var(--tinta);
  font-size: 15px;
  line-height: 1.5;
}
@media (min-width: 768px) { .vs-lista-beneficios { padding-top: 20px; } }
.vs-lista-beneficios li { display: grid; grid-template-columns: 18px minmax(0, 1fr); align-items: baseline; }
.vs-lista-beneficios li::before {
  content: '';
  width: 7px;
  height: 7px;
  background: var(--dorado);
  transform: translateY(-2px);
}

/* VSCR-104 · OBS-VIS-02: botón secundario hacia la Biblioteca (D-104-02
   sustituye a D-MODEL-19 sólo aquí). No usa el enlace editorial dorado: es
   navy con texto blanco y filete dorado, y queda por debajo de la acción
   primaria («▶ Ver recorrido», 48 de alto sobre el visual). 48 a todo el
   ancho en móvil; 44 y a su medida desde 768. El foco usa el anillo del
   sistema: la lámina pide el dorado, pero sobre #F4F6F8 da 1,59:1 (STOP
   parcial registrado en VSCR-104 §9.2). */
.vs-portada3d__accion { margin-top: 24px; }
.vs-portada3d__boton {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  height: 48px;
  box-sizing: border-box;
  padding: 0 20px;
  background: var(--azul-profundo);
  color: var(--blanco);
  border-bottom: 2px solid var(--dorado);
  font-family: var(--fuente-titulos);
  font-weight: 600;
  font-size: 15px;
  transition: background-color var(--dur-hover) var(--curva);
}
.vs-portada3d__boton:hover { background: var(--azul-profundo-900); color: var(--blanco); }
.vs-portada3d__flecha { display: inline-block; transition: transform var(--dur-hover) var(--curva); }
.vs-portada3d__boton:hover .vs-portada3d__flecha { transform: translateX(4px); }
@media (min-width: 768px) {
  .vs-portada3d__accion { margin-top: 28px; }
  .vs-portada3d__boton { display: inline-flex; width: auto; height: 44px; font-size: 14px; white-space: nowrap; }
}
@media (prefers-reduced-motion: reduce) {
  .vs-portada3d__flecha { transition: none; }
  .vs-portada3d__boton:hover .vs-portada3d__flecha { transform: none; }
}

/* Fila interna de toda banda CTA: `.vs-cta-banda` ya es flex a partir
   de 768px (sección 12); su `.vs-contenedor` necesita serlo también,
   en todos los anchos, para alinear texto+botón — se resuelve por
   selector compuesto, sin tocar el HTML de cada página. */
.vs-cta-banda .vs-contenedor {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-9);
  flex-wrap: wrap;
}

/* ---------------------------------------------------------------
   26. Página institucional — composición editorial (VSCR-76)
   ---------------------------------------------------------------
   Sustituye a la columna centrada de 64ch que dejó VSCR-74. Aquella
   resolvió la asimetría, pero el Product Owner siguió viendo la página
   como «una columna angosta flotando en un lienzo vacío»: el problema no
   era el centrado sino que un solo bloque estrecho no usa un contenedor
   de 1328px por más que esté bien centrado.
   La salida no es ensanchar el párrafo —a 15px, 800px son más de 100
   caracteres por línea— sino repartir: el encabezado de cada sección pasa
   a una columna propia a la izquierda y el texto ocupa la derecha con su
   medida de lectura intacta. El conjunto usa el ancho; la línea no cambia.
   El orden del DOM sigue siendo encabezado → contenido (§42 de a11y): las
   dos columnas son de rejilla, no de fuente.

   Es el contrato BASE de cualquier Página institucional. Hasta VSCR-78
   About lo usaba también, sin variante — pero el piloto tipográfico que
   el PO aprobó para About no está aprobado para el resto (VSCR-78, CUA
   2026-08-19: «la escala piloto de About se está heredando también en
   Privacidad» — no era intencional). Estas reglas vuelven a ser exactamente
   las de VSCR-76 (restauradas de `6cbbec7^`, antes del primer commit del
   piloto), y siguen sirviendo a toda Página institucional — Aviso de
   privacidad incluido — salvo que lleve el modifier de §26b. */
.vs-pagina-editorial { max-width: var(--contenedor-max); }
.vs-editorial__encabezado { margin-bottom: var(--sp-13); }
.vs-editorial__encabezado h1 { margin-bottom: var(--sp-6); }
/* La intro es corta y abre la página: admite más ancho que el cuerpo de
   una sección, pero sigue topada por medida de lectura, no por el marco. */
.vs-editorial__intro { max-width: 66ch; color: var(--tinta-60); font-size: 17px; line-height: 1.7; }
.vs-editorial__intro > * + * { margin-top: var(--sp-6); }

.vs-editorial__seccion { padding-top: var(--sp-11); border-top: var(--borde-estructura); }
.vs-editorial > .vs-editorial__seccion + .vs-editorial__seccion,
.vs-editorial > .vs-editorial__par { margin-top: var(--sp-11); }
.vs-editorial__intro + .vs-editorial__seccion,
.vs-editorial__intro + .vs-editorial__par { margin-top: var(--sp-13); }
.vs-editorial__titulo h2 { margin: 0; font-size: 22px; }
.vs-editorial__cuerpo { color: var(--tinta-60); max-width: 66ch; }
.vs-editorial__cuerpo > * + * { margin-top: var(--sp-6); }
.vs-editorial__cuerpo ul,
.vs-editorial__cuerpo ol { padding-left: 1.25em; display: flex; flex-direction: column; gap: var(--sp-3); }
.vs-editorial__cuerpo a { text-decoration: underline; }

@media (min-width: 1120px) {
  /* 1fr/2fr: el encabezado necesita poco y el texto conserva su medida.
     `minmax(0,…)` evita que una palabra larga desborde la columna. */
  .vs-editorial__seccion {
    display: grid;
    /* El texto se fija en su medida de lectura y el encabezado absorbe el
       resto: así el bloque llega al borde derecho del contenedor —lo que el
       PO pedía— sin que la línea de párrafo pase de los ~80 caracteres. */
    grid-template-columns: minmax(0, 1fr) minmax(0, 66ch);
    gap: var(--sp-11);
  }
  .vs-editorial__par {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--sp-11);
  }
  /* Dentro del par cada concepto vuelve a una sola columna: son bloques
     cortos y equivalentes (Misión / Visión), no secciones largas. */
  .vs-editorial__par .vs-editorial__seccion { display: block; margin-top: 0; }
  .vs-editorial__par .vs-editorial__cuerpo { margin-top: var(--sp-6); }
}

/* Cierre editorial: deja de ser un enlace suelto al final del texto y pasa
   a ser una franja de cierre con el botón que ya usa el resto del sitio. */
.vs-editorial__cierre {
  margin-top: var(--sp-14);
  padding: var(--sp-11);
  background: var(--fondo-suave);
  border: var(--borde-estructura);
  display: flex;
  flex-direction: column;
  gap: var(--sp-8);
}
.vs-editorial__cierre h3 { margin: 0 0 var(--sp-4); font-size: 24px; }
.vs-editorial__cierre p { color: var(--tinta-60); max-width: 62ch; margin: 0; }
.vs-editorial__cierre-accion { flex: none; }
@media (min-width: 768px) {
  .vs-editorial__cierre { flex-direction: row; align-items: center; justify-content: space-between; gap: var(--sp-11); padding: var(--sp-12) var(--sp-13); }
}

/* ---------------------------------------------------------------
   26b. Nosotros / About · historia integrada (VSCR-95 frente D)
   ---------------------------------------------------------------
   Lámina `VSCR-95 D Nosotros Narrativa.dc.html`, CUA FINAL APROBADO POR EL
   PRODUCT OWNER (2026-09-28). Sustituye al piloto tipográfico de VSCR-78.
   Escritorio (≥ 1024): contenedor de 944 = margen de capítulo 200 + 64 +
   columna de lectura 680, centrado (248 px de margen a 1440). Tablet: una
   columna de 640 con margen 40; móvil: una columna con margen 20. En
   ≤ 1023 el margen de capítulo pasa a ser una línea sobre el H2.
   Ritmo: cabecera → migas 72 / 48 / 32; entre movimientos 88 / 64 / 48;
   tras la Visión, el CTA a 88 / 64 / 40. Sin tarjetas ni sombras. */
.vs-nosotros { padding: 32px var(--contenedor-margen-mobile) 0; }
.vs-nosotros .vs-migas { font-size: 11px; margin-bottom: var(--sp-3); }
.vs-nosotros__kicker,
.vs-nosotros__numero {
  font-family: var(--fuente-mono);
  font-size: 11px;
  letter-spacing: .14em;
  color: #8A5E00;
}
.vs-nosotros__kicker { display: inline-block; border-top: 2px solid var(--dorado); padding-top: var(--sp-2); margin-bottom: var(--sp-5); }
.vs-nosotros__h1 { font-size: 31px; line-height: 1.16; letter-spacing: -.02em; margin: 0 0 var(--sp-6); text-wrap: balance; }
.vs-nosotros__identidad { font-size: 18px; line-height: 1.6; color: var(--tinta); margin: 0 0 var(--sp-5); }
.vs-nosotros__lead { font-size: 16px; line-height: 1.7; color: var(--tinta-60); margin: 0; }

.vs-nosotros__movimiento { padding-top: var(--sp-13); }
.vs-nosotros__margen {
  display: flex;
  align-items: baseline;
  gap: var(--sp-4);
  width: max-content;
  max-width: 100%;
  border-top: 2px solid var(--dorado);
  padding-top: var(--sp-2);
  margin-bottom: var(--sp-4);
}
.vs-nosotros__etiqueta { font-family: var(--fuente-mono); font-size: 11px; letter-spacing: .14em; color: var(--tinta-60); }
.vs-nosotros__anio { display: none; }
.vs-nosotros__h2 { font-size: 24px; line-height: 1.24; letter-spacing: -.01em; margin: 0 0 var(--sp-5); text-wrap: balance; }
.vs-nosotros__parrafo { font-size: 16px; line-height: 1.7; color: var(--tinta-60); margin: 0 0 var(--sp-6); text-wrap: pretty; }

.vs-nosotros__usos {
  list-style: none;
  margin: 0;
  padding: var(--sp-5) 0 0;
  border-top: var(--borde-estructura);
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
}
.vs-nosotros__usos li { display: flex; align-items: center; gap: var(--sp-3); font-family: var(--fuente-titulos); font-weight: 600; font-size: 16px; line-height: 1.4; color: var(--azul-profundo); }
.vs-nosotros__marcador { width: 7px; height: 7px; background: var(--dorado); flex: none; }
.vs-nosotros__nota { font-size: 14px; line-height: 1.6; color: var(--tinta-60); margin: var(--sp-4) 0 0; }

.vs-nosotros__pasos { list-style: none; margin: var(--sp-1) 0 var(--sp-8); padding: 0; display: flex; flex-direction: column; }
.vs-nosotros__pasos li { display: flex; gap: var(--sp-5); align-items: baseline; border-top: var(--borde-estructura); padding: var(--sp-4) 0; }
.vs-nosotros__paso-numero { font-family: var(--fuente-mono); font-size: 12px; color: #8A5E00; }
.vs-nosotros__paso-texto { font-family: var(--fuente-titulos); font-weight: 600; font-size: 16px; line-height: 1.35; color: var(--tinta); }

.vs-nosotros__cita { margin: 26px 0; padding: 0; }
.vs-nosotros__cita::before { content: ""; display: block; width: 32px; height: 3px; background: var(--dorado); margin-bottom: var(--sp-5); }
.vs-nosotros__cita p { font-family: var(--fuente-titulos); font-weight: 600; font-size: 21px; line-height: 1.34; color: var(--azul-profundo); margin: 0; text-wrap: balance; }

.vs-nosotros__figura { margin: var(--sp-8) 0 0; }
.vs-nosotros__figura img { display: block; width: 100%; height: auto; }
.vs-nosotros__figura figcaption { font-size: 14px; line-height: 1.6; color: var(--tinta-60); margin-top: var(--sp-4); padding-top: var(--sp-3); border-top: var(--borde-estructura); }

.vs-nosotros__alcance { margin-top: 26px; padding-top: 18px; border-top: var(--borde-estructura); }
.vs-nosotros__alcance-rotulo { font-family: var(--fuente-mono); font-size: 11px; letter-spacing: .14em; color: var(--tinta-60); margin: 0 0 var(--sp-4); }
.vs-nosotros__alcance .vs-nosotros__parrafo { margin-bottom: var(--sp-6); }

.vs-nosotros__declaracion { margin-top: 26px; border-top: 2px solid var(--azul-profundo); padding-top: 18px; }
.vs-nosotros__declaracion-rotulo { font-family: var(--fuente-mono); font-weight: 500; font-size: 12px; letter-spacing: .18em; color: #8A5E00; margin: 0 0 var(--sp-4); }
.vs-nosotros__declaracion-texto { font-family: var(--fuente-titulos); font-weight: 600; font-size: 18px; line-height: 1.45; color: var(--azul-profundo); margin: 0; text-wrap: pretty; }

.vs-nosotros__cta { padding: var(--sp-11) var(--contenedor-margen-mobile) 44px; }
.vs-nosotros__cta-caja { border: var(--borde-estructura); padding: var(--sp-10) var(--sp-8) 34px; text-align: center; }
.vs-nosotros__cta-caja h2 { font-size: 24px; line-height: 1.24; letter-spacing: -.015em; margin: 0 0 var(--sp-4); }
.vs-nosotros__cta-caja p { font-size: 16px; line-height: 1.7; color: var(--tinta-60); margin: 0 auto var(--sp-8); }
.vs-nosotros__cta-boton { width: 100%; min-height: 56px; justify-content: center; }

@media (min-width: 768px) {
  .vs-nosotros { padding: var(--sp-13) var(--sp-11) 0; }
  /* Entrada a 768 (VSCR-97 B): el H1 ocupa el ancho (688) y la identidad y
     el lead se alinean a los 640 de los movimientos. */
  .vs-nosotros .vs-migas { font-size: 12px; margin-bottom: var(--sp-8); }
  .vs-nosotros__kicker, .vs-nosotros__numero, .vs-nosotros__etiqueta { font-size: 12px; }
  .vs-nosotros__kicker { padding-top: var(--sp-3); margin-bottom: 18px; }
  .vs-nosotros__h1 { font-size: 38px; line-height: 1.14; margin-bottom: var(--sp-9); }
  .vs-nosotros__identidad { font-size: 19px; margin-bottom: var(--sp-6); max-width: 640px; }
  .vs-nosotros__lead { font-size: 17px; max-width: 640px; }
  .vs-nosotros__movimiento { padding-top: var(--sp-15); max-width: 640px; }
  .vs-nosotros__margen { gap: var(--sp-5); padding-top: var(--sp-3); margin-bottom: var(--sp-5); }
  .vs-nosotros__h2 { font-size: 28px; line-height: 1.22; letter-spacing: -.015em; margin-bottom: 18px; }
  .vs-nosotros__parrafo { font-size: 17px; margin-bottom: 18px; }
  .vs-nosotros__usos { margin-top: var(--sp-1); padding-top: var(--sp-6); flex-direction: row; flex-wrap: wrap; gap: var(--sp-2) var(--sp-8); }
  .vs-nosotros__usos li { font-size: 17px; }
  .vs-nosotros__nota { font-size: 15px; }
  .vs-nosotros__pasos { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-7); margin: 6px 0 var(--sp-9); }
  .vs-nosotros__pasos li { display: block; border-top: 2px solid var(--azul-profundo); padding: var(--sp-4) 0 0; }
  .vs-nosotros__paso-numero { display: block; margin-bottom: 6px; }
  .vs-nosotros__cita { margin: 30px 0; }
  .vs-nosotros__cita::before { width: 36px; margin-bottom: var(--sp-6); }
  .vs-nosotros__cita p { font-size: 24px; line-height: 1.32; }
  .vs-nosotros__figura { margin-top: 30px; }
  .vs-nosotros__figura figcaption { font-size: 15px; margin-top: var(--sp-5); padding-top: var(--sp-4); }
  .vs-nosotros__alcance { margin-top: 30px; }
  .vs-nosotros__alcance-rotulo { font-size: 12px; }
  .vs-nosotros__declaracion { margin-top: 30px; }
  .vs-nosotros__declaracion-rotulo { font-size: 13px; }
  .vs-nosotros__declaracion-texto { font-size: 20px; }
  .vs-nosotros__cta { padding: var(--sp-15) var(--sp-11) 72px; }
  .vs-nosotros__cta-caja { padding: var(--sp-12) var(--sp-13); }
  .vs-nosotros__cta-caja h2 { font-size: 27px; line-height: 1.22; margin-bottom: var(--sp-5); }
  .vs-nosotros__cta-caja p { font-size: 17px; max-width: 56ch; margin-bottom: 26px; }
  .vs-nosotros__cta-boton { width: auto; padding: 0 var(--sp-11); }
}
@media (min-width: 1024px) {
  .vs-nosotros { max-width: 944px; margin: 0 auto; padding: 72px 0 0; box-sizing: content-box; }
  /* Entrada sobre la retícula de los movimientos (VSCR-97 frente B, lámina
     aprobada): carril 200 + 64 + columna 680. El kicker va en el carril,
     como «01»; el H1 abarca los 944 en dos líneas; identidad y lead empiezan
     en el borde del texto de los movimientos (x 512 a 1440). Ritmo: migas →
     kicker 32 · kicker → H1 20 · H1 → identidad 40 · identidad → lead 18 ·
     lead → 01 88, igual que entre movimientos. El copy no cambia. */
  .vs-nosotros__apertura { display: grid; grid-template-columns: 200px 680px; column-gap: var(--sp-15); }
  .vs-nosotros__apertura .vs-migas { grid-column: 1 / span 2; margin-bottom: var(--sp-10); }
  .vs-nosotros__kicker { grid-column: 1; display: block; margin-bottom: var(--sp-7); }
  .vs-nosotros__h1 { grid-column: 1 / span 2; max-width: 944px; font-size: 48px; line-height: 1.12; margin-bottom: var(--sp-11); }
  .vs-nosotros__identidad { grid-column: 2; font-size: 21px; max-width: none; margin-bottom: 18px; text-wrap: pretty; }
  .vs-nosotros__lead { grid-column: 2; font-size: 18px; max-width: var(--medida-editorial); text-wrap: pretty; }
  .vs-nosotros__movimiento { display: grid; grid-template-columns: 200px 680px; column-gap: var(--sp-15); padding-top: var(--sp-16); max-width: none; }
  .vs-nosotros__margen { display: block; width: auto; border-top: 0; padding-top: 6px; margin-bottom: 0; }
  .vs-nosotros__numero { display: block; border-top: 2px solid var(--dorado); padding-top: var(--sp-3); }
  .vs-nosotros__etiqueta { display: block; margin-top: 6px; line-height: 1.5; }
  .vs-nosotros__anio { display: block; margin-top: var(--sp-5); }
  .vs-nosotros__anio-prefijo { display: block; font-family: var(--fuente-mono); font-size: 12px; letter-spacing: .14em; color: var(--tinta-60); margin-bottom: var(--sp-1); }
  .vs-nosotros__anio-valor { display: block; font-family: var(--fuente-titulos); font-weight: 700; font-size: 44px; line-height: 1; letter-spacing: -.03em; color: var(--azul-profundo); }
  .vs-nosotros__h2 { font-size: 32px; line-height: 1.2; margin-bottom: 22px; }
  .vs-nosotros__parrafo { font-size: 18px; line-height: 1.72; margin-bottom: var(--sp-7); }
  .vs-nosotros__usos { padding-top: 18px; gap: var(--sp-3) var(--sp-9); }
  .vs-nosotros__usos li { font-size: 18px; }
  .vs-nosotros__nota { margin-top: var(--sp-5); }
  .vs-nosotros__pasos { gap: var(--sp-8) var(--sp-10); margin: var(--sp-2) 0 var(--sp-10); }
  .vs-nosotros__pasos li { padding-top: var(--sp-5); }
  .vs-nosotros__paso-numero { margin-bottom: var(--sp-2); }
  .vs-nosotros__cita { margin: 36px 0; }
  .vs-nosotros__cita::before { width: 40px; margin-bottom: 18px; }
  .vs-nosotros__cita p { font-size: 28px; letter-spacing: -.01em; }
  .vs-nosotros__figura { margin-top: 36px; display: flex; flex-direction: column; gap: var(--sp-6); }
  .vs-nosotros__figura figcaption { margin-top: 0; }
  .vs-nosotros__alcance, .vs-nosotros__declaracion { margin-top: 36px; }
  .vs-nosotros__declaracion-texto { font-size: 22px; }
  .vs-nosotros__cta { padding: var(--sp-16) 0 96px; display: flex; justify-content: center; }
  .vs-nosotros__cta-caja { width: 760px; box-sizing: border-box; padding: 52px var(--sp-15) var(--sp-14); }
  .vs-nosotros__cta-caja h2 { font-size: 30px; margin-bottom: var(--sp-6); }
  .vs-nosotros__cta-caja p { max-width: 58ch; margin-bottom: 30px; }
}

/* ---------------------------------------------------------------
   27. Piloto de Servicio S1 — Recorridos y gemelos digitales 3D
       VSCR-79 · Claude Design dirección 1a, aprobada por el PO
       2026-08-19. La variante 1b (proceso horizontal) se descartó.

       Todo cuelga de `.vs-s1`: no se propaga a los demás Servicios,
       ni a Soluciones, Retail, About o Proyectos. Sin `!important`,
       sin CSS inline, sin frameworks.

       Tres anchos, uno por función — el histórico de 549px durante
       2 463px verticales no sobrevive:
         editorial   ~820px   prosa
         componente  ~940px   pares, capacidades, proceso
         visual     ~1160px   visor, Mattertags, contextos
   --------------------------------------------------------------- */
/* El marco suma su propio padding para que el ancho VISIBLE del bloque
   visual sea 1160px exactos, no 1160 menos el gutter. */
/* VSCR-88 · PO-IDX-03 (2026-09-10): el margen pasa a custom property para que
   la sangría de la evidencia pueda anclarse a él y no puedan desincronizarse
   —fue exactamente lo que rompió la sangría móvil en la Fase 2—. El valor de
   escritorio no cambia: `--sp-6` mantiene el bloque visual en 1160 exactos y
   su inset natural de 140 a 1440, que PO-IDX-03-A declara correcto. Ojo: aquí
   16 no es un «margen de página» —el frame exterior de la pieza es 56—, sino
   el gutter que hace que el bloque visible mida 1160. Son dos cajas distintas
   que este único elemento representa a la vez. */
.vs-s1__marco {
  --s1-margen: var(--sp-6);
  max-width: calc(1160px + var(--s1-margen) * 2);
  margin-inline: auto;
  padding-inline: var(--s1-margen);
}
/* PO-IDX-03-C: en tablet manda el frame de la pieza de S1 —40, no los 32 de la
   Familia Servicios, que no la cubre—, y la evidencia rompe ese frame hasta el
   viewport completo: «768 × 432 px a sangre… es el único bloque que rompe el
   margen de 40 px del frame». Banda canónica 768–1119, la misma de los
   arquetipos. Frame útil 688; evidencia 768 con bleed 0/0. */
@media (min-width: 768px) and (max-width: 1119px) {
  .vs-s1__marco { --s1-margen: var(--sp-11); }
  .vs-s1__visual .vs-matterport { margin-inline: calc(var(--s1-margen) * -1); }
}
.vs-s1__editorial { max-width: 820px; margin-inline: auto; }
/* CUA-02: variante para cuando el editorial antecede a un `.vs-s1__visual`
   (ancho 1160, ya alineado a `.vs-s1__marco` por construcción — 1160 es el
   ancho íntegro del marco) y ambos deben leerse como una sola entrada, no
   como dos bloques centrados por separado con cantos distintos. Sin
   `margin-inline: auto` el editorial se ancla al mismo borde que el
   visual; conserva su propio `max-width` de 820px, así que el párrafo de
   apertura no gana línea de lectura excesiva. Medido en Chrome real: sin
   esto, «Dónde tiene sentido» quedaba 170px a la derecha de la rejilla
   que describe. No se usa en el resto de la página — sólo donde el
   siguiente bloque es `.vs-s1__visual`. */
.vs-s1__editorial--flush { margin-inline: 0; }
.vs-s1__componente { max-width: 940px; margin-inline: auto; }
.vs-s1__visual { max-width: 1160px; margin-inline: auto; }

.vs-s1__seccion { padding-block: var(--sp-12); }
.vs-s1__seccion--cabecera { padding-top: var(--sp-10); padding-bottom: var(--sp-8); }
.vs-s1__seccion--suave { background: var(--fondo-suave); }
.vs-s1__seccion--evidencia { padding-top: 0; }

/* Escala aprobada: H1 40 / H2 28 / cuerpo 17. Por encima de la que
   traía la página (32/26/15) y alineada con la referencia editorial
   ya aprobada, sin pasar a titulares de hero. */
.vs-s1 h1 {
  margin: var(--sp-4) 0 var(--sp-6);
  font-size: clamp(31px, 3.2vw, 40px);
  line-height: 1.14;
  letter-spacing: -.015em;
}
.vs-s1 h2 {
  margin: 0 0 var(--sp-5);
  font-size: clamp(24px, 2.4vw, 28px);
  line-height: 1.22;
  letter-spacing: -.01em;
}
.vs-s1 h3 { margin: 0 0 var(--sp-4); font-size: 19px; line-height: 1.3; }
.vs-s1 p { font-size: 17px; line-height: 1.62; }
.vs-s1 .vs-s1__resumen { font-size: 19px; line-height: 1.55; color: var(--tinta-60); }
.vs-s1__editorial p + p { margin-top: var(--sp-4); }
.vs-s1 .vs-s1__nota { font-size: 15px; line-height: 1.55; color: var(--tinta-45); margin-top: var(--sp-6); }
.vs-s1__nota--centrada { text-align: center; }

/* 2 · Evidencia — el visor reutiliza `_matterport.php` tal cual, con
   su click-to-load, su badge y su disclosure. Aquí sólo se le da
   ancho y aire; no se redefine el componente. */
.vs-s1__seccion--evidencia .vs-s1__editorial { margin-bottom: var(--sp-8); }

/* 4 · Recibe → para qué sirve. Dos columnas con la relación visible:
   la flecha central es el contenido, no un adorno. */
.vs-s1__pares { display: grid; gap: 1px; background: var(--borde); border: var(--borde-estructura); }
.vs-s1__pares-encabezado {
  display: none;
  margin: 0;
  padding: var(--sp-4) var(--sp-6);
  background: var(--blanco);
  font-size: 12px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--tinta-45);
}
.vs-s1__par { display: grid; gap: var(--sp-2); padding: var(--sp-6); background: var(--blanco); }
.vs-s1 .vs-s1__par-etiqueta {
  margin: 0;
  font-size: 12px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--tinta-45);
}
.vs-s1 .vs-s1__par-a { margin: 0; font-weight: 600; }
.vs-s1 .vs-s1__par-b { margin: 0; color: var(--tinta-60); }

@media (min-width: 768px) {
  .vs-s1__pares { grid-template-columns: 1fr 1fr; }
  .vs-s1__pares-encabezado { display: block; }
  .vs-s1__par {
    grid-column: span 2;
    grid-template-columns: 1fr 1fr;
    align-items: start;
    gap: var(--sp-6);
    padding-left: var(--sp-6);
  }
  /* Las etiquetas por par sólo existen para móvil: en desktop la
     columna ya está rotulada arriba. */
  .vs-s1 .vs-s1__par-etiqueta { display: none; }
  /* La flecha vive en el borde de la primera celda, centrada en la
     medianera. `content` decorativo, nunca texto real. */
  .vs-s1__par-a { position: relative; padding-right: var(--sp-6); }
  .vs-s1__par-a::after {
    content: "→";
    position: absolute;
    right: calc(var(--sp-6) * -0.5);
    top: 0;
    color: var(--azul-senal);
  }
}

/* 5 · Capacidades y entregables adicionales (VSCR-109, DG-E, lámina E).
   Supersede las dos columnas de prosa de la dirección 1a: cada grupo es
   una tabla de cuatro columnas —complemento · qué es · para quién ·
   condición— con su título como `<caption>` y el acento de color en el
   filete superior (azul sobre el recorrido, ámbar para los derivados).
   Columnas de la lámina: 190 / 1.3fr / 1fr / 1.2fr con hueco de 20 desde
   1120 y 150 / 1.2fr / 1fr / 1.1fr en 768; aquí, el hueco va como relleno
   derecho de cada celda y los porcentajes salen de ese reparto sobre el
   ancho real del componente (940 y 688). En móvil las filas se apilan: los
   encabezados se ocultan y cada celda muestra su etiqueta en línea. */
.vs-s1__complementos { display: grid; gap: var(--sp-9); }
.vs-s1__grupo { display: block; width: 100%; border-collapse: collapse; }
.vs-s1__grupo-titulo { display: block; margin-bottom: 6px; padding-top: var(--sp-5); border-top: 3px solid var(--azul-senal); font-family: var(--fuente-titulos); font-weight: 700; font-size: 18px; line-height: 1.3; color: var(--tinta); text-align: left; }
.vs-s1__grupo--ambar .vs-s1__grupo-titulo { border-top-color: var(--dorado); }
.vs-s1__grupo thead { display: none; }
.vs-s1__grupo tbody,
.vs-s1__grupo tr,
.vs-s1__grupo th,
.vs-s1__grupo td { display: block; }
.vs-s1__grupo tbody tr { padding: var(--sp-5) 0; border-bottom: var(--borde-estructura); }
.vs-s1__grupo tbody th { font-family: var(--fuente-titulos); font-weight: 700; font-size: 15px; line-height: 1.4; color: var(--tinta); text-align: left; }
.vs-s1__grupo td { margin-top: 6px; font-size: 14.5px; line-height: 1.55; color: var(--tinta-60); }
.vs-s1__grupo td:first-of-type { color: var(--tinta); }
.vs-s1__complementos-etiqueta { font-family: var(--fuente-mono); font-size: 10px; letter-spacing: .1em; color: var(--tinta-60); }
@media (min-width: 768px) {
  .vs-s1__grupo { display: table; table-layout: fixed; }
  .vs-s1__grupo-titulo { display: table-caption; }
  .vs-s1__grupo thead { display: table-header-group; }
  .vs-s1__grupo tbody { display: table-row-group; }
  .vs-s1__grupo tr,
  .vs-s1__grupo tbody tr { display: table-row; padding: 0; }
  .vs-s1__grupo th,
  .vs-s1__grupo td { display: table-cell; box-sizing: border-box; margin-top: 0; padding: var(--sp-5) var(--sp-7) var(--sp-5) 0; border-bottom: var(--borde-estructura); vertical-align: top; text-align: left; }
  .vs-s1__grupo th:last-child,
  .vs-s1__grupo td:last-child { padding-right: 0; }
  .vs-s1__grupo thead th { padding-block: var(--sp-2); font-family: var(--fuente-mono); font-weight: 400; font-size: 10px; letter-spacing: .12em; line-height: 1.5; color: var(--tinta-60); }
  .vs-s1__grupo thead th:first-child { width: 170px; }
  .vs-s1__grupo thead th:nth-child(2) { width: 28.2%; }
  .vs-s1__grupo thead th:nth-child(3) { width: 24%; }
  .vs-s1__complementos-etiqueta { display: none; }
}
@media (min-width: 1120px) {
  .vs-s1__grupo thead th:first-child { width: 210px; }
  .vs-s1__grupo thead th:nth-child(2) { width: 29.4%; }
  .vs-s1__grupo thead th:nth-child(3) { width: 23.1%; }
}

/* 6 · Mattertags. Modelo demostrativo: la etiqueta va sobre la
   imagen y el disclosure en el pie, ambos siempre visibles — la
   procedencia nunca depende sólo del color. */
.vs-s1__mattertags { margin: var(--sp-9) 0 0; }
.vs-s1__mattertags-marco { position: relative; }
.vs-s1__mattertags img { display: block; width: 100%; height: auto; }
.vs-s1__etiqueta {
  position: absolute;
  top: var(--sp-4);
  left: var(--sp-4);
  padding: var(--sp-2) var(--sp-3);
  font-size: 11px;
  letter-spacing: .08em;
  text-transform: uppercase;
}
.vs-s1__etiqueta--demo { background: var(--azul-profundo); color: var(--blanco); }
.vs-s1__mattertags figcaption {
  margin-top: var(--sp-4);
  font-size: 15px;
  line-height: 1.55;
  color: var(--tinta-60);
}
.vs-s1__disclosure { display: block; margin-top: var(--sp-2); color: var(--tinta-45); }

/* 7 · Proceso — rail VERTICAL en los tres viewports. La línea la
   dibuja el borde izquierdo del `<li>`; el último tramo se recorta
   para que el rail no sobresalga por debajo del paso 06. */
/* CUA-02: el marcador (`.vs-s1__paso-num`, 34px) va centrado sobre la
   línea del rail vía `translateX(-50%)` — a propósito, es el patrón
   habitual de un timeline. Sin este padding esa mitad se sale de
   `.vs-s1__componente` (medido en Chrome real: 16px) y en móvil, donde
   editorial/componente/visual comparten el mismo borde que el marco,
   ese desborde cae fuera del propio viewport. El padding absorbe
   exactamente esa mitad — el rail se desplaza, el marcador no cambia. */
.vs-s1__proceso { margin: 0; padding: 0 0 0 16px; list-style: none; }
.vs-s1__paso {
  position: relative;
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--sp-5);
  padding: 0 0 var(--sp-8) var(--sp-7);
  border-left: 1.5px solid var(--borde);
}
.vs-s1__paso:last-child { border-left-color: transparent; padding-bottom: 0; }
.vs-s1__paso-num {
  position: absolute;
  left: 0;
  top: 0;
  transform: translateX(-50%);
  width: 34px;
  height: 34px;
  display: grid;
  place-items: center;
  background: var(--azul-profundo);
  font-size: 12px;
  color: var(--blanco);
}
/* 04 es el único paso que ocurre en el sitio del cliente: acento. Fondo
   ámbar, no sólo un borde — mismo par ámbar/tinta ya aprobado para las
   etiquetas «Proyecto propio» del visor, para no inventar un segundo
   contraste. Dirección 1a final: sin outlines blancos. */
.vs-s1__paso--acento .vs-s1__paso-num { background: var(--dorado); color: var(--tinta); }
.vs-s1__paso-cuerpo { grid-column: 1 / -1; }
.vs-s1 .vs-s1__paso-titulo { margin: 0 0 var(--sp-2); font-weight: 600; }
.vs-s1 .vs-s1__paso-texto { margin: 0; color: var(--tinta-60); }

/* 8 · Contextos. Dirección 1a final: ícono Tabler real (azul profundo,
   ~28px de dibujo en una caja óptica de 44px) + línea corta ámbar
   externa (~14×2px) como único acento, nunca dentro del SVG. El mapa
   contexto→ícono vive en PHP (`includes/iconos-tabler.php`), no aquí. */
.vs-s1__contextos { display: grid; gap: 1px; background: var(--borde); border: var(--borde-estructura); }
.vs-s1__contexto { padding: var(--sp-7); background: var(--blanco); }
.vs-s1__contexto h3 { margin: 0 0 var(--sp-3); font-size: 18px; }
.vs-s1__contexto p { font-size: 15px; line-height: 1.55; color: var(--tinta-60); margin: 0 0 var(--sp-5); }
.vs-s1__contexto-enlace { font-size: 14px; font-weight: 600; }
@media (min-width: 768px) { .vs-s1__contextos { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1120px) { .vs-s1__contextos { grid-template-columns: repeat(3, 1fr); } }

.vs-s1__contexto-icono { width: 44px; height: 44px; display: grid; place-items: center; margin: 0 0 var(--sp-3); }
.vs-s1__contexto-icono svg { width: 28px; height: 28px; color: var(--azul-profundo); }
.vs-s1__contexto-acento { display: block; width: 14px; height: 2px; background: var(--dorado); margin: 0 0 var(--sp-5); }

/* 9 · CTA + alojamiento. Un solo cierre, sobre azul profundo. El
   alojamiento es una condición, no una sección ni un pricing. */
.vs-s1__cta { background: var(--azul-profundo); color: var(--blanco); padding-block: var(--sp-12); }
.vs-s1__cta .vs-s1__marco { display: grid; gap: var(--sp-9); }
.vs-s1__cta h2 { color: var(--blanco); max-width: 20ch; }
.vs-s1__cta-cuerpo p { color: var(--sobre-oscuro); max-width: 58ch; margin-bottom: var(--sp-7); }
/* Acción secundaria integrada en el mismo CTA (Dirección 1a final,
   §10): subordinada al botón principal, nunca compitiendo con él —
   mismo tono apagado que ya usan los enlaces del footer sobre fondo
   oscuro (`--sobre-oscuro-2`), no dorado ni botón. */
.vs-s1__cta-acciones { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-7); }
.vs-s1__cta-secundario { font-size: 15px; color: var(--sobre-oscuro-2); }
.vs-s1__cta-secundario:hover { color: var(--blanco); }
.vs-s1__alojamiento { border-top: 1px solid var(--borde-oscuro); padding-top: var(--sp-6); }
.vs-s1__alojamiento p { font-size: 15px; line-height: 1.55; color: var(--sobre-oscuro); margin: 0; }
/* Dos clases (0,2,0) para ganarle a `.vs-s1__alojamiento p` (0,1,1)
   sin recurrir a `!important`. */
.vs-s1__alojamiento .vs-s1__alojamiento-etiqueta {
  margin: 0 0 var(--sp-3);
  font-size: 11px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--dorado);
}
@media (min-width: 1120px) {
  .vs-s1__cta .vs-s1__marco { grid-template-columns: 1.3fr 1fr; align-items: start; gap: var(--sp-11); }
  .vs-s1__alojamiento { border-top: 0; border-left: 1px solid var(--borde-oscuro); padding: 0 0 0 var(--sp-8); }
}

/* Móvil 375 — el visor va a sangre y el resto apila. Sin
   `white-space: nowrap` en ninguna parte. */
@media (max-width: 767px) {
  .vs-s1 p { font-size: 16px; }
  .vs-s1 .vs-s1__resumen { font-size: 17px; }
  .vs-s1__seccion { padding-block: var(--sp-9); }
  /* VSCR-88 · PO-IDX-02-A, ratificado por PO-IDX-03 §5: la pieza de S1 y el
     contrato de familia coinciden en 20 para móvil. La sangría se ancla a la
     misma variable que el margen, así que sigue dando 0/0 aunque el valor
     cambie. */
  .vs-s1__marco { --s1-margen: var(--sp-7); }
  .vs-s1__visual .vs-matterport { margin-inline: calc(var(--s1-margen) * -1); }
  .vs-s1__contexto { padding: var(--sp-6); }
}

/* ---------------------------------------------------------------
   28. Piloto de Solución S-Retail — Retail
       VSCR-81 · Claude Design dirección 1a FINAL, aprobada por el PO
       2026-08-21. Las rondas 1 y 2 quedan históricas/supersedidas.

       Todo cuelga de `.vs-retail`: no se propaga a las otras ocho
       Soluciones, ni a Servicios, About o Proyectos. Sin `!important`,
       sin CSS inline, sin frameworks, sin CDN.

       Mismo sistema de tres anchos ya aprobado, sobre UN eje central —
       el histórico 549 / 1328 / 843 con ejes distintos no sobrevive:
         editorial   820px   prosa, evidencia secundaria, alcance
         componente  940px   contraste, servicios, aplicaciones
         visual     1160px   evidencia principal

       Los valores se repiten aquí en vez de compartirse con el piloto
       de S1 (§27) a propósito: aquel está cerrado y verificado, y
       refactorizarlo para extraer tokens comunes es una unidad propia,
       no un efecto colateral de Retail.
   --------------------------------------------------------------- */
/* El marco suma su propio relleno para que el ancho VISIBLE del bloque
   visual sea 1160px exactos, no 1160 menos el gutter. */
/* VSCR-88 · PO-IDX-01 (2026-09-09): margen lateral responsive 32/20 en tablet
   y móvil. `Solucion Retail.dc.html` (VSCR-81, candidata final) declara 32 a
   768 y 20 a 375 en sus propios artboards, así que la divergencia con el 16
   congelado está demostrada contra la autoridad propia de esta página, no
   sólo contra el contrato de familia. A 1440 no cambia nada: sigue 1160/140. */
.vs-retail__marco {
  --retail-margen: var(--sp-7);
  max-width: calc(1160px + var(--retail-margen) * 2);
  margin-inline: auto;
  padding-inline: var(--retail-margen);
  box-sizing: border-box;
}
@media (min-width: 768px) { .vs-retail__marco { --retail-margen: var(--sp-10); } }
.vs-retail__editorial { max-width: 820px; margin-inline: auto; }
.vs-retail__componente { max-width: 940px; margin-inline: auto; }
.vs-retail__visual { max-width: 1160px; margin-inline: auto; }
/* Microgate responsive final (2026-08-27): en tablet, 1160 y 820 exceden
   ambos el ancho disponible (768 − 32 de gutter = 736), así que las dos
   evidencias colapsaban al mismo 736 y la jerarquía Lamborghini/Plomería
   —que la lámina 768 del `.dc.html` de Retail sí conserva— desaparecía.
   La lámina fija 704×396 para la principal y 640×360 para la secundaria.

   Scoped a los dos contenedores de evidencia, no a `.vs-retail__editorial`
   en general: esa clase la comparten también la entradilla y el Alcance,
   que no son parte de este microgate. */
@media (min-width: 768px) and (max-width: 1119px) {
  .vs-retail__visual { max-width: 704px; }
  .vs-retail__seccion--secundaria .vs-retail__editorial { max-width: 640px; }
}

.vs-retail__seccion { padding-block: var(--sp-12); }
.vs-retail__seccion--cabecera { padding-top: var(--sp-10); padding-bottom: var(--sp-8); }
/* La evidencia principal va pegada a la entradilla: son una sola entrada,
   no dos bloques. */
.vs-retail__seccion--evidencia { padding-top: 0; }
.vs-retail__seccion--suave { background: var(--fondo-suave); }
/* Alcance se lee como bloque secundario: menos aire arriba que el resto. */
.vs-retail__seccion--alcance { padding-top: var(--sp-10); }

/* Escala aprobada: H1 40 / H2 28 / cuerpo 17, la misma calibración ya
   validada en About y en el piloto de Servicio. Por encima de lo que
   traía la página (32/26/15) y sin pasar a titulares de hero. */
.vs-retail h1 {
  margin: var(--sp-4) 0 var(--sp-6);
  font-size: clamp(31px, 3.2vw, 40px);
  line-height: 1.14;
  letter-spacing: -.015em;
}
.vs-retail h2 {
  margin: 0 0 var(--sp-5);
  font-size: clamp(24px, 2.4vw, 28px);
  line-height: 1.22;
  letter-spacing: -.01em;
}
.vs-retail h3 { margin: 0 0 var(--sp-3); font-size: 19px; line-height: 1.3; }
.vs-retail p { font-size: 17px; line-height: 1.62; }
.vs-retail .vs-retail__lead { font-size: 19px; line-height: 1.55; color: var(--tinta-60); }

/* 3 · Problema ↔ solución. Una sola composición asimétrica: el problema
   ocupa menos y lleva tinta atenuada; la solución lleva la tinta
   principal y el peso. La separación es un filete discreto y aire — sin
   cards, sin sombras, sin iconos, sin números, sin flechas. */
.vs-retail__contraste { display: grid; gap: var(--sp-9); }
.vs-retail__contraste-problema { color: var(--tinta-60); }
.vs-retail__contraste-problema h2 { color: var(--tinta-60); }
.vs-retail__contraste-problema p,
.vs-retail__contraste-solucion p { margin: 0; }
.vs-retail__contraste-solucion { border-top: var(--borde-estructura); padding-top: var(--sp-9); }
@media (min-width: 1120px) {
  /* 0.62fr / 1fr ≈ 38 % / 62 %, dentro del rango aprobado. El filete
     pasa de horizontal a vertical y el relleno lo separa del texto. */
  .vs-retail__contraste { grid-template-columns: 0.62fr 1fr; gap: var(--sp-11); align-items: start; }
  .vs-retail__contraste-solucion {
    border-top: 0;
    border-left: var(--borde-estructura);
    padding-top: 0;
    padding-left: var(--sp-11);
  }
  .vs-retail__contraste-problema h2 { font-size: 24px; }
}

/* 4 · Puente + evidencia secundaria. El puente es una línea de enlace
   entre los dos capítulos, no un encabezado: tinta atenuada y aire
   suficiente para que no se lea como pie de la sección anterior. */
.vs-retail .vs-retail__puente {
  margin: 0 0 var(--sp-8);
  color: var(--tinta-60);
  max-width: 58ch;
}

/* 5 · Servicios — navegación, no una segunda sección editorial. Una sola
   superficie con divisor interno, igual criterio que las Capacidades de
   S1: dos opciones, no dos tarjetas sueltas compitiendo. Sin iconos:
   el proyecto no tiene mapa canónico de iconografía por Servicio. */
.vs-retail__servicios { display: grid; gap: 1px; background: var(--borde); border: var(--borde-estructura); }
.vs-retail__servicio { display: grid; align-content: start; padding: var(--sp-7); background: var(--blanco); }
.vs-retail__servicio p { font-size: 16px; line-height: 1.55; color: var(--tinta-60); margin: 0 0 var(--sp-6); }
.vs-retail__servicio-enlace { font-size: 14px; font-weight: 600; justify-self: start; }
@media (min-width: 768px) {
  .vs-retail__servicios { grid-template-columns: 1fr 1fr; align-items: stretch; }
}

/* 6 · Aplicaciones — patrón visual común A/B/C/Retail, ver
   `.vs-aplicaciones-arquetipo` (D-VIS-07). */

/* 7 · Alcance — bloque compacto sobre el eje editorial. El relleno queda
   dentro de los 820px porque el reset global aplica `box-sizing:
   border-box` a todo (§1): el filete izquierdo no desplaza el bloque ni
   lo hace exceder su ancho. */
.vs-retail__alcance {
  border-left: 3px solid var(--borde);
  padding-left: var(--sp-8);
}
.vs-retail__alcance h2 { font-size: 22px; margin-bottom: var(--sp-4); }
.vs-retail__alcance p { font-size: 16px; line-height: 1.6; color: var(--tinta-60); margin: 0; }
.vs-retail__alcance p + p { margin-top: var(--sp-4); }

/* 8 · CTA. Último capítulo antes del pie, sobre azul profundo y con el
   botón ámbar de marca. Nada se inserta después. */
.vs-retail__cta { background: var(--azul-profundo); color: var(--blanco); padding-block: var(--sp-12); }
.vs-retail__cta .vs-retail__marco { display: grid; gap: var(--sp-8); }
.vs-retail__cta h2 { color: var(--blanco); max-width: 22ch; }
.vs-retail__cta p { color: var(--sobre-oscuro); max-width: 58ch; margin: 0; }
@media (min-width: 1120px) {
  .vs-retail__cta .vs-retail__marco {
    grid-template-columns: 1.4fr auto;
    align-items: center;
    gap: var(--sp-11);
  }
  .vs-retail__cta-accion { justify-self: end; }
}

/* Móvil 375 — el visor principal va a sangre y el resto apila. Sin
   `white-space: nowrap` en ninguna parte y sin reducir la tipografía por
   debajo de la escala legible del sistema. */
@media (max-width: 767px) {
  .vs-retail p { font-size: 16px; }
  .vs-retail .vs-retail__lead { font-size: 17px; }
  .vs-retail__seccion { padding-block: var(--sp-9); }
  .vs-retail__seccion--evidencia { padding-top: 0; }
  /* VSCR-88 · PO-IDX-02 (2026-09-10): la sangría iba fijada a `--sp-6` porque
     ése era el padding del marco; al restaurar el margen móvil a 20 en la Fase 2
     dejó de alcanzar el borde y el visor quedó a 4px de cada lado. Ahora sigue
     al margen real del marco, así que no puede volver a desincronizarse. */
  .vs-retail__visual .vs-matterport { margin-inline: calc(var(--retail-margen) * -1); }
  /* Microgate responsive final (2026-08-27): las dos evidencias de Retail
     heredaban el `aspect-ratio: 1/1` que el componente compartido aplica a
     los demostrativos por debajo de 768px (VSCR-07K) y salían cuadradas.
     La lámina 375 del `.dc.html` de Retail fija 335×188 en las dos — 16:9
     exacto. Scoped a `.vs-retail`: el resto de los llamantes del componente
     (Home, S1, Proyecto, Biblioteca) conserva su 1/1 sin cambios. */
  .vs-retail .vs-matterport { aspect-ratio: 16 / 9; }
  .vs-retail__servicio { padding: var(--sp-6); }
  .vs-retail__alcance { padding-left: var(--sp-6); }
  .vs-retail__cta .vs-boton { width: 100%; text-align: center; }
}

/* ---------------------------------------------------------------
   29. Composición general de Solución — propagación (VSCR-84)
       Común a las ocho Soluciones que no son Retail. Reutiliza
       `.vs-pagina-editorial` + `componerPaginaEditorial()` (§26, ya en
       producción en About) con un modifier nuevo, análogo a
       `.vs-pagina--about-piloto` (§26b): mismo mecanismo de composición,
       calibración propia. Sólo se propaga a Soluciones — About, Retail,
       Servicio y Privacidad no llevan este modifier y no cambian.

       Sistema de anchos igual al de Retail (§28): editorial 820, visual
       1160, sobre un eje. Sin ancho de "componentes" propio: la rejilla
       de Servicios vive dentro del flujo editorial (para que el CTA
       siga siendo el último capítulo, sin reiniciar nada después) y
       comparte los 820px de la columna — una simplificación deliberada
       frente a los 940 nominales del sistema, documentada en el
       expediente de VSCR-84.
   --------------------------------------------------------------- */
.vs-pagina-editorial.vs-pagina--solucion-general {
  max-width: calc(820px + 2 * var(--contenedor-margen-mobile));
}
@media (min-width: 768px) {
  .vs-pagina-editorial.vs-pagina--solucion-general { max-width: calc(820px + 2 * var(--contenedor-margen-tablet)); }
}
@media (min-width: 1120px) {
  .vs-pagina-editorial.vs-pagina--solucion-general { max-width: calc(820px + 2 * var(--contenedor-margen-desktop)); }
  /* Cancela la retícula título-izquierda/texto-derecha de §26 (el mismo
     patrón que el Product Owner ya había rechazado en About antes de
     VSCR-78): una sola columna, encabezado pegado a su propio texto. */
  .vs-pagina--solucion-general .vs-editorial__seccion { display: block; grid-template-columns: none; }
}

/* Escala aprobada del sistema (Retail/Servicio): H1 40 / H2 28 / cuerpo 17.
   Por encima de lo que traía la página (32/26/15) y sin pasar a hero. */
.vs-pagina--solucion-general .vs-editorial__encabezado h1 {
  font-size: clamp(31px, 3.2vw, 40px);
  line-height: 1.15;
  letter-spacing: -.02em;
  margin-bottom: var(--sp-6);
}
.vs-pagina--solucion-general .vs-lead { font-size: 19px; line-height: 1.55; color: var(--tinta-60); max-width: none; }
.vs-pagina--solucion-general .vs-editorial__intro { max-width: none; font-size: 17px; line-height: 1.65; }
.vs-pagina--solucion-general .vs-editorial__titulo h2 {
  margin: 0 0 var(--sp-7);
  font-size: clamp(22px, 2.2vw, 28px);
  line-height: 1.25;
  letter-spacing: -.01em;
  max-width: 28ch;
}
.vs-pagina--solucion-general .vs-editorial__cuerpo { max-width: none; font-size: 17px; line-height: 1.62; }

/* Aplicaciones/Alcance quedan como par de conceptos (misma regla de forma
   que Misión/Visión en About): son las dos secciones de un solo bloque
   inmediatamente antes del cierre, y `componerPaginaEditorial()` las
   empareja sin que el template tenga que saber sus nombres. */
@media (min-width: 900px) {
  .vs-pagina--solucion-general .vs-editorial__par {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--sp-11);
  }
  .vs-pagina--solucion-general .vs-editorial__par .vs-editorial__seccion { margin-top: 0; }
}

.vs-pagina--solucion-general .vs-editorial__cierre h3 {
  margin: 0 0 var(--sp-4);
  font-size: clamp(21px, 2vw, 26px);
  line-height: 1.25;
}
.vs-pagina--solucion-general .vs-editorial__cierre p { max-width: none; font-size: 17px; line-height: 1.62; }

/* Servicios relacionados, insertados por `$bloqueAntesDelCierre` — vive
   dentro de `.vs-editorial`, así que hereda los 820px de la columna y
   reutiliza `.vs-rejilla-servicios`/`.vs-tarjeta-servicio` tal cual (mismo
   componente que el resto del sitio, sin clases nuevas de tarjeta). La
   única corrección necesaria: el modifier `--2col` de §7 fija columnas de
   420px pensadas para un contenedor más ancho (940 en Retail); dentro de
   los 820px de esta columna, dos tracks de 420px exceden el ancho
   disponible. Aquí se vuelven fluidas sólo en este contexto. */
.vs-sector-gral__servicios { margin-top: var(--sp-14); }
.vs-sector-gral__servicios h2 {
  margin: 0 0 var(--sp-7);
  font-size: clamp(22px, 2.2vw, 28px);
  line-height: 1.25;
}
@media (min-width: 768px) {
  .vs-sector-gral__servicios .vs-rejilla-servicios--1col,
  .vs-sector-gral__servicios .vs-rejilla-servicios--2col { width: auto; }
  .vs-sector-gral__servicios .vs-rejilla-servicios--1col { grid-template-columns: minmax(0, 1fr); }
  .vs-sector-gral__servicios .vs-rejilla-servicios--2col { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* Evidencia — ancho visual 1160 sobre el mismo eje que la columna
   editorial de 820 (idéntico cálculo de marco que Retail/Servicio §27-28:
   el padding se suma para que el ancho VISIBLE sea 1160 exactos). */
.vs-sector-gral__marco-visual {
  max-width: calc(1160px + var(--sp-6) * 2);
  margin-inline: auto;
  padding-inline: var(--sp-6);
}
.vs-sector-gral__evidencia-principal { max-width: 1160px; margin-inline: auto; }
.vs-sector-gral__evidencia-secundaria { max-width: 820px; margin-inline: auto; margin-top: var(--sp-11); }
.vs-sector-gral__biblioteca { max-width: 820px; margin: var(--sp-6) auto 0; font-size: 15px; }

@media (max-width: 767px) {
  .vs-sector-gral__evidencia-secundaria { margin-top: var(--sp-9); }
}

/* ---------------------------------------------------------------
   29.5. Servicios — superficie única de navegación, compartida por los
         arquetipos A/B/C (`_servicios-arquetipo.php`). Un rectángulo con
         borde, celdas separadas por 1px vía el truco `gap` + `background`
         (el mismo fondo del borde asoma en el hueco), sin iconos. Con un
         solo Servicio la celda ocupa el ancho completo y pasa a fila
         (etiqueta+línea a la izquierda, enlace centrado a la derecha) en
         vez de columna — regla M de la maestra de cada arquetipo.
         Corrección de fidelidad VSCR-84, 2026-08-25: reemplaza, sólo para
         estas tres composiciones, la rejilla de tarjetas con iconos que
         Retail/S1/el resto del sitio siguen usando sin cambios.
   --------------------------------------------------------------- */
.vs-servicios-arquetipo {
  display: flex;
  flex-direction: column;
  gap: 1px;
  border: var(--borde-estructura);
  background: var(--borde);
  box-sizing: border-box;
}
.vs-servicios-arquetipo__celda {
  background: var(--blanco);
  padding: var(--sp-6);
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
  min-height: 120px;
  box-sizing: border-box;
}
.vs-servicios-arquetipo__texto h3 { font-size: 19px; margin: 0 0 var(--sp-2); }
.vs-servicios-arquetipo__texto p { font-size: 16px; color: var(--tinta-60); margin: 0; }
.vs-servicios-arquetipo__celda a { font-family: var(--fuente-titulos); font-weight: 600; font-size: 15px; color: var(--azul-senal); margin-top: auto; }
.vs-servicios-arquetipo__nota { font-size: 15px; color: var(--tinta-45); margin: var(--sp-6) 0 0; }
/* CUA móvil (2026-08-26): a <=767px las tres láminas componen cada celda
   como una pieza de altura natural —título, microcopy y `Ver servicio →`
   uno tras otro, sin holgura muerta—. `min-height` + `margin-top:auto`
   servían a la fila de escritorio, donde igualan la línea base del enlace
   entre celdas de distinto alto; apilado no igualan nada y sólo abren un
   hueco entre la descripción y su enlace. */
@media (max-width: 767px) {
  .vs-servicios-arquetipo__celda { min-height: 0; }
  .vs-servicios-arquetipo__celda a { margin-top: 0; }
}
@media (min-width: 768px) {
  .vs-servicios-arquetipo--2,
  .vs-servicios-arquetipo--3 { flex-direction: row; }
  .vs-servicios-arquetipo--2 .vs-servicios-arquetipo__celda,
  .vs-servicios-arquetipo--3 .vs-servicios-arquetipo__celda { flex: 1 1 0; min-width: 0; }
  .vs-servicios-arquetipo--1 .vs-servicios-arquetipo__celda { flex-direction: row; align-items: center; gap: var(--sp-8); }
  .vs-servicios-arquetipo--1 .vs-servicios-arquetipo__texto { flex: 0 0 60%; }
  .vs-servicios-arquetipo--1 .vs-servicios-arquetipo__celda a { margin-top: 0; white-space: nowrap; }
}
/* CUA responsive 768 (corrección de drift, 2026-08-26): con tres
   Servicios a 704px, tres columnas quedan demasiado angostas para
   nombre+microcopy — el `.dc.html` de Turismo mantiene las tres en fila
   apilada hasta 1120px, cada fila con un reparto interno texto/enlace en
   vez del apilado vertical que usa esa misma fila en 375. Scoped al
   arquetipo A: Construcción (arquetipo C, también tres Servicios) no
   pasó por esta CUA y no debe heredar el cambio — sigue en columnas
   desde 768px, sin tocar.

   CUA de tablet (2026-08-26, segunda pasada): la regla anterior devolvía
   el contenedor a `column` pero dejaba viva la declaración `flex: 1 1 0`
   que la regla de fila de >=768px pone en cada celda. En un contenedor
   de columna esa base de 0 se aplica al EJE VERTICAL: las tres celdas
   repartían la altura del contenedor (100px / 3 ≈ 32px cada una) en vez
   de tomar la de su contenido (86px), y con `min-height: 0` desactivando
   el mínimo automático y `overflow: visible`, cada fila desbordaba sobre
   la siguiente — títulos superpuestos, descripciones fuera de su celda,
   `Ver servicio →` desplazado. La comprobación anterior midió el ancho
   (704px) y el número de filas (3) y ambos eran correctos: el fallo
   estaba en la ALTURA de cada fila, que ninguna aserción cubría.

   `flex: 0 0 auto` restituye la altura de contenido y `min-height: auto`
   devuelve el mínimo automático que evita el desbordamiento. La altura
   sigue siendo natural, no fijada: no hay recorte posible. */
@media (min-width: 768px) and (max-width: 1119px) {
  .vs-arq-a .vs-servicios-arquetipo--3 { flex-direction: column; }
  .vs-arq-a .vs-servicios-arquetipo--3 .vs-servicios-arquetipo__celda {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 130px;
    align-items: center;
    gap: var(--sp-6);
    flex: 0 0 auto;
    min-height: auto;
  }
  .vs-arq-a .vs-servicios-arquetipo--3 .vs-servicios-arquetipo__celda a { margin-top: 0; text-align: right; }
}

/* ---------------------------------------------------------------
   29.6. Aplicaciones ("Dónde aporta más valor") — patrón visual común a
         los tres arquetipos y a Retail (decisión del Product Owner,
         VSCR-84, D-VIS-07, 2026-08-26; expediente Parte XI). Ordinal,
         título en énfasis, descripción; un filete dorado entre el H2 y
         el contenido, nunca por celda; dos columnas desde 768px, una
         columna antes. Sin iconos, sin tarjetas ni fondos por celda.

         Sustituye tres composiciones que antes divergían visualmente
         entre sí (filas de ficha en A, columnas paralelas de 2 a 4 en B,
         acento de guión en Retail) y generaliza la que ya usaba C. El
         número de celdas sigue al número real de aplicaciones — Cultura
         tiene 3, no 4, y esta regla no fuerza una cuarta columna vacía:
         un grid de dos columnas con un número impar de celdas simplemente
         deja huérfana la última, sin romper el patrón.

         Escala tipográfica y espaciado alineados al contrato transversal
         D-85-15 (VSCR-85, Claude Design V3.2-B, CUA final aprobada por el
         Product Owner): ancho de módulo 940/640/335 (lo sigue fijando el
         wrapper `__marco-940` de cada arquetipo, sin cambios), ordinal
         11/12/13px, título 17/18/19px y descripción 16/16/17px en
         375/768/1120, con el mismo filete de 2px en `--dorado` (#F0BF2E)
         que ya usaba VSCR-84 — nunca el amarillo del logotipo (#FFD700/
         #D99400). Es el mismo componente que ya consumían A/B/C y Retail:
         un ajuste de tokens, no una reconstrucción. */
.vs-aplicaciones-arquetipo {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--sp-7);
  border-top: 2px solid var(--dorado);
  padding-top: var(--sp-6);
}
.vs-aplicaciones-arquetipo__numero {
  display: block;
  font-family: var(--fuente-mono);
  font-size: 11px;
  color: var(--tinta-30);
  margin-bottom: var(--sp-2);
}
.vs-aplicaciones-arquetipo__celda h3 {
  font-family: var(--fuente-titulos);
  font-weight: 700;
  font-size: 17px;
  line-height: 1.3;
  color: var(--tinta);
  margin: 0 0 var(--sp-2);
}
.vs-aplicaciones-arquetipo__celda p { font-size: 16px; line-height: 1.62; color: var(--tinta-60); margin: 0; }
@media (min-width: 768px) {
  .vs-aplicaciones-arquetipo {
    grid-template-columns: 1fr 1fr;
    gap: var(--sp-9) var(--sp-10);
    padding-top: var(--sp-7);
  }
  .vs-aplicaciones-arquetipo__numero { font-size: 12px; margin-bottom: var(--sp-2); }
  .vs-aplicaciones-arquetipo__celda h3 { font-size: 18px; }
  .vs-aplicaciones-arquetipo__celda p { line-height: 1.65; }
}
@media (min-width: 1120px) {
  .vs-aplicaciones-arquetipo {
    gap: var(--sp-10) var(--sp-11);
    padding-top: var(--sp-8);
  }
  .vs-aplicaciones-arquetipo__numero { font-size: 13px; margin-bottom: var(--sp-3); }
  .vs-aplicaciones-arquetipo__celda h3 { font-size: 19px; }
  .vs-aplicaciones-arquetipo__celda p { font-size: 17px; line-height: 1.7; }
}

/* ---------------------------------------------------------------
   30. Arquetipo A — evidencia jerarquizada propio → demo (VSCR-84 v2)
       Claude Design, CUA aprobada por el Product Owner el 2026-08-21,
       tras el rechazo visual de la V1 (composición general única, §29).

       Turismo y Hospitalidad (maestra) · Gestión de Alquileres ·
       Gastronómico. Namespace propio (`.vs-arq-a`): no comparte clases
       con Retail, S1, About ni con los otros dos arquetipos — la
       frontera visual es tan real como la de slug en PHP.

       Mismo sistema de anchos que Retail, sobre un eje único: cada
       marco es autocontenido (max-width + su propio padding-inline),
       así que 820/940/1160 quedan centrados sobre el mismo eje sin
       necesitar un contenedor exterior compartido.
   --------------------------------------------------------------- */
.vs-arq-a__marco-820 { max-width: calc(820px + var(--sp-6) * 2); margin-inline: auto; padding-inline: var(--sp-6); box-sizing: border-box; }
.vs-arq-a__marco-940 { max-width: calc(940px + var(--sp-6) * 2); margin-inline: auto; padding-inline: var(--sp-6); box-sizing: border-box; }
.vs-arq-a__marco-1160 { max-width: calc(1160px + var(--sp-6) * 2); margin-inline: auto; padding-inline: var(--sp-6); box-sizing: border-box; }
/* CUA responsive 768 (corrección de drift, 2026-08-26): los tres marcos
   nominales (820/940/1160) sólo se diferencian entre sí a partir de
   1120px — por debajo, los tres exceden el viewport y colapsan al mismo
   ancho (viewport − padding), borrando la jerarquía 640/704 que el
   `.dc.html` fija explícitamente en su lámina de 768. La única excepción
   es Servicios, que a 704 necesita más aire que el resto del cuerpo
   editorial: `--servicios` la separa de `__marco-940` sin crear una
   página nueva ni una regla por slug — es del arquetipo, no de la Solución. */
@media (min-width: 768px) and (max-width: 1119px) {
  .vs-arq-a__marco-820,
  .vs-arq-a__marco-940 { max-width: calc(640px + var(--sp-6) * 2); }
  .vs-arq-a__marco-1160 { max-width: calc(704px + var(--sp-6) * 2); }
  .vs-arq-a__marco-940--servicios { max-width: calc(704px + var(--sp-6) * 2); }
}

.vs-arq-a__seccion { padding-block: var(--sp-12); }
.vs-arq-a__seccion--cabecera { padding-top: var(--sp-10); padding-bottom: var(--sp-8); }
.vs-arq-a__seccion--evidencia { padding-top: 0; }
.vs-arq-a__seccion--suave { background: var(--fondo-suave); }
.vs-arq-a__seccion--secundaria { padding-top: var(--sp-11); padding-bottom: var(--sp-14); }
.vs-arq-a__seccion--alcance { padding-top: var(--sp-10); }

.vs-arq-a h1 { font-size: clamp(31px, 3.2vw, 40px); line-height: 1.15; letter-spacing: -.015em; margin: var(--sp-4) 0 var(--sp-6); }
.vs-arq-a h2 { font-size: clamp(24px, 2.4vw, 28px); line-height: 1.22; letter-spacing: -.01em; margin: 0 0 var(--sp-5); }
.vs-arq-a p { font-size: 17px; line-height: 1.62; margin: 0; }
.vs-arq-a .vs-lead { font-size: 19px; line-height: 1.55; max-width: none; }

/* 3 · Fricciones numeradas — pila, no rejilla: admite 3 a 5 ítems sin
   cambiar de composición (regla de propagación M). */
.vs-arq-a__lead-capitulo { color: var(--tinta-60); max-width: 64ch; margin-bottom: var(--sp-9); }
.vs-arq-a__fricciones { display: flex; flex-direction: column; gap: var(--sp-7); }
.vs-arq-a__friccion { display: grid; grid-template-columns: 40px minmax(0, 1fr); gap: 0 var(--sp-6); align-items: baseline; }
.vs-arq-a__friccion-numero { font-family: var(--fuente-mono); font-size: 13px; color: var(--tinta-30); }
.vs-arq-a__friccion strong { font-family: var(--fuente-titulos); font-weight: 700; }
@media (min-width: 768px) {
  .vs-arq-a__friccion { grid-template-columns: 56px minmax(0, 1fr); }
}

/* 4 · Solución — texto 60 / espina de contenido 40. Sin espina en móvil
   propio: se apila debajo, nunca se oculta (todo el contenido del CMS
   sigue siendo el mismo en los tres breakpoints). */
.vs-arq-a__solucion { display: flex; flex-direction: column; gap: var(--sp-9); }
.vs-arq-a__parrafo-secundario { color: var(--tinta-60); margin-top: var(--sp-6); }
.vs-arq-a__espina { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--sp-5); }
.vs-arq-a__espina li { font-size: 16px; line-height: 1.5; border-top: 1px solid var(--borde); padding-top: var(--sp-4); }
.vs-arq-a__espina li.vs-arq-a__espina-item--primero { border-top: 2px solid var(--dorado); }
@media (min-width: 1120px) {
  .vs-arq-a__solucion { display: grid; grid-template-columns: 60fr 40fr; gap: 0 var(--sp-11); align-items: start; }
}

/* 5 · Evidencia secundaria — subordinada y narrada por un puente, nunca
   la segunda casilla de una galería. */
.vs-arq-a__puente { font-family: var(--fuente-titulos); font-weight: 600; font-size: 16px; color: var(--azul-profundo); margin-bottom: var(--sp-6); }

/* 7 · Aplicaciones — patrón visual común A/B/C/Retail, ver
   `.vs-aplicaciones-arquetipo` (D-VIS-07). */

/* 8 · Alcance — visiblemente secundario, filete izquierdo, tinta atenuada. */
.vs-arq-a__alcance { border-left: 3px solid var(--borde); padding-left: var(--sp-8); box-sizing: border-box; }
.vs-arq-a__alcance h2 { font-size: 22px; color: var(--tinta-60); margin-bottom: var(--sp-4); }
.vs-arq-a__alcance p { font-size: 16px; color: var(--tinta-45); }

/* 9 · CTA — franja a sangre, cierre comercial real, 0px hasta el pie. */
.vs-arq-a__cta { background: var(--azul-profundo); padding-block: var(--sp-12); }
.vs-arq-a__cta-cuerpo { display: flex; flex-direction: column; gap: var(--sp-8); }
.vs-arq-a__cta h3 { color: var(--blanco); max-width: 22ch; }
.vs-arq-a__cta p { color: var(--sobre-oscuro); max-width: 56ch; }
@media (min-width: 1120px) {
  .vs-arq-a__cta-cuerpo { flex-direction: row; align-items: center; justify-content: space-between; gap: var(--sp-14); }
}

@media (max-width: 767px) {
  .vs-arq-a .vs-lead { font-size: 17px; }
  .vs-arq-a p { font-size: 16px; }
  .vs-arq-a__seccion { padding-block: var(--sp-9); }
  .vs-arq-a__seccion--evidencia { padding-top: 0; }
  .vs-arq-a__seccion--secundaria { padding-top: var(--sp-9); padding-bottom: var(--sp-9); }
  .vs-arq-a__marco-1160 .vs-matterport { margin-inline: calc(var(--sp-6) * -1); }
  /* CUA responsive 375 (corrección de drift, 2026-08-26): la evidencia
     secundaria (demo) sólo tenía el trato a sangre de la principal — el
     `.dc.html` pone ambas a los 375px completos del viewport a este
     corte, sin excepción; la jerarquía la da la altura, no el margen. */
  .vs-arq-a__marco-820 .vs-matterport { margin-inline: calc(var(--sp-6) * -1); }
  /* Altura, no margen: propio ≈250px (3/2), demo ≈211px (16/9) a 375px
     de ancho — el 1/1 heredado del componente compartido (VSCR-07K)
     dejaba el demo casi tan alto como ancho, muy por encima de lo
     aprobado. Scoped a A: el resto de los llamantes de `.vs-matterport`
     (Retail, S1, Proyecto, Biblioteca) conserva su 4/3 y 1/1 de siempre. */
  .vs-arq-a .vs-matterport { aspect-ratio: 3 / 2; }
  .vs-arq-a .vs-matterport--demo { aspect-ratio: 16 / 9; }
  .vs-arq-a__cta .vs-boton { width: 100%; text-align: center; }
}

/* ---------------------------------------------------------------
   31. Arquetipo B — dos estados, no dos visores equivalentes (VSCR-84 v2)
       Seguros (maestra) · Cultura · Eventos. La jerarquía es dimensional
       (1160 frente a 414), nunca cromática — la pestaña de procedencia
       de `_matterport.php` es la misma para ambos, ya sea que compartan
       origen demostrativo o no.
   --------------------------------------------------------------- */
.vs-arq-b__marco-820 { max-width: calc(820px + var(--sp-6) * 2); margin-inline: auto; padding-inline: var(--sp-6); box-sizing: border-box; }
.vs-arq-b__marco-940 { max-width: calc(940px + var(--sp-6) * 2); margin-inline: auto; padding-inline: var(--sp-6); box-sizing: border-box; }
.vs-arq-b__marco-1160 { max-width: calc(1160px + var(--sp-6) * 2); margin-inline: auto; padding-inline: var(--sp-6); box-sizing: border-box; }
/* CUA responsive 768 (corrección de drift, 2026-08-26): mismo hallazgo
   que el arquetipo A — los marcos nominales colapsan al mismo ancho por
   debajo de 1120px. `--servicios` separa esa sección de `__marco-940`
   (que también sirve a la columna de texto del problema y a Aplicaciones,
   ambas a 640) sin crear una regla por slug. */
@media (min-width: 768px) and (max-width: 1119px) {
  .vs-arq-b__marco-820,
  .vs-arq-b__marco-940 { max-width: calc(640px + var(--sp-6) * 2); }
  .vs-arq-b__marco-1160 { max-width: calc(704px + var(--sp-6) * 2); }
  .vs-arq-b__marco-940--servicios { max-width: calc(704px + var(--sp-6) * 2); }
}

.vs-arq-b__seccion { padding-block: var(--sp-12); }
.vs-arq-b__seccion--cabecera { padding-top: var(--sp-10); padding-bottom: var(--sp-8); }
.vs-arq-b__seccion--evidencia { padding-top: 0; }
.vs-arq-b__seccion--suave { background: var(--fondo-suave); }
.vs-arq-b__seccion--alcance { padding-top: var(--sp-10); }

.vs-arq-b h1 { font-size: clamp(31px, 3.2vw, 40px); line-height: 1.15; letter-spacing: -.015em; margin: var(--sp-4) 0 var(--sp-6); }
.vs-arq-b h2 { font-size: clamp(24px, 2.4vw, 28px); line-height: 1.22; letter-spacing: -.01em; margin: 0 0 var(--sp-5); }
.vs-arq-b p { font-size: 17px; line-height: 1.62; margin: 0 0 var(--sp-5); }
.vs-arq-b .vs-lead { font-size: 19px; line-height: 1.55; max-width: none; }

/* Etiqueta de estado — bajo el visor, no dentro: legible sin depender del
   badge de procedencia, y sin duplicar disclosure. */
.vs-arq-b__estado { display: block; font-family: var(--fuente-mono); font-size: 12px; letter-spacing: .1em; color: var(--tinta-45); margin-top: var(--sp-4); }
.vs-arq-b__estado-bloque { display: flex; flex-direction: column; gap: var(--sp-2); margin-top: var(--sp-4); }
.vs-arq-b__evidencia-2-nota { font-size: 15px; color: var(--tinta-45); }
.vs-arq-b__evidencia-2-intro { color: var(--tinta-60); font-size: 16px; margin-bottom: var(--sp-4); }

/* 3 · Problema — el capítulo se apila SIEMPRE (texto, luego Estado 02),
   en los tres anchos. Decisión del Product Owner (VSCR-84, D-VIS-07,
   2026-08-26): sustituye el grid 486fr/414fr de escritorio que fijaba el
   `.dc.html` histórico — con ese grid, el Estado 02 quedaba forzado a
   ~414px, demasiado pequeño para explorar un recorrido 3D, y sus
   controles internos de Matterport competían por ese mismo espacio
   angosto al abrir el visor. La evidencia sigue subordinada al Estado
   01 por tamaño (máximo 820, nunca a sangre) y por posición (bajo el
   texto, nunca al lado), no por ser una miniatura. */
.vs-arq-b__problema { display: flex; flex-direction: column; gap: var(--sp-9); }
.vs-arq-b__problema-texto { max-width: 640px; }
.vs-arq-b__problema-texto p:first-child { color: var(--tinta); }
.vs-arq-b__problema-texto p { color: var(--tinta-60); }
.vs-arq-b__problema-texto p:first-of-type strong { color: var(--tinta); }
.vs-arq-b__problema-evidencia { max-width: 820px; width: 100%; margin-inline: auto; }

/* 4 · Solución + ficha de datos — 2×2, etiqueta en ámbar-texto. */
.vs-arq-b__ficha { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-7) var(--sp-11); border-top: 2px solid var(--dorado); padding-top: var(--sp-7); margin-top: var(--sp-7); }
.vs-arq-b__ficha-item strong { display: block; font-family: var(--fuente-mono); font-size: 12px; letter-spacing: .1em; color: #8A5E00; margin-bottom: var(--sp-2); }
.vs-arq-b__ficha-item { font-size: 16px; line-height: 1.55; color: var(--tinta); }
@media (max-width: 767px) {
  .vs-arq-b__ficha { grid-template-columns: 1fr; }
}

/* 6 · Aplicaciones — patrón visual común A/B/C/Retail, ver
   `.vs-aplicaciones-arquetipo` (D-VIS-07). */

/* 7 · Alcance. */
.vs-arq-b__alcance { border-left: 3px solid var(--borde); padding-left: var(--sp-8); box-sizing: border-box; }
.vs-arq-b__alcance h2 { font-size: 22px; color: var(--tinta-60); margin-bottom: var(--sp-4); }
.vs-arq-b__alcance p { font-size: 16px; color: var(--tinta-45); margin: 0; }

/* 8 · CTA. */
.vs-arq-b__cta { background: var(--azul-profundo); padding-block: var(--sp-12); }
.vs-arq-b__cta-cuerpo { display: flex; flex-direction: column; gap: var(--sp-8); }
.vs-arq-b__cta h3 { color: var(--blanco); max-width: 22ch; }
.vs-arq-b__cta p { color: var(--sobre-oscuro); max-width: 56ch; margin: 0; }
@media (min-width: 1120px) {
  .vs-arq-b__cta-cuerpo { flex-direction: row; align-items: center; justify-content: space-between; gap: var(--sp-14); }
}

@media (max-width: 767px) {
  .vs-arq-b .vs-lead { font-size: 17px; }
  .vs-arq-b p { font-size: 16px; }
  .vs-arq-b__seccion { padding-block: var(--sp-9); }
  .vs-arq-b__seccion--evidencia { padding-top: 0; }
  .vs-arq-b__marco-1160 .vs-matterport { margin-inline: calc(var(--sp-6) * -1); }
  /* CUA móvil (2026-08-26): la lámina 375 fija dos alturas distintas y
     esa diferencia ES la jerarquía del arquetipo —el estado 01 a sangre
     375×250 (3/2), el estado 02 dentro del margen editorial y ≈16/9
     (333×187)—. Heredaban ambos el 1/1 del componente compartido
     (VSCR-07K), que los dejaba casi cuadrados y del mismo peso: la
     subordinación del estado 02 desaparecía. Scoped a B; el resto de
     los llamantes de `.vs-matterport` conserva su 4/3 y su 1/1. */
  .vs-arq-b .vs-matterport { aspect-ratio: 3 / 2; }
  .vs-arq-b__problema-evidencia .vs-matterport { aspect-ratio: 16 / 9; }
  .vs-arq-b__cta .vs-boton { width: 100%; text-align: center; }
}

/* ---------------------------------------------------------------
   32. Arquetipo C — una sola evidencia, protagonista (VSCR-84 v2)
       Inmobiliario (maestra) · Construcción. Único arquetipo con un
       momento a sangre: se justifica porque no hay segunda pieza que
       proteger. Rail de etiqueta al margen en vez de encabezado de
       sección — el mismo recurso resuelve Problema y Solución.
   --------------------------------------------------------------- */
.vs-arq-c__marco-820 { max-width: calc(820px + var(--sp-6) * 2); margin-inline: auto; padding-inline: var(--sp-6); box-sizing: border-box; }
.vs-arq-c__marco-940 { max-width: calc(940px + var(--sp-6) * 2); margin-inline: auto; padding-inline: var(--sp-6); box-sizing: border-box; }
.vs-arq-c__marco-1160 { max-width: calc(1160px + var(--sp-6) * 2); margin-inline: auto; padding-inline: var(--sp-6); box-sizing: border-box; }
/* CUA técnica final A/B/C (2026-08-26): C nunca recibió el estrechamiento
   de tablet que A y B ya tienen desde la Parte VI — su editorial (820/940
   sin modificador) seguía colapsando al ancho completo del viewport menos
   padding (736px) en vez de los 640px que fijan las láminas 768 para
   apertura, afirmaciones, rail de problema/solución, Aplicaciones y
   Alcance. Servicios, el único componente-tabla de C, necesita el mismo
   704 que ya usan A y B — de ahí el modificador `--servicios`, añadido
   ahora también a la vista de C. */
@media (min-width: 768px) and (max-width: 1119px) {
  .vs-arq-c__marco-820,
  .vs-arq-c__marco-940 { max-width: calc(640px + var(--sp-6) * 2); }
  .vs-arq-c__marco-940--servicios { max-width: calc(704px + var(--sp-6) * 2); }
}

.vs-arq-c__seccion { padding-block: var(--sp-12); }
.vs-arq-c__seccion--cabecera { padding-top: var(--sp-10); padding-bottom: var(--sp-8); }
.vs-arq-c__seccion--evidencia { padding-top: 0; }
.vs-arq-c__seccion--suave { background: var(--fondo-suave); }
.vs-arq-c__seccion--alcance { padding-top: var(--sp-10); }

/* Evidencia única a sangre — el único caso del sistema sin `.vs-seccion`
   ni marco: ocupa el ancho completo del viewport a propósito. */
.vs-arq-c__evidencia-sangre { padding: 0; }
.vs-arq-c__evidencia-sangre .vs-matterport { aspect-ratio: 21 / 9; border-radius: 0; }
/* CUA de fidelidad (2026-08-26): las láminas aprobadas dan 768×420 a
   tablet y 375×260 a móvil para esta misma portada a sangre. El 4/3 y
   el 3/4 anteriores venían del componente compartido y a 375px la
   dejaban en 500px de alto —casi el doble de lo aprobado—, empujando
   fuera de pantalla la primera afirmación del arquetipo. El corte pasa
   además de 1023px a los 1119px del sistema de los tres arquetipos. */
@media (min-width: 768px) and (max-width: 1119px) { .vs-arq-c__evidencia-sangre .vs-matterport { aspect-ratio: 64 / 35; } }
@media (max-width: 767px) { .vs-arq-c__evidencia-sangre .vs-matterport { aspect-ratio: 375 / 260; } }
/* La foto va a sangre, pero el `.dc.html` alinea el título y el CTA de su
   portada al mismo eje de 1160 que el resto de la página — no al borde
   real del viewport. Microgate de CUA desktop (2026-08-25). */
@media (min-width: 1120px) {
  .vs-arq-c__evidencia-sangre .vs-matterport__estado-inicial { max-width: 1160px; margin-inline: auto; }
}
/* CUA técnica final A/B/C (2026-08-26): la lámina 768 aplica el mismo
   principio a su propio eje (704, el ancho de "componente" de esa
   franja) — la portada sigue a sangre, sólo la fila identidad/CTA se
   centra. Sin esto, esa fila quedaba con el padding parejo de la regla
   general (§ portada A/B/C, `.vs-matterport__estado-inicial`) en vez de
   centrada como en la lámina. */
@media (min-width: 768px) and (max-width: 1119px) {
  .vs-arq-c__evidencia-sangre .vs-matterport__estado-inicial { max-width: 704px; margin-inline: auto; }
}

.vs-arq-c h1 { font-size: clamp(31px, 3.2vw, 40px); line-height: 1.15; letter-spacing: -.015em; margin: var(--sp-4) 0 var(--sp-6); }
.vs-arq-c h2 { font-size: clamp(24px, 2.4vw, 28px); line-height: 1.22; letter-spacing: -.01em; margin: 0 0 var(--sp-5); }
.vs-arq-c p { font-size: 17px; line-height: 1.62; margin: 0 0 var(--sp-5); }
.vs-arq-c p:last-child { margin-bottom: 0; }
.vs-arq-c .vs-lead { font-size: 19px; line-height: 1.55; max-width: none; }

/* 3/6 · Líneas de afirmación — el recurso propio del arquetipo, sólo dos
   por página (regla M): ningún tercer bloque de afirmación se añade. */
.vs-arq-c__afirmacion p { font-family: var(--fuente-titulos); font-weight: 700; font-size: clamp(22px, 2.4vw, 28px); line-height: 1.28; color: var(--tinta); max-width: 34ch; margin: 0; }
.vs-arq-c__afirmacion--cierre { border-top: 1px solid var(--borde); padding-top: var(--sp-8); }
.vs-arq-c__afirmacion--cierre p { max-width: 38ch; }
.vs-arq-c__afirmacion .vs-arq-c__afirmacion-nota { font-family: var(--fuente-texto); font-weight: 400; font-size: 17px; color: var(--tinta-60); max-width: 64ch; margin: var(--sp-4) 0 0; }

/* 4/5 · Rail de etiqueta al margen — se desmonta a kicker sobre el H2 por
   debajo de 1120px (no hay espacio de margen que proteger). */
.vs-arq-c__rail { display: flex; flex-direction: column; gap: var(--sp-4); }
.vs-arq-c__rail-etiqueta { font-family: var(--fuente-mono); font-size: 12px; letter-spacing: .14em; color: #8A5E00; border-top: 2px solid var(--dorado); padding-top: var(--sp-4); }
@media (min-width: 1120px) {
  .vs-arq-c__rail { display: grid; grid-template-columns: 200px minmax(0, 1fr); gap: 0 var(--sp-11); }
  .vs-arq-c__rail-etiqueta { padding-top: var(--sp-4); }
}

/* 8 · Aplicaciones — patrón visual común A/B/C/Retail, ver
   `.vs-aplicaciones-arquetipo` (D-VIS-07). */

/* 9 · Alcance. */
.vs-arq-c__alcance { border-left: 3px solid var(--borde); padding-left: var(--sp-8); box-sizing: border-box; }
.vs-arq-c__alcance h2 { font-size: 22px; color: var(--tinta-60); margin-bottom: var(--sp-4); }
.vs-arq-c__alcance p { font-size: 16px; color: var(--tinta-45); margin: 0; }

/* 10 · CTA. */
.vs-arq-c__cta { background: var(--azul-profundo); padding-block: var(--sp-12); }
.vs-arq-c__cta-cuerpo { display: flex; flex-direction: column; gap: var(--sp-8); }
.vs-arq-c__cta h3 { color: var(--blanco); max-width: 22ch; }
.vs-arq-c__cta p { color: var(--sobre-oscuro); max-width: 56ch; margin: 0; }
@media (min-width: 1120px) {
  .vs-arq-c__cta-cuerpo { flex-direction: row; align-items: center; justify-content: space-between; gap: var(--sp-14); }
}

@media (max-width: 767px) {
  .vs-arq-c .vs-lead { font-size: 17px; }
  .vs-arq-c p { font-size: 16px; }
  .vs-arq-c__seccion { padding-block: var(--sp-9); }
  .vs-arq-c__seccion--evidencia { padding-top: 0; }
  .vs-arq-c__cta .vs-boton { width: 100%; text-align: center; }
}

/* ---------------------------------------------------------------
   30. VSCR-85 — Familia Servicios (S2/S3/S4) e Índices (Claude Design
       V3.2-B, CUA final aprobada por el Product Owner, 2026-08-29).
       ----------------------------------------------------------------
   30.1. Familia Servicios — shell compartido por S2, S3 y S4. Mismos
         tres anchos que ya usa S1 (820 editorial / 940 componente /
         1160 visual): no se inventa una cuarta escala. */
/* VSCR-88 · PO-IDX-01 (2026-09-09): margen lateral responsive 140/32/20.
   La fórmula anterior congelaba el inset en `--sp-6` (16px) por debajo del
   `max-width`, que es el margen reservado a viewports <360px, no el del
   contrato: `Familia Indices.dc.html` F.3 fija 140 · 32 · 20 y remite a
   `Familia Servicios.dc.html` A.2/A.6, que lo declara para todo el sistema.
   Se expresa como custom property —mismo patrón que `.vs-indice-sol`, ya en
   producción y conforme— para que el margen escale con la banda existente de
   768px sin inventar breakpoint. A 1440 el resultado no cambia: 1160/140. */
.vs-fam__marco { --fam-margen: var(--sp-7); max-width: calc(1160px + var(--fam-margen) * 2); margin-inline: auto; padding-inline: var(--fam-margen); box-sizing: border-box; }
@media (min-width: 768px) { .vs-fam__marco { --fam-margen: var(--sp-10); } }
/* PO-SERV-FAMILY-02/03 (auditoría transversal, 2026-08-31): el editorial no
   llevaba `margin-inline: auto` — a diferencia de `.vs-s1__editorial` quedaba
   pegado al borde izquierdo del marco en vez de centrado, el drift visual que
   reportó el Product Owner. `.vs-fam__estructurado` es el nivel «componente»
   (940px) que ya usa S1 para Proceso: Proceso y D-85-15 lo adoptan aquí para
   dejar de heredar 820px por accidente de anidado. */
/* VSCR-88 · PO-IDX-01 · Lote C2 (2026-09-10): `Familia Servicios.dc.html`
   A.2/A.6 fija el ancho editorial en 820 → 640 → 335, y los tres artboards de
   768 de S2, S3-A y S4 lo renderizan a 640 —S2 lo rotula literalmente
   «editorial 640 / evidencia 704»—. Sin el escalón, en tablet el editorial se
   estiraba al ancho entero del marco. `.vs-fam__estructurado` (940) no
   necesita regla: el marco ya lo clampa a los 704 del nivel «compuesto», y a
   375 ambos los clampa a 335. Misma banda que los marcos de los arquetipos. */
.vs-fam__editorial { max-width: 820px; margin-inline: auto; }
@media (min-width: 768px) and (max-width: 1119px) { .vs-fam__editorial { max-width: 640px; } }
.vs-fam__estructurado { max-width: 940px; margin-inline: auto; }
.vs-fam__seccion { padding-block: var(--sp-14); }
.vs-fam__seccion--suave { background: var(--fondo-suave); }

/* Capítulos de la Familia Servicios (VSCR-85 / V3.2-B) — la anatomía
   aprobada sobre los H2 reales del CMS (D-85-06): eyebrow opcional,
   título de capítulo, y dos tratamientos de lista propios (entregables y
   proceso numerado). El componente «Dónde aporta más valor» no se
   redefine aquí: reutiliza `.vs-aplicaciones-arquetipo` de D-85-15. */
.vs-fam__capitulo { padding-block: var(--sp-11); border-top: 1px solid var(--borde); }
.vs-fam__capitulo:first-of-type { border-top: 0; }
.vs-fam__capitulo-intro { padding-block: var(--sp-11) 0; }
.vs-fam__capitulo-eyebrow {
  display: block; font-family: var(--fuente-mono); font-size: 13px;
  letter-spacing: .08em; text-transform: uppercase;
  color: var(--azul-senal); margin-bottom: var(--sp-3);
}
.vs-fam__capitulo h2 { font-family: var(--fuente-titulos); font-weight: 700; font-size: 24px; margin: 0 0 var(--sp-6); }
.vs-fam__entregables { margin: var(--sp-6) 0 0; padding-left: var(--sp-7); }
.vs-fam__entregables li { margin-bottom: var(--sp-4); }
/* «Ficha de entregables» (S2 §Qué se entrega, Parte XXII): rejilla con
   filete ámbar de apertura, sin etiqueta — el CMS real no separa etiqueta
   de descripción. 1 col a 375 (base), 2×2 desde 768, gaps más amplios
   desde 1120 — igual que `Servicio S2 Documentacion 3D Construccion.dc.html`. */
.vs-fam__ficha { display: flex; flex-direction: column; gap: var(--sp-6); border-top: 2px solid var(--dorado); padding-top: var(--sp-5); margin-top: var(--sp-6); }
.vs-fam__ficha-item { font-size: 16px; line-height: 1.62; color: var(--tinta); }
@media (min-width: 768px) {
  .vs-fam__ficha { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-8) var(--sp-10); padding-top: var(--sp-6); }
}
@media (min-width: 1120px) {
  .vs-fam__ficha { gap: var(--sp-9) var(--sp-11); padding-top: var(--sp-7); }
  .vs-fam__ficha-item { font-size: 17px; line-height: 1.7; }
}
/* «Momentos de registro» (VSCR-109, lámina C, C4 · S2): el kicker va en un
   rail con filete dorado a la izquierda —150 px desde 768 y 200 desde 1120
   (I-109-10)— y el capítulo conserva el H2 y la banda de la familia. Cinco
   momentos en dos columnas desde 768, con filete ámbar de apertura como la
   ficha, y una línea de límite al pie. En móvil todo se apila. */
.vs-fam__rail { display: grid; gap: var(--sp-6) var(--sp-11); }
@media (min-width: 768px) { .vs-fam__rail { grid-template-columns: 150px minmax(0, 1fr); } }
@media (min-width: 1120px) { .vs-fam__rail { grid-template-columns: 200px minmax(0, 1fr); } }
.vs-fam__rail-kicker { align-self: start; justify-self: start; padding-top: var(--sp-3); border-top: 2px solid var(--dorado); font-family: var(--fuente-mono); font-size: 12px; letter-spacing: .14em; color: #8A5E00; }
.vs-fam__rail-cuerpo > p { font-size: 16px; line-height: 1.7; color: var(--tinta); }
.vs-fam__momentos { display: grid; gap: 22px var(--sp-10); margin-top: 22px; padding-top: 18px; border-top: 2px solid var(--dorado); }
@media (min-width: 768px) { .vs-fam__momentos { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.vs-fam__momento p { font-size: 16px; line-height: 1.65; color: var(--tinta); }
.vs-fam__momento .vs-fam__momento-etiqueta { margin-bottom: 6px; font-family: var(--fuente-mono); font-size: 12px; letter-spacing: .1em; line-height: 1.5; color: #8A5E00; }
.vs-fam__rail-cuerpo > .vs-fam__momentos-limite { margin-top: var(--sp-7); font-size: 14px; line-height: 1.6; color: var(--tinta-60); }
@media (min-width: 1120px) {
  .vs-fam__rail-cuerpo > p,
  .vs-fam__momento p { font-size: 17px; }
  .vs-fam__rail-cuerpo > .vs-fam__momentos-limite { font-size: 14px; }
  .vs-fam__momento .vs-fam__momento-etiqueta { font-size: 12px; }
}
/* Proceso — misma gramática visual que `.vs-s1__proceso` (PO-SERV-FAMILY-03,
   auditoría transversal 2026-08-31): rail vertical continuo por el borde
   izquierdo del `<li>`, marcador cuadrado de 34px centrado sobre el rail vía
   `translateX(-50%)`, navy por defecto. Duplicado a propósito en vez de
   compartir clase con S1 (§7 de la ronda: no tocar S1 si no hace falta). El
   ámbar identifica el paso que ocurre físicamente en el sitio del cliente —
   declarado por página en `servicioFamiliaCapitulos()` (clave `acento`),
   nunca decorativo ni por excepción de slug en esta vista. */
.vs-fam__proceso { margin: var(--sp-6) 0 0; padding: 0 0 0 16px; list-style: none; }
.vs-fam__proceso-paso {
  position: relative;
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--sp-5);
  padding: 0 0 var(--sp-8) var(--sp-7);
  border-left: 1.5px solid var(--borde);
}
.vs-fam__proceso-paso:last-child { border-left-color: transparent; padding-bottom: 0; }
.vs-fam__proceso-numero {
  position: absolute;
  left: 0;
  top: 0;
  transform: translateX(-50%);
  width: 34px;
  height: 34px;
  display: grid;
  place-items: center;
  background: var(--azul-profundo);
  font-family: var(--fuente-mono);
  font-size: 12px;
  color: var(--blanco);
  border-radius: 0;
}
.vs-fam__proceso-paso--acento .vs-fam__proceso-numero { background: var(--dorado); color: var(--tinta); }
.vs-fam__proceso-cuerpo { grid-column: 1 / -1; }

/* «Qué aporta el aire» con los 5 aportes reales conservados (S3,
   PO-S3-01): prosa corrida en vez de bullets, con un párrafo
   introductorio fijo (copy literal de la Variante A) — sin título en
   negrita por ítem, el CMS no separa etiqueta de descripción. */
.vs-fam__lista-prosa-intro { font-size: 16px; line-height: 1.65; color: var(--tinta); margin: 0 0 var(--sp-4); }
.vs-fam__lista-prosa-item { font-size: 16px; line-height: 1.62; color: var(--tinta-60); margin: 0 0 var(--sp-3); }
.vs-fam__lista-prosa-item:last-child { margin-bottom: 0; }

/* «Dos entregables, dos usos» (S3 Entregables, PO-S3-02): apilado con
   divisor en móvil/tablet, dos columnas desde 1120px — igual a los tres
   cortes de la Variante A (768 y 375 comparten el tratamiento apilado;
   sólo el corte 1440 pasa a dos columnas lado a lado). */
.vs-fam__comparativo { display: flex; flex-direction: column; border-top: 2px solid var(--dorado); padding-top: var(--sp-6); margin-top: var(--sp-6); }
.vs-fam__comparativo-columna { padding-bottom: var(--sp-7); margin-bottom: var(--sp-7); border-bottom: 1px solid var(--borde); }
.vs-fam__comparativo-columna:last-child { padding-bottom: 0; margin-bottom: 0; border-bottom: 0; }
.vs-fam__comparativo-eyebrow { color: #8A5E00; letter-spacing: .1em; font-size: 12px; margin: 0 0 var(--sp-3); }
.vs-fam__comparativo-columna h3 { font-family: var(--fuente-titulos); font-weight: 700; font-size: 18px; margin: 0 0 var(--sp-3); }
.vs-fam__comparativo-columna p { font-size: 16px; line-height: 1.65; color: var(--tinta-60); margin: 0 0 var(--sp-4); }
.vs-fam__comparativo-columna p:last-child { margin-bottom: 0; }
@media (min-width: 1120px) {
  .vs-fam__lista-prosa-intro,
  .vs-fam__lista-prosa-item { font-size: 17px; line-height: 1.7; }
  .vs-fam__comparativo { flex-direction: row; gap: 0 var(--sp-10); padding-top: var(--sp-7); }
  .vs-fam__comparativo-columna { flex: 1; padding-bottom: 0; margin-bottom: 0; border-bottom: 0; padding-right: var(--sp-10); }
  .vs-fam__comparativo-columna + .vs-fam__comparativo-columna { padding-left: var(--sp-10); padding-right: 0; border-left: 1px solid var(--borde); }
  .vs-fam__comparativo-columna h3 { font-size: 19px; }
  .vs-fam__comparativo-columna p { font-size: 17px; line-height: 1.7; }
}
@media (min-width: 768px) {
  .vs-fam__capitulo { padding-block: var(--sp-13); }
  .vs-fam__capitulo h2 { font-size: 28px; }
}
.vs-fam__seccion--cabecera { padding-top: var(--sp-11); padding-bottom: var(--sp-9); }
.vs-fam__seccion--continua { padding-top: 0; }
/* La clase va en el propio `<h1 class="vs-fam">`, no en un ancestro — el
   selector es la clase a secas, no un combinador descendiente (bug real
   encontrado por QA en Chrome: sin esto, el h1 base de 32px ganaba y el
   H1 nunca escalaba a 40px en escritorio). */
h1.vs-fam { font-size: clamp(31px, 3.2vw, 40px); line-height: 1.15; letter-spacing: -.015em; margin: var(--sp-4) 0 var(--sp-6); }
.vs-fam__resumen { font-size: 17px; line-height: 1.65; color: var(--tinta-60); max-width: 62ch; margin: 0; }

/* Evidencia — un solo slot por página; su interior depende del tipo de
   evidencia (visor Matterport en S2/S4, audiovisual en S3), pero el
   marco, la relación de aspecto y la pestaña de procedencia son
   comunes a los tres. */
.vs-fam__evidencia { position: relative; aspect-ratio: 16 / 9; background: var(--tinta); overflow: hidden; }
.vs-fam__evidencia img { width: 100%; height: 100%; object-fit: cover; display: block; }
@media (max-width: 767px) {
  /* 375×211 a sangre (VSCR-85 §8, contrato E2): la evidencia rompe el
     padding del marco en vez de quedar recuadrada, mismo criterio que ya
     usa `.vs-arq-c__evidencia-sangre`. La secundaria de S4 no hereda esto
     — sigue subordinada, nunca a sangre. */
  /* VSCR-88 · PO-IDX-02 (2026-09-10): misma corrección que en Retail — la
     sangría sigue al margen del marco, no a un valor fijo. Hoy sólo la usa S3. */
  .vs-fam__evidencia { aspect-ratio: 375 / 211; margin-inline: calc(-1 * var(--fam-margen)); }
  .vs-fam__evidencia-secundaria .vs-fam__evidencia { margin-inline: 0; }
}
@media (min-width: 768px) and (max-width: 1119px) { .vs-fam__evidencia { aspect-ratio: 704 / 396; } }

/* S4 — segunda evidencia, subordinada por tamaño y posición, nunca por
   procedencia distinta (ambas son demostrativas). Vive dentro de
   `.vs-fam__editorial` (820) desde la apertura de S4 (2026-08-31): ya no
   necesita su propio max-width, sólo fijar la relación de aspecto —a
   diferencia de la evidencia principal, la secundaria se queda en 16:9
   en los tres cortes, nunca cambia a 704:396 ni a 375:211. */
.vs-fam__evidencia-secundaria .vs-fam__evidencia { aspect-ratio: 16 / 9; }

/* «El mismo formato sostiene un espacio comercial…» (S4, puente hacia la
   evidencia secundaria): una sola línea destacada, no un párrafo de
   cuerpo — mismo peso que un lead corto, nunca tan grande como un H2. */
.vs-fam__puente { font-family: var(--fuente-titulos); font-weight: 600; font-size: 17px; color: var(--azul-profundo); margin: 0 0 var(--sp-5); }

/* «Vos decidís qué aparece y dónde» (S4 §4, PO ratificado): mismo grid de
   `.vs-fam__ficha` con una etiqueta mono por ítem — único caso de la
   Familia Servicios con etiqueta, porque aquí sí hay cuatro verbos reales
   que nombrar, no una descripción sin título que separar. */
.vs-fam__ficha-etiqueta { color: #8A5E00; letter-spacing: .1em; font-size: 12px; margin: 0 0 var(--sp-2); }
.vs-fam__ficha--etiquetada .vs-fam__ficha-item p:last-child { margin: 0; }

/* Proceso con título propio por paso (S4 §6): el `<strong>` se separa del
   resto por el salto de línea del propio marcado (colapsa a un espacio),
   sin necesidad de un separador explícito en el copy. */
.vs-fam__proceso-titulo { font-family: var(--fuente-titulos); font-weight: 700; color: var(--tinta); display: block; margin-bottom: var(--sp-2); }

/* S3 — slot audiovisual E2 (contrato de la Variante A, VSCR-85; D-2 y
   PO-01, VSCR-15C §3.3): póster con la fotografía aérea propia, ficha con
   kicker, título y botón ámbar de 56 px, y nota de procedencia. El video
   (`youtube-nocookie.com`) se monta encima del póster sólo al pulsar, así
   que la fotografía queda como respaldo si el reproductor no carga.

   Dos niveles a propósito: `__marco` (imagen + cortina, posicionado) queda
   fuera de `__nota`, para que la cortina se ancle al pie de la imagen desde
   768 px sin arrastrar la nota, y en el flujo normal, apilada debajo, a
   375 px: cortina superpuesta en escritorio y tablet, bloque propio en
   móvil. `--pendiente` es la composición de espera si faltara el póster. */
.vs-fam__audiovisual__marco { position: relative; }
.vs-fam__audiovisual__cortina {
  display: flex; flex-direction: column; align-items: flex-start; gap: var(--sp-4);
  padding: var(--sp-6) 0 0;
}
/* `display: flex` le ganaría al atributo `hidden` (lección de VSCR-85): el
   script lo usa para retirar la ficha cuando el video ya está montado. */
.vs-fam__audiovisual__cortina[hidden] { display: none; }
.vs-fam__audiovisual__eyebrow { color: #8A5E00; letter-spacing: .1em; font-size: 12px; margin: 0; }
.vs-fam__audiovisual__titulo { font-family: var(--fuente-titulos); font-weight: 700; font-size: 19px; color: var(--tinta); margin: var(--sp-2) 0 4px; }
.vs-fam__audiovisual__subtitulo { font-size: 15px; color: var(--tinta-60); margin: 0; }
.vs-fam__audiovisual__boton { min-height: 56px; }
.vs-fam__audiovisual__iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; z-index: 1; }
.vs-fam__audiovisual__nota {
  display: flex; flex-direction: column; gap: var(--sp-2);
  margin: var(--sp-4) 0 0; font-size: 14px; color: var(--tinta-45);
}
@media (min-width: 768px) {
  .vs-fam__audiovisual__cortina {
    position: absolute; inset: auto 0 0 0; z-index: 1;
    flex-direction: row; align-items: flex-end; justify-content: space-between; gap: var(--sp-8);
    padding: var(--sp-8);
    /* Mismo tono de velo que ya usa `.vs-matterport__inicial::after` para
       leer texto sobre una portada — no el navy de fondo de sección
       (`--azul-profundo-900`), que es un color de superficie, no de velo. */
    background: linear-gradient(to top, rgba(10, 14, 30, .88), rgba(10, 14, 30, 0) 62%);
  }
  .vs-fam__audiovisual__eyebrow { color: var(--dorado); }
  .vs-fam__audiovisual__titulo { color: var(--blanco); font-size: 21px; }
  .vs-fam__audiovisual__subtitulo { color: var(--sobre-oscuro); }
  .vs-fam__audiovisual__nota { flex-direction: row; justify-content: space-between; margin-top: var(--sp-3); }
}

/* Los capítulos de cuerpo (Qué se documenta, Proceso, Alcance…) no tienen
   componente propio: reutilizan `componerPaginaEditorial()` + `.vs-editorial`
   —el mismo rail título/cuerpo que ya usan About y las Soluciones sin
   arquetipo— dentro de `.vs-pagina-editorial`, sin envolverlos en
   `.vs-fam__componente`. */

/* 30.2 · Índice Servicios — cuatro cards, procedencia por pestaña
         (D-85-08/09; reutiliza `.vs-matterport__etiqueta`, nunca una
         segunda gramática de color).

   PO-INDEX-SERV-02 (2026-09-02): marco propio de 1160px — misma fórmula que
   `.vs-fam__marco`/`.vs-s1__marco` (1160 + `--sp-6`×2, que en un viewport de
   1440 deja ~140px de margen visual real: (1440−1192)/2 + 16 ≈ 140), en vez
   del `.vs-contenedor` sitewide (1440, margen real 56px) que usaba antes.
   Scoped únicamente a esta superficie — Índice Proyectos y Biblioteca
   siguen con `.vs-contenedor` sin cambios; ver la regla de su CTA más abajo
   en 30.5. El encabezado va flush-left (sin `margin-inline:auto`), no
   centrado: antecede a la rejilla de abajo y debe compartir su borde
   izquierdo, mismo criterio ya usado por `.vs-s1__editorial--flush`. */
/* VSCR-88 · PO-IDX-01 (2026-09-09): margen lateral responsive 140/32/20.
   La fórmula anterior congelaba el inset en `--sp-6` (16px) por debajo del
   `max-width`, que es el margen reservado a viewports <360px, no el del
   contrato: `Familia Indices.dc.html` F.3 fija 140 · 32 · 20 y remite a
   `Familia Servicios.dc.html` A.2/A.6, que lo declara para todo el sistema.
   Se expresa como custom property —mismo patrón que `.vs-indice-sol`, ya en
   producción y conforme— para que el margen escale con la banda existente de
   768px sin inventar breakpoint. A 1440 el resultado no cambia: 1160/140. */
.vs-indice-servicios-marco { --idx-serv-margen: var(--sp-7); max-width: calc(1160px + var(--idx-serv-margen) * 2); margin-inline: auto; padding-inline: var(--idx-serv-margen); box-sizing: border-box; }
@media (min-width: 768px) { .vs-indice-servicios-marco { --idx-serv-margen: var(--sp-10); } }
/* VSCR-88 · PO-IDX-01 (2026-09-09): F.3 fija el encabezado en 820/640/335 y
   el `max-width` fijo sólo resolvía el corte de escritorio — en tablet se
   estiraba al ancho entero del marco. Se estrecha a 640 en la misma banda
   768–1119 que ya usan los marcos editoriales de los arquetipos (`515703c`,
   VSCR-84). A 375 lo clampa el marco, que ya rinde 335. */
.vs-indice-servicios-editorial { max-width: 820px; }
@media (min-width: 768px) and (max-width: 1119px) { .vs-indice-servicios-editorial { max-width: 640px; } }
.vs-indice-servicios { display: grid; grid-template-columns: 1fr; gap: var(--sp-7); }
.vs-indice-servicios__card { display: flex; flex-direction: column; }
.vs-indice-servicios__media { position: relative; aspect-ratio: 16 / 9; background: var(--fondo-suave); overflow: hidden; }
.vs-indice-servicios__media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.vs-indice-servicios__numero { display: block; font-family: var(--fuente-mono); font-size: 12px; color: var(--tinta-30); margin: var(--sp-5) 0 var(--sp-2); }
/* PRR-053: el título de la card vuelve a ser h2 (h1 → h3 saltaba un nivel,
   regresión de VSCR-12C). El aspecto es el del h3 que había: se anulan el
   interlineado, el tracking y el balanceo que el h2 global añade. */
.vs-indice-servicios__card h2 { font-family: var(--fuente-titulos); font-weight: 700; font-size: 20px; line-height: 1.20; letter-spacing: normal; text-wrap: wrap; margin: 0 0 var(--sp-3); }
.vs-indice-servicios__card p { font-size: 16px; line-height: 1.6; color: var(--tinta-60); margin: 0 0 var(--sp-4); }
/* Filete ámbar del enlace de card (Card A, `Familia Indices.dc.html` F.2):
   `.vs-tarjeta-servicio__enlace` es compartida con la card de Servicios de
   Home, que no lleva este filete — se scoped aquí, igual que ya hace
   `.vs-indice-soluciones__card .vs-tarjeta-servicio__enlace` con
   `margin-top`, en vez de tocar la regla base. */
.vs-indice-servicios__card .vs-tarjeta-servicio__enlace { border-bottom: 2px solid var(--dorado); padding-bottom: 3px; }
/* VSCR-109 (P-109-A1): procedencia en prosa de una demo de terceros bajo el
   texto de la card (hoy, S5), separada por un filete fino. */
.vs-indice-servicios__card .vs-indice-servicios__procedencia { margin: 0 0 var(--sp-4); padding-top: var(--sp-3); border-top: var(--borde-estructura); font-size: 13px; line-height: 1.55; color: var(--tinta-60); }
/* VSCR-88 · PO-IDX-01 (2026-09-09): el gap de columna era 28 (`--sp-9`) desde
   768 y no volvía a cambiar, así que incumplía en los dos cortes: F.3 fija
   24/24 en tablet y 32/32 en escritorio, y `Indice Servicios.dc.html` rotula
   «gap 32 · card 564» y «gap 24 · card 340». Con 28 la card medía 566 y 354.
   Se escalona con las mismas bandas que ya usan Proyectos y Biblioteca. */
@media (min-width: 768px) {
  .vs-indice-servicios { grid-template-columns: 1fr 1fr; gap: var(--sp-8); }
}
@media (min-width: 1120px) {
  .vs-indice-servicios { gap: var(--sp-10); }
}
/* VSCR-109 · P-109-B3: con un total impar de Servicios, la última card ocupa
   las dos columnas en formato horizontal (imagen | texto, 50/50). El hueco
   interior es el mismo de la rejilla, así que la imagen conserva el ancho de
   las demás cards. El filete ámbar, que en la card estrecha dibuja el enlace a
   todo su ancho, pasa a la card para seguir corriendo bajo las dos columnas.
   La última fila del texto absorbe el alto sobrante y deja el enlace abajo.
   En móvil no cambia. */
@media (min-width: 768px) {
  .vs-indice-servicios__card--ancha {
    grid-column: 1 / -1;
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    grid-template-rows: auto auto auto auto 1fr;
    column-gap: var(--sp-8);
    align-items: start;
    border-bottom: 2px solid var(--dorado);
    padding-bottom: 3px;
  }
  .vs-indice-servicios__card--ancha > .vs-indice-servicios__media { grid-column: 1; grid-row: 1 / -1; }
  .vs-indice-servicios__card--ancha > :not(.vs-indice-servicios__media) { grid-column: 2; }
  .vs-indice-servicios__card--ancha > .vs-indice-servicios__numero { margin-top: 0; }
  .vs-indice-servicios__card--ancha .vs-tarjeta-servicio__enlace { grid-row: -2; align-self: end; border-bottom: 0; padding-bottom: 0; }
}
@media (min-width: 1120px) {
  .vs-indice-servicios__card--ancha { column-gap: var(--sp-10); }
}

/* 30.3 · Índice Soluciones — V3.3-A.1 «Contenida», CUA aprobada por el
         Product Owner el 2026-08-29. Anatomía D-85-14 intacta: icono →
         firma ámbar → título → descripción → enlace, sin kicker textual.
         Lo que cambia respecto de V3.2-B es la geometría: la card recupera
         caja propia (antes era `display:block` sin fondo, borde ni
         padding) y la página gana su propia retícula, más estrecha que el
         contenedor global, para que el bloque editorial deje de quedar
         suelto contra el margen izquierdo.

         Contrato medido: 1440 → retícula 1160, 3 columnas de 365, gap 32;
         768 → 704, 2 columnas de 340, gap 24; 375 → 335, 1 columna. Los
         anchos de card salen de la retícula, no se fijan a mano.

         Alcance deliberado: estos valores son de ESTA composición, no una
         nueva escala global del sitio. */
.vs-indice-sol {
  --sol-margen: var(--sp-7);
  width: 100%;
  max-width: calc(1160px + 2 * var(--sol-margen));
  margin: 0 auto;
  padding-inline: var(--sol-margen);
}
.vs-indice-sol__encabezado { max-width: 335px; }
.vs-indice-sol__h1 { font-size: 29px; max-width: none; }
p.vs-indice-sol__lead { font-size: 17px; max-width: none; }

.vs-indice-soluciones__tramo { margin-bottom: 36px; }
.vs-indice-soluciones__tramo:last-child { margin-bottom: 0; }
.vs-indice-soluciones__tramo-titulo { font-family: var(--fuente-titulos); font-weight: 700; font-size: 21px; margin: 0 0 var(--sp-2); }
.vs-indice-soluciones__tramo-intro { font-size: 16px; color: var(--tinta-60); margin: 0 0 var(--sp-7); }
.vs-indice-soluciones { display: grid; grid-template-columns: 1fr; gap: var(--sp-7); }

/* La card vuelve a ser una unidad visual: caja blanca con filete fino,
   radio 0 y sin sombra (D-85-14 + V3.3-A.1). `flex` + `margin-top:auto`
   en el enlace lo ancla abajo; los items de la rejilla se estiran, así
   que las alturas quedan igualadas por fila sin JavaScript. */
.vs-indice-soluciones__card {
  display: flex;
  flex-direction: column;
  height: 100%;
  padding: 22px;
  background: var(--blanco);
  border: 1px solid var(--borde);
  border-radius: 0;
  box-shadow: none;
}
.vs-indice-soluciones__icono { display: inline-flex; align-items: center; justify-content: center; width: 30px; height: 30px; color: var(--tinta); }
.vs-indice-soluciones__icono-svg { width: 24px; height: 24px; }
.vs-indice-soluciones__firma { display: block; width: 14px; height: 2px; background: var(--dorado); margin: var(--sp-3) 0 var(--sp-4); }
.vs-indice-soluciones__card h3 { font-family: var(--fuente-titulos); font-weight: 700; font-size: 19px; margin: 0 0 var(--sp-2); }
.vs-indice-soluciones__card p { font-size: 16px; line-height: 1.6; color: var(--tinta-60); margin: 0 0 var(--sp-6); }
.vs-indice-soluciones__card .vs-tarjeta-servicio__enlace { margin-top: auto; }

@media (min-width: 768px) {
  .vs-indice-sol { --sol-margen: var(--sp-10); }
  .vs-indice-sol__encabezado { max-width: 640px; }
  .vs-indice-sol__h1 { font-size: 34px; }
  p.vs-indice-sol__lead { font-size: 18px; }
  .vs-indice-soluciones__tramo { margin-bottom: 44px; }
  .vs-indice-soluciones__tramo-titulo { font-size: 22px; }
  .vs-indice-soluciones__tramo-intro { margin-bottom: var(--sp-8); }
  .vs-indice-soluciones { grid-template-columns: repeat(2, 1fr); gap: var(--sp-8); }
  .vs-indice-soluciones__card { padding: 24px; }
  .vs-indice-soluciones__card h3 { font-size: 20px; }
}
@media (min-width: 1120px) {
  .vs-indice-sol__encabezado { max-width: 780px; }
  .vs-indice-sol__h1 { font-size: 40px; }
  p.vs-indice-sol__lead { font-size: 19px; }
  .vs-indice-soluciones__tramo { margin-bottom: var(--sp-14); }
  .vs-indice-soluciones__tramo-titulo { font-size: 24px; }
  .vs-indice-soluciones { grid-template-columns: repeat(3, 1fr); gap: var(--sp-10); }
  .vs-indice-soluciones__card { padding: var(--sp-9); }
  .vs-indice-soluciones__card h3 { font-size: 21px; }
}

/* 30.3.1 · CTA propio del Índice Soluciones (V3.3-A.1) — gris dentro de
            la retícula y subordinado a las cards, no la franja navy a
            sangre de `.vs-indice-cta`, que siguen usando los otros tres
            índices sin cambio de materialidad. */
.vs-cta-soluciones {
  margin-top: var(--sp-14);
  padding: var(--sp-9);
  background: var(--fondo-suave);
  /* Filete lateral izquierdo, no superior: es la orientación del contrato
     V3.3-A.1, verificada por el Product Owner contra el runtime. Vive en
     la clase de instancia, así que no alcanza a los otros tres índices. */
  border-left: 2px solid var(--dorado);
  display: flex;
  flex-direction: column;
  gap: var(--sp-6);
  align-items: flex-start;
}
.vs-cta-soluciones h2 { font-family: var(--fuente-titulos); font-weight: 700; font-size: 22px; margin: 0 0 var(--sp-2); max-width: 32ch; }
.vs-cta-soluciones p { font-size: 16px; line-height: 1.6; color: var(--tinta-60); margin: 0; max-width: 60ch; }
/* Botón a ancho completo sólo en móvil; a 768 el CTA sigue apilado pero el
   botón recupera su ancho natural, y sólo desde 1120 pasa a fila. */
.vs-cta-soluciones__boton { min-height: 52px; width: 100%; }
@media (min-width: 768px) {
  .vs-cta-soluciones__boton { width: auto; flex: none; }
}
@media (min-width: 1120px) {
  .vs-cta-soluciones { flex-direction: row; align-items: center; justify-content: space-between; gap: var(--sp-10); }
}

/* 30.4 · Biblioteca — filtro por pestaña (Todos/Propios/Demostrativos).
         Sin JavaScript de librería: son enlaces con estado activo,
         filtran ocultando secciones ya renderizadas — cero fetch,
         cero iframe adicional. */
.vs-biblioteca__filtros { display: flex; gap: var(--sp-8); border-bottom: 1px solid var(--borde); margin-bottom: var(--sp-9); }
.vs-biblioteca__filtro {
  font-family: var(--fuente-titulos); font-weight: 600; font-size: 16px;
  color: var(--tinta-60); background: none; border: none; cursor: pointer;
  padding: 0 0 var(--sp-4); border-bottom: 2px solid transparent; margin-bottom: -1px;
}
.vs-biblioteca__filtro:hover { color: var(--tinta); }
.vs-biblioteca__filtro[aria-pressed="true"] { color: var(--tinta); border-bottom-color: var(--dorado); }
.vs-biblioteca__seccion-oculta-por-filtro { display: none; }

/* 30.4b · Encabezado de índice · VSCR-95 C2 (lámina aprobada por el PO,
   2026-09-28). Una sola regla para Servicios, Soluciones y Proyectos; lo que
   los distingue es el copy. Biblioteca queda fuera (P-C1): conserva
   `.vs-indice__eyebrow` y su autoridad aprobada.
   - ≥ 1200: dos columnas H1 460 + 60 + lead 640 sobre el ancho del grid
     (1160), con filete superior de 1 px `#E3E6EC` a 24 px. Las columnas van
     en proporción 23:32 para que entre 1200 y 1224 —donde el marco rinde
     menos de 1160— no desborden; a 1160 miden exactamente 460 y 640.
   - < 1200: apilado según los frames de 768 y 375 (sin filete).
   Ritmo: cabecera del sitio → migas 40 / 40 / 36 (`.vs-seccion--indice`);
   intro → primer contenido 48 / 40 / 32 (margen inferior de este bloque). */
.vs-seccion--indice { padding-top: 36px; }
@media (min-width: 768px) { .vs-seccion--indice { padding-top: 40px; } }
.vs-encabezado-indice { margin-bottom: var(--sp-10); }
.vs-encabezado-indice .vs-migas { font-size: 11px; margin-bottom: var(--sp-3); }
.vs-encabezado-indice__kicker {
  display: inline-block;
  font-family: var(--fuente-mono);
  font-size: 11px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: #8A5E00;
  border-top: 2px solid var(--dorado);
  padding-top: var(--sp-2);
  margin-bottom: var(--sp-5);
}
.vs-encabezado-indice__h1 {
  font-size: 29px;
  line-height: 1.2;
  letter-spacing: -.02em;
  color: var(--tinta);
  margin: 0 0 var(--sp-4);
  max-width: none;
  text-wrap: balance;
}
.vs-encabezado-indice__lead { font-size: 17px; line-height: 1.6; color: var(--tinta-60); margin: 0; text-wrap: pretty; }
@media (min-width: 768px) {
  .vs-encabezado-indice { max-width: 640px; margin-bottom: var(--sp-11); }
  .vs-encabezado-indice .vs-migas { font-size: 12px; margin-bottom: var(--sp-5); }
  .vs-encabezado-indice__kicker { font-size: 12px; padding-top: var(--sp-3); margin-bottom: 18px; }
  .vs-encabezado-indice__h1 { font-size: 34px; line-height: 1.18; margin-bottom: var(--sp-5); }
  .vs-encabezado-indice__lead { max-width: 64ch; }
}
@media (min-width: 1120px) {
  .vs-encabezado-indice { max-width: 760px; margin-bottom: var(--sp-13); }
  .vs-encabezado-indice .vs-migas { margin-bottom: var(--sp-6); }
  .vs-encabezado-indice__kicker { margin-bottom: var(--sp-7); }
  .vs-encabezado-indice__h1 { font-size: 40px; line-height: 1.16; margin-bottom: var(--sp-6); }
  .vs-encabezado-indice__lead { font-size: 18px; line-height: 1.62; }
}
@media (min-width: 1200px) {
  .vs-encabezado-indice { max-width: 1160px; }
  .vs-encabezado-indice__cuerpo {
    display: grid;
    grid-template-columns: minmax(0, 23fr) minmax(0, 32fr);
    column-gap: 60px;
    align-items: start;
    border-top: var(--borde-estructura);
    padding-top: var(--sp-8);
  }
  .vs-encabezado-indice__h1 { margin: 0; }
  .vs-encabezado-indice__lead { max-width: none; padding-top: 6px; }
}

/* 30.5 · Encabezado y CTA compartidos de los cuatro índices (D-85-11). */
/* Texto en `--azul-senal`, no `--dorado`: #F0BF2E sobre blanco no alcanza
   contraste AA para texto (~1.6:1) — el mismo criterio que ya usa
   `.vs-hero__eyebrow .vs-mono`, donde el dorado es la línea, no la letra. */
.vs-indice__eyebrow { display: block; font-family: var(--fuente-mono); font-size: 13px; letter-spacing: .08em; text-transform: uppercase; color: var(--azul-senal); margin-bottom: var(--sp-4); }
.vs-indice__intro { font-size: 17px; line-height: 1.65; color: var(--tinta-60); max-width: 62ch; margin: var(--sp-5) 0 var(--sp-9); }
/* CTA compartido de índices (D-85-11) — Servicios, Proyectos y Biblioteca.
   Soluciones usa su propia instancia (`.vs-cta-soluciones`, V3.3-A.1).

   **Corrección estructural (VSCR-85, V3.3-A.1).** El layout vivía en la
   `<section>`, cuyo único hijo directo es `.vs-contenedor`: con un solo
   hijo flexible el `space-between` nunca se activaba, el contenedor
   encogía a su contenido (546–590px en vez del ancho de retícula) y su
   `margin: 0 auto` lo centraba, dejando el CTA ~447px desalineado del
   margen de texto de la propia página. El layout pasa al contenedor, que
   es quien realmente agrupa el bloque editorial y el botón; la sección
   conserva el fondo a sangre. Sin cambios de copy ni de materialidad en
   los tres índices que lo usan. */
.vs-indice-cta { background: var(--azul-profundo); padding-block: var(--sp-9); }
.vs-indice-cta > .vs-contenedor {
  display: flex; flex-direction: column; gap: var(--sp-6); align-items: flex-start;
}
.vs-indice-cta h2 { color: var(--blanco); font-size: 22px; margin: 0; max-width: 32ch; }
.vs-indice-cta p { color: var(--sobre-oscuro); font-size: 15px; margin: 0; max-width: 52ch; }
@media (min-width: 768px) {
  .vs-indice-cta > .vs-contenedor { flex-direction: row; align-items: center; justify-content: space-between; gap: var(--sp-9); }
}

/* PO-INDEX-SERV-02: el fondo navy sigue a sangre (`.vs-indice-cta`, sin
   cambios arriba) — sólo el contenido interior del Índice Servicios pasa de
   `.vs-contenedor` (1440) a su propio marco de 1160
   (`.vs-indice-servicios-marco`, definido en 30.2). Modificador scoped por
   variante de instancia, igual que ya hace `.vs-cta-soluciones` frente a
   este mismo componente. */
.vs-indice-cta--servicios > .vs-indice-servicios-marco {
  display: flex; flex-direction: column; gap: var(--sp-6); align-items: flex-start;
}
@media (min-width: 768px) {
  .vs-indice-cta--servicios > .vs-indice-servicios-marco { flex-direction: row; align-items: center; justify-content: space-between; gap: var(--sp-9); }
}

/* Lote A (reauditoría forense VSCR-85, 2026-09-02, PF-15): mismo patrón que
   `.vs-indice-cta--servicios` — el Índice de Proyectos pasa a su propio
   marco de 1160. */
.vs-indice-cta--proyectos > .vs-indice-proyectos-marco {
  display: flex; flex-direction: column; gap: var(--sp-6); align-items: flex-start;
}
@media (min-width: 768px) {
  .vs-indice-cta--proyectos > .vs-indice-proyectos-marco { flex-direction: row; align-items: center; justify-content: space-between; gap: var(--sp-9); }
}

/* Auditoría resolutiva (2026-09-04): mismo patrón — Biblioteca es la
   última de las cuatro superficies en pasar a su propio marco de 1160;
   ya no queda ninguna en el componente compartido `.vs-indice-cta > .vs-contenedor`. */
.vs-indice-cta--modelos3d > .vs-indice-modelos3d-marco {
  display: flex; flex-direction: column; gap: var(--sp-6); align-items: flex-start;
}
@media (min-width: 768px) {
  .vs-indice-cta--modelos3d > .vs-indice-modelos3d-marco { flex-direction: row; align-items: center; justify-content: space-between; gap: var(--sp-9); }
}

/* ---------------------------------------------------------------
   33. VSCR-86 — Propagación Bloque 3 (Home, Contacto, Proyectos)

   Autoridad por superficie, en el orden fijado en
   `docs/specs/VSCR-86/VSCR-86-propagacion-bloque-3.md` §1.2:
   `Home.dc.html` para Home, `Patrones de Pagina.dc.html` (PLANTILLA C
   Proyecto, PLANTILLA D Contacto, REGLAS DEL SISTEMA) para el resto.

   Lo que NO se toca, por ser falso positivo demostrado en la Fase 1B:
   `.vs-contenedor` global (el frame del sistema es 1440/56, no 1160/140),
   el ritmo de 88px, el H1 de 52 del hero y el filete de 1px de la rejilla
   de Servicios. Ver matriz definitiva en el comentario Jira 11343.
   --------------------------------------------------------------- */

/* T-04 · Escala de H2 en escritorio.
   `h2` global vale `--h2-mobile` (26) en todos los cortes y nunca hubo
   regla de escritorio: `--h2-desktop` (38) estaba declarado en tokens.css
   SIN un solo consumidor. `Home.dc.html` fija 38 para las cabeceras de
   sección y 32 para el módulo de Modelo 3D; la banda CTA ya rendía 34.
   Ambos selectores son exclusivos de Home —`.vs-seccion__cabecera` sólo
   vive en `inicio.php` y `_seccion-proyectos-destacados.php`, y el propio
   comentario de `.vs-intro-bloque` en la sección 24 declara que «sólo lo
   usa Home»—, así que el cambio no alcanza ninguna superficie cerrada.
   Las tarjetas de `.vs-valores`, que también son `h2` en el marcado pero
   la pieza dibuja a 19px, quedan fuera: no están en la matriz. */
@media (min-width: 1120px) {
  .vs-seccion__cabecera h2,
  .vs-intro-bloque h2 { font-size: var(--h2-desktop); line-height: 1.15; }
  .vs-titulo-matterport { font-size: 32px; line-height: 1.18; }
  /* R5-01 (2026-09-12): `Home.dc.html` compone el encabezado de Servicios con
     `max-width: 640px`, pero `.vs-seccion__cabecera > div` no declaraba
     ninguno y su ancho lo fijaba el contenido. Con el H2 a 26 medía 590,38 y
     cabía por accidente; al subirlo a 38 saltó a 862,86. Las dos secciones
     hermanas que sí lo respetan lo hacen porque `.vs-intro-bloque` declara su
     propio cap de 620. Va en esta misma banda —y sólo en ella— porque en
     tablet y móvil el encabezado ya lo clampa el marco de página. */
  .vs-seccion__cabecera > div { max-width: 640px; }
}

/* N-01 · Lead del hero de Home: 18px y 56ch en escritorio.
   Mismo patrón que T-04 — `--lead-desktop` (18) era el segundo token
   huérfano de tokens.css. `.vs-lead` base ya declara 56ch; aquí sólo
   sube el cuerpo, sin tocar la medida. */
@media (min-width: 1120px) { .vs-hero__lead { font-size: var(--lead-desktop); } }

/* N-03 · Módulo de Modelo 3D de portada: visor flexible + columna de
   texto de 360px, gap 48 (`Home.dc.html`). `.vs-rejilla-10` sólo declaraba
   `gap`, así que la sección caía a una columna de 1328px en escritorio. */
@media (min-width: 1120px) {
  .vs-rejilla-10 { grid-template-columns: minmax(0, 1fr) 360px; gap: var(--sp-13); }
}

/* H-06 · Área táctil de los enlaces de acción.
   REGLAS DEL SISTEMA: «Todo objetivo mínimo 44×44 px». Medidos en Home:
   22,39 · 30 · 25 · 20 · 18 px de alto. Se resuelve con una capa de
   impacto centrada, no agrandando el texto: la geometría pintada no
   cambia en ninguna superficie, incluidas las cerradas que comparten
   `.vs-tarjeta-servicio__enlace` y `.vs-tarjeta-proyecto__enlace`. */
.vs-seccion__enlace,
.vs-tarjeta-servicio__enlace,
.vs-tarjeta-proyecto__enlace,
.vs-rejilla-10 p a { position: relative; }
.vs-seccion__enlace::after,
.vs-tarjeta-servicio__enlace::after,
.vs-tarjeta-proyecto__enlace::after,
.vs-rejilla-10 p a::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
  height: 44px;
}

/* N-02 + P-03 · Banda CTA: el marco dejaba de ser el marco.
   `.vs-cta-banda` es flex y su `.vs-contenedor` es un item con
   `margin: 0 auto`, de modo que se encogía al ancho del contenido y el
   inset flotaba con el copy: 139,88px en Home y 217,08px en Proyecto,
   donde la autoridad pide el margen de página (56/32/20).
   `width: 100%` lo devuelve al marco sin tocar `.vs-contenedor` global.

   CAMBIO COMPARTIDO CONTROLADO: el selector lo consumen cuatro vistas.
   Se aplica por modificador —sólo `inicio.php` y `proyecto.php`— porque
   `_servicio-familia.php` es superficie CERRADA (VSCR-85) y hoy rinde
   inset 107,66: corregirla aquí sería modificar geometría aprobada.
   Queda registrada como residual, no como trabajo de VSCR-86. */
.vs-cta-banda--marco > .vs-contenedor { width: 100%; }

/* Ritmo vertical propio de la banda CTA de la portada: `Home.dc.html`
   la compone con `padding: 72px 56px`, frente a los 32 uniformes que
   hereda de la sección 12. 72 no existe como token de espaciado. */
@media (min-width: 1120px) { .vs-cta-banda--home { padding: 72px 0; } }

/* T-03 + C-02 · Contacto. La composición de PLANTILLA D ya estaba
   implementada —rejilla 1.15fr/1fr medida en 710,3/617,7, tres pasos,
   cuatro datos, inputs de 48, textarea de 120, envío de 52—; lo único
   que divergía era la escala del encabezado. */
@media (min-width: 1120px) {
  .vs-titulo-contacto { font-size: 42px; }
  .vs-lead--contacto { font-size: var(--lead-desktop); }
}

/* T-02 + T-03 + T-04 · Ficha de Proyecto (PLANTILLA C). Sustituida por el
   sistema común de la lámina VSCR-97 A (sección 35): sus reglas se retiraron
   con la composición anterior. */

/* ---------------------------------------------------------------
   34. 404 pública con Kobe (VSCR-95 frente A, lámina aprobada por el
       Product Owner el 2026-09-28)

   Geometría de la lámina, por banda:
     < 768   márgenes 20 · padding 28/48 · panel a sangre 220 (212 a 360)
             · «404» 80 (76) · Kobe 220 × 161 (212 × 155) · CTA a ancho
             completo · enlaces en lista con flecha, 48 de alto.
     768+    márgenes 32 · padding 32/72 · panel 300 · «404» 128 · filete
             36 · Kobe 360 × 264 · texto máx. 600 · enlaces en fila.
     1200+   marco de 1160 (márgenes 140 a 1440) · padding 72/96 · dos
             columnas 560 + 536, gap 64 · panel 536 × 500 · «404» 160 ·
             filete 40 · Kobe 400 × 293.
   Entre 360 y 375, panel, «404» y Kobe se interpolan hacia A6 con
   `clamp()`: coinciden en los dos marcos sin abrir una banda nueva.
   Kobe se ancla abajo a la derecha del panel: el corte de la cola
   coincide con su borde y se lee como encuadre.
   --------------------------------------------------------------- */
.vs-404__marco {
  max-width: 1160px;
  margin: 0 auto;
  padding: 0 20px 48px;
  display: flex;
  flex-direction: column;
}
.vs-404__panel {
  order: -1;
  position: relative;
  overflow: hidden;
  background: var(--fondo-suave);
  height: clamp(212px, calc(212px + (100vw - 360px) * 0.5334), 220px);
  margin: 0 -20px 28px;
}
.vs-404__numeral {
  position: absolute;
  left: 20px;
  top: 20px;
  font-family: var(--fuente-titulos);
  font-weight: 700;
  font-size: clamp(76px, calc(76px + (100vw - 360px) * 0.2667), 80px);
  line-height: 1;
  letter-spacing: -.04em;
  color: var(--azul-profundo);
}
.vs-404__filete { display: none; position: absolute; height: 3px; background: var(--dorado); }
.vs-404__kobe {
  position: absolute;
  right: 0;
  bottom: 0;
  width: clamp(212px, calc(212px + (100vw - 360px) * 0.5334), 220px);
  height: auto;
}
.vs-404__kicker {
  display: inline-block;
  font-family: var(--fuente-mono);
  font-size: 11px;
  letter-spacing: .14em;
  color: #8A5E00;
  border-top: 2px solid var(--dorado);
  padding-top: 8px;
  margin-bottom: 14px;
}
.vs-404__h1 { font-size: 29px; line-height: 1.2; letter-spacing: -.02em; color: var(--tinta); margin: 0 0 12px; text-wrap: balance; }
.vs-404__kobe-linea {
  font-family: var(--fuente-titulos);
  font-weight: 600;
  font-size: 17px;
  line-height: 1.45;
  color: var(--azul-profundo);
  margin: 0 0 12px;
  max-width: 34ch;
}
.vs-404__explicacion { font-size: 16px; line-height: 1.6; color: var(--tinta-60); margin: 0 0 24px; max-width: 52ch; }
.vs-404__cta { display: flex; width: 100%; min-height: 52px; padding: 0 28px; font-size: 16px; }
.vs-404__continuar { margin-top: 24px; padding-top: 16px; border-top: 1px solid var(--borde); }
.vs-404__continuar-etiqueta {
  display: block;
  font-family: var(--fuente-mono);
  font-size: 11px;
  letter-spacing: .12em;
  color: var(--tinta-60);
  margin-bottom: 4px;
}
.vs-404__enlaces { display: flex; flex-direction: column; }
.vs-404__enlaces a {
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 48px;
  font-family: var(--fuente-titulos);
  font-weight: 600;
  font-size: 16px;
  color: var(--azul-senal);
  border-bottom: 1px solid var(--borde);
}
.vs-404__enlaces a:last-child { border-bottom: 0; }
/* Foco de la lámina: 3 px azul señal, separación 3 (sobre blanco, 5,4:1). */
.vs-404 a:focus-visible { outline-offset: 3px; }

@media (min-width: 768px) {
  .vs-404__marco { padding: 32px 32px 72px; }
  .vs-404__panel { height: 300px; margin: 0 0 36px; }
  .vs-404__numeral { left: 32px; top: 32px; font-size: 128px; }
  .vs-404__filete { display: block; left: 36px; top: 176px; width: 36px; }
  .vs-404__kobe { width: 360px; }
  .vs-404__texto { max-width: 600px; }
  .vs-404__kicker { font-size: 12px; padding-top: 10px; margin-bottom: 18px; }
  .vs-404__h1 { font-size: 36px; line-height: 1.16; margin-bottom: 14px; }
  .vs-404__kobe-linea { font-size: 19px; margin-bottom: 14px; }
  .vs-404__explicacion { font-size: 17px; line-height: 1.65; margin-bottom: 28px; }
  .vs-404__cta { display: inline-flex; width: auto; }
  .vs-404__continuar { display: flex; align-items: center; flex-wrap: wrap; gap: 20px; padding-top: 18px; }
  .vs-404__continuar-etiqueta { font-size: 12px; margin-bottom: 0; }
  .vs-404__enlaces { flex-direction: row; flex-wrap: wrap; gap: 20px; }
  .vs-404__enlaces a,
  .vs-404__enlaces a:last-child { min-height: 44px; font-size: 15px; border-bottom: 2px solid var(--dorado); }
  .vs-404__flecha { display: none; }
}

@media (min-width: 1200px) {
  .vs-404__marco {
    display: grid;
    grid-template-columns: minmax(0, 560fr) minmax(0, 536fr);
    column-gap: 64px;
    align-items: center;
    padding: 72px 0 96px;
  }
  .vs-404__panel { order: 0; height: 500px; margin: 0; }
  .vs-404__numeral { left: 44px; top: 40px; font-size: 160px; }
  .vs-404__filete { left: 48px; top: 212px; width: 40px; }
  .vs-404__kobe { width: 400px; }
  .vs-404__texto { max-width: none; }
  .vs-404__kicker { margin-bottom: 20px; }
  .vs-404__h1 { font-size: 44px; line-height: 1.14; margin-bottom: 18px; }
  .vs-404__kobe-linea { font-size: 20px; margin-bottom: 16px; }
  .vs-404__explicacion { margin-bottom: 32px; }
  .vs-404__continuar { gap: 24px; margin-top: 28px; padding-top: 20px; }
  .vs-404__enlaces { gap: 24px; }
}

/* ---------------------------------------------------------------
   35. Ficha de Proyecto · sistema común (VSCR-97 frente A)

   Lámina `VSCR-97 A Detalle de Proyecto.dc.html` (V1.1), CUA FINAL
   APROBADO POR EL PRODUCT OWNER. Un solo sistema para los tres Proyectos.

   Por franja:
   - < 768: una columna al 100 %; ficha en filas; visor 4:3 con el botón
     bajo el nombre; video 16:9 con título y botón bajo el póster.
   - 768–1119: todo apilado; ficha en una fila de 3 columnas (Servicios
     ocupa 2 si no hay año); narrativa en una columna de 64ch;
     «Otros proyectos» en 2 columnas.
   - ≥ 1120: encabezado texto + ficha en fracciones 2,16 : 1 con gap 64,
     que a 1440 dan exactamente 864 + 400 sobre la retícula de 1328 (la
     cifra fija no cabe a 1200: el ancho útil allí es 1088); narrativa y
     «Otros proyectos» en 1fr 1fr (632 + 632 a 1440).
   Ritmo a 1440: migas 40 → 24 → H1; encabezado → visor 48; visor →
   narrativa 88; narrativa → video 72; → otros 88; otros → CTA 88.
   --------------------------------------------------------------- */
.vs-proyecto { padding-top: var(--sp-8); }
.vs-proyecto .vs-migas { font-size: 11px; line-height: 1.6; margin-bottom: var(--sp-6); }
.vs-proyecto__titulo {
  font-family: var(--fuente-titulos);
  font-weight: 700;
  font-size: 32px;
  line-height: 1.14;
  letter-spacing: -.02em;
  color: var(--tinta);
  margin: 0 0 var(--sp-5);
  text-wrap: balance;
}
.vs-proyecto__lead { font-size: 16px; line-height: 1.6; color: var(--tinta-60); margin: 0 0 var(--sp-7); }

.vs-proyecto__ficha { margin: 0; border-top: 2px solid var(--azul-profundo); }
.vs-proyecto__dato { padding: var(--sp-4) 0; border-bottom: var(--borde-estructura); }
.vs-proyecto__dato dt {
  font-family: var(--fuente-mono);
  font-size: 11px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--tinta-60);
  margin-bottom: var(--sp-1);
}
.vs-proyecto__dato dd { margin: 0; font-family: var(--fuente-titulos); font-weight: 600; font-size: 15px; line-height: 1.4; color: var(--tinta); }
.vs-proyecto__dato--servicios { padding-bottom: var(--sp-1); }
.vs-proyecto__dato--servicios dt { margin-bottom: 0; }
.vs-proyecto__dato--servicios dd { display: flex; flex-direction: column; }
.vs-proyecto__servicio {
  font-family: var(--fuente-titulos);
  font-weight: 600;
  font-size: 15px;
  line-height: 1.35;
  color: var(--azul-senal);
  min-height: 44px;
  display: flex;
  align-items: center;
  text-decoration: underline;
  text-underline-offset: 3px;
}
.vs-proyecto__servicio:hover { color: var(--azul-profundo); }

.vs-proyecto h2 { font-family: var(--fuente-titulos); font-weight: 700; font-size: 24px; line-height: 1.22; color: var(--tinta); }
.vs-proyecto__recorrido h2 { margin: var(--sp-10) 0 var(--sp-4); }
.vs-proyecto__nota { display: none; }
.vs-proyecto__visores { display: grid; gap: var(--sp-9); }

/* Estado inicial del visor (IDLE) en la ficha — el componente vigente con la
   geometría de la lámina: filete dorado de 3 px y ningún otro borde,
   degradado sólo en la franja inferior (no velo sobre toda la foto), nombre
   y botón centrados abajo. Al pulsar abre el visor común (VSCR-103). */
.vs-proyecto .vs-matterport { border: 0; border-top: 3px solid var(--dorado); background: var(--azul-profundo-900); }
.vs-proyecto .vs-matterport__inicial::after { content: none; }
.vs-proyecto .vs-matterport__estado-inicial {
  top: auto;
  padding: var(--sp-11) var(--sp-4) var(--sp-6);
  gap: var(--sp-2);
  background: linear-gradient(to top, rgba(7, 11, 54, .82), rgba(7, 11, 54, 0));
}
.vs-proyecto .vs-matterport__titulo { font-size: 15px; line-height: 1.3; max-width: none; text-shadow: none; }
.vs-proyecto .vs-matterport__estado-inicial .vs-boton { font-size: 15px; min-height: 48px; padding: 0 var(--sp-7); }
.vs-proyecto .vs-matterport__etiqueta { font-size: 10px; letter-spacing: .1em; padding: 6px 9px; }

.vs-proyecto__portada { margin: var(--sp-10) 0 0; aspect-ratio: 16 / 9; overflow: hidden; background: var(--azul-profundo-900); }
.vs-proyecto__portada img { display: block; width: 100%; height: 100%; object-fit: cover; }

.vs-proyecto__narrativa { margin-top: var(--sp-12); border-top: var(--borde-estructura); padding-top: var(--sp-8); }
.vs-proyecto__narrativa h2 { margin: 0 0 var(--sp-4); }
.vs-proyecto__narrativa-seccion + .vs-proyecto__narrativa-seccion h2 { margin-top: var(--sp-9); }
.vs-proyecto__narrativa p { font-size: 16px; line-height: 1.7; color: var(--tinta-60); margin: 0 0 var(--sp-5); text-wrap: pretty; }
.vs-proyecto__narrativa h3 { font-size: 20px; margin: var(--sp-7) 0 var(--sp-4); }
.vs-proyecto__narrativa ul,
.vs-proyecto__narrativa ol { color: var(--tinta-60); margin: 0 0 var(--sp-5); padding-left: 1.2em; }
.vs-proyecto__narrativa a { color: var(--azul-senal); text-decoration: underline; text-underline-offset: 3px; }

.vs-proyecto__video h2 { margin: var(--sp-11) 0 var(--sp-4); }
.vs-proyecto__video-marco { position: relative; }
.vs-proyecto__video-escenario { position: relative; aspect-ratio: 16 / 9; overflow: hidden; background: var(--azul-profundo-900); }
.vs-proyecto__video-escenario img { display: block; width: 100%; height: 100%; object-fit: cover; }
.vs-proyecto__video-escenario iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
.vs-proyecto__video-cortina { display: flex; flex-direction: column; }
.vs-proyecto__video-cortina[hidden] { display: none; }
.vs-proyecto__video-kicker { display: none; }
.vs-proyecto__video-titulo { font-family: var(--fuente-titulos); font-weight: 700; font-size: 16px; line-height: 1.35; color: var(--tinta); margin: var(--sp-5) 0 var(--sp-4); }
.vs-proyecto__video-boton { justify-content: center; min-height: 52px; font-weight: 700; font-size: 16px; }
.vs-proyecto__video-pie { margin: 0; padding-top: var(--sp-3); }
.vs-proyecto__video-procedencia { font-size: 10px; letter-spacing: .1em; text-transform: uppercase; color: var(--tinta-60); }
.vs-proyecto__video-nota { display: none; }

.vs-proyecto__otros { margin-top: var(--sp-14); border-top: var(--borde-estructura); padding: var(--sp-8) 0 var(--sp-14); }
.vs-proyecto__otros h2 { margin: 0 0 var(--sp-5); }
.vs-proyecto__otros-lista { display: flex; flex-direction: column; }
.vs-proyecto__otro { display: block; border-top: 2px solid var(--azul-profundo); padding: var(--sp-5) 0; color: var(--tinta); text-decoration: none; }
.vs-proyecto__otro:hover { color: var(--azul-profundo); }
.vs-proyecto__otro-nombre { display: block; font-family: var(--fuente-titulos); font-weight: 600; font-size: 16px; line-height: 1.3; margin-bottom: var(--sp-1); }
.vs-proyecto__otro-lugar { font-size: 11px; color: var(--tinta-60); }
.vs-proyecto__otro-flecha { color: var(--azul-senal); }
.vs-proyecto__otro > .vs-proyecto__otro-flecha { display: none; }

@media (min-width: 768px) {
  .vs-proyecto { padding-top: var(--sp-10); }
  .vs-proyecto .vs-migas { font-size: 12px; margin-bottom: var(--sp-7); }
  .vs-proyecto__titulo { font-size: 38px; line-height: 1.12; margin-bottom: var(--sp-6); max-width: 640px; }
  .vs-proyecto__lead { font-size: 17px; margin-bottom: var(--sp-8); max-width: var(--medida-editorial); }
  .vs-proyecto__ficha {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 0 var(--sp-8);
    border-bottom: var(--borde-estructura);
    padding: var(--sp-5) 0;
  }
  .vs-proyecto__dato,
  .vs-proyecto__dato--servicios { padding: 0; border-bottom: 0; }
  .vs-proyecto__dato dt { margin-bottom: 6px; }
  .vs-proyecto__dato--servicios dt { margin-bottom: 2px; }
  .vs-proyecto__ficha--sin-anio .vs-proyecto__dato--servicios { grid-column: span 2; }
  .vs-proyecto h2 { font-size: 26px; }
  .vs-proyecto__recorrido h2 { margin: var(--sp-11) 0 var(--sp-5); }
  .vs-proyecto .vs-matterport__estado-inicial { padding: 72px var(--sp-8) var(--sp-9); gap: var(--sp-4); }
  .vs-proyecto .vs-matterport__titulo { font-size: 18px; }
  .vs-proyecto .vs-matterport__estado-inicial .vs-boton { font-size: 16px; min-height: 52px; padding: 0 var(--sp-8); }
  .vs-proyecto .vs-matterport__etiqueta { font-size: 11px; letter-spacing: .12em; padding: 7px 11px; }
  .vs-proyecto__portada { margin-top: var(--sp-11); }
  .vs-proyecto__narrativa { margin-top: var(--sp-14); padding-top: var(--sp-9); max-width: var(--medida-editorial); }
  .vs-proyecto__narrativa h2 { margin-bottom: var(--sp-5); }
  .vs-proyecto__narrativa-seccion + .vs-proyecto__narrativa-seccion h2 { margin-top: var(--sp-10); }
  .vs-proyecto__narrativa p { font-size: 17px; margin-bottom: var(--sp-6); }
  .vs-proyecto__video h2 { margin: var(--sp-13) 0 var(--sp-5); }
  /* El título y el botón pasan sobre el póster, en la franja inferior. */
  .vs-proyecto__video-cortina {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    flex-direction: row;
    align-items: flex-end;
    justify-content: space-between;
    gap: var(--sp-7);
    padding: var(--sp-8);
    background: linear-gradient(to top, rgba(7, 11, 54, .88), rgba(7, 11, 54, 0));
  }
  .vs-proyecto__video-titulo { font-size: 18px; color: var(--blanco); max-width: 22ch; margin: 0; }
  .vs-proyecto__video-boton { flex: none; padding: 0 22px; }
  .vs-proyecto__video-procedencia { font-size: 11px; }
  .vs-proyecto__otros { margin-top: var(--sp-15); padding: var(--sp-9) 0 var(--sp-15); }
  .vs-proyecto__otros h2 { margin-bottom: var(--sp-6); }
  .vs-proyecto__otros-lista { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-8); }
  .vs-proyecto__otro { padding: var(--sp-6) 0; }
  .vs-proyecto__otro-nombre { font-size: 17px; margin-bottom: 6px; }
}

@media (min-width: 1120px) {
  .vs-proyecto { padding-top: var(--sp-11); }
  .vs-proyecto .vs-migas { margin-bottom: var(--sp-8); }
  .vs-proyecto__cabecera {
    display: grid;
    grid-template-columns: minmax(0, 2.16fr) minmax(0, 1fr);
    gap: var(--sp-15);
    align-items: start;
  }
  .vs-proyecto__titulo { font-size: 44px; line-height: 1.1; margin: 0 0 var(--sp-7); max-width: none; }
  .vs-proyecto__lead { font-size: 18px; margin: 0; text-wrap: pretty; }
  .vs-proyecto__ficha { display: block; border-bottom: 0; padding: 0; }
  .vs-proyecto__dato,
  .vs-proyecto__dato--servicios {
    display: grid;
    grid-template-columns: 136px minmax(0, 1fr);
    gap: var(--sp-6);
    padding: var(--sp-5) 0;
    border-bottom: var(--borde-estructura);
  }
  .vs-proyecto__dato dt,
  .vs-proyecto__dato--servicios dt { font-size: 12px; padding-top: 2px; margin: 0; }
  .vs-proyecto__dato dd { font-size: 16px; }
  .vs-proyecto__servicio { font-size: 16px; }
  .vs-proyecto h2 { font-size: 28px; }
  .vs-proyecto__recorrido { margin-top: var(--sp-13); }
  .vs-proyecto__cabeza-seccion { display: flex; align-items: baseline; justify-content: space-between; gap: var(--sp-8); margin-bottom: var(--sp-6); }
  .vs-proyecto__recorrido h2 { margin: 0; }
  .vs-proyecto__nota { display: inline; font-size: 12px; color: var(--tinta-60); }
  .vs-proyecto .vs-matterport__estado-inicial { padding: 120px var(--sp-10) var(--sp-11); gap: var(--sp-5); }
  .vs-proyecto .vs-matterport__titulo { font-size: 20px; }
  .vs-proyecto .vs-matterport__estado-inicial .vs-boton { padding: 0 var(--sp-9); }
  .vs-proyecto__portada { margin-top: var(--sp-13); }
  .vs-proyecto__narrativa { margin-top: var(--sp-16); padding-top: var(--sp-10); max-width: none; }
  .vs-proyecto__narrativa--dos { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-15); }
  .vs-proyecto__narrativa--dos .vs-proyecto__narrativa-seccion + .vs-proyecto__narrativa-seccion h2 { margin-top: 0; }
  .vs-proyecto__narrativa:not(.vs-proyecto__narrativa--dos) { max-width: var(--medida-editorial); }
  .vs-proyecto__narrativa h2 { margin-bottom: var(--sp-6); }
  .vs-proyecto__narrativa p { margin-bottom: var(--sp-6); }
  .vs-proyecto__video { margin-top: 72px; }
  .vs-proyecto__video h2 { margin: 0 0 var(--sp-6); }
  .vs-proyecto__video-cortina { padding: var(--sp-10); gap: var(--sp-10); }
  .vs-proyecto__video-kicker { display: block; font-size: 12px; letter-spacing: .14em; text-transform: uppercase; color: var(--dorado); margin: 0 0 var(--sp-3); }
  .vs-proyecto__video-titulo { font-size: 22px; max-width: none; }
  .vs-proyecto__video-boton { font-size: 17px; min-height: 56px; padding: 0 var(--sp-9); }
  .vs-proyecto__video-pie { display: flex; justify-content: space-between; gap: var(--sp-8); padding-top: var(--sp-4); }
  .vs-proyecto__video-procedencia { font-size: 12px; }
  .vs-proyecto__video-nota { display: inline; font-size: 15px; color: var(--tinta-60); }
  .vs-proyecto__otros { margin-top: var(--sp-16); padding: var(--sp-10) 0 var(--sp-16); }
  .vs-proyecto__otros h2 { margin-bottom: var(--sp-7); }
  .vs-proyecto__otros-lista { gap: var(--sp-15); }
  .vs-proyecto__otro { display: flex; justify-content: space-between; align-items: center; gap: var(--sp-8); padding: 18px 0; min-height: 44px; }
  .vs-proyecto__otro-nombre { font-size: 19px; }
  .vs-proyecto__otro-lugar { font-size: 12px; }
  .vs-proyecto__otro-flecha--en-linea { display: none; }
  .vs-proyecto__otro > .vs-proyecto__otro-flecha { display: inline; font-family: var(--fuente-titulos); font-weight: 600; font-size: 20px; }
}

/* ---------------------------------------------------------------
   36. Blog · índice y artículo (VSCR-97 frente C)

   Láminas `VSCR-97 C Blog Indice.dc.html` y `… C Blog Articulo.dc.html`,
   CUA FINAL APROBADO POR EL PRODUCT OWNER.

   Índice: encabezado C2 sin cambios sobre el marco de 1160 (140 / 32 / 20);
   destacado 700 + 400 (gap 60) sólo en la página 1; rejilla 3 × 365 (gap 32),
   2 × 564 con dos artículos, 2 × 340 a 768, una columna en móvil; paginación
   con botones de 44. Intro → contenido 48 / 40 / 32 (margen de C2); final →
   pie 88 / 64 / 56.

   Artículo: la retícula de Nosotros (200 + 64 + 680 en 944) desde 1024; una
   columna de 64ch en 768–1023 y en móvil. La imagen principal se abre a 1160
   en 16:9. Cuerpo 18/1.72, H2 28, H3 21.
   --------------------------------------------------------------- */
.vs-blog-marco { --blog-margen: var(--sp-7); max-width: calc(1160px + var(--blog-margen) * 2); margin-inline: auto; padding-inline: var(--blog-margen); box-sizing: border-box; }
@media (min-width: 768px) { .vs-blog-marco { --blog-margen: var(--sp-10); } }
.vs-blog { padding-bottom: var(--sp-14); }
@media (min-width: 768px) { .vs-blog { padding-bottom: var(--sp-15); } }
@media (min-width: 1120px) { .vs-blog { padding-bottom: var(--sp-16); } }
/* Fechas y «Página N de M» en Plex, con la caja del copy aprobado
   («2 de septiembre de 2026»): sin las mayúsculas ni el tracking de
   `.vs-mono`, que sí llevan rótulos y categorías. */
.vs-blog__pagina-de { font-family: var(--fuente-mono); font-size: 12px; color: var(--tinta-60); margin: var(--sp-4) 0 0; }

/* Card de la familia de índices, con fecha y categoría. */
.vs-blog-card { display: flex; }
.vs-blog-card__enlace {
  display: flex;
  flex-direction: column;
  width: 100%;
  border: var(--borde-estructura);
  color: var(--tinta);
  text-decoration: none;
  transition: border-color var(--dur-hover) var(--curva);
}
.vs-blog-card__enlace:hover { border-color: var(--azul-profundo); color: var(--tinta); }
.vs-blog-card__enlace:focus-visible,
.vs-blog-destacado__enlace:focus-visible { outline: 2px solid var(--azul-senal); outline-offset: 2px; }
.vs-blog-card__media { display: block; aspect-ratio: 16 / 9; overflow: hidden; background: var(--azul-profundo); }
.vs-blog-card__media img { display: block; width: 100%; height: 100%; object-fit: cover; }
.vs-blog-card--sin-imagen .vs-blog-card__enlace { border-top: 2px solid var(--azul-profundo); }
.vs-blog-card__cuerpo { display: flex; flex-direction: column; gap: var(--sp-2); flex: 1; padding: var(--sp-6) 18px 18px; }
.vs-blog-card__categoria { display: block; font-size: 11px; letter-spacing: .12em; text-transform: uppercase; color: var(--tinta-60); }
.vs-blog-card__titulo { font-family: var(--fuente-titulos); font-weight: 600; font-size: 18px; line-height: 1.3; color: var(--tinta); margin: 0; text-wrap: balance; }
.vs-blog-card__extracto { display: block; font-size: 15px; line-height: 1.6; color: var(--tinta-60); flex: 1; }
.vs-blog-card__fecha { display: block; font-family: var(--fuente-mono); font-size: 11px; color: var(--tinta-60); border-top: var(--borde-estructura); padding-top: var(--sp-3); }

/* Destacado. En móvil es la primera card de la lista, con el rótulo. Con un
   solo artículo es lo último del índice: sin margen, el final → pie queda en
   88 / 64 / 56 como en los demás estados. */
.vs-blog-destacado { margin-bottom: var(--sp-7); }
.vs-blog-destacado:last-child { margin-bottom: 0; }
.vs-blog-destacado__enlace { display: flex; flex-direction: column; border: var(--borde-estructura); color: var(--tinta); text-decoration: none; transition: border-color var(--dur-hover) var(--curva); }
.vs-blog-destacado__enlace:hover { border-color: var(--azul-profundo); color: var(--tinta); }
.vs-blog-destacado--sin-imagen .vs-blog-destacado__enlace { border-top: 2px solid var(--azul-profundo); }
.vs-blog-destacado__media { display: block; aspect-ratio: 16 / 9; overflow: hidden; background: var(--azul-profundo); }
.vs-blog-destacado__media img { display: block; width: 100%; height: 100%; object-fit: cover; }
.vs-blog-destacado__cuerpo { display: flex; flex-direction: column; gap: var(--sp-2); padding: var(--sp-6) 18px 18px; }
.vs-blog-destacado__kicker { display: block; font-size: 11px; letter-spacing: .14em; text-transform: uppercase; color: #8A5E00; }
.vs-blog-destacado__titulo { font-family: var(--fuente-titulos); font-weight: 600; font-size: 18px; line-height: 1.3; color: var(--tinta); margin: 0; text-wrap: balance; }
.vs-blog-destacado__extracto { display: block; font-size: 15px; line-height: 1.6; color: var(--tinta-60); }
.vs-blog-destacado__meta { display: block; font-family: var(--fuente-mono); font-size: 11px; color: var(--tinta-60); border-top: var(--borde-estructura); padding-top: var(--sp-3); }
.vs-blog-destacado__categoria-meta { display: none; }

.vs-blog__rejilla { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--sp-7); }

/* Estado vacío: mensaje + tres enlaces útiles. */
.vs-blog-vacio { border-top: 2px solid var(--azul-profundo); padding-top: var(--sp-7); }
.vs-blog-vacio__titulo { font-family: var(--fuente-titulos); font-weight: 700; font-size: 22px; line-height: 1.3; margin: 0 0 var(--sp-4); }
.vs-blog-vacio__texto { font-size: 16px; line-height: 1.65; color: var(--tinta-60); margin: 0 0 var(--sp-3); }
.vs-blog-vacio__enlaces { display: flex; flex-direction: column; }
.vs-blog-vacio__enlaces a { font-family: var(--fuente-titulos); font-weight: 600; font-size: 16px; color: var(--azul-senal); min-height: 44px; display: flex; align-items: center; gap: 6px; }

/* Paginación — la primera pública del sitio. Móvil: flechas de 44 con
   nombre accesible y números, centrados. */
.vs-blog-paginacion { margin-top: var(--sp-11); border-top: var(--borde-estructura); padding-top: 18px; display: flex; align-items: center; justify-content: center; gap: var(--sp-2); }
.vs-blog-paginacion__numeros { list-style: none; margin: 0; padding: 0; display: flex; gap: var(--sp-2); }
.vs-blog-paginacion__numero,
.vs-blog-paginacion__salto,
.vs-blog-paginacion__paso {
  min-width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
}
.vs-blog-paginacion__numero { font-family: var(--fuente-mono); font-size: 14px; border: 1px solid var(--borde-campo); color: var(--tinta); text-decoration: none; }
.vs-blog-paginacion__numero[aria-current="page"] { background: var(--azul-profundo); border-color: var(--azul-profundo); color: var(--blanco); font-weight: 500; }
.vs-blog-paginacion__salto { font-family: var(--fuente-mono); color: var(--tinta-60); }
.vs-blog-paginacion__paso { border: 1.5px solid var(--azul-profundo); color: var(--azul-profundo); font-family: var(--fuente-titulos); font-weight: 700; text-decoration: none; }
.vs-blog-paginacion__paso-texto { display: none; }
.vs-blog-paginacion__paso--inactivo { border: 1px solid var(--borde); color: var(--tinta-30); font-weight: 400; }
.vs-blog-paginacion a:focus-visible { outline: 2px solid var(--azul-senal); outline-offset: 2px; }

@media (min-width: 768px) {
  .vs-blog-card__cuerpo { padding: 18px var(--sp-7) var(--sp-7); }
  .vs-blog-card__fecha { font-size: 12px; }
  .vs-blog__rejilla { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-8); }
  .vs-blog-destacado { margin-bottom: var(--sp-8); }
  .vs-blog-destacado__cuerpo { padding: var(--sp-8) var(--sp-9); gap: 0; }
  .vs-blog-destacado__kicker { margin-bottom: var(--sp-3); }
  .vs-blog-destacado__categoria-sobre { display: none; }
  .vs-blog-destacado__titulo { font-weight: 700; font-size: 24px; line-height: 1.25; margin-bottom: var(--sp-4); }
  .vs-blog-destacado__extracto { font-size: 16px; margin-bottom: var(--sp-5); }
  .vs-blog-destacado__meta { font-size: 12px; border-top: 0; padding-top: 0; }
  .vs-blog-destacado__categoria-meta { display: inline; }
  .vs-blog-vacio { padding-top: var(--sp-8); }
  .vs-blog-vacio__titulo { font-size: 24px; }
  .vs-blog-vacio__texto { font-size: 17px; margin-bottom: var(--sp-6); }
  .vs-blog-vacio__enlaces { flex-direction: row; flex-wrap: wrap; gap: var(--sp-2) var(--sp-9); }
  .vs-blog-paginacion { margin-top: var(--sp-13); padding-top: var(--sp-7); justify-content: space-between; }
  .vs-blog-paginacion__paso { min-width: 110px; padding: 0 18px; gap: 6px; font-weight: 600; font-size: 15px; }
  .vs-blog-paginacion__paso-texto { display: inline; }
  .vs-blog-paginacion__paso--inactivo { visibility: hidden; }
}
@media (min-width: 1120px) {
  .vs-blog-card__titulo { font-size: 20px; }
  .vs-blog-paginacion { margin-top: var(--sp-14); padding-top: var(--sp-8); }
  .vs-blog-paginacion__paso { min-width: 120px; padding: 0 var(--sp-7); }
  .vs-blog-card__cuerpo { padding: var(--sp-7) 22px 22px; gap: var(--sp-3); }
  .vs-blog-card__fecha { padding-top: var(--sp-4); }
  .vs-blog__rejilla { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--sp-10); }
  .vs-blog__rejilla--dos { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .vs-blog__rejilla--dos .vs-blog-card__cuerpo { padding: var(--sp-8) var(--sp-9) 26px; }
  .vs-blog__rejilla--dos .vs-blog-card__titulo { font-size: 22px; }
  .vs-blog__rejilla--dos .vs-blog-card__extracto { font-size: 16px; }
  .vs-blog-destacado { margin-bottom: var(--sp-10); }
  .vs-blog-destacado__enlace { display: grid; grid-template-columns: minmax(0, 700fr) minmax(0, 400fr); column-gap: 60px; align-items: center; }
  .vs-blog-destacado--sin-imagen .vs-blog-destacado__enlace { grid-template-columns: minmax(0, 1fr); }
  .vs-blog-destacado__cuerpo { padding: var(--sp-10) var(--sp-11) var(--sp-10) 0; }
  .vs-blog-destacado--sin-imagen .vs-blog-destacado__cuerpo { padding-left: var(--sp-11); }
  .vs-blog-destacado__titulo { font-size: 28px; line-height: 1.22; margin-bottom: var(--sp-5); }
  .vs-blog-destacado__extracto { margin-bottom: 18px; line-height: 1.65; }
  .vs-blog-vacio { display: grid; grid-template-columns: minmax(0, 23fr) minmax(0, 32fr); column-gap: 60px; padding-top: var(--sp-8); }
  .vs-blog-vacio__titulo { margin: 0; }
}

/* Artículo */
.vs-articulo__marco { padding-inline: var(--contenedor-margen-mobile); }
@media (max-width: 359.98px) { .vs-articulo__marco { padding-inline: var(--contenedor-margen-mobile-360); } }
.vs-articulo__encabezado { padding-top: var(--sp-8); }
.vs-articulo__migas { font-size: 11px; line-height: 1.6; margin-bottom: var(--sp-7); }
.vs-articulo__migas [aria-current="page"] { display: inline-block; max-width: 100%; vertical-align: bottom; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.vs-articulo__categoria { font-size: 11px; letter-spacing: .14em; text-transform: uppercase; color: var(--tinta-60); margin: 0 0 var(--sp-3); }
.vs-articulo__titulo { font-family: var(--fuente-titulos); font-weight: 700; font-size: 28px; line-height: 1.16; letter-spacing: -.02em; color: var(--tinta); margin: 0 0 var(--sp-7); text-wrap: balance; }
.vs-articulo__meta { margin: 0 0 var(--sp-6); display: flex; flex-wrap: wrap; gap: var(--sp-1) var(--sp-6); border-top: var(--borde-estructura); padding-top: var(--sp-5); font-size: 12px; color: var(--tinta-60); }
.vs-articulo__meta dt { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.vs-articulo__meta dd { margin: 0; }
.vs-articulo__fecha { font-family: var(--fuente-mono); }
.vs-articulo__meta-dato--firma dd::before { content: "· "; font-family: var(--fuente-mono); color: var(--tinta-60); }
.vs-articulo__firma { font-family: var(--fuente-titulos); font-weight: 600; font-size: 14px; color: var(--tinta); }
.vs-articulo__extracto { font-size: 17px; line-height: 1.6; color: var(--tinta); margin: 0; max-width: var(--medida-editorial); text-wrap: pretty; }
.vs-articulo__principal { margin: var(--sp-10) auto 0; width: calc(100% - 2 * var(--contenedor-margen-mobile)); aspect-ratio: 16 / 9; overflow: hidden; background: var(--azul-profundo); }
.vs-articulo__principal img { display: block; width: 100%; height: 100%; object-fit: cover; }
.vs-articulo__contenido { padding-top: var(--sp-6); }
.vs-articulo__cuerpo { max-width: var(--medida-editorial); }
.vs-articulo__cuerpo h2 { font-family: var(--fuente-titulos); font-weight: 700; font-size: 24px; line-height: 1.25; letter-spacing: -.01em; color: var(--tinta); margin: 36px 0 var(--sp-4); }
.vs-articulo__cuerpo h3 { font-family: var(--fuente-titulos); font-weight: 700; font-size: 19px; line-height: 1.3; color: var(--tinta); margin: 26px 0 var(--sp-3); }
.vs-articulo__cuerpo p { font-size: 16px; line-height: 1.7; color: var(--tinta); margin: 0 0 18px; text-wrap: pretty; }
.vs-articulo__cuerpo a { color: var(--azul-senal); text-decoration: underline; text-underline-offset: 3px; }
.vs-articulo__cuerpo a:hover { color: var(--azul-profundo); }
/* Énfasis editorial controlado (VSCR-16): `**texto**` → <strong>. Open Sans 600, el peso que ya se sirve; sin fuente nueva ni cambio de color. */
.vs-articulo__cuerpo strong { font-weight: 600; }
.vs-articulo__lista { list-style: none; margin: 0 0 var(--sp-7); padding: 0; display: flex; flex-direction: column; gap: var(--sp-2); }
.vs-articulo__lista li { display: grid; grid-template-columns: 20px minmax(0, 1fr); font-size: 16px; line-height: 1.6; color: var(--tinta); }
.vs-articulo__vineta { width: 6px; height: 6px; background: var(--dorado); margin-top: var(--sp-3); }
.vs-articulo__lista--numerada li { grid-template-columns: 30px minmax(0, 1fr); }
.vs-articulo__numero { font-size: 12px; color: #8A5E00; padding-top: 3px; }
.vs-articulo__cita { margin: var(--sp-9) 0; border-top: 2px solid var(--dorado); padding-top: var(--sp-5); }
.vs-articulo__cuerpo .vs-articulo__cita p { font-family: var(--fuente-titulos); font-weight: 600; font-size: 19px; line-height: 1.45; color: var(--azul-profundo); margin: 0; }
.vs-articulo__figura { margin: var(--sp-9) 0; }
.vs-articulo__figura img { display: block; width: 100%; height: auto; }
/* Caption de la lámina (IMAGEN EDITORIAL): Open Sans 14/1.5, filete de 1 px
   y 10 arriba, en todos los anchos. */
.vs-articulo__figura figcaption { font-size: 14px; line-height: 1.5; color: var(--tinta-60); margin-top: var(--sp-3); padding-top: var(--sp-3); border-top: var(--borde-estructura); }
.vs-articulo__volver { margin-top: var(--sp-4); font-family: var(--fuente-titulos); font-weight: 600; font-size: 15px; color: var(--azul-senal); min-height: 44px; display: inline-flex; align-items: center; text-decoration: none; }
.vs-articulo__cuerpo .vs-articulo__volver { text-decoration: none; }
.vs-articulo__servicios { margin-top: 36px; }
.vs-articulo__servicios > * { max-width: var(--medida-editorial); }
.vs-articulo__servicios-titulo { font-weight: 500; font-size: 11px; letter-spacing: .14em; text-transform: uppercase; color: var(--tinta-60); margin: 0 0 var(--sp-1); border-top: 2px solid var(--azul-profundo); padding-top: var(--sp-6); }
.vs-articulo__servicio { display: flex; justify-content: space-between; align-items: center; gap: var(--sp-6); padding: var(--sp-4) 0; border-bottom: var(--borde-estructura); min-height: 44px; color: var(--tinta); text-decoration: none; }
.vs-articulo__servicio-nombre { font-family: var(--fuente-titulos); font-weight: 600; font-size: 16px; line-height: 1.35; }
.vs-articulo__servicio-ver { font-family: var(--fuente-titulos); font-weight: 700; color: var(--azul-senal); }
.vs-articulo__servicio-ver { font-size: 0; }
.vs-articulo__servicio-ver [aria-hidden="true"] { font-size: 16px; }
.vs-articulo__cta { margin-top: var(--sp-13); background: var(--azul-profundo); padding: 36px 0; }
.vs-articulo__cta-marco { display: flex; flex-direction: column; gap: 18px; }
.vs-articulo__cta h2 { font-family: var(--fuente-titulos); font-weight: 700; font-size: 22px; line-height: 1.25; color: var(--blanco); margin: 0; }
.vs-articulo__cta-boton { justify-content: center; min-height: 52px; font-weight: 700; font-size: 16px; }
.vs-articulo__mas { padding: var(--sp-13) 0 var(--sp-14); }
.vs-articulo__mas h2 { font-family: var(--fuente-titulos); font-weight: 700; font-size: 24px; line-height: 1.22; margin: 0 0 var(--sp-6); }
.vs-articulo__mas-lista { display: flex; flex-direction: column; gap: var(--sp-6); }
.vs-articulo__mas .vs-blog-card__media { display: none; }
.vs-articulo__mas .vs-blog-card__enlace { border-top-width: 1px; }
.vs-articulo__mas .vs-blog-card__cuerpo { padding: var(--sp-6) 18px; gap: var(--sp-2); }
.vs-articulo__mas .vs-blog-card__titulo { font-size: 17px; }
.vs-articulo__mas .vs-blog-card__fecha { border-top: 0; padding-top: 0; font-size: 11px; }
.vs-articulo__sin-mas { height: var(--sp-14); }
.vs-vista-previa { margin: 0; padding: var(--sp-3) var(--contenedor-margen-mobile); background: var(--error); color: var(--blanco); font-size: 12px; letter-spacing: .12em; text-transform: uppercase; }

@media (min-width: 768px) {
  .vs-articulo__marco { padding-inline: var(--contenedor-margen-tablet); }
  .vs-articulo__encabezado { padding-top: var(--sp-10); }
  .vs-articulo__titulo { font-size: 36px; }
  .vs-articulo__extracto { font-size: 19px; }
  .vs-articulo__principal { width: calc(100% - 2 * var(--contenedor-margen-tablet)); }
  /* 768–1023: una columna de 640, el ancho que la lámina fija para el
     cuerpo y sus imágenes a 768 (≈ 64–66 caracteres a 17 px). `64ch` sobre
     el contenedor la dejaba en 549, porque se mide con la fuente de 15 px del
     contenedor y no con la del texto. */
  .vs-articulo__cuerpo { max-width: 640px; }
  .vs-articulo__cuerpo p { font-size: 17px; }
  .vs-articulo__lista li { font-size: 17px; }
  .vs-articulo__figura { margin: 36px 0; }
  .vs-articulo__cta { margin-top: var(--sp-13); }
  .vs-articulo__cta-marco { align-items: flex-start; }
  .vs-articulo__cta-boton { padding: 0 var(--sp-8); }
  .vs-articulo__mas { padding: var(--sp-13) 0 var(--sp-14); }
}
@media (min-width: 1024px) {
  .vs-articulo__marco { max-width: 944px; margin-inline: auto; padding-inline: 0; box-sizing: content-box; }
  .vs-articulo__encabezado { padding-top: var(--sp-11); }
  .vs-articulo__migas { font-size: 12px; margin-bottom: var(--sp-10); }
  .vs-articulo__categoria { font-size: 12px; margin-bottom: var(--sp-5); }
  .vs-articulo__titulo { font-size: 44px; line-height: 1.14; margin-bottom: var(--sp-10); max-width: 944px; }
  .vs-articulo__cabecera { display: grid; grid-template-columns: 200px 680px; column-gap: var(--sp-15); border-top: var(--borde-estructura); padding-top: var(--sp-8); }
  .vs-articulo__meta { flex-direction: column; flex-wrap: nowrap; gap: var(--sp-5); margin: 0; border-top: 0; padding-top: 0; }
  .vs-articulo__meta dt { position: static; width: auto; height: auto; margin: 0 0 var(--sp-1); overflow: visible; clip: auto; white-space: normal; font-family: var(--fuente-mono); font-size: 11px; letter-spacing: .14em; text-transform: uppercase; color: var(--tinta-60); }
  .vs-articulo__meta dd { font-size: 13px; color: var(--tinta); }
  .vs-articulo__meta-dato--firma dd::before { content: none; }
  .vs-articulo__firma { font-size: 15px; line-height: 1.35; }
  .vs-articulo__extracto { font-size: 21px; max-width: none; }
  .vs-articulo__principal { margin-top: var(--sp-13); width: min(1160px, calc(100% - 2 * var(--contenedor-margen-tablet))); }
  .vs-articulo__contenido { display: grid; grid-template-columns: 200px 680px; column-gap: var(--sp-15); padding-top: var(--sp-14); }
  .vs-articulo__cuerpo { grid-column: 2; max-width: none; }
  .vs-articulo__cuerpo h2 { font-size: 28px; margin: var(--sp-13) 0 var(--sp-6); }
  .vs-articulo__cuerpo h3 { font-size: 21px; margin: var(--sp-10) 0 var(--sp-4); }
  .vs-articulo__cuerpo p { font-size: 18px; line-height: 1.72; margin-bottom: 22px; }
  .vs-articulo__lista { gap: var(--sp-3); margin-bottom: var(--sp-8); }
  .vs-articulo__lista li { grid-template-columns: 22px minmax(0, 1fr); font-size: 18px; line-height: 1.65; }
  .vs-articulo__vineta { margin-top: var(--sp-4); }
  .vs-articulo__lista--numerada li { grid-template-columns: 34px minmax(0, 1fr); }
  .vs-articulo__numero { font-size: 13px; padding-top: var(--sp-1); }
  .vs-articulo__cita { margin: 36px 0; padding-top: 18px; }
  .vs-articulo__cuerpo .vs-articulo__cita p { font-size: 22px; }
  .vs-articulo__volver { margin-top: var(--sp-8); }
  .vs-articulo__servicios { margin-top: var(--sp-14); display: grid; grid-template-columns: 200px 680px; column-gap: var(--sp-15); border-top: 2px solid var(--azul-profundo); padding-top: var(--sp-7); }
  .vs-articulo__servicios > * { max-width: none; }
  .vs-articulo__servicios-titulo { font-size: 12px; border-top: 0; padding-top: 0; margin: var(--sp-1) 0 0; }
  .vs-articulo__servicio { gap: var(--sp-8); padding: var(--sp-5) 0; }
  .vs-articulo__servicio-nombre { font-size: 19px; }
  .vs-articulo__servicio-ver { font-size: 15px; font-weight: 600; }
  .vs-articulo__servicio-ver [aria-hidden="true"] { font-size: inherit; }
  .vs-articulo__cta { margin-top: var(--sp-15); padding: var(--sp-13) 0; }
  .vs-articulo__cta-marco { flex-direction: row; align-items: center; justify-content: space-between; gap: var(--sp-11); }
  .vs-articulo__cta h2 { font-size: 28px; line-height: 1.22; max-width: 26ch; }
  .vs-articulo__cta-boton { flex: none; font-size: 17px; min-height: 56px; padding: 0 var(--sp-10); white-space: nowrap; }
}
@media (min-width: 1120px) {
  .vs-articulo__mas { padding: var(--sp-15) 0 var(--sp-16); }
  .vs-articulo__mas h2 { font-size: 28px; margin-bottom: var(--sp-8); }
  .vs-articulo__mas-lista { display: grid; grid-template-columns: repeat(3, minmax(0, 365px)); gap: var(--sp-10); }
  .vs-articulo__mas .vs-blog-card__media { display: block; }
  .vs-articulo__mas .vs-blog-card--sin-imagen .vs-blog-card__enlace { border-top-width: 2px; }
  .vs-articulo__mas .vs-blog-card__cuerpo { padding: var(--sp-7) 22px 22px; gap: var(--sp-3); }
  .vs-articulo__mas .vs-blog-card__titulo { font-size: 20px; }
  .vs-articulo__mas .vs-blog-card__fecha { border-top: var(--borde-estructura); padding-top: var(--sp-4); font-size: 12px; }
  .vs-articulo__sin-mas { height: var(--sp-16); }
}

/* ---------------------------------------------------------------
   VSCR-106 · Composición propia de la ficha de ferias, exposiciones y
   venues (lámina C-D-E aprobada por el PO el 30-09-2026, con el
   precedente de Retail). El prefijo no repite el slug de la
   Solución porque esta hoja no puede contenerlo.

   Retícula de índices: 1160 útiles (140 de margen a 1440), 32 desde 768
   y 20 en móvil. Desde 768 rigen las medidas de escritorio con rejillas
   de dos columnas; desde 1120, las de cuatro y tres, y el panel de
   concepto al lado del texto.
   --------------------------------------------------------------- */
.vs-ferias__marco {
  --ferias-margen: var(--sp-7);
  max-width: calc(1160px + var(--ferias-margen) * 2);
  margin-inline: auto;
  padding-inline: var(--ferias-margen);
  box-sizing: border-box;
}
@media (min-width: 768px) { .vs-ferias__marco { --ferias-margen: var(--sp-10); } }

/* Cabecera y panel de concepto */
.vs-ferias__cabecera { padding: var(--sp-8) 0 var(--sp-11); }
@media (min-width: 768px) { .vs-ferias__cabecera { padding: var(--sp-11) 0 var(--sp-15); } }
.vs-ferias .vs-migas { color: var(--tinta-60); margin-bottom: var(--sp-7); }
.vs-ferias__hero { display: grid; gap: var(--sp-8); }
@media (min-width: 768px) { .vs-ferias__hero { gap: var(--sp-13); } }
@media (min-width: 1120px) { .vs-ferias__hero { grid-template-columns: minmax(0, 1fr) 420px; align-items: end; } }
.vs-ferias__eyebrow {
  display: inline-block;
  margin-bottom: 18px;
  padding-top: var(--sp-3);
  border-top: 2px solid var(--dorado);
  font-family: var(--fuente-mono);
  font-size: 12px;
  letter-spacing: .14em;
  color: #8A5E00;
}
.vs-ferias h1 { margin-bottom: var(--sp-7); font-size: 30px; line-height: 1.12; letter-spacing: -.02em; text-wrap: balance; }
@media (min-width: 768px) { .vs-ferias h1 { font-size: 44px; } }
.vs-ferias__lead { max-width: 62ch; font-size: 16px; line-height: 1.6; color: var(--tinta-60); text-wrap: pretty; }
@media (min-width: 768px) { .vs-ferias__lead { font-size: 18px; } }
.vs-ferias__concepto { background: var(--azul-profundo); padding: var(--sp-8) var(--sp-7); }
@media (min-width: 768px) { .vs-ferias__concepto { padding: var(--sp-10); } }
.vs-ferias__concepto-frase {
  margin-bottom: var(--sp-5);
  font-family: var(--fuente-titulos);
  font-weight: 700;
  font-size: 20px;
  line-height: 1.25;
  color: var(--blanco);
  text-wrap: balance;
}
@media (min-width: 768px) { .vs-ferias__concepto-frase { font-size: 24px; } }
.vs-ferias__concepto-nota { margin-bottom: 22px; font-size: 14px; line-height: 1.6; color: var(--sobre-oscuro); }
.vs-ferias__acciones { display: flex; flex-wrap: wrap; gap: var(--sp-4); }
.vs-ferias__cta-principal,
.vs-ferias__cta-boton {
  display: flex;
  align-items: center;
  background: var(--dorado);
  color: var(--tinta);
  font-family: var(--fuente-titulos);
  font-weight: 700;
  transition: background-color var(--dur-hover) var(--curva);
}
.vs-ferias__cta-principal { min-height: var(--sp-13); padding: 0 22px; font-size: 15px; }
.vs-ferias__cta-principal:hover,
.vs-ferias__cta-boton:hover { background: #FFD24A; color: var(--tinta); }
/* Enlace dorado de la regla de VSCR-104 (color fijo, foco dorado) con el
   filete siempre visible, como lo dibuja la lámina; la flecha baja 4 px
   en hover y foco porque ancla hacia los pilares. */
.vs-ferias__cta-ancla {
  display: flex;
  align-items: center;
  gap: 6px;
  min-height: var(--sp-13);
  box-sizing: border-box;
  border-bottom: 2px solid var(--dorado);
  font-family: var(--fuente-titulos);
  font-weight: 600;
  font-size: 14px;
  color: var(--dorado);
}
.vs-ferias__cta-ancla:hover,
.vs-ferias__cta-ancla:focus-visible { color: var(--dorado); }
.vs-ferias__cta-ancla-flecha { display: inline-block; transition: transform var(--dur-hover) var(--curva); }
.vs-ferias__cta-ancla:hover .vs-ferias__cta-ancla-flecha,
.vs-ferias__cta-ancla:focus-visible .vs-ferias__cta-ancla-flecha { transform: translateY(4px); }
@media (prefers-reduced-motion: reduce) {
  .vs-ferias__cta-ancla-flecha { transition: none; }
  .vs-ferias__cta-ancla:hover .vs-ferias__cta-ancla-flecha,
  .vs-ferias__cta-ancla:focus-visible .vs-ferias__cta-ancla-flecha { transform: none; }
}

/* Secciones: blanco, #F4F6F8 y navy alternados */
.vs-ferias__seccion { padding-block: var(--sp-13); }
@media (min-width: 768px) { .vs-ferias__seccion { padding-block: 72px; } }
.vs-ferias__seccion--suave { background: var(--fondo-suave); }
.vs-ferias__seccion--oscura { background: var(--azul-profundo); }
/* El ancla del panel de concepto no deja el título bajo el header compacto. */
.vs-ferias__seccion--pilares { scroll-margin-top: var(--sp-11); }
.vs-ferias__titulo { font-size: 26px; line-height: 1.2; }
@media (min-width: 768px) { .vs-ferias__titulo { font-size: 32px; } }
.vs-ferias__titulo--problema { max-width: 22ch; margin-bottom: var(--sp-7); }
.vs-ferias__titulo--pilares { margin-bottom: var(--sp-8); }
.vs-ferias__titulo--como { margin-bottom: var(--sp-2); color: var(--blanco); }
.vs-ferias__titulo--capacidades { margin-bottom: var(--sp-5); }
.vs-ferias__titulo--usos { margin-bottom: var(--sp-7); }
/* H2 en la jerarquía, con el tamaño de un H3 en la lámina.
   «Para profundizar» fuera de esta ficha (VSCR-109, DG-F) comparte estas
   reglas por selector agrupado (I-109-16). Su título sube de especificidad
   para que las reglas de `h2` de los arquetipos A y C no lo alteren. */
.vs-ferias__titulo--valor,
.vs-ferias__titulo--lecturas,
.vs-profundizar .vs-profundizar__titulo { font-size: 21px; line-height: 1.25; }
@media (min-width: 768px) {
  .vs-ferias__titulo--valor,
  .vs-ferias__titulo--lecturas,
  .vs-profundizar .vs-profundizar__titulo { font-size: 24px; }
}
.vs-ferias__titulo--valor { margin-bottom: 6px; }
.vs-ferias__titulo--lecturas,
.vs-profundizar .vs-profundizar__titulo { margin-bottom: var(--sp-6); }
.vs-profundizar .vs-profundizar__titulo { margin-top: 0; letter-spacing: -.015em; }
.vs-ferias__rejilla,
.vs-profundizar__rejilla { display: grid; gap: var(--sp-8); }
@media (min-width: 768px) { .vs-ferias__rejilla, .vs-profundizar__rejilla { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-13); } }

/* Problema */
.vs-ferias__problema { padding-top: var(--sp-6); border-top: 2px solid var(--azul-profundo); }
.vs-ferias__rotulo { margin-bottom: var(--sp-2); font-family: var(--fuente-mono); font-size: 11px; letter-spacing: .14em; color: var(--tinta-60); }
.vs-ferias__problema-texto { font-size: 15px; line-height: 1.65; }
@media (min-width: 768px) { .vs-ferias__problema-texto { font-size: 16px; } }

/* Dos pilares */
.vs-ferias__pilar { display: flex; flex-direction: column; border: var(--borde-estructura); }
.vs-ferias__pilar-medio { position: relative; aspect-ratio: 16 / 9; background: var(--azul-profundo); overflow: hidden; }
/* El visor común ocupa el póster 16:9 del pilar en todos los anchos y queda
   enrasado con la card: sin su borde propio ni la proporción cuadrada que
   el demostrativo toma en móvil. Etiqueta, botón y contrato no cambian. */
.vs-ferias__pilar-medio .vs-matterport { aspect-ratio: auto; height: 100%; border: 0; }
.vs-ferias__pilar-cuerpo { display: flex; flex-direction: column; gap: var(--sp-3); padding: 18px 18px 22px; }
@media (min-width: 768px) { .vs-ferias__pilar-cuerpo { padding: var(--sp-8) var(--sp-9) var(--sp-9); } }
.vs-ferias__pilar-rotulo { font-family: var(--fuente-mono); font-size: 11px; letter-spacing: .14em; color: #8A5E00; }
.vs-ferias__pilar h3 { font-size: 21px; line-height: 1.25; }
@media (min-width: 768px) { .vs-ferias__pilar h3 { font-size: 24px; } }
.vs-ferias__pilar-texto { font-size: 15px; line-height: 1.65; color: var(--tinta-60); }
@media (min-width: 768px) { .vs-ferias__pilar-texto { font-size: 16px; } }
.vs-ferias__pilar-para { font-family: var(--fuente-mono); font-size: 11px; color: var(--tinta-60); }
.vs-ferias__procedencia { margin-top: var(--sp-1); padding-top: var(--sp-3); border-top: var(--borde-estructura); font-size: 13px; line-height: 1.55; color: var(--tinta-60); }
/* VSCR-109 (A8): línea del pilar B que lleva al Servicio de ferias (S5). */
.vs-ferias__pilar-servicio a { display: inline-flex; align-items: center; min-height: 24px; font-family: var(--fuente-titulos); font-weight: 600; font-size: 14px; color: var(--azul-senal); }

/* Cómo se digitaliza una feria */
.vs-ferias__como-lead { max-width: 64ch; margin-bottom: var(--sp-9); font-size: 15px; line-height: 1.6; color: var(--sobre-oscuro); }
@media (min-width: 768px) { .vs-ferias__como-lead { font-size: 16px; } }
.vs-ferias__pasos { display: grid; gap: var(--sp-8); }
@media (min-width: 768px) { .vs-ferias__pasos { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-13); } }
@media (min-width: 1120px) { .vs-ferias__pasos { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.vs-ferias__paso { padding-top: var(--sp-5); border-top: 2px solid var(--dorado); }
.vs-ferias__paso-numero { display: block; margin-bottom: var(--sp-2); font-family: var(--fuente-mono); font-size: 12px; color: var(--dorado); }
.vs-ferias__paso-titulo { margin-bottom: var(--sp-2); font-family: var(--fuente-titulos); font-weight: 600; font-size: 17px; line-height: 1.3; color: var(--blanco); }
.vs-ferias__paso-texto { font-size: 14px; line-height: 1.6; color: var(--sobre-oscuro); }

/* Organizador y expositor: la lista con marcador de VSCR-104 */
.vs-ferias__valor-lead { margin-bottom: var(--sp-6); font-size: 15px; line-height: 1.6; color: var(--tinta-60); }
@media (min-width: 768px) { .vs-ferias__valor-lead { font-size: 16px; } }
.vs-ferias__lista { display: flex; flex-direction: column; gap: var(--sp-3); padding-top: var(--sp-6); border-top: var(--borde-estructura); font-size: 15px; line-height: 1.55; }
.vs-ferias__lista li { display: grid; grid-template-columns: 18px minmax(0, 1fr); align-items: baseline; }
.vs-ferias__lista li::before { content: ''; width: 7px; height: 7px; background: var(--dorado); transform: translateY(-2px); }

/* Capacidades: enlaces a S1 y S4 */
.vs-ferias__capacidades { align-items: start; }
.vs-ferias__texto-atenuado { font-size: 15px; line-height: 1.65; color: var(--tinta-60); }
@media (min-width: 768px) { .vs-ferias__texto-atenuado { font-size: 16px; } }
.vs-ferias__servicios { display: flex; flex-direction: column; }
.vs-ferias__servicio {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--sp-7);
  min-height: var(--sp-12);
  padding: 18px 0;
  border-top: 2px solid var(--azul-profundo);
  color: var(--tinta);
}
.vs-ferias__servicio-nombre { display: block; margin-bottom: var(--sp-1); font-family: var(--fuente-titulos); font-weight: 600; font-size: 18px; }
.vs-ferias__servicio-descripcion { font-size: 14px; line-height: 1.5; color: var(--tinta-60); }
.vs-ferias__servicio-enlace { font-family: var(--fuente-titulos); font-weight: 600; font-size: 14px; color: var(--azul-senal); white-space: nowrap; }

/* Usos posibles y alcance */
.vs-ferias__usos { display: grid; gap: var(--sp-8); }
@media (min-width: 768px) { .vs-ferias__usos { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-13); } }
@media (min-width: 1120px) { .vs-ferias__usos { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.vs-ferias__uso { padding-top: var(--sp-5); border-top: var(--borde-estructura); }
.vs-ferias__uso-numero { display: block; margin-bottom: 6px; font-family: var(--fuente-mono); font-size: 11px; color: var(--tinta-60); }
.vs-ferias__uso-titulo { margin-bottom: 6px; font-family: var(--fuente-titulos); font-weight: 600; font-size: 16px; line-height: 1.35; }
.vs-ferias__uso-texto { font-size: 14px; line-height: 1.55; color: var(--tinta-60); }
.vs-ferias__alcance { max-width: 900px; margin-top: var(--sp-11); padding-top: var(--sp-6); border-top: 2px solid var(--dorado); }
.vs-ferias__alcance-titulo { margin-bottom: var(--sp-2); font-family: var(--fuente-titulos); font-weight: 600; font-size: 17px; }
.vs-ferias__alcance p:not(.vs-ferias__alcance-titulo) { font-size: 14px; line-height: 1.65; color: var(--tinta-60); }

/* CTA */
.vs-ferias__cta { padding-block: 36px; background: var(--azul-profundo); }
@media (min-width: 768px) { .vs-ferias__cta { padding-block: var(--sp-13); } }
.vs-ferias__cta-marco { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--sp-8); }
.vs-ferias__cta-cuerpo { max-width: 620px; }
.vs-ferias__cta-cuerpo h2 { margin-bottom: var(--sp-2); font-size: 21px; line-height: 1.25; color: var(--blanco); }
@media (min-width: 768px) { .vs-ferias__cta-cuerpo h2 { font-size: 24px; } }
.vs-ferias__cta-cuerpo p { font-size: 15px; line-height: 1.6; color: var(--sobre-oscuro); }
.vs-ferias__cta-boton { min-height: 52px; padding: 0 var(--sp-9); font-size: 16px; }

/* Para profundizar: sólo existe con artículos publicados del clúster. Mismas
   reglas para el bloque compartido de VSCR-109 (`views/_para-profundizar.php`). */
.vs-ferias__lectura,
.vs-profundizar__lectura { display: block; padding: var(--sp-6) 0; border-top: 2px solid var(--azul-profundo); color: var(--tinta); }
.vs-ferias__lectura-titulo,
.vs-profundizar__lectura-titulo { display: block; margin-bottom: 6px; font-family: var(--fuente-titulos); font-weight: 600; font-size: 17px; line-height: 1.35; }
.vs-ferias__lectura-enlace,
.vs-profundizar__lectura-enlace { font-family: var(--fuente-titulos); font-weight: 600; font-size: 14px; color: var(--azul-senal); }

/* Bloque interdivisional Virtual Space × Servitec GyG (VSCR-109, DG-G, lámina
   G). Un solo componente con dos variantes de contenido. La jerarquía la marca
   el filete: navy para Virtual Space y gris para Servitec GyG, que aparece como
   división de desarrollo de software y sin logo. El kicker y las etiquetas
   conservan la caja del copy («GyG»): no usan `.vs-mono`, que impone
   mayúsculas. El flujo por capas es opcional; cada paso nombra a su
   responsable en texto y el filete sólo lo refuerza. Los párrafos suben de
   especificidad porque la ficha del arquetipo A fija `p` a 17 px. */
.vs-interdivisional { border: var(--borde-estructura); padding: 22px 18px; }
@media (min-width: 768px) { .vs-interdivisional { padding: var(--sp-10) 36px; } }
.vs-interdivisional .vs-interdivisional__kicker { margin: 0 0 var(--sp-3); font-family: var(--fuente-mono); font-size: 11px; letter-spacing: .14em; color: #8A5E00; }
.vs-interdivisional .vs-interdivisional__titulo { max-width: 24ch; margin: 0 0 var(--sp-4); font-size: 23px; line-height: 1.2; letter-spacing: -.015em; }
@media (min-width: 768px) { .vs-interdivisional .vs-interdivisional__titulo { font-size: 26px; } }
@media (min-width: 1120px) { .vs-interdivisional .vs-interdivisional__titulo { font-size: 28px; } }
.vs-interdivisional .vs-interdivisional__lead { max-width: 62ch; margin: 0 0 var(--sp-8); font-size: 16px; line-height: 1.65; color: var(--tinta-60); }
.vs-interdivisional__flujo { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-6); margin: 0 0 var(--sp-4); padding: 0; list-style: none; }
@media (min-width: 768px) { .vs-interdivisional__flujo { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--sp-7); } }
@media (min-width: 1120px) { .vs-interdivisional__flujo { grid-template-columns: repeat(6, minmax(0, 1fr)); gap: var(--sp-6); } }
.vs-interdivisional__paso { display: flex; flex-direction: column; padding-top: var(--sp-4); border-top: 2px solid var(--azul-profundo); }
.vs-interdivisional__paso--sg { border-top-color: var(--tinta-30); }
.vs-interdivisional__paso--cliente { border-top: 2px dashed var(--tinta-30); }
.vs-interdivisional__paso-numero { margin-bottom: 6px; font-family: var(--fuente-mono); font-size: 11px; color: var(--tinta-45); }
/* El flujo de seis columnas vive dentro de la caja del componente (748 px
   útiles desde 1120): «Disponibilidad» mide 121 px en una celda de 111. Se
   parte por sílabas en vez de desbordar hacia el hueco. */
.vs-interdivisional__paso-titulo { margin-bottom: 6px; font-family: var(--fuente-titulos); font-weight: 700; font-size: 16px; line-height: 1.3; color: var(--tinta); hyphens: auto; overflow-wrap: break-word; }
.vs-interdivisional__paso-quien { font-family: var(--fuente-mono); font-size: 10px; letter-spacing: .1em; line-height: 1.5; color: var(--tinta-60); }
.vs-interdivisional__paso--vs .vs-interdivisional__paso-quien { color: var(--azul-profundo); }
.vs-interdivisional__leyenda { display: flex; flex-wrap: wrap; gap: var(--sp-2) var(--sp-7); margin: 0 0 var(--sp-9); padding: 0; list-style: none; font-family: var(--fuente-mono); font-size: 10px; letter-spacing: .08em; color: var(--tinta-60); }
.vs-interdivisional__leyenda-item { display: flex; align-items: center; gap: 6px; }
.vs-interdivisional__leyenda-item::before { content: ""; width: 18px; border-top: 2px solid var(--azul-profundo); }
.vs-interdivisional__leyenda-item--sg::before { border-top-color: var(--tinta-30); }
.vs-interdivisional__leyenda-item--cliente::before { border-top-style: dashed; border-top-color: var(--tinta-30); }
.vs-interdivisional__columnas { display: grid; gap: var(--sp-8); }
@media (min-width: 768px) { .vs-interdivisional__columnas { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-11); } }
.vs-interdivisional__columna { padding-top: var(--sp-5); border-top: 2px solid var(--azul-profundo); }
.vs-interdivisional__columna--sg { border-top-color: var(--tinta-30); }
.vs-interdivisional .vs-interdivisional__etiqueta { margin: 0 0 6px; font-family: var(--fuente-mono); font-size: 11px; letter-spacing: .12em; color: var(--azul-profundo); }
.vs-interdivisional .vs-interdivisional__columna--sg .vs-interdivisional__etiqueta { color: var(--tinta-60); }
.vs-interdivisional .vs-interdivisional__columna-titulo { margin: 0 0 var(--sp-3); font-family: var(--fuente-titulos); font-weight: 700; font-size: 17px; line-height: 1.3; letter-spacing: normal; }
.vs-interdivisional__lista { display: flex; flex-direction: column; gap: var(--sp-2); margin: 0; padding: 0; list-style: none; }
.vs-interdivisional__lista li { display: grid; grid-template-columns: 18px minmax(0, 1fr); align-items: baseline; font-size: 15px; line-height: 1.55; }
.vs-interdivisional__lista li::before { content: ""; width: 7px; height: 7px; background: var(--dorado); transform: translateY(-2px); }
.vs-interdivisional__columna--sg .vs-interdivisional__lista li::before { background: transparent; border: 1.5px solid var(--tinta-60); box-sizing: border-box; }
.vs-interdivisional .vs-interdivisional__cierre { margin: 22px 0 0; padding-top: var(--sp-5); border-top: var(--borde-estructura); font-size: 14px; line-height: 1.6; color: var(--tinta); }
.vs-interdivisional__cierre strong { font-family: var(--fuente-titulos); font-weight: 700; }

/* ---------------------------------------------------------------
   S5 · Digitalización 3D de ferias y exposiciones (VSCR-109, DG-A,
   lámina A). Composición propia fuera de la familia (I-109-09) que
   reutiliza sus piezas: cabecera, visor común, Proceso, D-85-15 y banda
   CTA. Aquí sólo lo nuevo: fondos alternos, modalidades, filas enlazadas,
   alcance y tecnología. Anchos de la familia (820 / 940 / 1160).
   --------------------------------------------------------------- */
.vs-s5__seccion { padding-block: var(--sp-11); }
@media (min-width: 768px) { .vs-s5__seccion { padding-block: var(--sp-14); } }
@media (min-width: 1120px) { .vs-s5__seccion { padding-block: var(--sp-15); } }
.vs-s5__seccion--suave { background: var(--fondo-suave); }
.vs-s5__seccion--sin-arriba { padding-top: 0; }
.vs-s5__seccion--visor { padding-bottom: 0; }
.vs-s5 .vs-s5__procedencia { margin: var(--sp-3) 0 var(--sp-11); font-size: 13px; line-height: 1.55; color: var(--tinta-60); }
.vs-s5 .vs-s5__titulo,
.vs-s5__aplicaciones h2 { margin: 0 0 var(--sp-2); font-size: 23px; line-height: 1.2; letter-spacing: -.015em; }
.vs-s5__aplicaciones h2 { margin-bottom: var(--sp-7); }
.vs-fam__estructurado > .vs-s5__titulo { margin-bottom: var(--sp-7); }
@media (min-width: 768px) {
  .vs-s5 .vs-s5__titulo,
  .vs-s5__aplicaciones h2 { font-size: 26px; }
}
@media (min-width: 1120px) {
  .vs-s5 .vs-s5__titulo,
  .vs-s5__aplicaciones h2 { font-size: 28px; }
}
.vs-s5 .vs-s5__intro { max-width: 64ch; margin: 0 0 var(--sp-11); font-size: 16px; line-height: 1.7; color: var(--tinta); }
.vs-s5 .vs-s5__lead { max-width: 60ch; margin: 0 0 var(--sp-8); font-size: 16px; line-height: 1.6; color: var(--tinta-60); }

/* Modalidades: tres cards blancas con filete navy; tres columnas desde 1120. */
.vs-s5__modalidades { display: grid; gap: var(--sp-6); }
@media (min-width: 768px) { .vs-s5__modalidades { gap: var(--sp-7); } }
@media (min-width: 1120px) { .vs-s5__modalidades { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--sp-8); } }
.vs-s5__modalidad { display: flex; flex-direction: column; gap: var(--sp-5); padding: 20px 18px 18px; background: var(--blanco); border-top: 3px solid var(--azul-profundo); }
@media (min-width: 768px) { .vs-s5__modalidad { padding: var(--sp-8) var(--sp-8) var(--sp-7); } }
@media (min-width: 1120px) { .vs-s5__modalidad { padding: 26px 26px 22px; } }
.vs-s5 .vs-s5__modalidad-kicker { margin: 0; font-family: var(--fuente-mono); font-size: 11px; letter-spacing: .14em; color: #8A5E00; }
.vs-s5__modalidad h3 { margin: 0; font-family: var(--fuente-titulos); font-weight: 700; font-size: 19px; line-height: 1.25; }
@media (min-width: 768px) { .vs-s5__modalidad h3 { font-size: 20px; } }
@media (min-width: 1120px) { .vs-s5__modalidad h3 { font-size: 21px; } }
.vs-s5 .vs-s5__modalidad-para { margin: 0; font-size: 14px; line-height: 1.55; color: var(--tinta-60); }
.vs-s5__modalidad-ficha { display: flex; flex-direction: column; margin: 0; }
.vs-s5__modalidad-ficha > div { padding: var(--sp-4) 0; border-top: var(--borde-estructura); }
.vs-s5__modalidad-ficha > div:last-child { padding-bottom: 0; }
.vs-s5__modalidad-ficha dt { margin-bottom: var(--sp-1); font-family: var(--fuente-mono); font-size: 11px; letter-spacing: .12em; color: var(--tinta-60); }
.vs-s5__modalidad-ficha dd { margin: 0; font-size: 15px; line-height: 1.6; color: var(--tinta); }

/* Capacidades: texto y filas enlazadas a S1 y S4 (filete navy, ≥ 44 px). */
.vs-s5__capacidades { display: grid; gap: var(--sp-8); }
@media (min-width: 768px) { .vs-s5__capacidades { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-10); align-items: start; } }
@media (min-width: 1120px) { .vs-s5__capacidades { gap: var(--sp-11); } }
.vs-s5__capacidades .vs-s5__titulo { margin-bottom: var(--sp-5); }
.vs-s5 .vs-s5__texto-atenuado { margin: 0; font-size: 16px; line-height: 1.65; color: var(--tinta-60); }
.vs-s5__filas { display: flex; flex-direction: column; }
.vs-s5__fila { display: flex; justify-content: space-between; align-items: center; gap: var(--sp-7); min-height: var(--sp-12); padding: var(--sp-6) 0; border-top: 2px solid var(--azul-profundo); color: var(--tinta); }
.vs-s5__fila-nombre { display: block; margin-bottom: var(--sp-1); font-family: var(--fuente-titulos); font-weight: 600; font-size: 17px; }
.vs-s5__fila-texto { font-size: 14px; line-height: 1.5; color: var(--tinta-60); }
.vs-s5__fila-enlace { font-family: var(--fuente-titulos); font-weight: 600; font-size: 14px; color: var(--azul-senal); white-space: nowrap; }
.vs-s5__fila--solucion { flex-wrap: wrap; gap: var(--sp-2) var(--sp-7); margin-top: var(--sp-9); }
.vs-s5__fila--solucion .vs-s5__fila-texto { max-width: 56ch; font-size: 15px; line-height: 1.55; }

/* Alcance: filete izquierdo y límites en lista (región del CMS). */
.vs-s5__alcance { padding-left: var(--sp-6); border-left: 3px solid var(--borde); }
@media (min-width: 768px) { .vs-s5__alcance { padding-left: var(--sp-7); } }
@media (min-width: 1120px) { .vs-s5__alcance { padding-left: var(--sp-8); } }
.vs-s5 .vs-s5__alcance h2,
.vs-s5 .vs-s5__tecnologia h2 { margin: 0 0 var(--sp-4); font-size: 19px; line-height: 1.3; letter-spacing: normal; }
.vs-s5 .vs-s5__alcance h2 { color: var(--tinta-60); }
@media (min-width: 768px) {
  .vs-s5 .vs-s5__alcance h2,
  .vs-s5 .vs-s5__tecnologia h2 { font-size: 20px; }
}
@media (min-width: 1120px) {
  .vs-s5 .vs-s5__alcance h2,
  .vs-s5 .vs-s5__tecnologia h2 { font-size: 21px; }
}
.vs-s5__alcance ul { display: flex; flex-direction: column; gap: 6px; margin: 0; padding-left: 18px; list-style: disc; font-size: 15px; line-height: 1.6; color: var(--tinta-60); }

/* Tecnología y alojamiento de la experiencia: dos columnas desde 768. */
.vs-s5__tecnologia { display: grid; gap: var(--sp-8); }
@media (min-width: 768px) { .vs-s5__tecnologia { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-10); } }
@media (min-width: 1120px) { .vs-s5__tecnologia { gap: var(--sp-11); } }
.vs-s5 .vs-s5__tecnologia p { margin: 0; font-size: 15px; line-height: 1.6; color: var(--tinta-60); }
