/* ==========================================================================
   Blueprint — portada comercial
   --------------------------------------------------------------------------
   Tres decisiones que explican casi todo lo que sigue.

   1. NO HAY FUENTE MANUSCRITA, Y NO HAY FUENTE EXTERNA.
      La versión anterior traía 'Shadows Into Light' desde Typekit y la usaba
      para la entradilla de cada sección — es decir, para la frase más
      importante de cada pantalla. Una tipografía de fantasía cargando el texto
      que tiene que convencer hace dos daños a la vez: cuesta leerla, y le dice
      al visitante que esto es una maqueta. Además era una llamada a un tercero
      en un sitio que promete no hacer ninguna.
      Acá manda la tipografía del sistema, que es exactamente lo que hace Apple:
      en un Mac se ve en SF Pro, en Windows en Segoe, y en ambos se ve nativa,
      instantánea y sin pedirle nada a nadie.

   2. EL PRODUCTO SE MUESTRA, NO SE CUENTA.
      Cada sección tiene una captura real de la plataforma funcionando, y la
      captura es lo grande de la sección. El texto está para decir qué mirar.

   3. EL CONTENIDO NO DEPENDE DEL JAVASCRIPT.
      Antes todo nacía en opacity:0 y sólo la revelación al hacer scroll lo
      encendía: sin JS, o para un buscador, la página quedaba en blanco. Acá la
      animación es una mejora sobre algo que ya se ve.
   ========================================================================== */

:root {
  /* Marca. Los mismos valores del producto, para que el sitio y la
     plataforma no se vean como dos cosas distintas. */
  --azul: #003153;
  --azul-hondo: #001d30;
  --azul-vivo: #1a7fb8;
  --cian: #4fb8e8;

  --tinta: #0a0e14;
  --tinta-2: #33415c;
  --gris: #5b6b84;
  --gris-2: #8a99b0;
  --linea: #e3e7ee;
  --linea-tenue: #eef1f6;

  --papel: #ffffff;
  --papel-2: #f6f7f9;
  --papel-3: #eceff4;

  /* Curvas fuertes: las de fábrica de CSS no tienen carácter suficiente y
     dejan las transiciones con aspecto de plantilla. */
  --sale: cubic-bezier(0.23, 1, 0.32, 1);

  --sombra-1: 0 1px 2px rgb(10 14 20 / .04), 0 1px 3px rgb(10 14 20 / .06);
  --sombra-2: 0 2px 4px rgb(10 14 20 / .04), 0 12px 28px rgb(10 14 20 / .08);
  --sombra-3: 0 4px 10px rgb(10 14 20 / .06), 0 40px 80px rgb(10 14 20 / .16);

  --radio-s: 10px;
  --radio: 14px;
  --radio-l: 22px;

  /*
   * Las marcas de plano, como máscaras.
   *
   * Son las mismas de la versión anterior y se conservan a propósito: la
   * retícula y las cotas son la identidad de la marca —de ahí sale el nombre—
   * y quitarlas del todo dejaba el sitio correcto pero anónimo. Lo que cambia
   * es la dosis: antes cubrían la página entera y competían con el texto;
   * ahora aparecen sólo sobre los fondos oscuros y en los bordes, donde se
   * perciben más de lo que se ven.
   *
   * Van como `mask-image` y no como imagen de fondo para poder pintarlas del
   * color que corresponda en cada fondo sin duplicar el SVG.
   */
  --cota-h: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 132 42'%3E%3Cg fill='none' stroke='black' stroke-width='1.15' stroke-linecap='round' stroke-linejoin='round'%3E %3Cpath d='M10 4v30M122 4v30'/%3E %3Cpath d='M10 28h112'/%3E %3Cpath d='M4 33l12-10M116 33l12-10'/%3E %3C/g%3E %3Ctext x='66' y='22' font-size='11' fill='black' font-family='Helvetica,Arial,sans-serif' text-anchor='middle'%3E2.40%3C/text%3E%3C/svg%3E");
  --cota-v: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 52 146'%3E%3Cg fill='none' stroke='black' stroke-width='1.15' stroke-linecap='round' stroke-linejoin='round'%3E %3Cpath d='M18 10h30M18 136h30'/%3E %3Cpath d='M24 10v126'/%3E %3Cpath d='M19 4l10 12M19 130l10 12'/%3E %3C/g%3E %3Ctext x='42' y='73' font-size='11' fill='black' font-family='Helvetica,Arial,sans-serif' text-anchor='middle' transform='rotate(-90 42 73)'%3E0.90%3C/text%3E%3C/svg%3E");

  --ancho: 1120px;
  --canto: 24px;

  /* La barra es fija: todo lo que se ancle arriba tiene que descontarla, y
     también los saltos a un ancla. */
  --barra: 56px;

  /*
   * La manuscrita de la marca (Typekit, `ikz5ryk`).
   *
   * Va como token y no suelta en la regla para que cambiar su alcance —o
   * volver atrás— sea tocar un solo lugar. El respaldo es la fuente del
   * sistema, deliberadamente: si Typekit no responde, la entradilla se ve como
   * el resto del texto, en vez de caer en la cursiva que traiga el sistema
   * operativo, que nunca es la que uno quiere.
   */
  --manuscrita: 'shadows-into-light', -apple-system, BlinkMacSystemFont, sans-serif;
}

/* --------------------------------------------------------------------------
   Base
   -------------------------------------------------------------------------- */

*, *::before, *::after { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  /* Sin esto, un enlace a #ancla deja el título debajo de la barra fija. */
  scroll-padding-top: calc(var(--barra) + 16px);
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--papel);
  color: var(--tinta);
  font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Text', 'Segoe UI',
    Roboto, 'Helvetica Neue', Arial, sans-serif;
  font-size: 17px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  /* La página nunca se desplaza en horizontal. Es la regla que más se rompe
     sola cuando una imagen o una tabla se pasa de ancho. */
  overflow-x: hidden;
}

img { max-width: 100%; height: auto; display: block; }
a { color: inherit; }

/*
 * Tracking por tamaño, no un solo valor para todo.
 *
 * Las letras de un titular grande se leen demasiado separadas si conservan el
 * espaciado del texto corrido; las de un texto chico, demasiado juntas. Es la
 * misma regla del optical sizing de Apple, aplicada a mano.
 */
/* Ninguna palabra se parte con guión, en ningún idioma y a ningún ancho. Los
   navegadores no guionan por omisión, pero dejarlo escrito evita que alguien
   lo active «para que quepa» — que es exactamente el defecto que hubo que
   corregir en la hoja de estilos de las páginas antiguas. */
h1, h2, h3, h4, p, li, span, b, a {
  -webkit-hyphens: manual;
  hyphens: manual;
}

h1, h2, h3 {
  margin: 0;
  font-weight: 700;
  line-height: 1.06;
  letter-spacing: -0.028em;
  text-wrap: balance;
}

h1 { font-size: clamp(2.5rem, 6.2vw, 4.25rem); }
h2 { font-size: clamp(2rem, 4.4vw, 3.1rem); }
h3 { font-size: clamp(1.15rem, 1.6vw, 1.35rem); letter-spacing: -0.02em; line-height: 1.25; }

p { margin: 0; }

.env {
  width: 100%;
  max-width: var(--ancho);
  margin-inline: auto;
  padding-inline: var(--canto);
}

/* Para lectores de pantalla y nada más. */
.solo-lector {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.saltar {
  position: absolute; left: 12px; top: -60px; z-index: 100;
  background: var(--azul); color: #fff; padding: 10px 16px;
  border-radius: var(--radio-s); font-weight: 600; text-decoration: none;
  transition: top 160ms var(--sale);
}
.saltar:focus { top: 12px; }

:where(a, button, summary):focus-visible {
  outline: 2px solid var(--azul-vivo);
  outline-offset: 3px;
  border-radius: 6px;
}

/* --------------------------------------------------------------------------
   Barra
   --------------------------------------------------------------------------
   Translúcida con desenfoque, como una capa que flota sobre el contenido y no
   como una franja que se lo come. El desenfoque no es decorativo: sin él, el
   texto que pasa por debajo se mezcla con el de la barra y las dos cosas se
   vuelven ilegibles — que es exactamente lo que pasaba antes.
   -------------------------------------------------------------------------- */

/*
 * Arriba del todo la barra desaparece; en cuanto se baja, se materializa.
 *
 * La portada es el plano azul hondo, y una franja blanca cruzándola por arriba
 * la parte en dos. Mientras no se ha desplazado nada, la barra no tiene fondo y
 * su tipografía va en blanco: el plano llega hasta el borde de la ventana.
 * Apenas hay contenido pasando por debajo aparece el vidrio esmerilado, que es
 * lo que hace falta para que el texto no se mezcle con el de la barra.
 *
 * El fondo y el desenfoque se animan juntos: una superficie de vidrio que
 * aparece sólo cambiando la opacidad se lee como un velo, no como un material.
 */
/*
 * Fija y no pegajosa: la barra flota SOBRE la portada, no encima de ella.
 *
 * Con `sticky` la barra ocupa sitio propio y dejaba una franja blanca de 56 px
 * por arriba del plano azul, que partía la portada en dos. Fija, el plano llega
 * hasta el borde de la ventana y la barra se le pone encima — que es cómo se
 * comporta una capa de vidrio. El hueco lo compensa la portada con su padding.
 */
.barra {
  position: fixed; inset: 0 0 auto; z-index: 50;
  height: var(--barra);
  background: rgb(255 255 255 / 0);
  backdrop-filter: saturate(100%) blur(0px);
  -webkit-backdrop-filter: saturate(100%) blur(0px);
  border-bottom: 1px solid transparent;
  transition:
    background 260ms var(--sale),
    backdrop-filter 260ms var(--sale),
    -webkit-backdrop-filter 260ms var(--sale),
    border-color 260ms var(--sale);
}
.barra[data-desplazada='si'] {
  background: rgb(255 255 255 / .94);
  backdrop-filter: saturate(180%) blur(20px);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  border-bottom-color: rgb(10 14 20 / .08);
}

/* Sobre el plano, en blanco. */
.barra[data-desplazada='no'] .barra-menu a { color: rgb(255 255 255 / .82); }
.barra[data-desplazada='no'] .barra-menu a:hover { color: #fff; }
.barra[data-desplazada='no'] .abrir-menu { color: #fff; }
/* Sobre la portada oscura, lo mismo al revés: blanco al 15% con filete claro.
   Aquí el contraste del texto lo da el fondo azul, no el relleno del botón. */
.barra[data-desplazada='no'] .barra-cta {
  background: rgb(255 255 255 / .15);
  color: #fff;
  border-color: rgb(255 255 255 / .42);
}
.barra[data-desplazada='no'] .barra-cta:hover {
  background: #fff;
  color: var(--azul-hondo);
  border-color: #fff;
}

/* El logotipo tiene sus dos versiones y se cruzan; no se cambia el `src`,
   porque eso provoca un parpadeo la primera vez que se sube la página. */
.barra-marca { position: relative; }
.barra-marca img { transition: opacity 260ms var(--sale); }
.barra-marca .negativo { position: absolute; inset: 0; }
.barra[data-desplazada='no'] .barra-marca .positivo { opacity: 0; }
.barra[data-desplazada='si'] .barra-marca .negativo { opacity: 0; }

.barra-int {
  height: 100%;
  display: flex; align-items: center; gap: 28px;
  max-width: var(--ancho); margin-inline: auto; padding-inline: var(--canto);
}

.barra-marca { display: flex; align-items: center; text-decoration: none; flex: none; }
/*
 * El logotipo, cuatro píxeles más alto.
 *
 * A 21 px pesaba menos que el botón de la derecha y los dos competían: en una
 * barra, lo primero que tiene que reconocerse es de quién es el sitio, y lo
 * segundo qué se puede hacer en él. Con 25 px la marca recupera ese orden sin
 * engordar la barra —siguen sobrando 15 px de los 56 de alto— y el botón, ya
 * aligerado, deja de disputárselo.
 */
.barra-marca img { height: 25px; width: auto; }

.barra-menu { display: flex; align-items: center; gap: 26px; margin-left: auto; }
.barra-menu a {
  font-size: 14px; color: var(--tinta-2); text-decoration: none;
  transition: color 160ms ease;
}
.barra-menu a:hover { color: var(--tinta); }

/*
 * El botón de la barra es el segundo, no el primero.
 *
 * Era un pastilla azul maciza y pesaba más que el logotipo, así que la barra
 * tenía dos centros de atención peleándose. Y encima duplica un botón que ya
 * está, macizo y grande, tres líneas más abajo en la portada.
 *
 * Se vuelve translúcido: el mismo azul de marca al 10%, con la palabra en azul
 * y un filete que le da borde. Sigue leyéndose como botón —el contorno y la
 * pastilla están— pero deja de gritar. Al pasar el puntero sube a macizo, que
 * es cuando la persona ya lo eligió y conviene confirmárselo.
 */
.barra-cta {
  flex: none;
  font-size: 14px; font-weight: 600;
  padding: 8px 16px; border-radius: 980px;
  background: rgb(0 49 83 / .09);
  color: var(--azul);
  border: 1px solid rgb(0 49 83 / .2);
  text-decoration: none;
  transition: transform 160ms var(--sale), background 160ms ease,
    color 160ms ease, border-color 160ms ease;
}
.barra-cta:hover {
  background: var(--azul);
  color: #fff;
  border-color: var(--azul);
}
/* Respuesta al presionar. Sin esto un botón se siente muerto. */
.barra-cta:active { transform: scale(.97); }

.abrir-menu {
  display: none; margin-left: auto;
  background: none; border: 0; padding: 8px; cursor: pointer;
  color: var(--tinta);
}

/* --------------------------------------------------------------------------
   Botones
   -------------------------------------------------------------------------- */

.boton {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  font-size: 16px; font-weight: 600; text-decoration: none;
  padding: 13px 26px; border-radius: 980px;
  border: 1px solid transparent;
  transition: transform 160ms var(--sale), background 160ms ease, border-color 160ms ease;
}
.boton:active { transform: scale(.97); }

.boton-lleno { background: var(--azul); color: #fff; }
.boton-lleno:hover { background: var(--azul-hondo); }

.boton-linea { background: transparent; color: var(--azul); border-color: rgb(0 49 83 / .25); }
.boton-linea:hover { border-color: var(--azul); background: rgb(0 49 83 / .04); }

.oscuro .boton-lleno { background: #fff; color: var(--azul-hondo); }
.oscuro .boton-lleno:hover { background: #eaf4fb; }
.oscuro .boton-linea { color: #fff; border-color: rgb(255 255 255 / .35); }
.oscuro .boton-linea:hover { border-color: #fff; background: rgb(255 255 255 / .08); }

.botonera { display: flex; flex-wrap: wrap; gap: 12px; }

/* --------------------------------------------------------------------------
   Ritmo de las secciones
   --------------------------------------------------------------------------
   Un solo valor de aire entre secciones, y otro dentro. La versión anterior
   tenía huecos de 400 px en unos lugares y de 40 en otros, y esa irregularidad
   es la que hace que una página se vea armada a mano y no diseñada.
   -------------------------------------------------------------------------- */

/*
 * Todas las secciones respiran por arriba y por abajo. Sin excepciones.
 *
 * Antes había una regla que le quitaba el aire superior a toda sección que
 * viniera después de otra, para evitar el doble espacio entre dos bloques del
 * mismo color. La idea era razonable y el efecto era pésimo: cuando el bloque
 * de arriba tenía fondo —el plano azul, el papel gris— el titular del bloque
 * blanco quedaba pegado al canto del color, como si fuera el pie del bloque
 * anterior y no el encabezado del suyo.
 *
 * El doble espacio entre dos bloques del mismo color no es un problema: son
 * dos temas distintos y separarlos está bien. Un titular pegado a un borde sí
 * lo es.
 */
.seccion { padding-block: clamp(64px, 7.5vw, 110px); }

.tenue {
  background: var(--papel-2);
  /* La misma retícula, casi imperceptible: sobre papel claro basta muchísimo
     menos contraste para que se note que hay una trama debajo. */
  background-image:
    linear-gradient(rgb(0 49 83 / .028) 1px, transparent 1px),
    linear-gradient(90deg, rgb(0 49 83 / .028) 1px, transparent 1px);
  background-size: 28px 28px, 28px 28px;
}

.oscuro {
  position: relative;
  isolation: isolate;
  background:
    radial-gradient(120% 90% at 50% 0%, #0a4a75 0%, transparent 60%),
    var(--azul-hondo);
  color: #fff;
}

/*
 * La retícula del plano.
 *
 * Dos tramas superpuestas —una fina de 28 px y una gruesa de 140— que es como
 * se dibuja una lámina de verdad: la fina para medir, la gruesa para ubicarse.
 * Muy tenue: una cuadrícula que se lee como cuadrícula compite con el texto.
 * Y se desvanece hacia abajo, para que el pie de la sección quede limpio y el
 * paso al siguiente bloque no tenga costura.
 */
.oscuro::before {
  content: '';
  position: absolute; inset: 0; z-index: -1;
  pointer-events: none;
  background-image:
    linear-gradient(rgb(255 255 255 / .035) 1px, transparent 1px),
    linear-gradient(90deg, rgb(255 255 255 / .035) 1px, transparent 1px),
    linear-gradient(rgb(255 255 255 / .07) 1px, transparent 1px),
    linear-gradient(90deg, rgb(255 255 255 / .07) 1px, transparent 1px);
  background-size: 28px 28px, 28px 28px, 140px 140px, 140px 140px;
  -webkit-mask-image: linear-gradient(180deg, #000 0%, #000 55%, transparent 100%);
  mask-image: linear-gradient(180deg, #000 0%, #000 55%, transparent 100%);
}

/*
 * Una cota, arriba a la izquierda de la sección oscura.
 *
 * Es la firma de la marca y va donde va en una lámina: en el margen, fuera del
 * dibujo. Una sola por sección — repetirla en cada bloque la convierte en
 * papel mural.
 *
 * En la portada no va: ahí ya está `.marca-1`, que es la misma cota y además
 * entra animada. Las dos juntas quedaban una encima de otra, la de arriba
 * quieta y la de abajo apareciendo — se leía como un error de montaje, que es
 * exactamente lo que era.
 */
.oscuro::after {
  content: '';
  position: absolute; z-index: -1;
  left: clamp(16px, 4vw, 64px); top: 34px;
  width: 132px; height: 42px;
  background: rgb(255 255 255 / .3);
  -webkit-mask-image: var(--cota-h); mask-image: var(--cota-h);
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-size: contain; mask-size: contain;
  pointer-events: none;
}

/*
 * En la portada, no.
 *
 * Ahí ya está `.marca-1`, que es la misma cota y además entra animada. Las dos
 * juntas quedaban una encima de otra, la de arriba quieta y la de abajo
 * apareciendo: se leía como un error de montaje, que es lo que era.
 *
 * Va DESPUÉS de `.oscuro::after` y no antes. Las dos reglas tienen la misma
 * especificidad —una clase y un pseudoelemento— así que decide el orden, y
 * puesta antes perdía. Es el mismo tropiezo que el de `.bloque.invertido`, con
 * la variante de que acá ni siquiera hacía falta una consulta de medios.
 */
.portada::after { content: none; }

/*
 * Dos secciones oscuras seguidas necesitan un canto.
 *
 * En la página de cumplimiento la portada y la sección siguiente son las dos
 * del mismo azul, y sin nada entre ellas se leían como un solo bloque partido
 * por una costura casual. Un filete claro convierte esa costura en una línea
 * puesta a propósito, que es lo que hace una lámina cuando cambia de zona.
 */
.oscuro + .oscuro { border-top: 1px solid rgb(255 255 255 / .09); }
/* Y el resplandor de la segunda no puede ser más claro que el pie de la primera:
   si lo es, el canto se lee como un salto de color y no como una línea. */
.oscuro + .oscuro { background: var(--azul-hondo); }

/* En el papel claro la cota va vertical y en el canto derecho, como la cota
   general de una lámina. Se esconde en pantallas angostas: ahí no hay margen
   que le sobre a nadie. */
.tenue { position: relative; isolation: isolate; }
.tenue::after {
  content: '';
  position: absolute; z-index: -1;
  right: 22px; top: 12%;
  width: 52px; height: 146px;
  background: rgb(0 49 83 / .16);
  -webkit-mask-image: var(--cota-v); mask-image: var(--cota-v);
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-size: contain; mask-size: contain;
  pointer-events: none;
}
@media (max-width: 1280px) { .tenue::after { display: none; } }
.oscuro h2, .oscuro h3 { color: #fff; }
.oscuro .bajada, .oscuro .cuerpo { color: rgb(255 255 255 / .78); }
.oscuro .rotulo { color: var(--cian); }

.rotulo {
  font-size: 12.5px; font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; color: var(--azul-vivo);
  margin-bottom: 14px;
}

/* La entradilla. Antes iba en manuscrita; ahora es simplemente el texto más
   grande del bloque, que es como se marca la jerarquía sin disfraces. */
.bajada {
  font-size: clamp(1.1rem, 1.5vw, 1.3rem);
  line-height: 1.5;
  color: var(--tinta-2);
  max-width: 62ch;
  text-wrap: pretty;
}

.cuerpo { color: var(--gris); max-width: 62ch; text-wrap: pretty; }

.encabezado-seccion { max-width: 46rem; margin-bottom: clamp(32px, 4vw, 56px); }
.encabezado-seccion h2 + .bajada { margin-top: 18px; }

/* --------------------------------------------------------------------------
   Portada
   -------------------------------------------------------------------------- */

/*
 * La portada es el plano.
 *
 * Acá está la presencia de la marca: fondo azul hondo, la retícula de la lámina
 * y sus marcas —cotas con su medida— alrededor del contenido. Es de donde sale
 * el nombre del producto y es lo primero que se ve.
 *
 * Sobre ese fondo el MacBook flota, que es exactamente lo que hace falta: la
 * pantalla del producto es clara y contra el azul hondo gana todo el contraste
 * sin necesidad de ninguna sombra inventada.
 *
 * La retícula de la portada va más marcada que la de las otras secciones
 * oscuras —es la firma— pero se disuelve hacia el centro para que el titular no
 * tenga que pelear con ella.
 */
.portada {
  text-align: center;
  padding-top: calc(var(--barra) + clamp(48px, 6vw, 88px));
  /*
   * Cero abajo: la base del computador ES el borde de la sección.
   *
   * La retícula del plano termina exactamente donde apoya el equipo, y desde
   * ahí empieza el blanco. Con un padding abajo quedaba una franja oscura por
   * debajo del computador y el equipo se leía flotando dentro de una caja, en
   * vez de apoyado sobre la línea que separa las dos secciones.
   */
  padding-bottom: 0;
}

.portada::before {
  background-image:
    linear-gradient(rgb(255 255 255 / .05) 1px, transparent 1px),
    linear-gradient(90deg, rgb(255 255 255 / .05) 1px, transparent 1px),
    linear-gradient(rgb(255 255 255 / .1) 1px, transparent 1px),
    linear-gradient(90deg, rgb(255 255 255 / .1) 1px, transparent 1px);
  background-size: 28px 28px, 28px 28px, 140px 140px, 140px 140px;
  -webkit-mask-image: radial-gradient(58% 46% at 50% 34%, transparent 0%, #000 78%);
  mask-image: radial-gradient(58% 46% at 50% 34%, transparent 0%, #000 78%);
}

/* Las marcas de plano de la portada: dos cotas en los márgenes, como en una
   lámina. No van sobre el dibujo — van alrededor. */
.marcas { position: absolute; inset: 0; z-index: -1; pointer-events: none; }
.marca {
  position: absolute;
  background: rgb(255 255 255 / .34);
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-size: contain; mask-size: contain;
}
.marca-1 {
  left: clamp(16px, 4vw, 56px); top: calc(var(--barra) + 26px); width: 132px; height: 42px;
  -webkit-mask-image: var(--cota-h); mask-image: var(--cota-h);
}
.marca-2 {
  right: clamp(16px, 4vw, 56px); top: 22%; width: 52px; height: 146px;
  -webkit-mask-image: var(--cota-v); mask-image: var(--cota-v);
}
.marca-3 {
  left: clamp(16px, 5vw, 90px); bottom: 16%; width: 132px; height: 42px;
  -webkit-mask-image: var(--cota-h); mask-image: var(--cota-h);
  /* Más tenue que las otras dos, pero por color y no por `opacity`: la entrada
     termina en `opacity: 1` y una opacidad propia acá se perdería al acabar. */
  background: rgb(255 255 255 / .24);
}
@media (max-width: 900px) { .marca-2, .marca-3 { display: none; } }

.portada .bajada { color: rgb(255 255 255 / .82); }
.portada-nota { color: rgb(255 255 255 / .55); }

.portada h1 { max-width: 15ch; margin-inline: auto; }
.portada .bajada {
  margin: 22px auto 0;
  max-width: 54ch;
  font-size: clamp(1.15rem, 1.6vw, 1.35rem);
}
/* --------------------------------------------------------------------------
   El índice de la portada de cumplimiento
   --------------------------------------------------------------------------
   Cuatro tarjetas translúcidas sobre el plano. No compiten con el titular: la
   norma va en gris claro y el nombre del tema en blanco, con el peso justo
   para que se lea que son cuatro puertas y no cuatro párrafos.
   -------------------------------------------------------------------------- */

.indice-normas {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 14px;
  margin-top: clamp(36px, 4.5vw, 60px);
  text-align: left;
}

.indice-normas a {
  display: block;
  padding: 16px 18px;
  border-radius: var(--radio);
  background: rgb(255 255 255 / .06);
  border: 1px solid rgb(255 255 255 / .14);
  text-decoration: none;
  transition: background 180ms var(--sale), border-color 180ms var(--sale),
    transform 180ms var(--sale);
}
.indice-normas a:hover {
  background: rgb(255 255 255 / .11);
  border-color: rgb(255 255 255 / .28);
  transform: translateY(-2px);
}
.indice-normas a:active { transform: translateY(0) scale(.99); }

.indice-normas b {
  display: block;
  font-size: 15.5px; font-weight: 650; letter-spacing: -.01em;
  color: #fff;
}
.indice-normas span {
  display: block; margin-top: 6px;
  font-size: 13px; line-height: 1.4;
  color: rgb(255 255 255 / .62);
}

/*
 * Cinco tarjetas, en pirámide: dos arriba, tres abajo (pedido de Fabián para
 * Planes). Se arma sobre una retícula de seis: las dos primeras ocupan tres
 * columnas cada una y las tres siguientes dos, así las dos filas quedan
 * centradas y con los mismos márgenes — una pirámide que se abre hacia abajo.
 */
.indice-normas.en-piramide { grid-template-columns: repeat(6, minmax(0, 1fr)); }
.indice-normas.en-piramide a { grid-column: span 3; }
.indice-normas.en-piramide a:nth-child(n + 3) { grid-column: span 2; }

/*
 * La portada que trae índice necesita piso propio.
 *
 * `.portada` lleva `padding-bottom: 0` porque en el home la base del MacBook
 * ES el borde de la sección. Pero en las páginas cuyo hero termina en las
 * tarjetas del índice, ese cero pegaba las tarjetas contra el corte del plano
 * al blanco y el cambio de fondo se leía como un error, no como un borde.
 */
.portada:has(.indice-normas) { padding-bottom: clamp(44px, 5.5vw, 76px); }

@media (max-width: 860px) {
  .indice-normas,
  .indice-normas.en-piramide { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .indice-normas.en-piramide a { grid-column: auto; }
}
@media (max-width: 520px) {
  .indice-normas,
  .indice-normas.en-piramide { grid-template-columns: minmax(0, 1fr); }
}

.portada .botonera { justify-content: center; margin-top: 32px; }

.portada-nota {
  margin-top: 18px; font-size: 14px; color: var(--gris-2);
}

/*
 * El hero enmarcado en el MacBook.
 *
 * No lleva tarjeta ni sombra propias: el marco ya trae la suya y superponerle
 * otra deja un halo raro alrededor del aluminio. Se deja respirar hacia los
 * lados porque el marco tiene su propio aire y encajarlo al ancho exacto del
 * contenedor lo aprieta.
 */
.vitrina-mac {
  /*
   * De canto a canto, y fuera de `.env`.
   *
   * Está puesto como hijo directo de la sección y no dentro del contenedor
   * centrado: así «ancho completo» es literalmente el ancho de la sección, sin
   * `100vw` de por medio. `100vw` incluye la barra de desplazamiento en varios
   * navegadores y habría metido un desplazamiento horizontal de unos pocos
   * píxeles — el defecto más difícil de ver y el más fácil de introducir.
   */
  /* El aire entre la nota de la portada y el borde de arriba del computador,
     medido con el computador ya en su tamaño de partida. */
  margin-top: clamp(28px, 3.6vw, 56px);

  /*
   * Los últimos 40 px de la imagen quedan fuera de la sección oscura.
   *
   * La base del MacBook tiene las esquinas redondeadas, y en esas dos muescas
   * la imagen es transparente. Con el borde de la sección justo en el canto de
   * la imagen, por ahí se asomaba el azul del fondo: dos cuñas oscuras a los
   * lados de la base, encima del blanco. Se veía como un recorte mal hecho.
   *
   * La medida sale de la propia imagen: hasta la fila 1205 de 1245 la base
   * ocupa el ancho completo, y de ahí abajo empiezan las curvas. Esas cuarenta
   * filas —el 2% del ancho de la imagen— se dejan caer sobre el blanco, así
   * que la sección oscura termina donde la base todavía es una línea recta.
   *
   * En porcentaje y no en píxeles porque los márgenes en porcentaje se
   * resuelven contra el ancho del contenedor: al cambiar el ancho de la
   * ventana, el desborde acompaña solo al tamaño de la imagen.
   */
  margin-bottom: -2%;

  /* Y por encima de la sección siguiente, que si no le pinta su fondo encima
     a esos 40 px. */
  position: relative;
  z-index: 2;

  /* Crece desde su base: la línea donde apoya no se mueve, y lo que cambia es
     cuánto ocupa hacia arriba. */
  transform-origin: 50% 100%;

  /*
   * Los dos parámetros del gesto, como variables y no escritos en el
   * fotograma: el mismo movimiento sirve para el MacBook y para los teléfonos
   * cambiando estos dos números, sin duplicar los `@keyframes`.
   *
   * `--sube` compensa lo que baja el borde superior al achicarse con el eje en
   * la base. En el MacBook vale -20% —el 20% de su alto— para que la tapa
   * arranque justo bajo la nota de la portada. Cuánto vale en teléfono, más
   * abajo.
   */
  --desde: .8;
  --sube: -20%;
}
.vitrina-mac picture { display: block; }
.vitrina-mac img { width: 100%; display: block; }

/*
 * En teléfono el hero cambia de aparato, y con él la geometría.
 *
 * El desborde de -2% existe por las esquinas redondeadas de la base del
 * MacBook, por las que se asomaba el fondo azul. Los teléfonos vienen cortados
 * a ras por abajo —la fotografía ya termina ahí— así que ese desborde les
 * cortaría la punta. Se anula.
 *
 * La proporción se declara acá además de en el `<source>`: no todos los
 * navegadores toman el `width`/`height` de un `source`, y sin proporción el
 * hueco nace con la del MacBook y la página salta cuando llega la imagen.
 */
@media (max-width: 720px) {
  .vitrina-mac { margin-bottom: 0; }
  .vitrina-mac img { aspect-ratio: 1050 / 1115; }

  /*
   * Los teléfonos van pegados al borde, siempre.
   *
   * Con el eje de la transformación en la base, el canto de abajo del elemento
   * no se mueve pase lo que pase con la escala: está clavado en el corte entre
   * la portada azul y el blanco. Lo que lo despegaba era `--sube`, que existe
   * para el MacBook —ahí compensa el hundimiento del borde de arriba— y acá
   * sobra: la fotografía viene cortada a ras por abajo, así que separarla del
   * corte la deja flotando, que es justo lo que no tiene que pasar.
   *
   * En cero, entonces. Y se arranca de 0,86 en vez de 0,8: sin la subida, todo
   * lo que se achica se descuenta del alto, y con 0,8 quedaba un hueco de
   * ochenta píxeles entre la nota de la portada y los teléfonos.
   */
  .vitrina-mac { --sube: 0%; --desde: .86; }
}

/* Las capturas de las secciones interiores van sin marco: ahí lo que importa
   es lo que dice la pantalla, y un bezel repetido en cada bloque cansa. */
.vitrina {
  margin-top: clamp(40px, 5vw, 68px);
  border-radius: var(--radio-l);
  overflow: hidden;
  box-shadow: var(--sombra-3);
  border: 1px solid var(--linea);
  background: var(--papel);
}
.vitrina img { width: 100%; }

.oscuro .vitrina { border-color: rgb(255 255 255 / .12); }

/* --------------------------------------------------------------------------
   El ciclo: un dato entra una vez y recorre todo
   -------------------------------------------------------------------------- */

/*
 * Es una lista ordenada de verdad —los seis pasos van en ese orden y un lector
 * de pantalla tiene que decirlo— pero sin los números del navegador: el número
 * que se ve es el del contador, con su cero delante y en el color de la marca.
 * Con los dos puestos salían «1. 01», «2. 02», que es un error de bulto.
 */
.ciclo {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: 12px;
  counter-reset: paso;
}

.ciclo-paso {
  position: relative;
  padding: 20px 18px;
  border-radius: var(--radio);
  background: var(--papel);
  border: 1px solid var(--linea);
}
.ciclo-paso::before {
  counter-increment: paso;
  content: counter(paso, decimal-leading-zero);
  display: block;
  font-size: 12px; font-weight: 700; letter-spacing: .08em;
  color: var(--azul-vivo);
  margin-bottom: 10px;
  font-variant-numeric: tabular-nums;
}
.ciclo-paso b { display: block; font-size: 15.5px; letter-spacing: -.01em; }
.ciclo-paso span { display: block; margin-top: 4px; font-size: 13.5px; color: var(--gris); }

/*
 * Acá había una rayita conectando cada paso con el siguiente. Se quitó: iba
 * posicionada 12 px fuera de su tarjeta y eso ensanchaba el elemento, que es
 * justo lo que la comprobación de desbordes tiene que atrapar. Un adorno de un
 * píxel de alto no vale hacerle ruido a la única prueba que impide que la
 * página se desplace de lado en un teléfono.
 */

.ciclo-cierre {
  margin-top: 28px;
  font-size: clamp(1.05rem, 1.4vw, 1.2rem);
  color: var(--tinta-2);
}

/* --------------------------------------------------------------------------
   Bloques de producto: texto a un lado, pantalla al otro
   -------------------------------------------------------------------------- */

.bloque {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: clamp(32px, 5vw, 72px);
  align-items: center;
}
/*
 * Al invertir hay que invertir también el reparto de columnas.
 *
 * Sin esto, el bloque invertido dejaba la imagen en la columna de 5 y el texto
 * en la de 7 — al revés que los bloques normales. La consecuencia se veía: la
 * misma captura salía grande en una sección y apretada en la siguiente, sin
 * ninguna razón que el lector pudiera adivinar.
 */
.bloque.invertido { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); }
.bloque.invertido > .bloque-texto { order: 2; }

.bloque + .bloque { margin-top: clamp(64px, 8vw, 112px); }

.bloque-texto h2 { font-size: clamp(1.75rem, 3.2vw, 2.5rem); }
.bloque-texto .bajada { margin-top: 16px; }

.lista { margin: 26px 0 0; padding: 0; list-style: none; display: grid; gap: 16px; }
.lista li { display: grid; grid-template-columns: 20px 1fr; gap: 12px; align-items: start; }
.lista b { display: block; font-size: 16px; letter-spacing: -.01em; }
.lista span { display: block; font-size: 15px; color: var(--gris); margin-top: 2px; }
.oscuro .lista span { color: rgb(255 255 255 / .7); }

.tilde {
  width: 20px; height: 20px; margin-top: 2px; flex: none;
  color: var(--azul-vivo);
}
.oscuro .tilde { color: var(--cian); }

/* Cuando la sección es sobre todo una imagen, su encabezado va centrado: un
   título corto alineado a la izquierda con media pantalla vacía al lado se lee
   como una columna que se quedó sin su pareja. */
.encabezado-centrado {
  max-width: 44rem;
  margin-inline: auto;
  text-align: center;
}
.encabezado-centrado .bajada { margin-inline: auto; }

/* --------------------------------------------------------------------------
   La escena de terreno
   --------------------------------------------------------------------------
   Una fotografía apoyada en la esquina de la sección, con el texto al lado.

   El brazo se corta contra el canto inferior derecho de la sección oscura, no
   contra un rectángulo invisible en medio del aire: ahí termina el encuadre, y
   el corte se lee como que la persona sigue existiendo fuera de la foto. Es la
   diferencia entre una fotografía y una calcomanía.

   Y no se anima. Un maquete que entra volando desmiente lo único que aporta,
   que es parecer una foto de alguien trabajando.
   -------------------------------------------------------------------------- */

.terreno { padding-bottom: 0; }

.escena {
  /* El ancho de la fotografía se declara una vez y de él sale todo lo demás. */
  --mano: min(660px, 48vw);
  /* Alto de la fotografía: 1015 / 1200 del ancho. Escrito así y no a ojo,
     porque de este número depende que no se corte. */
  --mano-alto: calc(var(--mano) * 0.846);

  position: relative;
  margin-top: clamp(48px, 6vw, 96px);
  /*
   * La sección reserva exactamente lo que mide la foto.
   *
   * Antes reservaba menos y recortaba lo que sobraba con `overflow: hidden`,
   * y lo que sobraba era la parte de arriba del teléfono. Un teléfono cortado
   * por una línea recta a media pantalla no se lee como «sigue fuera del
   * encuadre»: se lee como una imagen mal puesta. El único corte que tiene que
   * haber es el del brazo, y ése ya viene en la fotografía.
   */
  min-height: calc(var(--mano-alto) + 40px);
  display: flex;
  align-items: center;
}

.escena-texto {
  /* Poco más de la mitad: lo que queda libre a la izquierda de la mano. */
  max-width: min(46%, 52ch);
}
.escena-texto .rotulo { margin-bottom: 10px; }
.escena-texto h3 {
  font-size: clamp(1.35rem, 2.5vw, 2rem);
  letter-spacing: -.025em; line-height: 1.12;
}
.escena-texto .cuerpo { margin-top: 16px; }

.escena-mano {
  position: absolute;
  right: 0;
  bottom: 0;
  width: var(--mano);
  height: auto;
  pointer-events: none;
  /* Sin `drop-shadow`: la fotografía ya trae su propia luz, y una sombra
     inventada alrededor de un brazo recortado delata el recorte. */
}

@media (max-width: 860px) {
  /* Angosto: la foto pasa a ser el fondo de la que el texto se apoya arriba.
     Partirla en dos columnas con 400 px de ancho no deja leer ninguna de las
     dos cosas. */
  /* Acá sí hay que recortar: la foto se sale un poco por el canto derecho a
     propósito, para que en pantalla angosta siga leyéndose que el brazo
     continúa fuera. En ancho normal no se recorta nada — recortar ahí era lo
     que cortaba el teléfono por arriba. */
  .escena {
    flex-direction: column; align-items: stretch;
    min-height: 0;
    overflow: hidden;
  }
  .escena-texto { max-width: none; }
  .escena-mano {
    position: static;
    width: min(560px, 106%);
    margin: 24px -6% -1px auto;
    display: block;
  }
}

/* --------------------------------------------------------------------------
   Un aparato dentro de un bloque de dos columnas
   --------------------------------------------------------------------------
   El teléfono es alto y estrecho; el hueco donde va es ancho y bajo. Sin
   centrarlo y sin ponerle techo, estira la fila y deja los dos textos de al
   lado flotando en el medio de una columna vacía.
   -------------------------------------------------------------------------- */

.vitrina-aparato {
  display: flex;
  justify-content: center;
  align-items: center;
}
.vitrina-aparato img {
  width: min(268px, 62%);
  height: auto;
  /* La sombra sigue el contorno del marco y no una caja: el aparato trae su
     propio canal alfa. */
  filter: drop-shadow(0 26px 52px rgb(10 20 34 / .22));
}
@media (max-width: 860px) {
  .vitrina-aparato img { width: min(238px, 62vw); }
}

/* Acá había una llave de más, huérfana, sobrante de una regla borrada. El navegador no la ignora: al encontrarla en el nivel superior entra en recuperación de error y se come la regla siguiente — que era `.cifras`, la banda de cifras de la portada. El resultado en pantalla era una rejilla que no era rejilla: las cuatro tarjetas apiladas a lo largo. No lo cazaba ninguna prueba porque el HTML estaba bien; lo que estaba roto era el CSS, y en silencio. */

/* --------------------------------------------------------------------------
   Cifras
   -------------------------------------------------------------------------- */

.cifras { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 20px; }
.cifra { padding: 22px; border-radius: var(--radio); background: rgb(255 255 255 / .06); border: 1px solid rgb(255 255 255 / .1); }
.cifra b {
  display: block; font-size: clamp(1.8rem, 3vw, 2.4rem); font-weight: 700;
  letter-spacing: -.03em; line-height: 1; font-variant-numeric: tabular-nums;
}
.cifra span { display: block; margin-top: 8px; font-size: 14.5px; color: rgb(255 255 255 / .72); }

/* --------------------------------------------------------------------------
   Cumplimiento: el hilo hacia su página
   -------------------------------------------------------------------------- */

.nota-legal {
  display: flex; flex-wrap: wrap; align-items: center;
  justify-content: space-between; gap: 28px;
}
.nota-legal > div { max-width: 44rem; }
.nota-legal h2 { font-size: clamp(1.6rem, 2.8vw, 2.2rem); margin-top: 0; }
.nota-legal .bajada { margin-top: 14px; }
.nota-legal .boton { flex: none; }

/* --------------------------------------------------------------------------
   Fichas de norma (viven en la página de cumplimiento)
   -------------------------------------------------------------------------- */

.normas { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; }

.norma {
  padding: 24px;
  border-radius: var(--radio);
  background: var(--papel);
  border: 1px solid var(--linea);
  border-left: 3px solid var(--azul-vivo);
}
.norma h3 { font-size: 15px; letter-spacing: .02em; text-transform: none; color: var(--azul); }
.norma p { margin-top: 10px; font-size: 15px; color: var(--gris); }
.norma cite { display: block; margin-top: 12px; font-size: 13px; color: var(--gris-2); font-style: normal; }

.aviso-legal {
  margin-top: 20px; padding: 16px 18px;
  border-radius: var(--radio-s);
  background: var(--papel-3);
  font-size: 14px; color: var(--gris);
}

/* --------------------------------------------------------------------------
   Cierre
   -------------------------------------------------------------------------- */

/*
 * El cierre necesita aire por arriba.
 *
 * `.seccion + .seccion` quita el padding superior para que dos bloques claros
 * seguidos no dejen el doble de espacio entre sí. Pero el cierre viene después
 * de una sección oscura, y ahí la regla juega en contra: el titular quedaba
 * pegado al borde del bloque anterior, como si fuera parte de él. Un remate
 * necesita separarse de lo que remata.
 */
.seccion.cierre { padding-top: clamp(96px, 12vw, 176px); }

.cierre { text-align: center; }
.cierre h2 { max-width: 18ch; margin-inline: auto; }
.cierre .bajada { margin: 20px auto 0; }
.cierre .botonera { justify-content: center; margin-top: 32px; }

.pie {
  padding-block: 56px 40px;
  border-top: 1px solid var(--linea);
  font-size: 14px; color: var(--gris);
}
.pie-cols { display: grid; grid-template-columns: 1.4fr repeat(3, 1fr); gap: 32px; }
.pie h4 { margin: 0 0 12px; font-size: 13px; font-weight: 700; color: var(--tinta); letter-spacing: .02em; }
.pie ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.pie a { text-decoration: none; color: var(--gris); }
.pie a:hover { color: var(--tinta); text-decoration: underline; }
.pie-fin { margin-top: 40px; padding-top: 24px; border-top: 1px solid var(--linea-tenue); font-size: 13px; color: var(--gris-2); }
.pie-marca img { height: 22px; margin-bottom: 12px; }
.pie-redes { margin-top: 40px; padding-top: 24px; border-top: 1px solid var(--linea-tenue); display: flex; flex-wrap: wrap; gap: 8px 20px; font-size: 13px; }
.pie-redes a { color: var(--gris); text-decoration: none; }
.pie-redes a:hover { color: var(--tinta); text-decoration: underline; }
.pie-redes + .pie-fin { margin-top: 16px; padding-top: 0; border-top: 0; }

/* --------------------------------------------------------------------------
   Revelado al entrar
   --------------------------------------------------------------------------
   Sutil y una sola vez. 14 px de recorrido y 460 ms: lo justo para que la
   página se sienta viva sin que haya que esperarla. Y sobre todo: esto se
   aplica SÓLO si el JavaScript está vivo (la clase la pone él), así que sin JS
   todo se ve, que es lo que antes no pasaba.
   -------------------------------------------------------------------------- */

/*
 * El bloque entra subiendo, creciendo un poco y enfocándose.
 *
 * Antes eran 14 px de recorrido y sólo opacidad: correcto, y prácticamente
 * invisible. Un sitio de producto tiene que sentirse vivo al recorrerlo, así
 * que acá el gesto es más amplio —28 px, escala desde 0,975 y un desenfoque de
 * 8 px que se resuelve— y dura 720 ms, que en una página de marketing está
 * permitido: no hay nadie esperando para hacer clic.
 *
 * El desenfoque es lo que hace la diferencia. Sin él, mover y aparecer se leen
 * como dos objetos superpuestos; con él, se lee como una sola cosa que entra en
 * foco. Es el mismo truco que se usa para tapar una transición imperfecta,
 * aplicado a propósito.
 */
.js .revela {
  opacity: 0;
  transform: translateY(28px) scale(.975);
  filter: blur(8px);
  transition:
    opacity 720ms var(--sale),
    transform 720ms var(--sale),
    filter 720ms var(--sale);
  will-change: transform, opacity;
}
.js .revela[data-visible='si'] {
  opacity: 1;
  transform: none;
  filter: none;
}
/* Terminada la entrada, se suelta la promesa de composición: mantenerla viva
   en cuarenta elementos consume memoria de vídeo sin ninguna ganancia. */
.js .revela[data-visible='si'] { will-change: auto; }

/*
 * El revelado amarrado al scroll, donde el navegador sabe hacerlo.
 *
 * La entrada de arriba es de un solo disparo: el observador la enciende y ahí
 * queda. Esto la reemplaza —sólo en navegadores con `animation-timeline`— por
 * la versión que hace Apple en sus páginas de producto: el avance de la
 * entrada es EL SCROLL, no un reloj. Subir la devuelve, bajar la trae, y a la
 * velocidad de la mano de quien mira. No es la animación repetida que la nota
 * del observador rechaza —eso era un reloj que vuelve a sonar—: es un valor
 * continuo pegado al desplazamiento, como la sombra pegada a un objeto.
 *
 * Dos diferencias deliberadas con la entrada de un disparo:
 * - **Sin desenfoque.** El blur de la entrada única se paga una vez; scrubeado
 *   se pagaría en cada cuadro del scroll, sobre decenas de elementos. Sólo
 *   opacidad y transform, que van por el compositor.
 * - **El tramo es corto** (del 5% al 55% de la entrada): el elemento está
 *   resuelto antes de llegar al centro de la pantalla, que es donde el ojo lo
 *   espera terminado.
 *
 * En Safari y Firefox sin soporte no cambia nada: sigue la entrada de un
 * disparo, que ya estaba bien. Y quien pide menos movimiento apaga también
 * esto, más abajo, con `animation: none`.
 */
@supports (animation-timeline: view()) {
  .js .revela,
  .js .revela[data-visible='si'] {
    opacity: 1;
    transform: none;
    filter: none;
    transition: none;
    will-change: auto;
    animation: revela-con-el-scroll linear both;
    animation-timeline: view();
    animation-range: entry 60px entry 340px;
  }
  @keyframes revela-con-el-scroll {
    from { opacity: 0; transform: translateY(30px) scale(.975); }
    to { opacity: 1; transform: none; }
  }
}

/*
 * Los tildes de las listas se marcan, uno tras otro.
 *
 * Es el gesto de alguien revisando un checklist con lápiz, que es exactamente
 * lo que la lista dice que la plataforma hace. El trazo del tilde mide ~18
 * unidades; el desfase entre hermanos hace que se marquen en orden y no como
 * un timbre de goma. Sigue colgado de `data-visible` —un solo disparo— a
 * propósito: un checklist que se des-marca al subir el scroll diría lo
 * contrario de lo que tiene que decir.
 */
.js .revela .tilde path {
  stroke-dasharray: 20;
  stroke-dashoffset: 20;
  transition: stroke-dashoffset 340ms var(--sale);
}
.js .revela[data-visible='si'] .tilde path { stroke-dashoffset: 0; }
.js .revela li:nth-child(1) .tilde path { transition-delay: 120ms; }
.js .revela li:nth-child(2) .tilde path { transition-delay: 210ms; }
.js .revela li:nth-child(3) .tilde path { transition-delay: 300ms; }
.js .revela li:nth-child(4) .tilde path { transition-delay: 390ms; }
.js .revela li:nth-child(5) .tilde path { transition-delay: 480ms; }
.js .revela li:nth-child(6) .tilde path { transition-delay: 570ms; }
.js .revela li:nth-child(7) .tilde path { transition-delay: 660ms; }
.js .revela li:nth-child(8) .tilde path { transition-delay: 750ms; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  /* `animation: none` y no sólo la duración: una animación amarrada al scroll
     ignora su duración, así que acortarla no la apaga. */
  .js .revela { opacity: 1; transform: none; transition: none; animation: none !important; }
  .js .revela .tilde path { stroke-dashoffset: 0; transition: none; }
  * { animation-duration: .001ms !important; transition-duration: .001ms !important; }
}

/*
 * Quien pidió menos transparencia no debería recibir una barra translúcida.
 *
 * Pero «sólida» sólo tiene sentido cuando hay algo debajo de lo que separarse.
 * Arriba del todo la barra flota sobre la portada oscura y el logotipo que
 * lleva es el blanco: pintarla blanca ahí dejaba el logotipo blanco sobre
 * fondo blanco —invisible— y metía una franja clara que partía la portada en
 * dos. Se vio en producción, en un equipo con «reducir transparencia» puesto.
 *
 * Lo correcto es no pintarla mientras no se ha desplazado nada: sin fondo no
 * hay transparencia que reducir, y el contraste del texto blanco contra la
 * portada oscura es mejor que el de cualquier vidrio.
 */
@media (prefers-reduced-transparency: reduce) {
  .barra { backdrop-filter: none; -webkit-backdrop-filter: none; }
  .barra[data-desplazada='si'] { background: #fff; }
  .barra[data-desplazada='no'] { background: transparent; }
}

@media (prefers-contrast: more) {
  :root { --gris: #3d4a60; --gris-2: #4a5670; --linea: #c2c9d6; }
  .barra { backdrop-filter: none; -webkit-backdrop-filter: none; }
  .barra[data-desplazada='si'] { background: #fff; border-bottom-color: rgb(10 14 20 / .22); }
  .barra[data-desplazada='no'] { background: transparent; }
}

/* --------------------------------------------------------------------------
   Anchos
   -------------------------------------------------------------------------- */

@media (max-width: 1040px) {
  .ciclo { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .ciclo-paso:nth-child(3)::after { display: none; }
  .cifras { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 860px) {
  .barra-menu { display: none; }
  .barra-cta { display: none; }
  .abrir-menu { display: inline-flex; }

  /*
   * Una columna, y el invertido nombrado explícitamente.
   *
   * Acá había `.bloque { … 1fr }` a secas, y no bastaba: `.bloque.invertido`
   * son dos clases contra una, así que ganaba y se quedaba con sus dos
   * columnas **también en teléfono**. El resultado en pantalla era grotesco —
   * el texto en media pantalla partiéndose en tres palabras por línea y la
   * captura reducida a una estampilla al lado— y no lo cazaba ninguna prueba,
   * porque dos columnas apretadas no desbordan la página ni el texto: caben,
   * sólo que ilegibles.
   *
   * Una consulta de medios NO sube la especificidad. Es el error de bulto más
   * fácil de cometer en CSS adaptable y el más difícil de ver en escritorio.
   */
  .bloque,
  .bloque.invertido { grid-template-columns: minmax(0, 1fr); gap: 32px; }
  .bloque.invertido > .bloque-texto { order: 0; }

  .normas { grid-template-columns: minmax(0, 1fr); }
  .pie-cols { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 28px; }
}

@media (max-width: 620px) {
  body { font-size: 16px; }
  /* El MacBook ya sale de canto a canto por sí solo —está fuera de `.env`— y
     el margen negativo que traía de cuando vivía dentro sobraba: lo empujaba
     12 px fuera de la ventana y metía un desplazamiento horizontal. */
  .ciclo { grid-template-columns: minmax(0, 1fr); }
  .ciclo-paso::after { display: none !important; }
  .cifras { grid-template-columns: minmax(0, 1fr); }
  .portada .botonera .boton { width: 100%; }
}

/* --------------------------------------------------------------------------
   Menú desplegable en teléfono
   -------------------------------------------------------------------------- */

.menu-movil {
  position: fixed; inset: var(--barra) 0 0; z-index: 49;
  background: rgb(255 255 255 / .96);
  backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px);
  padding: 24px var(--canto);
  display: none;
  overflow-y: auto;
}
.menu-movil[data-abierto='si'] { display: block; }
.menu-movil ul { list-style: none; margin: 0 0 24px; padding: 0; display: grid; gap: 2px; }
.menu-movil a {
  display: block; padding: 14px 4px; font-size: 19px; font-weight: 600;
  text-decoration: none; letter-spacing: -.01em;
  border-bottom: 1px solid var(--linea-tenue);
}
.menu-movil .boton { width: 100%; }

/* Impresión: sin barra, sin animación, todo visible. */
@media print {
  .barra, .menu-movil, .botonera { display: none !important; }
  .js .revela { opacity: 1 !important; transform: none !important; }
  .oscuro { background: #fff !important; color: #000 !important; }
}

/* ==========================================================================
   MOVIMIENTO
   --------------------------------------------------------------------------
   Esta página es lo contrario de una herramienta: se ve una vez, o dos. Ahí es
   donde vive el presupuesto de animación —el tramo «raro / primera vez»— y por
   eso acá sí se anima lo que en el producto jamás se animaría.

   Aun así la regla que ordena todo es la misma: cada movimiento tiene que poder
   decir para qué está. Los cuatro propósitos que se usan acá son EXPLICAR (el
   croquis que se dibuja, el gráfico que sube de tramo, la cifra que cuenta),
   EVITAR UN CAMBIO BRUSCO (las rejillas que entran escalonadas en vez de
   aparecer de golpe), DAR RESPUESTA (el botón que se hunde al presionarlo) y
   AGRADAR, que sólo se permite acá porque nadie mira esta página cien veces al
   día.

   Todo va en `transform` y `opacity` —las dos propiedades que se resuelven en
   la GPU sin rehacer el diseño de la página— y todo cae a nada bajo
   `prefers-reduced-motion`.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Entrada de la portada
   --------------------------------------------------------------------------
   La única animación que ocurre al cargar. No espera al scroll: es lo primero
   que se ve y tiene que estar terminada antes de que el ojo termine de
   recorrerla. 70 ms de desfase entre piezas — lo justo para que se lea como una
   secuencia y no como seis cosas cayendo juntas.
   -------------------------------------------------------------------------- */

@keyframes entra {
  from { opacity: 0; transform: translateY(34px); filter: blur(7px); }
  to   { opacity: 1; transform: none; filter: blur(0); }
}

/*
 * El titular se levanta detrás de su propia línea de base.
 *
 * `clip-path` recorta por abajo y va soltando: el texto no aparece, sube desde
 * debajo de un borde que no se ve. Es el gesto de portada de Apple y de Sketch,
 * y es lo que faltaba — subir y aparecer, sin más, se leía como una transición
 * de plantilla.
 *
 * Se recorta con holgura a los lados y por arriba (-14%) para no comerse ni
 * las colas de las jotas ni el desenfoque mientras dura.
 */
@keyframes entra-titulo {
  from {
    opacity: 0;
    transform: translateY(52px) scale(.965);
    clip-path: inset(-14% -8% 100% -8%);
  }
  to {
    opacity: 1;
    transform: none;
    clip-path: inset(-14% -8% -14% -8%);
  }
}

/* Sólo si el JavaScript está vivo: sin él la portada se ve entera y quieta. */
.js .portada .env > * {
  animation: entra 760ms var(--sale) both;
}
.js .portada h1 {
  animation: entra-titulo 980ms var(--sale) both;
  animation-delay: 40ms;
}
.js .portada .bajada { animation-delay: 260ms; }
.js .portada .botonera { animation-delay: 380ms; }
.js .portada .portada-nota { animation-delay: 470ms; }

/*
 * El MacBook entra distinto: además de subir, crece desde 0,97.
 *
 * Nunca desde cero. Nada en el mundo real aparece de la nada, y un objeto que
 * nace sin tamaño se lee como un truco. Desde 0,97 se lee como algo que se
 * acerca.
 */
/*
 * El MacBook se acerca: entra a un 80% y crece hasta ocupar el ancho completo.
 *
 * Un solo gesto, grande y legible, con el eje de la transformación en la base:
 * la línea donde el equipo apoya —que es también donde termina la sección
 * oscura— no se mueve ni un píxel, y lo único que cambia es cuánto ocupa hacia
 * arriba. Es la diferencia entre algo que se acerca y algo que se infla.
 *
 * Nunca desde cero. Nada en el mundo real aparece de la nada, y un objeto que
 * nace sin tamaño se lee como un truco. 0,8 es bastante y sigue siendo un
 * objeto.
 */
@keyframes entra-aparato {
  from { opacity: 0; transform: translateY(var(--sube)) scale(var(--desde)); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
/*
 * De reserva: si el navegador no sabe atar una animación al desplazamiento,
 * el MacBook entra igual, con tiempo. Es lo que hacía hasta ahora y funciona;
 * simplemente no responde a la rueda.
 */
.js .portada .vitrina-mac {
  animation: entra-aparato 1300ms var(--sale) both;
  animation-delay: 520ms;
}

/*
 * Lo bueno: crece con el desplazamiento, no con un cronómetro.
 *
 * La diferencia no es de forma sino de quién manda. Una animación temporizada
 * ocurre igual estés mirando o no; ésta la hace la persona, y por eso el
 * tamaño del equipo queda pegado a su gesto: rueda arriba y se achica, rueda
 * abajo y crece. Es la misma idea de la barra que se materializa al bajar.
 *
 * `scroll(root block)` y no `view()`: así el punto de partida es siempre el
 * 80% con la página arriba del todo, sin depender del alto de la ventana. Y
 * `linear`, obligatorio — la curva de aceleración acá la pone la mano.
 */
@supports (animation-timeline: scroll()) {
  @media (prefers-reduced-motion: no-preference) {
    /*
     * El 20% de subida no es decoración: es la compensación exacta.
     *
     * El eje de la transformación está en la base, así que al achicar a 0,8 la
     * base se queda quieta y el borde de arriba baja un 20% del alto — o sea,
     * el computador arrancaba hundido, con un vacío enorme entre la nota de la
     * portada y la tapa. Subiéndolo ese mismo 20%, el borde de arriba queda
     * clavado donde tiene que estar desde el primer píxel, y lo que crece es
     * hacia abajo, hasta que la base aterriza justo en el corte de la sección.
     */
    @keyframes crecer-mac {
      from { transform: translateY(var(--sube)) scale(var(--desde)); }
      to   { transform: translateY(0) scale(1); }
    }

    .js .portada .vitrina-mac {
      animation: crecer-mac linear both;
      animation-timeline: scroll(root block);
      animation-range: 0 75vh;
      animation-delay: 0s;
    }
  }
}

/* Las marcas de plano entran las últimas y muy lento: son el fondo, no el
   mensaje, y llegar antes que el titular sería competir con él. */
@keyframes entra-marca {
  from { opacity: 0; transform: translateX(-14px); }
  to   { opacity: 1; transform: none; }
}
.js .marca { animation: entra-marca 1400ms var(--sale) both; }
.js .marca-1 { animation-delay: 760ms; }
/* La del canto derecho entra desde su lado, no desde el contrario. */
.js .marca-2 { animation-name: entra-marca-der; }
@keyframes entra-marca-der {
  from { opacity: 0; transform: translateX(14px); }
  to   { opacity: 1; transform: none; }
}
.js .marca-2 { animation-delay: 940ms; }
.js .marca-3 { animation-delay: 1120ms; }

/* --------------------------------------------------------------------------
   Escritura a mano
   --------------------------------------------------------------------------
   La entradilla de la portada no aparece: se escribe, letra a letra y con el
   pulso irregular de una mano. Es la única animación de la página que cambia
   de registro — todo lo demás se desliza o crece, cosas de interfaz; esto se
   parece a alguien anotando una frase.

   El desnivel del trazo NO es movimiento: es cómo se ve una letra escrita a
   mano, y por eso sobrevive a `prefers-reduced-motion`. Lo que se apaga ahí es
   la aparición letra a letra, no la inclinación.
   -------------------------------------------------------------------------- */

/*
 * La entradilla que se escribe va en la manuscrita, y no es un adorno aparte:
 * es la mitad del mismo gesto.
 *
 * La animación letra a letra con desnivel de trazo, puesta sobre la tipografía
 * del sistema, no se lee como alguien escribiendo — se lee como un párrafo
 * roto, con las letras bailando sin motivo. La letra manuscrita es lo que le
 * da sentido al pulso irregular. Van juntas o no van.
 *
 * Suavizado de fábrica: el `antialiased` global adelgaza el trazo, y en una
 * letra fina eso se nota sobre todo en blanco sobre el plano azul.
 */
[data-escribe] {
  font-family: var(--manuscrita);
  font-weight: 400;
  font-style: normal;
  letter-spacing: 0;
  line-height: 1.4;
  -webkit-font-smoothing: auto;
  -moz-osx-font-smoothing: auto;
}

.portada [data-escribe] {
  /* Más grande que la entradilla normal: esta letra es fina y de caja pequeña,
     y al cuerpo del texto corriente se lee desvaída sobre el plano azul. */
  font-size: clamp(1.4rem, 2.5vw, 1.85rem);
  /* En caracteres, no en píxeles: al cambiar de tipografía cambia el ancho del
     carácter, y lo que hay que mantener constante es cuántos caben por línea. */
  max-width: 46ch;
  margin-inline: auto;
  color: rgb(255 255 255 / .93);
}

.mano__palabra {
  display: inline-block;
  transform: translateY(var(--altoP, 0px)) rotate(var(--giroP, 0deg));
}

.mano__letra {
  display: inline-block;
  opacity: 0;
  margin-left: var(--corr, 0px);
  transform: translateY(var(--alto, 0px)) rotate(var(--giro, 0deg));
}

/* El bloque deja de aparecer como bloque en cuanto se parte en letras: dejar
   las dos cosas encima hacía que el párrafo se desvaneciera mientras se estaba
   escribiendo. */
.js .portada .env > .bajada.mano {
  animation: none;
  opacity: 1;
  transform: none;
  filter: none;
}

/* La espera de cada letra la calcula el guion: el ritmo es irregular y hay una
   pausa más larga al empezar cada palabra, que es el lápiz levantándose. Los
   300 ms de entrada son para que la tinta se pose, no para que aparezca. */
.js .mano .mano__letra {
  animation: escribir 300ms var(--sale) forwards;
  animation-delay: var(--espera, 0ms);
}

@keyframes escribir {
  from {
    opacity: 0;
    transform: translateY(calc(var(--alto, 0px) + 2.5px)) rotate(var(--giro, 0deg));
  }
  to {
    opacity: 1;
    transform: translateY(var(--alto, 0px)) rotate(var(--giro, 0deg));
  }
}

@media (prefers-reduced-motion: reduce) {
  .mano__letra { opacity: 1; }
  .js .mano .mano__letra { animation: none; }
}

/* --------------------------------------------------------------------------
   Entradas escalonadas
   --------------------------------------------------------------------------
   Una rejilla de seis tarjetas que aparece de golpe se percibe como un
   parpadeo. Escalonada, se lee como una lista que se va poniendo. 55 ms: por
   debajo se pierde el efecto, por encima el último elemento se hace esperar.
   -------------------------------------------------------------------------- */

.js .escalonado > * {
  opacity: 0;
  transform: translateY(22px) scale(.985);
  filter: blur(5px);
  transition:
    opacity 640ms var(--sale),
    transform 640ms var(--sale),
    filter 640ms var(--sale);
}
.js .escalonado[data-visible='si'] > * { filter: none; }
.js .escalonado[data-visible='si'] > * { opacity: 1; transform: none; }
.js .escalonado[data-visible='si'] > *:nth-child(1) { transition-delay: 0ms; }
.js .escalonado[data-visible='si'] > *:nth-child(2) { transition-delay: 80ms; }
.js .escalonado[data-visible='si'] > *:nth-child(3) { transition-delay: 160ms; }
.js .escalonado[data-visible='si'] > *:nth-child(4) { transition-delay: 240ms; }
.js .escalonado[data-visible='si'] > *:nth-child(5) { transition-delay: 320ms; }
.js .escalonado[data-visible='si'] > *:nth-child(6) { transition-delay: 400ms; }

/* --------------------------------------------------------------------------
   Las capturas responden al cursor
   --------------------------------------------------------------------------
   Dos píxeles y nada más. Es una superficie que se mira decenas de veces
   mientras se recorre la página, y en ese tramo de frecuencia el movimiento
   tiene que ser casi imperceptible: sólo lo suficiente para que se lea como una
   pantalla de verdad y no como una lámina pegada.

   Va detrás de `hover: hover` y `pointer: fine` porque en una pantalla táctil
   el «hover» se queda pegado después de tocar, y entonces la tarjeta se levanta
   y no vuelve a bajar.
   -------------------------------------------------------------------------- */

@media (hover: hover) and (pointer: fine) {
  .vitrina {
    transition: transform 260ms var(--sale), box-shadow 260ms var(--sale);
  }
  .vitrina:hover {
    transform: translateY(-2px);
    box-shadow: 0 6px 14px rgb(10 14 20 / .07), 0 50px 90px rgb(10 14 20 / .18);
  }
}

/* --------------------------------------------------------------------------
   Dibujos que se trazan solos
   --------------------------------------------------------------------------
   `stroke-dasharray` puesta al largo de la línea y `stroke-dashoffset` bajando
   a cero: el trazo aparece como si alguien lo estuviera dibujando. Es la única
   animación de la página que EXPLICA algo — un levantamiento es exactamente
   eso, alguien que va y dibuja el recinto— y por eso se le permite durar más
   que los 300 ms de la interfaz.
   -------------------------------------------------------------------------- */

.js .traza [data-traza] {
  stroke-dasharray: var(--largo, 1200);
  stroke-dashoffset: var(--largo, 1200);
  transition: stroke-dashoffset 1100ms var(--sale);
}
.js .traza[data-visible='si'] [data-traza] { stroke-dashoffset: 0; }

/*
 * Las cuatro ramas del ciclo, corregidas: menos cola y otra curva.
 *
 * Con 140 ms entre ramas y `--sale` —que arranca disparado y frena al final—
 * las cuatro líneas salían como cuatro latigazos escalonados y el conjunto se
 * leía nervioso, que es exactamente lo contrario del argumento: un dato que
 * fluye tranquilo hacia cuatro documentos.
 *
 * Acá el desfase baja a 55 ms —lo justo para que se note una dirección, no
 * para que se cuenten cuatro golpes— y la curva es simétrica: arranca suave,
 * mantiene velocidad en el medio y se detiene suave. Es cómo se mueve algo que
 * recorre un camino, en vez de algo a lo que le dieron un empujón.
 */
.js .traza .ramas [data-traza] {
  transition: stroke-dashoffset 900ms cubic-bezier(.5, .05, .25, 1);
}
.js .traza .ramas [data-traza]:nth-child(1) { transition-delay: 0ms; }
.js .traza .ramas [data-traza]:nth-child(2) { transition-delay: 55ms; }
.js .traza .ramas [data-traza]:nth-child(3) { transition-delay: 110ms; }
.js .traza .ramas [data-traza]:nth-child(4) { transition-delay: 165ms; }

/*
 * Lo que no es línea —rótulos, rellenos, la cota con su número— no se traza:
 * aparece después, cuando el dibujo ya está.
 *
 * Ojo con una trampa que costó una revisión: el elemento que lleva `.traza`
 * tiene que llevar TAMBIÉN `.revela`, porque `data-visible` lo pone el
 * observador sobre los elementos que observa. Si `.revela` está en un ancestro,
 * el dibujo se queda con el trazo en cero para siempre — es decir, invisible.
 */
.js .traza [data-tras] {
  opacity: 0;
  transition: opacity 520ms ease;
  transition-delay: 760ms;
}
.js .traza[data-visible='si'] [data-tras] { opacity: 1; }

/*
 * El croquis acotado: la lámina que se mide sola, cota por cota.
 *
 * Antes todo el rotulado aparecía junto a los 760 ms y el dibujo se leía como
 * una diapositiva que se enciende. Acá cada pieza lleva su turno en `--paso`
 * —el orden en que acotaría alguien con la huincha: recinto, medidas, muro,
 * cuello de botella, equipo— y la coreografía completa es esta regla, no
 * veinte retardos escritos a mano. Cambiar el ritmo es cambiar UN número.
 *
 * El paso son 300 ms: suficiente para que el ojo siga la secuencia, no tanto
 * como para que parezca una presentación. El rotulado de cada paso llega
 * 420 ms después de su trazo, cuando la línea ya casi terminó de dibujarse.
 * La reducción de movimiento de más abajo lo apaga todo igual que siempre:
 * ahí el croquis aparece entero y quieto, que es lo pedido.
 */
.js .traza.acotado [data-traza] {
  transition-duration: 800ms;
  transition-delay: calc(var(--paso, 0) * 300ms);
}
.js .traza.acotado [data-tras] {
  transition-duration: 420ms;
  transition-delay: calc(var(--paso, 0) * 300ms + 420ms);
}

/* --------------------------------------------------------------------------
   Cifras que cuentan
   --------------------------------------------------------------------------
   Sólo donde el número ES el argumento: 6,80%, 24 meses, 48 copias. Contar
   obliga a leerlo, que es justo lo que se quiere de una cifra que se puso ahí
   para que impresione. En una tabla de datos sería insoportable; acá hay una
   por bloque.

   `tabular-nums` es obligatorio: sin ancho fijo por dígito el número tiembla
   mientras cuenta y el efecto se vuelve un defecto.
   -------------------------------------------------------------------------- */

[data-cuenta] { font-variant-numeric: tabular-nums; }


/* --------------------------------------------------------------------------
   La lista de tarifas de los módulos sueltos (planes.html)
   --------------------------------------------------------------------------
   Nombre a la izquierda, precio a la derecha y una línea punteada entre
   medio, como una especificación de plano: es la estética del sitio aplicada
   a una lista de precios. `tabular-nums` para que la columna de montos quede
   alineada dígito a dígito y se pueda comparar de un vistazo.
   -------------------------------------------------------------------------- */
.tarifas {
  list-style: none;
  margin: clamp(26px, 4vw, 40px) auto 0;
  padding: 0;
  max-width: 880px;
  display: grid;
  grid-template-columns: 1fr 1fr;
  column-gap: clamp(28px, 5vw, 64px);
  row-gap: 10px;
}
.tarifas li {
  display: flex;
  align-items: baseline;
  gap: 10px;
  font-size: 15px;
  color: var(--tinta);
}
.tarifas li::after {
  content: '';
  order: 2;
  flex: 1;
  border-bottom: 1px dotted var(--linea);
  transform: translateY(-3px);
}
.tarifas li span { order: 1; }
.tarifas li b {
  order: 3;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
@media (max-width: 720px) {
  .tarifas { grid-template-columns: 1fr; }
}

.tarifas-remate {
  margin: clamp(30px, 4vw, 44px) auto 0;
  max-width: 640px;
  text-align: center;
  border: 1px solid var(--linea);
  border-radius: 16px;
  padding: clamp(22px, 3.5vw, 34px);
  background: var(--papel, #fff);
}
.tarifas-remate p { margin: 0 0 18px; font-size: 16px; line-height: 1.55; color: var(--gris); }
.tarifas-remate p b { color: var(--tinta); font-variant-numeric: tabular-nums; }

/* --------------------------------------------------------------------------
   Reducción de movimiento
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  .js .portada .env > *,
  .js .portada .vitrina-mac,
  .js .marca { animation: none !important; opacity: 1 !important; transform: none !important; }
  .js .escalonado > * { opacity: 1 !important; transform: none !important; transition: none !important; }
  .js .traza [data-traza] { stroke-dashoffset: 0 !important; transition: none !important; }
  .js .traza [data-tras] { opacity: 1 !important; transform: none !important; transition: none !important; }
  .vitrina:hover { transform: none; }
}

/* ==========================================================================
   ILUSTRACIONES
   --------------------------------------------------------------------------
   Vienen de la versión anterior y se conservan porque funcionaban: son dibujos
   que explican en un vistazo algo que en texto necesita un párrafo. Lo que
   cambia es el encuadre — antes flotaban sobre el fondo de la sección, ahora
   van dentro de una lámina con su propia retícula, que es lo que las convierte
   en «plano» y no en «gráfico».
   ========================================================================== */

.lamina {
  position: relative;
  border-radius: var(--radio-l);
  padding: clamp(20px, 3vw, 36px);
  background:
    radial-gradient(120% 100% at 20% 0%, #0d4b78 0%, transparent 62%),
    var(--azul-hondo);
  overflow: hidden;
  box-shadow: var(--sombra-3);
  color: #fff;
}
.lamina::before {
  content: '';
  position: absolute; inset: 0; pointer-events: none;
  background-image:
    linear-gradient(rgb(255 255 255 / .045) 1px, transparent 1px),
    linear-gradient(90deg, rgb(255 255 255 / .045) 1px, transparent 1px);
  background-size: 34px 34px;
}
.lamina > * { position: relative; }
.lamina svg { width: 100%; height: auto; display: block; }

/* La ficha de resultado que va bajo el dibujo: el dato que el dibujo dejó a la
   vista, dicho con todas sus letras. */
.hallazgo {
  margin-top: clamp(16px, 2.5vw, 28px);
  padding: 18px 22px;
  border-radius: var(--radio);
  background: rgb(255 255 255 / .07);
  border: 1px solid rgb(255 255 255 / .12);
}
/*
 * El titular del hallazgo bajó y el cuerpo subió.
 *
 * Estaban en 2,3 rem contra 15 px: un salto de más de dos veces y media dentro
 * de una misma tarjeta, con el resultado de que el titular gritaba y la frase
 * que de verdad explica el argumento se leía como un pie de foto.
 */
.hallazgo b {
  display: block;
  font-size: clamp(1.45rem, 2.3vw, 1.85rem);
  font-weight: 700; letter-spacing: -.03em; line-height: 1.05;
}
.hallazgo span {
  display: block; margin-top: 10px; max-width: 70ch;
  font-size: clamp(15px, 1.15vw, 17px); line-height: 1.55; color: rgb(255 255 255 / .78);
}

/* Tipografía dentro de los dibujos. Va acá y no en el SVG para que herede el
   ajuste de tamaño del sistema y no quede fija en píxeles. */
.lamina text { font-family: inherit; }
.rotulo-plano { font-size: 13px; fill: rgb(255 255 255 / .72); }
.cota-plano   { font-size: 13px; fill: rgb(255 255 255 / .8); }
.destacado    { font-size: 13px; font-weight: 700; fill: #f2c94c; }
.pieza        { font-size: 13px; fill: rgb(255 255 255 / .9); }

/* --------------------------------------------------------------------------
   El ciclo del dato, ramificado
   --------------------------------------------------------------------------
   Reemplaza a la tira de seis pasos numerados. La tira contaba una secuencia y
   el argumento no es una secuencia: es que UN dato se escribe una vez y aparece
   en cuatro documentos a la vez. Eso es una ramificación, no una fila.
   -------------------------------------------------------------------------- */

.ramas .origen  { fill: rgb(242 201 76 / .14); stroke: #f2c94c; }
.ramas .destino { fill: rgb(255 255 255 / .06); stroke: rgb(255 255 255 / .3); }
.ramas .hilo    { stroke: rgb(120 190 235 / .62); }

/*
 * Los tamaños, corregidos.
 *
 * Estaban en 15 y 12,5 px sobre un lienzo que ocupa el ancho entero de la
 * lámina —hasta 1100 px en escritorio— así que se leían como una nota al pie
 * dentro de un dibujo grande. Acá el rótulo del destino va a 21 px, que es el
 * tamaño de un texto normal a esa escala, y el secundario a 15,5.
 */
.ramas .origen-t  { fill: #f2c94c; font-weight: 700; font-size: 25px; }
.ramas .origen-s  { fill: rgb(255 255 255 / .74); font-size: 15.5px; }
.ramas .destino-t { fill: #fff; font-size: 21px; font-weight: 600; }
.ramas .destino-s { fill: rgb(255 255 255 / .55); font-size: 15.5px; }

/*
 * Cada destino entra por su cuenta y detrás de su propia línea.
 *
 * La línea se traza de izquierda a derecha; la caja tiene que llegar después,
 * no antes, y desplazada un poco hacia la izquierda para que se lea que viene
 * por el hilo y no que se enciende en su sitio. `--i` ordena la cola: el origen
 * primero y los cuatro destinos detrás, de arriba abajo.
 */
/*
 * Las cajas, más juntas y con menos recorrido.
 *
 * 16 px de desplazamiento y 150 ms entre una y otra hacían que las cinco
 * cajas se sintieran como cinco eventos distintos. Con 8 px y 80 ms se leen
 * como un solo gesto que va apareciendo, y el conjunto entero —líneas y
 * cajas— cabe en poco más de un segundo y medio.
 */
.js .traza .ramas [data-tras] {
  transform: translateX(-8px);
  transition: opacity 540ms ease, transform 640ms cubic-bezier(.33, .8, .33, 1);
  transition-delay: calc(380ms + var(--i, 0) * 80ms);
}
.js .traza[data-visible='si'] .ramas [data-tras] { transform: none; }

/* --------------------------------------------------------------------------
   El gráfico del DS 67
   --------------------------------------------------------------------------
   Un escalón, y nada más. El argumento entero de esa norma es que un accidente
   te sube de tramo y ese tramo se paga durante veinticuatro meses sobre toda la
   planilla: eso es literalmente un escalón que sube y se queda arriba. Cualquier
   gráfico más elaborado contaría menos.
   -------------------------------------------------------------------------- */

.escalon .base   { stroke: rgb(255 255 255 / .55); }
.escalon .salto  { stroke: #f2c94c; }
.escalon .bulto  { fill: #f2c94c; }
.escalon .caja   { fill: rgb(255 255 255 / .05); }
.escalon .marca-t { fill: #f2c94c; font-size: 13.5px; font-weight: 700; }

/* --------------------------------------------------------------------------
   El acta firmada
   --------------------------------------------------------------------------
   Tres hojas apiladas y la de arriba con su firma y su fecha. La pila importa:
   un acta no es un documento suelto, es el último de una serie, y lo que se
   discute meses después es cuál de todas era la vigente.
   -------------------------------------------------------------------------- */

.acta .hoja   { fill: rgb(255 255 255 / .05); stroke: rgb(255 255 255 / .18); }
.acta .arriba { fill: rgb(255 255 255 / .07); stroke: #f2c94c; }
.acta .renglon { stroke: rgb(140 200 240 / .55); stroke-linecap: round; }
.acta .firma  { stroke: #f2c94c; }
.acta .sello  { fill: #f2c94c; font-size: 13px; font-weight: 700; }

/* --------------------------------------------------------------------------
   Fichas de norma
   -------------------------------------------------------------------------- */

.normas { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; }

.norma {
  padding: 24px;
  border-radius: var(--radio);
  background: var(--papel);
  border: 1px solid var(--linea);
  border-left: 3px solid var(--azul-vivo);
}
.norma h3 { font-size: 15px; letter-spacing: .02em; color: var(--azul); }
.norma p { margin-top: 10px; font-size: 15px; color: var(--gris); }
.norma cite { display: block; margin-top: 12px; font-size: 13px; color: var(--gris-2); font-style: normal; }

.oscuro .norma { background: rgb(255 255 255 / .05); border-color: rgb(255 255 255 / .12); border-left-color: var(--cian); }
.oscuro .norma h3 { color: var(--cian); }
.oscuro .norma p { color: rgb(255 255 255 / .78); }
.oscuro .norma cite { color: rgb(255 255 255 / .5); }

.aviso-legal {
  margin-top: 20px; padding: 16px 18px;
  border-radius: var(--radio-s);
  background: var(--papel-3);
  font-size: 14px; color: var(--gris);
}

/* La cifra grande de una ficha legal: es el argumento, así que va del tamaño
   de un titular y no del de un dato. */
.cifra-norma {
  display: block;
  font-size: clamp(2.6rem, 5.5vw, 4rem);
  font-weight: 700; letter-spacing: -.035em; line-height: 1;
  color: var(--cian);
  margin: 8px 0 18px;
}

@media (max-width: 860px) { .normas { grid-template-columns: minmax(0, 1fr); } }


/* ==========================================================================
   MOVIMIENTO LIGADO AL SCROLL
   --------------------------------------------------------------------------
   Lo que hace que un sitio de Apple se sienta como se siente no son las
   entradas: es que las piezas responden al scroll de forma continua, no por
   disparos. Acá hay dos gestos y ninguno más.

   1. EL APARATO DE LA PORTADA se acerca. Empieza un poco más chico y más abajo
      y se asienta a medida que la portada sale de pantalla. Es lo que sugiere
      que estás entrando en el producto y no pasando por delante de una foto.

   2. LAS CAPTURAS crecen al entrar, de 0,94 a 1. Muy poco, pero suficiente para
      que una pantalla se lea como algo que se acerca y no como una lámina que
      aparece.

   Se implementa con animaciones ligadas al scroll del navegador —
   `animation-timeline`— y no con un oyente de scroll en JavaScript. La
   diferencia importa: la versión del navegador corre en el hilo de composición
   y no se traba aunque la página esté ocupada; la de JavaScript se pega al
   desplazamiento en cuanto algo más pide tiempo de CPU.

   Donde el navegador no la soporta no pasa nada: quedan las entradas de
   arriba, que ya son el grueso del movimiento. Es una mejora, no un requisito.
   ========================================================================== */

@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {

    /* El MacBook de la portada ya no lleva animación ligada al scroll: entra
       con su propio gesto al cargar, y encima ocupa el ancho completo — dos
       movimientos sobre el mismo elemento se pelean por el `transform`. */

    @keyframes acercar {
      from { transform: scale(.94); }
      to   { transform: scale(1); }
    }

    .js .vitrina img {
      animation: acercar linear both;
      animation-timeline: view();
      animation-range: entry 8% cover 46%;
    }

    /*
     * La retícula del plano se desplaza más lento que la página.
     *
     * Es el único parallax del sitio y va sobre el fondo, nunca sobre el texto:
     * mover lo que se está leyendo es lo que produce ese mareo de los sitios
     * que abusan del efecto. Acá sólo separa el plano del contenido, que es
     * exactamente lo que hace un fondo en una lámina.
     */
    @keyframes derivar {
      from { transform: translateY(-3%); }
      to   { transform: translateY(3%); }
    }

    .js .oscuro::before {
      animation: derivar linear both;
      animation-timeline: view();
      animation-range: cover 0% cover 100%;
    }
  }
}

/*
 * La barra crece de línea a la vez que aparece.
 *
 * Detalle chico y de los que se notan sin verse: al pasar de transparente a
 * vidrio, la línea inferior no aparece de golpe sino que se dibuja desde el
 * centro hacia los bordes.
 */
.barra::after {
  content: '';
  position: absolute; left: 0; right: 0; bottom: -1px; height: 1px;
  background: rgb(10 14 20 / .1);
  transform: scaleX(0);
  transition: transform 420ms var(--sale);
}
.barra[data-desplazada='si']::after { transform: scaleX(1); }
.barra[data-desplazada='si'] { border-bottom-color: transparent; }

@media (prefers-reduced-motion: reduce) {
  .barra::after { transition: none; }
}

/* --------------------------------------------------------------------------
   Planes
   --------------------------------------------------------------------------
   Tres tarjetas comparables. Comparables es la palabra: cada fila —los topes,
   el resumen, lo que incluye— arranca a la misma altura en las tres, porque lo
   que hace alguien en esta página es mirar de lado a lado, y si las filas no
   calzan tiene que ir y volver con el dedo.

   Por eso la tarjeta es una rejilla con `subgrid`: las filas las define la
   rejilla de arriba y las tres tarjetas se cuelgan de ella. Donde no hay
   `subgrid` cada tarjeta se apila sola y se ve igual de bien, sólo que sin la
   alineación fina.
   -------------------------------------------------------------------------- */

.planes {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 20px;
  margin-top: clamp(36px, 4.5vw, 60px);
  align-items: stretch;
}

.plan {
  position: relative;
  display: grid;
  gap: 0;
  padding: 26px;
  border-radius: var(--radio-l);
  background: var(--papel);
  border: 1px solid var(--linea);
  box-shadow: var(--sombra-1);
  /*
   * El levante al pasar el cursor (pedido de Fabián: las tarjetas estaban
   * planas). Sólo transform y sombra —van por el compositor— y con la curva
   * de salida de la casa: la tarjeta responde al tiro, no se despereza.
   */
  transition: translate 200ms var(--sale), box-shadow 200ms var(--sale),
    border-color 200ms var(--sale);
}

@media (hover: hover) {
  /*
   * `translate` y no `transform`: la tarjeta también es `.revela`, y su
   * entrada amarrada al scroll ANIMA `transform` — una animación le gana a
   * cualquier declaración sobre la misma propiedad, así que el hover por
   * `transform` no movía nada. `translate` es propiedad aparte y convive.
   */
  .plan:hover {
    translate: 0 -6px;
    box-shadow: var(--sombra-2);
    border-color: rgb(0 83 214 / .35);
  }
  /* El recomendado ya está elevado: sube lo mismo pero no cambia su borde,
     que es su distintivo. */
  .plan--recomendado:hover { border-color: var(--azul); }
}

@supports (grid-template-rows: subgrid) {
  .planes { grid-template-rows: auto auto auto auto auto; }
  .plan { grid-row: span 5; grid-template-rows: subgrid; }
}

/*
 * El plan recomendado: elevado y con borde de marca, no de otro color.
 *
 * Un color distinto para destacar una tarjeta introduce un segundo acento en
 * una paleta que tiene uno solo, y el resultado se lee como una promoción y no
 * como una recomendación.
 */
.plan--recomendado {
  border: 2px solid var(--azul);
  box-shadow: var(--sombra-2);
}

.plan .insignia {
  position: absolute;
  top: -11px;
  left: 26px;
  padding: 4px 12px;
  border-radius: 999px;
  background: var(--azul);
  color: #fff;
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: .04em;
  text-transform: uppercase;
  white-space: nowrap;
}

.plan h3 {
  font-size: clamp(1.4rem, 2.2vw, 1.7rem);
  letter-spacing: -.022em;
  margin: 0;
}
.plan .rotulo { margin-bottom: 6px; }
.plan .cuerpo { margin-top: 12px; font-size: 15px; }

/* Los topes: la cifra manda y su unidad va debajo, para poder leer las tres
   tarjetas en horizontal sin tropezar con las palabras. */
.topes {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 4px 14px;
  margin: 22px 0 0;
  padding-top: 18px;
  border-top: 1px solid var(--linea);
}
.topes b {
  grid-row: 1;
  font-size: 1.35rem;
  font-weight: 700;
  letter-spacing: -.028em;
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
}
.topes span {
  grid-row: 2;
  font-size: 13px;
  color: var(--gris);
  text-wrap: balance;
}

.plan .lista { margin-top: 16px; }
.plan .lista li { grid-template-columns: 18px 1fr; gap: 10px; }
.plan .lista b { font-size: 15px; font-weight: 400; }

.plan-corte {
  height: 1px;
  background: var(--linea);
  border: 0;
  margin: 22px 0 0;
}

@media (max-width: 900px) {
  .planes { grid-template-columns: minmax(0, 1fr); gap: 24px; }
  @supports (grid-template-rows: subgrid) {
    .planes { grid-template-rows: none; }
    .plan { grid-row: auto; grid-template-rows: none; }
  }
}

/* --------------------------------------------------------------------------
   Preguntas frecuentes
   --------------------------------------------------------------------------
   Con `<details>` nativo y no con un acordeón de JavaScript.

   Tres razones, en orden de peso: funciona con el JavaScript apagado —y la
   batería comprueba justamente que la página se lea entera sin él—; trae la
   accesibilidad hecha, con su estado anunciado y su teclado; y el navegador ya
   sabe abrirlo cuando alguien usa «buscar en la página», que es exactamente lo
   que hace quien llega a una página de preguntas con una duda concreta.
   -------------------------------------------------------------------------- */

.faq { display: grid; gap: 12px; margin-top: clamp(22px, 3vw, 32px); }

.faq details {
  border: 1px solid var(--linea);
  border-radius: var(--radio);
  background: var(--papel);
  overflow: hidden;
}
.oscuro .faq details {
  background: rgb(255 255 255 / .05);
  border-color: rgb(255 255 255 / .13);
}

.faq summary {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 18px;
  padding: 18px 22px;
  font-size: 16.5px; font-weight: 600; letter-spacing: -.012em;
  cursor: pointer; list-style: none;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary:hover { background: var(--papel-2); }
.oscuro .faq summary:hover { background: rgb(255 255 255 / .04); }
.faq summary:focus-visible { outline: 2px solid var(--azul-vivo); outline-offset: -2px; }

/* El signo: una cruz que gira hasta ser un menos. Se dibuja con dos trazos y
   no con un carácter, porque un «+» tipográfico cambia de grosor y de centro
   con cada fuente del sistema. */
.faq .signo {
  flex: none; width: 20px; height: 20px; margin-top: 2px; position: relative;
  color: var(--azul-vivo);
}
.oscuro .faq .signo { color: var(--cian); }
.faq .signo::before,
.faq .signo::after {
  content: ''; position: absolute; inset: 0; margin: auto;
  background: currentColor; border-radius: 1px;
}
.faq .signo::before { width: 13px; height: 1.8px; }
.faq .signo::after  { width: 1.8px; height: 13px; transition: transform 200ms var(--sale); }
.faq details[open] .signo::after { transform: rotate(90deg); }

.faq .respuesta {
  padding: 0 22px 20px;
  font-size: 15.5px; line-height: 1.65; color: var(--gris);
  max-width: 68ch;
}
.oscuro .faq .respuesta { color: rgb(255 255 255 / .74); }
.faq .respuesta a { color: var(--azul-vivo); text-decoration: none; font-weight: 500; }
.oscuro .faq .respuesta a { color: var(--cian); }
.faq .respuesta a:hover { text-decoration: underline; }

/* El rótulo de cada grupo, con aire por encima salvo el primero. */
.faq-grupo + .faq-grupo { margin-top: clamp(38px, 5vw, 58px); }

@media (prefers-reduced-motion: reduce) {
  .faq .signo::after { transition: none; }
}

/* El encabezado de cada grupo: la bajada pegada al título se lee como una
   segunda línea del título y no como lo que es. */
.faq-grupo .bajada { margin-top: 10px; max-width: 62ch; }
.faq-grupo h2 { margin-top: 6px; }

/* --------------------------------------------------------------------------
   Formulario de contacto
   --------------------------------------------------------------------------
   El formulario a la izquierda y lo que pasa después a la derecha. En ese
   orden y no al revés: quien llega a esta página ya decidió escribir, y lo
   primero que tiene que encontrar es dónde hacerlo.
   -------------------------------------------------------------------------- */

.contacto {
  display: grid;
  grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr);
  gap: clamp(28px, 4vw, 56px);
  align-items: start;
}

.campo { display: grid; gap: 6px; margin-bottom: 16px; }
.campo label { font-size: 14.5px; font-weight: 600; letter-spacing: -.008em; }
.campo .ayuda { font-size: 13px; color: var(--gris); font-weight: 400; }

.campo input,
.campo select,
.campo textarea {
  width: 100%;
  padding: 12px 14px;
  font: inherit;
  font-size: 15.5px;
  color: var(--tinta);
  background: var(--papel);
  border: 1px solid var(--linea);
  border-radius: var(--radio-s);
  transition: border-color 160ms var(--sale), box-shadow 160ms var(--sale);
}
.campo textarea { resize: vertical; min-height: 110px; }
.campo input:focus,
.campo select:focus,
.campo textarea:focus {
  outline: none;
  border-color: var(--azul-vivo);
  box-shadow: 0 0 0 3px rgb(26 127 184 / .16);
}
/* El campo inválido se marca sólo después de intentar enviar: pintar de rojo
   mientras alguien todavía está escribiendo es regañarlo por no haber
   terminado. */
.campo input:user-invalid,
.campo textarea:user-invalid { border-color: #c0392b; }

/* La trampa para robots: fuera de pantalla, fuera del tabulador y fuera de un
   lector de pantalla. Un formulario que llega con esto lleno no lo llenó una
   persona. Se esconde con posición y no con `display:none`, porque algunos
   robots saltan justamente lo que está oculto. */
.trampa {
  position: absolute;
  left: -9999px;
  width: 1px; height: 1px;
  overflow: hidden;
}

.aviso {
  padding: 16px 18px;
  border-radius: var(--radio);
  margin-bottom: 22px;
  border: 1px solid;
}
.aviso b { display: block; font-size: 16px; letter-spacing: -.012em; }
.aviso p { margin: 6px 0 0; font-size: 15px; line-height: 1.55; }
.aviso--ok { background: #eef8f3; border-color: #bfe3d3; color: #14523a; }
.aviso--falla { background: #fdf1f0; border-color: #f0cdc9; color: #8a2b22; }

/* Lo que pasa después, al lado. */
.pasos { counter-reset: paso; list-style: none; margin: 16px 0 0; padding: 0; display: grid; gap: 16px; }
.pasos li { counter-increment: paso; display: grid; grid-template-columns: 26px 1fr; gap: 12px; }
.pasos li::before {
  content: counter(paso);
  width: 26px; height: 26px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--azul); color: #fff;
  font-size: 12.5px; font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.pasos b { display: block; font-size: 15px; letter-spacing: -.008em; }
.pasos span { display: block; font-size: 14.5px; color: var(--gris); margin-top: 2px; }

.ficha {
  padding: 24px;
  border-radius: var(--radio);
  background: var(--papel);
  border: 1px solid var(--linea);
  box-shadow: var(--sombra-1);
}
.ficha + .ficha { margin-top: 18px; }
.ficha a { color: var(--azul-vivo); text-decoration: none; }
.ficha a:hover { text-decoration: underline; }

@media (max-width: 860px) {
  .contacto { grid-template-columns: minmax(0, 1fr); }
}

/* --------------------------------------------------------------------------
   Los módulos, en tira
   --------------------------------------------------------------------------
   `.normas` reparte en dos columnas, que es lo correcto cuando ocupa el ancho
   entero de la sección. Adentro de un `.bloque` no lo ocupa: vive en la
   columna de 7 de doce, y tres tarjetas en dos columnas dejan la tercera sola
   ocupando el doble de ancho que sus hermanas, sin ninguna razón que el lector
   pueda adivinar. En tira las tres miden lo mismo y se leen de arriba abajo,
   que además es el orden en que están escritas.
   -------------------------------------------------------------------------- */
.normas-tira { grid-template-columns: minmax(0, 1fr); }

/* --------------------------------------------------------------------------
   El índice, en tres columnas
   --------------------------------------------------------------------------
   `.indice-normas` reparte en cuatro porque en la página de cumplimiento son
   cuatro normas justas. Con cinco o seis entradas, cuatro columnas dejan la
   última fila a medio llenar —una o dos tarjetas solas— y eso se lee como si
   algo hubiera quedado sin cargar.

   La clase se llama por lo que hace y no por cuántas entradas hay. Se llamaba
   `de-seis`, y a la primera página con cinco hubo que decidir entre poner una
   clase que mentía o escribir una segunda regla idéntica con otro nombre. Las
   dos salidas eran malas: el nombre correcto es el de la forma.
   -------------------------------------------------------------------------- */
.indice-normas.en-tres { grid-template-columns: repeat(3, minmax(0, 1fr)); }
@media (max-width: 900px) {
  .indice-normas.en-tres { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 560px) {
  .indice-normas.en-tres { grid-template-columns: minmax(0, 1fr); }
}

/* --------------------------------------------------------------------------
   Tres cifras
   --------------------------------------------------------------------------
   `.cifras` reparte en cuatro porque en la portada son cuatro. Cuando son tres
   —los tipos de equipo, los alcances y las mediciones con rango— la cuarta
   columna queda vacía y las tres se corren a la izquierda, descentradas
   respecto del encabezado que va arriba de ellas.
   -------------------------------------------------------------------------- */
.cifras-tres { grid-template-columns: repeat(3, minmax(0, 1fr)); }
@media (max-width: 860px) {
  .cifras-tres { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 560px) {
  .cifras-tres { grid-template-columns: minmax(0, 1fr); }
}

/* --------------------------------------------------------------------------
   Los pasos, sobre fondo oscuro
   --------------------------------------------------------------------------
   `.pasos` nació en el formulario de contacto, que va sobre papel. En una
   sección oscura el número queda azul sobre azul —ilegible— y el texto
   secundario, gris sobre azul oscuro, tampoco se lee. Se corrigen los dos.
   -------------------------------------------------------------------------- */
.oscuro .pasos li::before { background: var(--cian); color: var(--azul); }
.oscuro .pasos span { color: rgb(255 255 255 / .7); }

/* La banda «Una plataforma viva» (índice): las tarjetas de cifras, en claro.
   `.cifra` nació para el fondo azul del cierre —vidrio blanco translúcido— y
   sobre el fondo tenue desaparece. Acá son tarjetas blancas con borde, y el
   número grande toma el color de su tipo, igual que en el cuadro de
   Actualizaciones de la plataforma: verde lo nuevo, ámbar lo corregido. */
.cifras-claras .cifra { background: #fff; border-color: var(--linea); }
.cifras-claras .cifra b { color: var(--tinta); font-variant-numeric: tabular-nums; }
.cifras-claras .cifra b.verde { color: #15803d; }
.cifras-claras .cifra b.ambar { color: #b45309; }
.cifras-claras .cifra span { color: var(--tinta-2); }
#en-movimiento .bajada b { font-weight: 600; color: var(--tinta); font-variant-numeric: tabular-nums; }

/* --- El video (facade de YouTube) ---------------------------------------- */
.video-marco { max-width: 960px; margin: 0 auto; }
.video-facade { position: relative; display: block; aspect-ratio: 16 / 9; overflow: hidden; border-radius: var(--radio-l); background: var(--azul-hondo); box-shadow: 0 30px 60px -30px rgba(0, 29, 48, .55); }
.video-facade img { display: block; width: 100%; height: 100%; object-fit: cover; transition: transform .6s var(--sale); }
.video-facade:hover img { transform: scale(1.02); }
.video-play { position: absolute; inset: 0; margin: auto; width: 84px; height: 84px; border-radius: 50%; background: rgba(255, 255, 255, .92); color: var(--azul); display: flex; align-items: center; justify-content: center; box-shadow: 0 10px 30px rgba(0, 29, 48, .35); transition: transform .2s var(--sale), background .2s; }
.video-play svg { margin-left: 4px; }
.video-facade:hover .video-play { transform: scale(1.06); background: #fff; }
.video-facade:focus-visible { outline: 3px solid var(--cian); outline-offset: 4px; }
.video-facade iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
@media (prefers-reduced-motion: reduce) { .video-facade img, .video-play { transition: none; } .video-facade:hover img { transform: none; } }
