/*
 * ============================================================
 *  vms-core.css — Núcleo de componentes VMS Energy
 *  Versión 1.0 · agosto 2026 · fase F-0
 * ============================================================
 *
 *  QUÉ ES
 *  Consolida los 299 selectores compartidos que hoy viven repetidos
 *  dentro de las 93 páginas del prototipo, de los cuales 182 tenían
 *  definiciones que ya no coincidían entre sí. Son ~5,286
 *  declaraciones que se reducen a este archivo.
 *
 *  CÓMO SE CONSOLIDÓ
 *  No es una fusión mecánica. Fusionar 182 definiciones en conflicto
 *  solo habría codificado el desorden. Para cada componente se tomó
 *  la definición canónica —la más frecuente en el prototipo— y se
 *  reescribió contra los tokens, unificando los valores que estaban
 *  a un pelo de distancia unos de otros:
 *
 *    · Radios 14px / 16px / 18px          → --radius-card (14px)
 *    · Tres sombras casi idénticas
 *      (0 8px 24px · 0 10px 26px · 0 12px 28px, todas rgba(9,32,58,.06–.1))
 *                                          → --shadow-card / --shadow-hover
 *    · #fff, var(--cobalt), rgba(23,44,81,.12) sueltos → tokens
 *
 *  DEPENDE DE tokens.css v2.0. Cero colores literales: si algo aquí
 *  necesita un valor nuevo, se agrega a tokens.css, no a este archivo.
 *
 *  ORDEN DE CARGA
 *    <link rel="stylesheet" href="tokens.css">
 *    <link rel="stylesheet" href="vms-core.css">
 *    <link rel="stylesheet" href="vms-header.css">
 *
 *  ALCANCE — lo que SÍ cubre este archivo
 *    layout · tipografía · botones · tarjetas · hero · KPI · píldoras
 *    formularios · pie de página · artículo de blog · utilidades
 *
 *  ALCANCE — lo que NO cubre todavía (queda para F-3, por página)
 *    · `catalogx` — el buscador de catálogo de la home (238 páginas·sel)
 *    · `quicklead-modal` / `quicklead-form` (145) y `sticky-actions` (113)
 *    · `process-slide` (60) — el carrusel de proceso
 *    Son componentes con JavaScript propio y merecen su módulo. Se
 *    consolidan cuando su página entre al lote correspondiente.
 * ============================================================ */


/* ============================================================
   1 · BASE
   ============================================================ */
*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--bg-page);
  color: var(--text-primary);
  font-family: var(--font-body);
  font-size: var(--fs-base);
  line-height: var(--lh-base);
  -webkit-font-smoothing: antialiased;
}

img, svg, video { max-width: 100%; height: auto; display: block; }

a { color: var(--concept-primary); }

h1, h2, h3, h4 {
  margin: 0 0 .5em;
  line-height: var(--lh-tight);
  text-wrap: balance;
  font-weight: var(--font-weight-bold);
}
h1 { font-size: var(--fs-hero); }
h2 { font-size: var(--fs-2xl); }
h3 { font-size: var(--fs-xl); }
h4 { font-size: var(--fs-lg); }

p { margin: 0 0 1em; }
p:last-child { margin-bottom: 0; }

/* Texto largo legible. Antes cada página fijaba su propio ancho. */
.prose { max-width: var(--max-width-read); }


/* ============================================================
   2 · LAYOUT
   Antes: `.container` con 9 definiciones distintas en 33 páginas.
   ============================================================ */
.container {
  width: 100%;
  max-width: var(--max-width-wide);
  margin-inline: auto;
  padding-inline: clamp(1rem, 4vw, 1.5rem);
}
.container--narrow { max-width: var(--max-width); }

/* El ritmo vertical sale del concepto de la página (tokens.css §8):
   corporativo 72px · equipamiento 56px · e-shop 48px. Es la
   diferenciación que antes hacía el color. */
.section { padding-block: var(--section-pad-y); }
.section--alt  { background: var(--concept-section-alt); }
.section--soft { background: var(--bg-soft); }
.section--dark {
  background: var(--concept-section-dark);
  color: var(--text-invert);
}
.section--dark h1, .section--dark h2,
.section--dark h3, .section--dark h4 { color: var(--text-invert); }
.section--dark p  { color: var(--text-on-dark); }
.section--dark a  { color: var(--vms-blue-200); }

/* Rejilla única. Antes `.grid` tenía 7 definiciones en 14 páginas,
   casi todas resolviendo lo mismo con distinto breakpoint. */
.grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(var(--grid-min), 1fr));
  gap: var(--grid-gap);
}
.grid--2 { grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr)); }
.grid--tight { --grid-gap: 14px; }

.stack { display: flex; flex-direction: column; gap: var(--grid-gap); }
.cluster { display: flex; flex-wrap: wrap; gap: .6rem; align-items: center; }


/* ============================================================
   3 · BOTONES
   Antes: `.btn` con 19 definiciones en 61 páginas,
   `.btn--primary` con 14 y `.btn--secondary` con 13.
   ============================================================ */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 12px 18px;
  border: 1px solid transparent;
  border-radius: var(--radius-card);
  font-family: var(--font-body);
  font-weight: var(--font-weight-bold);
  font-size: var(--fs-sm);
  line-height: 1.2;
  text-decoration: none;
  cursor: pointer;
  transition: background var(--transition-base), border-color var(--transition-base), color var(--transition-base);
}
.btn--pill { border-radius: var(--radius-btn); }

.btn--primary {
  background: var(--concept-btn-primary);
  color: var(--concept-btn-text);
}
.btn--primary:hover,
.btn--primary:focus-visible { background: var(--concept-btn-hover); }

/* CORREGIDO. La versión anterior era `color:#fff` con borde blanco:
   solo funcionaba sobre fondo oscuro, y en secciones claras quedaba
   texto blanco sobre blanco. Ahora la variante clara es la base y la
   oscura es explícita. */
.btn--secondary {
  background: transparent;
  border-color: var(--border-strong);
  color: var(--concept-primary);
}
.btn--secondary:hover,
.btn--secondary:focus-visible {
  background: var(--vms-blue-50);
  border-color: var(--concept-primary);
}

.btn--on-dark {
  background: transparent;
  border-color: rgba(255, 255, 255, .42);
  color: var(--text-invert);
}
.btn--on-dark:hover,
.btn--on-dark:focus-visible { background: rgba(255, 255, 255, .12); }

/* ------------------------------------------------------------
   CONTEXTO OSCURO — `.on-dark` en el contenedor, no en el botón
   ------------------------------------------------------------
   Por qué existe. `.btn--secondary` se usa 218 veces en 56 páginas, y al
   medir el fondo real detrás de cada una (muestreando píxeles del render,
   no la propiedad background-color, que en estos heroes es transparente
   porque el azul viene de un ::before) resultó que 73 de 195 visibles
   están sobre azul marino: heroes y bandas de cierre de artículo.

   Cada una de esas páginas lo resolvía por su cuenta, y así aparecieron
   16 definiciones distintas de `.btn--secondary`. Una de ellas —variante
   oscura aplicada en una sección clara— dejaba el botón blanco sobre
   blanco en `certificaciones.html`.

   El contexto va en el contenedor y no en el botón por dos razones: son
   73 contenedores contra 218 botones, y varios de esos botones los genera
   JavaScript a partir de plantillas, donde no hay una clase que editar.

   Se marcaron sólo los contenedores medidos como oscuros. `.hero__actions`
   NO se usó como señal: en `procura.html` es la fila de un formulario claro
   y en `soluciones.html` vive en una sección clara. Inferir el contexto por
   el nombre de la clase habría reintroducido el bug de blanco sobre blanco
   en esas dos páginas. */
/* ------------------------------------------------------------
   Jerarquia de botones sobre fondo oscuro
   ------------------------------------------------------------
   Faltaba la variante oscura de `.btn--primary`. Mientras cada pagina
   repintaba el primario por su cuenta —naranja, verde, degradados— el hueco
   no se notaba: cualquier color distinto al de la banda lo hacia visible. Al
   retirar esas 60 redefiniciones y dejar que gobierne el nucleo, el primario
   quedo del MISMO azul #0F4C81 que la banda que lo contiene: invisible salvo
   por su texto. Lo detecto la medicion comparando el antes y el despues, no
   el ojo.

   Sobre oscuro la jerarquia se invierte respecto al fondo claro:

     primario    relleno blanco, texto azul  — lo mas fuerte de la banda
     secundario  contorno blanco solido      — un escalon abajo
     fantasma    contorno tenue (42%)        — lo mas discreto

   El secundario deja de ser relleno blanco: con el primario ya en blanco,
   dos rellenos identicos uno al lado del otro no son una jerarquia.
   ------------------------------------------------------------ */
.on-dark .btn--primary {
  background: var(--bg-page);
  border-color: transparent;
  color: var(--concept-primary);
}
.on-dark .btn--primary:hover,
.on-dark .btn--primary:focus-visible {
  background: var(--vms-blue-50);
  border-color: transparent;
}

.on-dark .btn--secondary {
  background: transparent;
  border: 1px solid var(--text-invert);
  color: var(--text-invert);
}
.on-dark .btn--secondary:hover,
.on-dark .btn--secondary:focus-visible {
  background: rgba(255, 255, 255, .12);
  border-color: var(--text-invert);
}

/* Texto y enlaces sueltos dentro de una fila de acciones oscura. */
.on-dark { color: var(--text-on-dark); }
.on-dark a:not(.btn) { color: var(--text-invert); }

/* ------------------------------------------------------------
   `.btn--ghost` — el botón de contorno
   ------------------------------------------------------------
   Se usa 68 veces en 43 páginas y estaba definido en OCHO sitios a la vez:
   cuatro hojas base, cuatro páginas y —por descuido nuestro— tokens.css,
   que sólo debería declarar tokens. Las variantes se diferenciaban en el
   alfa del borde blanco: .26, .35, .38, .45 y .5. Nadie decidió esos cinco
   valores; se fueron copiando.

   Al medir el fondo real detrás de cada instancia, **58 de 64 (91 %) están
   sobre oscuro**. Igual que `.btn--secondary`, la clase significaba en la
   práctica «el botón de contorno del hero», no «botón de contorno».

   El sistema queda con la pareja completa y explícita:
     .btn--secondary  → énfasis relleno   (blanco sólido sobre oscuro)
     .btn--ghost      → contorno          (borde, sin relleno)
   y cada uno con su versión clara y su versión bajo `.on-dark`. */
/* Se escribe `.btn.btn--ghost` —doble clase, (0,2,0)— y no `.btn--ghost` a
   secas. `sectorial-base.css` y `servicios-base.css` declaran
   `.btn--ghost{border:2px solid rgba(255,255,255,.35);color:#fff}` en (0,1,0)
   y cargan DESPUÉS del núcleo: con especificidad igual gana la última, y esa
   variante de fondo oscuro se filtraba a las secciones claras dejando el botón
   blanco sobre blanco. Pasó de verdad en tres botones de `soluciones_mineria`
   en cuanto se quitó la regla local que lo tapaba. */
.btn.btn--ghost {
  background: transparent;
  color: var(--concept-primary);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-btn);
}
.btn.btn--ghost:hover,
.btn.btn--ghost:focus-visible { background: var(--vms-blue-50); }

/* Sobre oscuro, (0,3,0): por encima tanto del núcleo claro como de las cinco
   definiciones heredadas. El alfa unificado es .42, el mismo de `.btn--on-dark`. */
.on-dark .btn.btn--ghost {
  background: transparent;
  border-color: rgba(255, 255, 255, .42);
  color: var(--text-invert);
}
.on-dark .btn.btn--ghost:hover,
.on-dark .btn.btn--ghost:focus-visible {
  background: rgba(255, 255, 255, .12);
  border-color: rgba(255, 255, 255, .7);
}

/* Fila de acciones de la banda de cierre.
   Existía en 27 páginas como `style="display:flex;gap:14px;justify-content:
   center;flex-wrap:wrap"` escrito a mano, con el botón de contorno llevando
   además su propio `style="color:#fff;border-color:rgba(255,255,255,.5)"`.
   Un estilo en línea le gana a cualquier hoja: mientras estuviera ahí, el
   sistema no podía gobernar ese botón por más reglas que declarara. */
.cta-band__actions {
  display: flex;
  flex-wrap: wrap;
  gap: .875rem;
  justify-content: center;
}

/* Compra — acento comercial, no identidad (ver tokens.css §3) */
.btn--buy { background: var(--commerce); color: var(--text-invert); }
.btn--buy:hover, .btn--buy:focus-visible { filter: brightness(.92); }

.btn[disabled], .btn[aria-disabled="true"] { opacity: .55; pointer-events: none; }


/* ============================================================
   4 · TARJETAS
   Antes: `.card` (10 defs), `.svc-card` (3), `.case-card`,
   `.sidebar-card` (2), `.challenge-card`, `.privacy-card` — seis
   componentes que eran la misma tarjeta con radios y sombras
   ligeramente distintos.
   ============================================================ */
.card {
  background: var(--bg-page);
  border: 1px solid var(--border-line);
  border-radius: var(--radius-card);
  padding: var(--card-pad);
  box-shadow: var(--shadow-card);
  transition: box-shadow var(--transition-base), border-color var(--transition-base);
}
.card:hover { box-shadow: var(--shadow-hover); }

.card--soft   { background: var(--bg-soft); box-shadow: none; }
.card--flush  { padding: 0; overflow: hidden; }
.card--accent { border-color: var(--concept-accent); }

.card__media { aspect-ratio: 3 / 2; overflow: hidden; background: var(--bg-surface); }
.card__media img { width: 100%; height: 100%; object-fit: cover; }
.card__body { padding: var(--card-pad); display: flex; flex-direction: column; gap: .5rem; }
.card__title { font-size: var(--fs-lg); font-weight: var(--font-weight-bold); margin: 0; }
.card__text  { color: var(--text-muted); font-size: var(--fs-sm); margin: 0; }

/* Caso de éxito — tarjeta destacada */
.card--case { border-color: var(--concept-accent); box-shadow: var(--shadow-hover); }


/* ============================================================
   5 · HERO
   Antes: `.hero` con 16 definiciones en 49 páginas, y dos patrones
   incompatibles para la imagen de fondo (.hero::before y .hero__frame).
   El alto y el velo salen del concepto (tokens.css §8).
   ============================================================ */
.hero {
  position: relative;
  min-height: var(--hero-min-h);
  display: flex;
  align-items: center;
  color: var(--text-invert);
  background: var(--concept-hero-gradient);
  isolation: isolate;
}
.hero__inner { position: relative; z-index: 1; padding-block: clamp(2.5rem, 6vw, 4.5rem); }
.hero h1 { color: var(--text-invert); max-width: 18ch; }
.hero__lede {
  color: var(--concept-hero-tag-text);
  font-size: var(--fs-lg);
  max-width: 52ch;
}
.hero__actions { display: flex; flex-wrap: wrap; gap: .75rem; margin-top: 1.5rem; }

/* Hero con fotografía. La imagen la fija la página; el velo, el token.
   Ver tokens.css §10 para por qué la imagen no vive en el sistema. */
.hero--photo::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background:
    linear-gradient(105deg,
      rgba(11, 26, 48, var(--hero-overlay)),
      rgba(23, 44, 81, calc(var(--hero-overlay) * .72)) 55%,
      rgba(15, 76, 129, calc(var(--hero-overlay) * .45))),
    var(--hero-image, none) center / cover no-repeat;
}

/* ------------------------------------------------------------
   `.hero--veil-flat` — velo plano para fotografias claras
   ------------------------------------------------------------
   El velo de `.hero--photo` es diagonal: abre de var(--hero-overlay) a
   .45 del mismo alfa en el borde derecho. Funciona cuando la fotografia
   tiene su zona clara a la derecha y el texto vive a la izquierda.

   Los heros de la serie de tres registros (dibujo / transicion / foto)
   ponen la fotografia justo ahi, y a 768 y 390 px el texto ocupa el
   ancho completo: cae sobre la parte abierta del velo y baja de 4.5:1.
   Medido: fondos de RGB(100..160) bajo texto #DBEAFE dan 2.7 a 3.8.

   Esta variante mantiene el alfa casi constante (94 % y 88 % en vez de
   72 % y 45 %), conservando la direccion del degradado pero sin abrirlo.
   Se aplica por pagina, con `class="hero hero--photo hero--veil-flat"`.
   ------------------------------------------------------------ */
.hero--photo.hero--veil-flat::before {
  background:
    linear-gradient(105deg,
      rgba(8, 20, 40, var(--hero-overlay)),
      rgba(11, 26, 48, calc(var(--hero-overlay) * .94)) 55%,
      rgba(15, 40, 72, calc(var(--hero-overlay) * .88))),
    var(--hero-image, none) center / cover no-repeat;
}


/* ============================================================
   6 · KPI Y DATOS
   ============================================================ */
.kpi {
  display: flex;
  align-items: center;
  gap: 12px;
  background: var(--bg-soft);
  border: 1px solid var(--border-line);
  border-radius: var(--radius-card);
  padding: var(--card-pad);
}
.kpi__value {
  font-size: var(--fs-2xl);
  font-weight: var(--font-weight-bold);
  line-height: 1;
  color: var(--concept-primary);
  font-variant-numeric: tabular-nums;
}
.kpi__label { font-size: var(--fs-sm); color: var(--text-muted); }

/* Tira de KPI sobre fondo oscuro */
.kpi-band { background: var(--concept-kpi-bg); color: var(--text-invert); }
/* 26-ago-2026: el reset existia solo para .kpi-band. Las paginas sectoriales y de
   servicios usan .kpi-strip, asi que sus tarjetas quedaban casi blancas bajo el
   texto claro: contraste 1.15:1 en la etiqueta, 1.66:1 en el numero. */
.kpi-band .kpi,
.kpi-strip .kpi { background: transparent; border-color: rgba(255, 255, 255, .16); }
.kpi-band .kpi__value,
.kpi-strip .kpi__value { color: var(--concept-kpi-val); }
.kpi-band .kpi__label,
.kpi-strip .kpi__label { color: var(--concept-kpi-lbl); }


/* ============================================================
   7 · PÍLDORAS, ETIQUETAS Y BADGES
   Antes: `.tag` (3 defs), `.pill` (4) y `.badge` (8) hacían
   prácticamente lo mismo con valores distintos. Se unifican en un
   solo componente con variantes.
   ============================================================ */
.pill {
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  padding: .16rem .55rem;
  border: 1px solid var(--border-line);
  border-radius: var(--radius-tag);
  font-size: var(--fs-xs);
  color: var(--text-muted);
  background: var(--bg-page);
}
.pill--solid  { background: var(--concept-primary); border-color: transparent; color: var(--text-invert); }
.pill--soft   { background: var(--concept-accent-light); border-color: transparent; color: var(--concept-accent-text); }
.pill--norm   { background: var(--vms-blue-100); color: var(--spec-badge-norm); font-weight: var(--font-weight-bold); border-color: transparent; border-radius: 4px; }
.pill--ok     { background: var(--success-bg); color: var(--success); border-color: transparent; }
.pill--warn   { background: var(--warning-bg); color: var(--urgency-badge-text); border-color: transparent; }
.pill--danger { background: var(--danger-bg); color: var(--danger); border-color: transparent; }


/* ============================================================
   8 · TABLAS TÉCNICAS
   La densidad sale del concepto: equipamiento y e-shop la aprietan.
   ============================================================ */
.table-wrap { overflow-x: auto; border: 1px solid var(--border-line); border-radius: var(--radius-card); }
.spec-table { width: 100%; border-collapse: collapse; font-size: var(--fs-sm); }
.spec-table th, .spec-table td {
  padding: var(--table-pad-y) .9rem;
  text-align: left;
  border-bottom: 1px solid var(--border-line);
  vertical-align: top;
}
.spec-table thead th {
  background: var(--bg-surface);
  font-size: var(--fs-xs);
  font-weight: var(--font-weight-bold);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--text-hint);
  white-space: nowrap;
}
.spec-table tbody tr:last-child td { border-bottom: 0; }
.spec-table td.num { font-variant-numeric: tabular-nums; white-space: nowrap; }


/* ============================================================
   9 · FORMULARIOS
   ============================================================ */
.field { display: flex; flex-direction: column; gap: .3rem; }
.field > label {
  font-size: var(--fs-xs);
  font-weight: var(--font-weight-bold);
  color: var(--text-muted);
}
.input, select, textarea {
  width: 100%;
  padding: 10px 12px;
  border: 1px solid var(--border-line);
  border-radius: var(--radius-sm);
  background: var(--bg-page);
  color: var(--text-primary);
  font-family: var(--font-body);
  font-size: var(--fs-sm);
}
.input:focus, select:focus, textarea:focus {
  border-color: var(--concept-primary);
  outline: 2px solid var(--concept-primary);
  outline-offset: 1px;
}
.input[aria-invalid="true"] { border-color: var(--danger); }
.field__error { font-size: var(--fs-xs); color: var(--danger); }
.field__hint  { font-size: var(--fs-xs); color: var(--text-hint); }


/* ============================================================
   10 · FAQ / ACORDEÓN
   ============================================================ */
.faq { background: var(--bg-soft); }
.faq__item { border-bottom: 1px solid var(--border-line); }
.faq__q {
  width: 100%;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
  padding: 1rem 0;
  background: none;
  border: 0;
  text-align: left;
  font-family: var(--font-body);
  font-size: var(--fs-base);
  font-weight: var(--font-weight-bold);
  color: var(--text-primary);
  cursor: pointer;
}
.faq__q::after {
  content: "";
  width: .5em; height: .5em; flex: none;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg) translateY(-.15em);
  transition: transform var(--transition-base);
}
.faq__q[aria-expanded="true"]::after { transform: rotate(225deg) translateY(-.25em); }
.faq__a { padding-bottom: 1rem; color: var(--text-muted); max-width: var(--max-width-read); }
.faq__q[aria-expanded="false"] + .faq__a { display: none; }


/* ============================================================
   11 · ARTÍCULO DE BLOG
   ============================================================ */
.article { display: grid; grid-template-columns: minmax(0, 1fr) 20rem; gap: 2.5rem; align-items: start; }
@media (max-width: 900px) { .article { grid-template-columns: 1fr; } }

.article__body { max-width: var(--max-width-read); }
.article__body h2 { margin-top: 2em; }
.article__body img { border-radius: var(--radius-card); margin-block: 1.5em; }
.article__body blockquote {
  margin: 1.5em 0;
  padding-left: 1.1em;
  border-left: 3px solid var(--concept-accent);
  color: var(--text-muted);
}

.article__toc {
  position: sticky; top: 5rem;
  background: var(--bg-soft);
  border: 1px solid var(--border-line);
  border-radius: var(--radius-card);
  padding: var(--card-pad);
  font-size: var(--fs-sm);
}
.article__toc ol { margin: 0; padding-left: 1.1em; display: flex; flex-direction: column; gap: .35rem; }
.article__toc a { color: var(--text-muted); text-decoration: none; }
.article__toc a:hover { color: var(--concept-primary); }


/* ============================================================
   12 · CTA FINAL
   ============================================================ */
.cta-final {
  padding-block: var(--section-pad-y);
  background: var(--concept-hero-gradient);
  color: var(--text-invert);
  text-align: center;
}
.cta-final h2 { color: var(--text-invert); }
.cta-final p  { color: var(--concept-hero-tag-text); max-width: 48ch; margin-inline: auto; }
.cta-final .hero__actions { justify-content: center; }


/* ============================================================
   13 · PIE DE PÁGINA
   ------------------------------------------------------------
   Antes: 25 variantes en 73 páginas, y 20 páginas sin pie alguno.
   `#footer .container` tenía 21 definiciones distintas — todas
   resolviendo el mismo problema de columnas en móvil a base de
   !important, una encima de otra.

   El sistema queda con TRES pies declarados, seleccionados por
   clase modificadora. La variación es real y deliberada (ver
   NOTA-pie-de-pagina.md); lo que faltaba era declararla.

     .site-footer                → completo   (institucional, sectorial, blog)
     .site-footer--compact       → compacto   (landings lp-*)
     .site-footer--minimal       → mínimo     (herramientas y lead magnets)

   El bloque legal es idéntico en los tres y NO es opcional.
   ============================================================ */
.site-footer {
  background: var(--concept-section-dark);
  color: var(--text-on-dark);
  padding-block: clamp(2.5rem, 5vw, 3.5rem) 0;
  font-size: var(--fs-sm);
}

.site-footer__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  gap: 2rem;
}
/* Compacto — landings `lp-*`.
   La versión anterior sólo subía el ancho mínimo de columna a 15rem. En el
   contenedor de 1080 px de las landings eso da tres columnas para cuatro
   bloques: EMPRESA caía sola a una segunda fila y el pie "compacto" quedaba
   MÁS alto que el completo (769 px contra 514 px). Compacto es menos aire,
   no menos columnas: mismas cuatro, con la mitad de respiración vertical.
   Si además conviene que una landing muestre menos enlaces, eso es una
   decisión de contenido y va en el HTML, no aquí. */
.site-footer--compact { padding-block: clamp(1.6rem, 3vw, 2.2rem) 0; }
.site-footer--compact .site-footer__grid { gap: 1.5rem; }
.site-footer--compact .site-footer__legal { margin-top: 1.4rem; }

.site-footer--minimal .site-footer__grid { display: none; }

.site-footer h3 {
  font-size: var(--fs-xs);
  font-weight: var(--font-weight-bold);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--concept-kpi-lbl);
  margin-bottom: .8rem;
}
.site-footer ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: .4rem; }
.site-footer a { color: var(--text-on-dark); text-decoration: none; }
.site-footer a:hover,
.site-footer a:focus-visible { color: var(--text-invert); text-decoration: underline; }

.site-footer__brand img { height: 44px; width: auto; margin-bottom: .9rem; }
.site-footer__contact { display: flex; flex-direction: column; gap: .4rem; }

/* Redes. Antes `.foot-social` estaba en 199 páginas·selector con
   tamaños de icono distintos. */
.foot-social { display: flex; gap: .6rem; margin-top: 1rem; }
.foot-social a {
  display: inline-flex; align-items: center; justify-content: center;
  width: 2.1rem; height: 2.1rem;
  border: 1px solid rgba(255, 255, 255, .22);
  border-radius: var(--radius-tag);
}
.foot-social a:hover { background: rgba(255, 255, 255, .12); }
.foot-social svg { width: 1rem; height: 1rem; fill: currentColor; }

/* Bloque legal — obligatorio en las tres variantes */
.site-footer__legal {
  margin-top: 2.2rem;
  padding-block: 1.1rem;
  border-top: 1px solid rgba(255, 255, 255, .16);
  display: flex;
  flex-wrap: wrap;
  gap: .5rem 1.4rem;
  align-items: center;
  font-size: var(--fs-xs);
  color: var(--concept-kpi-lbl);
}
.site-footer--minimal .site-footer__legal { margin-top: 0; border-top: 0; }
.site-footer__legal nav { display: flex; flex-wrap: wrap; gap: .5rem 1.2rem; }
.site-footer__copy { margin-left: auto; }
@media (max-width: 720px) { .site-footer__copy { margin-left: 0; } }


/* ============================================================
   14 · UTILIDADES
   ============================================================ */
.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap; border: 0;
}
.center     { text-align: center; }
.num        { font-variant-numeric: tabular-nums; }
.muted      { color: var(--text-muted); }
/* 26-ago-2026: en el pie ese gris va sobre azul marino: 1.83:1. tokens.css ya
   trae la variable para texto atenuado sobre oscuro. */
.site-footer .muted,
#footer .muted { color: var(--text-on-dark); }

.hint       { color: var(--text-hint); }
.no-wrap    { white-space: nowrap; }
.mt-0 { margin-top: 0; } .mb-0 { margin-bottom: 0; }

/* Foco visible global — no existía antes en ninguna página */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--concept-primary);
  outline-offset: 2px;
  border-radius: 3px;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; scroll-behavior: auto !important; }
}

/* CTA propio de página dentro del pie.
   Cinco landings de cable llevaban su enlace de conversión en el pie
   viejo (contacto_cta.html?producto=…). El migrador lo reinyecta aquí:
   es maquinaria comercial, no navegación, y por eso no vive en el pie
   compartido sino en una ranura que cada página llena o deja vacía. */
.site-footer__cta {
  margin-top: 1.6rem;
  padding-top: 1.4rem;
  border-top: 1px solid rgba(255, 255, 255, .16);
  display: flex;
  justify-content: center;
}

/* ── Texto sobre hero fotográfico ─────────────────────────────
   Sobre foto, el texto de acento no puede ir en el azul de marca:
   es texto oscuro sobre imagen oscura. En las páginas sectoriales
   el `.hero-eyebrow` y el `<em>` del titular usaban --concept-primary
   y quedaban casi ilegibles. Se suben al tinte claro, que es el que
   tokens.css reserva para fondos oscuros (11.36 de contraste sobre
   --concept-dark). Ya pasaba antes con el degradado plano; la foto
   solo lo hizo evidente. */
.hero.hero--photo .hero-eyebrow,
.hero.hero--photo h1 em,
.hero.hero--photo h2 em { color: var(--text-on-dark); font-style: normal; }
.hero.hero--photo .hero-eyebrow { opacity: .95; }

/* Doble clase a proposito: sectorial-base.css carga DESPUES del nucleo y
   define `.hero h1 em` con la misma especificidad, asi que ganaba por orden
   de documento. `.hero.hero--photo` sube a (0,2,2) y resuelve el empate. */

/* ══════════════════════════════════════════════════════════════════════════
   PROYECTOS DE REFERENCIA  ·  .ref-grid / .ref-card
   ──────────────────────────────────────────────────────────────────────────
   Componente compartido por 39 paginas y 259 tarjetas.

   POR QUE VIVE AQUI Y NO EN LAS HOJAS DE PAGINA
   Estaba copiado cinco veces: dos en equipamiento-base.css (bloque duplicado
   literal), dos en mineria-landing.css (con una variante divergente), una en
   sectorial-base.css y una en servicios-base.css. Veintiocho de las 39
   paginas que usan el componente no cargaban ninguna de esas hojas, asi que
   la seccion se veia sin ningun estilo: parrafos sueltos en una sola columna.
   Al vivir en el nucleo funciona en las 39 sin tocar una sola pagina.

   CONTRATO DEL MARCADO
   Obligatorio:  .ref-card__cliente  .ref-card__lugar  .ref-card__desc
   Opcional:     .ref-card__sector   .ref-card__metric   .ref-card__foto
                 .ref-card--feat
   Una tarjeta que solo trae los tres obligatorios se ve correcta. Por eso se
   puede enriquecer pagina por pagina sin migrar las 259 de golpe.

   EL PIN
   El marcado traia el emoji &var(--vms-green-500); escrito en el HTML. Aqui es un SVG del
   sistema aplicado por CSS, para que herede color y tamano del componente.
   Si vuelves a ver dos pines juntos, es que alguna tarjeta conserva el emoji.
   ══════════════════════════════════════════════════════════════════════════ */

.ref-grid { display:grid; grid-template-columns:repeat(3,1fr); gap:18px }

.ref-card {
  position:relative; display:flex; flex-direction:column;
  background:var(--bg-page);
  border:1px solid var(--border-line);
  border-radius:var(--radius-card);
  padding:1.15rem 1.3rem 1.3rem;
  box-shadow:var(--shadow-card);
  transition:transform .18s ease, box-shadow .18s ease, border-color .18s ease;
  overflow:hidden;
}
.ref-card::before {
  content:""; position:absolute; inset:0 0 auto 0; height:3px;
  background:linear-gradient(90deg,var(--concept-primary),var(--concept-accent));
}
.ref-card:hover {
  transform:translateY(-3px);
  box-shadow:var(--shadow-hover);
  border-color:var(--border-hover);
}

.ref-card__sector {
  display:inline-flex; align-self:flex-start; margin-bottom:.55rem;
  padding:.2rem .6rem; border-radius:var(--radius-tag);
  background:var(--concept-accent-light); color:var(--concept-accent-text);
  font-size:.66rem; font-weight:800; text-transform:uppercase; letter-spacing:.07em;
}

.ref-card__cliente {
  margin:0 0 .28rem; font-size:1rem; font-weight:800; line-height:1.3;
  color:var(--text-primary);
}

.ref-card__lugar {
  margin:0; padding-left:1.05rem; font-size:.78rem; color:var(--text-hint);
  background:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%236E8AAA'%3E%3Cpath d='M12 2C8.1 2 5 5.1 5 9c0 5.2 7 13 7 13s7-7.8 7-13c0-3.9-3.1-7-7-7zm0 9.5A2.5 2.5 0 1 1 12 6.5a2.5 2.5 0 0 1 0 5z'/%3E%3C/svg%3E") left .1em/.85rem no-repeat;
}

/* La metrica va DEBAJO del cliente, no encima: asi todos los titulos de una
   fila quedan a la misma altura aunque solo algunas tarjetas tengan dato. */
.ref-card__metric {
  display:flex; align-items:baseline; gap:.45rem; flex-wrap:wrap;
  margin:.85rem 0 0; padding:.5rem .7rem;
  border-radius:var(--radius-sm);
  background:var(--concept-light);
  border-left:3px solid var(--concept-primary);
}
.ref-card__metric b {
  font-size:1.65rem; font-weight:800; line-height:1; letter-spacing:-.02em;
  color:var(--concept-primary); font-variant-numeric:tabular-nums;
}
.ref-card__metric span {
  font-size:.7rem; font-weight:700; text-transform:uppercase;
  letter-spacing:.05em; color:var(--concept-accent-text);
}

.ref-card__desc { margin:.85rem 0 0; font-size:.85rem; line-height:1.6; color:var(--text-muted) }

/* ── Destacada ─────────────────────────────────────────────────────────────
   Ancho completo y en horizontal. Ocupa la fila entera para que el resto de
   la reticula quede en filas limpias de tres, sea cual sea el numero de
   tarjetas de la pagina. */
.ref-card--feat {
  grid-column:1/-1;
  display:grid; grid-template-columns:1.15fr .85fr; gap:0;
  padding:0; background:var(--concept-section-dark); border-color:transparent;
}
.ref-card--feat::before { display:none }
.ref-card--feat:hover { transform:none; box-shadow:var(--shadow-card) }
.ref-card--feat .ref-card__body {
  padding:1.6rem 1.8rem; display:flex; flex-direction:column; justify-content:center;
}
.ref-card--feat .ref-card__cliente { color:var(--text-invert); font-size:1.35rem }
.ref-card--feat .ref-card__desc { color:var(--text-on-dark); font-size:.9rem; max-width:52ch }
.ref-card--feat .ref-card__sector {
  background:var(--concept-hero-tag-bg); color:var(--concept-hero-tag-text);
  border:1px solid var(--concept-hero-tag-border);
}
.ref-card--feat .ref-card__lugar {
  color:var(--concept-accent);
  background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%234997DD'%3E%3Cpath d='M12 2C8.1 2 5 5.1 5 9c0 5.2 7 13 7 13s7-7.8 7-13c0-3.9-3.1-7-7-7zm0 9.5A2.5 2.5 0 1 1 12 6.5a2.5 2.5 0 0 1 0 5z'/%3E%3C/svg%3E");
}
.ref-card--feat .ref-card__metric {
  background:rgba(255,255,255,.08); border-left-color:var(--concept-accent);
  align-self:flex-start;
}
.ref-card--feat .ref-card__metric b { color:#fff; font-size:2.4rem }
.ref-card--feat .ref-card__metric span { color:var(--concept-accent) }

/* Hueco de fotografia. Mientras no haya imagen muestra un degradado de marca,
   de modo que la seccion se ve terminada y la foto entra despues sin tocar CSS. */
.ref-card__foto {
  position:relative; min-height:200px; overflow:hidden;
  background:
    radial-gradient(120% 100% at 80% 10%, rgba(73,151,221,.35), transparent 60%),
    var(--concept-darker);
}
.ref-card__foto img { width:100%; height:100%; object-fit:cover; display:block }

@media (max-width:900px) {
  .ref-grid { grid-template-columns:1fr 1fr }
  .ref-card--feat { grid-template-columns:1fr }
  .ref-card--feat .ref-card__foto { order:-1; min-height:150px }
}
@media (max-width:600px) {
  .ref-grid { grid-template-columns:1fr }
  .ref-card--feat .ref-card__metric b { font-size:2rem }
}

/* ── Tablas anchas en pantallas chicas ─────────────────────────────────────
   Varias landings llevan tablas tecnicas —semaforo de diagnostico, limites de
   gases disueltos, comparativa de gobernadores— cuyo ancho minimo supera los
   390 px de un telefono. Sin esto, la tabla empuja el ancho de TODA la pagina
   y el visitante termina desplazando el sitio entero de lado para leer un
   parrafo.

   display:block convierte la tabla en su propia caja desplazable: el resto de
   la pagina deja de moverse y la tabla se recorre sola. Resuelve las tres
   paginas afectadas sin tocar el HTML de ninguna. */
@media (max-width: 760px) {
  main table {
    display: block;
    max-width: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }
}


/* ═══════════════════════════════════════════════════════════════════════
   CONFIGURADOR / CALCULADORA  ·  .cfg
   Componente compartido: el configurador de especificación de cable MT y la
   calculadora de sección de cable solar. Formulario a la izquierda, resultado
   a la derecha y pegado al hacer scroll; por debajo de 900 px se apila y el
   resultado sube, porque en el teléfono lo primero que importa es la cifra.
   ═══════════════════════════════════════════════════════════════════════ */
/* ── Configurador de especificación ─────────────────────────────────
   Dos columnas: el formulario a la izquierda, el resultado a la derecha
   y pegado al hacer scroll, para que el ingeniero vea cambiar la sección
   mientras mueve los controles. Por debajo de 900 px se apila y el
   resultado pasa arriba: en el teléfono lo primero que importa es la
   cifra, no los controles que ya movió. */
.cfg{margin-top:18px;display:grid;grid-template-columns:minmax(0,1fr) minmax(0,360px);gap:18px;align-items:start}
.cfg__panel{background:#fff;border:1px solid #dbe6f4;border-radius:16px;padding:18px;display:grid;gap:16px;box-shadow:0 6px 14px rgba(16,35,61,.06)}
.cfg__field{display:grid;gap:8px;min-width:0}
.cfg__field--par{grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:12px}
.cfg__label{display:block;font-weight:700;color:#113960;font-size:.92rem}
.cfg__hint{font-weight:400;color:#6b809a;font-size:.82rem}
.cfg__select,.cfg__input{width:100%;border:1px solid #cfdceb;border-radius:10px;padding:10px 11px;font:inherit;color:var(--ink);background:#fff}
.cfg__select:focus,.cfg__input:focus{outline:2px solid rgba(15,76,129,.25);border-color:var(--concept-primary)}
.cfg__opts{display:flex;flex-wrap:wrap;gap:8px}
.cfg__opt{position:relative;display:inline-flex}
.cfg__opt input{position:absolute;inset:0;opacity:0;cursor:pointer;margin:0}
.cfg__opt span{display:inline-flex;align-items:center;border:1px solid #cfdceb;border-radius:999px;padding:.45rem .9rem;font-size:.88rem;font-weight:600;color:#35516f;background:#fff;transition:background .15s ease,border-color .15s ease,color .15s ease}
.cfg__opt input:checked+span{background:var(--concept-primary);border-color:var(--concept-primary);color:#fff}
.cfg__opt input:focus-visible+span{outline:2px solid rgba(15,76,129,.35);outline-offset:2px}
.cfg__opt input:disabled+span{opacity:.4;cursor:not-allowed}
.cfg__nota{margin:0;font-size:.82rem;line-height:1.5;color:#5b7186}
.cfg__nota:empty{display:none}

.cfg__out{position:sticky;top:86px;background:linear-gradient(160deg,#0f2b4a,#123f6b);color:#fff;border-radius:16px;padding:20px;box-shadow:0 14px 30px rgba(9,26,48,.22)}
.cfg__outKicker{margin:0;font-size:.78rem;letter-spacing:.08em;text-transform:uppercase;color:#9dc2ea;font-weight:700}
.cfg__cifra{margin:6px 0 0;font-size:clamp(2.2rem,5.4vw,3rem);line-height:1;font-weight:700}
.cfg__cifra small{font-size:.42em;font-weight:600;margin-left:.25em;color:#bcd8f4}
.cfg__spec{margin:10px 0 0;font-size:.94rem;line-height:1.5;color:#dbeaf9}
.cfg__chips{margin:14px 0 0;display:grid;grid-template-columns:repeat(auto-fit,minmax(118px,1fr));gap:8px}
.cfg__chip{background:rgba(255,255,255,.1);border:1px solid rgba(255,255,255,.16);border-radius:11px;padding:9px 10px;min-width:0}
.cfg__chip dt{margin:0;font-size:.72rem;letter-spacing:.05em;text-transform:uppercase;color:#a9cbee}
.cfg__chip dd{margin:3px 0 0;font-size:1.02rem;font-weight:700;overflow-wrap:anywhere}
.cfg__holgura{margin:12px 0 0;font-size:.86rem;color:#cfe3f7}
.cfg__barra{margin-top:6px;height:7px;border-radius:99px;background:rgba(255,255,255,.16);overflow:hidden}
.cfg__barra i{display:block;height:100%;background:var(--vms-green-300);border-radius:99px}
.cfg__barra--justa i{background:#f6c65b}
.cfg__aviso{margin:12px 0 0;padding:10px 12px;border-radius:11px;background:rgba(246,198,91,.14);border:1px solid rgba(246,198,91,.4);font-size:.86rem;line-height:1.5;color:#ffe9b8}
.cfg__copiar{margin-top:14px;width:100%;border:1px solid rgba(255,255,255,.4);background:transparent;color:#fff;border-radius:11px;padding:10px 12px;font:inherit;font-weight:700;cursor:pointer;transition:background .15s ease}
.cfg__copiar:hover,.cfg__copiar:focus-visible{background:rgba(255,255,255,.14)}

.cfg__vecinas{margin:14px 0 0;width:100%;border-collapse:collapse;font-size:.84rem}
.cfg__vecinas th{text-align:left;font-weight:700;color:#a9cbee;font-size:.72rem;letter-spacing:.05em;text-transform:uppercase;padding:0 6px 5px 0}
.cfg__vecinas td{padding:5px 6px 5px 0;border-top:1px solid rgba(255,255,255,.12);color:#dbeaf9}
.cfg__vecinas tr[data-elegida] td{color:#fff;font-weight:700}

.cfg__tabla{margin-top:18px;border:1px solid #dbe6f4;border-radius:14px;background:#fff}
.cfg__tabla>summary{cursor:pointer;padding:12px 14px;font-weight:700;color:var(--concept-primary);list-style:none}
.cfg__tabla>summary::-webkit-details-marker{display:none}
.cfg__tabla>summary::before{content:"\25B8";display:inline-block;margin-right:8px;transition:transform .15s ease}
.cfg__tabla[open]>summary::before{transform:rotate(90deg)}
.cfg__tablaWrap{overflow-x:auto;-webkit-overflow-scrolling:touch;border-top:1px solid #e6eef8}
.cfg__tablaWrap table{width:100%;border-collapse:collapse;min-width:640px;font-size:.85rem}
.cfg__tablaWrap th,.cfg__tablaWrap td{padding:8px 12px;border-bottom:1px solid #eef4fb;text-align:right;white-space:nowrap}
.cfg__tablaWrap th{background:#f4f8ff;color:#113960;text-align:right;font-size:.72rem;letter-spacing:.04em;text-transform:uppercase;position:sticky;top:0}
.cfg__tablaWrap th:first-child,.cfg__tablaWrap td:first-child{text-align:left}
.cfg__tablaWrap tr[data-elegida]{background:#eaf3ff}
.cfg__tablaWrap tr[data-elegida] td{font-weight:700;color:#113960}
.cfg__marca{color:#9a4d00;cursor:help;font-weight:700}
.cfg__pie{margin:12px 0 0;font-size:.82rem;line-height:1.55;color:#5b7186}

@media (max-width:900px){
  .cfg{grid-template-columns:1fr}
  .cfg__out{position:static;order:-1}
}
@media (max-width:520px){
  .cfg__field--par{grid-template-columns:1fr}
}

/* Cuál de las dos condiciones obliga a subir de sección. Lo usa la
   calculadora solar, donde la respuesta no es obvia: casi siempre manda la
   caída de tensión y no la ampacidad. */
.cfg__manda{display:inline-block;margin-top:6px;padding:.16rem .6rem;border-radius:999px;
  background:rgba(255,255,255,.14);border:1px solid rgba(255,255,255,.24);font-size:.84rem}
.cfg__manda strong{color:#fff}
/* Una casilla con el mismo aspecto que las píldoras de opción. */
.cfg__opt--check{align-items:flex-start}
.cfg__opt--check input{position:static;opacity:1;width:16px;height:16px;margin:.18rem .55rem 0 0;
  accent-color:var(--concept-primary);flex:0 0 auto;cursor:pointer}
.cfg__opt--check span{border:0;padding:0;background:none;color:#35516f;font-weight:600;
  border-radius:0;line-height:1.4}
.cfg__opt--check input:checked+span{background:none;color:#113960}

/* ══ Encabezado de seccion ═══════════════════════════════════════════════
   Antetitulo, titular y entradilla. Los usan 34 paginas. Hasta el 23-ago-2026
   vivian duplicados en cuatro hojas de familia —con tres apariencias— y dos
   paginas los usaban sin que nadie los definiera. Ahora estan aqui y solo
   aqui; si hace falta una variante, se anade un modificador, no una copia.

   Los valores salen de contar lo que el sitio ya hacia: la pildora del
   antetitulo (87 usos contra 38 planos) y el navy #172C51 del titular (tres
   de las cuatro hojas). El tamano y el peso los eligio Hugo, porque ahi la
   medicion no daba ganador.                                                */
.sec-label {
  display: inline-block;
  margin: 0 0 10px;
  padding: .2rem .7rem;
  border-radius: 999px;
  background: var(--concept-accent-light);
  color: var(--concept-accent-text);
  font-size: .72rem;
  font-weight: 800;
  letter-spacing: .1em;
  text-transform: uppercase;
}
.sec-label--light { background: rgba(255,255,255,.15); color: var(--text-invert, #fff) }

.sec-h2 {
  margin: 0 0 10px;
  font-size: clamp(22px, 3vw, 32px);
  font-weight: 900;
  line-height: 1.15;
  color: var(--concept-dark);
}
.sec-h2--white { color: var(--text-invert, #fff) }

.sec-lead {
  margin: 0 0 32px;
  max-width: 680px;
  color: var(--text-muted);
}
.sec-lead--light { color: var(--vms-slate-400, #94a3b8) }

/* ==== tablas anchas en pantalla estrecha ==== */
/* Medido a 360 px: de las 88 tablas del sitio, 55 ya viven dentro de un
   contenedor que las desplaza y 33 no. Diez de esas 33 recortaban entre 23 y
   194 px de texto dentro de sus propias celdas, sin barra que mover. El
   contenedor no cambia nada para las tablas que caben; el min-width que llevan
   las diez es su ancho natural medido, redondeado hacia arriba. */
.tabla-scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  max-width: 100%;
}

/* ============================================================
   Carrusel del hero  ·  consolidado el 25-ago-2026
   Estaba duplicado palabra por palabra en index, nosotros,
   soluciones y proyectos-vms (esta ultima sin usarlo siquiera).
   Los controles van al pie, en fila: flecha - puntos - flecha.
   Antes las flechas eran absolutas a media altura y se encimaban
   con el titular y el parrafo en todos los anchos.
   ============================================================ */
.hero-carousel { position: relative; }
.hero-carousel__viewport { position: relative; }

.hero-carousel__controls {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 0 0 18px;
}

.hero-carousel__nav {
  flex: 0 0 auto;
  width: 42px;
  height: 42px;
  display: grid;
  place-items: center;
  border: 1px solid rgba(255,255,255,.28);
  border-radius: 999px;
  background: rgba(10,22,43,.48);
  color: #fff;
  font-size: 1.1rem;
  line-height: 1;
  cursor: pointer;
  transition: background .18s;
}
.hero-carousel__nav:hover { background: rgba(10,22,43,.72); }

.hero-carousel__dots {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0;
}

/* El circulo mide 10 px como siempre; el boton mide 24 para que se pueda
   tocar con el dedo (WCAG 2.1, criterio 2.5.5). */
.hero-carousel__dot {
  width: 24px;
  height: 24px;
  padding: 0;
  border: 0;
  background: none;
  display: grid;
  place-items: center;
  cursor: pointer;
}
.hero-carousel__dot::before {
  content: "";
  width: 10px;
  height: 10px;
  border-radius: 999px;
  border: 1px solid rgba(255,255,255,.5);
  background: transparent;
  transition: background .18s;
}
.hero-carousel__dot.is-active::before { background: #fff; }

@media (max-width: 640px) {
  .hero-carousel__nav { width: 36px; height: 36px; }
  .hero-carousel__controls { gap: 6px; }
}

/* ============================================================
   Metadatos de cabecera del blog  ·  consolidado el 25-ago-2026
   Estaba duplicado palabra por palabra en las 9 entradas que lo
   usaban. Vive aqui para que cualquier entrada nueva lo herede.
   ============================================================ */
.hero__meta {
  margin-top: 18px;
  color: #bcd0ee;
  font-size: .92rem;
  display: flex;
  gap: 14px;
  flex-wrap: wrap;
}
.hero__meta span { display: inline-flex; align-items: center; gap: 6px; }


/* ---- Consentimiento de datos personales (25-ago-2026) ------------------
   Una sola definicion para los 28 formularios del sitio. */
.form-consent{grid-column:1/-1;flex:0 0 100%;display:flex;gap:.55rem;align-items:flex-start;margin:.9rem 0;
  font-size:.85rem;line-height:1.45;text-align:left}
.form-consent input[type="checkbox"]{flex:0 0 auto;margin:.2rem 0 0;width:1rem;height:1rem;
  accent-color:var(--concept-primary,#0F4C81)}
.form-consent label{margin:0;font-weight:400;cursor:pointer;font-size:inherit;line-height:inherit}
.form-consent a{color:inherit;text-decoration:underline}
.form-consent.is-missing{color:#b3261e}
.form-consent.is-missing input[type="checkbox"]{outline:2px solid #b3261e;outline-offset:2px}


/* ---- Control documental de las paginas legales (25-ago-2026) -----------
   Los PDF de VMS llevan codigo, revision y fecha; las paginas web los perdian. */
.doc-control{margin:2rem 0 0;padding:.9rem 1.05rem;border-left:3px solid var(--concept-primary,#0F4C81);
  background:rgba(15,76,129,.05);font-size:.85rem;line-height:1.55;color:inherit}
.doc-control b{font-weight:700}


/* ---- Suministro multimarca (26-ago-2026) ------------------------------------
   Tres paginas usan .marcas-grid / .marca-card / .marca-featured. Una no tenia
   ninguna regla (se veia como lista) y las otras dos las definian por separado,
   con columnas cableadas y grises ajenos a la paleta. Definicion unica aqui.
   .marca-tag = eje de decision (tension, armonicas, tipo de compensacion), que
   es lo que prometen las entradillas de esas secciones. ------------------- */
.marcas-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,236px),1fr));
  gap:14px;margin:18px 0 0;align-items:stretch}
.marca-card{display:flex;flex-direction:column;gap:12px;text-align:left;background:#fff;
  border:1px solid var(--border-line,rgba(23,44,81,.12));
  border-top:3px solid var(--concept-primary,#0F4C81);
  border-radius:14px;padding:18px;box-shadow:0 6px 18px rgba(9,32,58,.05)}
.marca-card__name{margin:0;font-size:1.06rem;font-weight:800;letter-spacing:-.01em;
  color:var(--concept-primary,#0F4C81);padding-bottom:11px;
  border-bottom:1px solid rgba(15,76,129,.14)}
.marca-card__series{margin:0;padding:0;list-style:none;color:#23486f;
  font-size:.92rem;line-height:1.5;display:grid;gap:7px}
.marca-card__series li{display:grid;grid-template-columns:7px 1fr;gap:9px;align-items:baseline}
.marca-card__series li::before{content:"";width:7px;height:7px;border-radius:2px;
  background:rgba(15,76,129,.34)}
p.marca-card__series{display:block;line-height:1.6}
.marca-card__tags{display:flex;flex-wrap:wrap;gap:6px;margin:auto 0 0;padding-top:2px}
.marca-tag{font-size:.74rem;font-weight:700;color:#103961;background:#f0f6ff;
  border:1px solid rgba(15,76,129,.18);padding:.16rem .5rem;border-radius:999px;white-space:nowrap}
.marcas-sublabel{margin:24px 0 0;font-size:.78rem;font-weight:800;letter-spacing:.09em;
  text-transform:uppercase;color:#4B647F}
.marca-featured{margin:18px 0 0;padding:22px 26px;border-radius:18px;color:#fff;
  background:linear-gradient(135deg,var(--vms-blue-600,#0F4C81) 0%,var(--vms-blue-800,#172C51) 100%);
  box-shadow:0 10px 30px rgba(9,32,58,.14)}
.marca-featured__badge{display:inline-flex;align-items:center;font-size:.74rem;font-weight:700;
  letter-spacing:.06em;text-transform:uppercase;color:#eaf2ff;
  background:rgba(143,215,255,.18);border:1px solid rgba(143,215,255,.35);
  padding:.22rem .65rem;border-radius:999px}
.marca-featured__name{margin:12px 0 6px;font-size:clamp(20px,2.2vw,26px);font-weight:800;
  letter-spacing:-.01em;color:#fff}
.marca-featured__desc{margin:0;color:rgba(255,255,255,.85);font-size:.94rem;
  line-height:1.6;max-width:760px}
