/* ============ Tipografias: solo local, ninguna peticion a terceros ============ */

@font-face {
  font-family: "IBM Plex Sans";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/assets/fonts/ibm-plex-sans-latin-400-normal.woff2") format("woff2");
}

@font-face {
  font-family: "IBM Plex Sans";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("/assets/fonts/ibm-plex-sans-latin-500-normal.woff2") format("woff2");
}

@font-face {
  font-family: "IBM Plex Sans";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("/assets/fonts/ibm-plex-sans-latin-600-normal.woff2") format("woff2");
}

@font-face {
  font-family: "Archivo";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("/assets/fonts/archivo-latin-700-normal.woff2") format("woff2");
}

@font-face {
  font-family: "Archivo";
  font-style: normal;
  font-weight: 800;
  font-display: swap;
  src: url("/assets/fonts/archivo-latin-800-normal.woff2") format("woff2");
}

/* ============ Reset minimo ============ */

*, *::before, *::after { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  /* La web es clara (fase 2): le dice al navegador que pinte en claro lo que dibuja el sistema
     (barra de desplazamiento, autocompletado, seleccion, controles nativos). */
  color-scheme: light;
}

body, h1, h2, h3, h4, p, figure { margin: 0; }

img, svg { display: block; max-width: 100%; }

a { color: inherit; }

button { font: inherit; color: inherit; }

/*
 * `hidden` es un atributo, no una sugerencia (2026-09-06).
 *
 * El navegador oculta `[hidden]` desde SU hoja de estilos, y cualquier regla de autor le gana por
 * origen, por poca especificidad que tenga. Este proyecto tenia dos elementos marcados `hidden` en
 * el HTML cuya propia clase declaraba un `display`:
 *
 *   <form id="calculadora-formulario" class="calculadora-interactiva" hidden>  ->  display: grid
 *   <div id="calculadora-tablas" class="calculadora-tablas">  (JS le pone hidden)  ->  display: grid
 *
 * Es decir: la calculadora interactiva se veia SIN JavaScript, a medio construir y con guiones donde
 * van los importes, y la tabla de respaldo seguia viendose CON JavaScript, debajo de la calculadora
 * que viene a sustituirla. Las dos capas a la vez, en las cuatro paginas que incluyen el bloque, y
 * desde que el bloque existe.
 *
 * Nadie lo vio porque por dentro todo era correcto: `element.hidden` valia `true` y el atributo
 * estaba en el HTML. Solo se cae midiendo la pagina PINTADA -- `getBoundingClientRect()` devolvia
 * 544 px de tabla "oculta" --, que es lo que se hizo al subir la calculadora al heroe para
 * comprobar si cabia en 1366x768. `test/plantilla.test.js` lo fija ahora como regresion.
 *
 * `!important` es la unica forma de que el atributo recupere la ultima palabra sin ir persiguiendo
 * cada regla de `display` que alguien escriba manana. Es la misma regla que traen los "reset"
 * conocidos, y por el mismo motivo.
 */
[hidden] { display: none !important; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

/* ============ Base ============ */

body {
  background: var(--fondo);
  color: var(--tinta);
  font-family: var(--sans);
  font-size: 16.5px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

/* ============ Escala tipografica ============ */
/*
 * Procedencia real, revisada tras dos rondas de correccion (2026-09-05):
 * dentro de .dir-b ("Direccion B - Suite", web-satcontrol-direcciones.html) solo existen DOS
 * textos con forma de encabezado: el H1 (`.dir-b h1.mock-h1`) y el titulo de tarjeta de
 * producto (`.dir-b .prods h4`, 1.02rem). No hay ningun h2 ni h3 genuino en esa maqueta, y
 * tampoco hay NINGUN parrafo de texto corrido de pagina -- `.dir-b .prods p` es texto DENTRO
 * de una tarjeta de producto, no cuerpo general. Ronda 1 corrigio h2/h3/entradilla; ronda 2
 * corrigio que el cuerpo general (`p`) se habia quedado con el tamano/tinta de esa tarjeta.
 */

h1 {
  /*
   * Procedencia hasta 2026-09-06: `.dir-b h1.mock-h1`, literal. Desde hoy la referencia es otra --
   * el titular rechazo la direccion B comparandola con sus propios productos y pidio ese lenguaje:
   * titulares MUY grandes con una palabra en degradado (`.brand-headline` de
   * SatcontrolFactur/frontend/src/app/pages/acceso-comun.scss). De alli se copian los dos
   * parametros que dan ese caracter: tamaño y espaciado entre letras.
   *
   * Tamaño: el producto usa clamp(40px, 4.5vw, 64px). Aqui la raiz son 16,5px, asi que esos mismos
   * limites en rem son 2.42rem y 3.88rem; se redondean a 2.4 y 4, y el termino medio sube a 5.2vw
   * para que llegue antes al tope. Es sensiblemente mayor que el clamp anterior (2.1 - 3.5rem).
   *
   * Espaciado: -.02em, el del producto, en vez de los -.04em de la maqueta vieja. Archivo es una
   * grotesca estrecha y a 4rem un apretado de -.04em junta los remates.
   *
   * El peso NO se copia: el producto pinta 700 sobre Inter y aqui la display es Archivo, de la que
   * el sitio sirve tambien la 800. Se mantiene 800 -- lo que este sitio lleva desde la Tarea 2 --
   * porque en Archivo el salto 700 -> 800 es el que da el peso visual que en Inter da ya el 700, y
   * el spec §9 prohibe traer una tipografia de terceros para igualarlo.
   */
  font-family: var(--display);
  font-weight: 800;
  font-size: clamp(2.4rem, 5.2vw, 4rem);
  line-height: 1.03;
  letter-spacing: -.02em;
  /*
   * La red de seguridad del titular (2026-09-07). El minimo del clamp son 2,4rem, y `rem` cuelga
   * del tamaño de letra del navegador: con el ajuste al 200 % la raiz pasa de 16,5 a 33 px y ese
   * minimo se convierte en 79 px. A 360 px de ancho la columna de texto mide 292, y "plantilla"
   * sola mide 370: el titular desbordaba 78 px y sacaba barra de desplazamiento lateral en toda la
   * pagina (medido en Chrome: scrollWidth 404 contra 360 de ventana), que es justo lo que el spec
   * §12.6 prohibe. Con esto la palabra se parte -- feo, pero legible y sin barra -- y solo cuando
   * de verdad no cabe: a tamaño normal ninguna palabra del sitio llega a ese caso.
   */
  overflow-wrap: break-word;
}

h2 {
  /*
   * No existe h2 en .dir-b: se interpola matematicamente entre el H1 real (minimo del clamp,
   * 2.1rem) y el h3 ORIGINAL (1.02rem, el valor literal de la maqueta vigente hasta la ronda de
   * correccion 1 de la Tarea 5 -- ver comentario de h3 abajo) con razon constante
   * r = sqrt(2.1/1.02) ~= 1.435, aplicada a los TRES parametros del clamp de h1 (min, vw, max)
   * para que h2 = h1 / 1.435 en cualquier ancho de viewport (clamp(a,b,c)/k = clamp(a/k,b/k,c/k)
   * para k>0): 2.1/1.435=1.46, 4.6/1.435=3.2, 3.5/1.435=2.44. line-height y letter-spacing
   * tambien son interpolados (media de h1 y h3), no medidos: no hay dato real de h2 que copiar.
   *
   * Nota (ronda de correccion 1 de la Tarea 5): h3 crecio despues a 1.25rem (ver su comentario).
   * Los tres numeros del clamp de aqui NO se han vuelto a calcular con ese h3 nuevo como ancla --
   * siguen siendo los originales, y siguen siendo validos porque el minimo del clamp (1.46rem)
   * sigue siendo mayor que el h3 nuevo (1.25rem) en cualquier ancho: la escala monotona
   * h1 > h2 > h3 > p se mantiene. Si h3 vuelve a cambiar, hay que comprobar de nuevo esa
   * desigualdad antes de asumir que este clamp sigue sirviendo.
   *
   * margin-bottom: 20px, nuevo en esta ronda. No hay dato literal que copiar (no existe h2 en la
   * maqueta): se deriva de que h2 encabeza una seccion entera de pagina (mas peso que el h3 de
   * una tarjeta), asi que lleva mas separacion que los 5px de h3.
   */
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(1.46rem, 3.2vw, 2.44rem);
  line-height: 1.1;
  letter-spacing: -.03em;
  margin-bottom: 20px;
}

h3 {
  /*
   * Ronda de correccion 1 de la Tarea 5 (la portada llego con contenido real y un h3 se leia
   * como una linea suelta en negrita, no como un encabezado -- ver task-5-report.md). Dos
   * cambios, con procedencia DISTINTA cada uno:
   *
   * - margin-bottom: 5px SI es literal de `.dir-b .prods h4` (`margin: 0 0 5px`, la maqueta
   *   trae ese margen). El reset global de mas arriba (`h1,h2,h3,h4,p,figure {margin:0}`) lo
   *   habia dejado en cero desde que existe esta regla: la transcripcion original copio la
   *   tipografia pero no el margen, y esa es la causa real del hueco de 0px entre el h3 y el
   *   texto que le sigue.
   * - font-size: 1.25rem YA NO es literal de la maqueta (que trae 1.02rem, ver arriba en el
   *   comentario de h2): se agranda en esta ronda porque 1.02rem, un 2% por encima del cuerpo
   *   general (1rem), no se distinguia con claridad. 1.25rem (25% mas que el cuerpo) mantiene la
   *   escala monotona h1 > h2 > h3 > p en cualquier ancho de viewport (el minimo del clamp de h2
   *   es 1.46rem, sigue siendo mayor).
   *
   * font-family/font-weight/letter-spacing/line-height SI siguen siendo literales de
   * `.dir-b .prods h4`; no cambiaron en esta ronda.
   */
  font-family: var(--display);
  font-weight: 700;
  font-size: 1.25rem;
  line-height: 1.2;
  letter-spacing: -.02em;
  margin-bottom: 5px;
}

p {
  /*
   * .dir-b NO tiene ningun parrafo de texto corrido de pagina -- ronda 1 dejo aqui el tamano de
   * `.dir-b .prods p`, que es texto DENTRO de una tarjeta de producto, no cuerpo general (mismo
   * error que la entradilla, en sentido contrario: habria sacado las 10 paginas siguientes a
   * ~14px en tinta apagada). Al no haber dato real que copiar, se deriva del cuerpo: tamano base
   * (1rem = 16.5px heredados de `body`) y tinta principal `--tinta`, no `--tinta-2`.
   */
  color: var(--tinta);
  font-size: 1rem;
}

.tarjeta p {
  /*
   * Real, literal: .dir-b .prods p (texto de cuerpo dentro de una tarjeta de producto). Aqui SI
   * es el dato correcto porque esta acotado a `.tarjeta` (mapea `.prods > div`), el mismo
   * contexto de la maqueta; no se aplica al `p` general de la pagina.
   */
  color: var(--tinta-2);
  font-size: .85rem;
}

.entradilla {
  /* Real, literal: .dir-b .sub (entradilla bajo el H1). No aplicar al tag <p> generico. */
  color: var(--tinta-2);
  font-size: 1.08rem;
  max-width: 52ch;
}

small, .micro {
  display: block;
  font-size: .8rem;
  color: var(--tinta-2);
  /*
   * La red de seguridad de las NOTAS (2026-09-07). Aqui es donde el sitio imprime las fuentes de
   * las comparativas, y una fuente es una URL entera sin espacios:
   * la URL de la pagina de precios de un competidor. Con el tamaño de letra del navegador al 200 %, esa cadena
   * mide mas que la columna a 360 px y desbordaba la pagina entera -- medido en Chrome sobre
   * la comparativa mas larga: scrollWidth 455 contra 360 de ventana, o sea barra de desplazamiento
   * lateral, que es lo que el spec §12.6 prohibe. `break-word` parte la URL solo cuando la palabra
   * sola no cabe; a tamaño normal no se parte ninguna.
   */
  overflow-wrap: break-word;
}

/* El antetitulo dorado: versales, peso 600, espaciado .2em. */
.eyebrow {
  display: inline-block;
  font-size: .8rem;
  font-weight: 600;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--oro-texto);
}

/* ============ Utilidades de contenedor ============ */

.contenedor {
  max-width: 1100px;
  margin: 0 auto;
  padding: 0 34px;
}

/*
 * `padding-block` y no la forma corta `padding: X 0 Y`. Las tres clases se escriben SIEMPRE junto a
 * `.contenedor` (comprobado en las seis combinaciones que existen en las plantillas), y la forma
 * corta ponia a cero los 34 px de relleno lateral que `.contenedor` acababa de declarar: en 360 px
 * el titular y el texto llegaban pegados al borde izquierdo de la pantalla. En escritorio no se
 * notaba porque ahi sobra margen a los lados, y por eso llevaba asi desde la Tarea 2 -- hasta que
 * el heroe paso a tener fondo propio y el texto quedo pegado a su canto.
 */
.seccion { padding-block: 48px; }
.seccion-hero { padding-block: 74px 64px; }
.seccion-compacta { padding-block: 20px 56px; }

/*
 * El ritmo vertical del heroe, que hasta hoy salia solo de las alturas de linea. Con el titular al
 * tamaño de la piel de producto eso ya no basta: la entradilla se pegaba al ultimo renglon del
 * titular. Los dos valores son los de `.brand-eyebrow` y `.brand-headline` del producto (20 px y
 * 24 px); el segundo baja a 22 porque aqui la entradilla arranca antes.
 */
.seccion-hero .eyebrow {
  margin-bottom: 20px;
}

.seccion-hero h1 {
  margin-bottom: 22px;
}

/*
 * ============ Componentes base ============
 * `.btn`: radio 10px, de las maquetas aprobadas de la fase 2 (ya no la pastilla de 999px de
 * `.dir-b`). Tarjeta: 14px de `.dir-b .prods > div`/`.stack`; 16px de `.dir-b .calcbox`. Sombra:
 * `var(--sombra)` de tokens.css, neutra (tinte de --tinta) desde la piel clara de la fase 2.
 */

.btn {
  display: inline-block;
  font-weight: 600;
  font-size: .87rem;
  padding: 11px 23px;
  border-radius: 10px;
  border: 1px solid transparent;
  cursor: pointer;
  /*
   * text-decoration: none -- no viene de `.dir-b .btn` (la maqueta usa <span>, que nunca lleva
   * subrayado; no habia necesidad de resetearlo alli). Se anade aqui, en la Tarea 4, porque es
   * la primera vez que `.btn` se aplica a un <a> real (los de cabecera.njk/pie.njk): sin esta
   * linea, todo boton-enlace del sitio sale subrayado por el estilo por defecto del navegador,
   * lo que ninguna de las tres direcciones de la maqueta muestra. Se documenta aqui, tal y como
   * pide la Tarea 4, por tocar un fichero que no le pertenece.
   */
  text-decoration: none;
}

.btn-primario {
  /*
   * DEGRADADO, no color plano (2026-09-06): es lo que el titular senala de sus productos. Los dos
   * extremos son fichas -- --rojo y --rojo-hondo -- y los dos cumplen AA con --sobre-rojo encima
   * (5,42:1 y 8,26:1), asi que el boton pasa AA en todo el recorrido del degradado y no solo en el
   * punto que se mire. Los dos pares los recalcula test/piel.test.js desde tokens.css.
   */
  background: linear-gradient(135deg, var(--rojo), var(--rojo-hondo));
  /*
   * `--sobre-rojo` (definido en tokens.css, fuera del brief original -- ver comentario alli) y no
   * un `#fff` literal: cuando el proyecto tenia dos temas, el blanco literal no llegaba al 4,5:1
   * que AA exige a este texto (.87rem/600, por debajo del umbral de "texto grande") en uno de
   * ellos. Hoy la ficha vale blanco y hay una sola paleta, pero se conserva como ficha porque es
   * lo que hace que el par "texto sobre fondo saturado" se pueda medir en test/piel.test.js sin
   * que la prueba tenga que saber que hay un literal escondido en esta regla.
   */
  color: var(--sobre-rojo);
}

.btn-fantasma {
  color: var(--rojo-texto);
  border-color: var(--rojo);
  background: transparent;
}

/*
 * `min-width: 0` (2026-09-07): la tarjeta es item de rejilla en las tres parrillas del sitio
 * (productos, casos, comparativas), y el tamaño MINIMO automatico de un item de rejilla es su
 * `min-content` -- o sea, el ancho de la palabra mas larga que haya dentro. A 360 px con el texto
 * al 200 %, la pista de la parrilla de /casos/ se estiraba a 297,9 px dentro de un contenedor de
 * 292 y las tarjetas salian cortadas 6 px por la derecha. Con esto la pista vuelve a valer lo que
 * dice `1fr` y el texto se parte, que es lo que `overflow-wrap` de aqui abajo permite.
 */
.tarjeta {
  min-width: 0;
  overflow-wrap: break-word;
  background: var(--blanco);
  border: 1px solid var(--linea);
  border-radius: 14px;
  padding: 21px 20px 22px;
  box-shadow: var(--sombra-suave);
}

.tarjeta-elevada {
  background: var(--blanco);
  border: 1px solid var(--linea);
  border-radius: 16px;
  box-shadow: var(--sombra);
}

/*
 * ==================================================================================================
 * LA PIEL CLARA DEL DOSSIER (fase 2, 2026-09-17)
 * ==================================================================================================
 * Sustituye a la superficie de panel oscura (destello, rejilla y titular en degradado) que vivia
 * aqui hasta esta fase: el titular pidio la piel clara del dossier comercial. Lo que sigue son la
 * marca de agua (spec §3.3) y los componentes que la piel necesita -- ver tokens.css para la
 * paleta.
 */

/*
 * `clip-path: inset(0 -100vmax)`: recorta arriba y abajo, y deja pasar a los lados. Los lados
 * hacen falta porque estas secciones son `.contenedor` (1100 px como mucho, centrado) y la marca
 * de agua (el ::before de mas abajo, de 100vw) tiene que llegar al borde de la ventana. Como 100vw
 * incluye la barra de desplazamiento, lo que sobra por los lados lo cortan html y body con
 * `overflow-x: clip`: sin eso habria desplazamiento lateral, que el spec §12.6 prohibe.
 */
/* --fondo-seccion: de que color es ESTA seccion. Existe porque el color lo decide un
   :nth-of-type(even) que cuenta TODAS las <section> del main, no solo las .seccion -- y eso incluye
   al heroe y al cierre, asi que "la primera de contenido" es la PAR y va en blanco. Adivinarlo de
   memoria sale mal: se le puso a la tarjeta de la calculadora un anillo de --fondo creyendo que
   #precio era gris, y quedo un marco gris sobre una seccion blanca. Con el token, todo lo que
   necesite el color de su seccion lo hereda en vez de deducirlo. */
.seccion-hero,
main > .seccion,
main > .seccion-compacta {
  --fondo-seccion: var(--fondo);
  position: relative;
  isolation: isolate;
  clip-path: inset(0 -100vmax);
}

main > .seccion:nth-of-type(even),
main > .seccion-compacta:nth-of-type(even) {
  --fondo-seccion: var(--blanco);
}

/*
 * `clip` y NO `hidden`: `overflow: hidden` convierte al elemento en contenedor de desplazamiento,
 * y eso cambia el comportamiento de todo lo pegajoso que haya dentro (la cabecera del sitio es
 * `position: sticky`). El pie SI conserva su fondo propio: es lo que le da el borde superior algo
 * mas oscuro que lo separa de la ultima seccion.
 */
.pie {
  position: relative;
  isolation: isolate;
  background: var(--pie-fondo);
  overflow: clip;
}

/*
 * Marca de agua del dossier (fase 2, spec §3.3): los trazos del monograma JM2 en gris muy claro,
 * de fondo en el heroe, en cada seccion de contenido y en el pie. El ::before sale a sangre hasta
 * los bordes de la ventana (las secciones son .contenedor, de 1100 px); clip-path de la regla de
 * arriba recorta lo que sobresale en vertical y html/body cortan el desbordamiento horizontal.
 * Las secciones pares van en blanco y con el dibujo en espejo, para no repetir forma dos veces
 * seguidas; las de tablas o texto legal, sin trazos.
 */
html,
body {
  overflow-x: clip;
}

.seccion-hero::before,
main > .seccion::before,
main > .seccion-compacta::before {
  content: "";
  position: absolute;
  inset: 0 calc(50% - 50vw);
  z-index: -2;
  pointer-events: none;
  background: var(--fondo-seccion) url("/assets/img/marca/clara.svg") center / cover no-repeat;
}

main > .seccion:nth-of-type(even)::before,
main > .seccion-compacta:nth-of-type(even)::before {
  background: var(--fondo-seccion) url("/assets/img/marca/blanca.svg") center / cover no-repeat;
  transform: scaleX(-1);
}

/* `:nth-of-type(n)` solo sube la especificidad: sin el, la regla de las pares (0,2,2) ganaba a esta
   y la marca blanca salia detras de las tablas de /precios/, las comparativas y /contratar/.
   `table:not(.calculadora-tablas table)` (2026-09-17): las tablas de respaldo sin JavaScript de la
   calculadora no cuentan, o `#precio` de la portada se quedaba sin marca de agua por llevarlas dentro. */
main > .seccion:nth-of-type(n):has(table:not(.calculadora-tablas table))::before,
main > .seccion:nth-of-type(n):has(.texto-legal)::before,
main > .seccion-compacta:nth-of-type(n):has(table:not(.calculadora-tablas table))::before,
main > .seccion-compacta:nth-of-type(n):has(.texto-legal)::before {
  background-image: none;
}

/*
 * EL PIE VA LISO (2026-09-18). Llevaba la marca de agua `marca/gris.svg`, como el heroe y las
 * secciones llevan la suya. El titular la retiro: "en el footer lo quiero liso el gris sin marca de
 * agua". Con las dos tiras de modulos y las insignias de tienda, el monograma de fondo cruzando por
 * detras cargaba una zona que ya tiene mucho texto.
 *
 * `gris.svg` se queda en el repositorio pero YA NO LO USA NADIE. Si no vuelve, se puede borrar:
 * es el unico de los cuatro (clara, blanca, gris, roja) sin usuarios.
 */

/* Componentes de la piel clara (spec §3.5) */

h1 em,
h2 em {
  font-style: normal;
  color: var(--rojo-texto);
}

.btn:focus-visible {
  outline: 3px solid var(--rojo);
  outline-offset: 3px;
}

.btn-blanco {
  background: var(--blanco);
  color: var(--granate);
}

.btn-fantasma-blanco {
  background: transparent;
  color: var(--sobre-rojo);
  border-color: var(--sobre-rojo);
}

.tarjeta-filo {
  min-width: 0;
  background: var(--blanco);
  border-top: 5px solid var(--rojo);
  border-radius: 16px;
  box-shadow: var(--sombra);
  padding: 26px 28px;
}

/* Foto en capsula: la proporcion es la de las capsulas del dossier (890 x 556) y su extremo libre es
   un semicirculo, asi que las esquinas claras del recorte quedan fuera (spec §3.4). */
/* `clip` y NO `hidden`: `overflow: hidden` convierte a la capsula en contenedor de scroll, y eso
   cambia contra QUE se mide la linea de tiempo de la foto que lleva dentro. Con `hidden`, el
   parallax de movimiento.css medía el viaje de la foto dentro de la propia capsula -- donde la foto
   no se mueve nunca -- y se quedaba clavada. `clip` recorta igual, respeta el border-radius y no
   crea contenedor de scroll. Es el mismo motivo por el que el pie usa `clip`, unas lineas mas
   arriba. */
.capsula {
  position: relative;
  overflow: clip;
  aspect-ratio: 890 / 556;
}

.capsula img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.capsula--izquierda {
  border-radius: 0 999px 999px 0;
}

.capsula--derecha {
  border-radius: 999px 0 0 999px;
}

/* En el dossier todas las capsulas salen del borde izquierdo: la del derecho es la misma foto en espejo. */
.capsula--derecha img {
  transform: scaleX(-1);
}

.lista-check {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 14px;
}

.lista-check li {
  position: relative;
  padding-left: 36px;
  color: var(--tinta-2);
}

.lista-check li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  width: 24px;
  height: 24px;
  background: url("/assets/img/iconos/check.svg") center / contain no-repeat;
}

.insignia {
  display: inline-block;
  font-size: .72rem;
  font-weight: 600;
  line-height: 1.2;
  border-radius: 99px;
  padding: 4px 10px;
  white-space: nowrap;
}

.insignia--incluido { color: var(--insignia-incluido-tinta); background: var(--insignia-incluido-fondo); }
.insignia--anade { color: var(--insignia-anade-tinta); background: var(--insignia-anade-fondo); }
.insignia--aparte { color: var(--insignia-aparte-tinta); background: var(--insignia-aparte-fondo); }
.insignia--pronto { color: var(--insignia-pronto-tinta); background: var(--insignia-pronto-fondo); }

.icono-modulo {
  display: inline-grid;
  place-items: center;
  flex: none;
  width: 42px;
  height: 42px;
  border-radius: 11px;
  border: 1px solid var(--linea);
  background: var(--blanco);
  box-shadow: 0 1px 2px rgba(31, 35, 44, .04);
}

.icono-modulo svg {
  width: 20px;
  height: 20px;
  fill: none;
  stroke: var(--rojo);
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.enlace-flecha {
  display: inline-block;
  font-weight: 600;
  color: var(--rojo-texto);
  text-decoration: none;
}

.enlace-flecha:hover,
.enlace-flecha:focus-visible {
  text-decoration: underline;
}

.pastillas {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.pastillas li {
  font-size: .85rem;
  color: var(--tinta-2);
  background: var(--blanco);
  border: 1px solid var(--linea-fuerte);
  border-radius: 99px;
  padding: 5px 12px;
}

.pastillas a {
  color: inherit;
  text-decoration: none;
}

/* Enlaces dentro del cuerpo de texto (las fuentes de las tablas, la nota de pago, los legales):
   sin esto heredan la tinta del cuerpo y no se distinguen de la frase que los rodea. */
.micro a,
.entradilla a,
.tarjeta p a {
  color: var(--rojo-texto);
  text-decoration: underline;
}


/*
 * ============ Calculadora interactiva (Tarea 6) ============
 * Vive aqui (no en portada.css) a proposito: calculadora.njk se declara reutilizable ("el
 * bloque {% include "calculadora.njk" %}, que usan la portada y /precios/", brief de la
 * Tarea 6) y portada.css solo se carga en index.njk (ver cssExtra en index.11tydata.js y el
 * comentario de base.njk). Si esto viviera en portada.css, /precios/ tendria que declarar el
 * mismo cssExtra solo para que esta seccion se viera bien.
 *
 * Traduccion de `.dir-b .calcbox`/`.slider`/`.chk`/`.box` (web-satcontrol-direcciones.html) a
 * los tokens del proyecto, con una desviacion deliberada: la maqueta dibuja el checkbox y el
 * deslizador con <div> a medida (".box"/".box.on", ".slider i/u"), que no son operables por
 * teclado ni foco nativo. Aqui son <input type="checkbox">/<input type="range"> REALES
 * (la accesibilidad de esta tarea lo exige), coloreados con la propiedad estandar
 * `accent-color` en vez de reconstruir el dibujo a mano -- ningun literal hexadecimal nuevo,
 * `accent-color` toma el mismo acento de texto que el resto del sitio (ver su regla mas abajo).
 */

.calculadora-interactiva {
  display: grid;
  grid-template-columns: 1.25fr 1fr;
  background: var(--superficie);
  border: 1px solid var(--linea);
  border-radius: 16px;
  box-shadow: var(--sombra);
  overflow: hidden;
  margin-top: 12px;
}

@media (max-width: 780px) {
  .calculadora-interactiva {
    grid-template-columns: 1fr;
  }
}

.calculadora-columna-izquierda {
  padding: 26px 28px;
}

.calculadora-columna-derecha {
  padding: 26px 28px;
  background: var(--fondo-2);
}

.calculadora-modulos {
  border: 0;
  padding: 0;
  margin: 18px 0 0;
}

.calculadora-modulos legend {
  font-family: var(--display);
  font-weight: 700;
  font-size: .72rem;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--tinta-2);
  padding: 0;
  margin-bottom: 4px;
}

.calculadora-fila {
  display: flex;
  align-items: center;
  justify-content: space-between;
  /*
   * `flex-wrap: wrap` es la red de seguridad de esta fila (2026-09-07). Sin ella, un nombre de
   * modulo o una etiqueta de disponibilidad que no quepan junto a su importe no se parten: se
   * desbordan de la celda y se pintan encima de la fila vecina. Ya paso una vez, con "En fase de
   * activación" sobre "Gestión de gastos". Partirse en dos lineas siempre es preferible a pisar,
   * y por eso esta regla vive aqui -- en el componente -- y no en una variante concreta.
   */
  flex-wrap: wrap;
  gap: 12px;
  padding: 11px 0;
  border-bottom: 1px solid var(--linea);
  font-size: .9rem;
}

.calculadora-fila:last-child {
  border-bottom: 0;
}

.calculadora-fila-etiqueta {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  cursor: pointer;
}

.calculadora-fila-importe {
  font-variant-numeric: tabular-nums;
  color: var(--tinta-2);
}

/* El tinte de la casilla marcada y de la barra recorrida del deslizador: --rojo-texto (fase 2,
   piel clara del dossier), recalculado por test/piel.test.js contra el umbral de componente. */
.calculadora-interactiva input[type="checkbox"],
.calculadora-interactiva input[type="range"] {
  accent-color: var(--rojo-texto);
}

.calculadora-interactiva input[type="checkbox"] {
  /* 19 px, y no 17: es la medida con la que la sangria de `.etiqueta-no-disponible` (29 px = 19 de
     casilla + 10 de hueco) alinea la etiqueta con el nombre de su modulo. Si cambia una, cambia la
     otra. */
  width: 19px;
  height: 19px;
  flex: 0 0 auto;
}

.calculadora-empleados {
  margin-top: 18px;
}

.calculadora-empleados-cabecera {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  font-size: .85rem;
}

.calculadora-empleados-cabecera output {
  font-family: var(--display);
  font-weight: 700;
}

.calculadora-interactiva input[type="range"] {
  display: block;
  width: 100%;
  margin: 9px 0 6px;
}

.calculadora-empleados-limites {
  display: flex;
  justify-content: space-between;
  font-size: .75rem;
  color: var(--tinta-2);
}

.calculadora-resultado p:first-child {
  margin-bottom: 6px;
}

.calculadora-total {
  font-family: var(--display);
  font-weight: 800;
  font-size: 2.6rem;
  letter-spacing: -.04em;
  line-height: 1;
  /* --rojo-texto y no --rojo: este importe es texto pequeño, y test/piel.test.js recalcula que
     --rojo-texto llega a AA sobre --fondo-2 (la columna derecha de la calculadora). */
  color: var(--rojo-texto);
}

.calculadora-ahorro {
  color: var(--ok);
  font-size: .86rem;
  font-weight: 600;
  margin-top: 7px;
}

.calculadora-cta {
  display: block;
  text-align: center;
  margin-top: 20px;
}

.calculadora-columna-derecha .micro:last-child {
  margin-top: 11px;
}

/*
 * ============ Calculadora: tabla estatica de respaldo (Tarea 5, movida aqui en la ronda de
 * correccion 1 de la Tarea 6) ============
 * Vivia en portada.css, que solo se carga en index.njk (`cssExtra`, ver base.njk). Como
 * `.calculadora-tablas`/`.tabla-precios`/`.nota-marcador` son el respaldo sin JavaScript de
 * `calculadora.njk` -- el bloque reutilizable que tambien incluira /precios/ --, dejarlas en
 * portada.css significaba que cualquier pagina que no fuera la portada incluia el bloque sin
 * hoja de estilos para su tabla de respaldo: se veia sin tabla, sin bordes, todo en una columna.
 * Mismo criterio que ya se aplico a la mitad interactiva de esta seccion (comentario de arriba):
 * si `calculadora.njk` lo necesita, vive donde SIEMPRE se carga.
 */

.calculadora-tablas {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 28px;
  margin-top: 12px;
}

@media (max-width: 780px) {
  .calculadora-tablas {
    grid-template-columns: 1fr;
  }
}

.tabla-precios {
  width: 100%;
  border-collapse: collapse;
  margin-top: 14px;
  font-size: .9rem;
}

.tabla-precios th,
.tabla-precios td {
  text-align: left;
  padding: 10px 14px;
  border-bottom: 1px solid var(--linea);
  /*
   * overflow-wrap (Tarea 13, ronda de correccion 1): esta tabla ya se reutilizaba para 2-3
   * columnas de textos cortos (precios, "Sí"/"No"). La tabla de criterios de comparativas.njk le
   * suma celdas de texto mas largas ("Firma electrónica incluida en el precio, sin coste por
   * firmante", "Sí, incluida en su plan de entrada con límite de documentos") -- ninguna palabra
   * suelta de esas frases es mas larga que las que ya cabian aqui, pero esto es una red de
   * seguridad explicita para que ninguna celda futura, sea cual sea su longitud, pueda forzar un
   * desplazamiento lateral de la pagina entera (restriccion global del sitio a 360px de ancho): sin
   * esta regla, una tabla de layout automatico puede dejar que una palabra suelta mas ancha que su
   * columna desborde el contenedor en vez de partirse. No cambia nada visualmente en las tablas
   * existentes (precios/casos), cuyo contenido ya cabe sin partirse.
   */
  overflow-wrap: anywhere;
}

.tabla-precios th {
  font-family: var(--display);
  font-weight: 700;
  font-size: .72rem;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--tinta-2);
}

/* El rayado guia la lectura de filas largas (la comparativa de /precios/ y las de cada
   comparativa, con celdas de frase entera). */
.tabla-precios tbody tr:nth-child(even) {
  background: var(--fila-par);
}

@media (max-width: 420px) {
  .tabla-precios th,
  .tabla-precios td {
    padding: 8px 8px;
    font-size: .82rem;
  }
}

/* Ronda de correccion 2 de la Tarea 5: marcador de nota en la fila de Soporte remoto (texto
   pequeno sobre fondo claro -> --rojo-texto, regla global del proyecto, igual que
   .cabecera-enlaces a:hover). */
.nota-marcador {
  color: var(--rojo-texto);
  text-decoration: none;
}

.nota-marcador:hover,
.nota-marcador:focus-visible {
  text-decoration: underline;
}

/*
 * ============ Modulo no disponible (Tarea 8, encargo de propagacion de `disponible`) ============
 * Un solo par de clases para las dos superficies que ofrecen modulos (formulario interactivo de
 * calculadora.njk y su tabla de respaldo): la fila se atenua salvo el enlace de aviso (ver abajo) y
 * el nombre del modulo lleva la misma "pildora" de aviso.
 * Ningun literal hexadecimal nuevo: los tres colores son tokens ya declarados en tokens.css
 * (`--apagado` no lo usaba ninguna otra regla hasta esta).
 *
 * Ronda de revision 1 (Tarea 8): `.etiqueta-no-disponible` paso de <span> a <a href="/slug/">
 * (enlaza a la pagina del producto, que trae el aviso completo) -- por eso ahora lleva
 * `text-decoration: underline` por defecto (si no, una pildora con fondo no se lee como enlace) y
 * un estado hover/focus que reutiliza `--rojo-texto`, el mismo color que ya usa `.nota-marcador`
 * para "esto es un enlace de nota", no un color nuevo.
 */
/* Se atenua lo que no se puede usar (casilla, nombre e importe), no el enlace que explica por que:
   con la fila entera a .6 ese enlace quedaba a 2,43:1. En la tabla de respaldo nombre y enlace
   comparten celda, asi que ahi se atenua con color y no con opacidad. */
.calculadora-fila-no-disponible .calculadora-fila-etiqueta,
.calculadora-fila-no-disponible .calculadora-fila-importe:not(.etiqueta-no-disponible) {
  opacity: .6;
}

.fila-no-disponible {
  color: var(--apagado);
}

.calculadora-fila-no-disponible .calculadora-fila-etiqueta,
.calculadora-fila-no-disponible input[type="checkbox"] {
  cursor: not-allowed;
}

/*
 * Cuando la fila se parte (ver `flex-wrap` en `.calculadora-fila`), la etiqueta cae en una linea
 * propia y hasta el 2026-09-07 lo hacia pegada al borde izquierdo, a la altura de la casilla: leida
 * asi no etiquetaba a su modulo sino al de la fila de abajo. Sangrada lo que mide la casilla mas su
 * hueco (19 + 10) queda alineada con el NOMBRE al que se refiere. Cuando la fila NO se parte esta
 * sangria es invisible: `justify-content: space-between` ya separa los dos extremos mucho mas.
 */
.calculadora-fila-no-disponible .etiqueta-no-disponible {
  margin-left: 29px;
  color: var(--tinta-2);
}

.etiqueta-no-disponible {
  display: inline-block;
  font-size: .68rem;
  font-weight: 600;
  letter-spacing: .02em;
  color: var(--apagado);
  background: var(--fondo-2);
  border: 1px solid var(--linea);
  border-radius: 999px;
  padding: 2px 9px;
  margin-left: 8px;
  text-decoration: underline;
}

.etiqueta-no-disponible:hover,
.etiqueta-no-disponible:focus-visible {
  color: var(--rojo-texto);
}

/*
 * ============ Texto legal ============
 * Cuerpo de las cuatro paginas legales heredadas y del aviso legal. Vive en base.css (que se carga
 * siempre) y no en portada.css: esas paginas ya no declaran `cssExtra` -- lo unico que sacaban de
 * portada.css era `.aviso-disponibilidad`, el componente del marcador de texto pendiente, que ha
 * desaparecido con el.
 *
 * No hay maqueta que copiar: `.dir-b` no maqueta ninguna pagina de texto largo. Se deriva de lo
 * que ya existe -- misma tipografia, mismos tokens de color, ningun literal hexadecimal nuevo -- y
 * la unica decision propia es la MEDIDA: 68ch. Un texto legal se lee de arriba a abajo, y a lo
 * ancho de los 1100px del `.contenedor` una linea rondaria los 150 caracteres, mas del doble de lo
 * que se sigue con comodidad.
 */

/* `.texto-articulo` (2026-09-24): el cuerpo de los articulos del blog, con la misma columna de
   lectura que los textos legales. */
.texto-legal,
.texto-articulo {
  max-width: 68ch;
}

.texto-legal p,
.texto-articulo p {
  margin-bottom: 16px;
}

.articulo-fuente {
  max-width: 68ch;
  margin-top: 8px;
}

.articulo-fuente p {
  margin: 6px 0 0;
}

.articulo-accion {
  margin-top: 24px;
}

.articulo-volver {
  margin-top: 24px;
}

/* Aire por encima de cada encabezado del documento, no por debajo: separa secciones sin alejar el
   titulo de su primer parrafo. `:first-child` evita el hueco inicial, que ya lo pone `.seccion`. */
.texto-legal h2,
.texto-articulo h2 {
  margin-top: 34px;
  font-size: clamp(1.25rem, 2.4vw, 1.6rem);
}

.texto-legal h2:first-child,
.texto-articulo h2:first-child {
  margin-top: 0;
}

.texto-legal a {
  color: var(--rojo-texto);
}

/*
 * Datos identificativos del aviso legal (LSSI-CE): una <dl> de verdad, no una tabla ni parrafos
 * con negritas -- cada dato es un par etiqueta/valor y asi es como lo anuncia un lector de
 * pantalla. En pantallas estrechas cae a una sola columna.
 */
.datos-identificativos {
  display: grid;
  grid-template-columns: minmax(11rem, auto) 1fr;
  gap: 10px 24px;
  margin: 0;
}

.datos-identificativos dt {
  font-family: var(--display);
  font-weight: 700;
  font-size: .78rem;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--tinta-2);
  padding-top: 3px;
}

.datos-identificativos dd {
  margin: 0;
}

@media (max-width: 560px) {
  .datos-identificativos {
    grid-template-columns: 1fr;
    gap: 2px 0;
  }

  .datos-identificativos dd {
    margin-bottom: 14px;
  }
}

/* Compartidas entre paginas: `.heroe-ctas` (portada, 404, contacto, modulos y casos), la rejilla y
   su icono (indices de casos y comparativas) y `.producto-precio` (paginas de modulo). */

.heroe-ctas {
  display: flex;
  gap: 11px;
  flex-wrap: wrap;
  margin-top: 22px;
}

.productos-rejilla {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 14px;
  margin-top: 28px;
}

@media (max-width: 900px) {
  .productos-rejilla {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 560px) {
  .productos-rejilla {
    grid-template-columns: 1fr;
  }
}

.producto-icono {
  width: 40px;
  height: 40px;
  border-radius: 11px;
  background: var(--fondo-2);
  color: var(--rojo-texto);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--display);
  font-weight: 700;
  margin-bottom: 13px;
}

/*
 * Aqui vivia `.escena .producto-icono`, que le ponia el degradado de marca al icono cuando la
 * rejilla de productos iba dentro de una escena anclada, sobre la superficie de panel. Con las
 * escenas retiradas (2026-09-06) esa seccion vuelve al lienzo claro del resto del sitio, donde el
 * velo neutro de la regla de aqui arriba es lo correcto -- que es exactamente lo mismo que ya
 * hacian los indices de casos y de comparativas con esta misma clase.
 */

.producto-precio {
  font-size: .8rem;
  font-weight: 600;
  color: var(--rojo-texto);
  margin-top: 4px;
}

/*
 * ============ Aviso de disponibilidad (Tarea 7, ronda de correccion 1) ============
 * Bloque nuevo: no hay maqueta que copiar -- `web-satcontrol-direcciones.html` no maqueta ningun
 * aviso de disponibilidad, esto no existia en ninguna direccion de diseno. Solo lo usa hoy
 * `/facturacion/` (ver `producto.disponible` en productos.js y su uso en productos.njk), escrito
 * como componente reutilizable por si otro producto entra en la misma situacion mas adelante.
 * Ningun literal hexadecimal nuevo: `--rojo`/`--rojo-texto`/`--fondo-2`/`--tinta` ya existen en
 * tokens.css. El borde izquierdo grueso en `--rojo` (en vez de fondo saturado en rojo) es a
 * proposito: es un aviso informativo ("todavia no", no un error ni una plantilla de urgencia
 * roja), asi que solo el acento de borde usa el color de marca; el fondo es el neutro `--fondo-2`
 * (blanco en la piel clara), como otras superficies secundarias.
 */
.aviso-disponibilidad {
  margin-top: 22px;
  max-width: 60ch;
  padding: 14px 18px;
  background: var(--fondo-2);
  border: 1px solid var(--linea);
  /* Este filete es lo unico que distingue el aviso de una caja normal, asi que 1.4.11 le pide 3:1
     contra lo que lo rodea; test/piel.test.js lo recalcula. */
  border-left: 4px solid var(--rojo-texto);
  border-radius: 8px;
  font-size: .92rem;
  color: var(--tinta);
  text-align: left;
}

.aviso-disponibilidad strong {
  color: var(--rojo-texto);
}

/* Mismo --rojo-texto que ya usa `.aviso-disponibilidad`: esta regla existe por si el heroe alguna
   vez necesita un filete distinto al del resto del sitio. */
.seccion-hero .aviso-disponibilidad {
  border-left-color: var(--rojo-texto);
}

/*
 * ============ Logotipo de producto (2026-09-06) ============
 * Solo lo pintan las tres paginas de producto que tienen logotipo propio (ver `logotipo` en
 * productos.js). No hay maqueta que copiar -- `.dir-b` no maqueta ninguna pagina de producto --,
 * asi que se compone con lo que ya existe: la misma placa con borde `--linea` y esquinas
 * redondeadas de `.tarjeta`. Ningun literal hexadecimal nuevo: `--placa-logo` (tokens.css) es
 * blanco opaco porque los tres logotipos de producto vienen sobre fondo blanco sin canal alfa.
 *
 * `display: block` con `width: fit-content`: la placa mide lo que el logotipo, no el ancho del
 * heroe, pero ocupa su propia linea. Era `inline-block`, y con el <p> en linea la etiqueta que va
 * justo despues se colocaba A SU DERECHA en vez de debajo -- se ve en /facturacion/, donde la
 * pildora "FACTURACIÓN VERIFACTU" aparecia colgada del costado de la placa.
 * `height` fija + `width: auto` en la imagen, igual que el logotipo de la cabecera: el HTML declara
 * las medidas del fichero para que no salte la maquetacion, y el CSS decide el tamaño en pantalla.
 */
.logo-producto {
  display: block;
  width: fit-content;
  max-width: 100%;
  margin: 0 0 18px;
  padding: 10px 16px;
  background: var(--placa-logo);
  border: 1px solid var(--linea);
  border-radius: 12px;
  line-height: 0;
}

.logo-producto img {
  height: 40px;
  width: auto;
}

/* Casos en tarjeta: pagina de modulo y portada (fase 2, spec §6.4 y §8) */
.rejilla-casos {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 24px;
}

@media (max-width: 900px) {
  .rejilla-casos {
    grid-template-columns: minmax(0, 1fr);
  }
}

.tarjeta-caso {
  position: relative;
  overflow: hidden;
  display: grid;
  gap: 10px;
  align-content: start;
  min-width: 0;
  background: var(--blanco);
  border: 1px solid var(--linea);
  border-radius: 16px;
  padding: 26px 28px 26px 32px;
}

.tarjeta-caso::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 4px;
  background: var(--rojo);
}

.tarjeta-caso h3 {
  margin: 0;
}

.tarjeta-caso p {
  color: var(--tinta-2);
}

.tarjeta-caso .tarjeta-caso-sector {
  font-size: .75rem;
  font-weight: 600;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--oro-texto);
}
