/* ============================================================================
   ReconoCer IPS — Sistema de diseño v2
   Ancla visual: su propio local. Vidrio, madera clara, techo industrial negro
   y un letrero iluminado en cian y magenta. El degradado del logo ES ese
   letrero: aquí es el recurso gráfico de toda la web.
   ========================================================================== */

:root {
  /* Marca */
  --azul: #19255a;
  --azul-900: #0b1023;
  --azul-700: #243359;
  --cian: #009fe3;
  /* Enlaces y acentos de texto. Sobre oscuro es el celeste del manual sin
     tocar: da 6,1:1 y no hace falta aclararlo. Se redefine en el tema claro,
     donde el mismo color no llega. */
  --cian-claro: var(--cian);
  --magenta: #e6007e;


  /* El letrero: degradado propio de la marca */
  --letrero: linear-gradient(100deg, var(--cian) 0%, #6b57c4 52%, var(--magenta) 100%);

  /* El mismo letrero, pero para TEXTO recortado y para filos finos. Existe
     aparte porque un FONDO puede llevar el cian de marca y una LETRA no: sobre
     el tema claro #009fe3 da 2,79:1 y el arranque del titular se lava.
     Se redefine en el bloque del tema claro.

     Sobre oscuro NO son las mismas paradas que el letrero de fondo, y es a
     propósito. Medido en luminancia, el letrero original va 0,303 → 0,139 →
     0,183: arranca brillante, se HUNDE en el violeta y termina apagado, así
     que el ojo se queda solo con el azul. Aquí el recorrido va 0,303 → 0,215
     → 0,293, parejo de punta a punta, y el violeta se adelanta al 44% para
     que el magenta tenga sitio de verdad. */
  --letrero-texto: linear-gradient(100deg, var(--cian) 0%, #8a6ce0 44%, #ff4da6 100%);

  /* Palabras resaltadas DENTRO de un párrafo. Son los DOS colores del manual
     sin retocar: celeste #009fe3 y magenta #e6007e.

     Que puedan ser los del manual depende de `.resalte`, que va en 700. El
     magenta puro como texto normal da 4,33:1 sobre oscuro y se queda a un pelo
     del 4,5:1 que exige el texto de párrafo; en negrita a 18,7 px la entradilla
     ya cuenta como texto grande (WCAG: ≥18,66 px en 700) y el listón baja a
     3:1, que cumple de sobra. El peso no es maquillaje para pasar la medida:
     era necesario igual, porque en regular el celeste se leía como un ENLACE
     en vez de como una palabra resaltada. */
  --resalte-cian: var(--cian);
  --resalte-magenta: var(--magenta);

  /* Magenta para ENLACES. Existe aparte de --magenta por la misma razón que
     --cian-claro existe aparte de --cian: el color del manual no cumple como
     texto pequeño. #e6007e sobre el vidrio de una tarjeta da 3,77:1 y los
     enlaces van a 14 px, así que el listón son 4,5. Este aclarado da 6,4:1, y
     no es inventado: es el mismo #ff4da6 con el que cierra el letrero escrito
     del titular. Se redefine en el tema claro. */
  --enlace-magenta: #ff4da6;

  /* Fondo. El sitio entero vive sobre este pozo; la luz la pone body::before */
  --fondo: #070c1a;

  /* Superficies de vidrio. No son colores planos: dejan pasar el degradado.
     Por eso todo el sitio se lee como UNA superficie con luz encima. */
  --superficie: rgba(255, 255, 255, .045);
  --superficie-2: rgba(255, 255, 255, .075);
  --velo: rgba(255, 255, 255, .022);
  --borde: rgba(255, 255, 255, .10);
  --borde-fuerte: rgba(255, 255, 255, .20);
  /* Capas translúcidas: realces y filos. Cambian de signo con el tema. */
  --capa-1: rgba(255, 255, 255, .07);
  --capa-2: rgba(255, 255, 255, .14);
  --nav-vidrio: rgba(11, 16, 35, .72);
  --nav-vidrio-fijo: rgba(11, 16, 35, .90);
  --nav-sombra: 0 18px 46px rgba(11, 16, 35, .30);
  --pie-fondo: rgba(3, 6, 16, .38);

  /* Texto sobre oscuro. --tinta ya no es tinta: es el blanco de titular. */
  --tinta: #ffffff;
  --texto: #dde4f4;
  --suave: #aeb9d6;
  --sobre-azul: #c6d0e8;

  --fuente: "Ubuntu", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;

  /* Escala. Techo 88px: por debajo del limite de impeccable (96px) */
  /* --- Los titulares, en escala áurea -----------------------------------
     La razón es √φ = 1,272 (la raíz de la áurea), no φ = 1,618. No es una
     rebaja: con φ entera, tres niveles seguidos van 1 : 1,618 : 2,618, y para
     que el h1 creciera el h2 tendría que ENCOGER por debajo de lo que ya
     tiene. √φ da una escalera de peldaños iguales donde los tres crecen.

     La escalera completa, desde el cuerpo de texto (17 px), multiplicando por
     1,272 cada vez:

       17 · 21,6 · 27,5 · 35 · 44,5 · 56 · 72 · 92
        ↑     ↑      ↑                  ↑    ↑    ↑
      cuerpo lead    h3                 h2   h1  display

     Los tres titulares principales son ahora **peldaños consecutivos** —56,
     72, 92—, que es lo que hace que la jerarquía se lea sin pensarla. Antes
     iban 50 · 60 · 88: entre h2 y h1 había un 1,2 (demasiado poco, se
     confundían) y entre h1 y display un 1,47 (demasiado, se rompía).

     El h3 NO sube: titula tarjetas («Carro o moto», el nombre de una sede) y
     al tamaño de un titular de sección dejaría de leerse como lo que es. Se
     queda en su peldaño de 27,5.

     Los mínimos suben menos que los máximos, y a propósito: en 320 px un
     titular de cinco palabras a 44 px ocupa cinco renglones. Medido en las 16
     páginas a 320, 360 y 390 antes de darlo por bueno. */
  --t-display: clamp(3.125rem, 6.97vw, 5.75rem);
  --t-h1: clamp(2.5rem, 5.45vw, 4.5rem);
  --t-h2: clamp(2.1875rem, 4.24vw, 3.5rem);
  --t-h3: clamp(1.375rem, 1.9vw, 1.75rem);
  --t-lead: clamp(1.0625rem, 1.3vw, 1.3125rem);
  /* Entradilla de titular GRANDE. Existe porque la escala tenía un agujero: la
     entradilla normal se calculó contra titulares de 50 px, y bajo uno de 60
     la razón se iba a 3,2 y el texto se leía como un pie de foto. Un escalón
     por encima de --t-lead y por debajo de --t-h3, que ya es tamaño de titular.

     🔴 SUBE CON LOS TITULARES, y no es opcional. Al pasar el h1 de 60 a 72 px,
     una entradilla de 23 dejaba la razón en 3,13 — otra vez dentro de la zona
     donde se lee como un pie de foto, que es justo el problema que este token
     vino a resolver. A 25,6 px la razón queda en 2,81. Agrandar un titular sin
     mirar lo que va debajo deshace el arreglo anterior. */
  --t-lead-mayor: clamp(1.25rem, 1.95vw, 1.6rem);
  --t-cuerpo: 1.0625rem;
  --t-menor: 0.9375rem;
  --t-mini: 0.8125rem;

  --seccion: clamp(4.5rem, 9vw, 8rem);
  /* El aire entre una cabecera de sección y lo que encabeza. Es un TOKEN y no
     un valor suelto porque lo necesitan dos reglas (ver la nota de
     `.cabeza-seccion + *`), y dos copias de un clamp se separan solas. */
  --aire-cabeza: clamp(2.75rem, 5vw, 4.5rem);
  --seccion-corta: clamp(3.5rem, 7vw, 6rem);
  --ancho: 1240px;
  --ancho-prosa: 720px;
  --canal: clamp(1.25rem, 5vw, 3rem);

  --r-s: 10px;
  --r-m: 16px;
  --r-l: 24px;
  --r-xl: 34px;
  /* Sobre oscuro una sombra no se ve: la elevación se hace con luz, no con sombra */
  --sombra-media: 0 24px 60px rgba(0, 0, 0, .45);
  --sombra-alta: 0 40px 110px rgba(0, 0, 0, .6);
  --brillo-cian: 0 20px 60px rgba(0, 159, 227, .22);
  /* El filo y el halo de «esto esta senalado». Existen aparte del cian porque
     el cian ya significa «esto se puede pulsar»: si los dos son iguales, la
     sede que salio mas cerca se ve igual que la tarjeta sobre la que esta el
     raton.

     El filo va a media tinta y no a magenta pleno: a 1 px y a plena
     saturacion el borde compite con la pildora y con la linea de la distancia,
     que son las que llevan el dato. Marcar no es gritar. La opacidad cambia
     por tema porque el mismo rgba sobre un fondo casi negro y sobre uno casi
     blanco no da el mismo peso visual. */
  --filo-cercana: rgba(230, 0, 126, .62);
  --brillo-magenta: 0 20px 60px rgba(230, 0, 126, .18);


  /* === VOCABULARIO DE MOVIMIENTO =======================================
     Medido en apple.com/iphone antes de escribir esto: 471 curvas, 82
     duraciones distintas y 34 bloques de reduced-motion. Ni vídeo, ni canvas,
     ni scroll-driven CSS: transiciones normales con un vocabulario enorme.
     Aquí había 5 curvas sueltas por el archivo y ninguna decía para qué era.

     Una curva por TIPO DE GESTO, no por elemento:

       entra      lo que llega a la pantalla. Frena al final, como algo que
                  se posa. Es la de siempre (`--sal`), ahora con nombre.
       sale       lo que se va. Arranca despacio y acelera al irse: al ojo no
                  le interesa el final de algo que desaparece.
       toque      la respuesta al cursor o al dedo. Corta y casi lineal al
                  principio: si tarda, se siente floja.
       despliega  lo que se abre en su sitio (un panel, una respuesta).
       empuje     se PASA del destino y vuelve. Es el acento: solo donde algo
                  tiene que sentir peso. Nunca en varios sitios a la vez.

     🔴 Las tres primeras y `despliega` son monótonas (van de 0 a 1 sin
     volverse). `empuje` NO: su cuarto valor pasa de 1, así que sobrepasa. No
     usarla en nada que mida distancia real o el usuario percibe un rebote
     donde no lo hay. */
  --mov-entra: cubic-bezier(.23, 1, .32, 1);
  --mov-toque: cubic-bezier(.33, 0, .2, 1);
  --mov-despliega: cubic-bezier(.32, .72, 0, 1);
  --mov-empuje: cubic-bezier(.34, 1.32, .64, 1);

  --t-toque: 220ms;
  --t-entra: 620ms;
  --t-despliega: 420ms;

  /* `--sal` y `--mov` son los nombres viejos y siguen vivos porque los usan 28
     transiciones. `--sal` ES `--mov-entra`: se apunta al token nuevo para que
     haya UNA sola definición y no dos que se puedan separar con el tiempo. */
  --sal: var(--mov-entra);

  --z-barra: 90;    /* barra de acción del móvil: por debajo de la cabecera */
  --z-sticky: 100;
  /* 🔴 No hay `--z-sheet`. Lo hubo, en 200, y no lo usaba nadie: la hoja del
     menú vive DENTRO del contexto de apilamiento de `.nav`, así que su z es
     local (1, por debajo de la píldora, que va en 2) y el peldaño global
     sobraba. Un peldaño con nombre y sin nadie encima engaña al que lo lee. */
  --z-sheet-sobre: 210;  /* la cabecera cuando la hoja está abierta */
  --z-skip: 300;
}

/* === La maqueta dejaba de crecer a 1440 ==================================
   Todas las medidas son clamp() con tope, y ese tope se alcanzaba a 1440 px.
   De ahí en adelante la página no movía UNA SOLA medida. Medido en el canal:

     ventana   envoltura   % de pantalla usado
      1280       1240            97%
      1440       1240            86%
      1920       1240            65%
      2560       1240            48%
      3840       1240            32%   <- esto es quitar zoom al 50%

   El cuerpo se quedaba en 17 px y el display en 92 px en las cinco.

   Por qué el zoom lo destapa: alejar el zoom NO encoge la página, agranda el
   viewport en píxeles CSS. Quitar zoom al 50% en un monitor de 1920 es
   exactamente lo mismo que abrirla en uno de 3840, y la maqueta lo trataba
   como si no hubiera pasado nada: la misma columna de 1240 en medio de un
   desierto.

   El arreglo es REANUDAR el crecimiento a partir de 1440, no rehacer la
   escala. Por debajo de 1441 no se mueve ni un píxel, así que todo lo medido
   hasta hoy —móvil 320-560, portátil 1000-1366, contrastes, desbordes— sigue
   valiendo sin volver a medirlo.

   La forma `px + vw` y no `vw` a secas: cada valor tiene que arrancar
   EXACTAMENTE donde estaba a 1440 y llegar a su nuevo tope a 2200. Con solo
   `vw` el suelo del clamp aguantaría hasta cruzarse con la recta y ahí
   habría un escalón visible.

   Los titulares crecen MENOS que el texto corrido (+4% contra +12%). No es
   descuido: es cómo funciona una escala tipográfica. Lo que ya es grande se
   lee de sobra; lo que se pierde al alejarse es lo pequeño. Y el display se
   planta en 6rem (96 px) porque por encima de ahí un titular deja de diseñar
   y se pone a gritar.

   Las CAJAS de texto crecen con la letra, no se quedan en rem: si no, la
   columna encoge en caracteres por renglón justo cuando la pantalla crece.
   Detalle y trampa de especificidad, dentro del bloque.
   ======================================================================== */
@media (min-width: 1441px) {
  :root {
    --ancho: clamp(1240px, 557.9px + 47.37vw, 1600px);
    --canal: clamp(3rem, 17.7px + 2.11vw, 4rem);

    --t-display:    clamp(5.75rem,   84.4px + 0.53vw, 6rem);
    --t-h1:         clamp(4.5rem,    66.3px + 0.40vw, 4.6875rem);
    --t-h2:         clamp(3.5rem,    51.5px + 0.32vw, 3.65rem);
    --t-h3:         clamp(1.71rem,   22.4px + 0.347vw, 1.875rem);
    --t-lead:       clamp(1.17rem,   10.6px + 0.563vw, 1.4375rem);
    --t-lead-mayor: clamp(1.6rem,    21.1px + 0.32vw, 1.75rem);
    --t-cuerpo:     clamp(1.0625rem, 13.2px + 0.26vw, 1.1875rem);
    --t-menor:      clamp(0.9375rem, 12.2px + 0.20vw, 1.03125rem);
    --t-mini:       clamp(0.8125rem, 11.1px + 0.13vw, 0.875rem);

    /* 🔴 --t-h3 y --t-lead arrancan en 1,71rem y 1,17rem, NO en su tope.
       Sus clamps de abajo son 1.9vw y 1.3vw: no llegan al tope a 1440 sino a
       1474 y 1615. Poner aquí el tope como suelo metía un SALTO justo al
       cruzar 1441 —la entradilla brincaba de 18,7 a 21 px de golpe, un 12%—.
       El suelo de cada token tiene que ser lo que VALE a 1440, no su máximo
       teórico. Medido con `ancho-fluido.js`, que barre 1430-1460. */

    /* La caja de prosa crece con la letra, no se queda en 720px: ver abajo. */
    --ancho-prosa: 42.35em;
  }

  /* --- Las CAJAS de texto crecen con la LETRA ---------------------------
     Si la letra crece y su caja se queda en rem, la caja encoge en la unidad
     que de verdad importa —caracteres por renglón— y el texto cabe PEOR en
     una pantalla MÁS grande. Medido a 2560 antes de esto: nueve bloques
     ganaban renglón, y la entradilla de «Tres sedes en Bogotá» pasaba de dos
     renglones a tres, desmintiendo lo que dice su propio comentario.

     Van en `em` y no en píxeles calculados: `em` se mide contra la letra del
     propio bloque, así que la medida en caracteres se queda clavada sola, a
     cualquier tamaño y sin cuentas. Y por debajo de 1441 dan EXACTAMENTE lo
     que había —42,35em x 17px = 720px; 25em x 25,6px = 640px— porque ahí la
     letra no se mueve.

     🔴 El `:root` delante no es adorno. Estas reglas viven junto a los tokens
     y las que tienen que pisar están 600 líneas más abajo con el mismo peso
     (0,1,0). A igual peso gana la última del archivo, y una media query NO
     suma especificidad. Sin el `:root` esto se escribe, se despliega y no
     hace absolutamente nada. Pasó dos veces seguidas en este bloque. */
  :root .cabeza-seccion { max-width: 45.18em; }   /* eran 48rem */
  :root .faq            { max-width: 45.18em; }   /* eran 48rem */
  :root .sedes-cabeza   { max-width: 54.59em; }   /* eran 58rem */
  :root .cabeza-seccion .lead,
  :root .sedes-cabeza > p { max-width: 25em; }    /* eran 40rem */

  /* La home redefine --t-h1 y --t-h2 SOBRE EL BODY (para agrandar el titular
     en el teléfono). Una propiedad puesta en `body` gana a la misma puesta en
     `:root` para todo lo que cuelga del body, así que sin repetirlas aquí la
     home sería la única página que NO crece: medido, su h1 se quedaba clavado
     en 72 px hasta 3840. Mismo `:root` por el mismo motivo de arriba. */
  :root body[data-pagina="home"] {
    --t-h1: clamp(4.5rem, 66.3px + 0.40vw, 4.6875rem);
    --t-h2: var(--t-h1);   /* mismo peldano: ver la nota de arriba */
  }
}

/* --- Reset -------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }

/* 🔴 Sin rebote en los extremos de la página (15-09-2026).

   En Safari de Mac, al arrastrar hacia arriba estando ya arriba del todo, la
   página hace el rebote elástico y la píldora de navegación se veía CORTADA
   durante un instante. La píldora es vidrio (`backdrop-filter`) y va fija:
   mientras dura el rebote, el trozo de pantalla que tiene detrás queda FUERA
   del documento, WebKit no tiene nada que desenfocar ahí y ese trozo sale
   vacío. Justo arriba del todo, además, la píldora está en su versión más
   transparente (`--nav-vidrio`, antes del cambio a `-fijo` a los 12 px), así
   que es cuando más se nota. Chrome no rebota en escritorio: aquí no se ve.

   Se quita la causa, no el vidrio: sin rebote no hay hueco fuera del
   documento. Safari lo respeta desde la versión 16. Va en `html`, que es
   quien hace scroll, y en `body` por si alguna versión de WebKit mira ahí.
   No toca la inercia del dedo dentro de la página —el deslizamiento suave que
   se arregló el 14-09— porque sólo actúa cuando el scroll ya llegó al tope.

   🔴 NO arreglarlo poniendo `background` en `html`. Parece lo obvio (pintar
   el hueco del rebote del color de la página) y rompe el campo de luz: con
   fondo propio en `html`, el de `body` deja de pasar al lienzo y se pinta
   sobre su propia caja, que va POR ENCIMA de `body::before` (z-index -2). El
   degradado de fondo de todo el sitio desaparecería. */
html, body { overscroll-behavior-y: none; }

/* 🔴 NO poner `scroll-behavior: smooth` aquí. Es incompatible con
   ScrollTrigger: para medir posiciones, ScrollTrigger vuelve a cero, mide y
   restaura el scroll, y con el desplazamiento suave ese salto NO es inmediato,
   así que mide contra la posición equivocada. Medido: tras un refresco estando
   a 1400 px de scroll, el disparador del héroe pasaba de `start 141 / end 830`
   a `start -1320 / end -590` —desplazado justo el scroll que había— y la foto
   de los gemelos se quedaba invisible para siempre.
   Se disparaba al cambiar de tema (que refresca) y también al REDIMENSIONAR la
   ventana, que refresca sola. Lo notó el usuario en su teléfono.
   El sitio tiene un único ancla interna, el enlace de saltar al contenido, que
   además debe saltar al instante: en un salto de accesibilidad el
   desplazamiento suave estorba. */

body {
  position: relative;
  margin: 0;
  font-family: var(--fuente);
  font-size: var(--t-cuerpo);
  line-height: 1.65;
  color: var(--texto);
  background: var(--fondo);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  /* 🔴 `hidden` NO basta en iOS. Recorta lo que se sale, así que en Chrome la
     página parece correcta, pero Safari en iPhone sigue dejando ARRASTRAR el
     documento entero con el dedo: la barra fija se queda quieta y todo lo
     demás se corre y se corta por la derecha. Con un solo píxel de sobra ya
     pasa. Se vio en un iPhone de verdad; ninguna medición en Chrome lo
     detectaba.

     `clip` sí lo impide, y además —a diferencia de `hidden`— no convierte al
     body en un contenedor de scroll, así que no rompe `position: sticky`.
     Se dejan los dos: el navegador que no entienda `clip` se queda con
     `hidden`, que es lo que había. */
  overflow-x: hidden;
  overflow-x: clip;
}

/* El campo de luz. Fijo al viewport: el contenido pasa por delante y el
   degradado se mantiene, que es lo que hace que la página se lea continua.
   z-index negativo => pinta por debajo del contenido en flujo sin envolverlo. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -2;
  pointer-events: none;
  background:
    radial-gradient(78% 52% at 50% -4%, rgba(38, 54, 116, .95) 0%, transparent 64%),
    radial-gradient(52% 38% at 90% 20%, rgba(0, 159, 227, .17) 0%, transparent 62%),
    radial-gradient(58% 44% at 4% 56%, rgba(107, 87, 196, .17) 0%, transparent 64%),
    radial-gradient(66% 48% at 82% 88%, rgba(230, 0, 126, .13) 0%, transparent 62%);
}

/* Grano global. Le quita el plástico al degradado y evita el banding en
   pantallas de 8 bits, que sobre azules grandes se nota mucho. */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: .42;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23g)' opacity='.35'/%3E%3C/svg%3E");
}

[hidden] { display: none !important; }
img, picture, svg, video { display: block; max-width: 100%; }
img { height: auto; }
button, input, select, textarea { font: inherit; color: inherit; }
h1, h2, h3, h4, p, figure, blockquote, ul, ol, dl, dd, fieldset { margin: 0; }
ul, ol { padding: 0; list-style: none; }
fieldset { border: 0; padding: 0; }

:focus-visible { outline: 3px solid var(--cian); outline-offset: 3px; border-radius: 4px; }
::selection { background: var(--cian); color: var(--azul-900); }

.saltar {
  position: absolute; left: var(--canal); top: -100px; z-index: var(--z-skip);
  background: var(--cian); color: var(--azul-900); padding: .75rem 1.25rem;
  border-radius: 0 0 var(--r-s) var(--r-s); text-decoration: none; font-weight: 500;
  transition: top 180ms var(--sal);
}
.saltar:focus { top: 0; }

/* --- Tipografía --------------------------------------------------------- */
h1, h2, h3, h4 {
  color: var(--tinta); font-weight: 700; line-height: 1.06;
  letter-spacing: -0.032em; text-wrap: balance;
}
h3, h4 { line-height: 1.24; letter-spacing: -0.02em; }

/* -0,02em, no -0,04em. Medido sobre la papelería de la marca: el titular de
   «Crecemos con propósito» (Ubuntu Bold a ~88 px sobre 1600×900) va a un
   interletrado de entre -0,015 y 0em. Estábamos apretando el doble que la
   propia marca, y -0,04em es además el suelo de lo aceptable: por debajo las
   letras se tocan. Margen de la medición: ±0,01em. */
.display { font-size: var(--t-display); letter-spacing: -0.02em; line-height: 1.0; }

/* --- El letrero, escrito -------------------------------------------------
   El degradado del logo aplicado a la propia letra: mismo ángulo y mismas
   paradas que el letrero de la fachada.

   🔴 LA REGLA CAMBIÓ el 13-09-2026, y conviene saber por qué. Esta nota decía
   «solo el titular del héroe y el de las tres sedes; repetido en cada h2 deja
   de ser una firma». Eso valía cuando el degradado era un adorno suelto. Ahora
   es GRAMÁTICA, y la gramática tiene que ser la misma en todo el sitio o deja
   de significar nada:

     · degradado  = AQUÍ EMPIEZA UNA SECCIÓN (h1 de página, h2 de sección,
                    titular de cierre, y el h2 de artículo dentro de una guía)
     · tinta sólida = todo lo que vive DENTRO de una sección: h3 de tarjeta,
                    h3 de paso, subtítulos de artículo.

   Lo que mantiene la escasez ya no es la lista corta: es que ningún titular de
   segundo nivel lo lleva. Un lector que baja ve aproximadamente un degradado
   por pantalla, que es la densidad que ya tenía la home.

   Y donde el bloque es de DOS COLUMNAS (`.alterno`, `.ficha`, `.prueba`) el
   titular lleva degradado pero NO el encendido palabra a palabra: ahí la
   entrada la hace el bloque entero, y dos animaciones peleándose por la misma
   opacidad hacen parpadear el texto. Está probado y anotado en sitio.js.

   El interletrado vive aquí y no en cada sitio de uso: lo que lleva el
   degradado lleva también el interletrado MEDIDO sobre la papelería de la
   marca (-0,02em), no el -0,032em genérico de los h2. Las dos cosas son el
   mismo gesto y tienen que viajar juntas. */
.letrero-texto { color: var(--tinta); letter-spacing: -0.02em; }

@supports ((background-clip: text) or (-webkit-background-clip: text)) {
  .letrero-texto {
    background-image: var(--letrero-texto);
    -webkit-background-clip: text;
            background-clip: text;
    color: transparent;
    -webkit-text-fill-color: transparent;
    /* El degradado se recorta a la CAJA, y con line-height 1.0 las mayúsculas
       y las colas de la "y" se salen de ella: sin este aire quedarían sin
       pintar, o sea invisibles. El margen negativo lo devuelve al maquetado,
       así que no mueve nada. */
    padding-block: .14em .18em;
    margin-block: -.14em -.18em;
  }
}

/* En alto contraste de Windows no hay degradado, y sin degradado no hay letra:
   el titular desaparecería entero. Se devuelve el color del sistema. */
@media (forced-colors: active) {
  .letrero-texto {
    background-image: none;
    color: CanvasText;
    -webkit-text-fill-color: CanvasText;
  }
}

/* --- El degradado, repartido palabra a palabra ---------------------------
   Para el encendido por scroll de [data-enciende-palabras]. Lo pone sitio.js marcando
   `data-partido`, así que sin JS nada de esto existe y el titular es el de
   siempre.

   🔴 POR QUÉ HACE FALTA. Con `background-clip: text` el color no lo pintan
   los glifos —son transparentes— sino el FONDO DEL PADRE. Un <span> hijo no
   pinta nada, así que bajarle la opacidad no lo atenúa: comprobado con dos
   capturas idénticas píxel a píxel. Para poder encender una palabra, la
   palabra tiene que pintar su propio trozo del degradado. */
@supports ((background-clip: text) or (-webkit-background-clip: text)) {
  /* El padre deja de pintar. Si siguiera, sus letras saldrían a plena luz por
     debajo de las palabras apagadas y no se vería ningún encendido. */
  .letrero-texto[data-partido] { background-image: none; }

  .letrero-texto[data-partido] .palabra {
    background-image: var(--letrero-texto);
    /* 🔴 Sin esto el degradado SE REPITE dentro de cada palabra: mide lo que el
       titular entero y va colocado en negativo, así que la baldosa de al lado
       entra en la caja. Se vería un arcoíris por palabra en vez de uno solo. */
    background-repeat: no-repeat;
    -webkit-background-clip: text;
            background-clip: text;
    color: transparent;
    -webkit-text-fill-color: transparent;
    /* El mismo aire que lleva el titular y por la misma razón: el degradado se
       recorta a la caja, y con interlineado corto las mayúsculas y las colas de
       la "y" se saldrían de ella, o sea que quedarían sin pintar.
       El tamaño y la posición van en píxeles y los calcula sitio.js, que mide
       DESPUÉS de que esto se aplique: este aire cambia la caja de la palabra. */
    padding-block: .14em .18em;
    /* Sin `margin-block` negativo, al revés que en el titular: estas palabras
       son `inline`, y en una caja en línea el relleno vertical NO empuja el
       maquetado —solo agranda la zona pintada, que es justo lo que hace falta—
       mientras que el margen vertical se ignora por completo. Ponerlo sería
       una línea que no hace nada. */
  }
}

@media (forced-colors: active) {
  .letrero-texto[data-partido] .palabra {
    background-image: none;
    color: CanvasText;
    -webkit-text-fill-color: CanvasText;
  }
}


/* ========================================================================
   HOME · Titulares de sección
   Solo la home: se trabaja por capas. El día que se quiera en las internas,
   es quitar el `body[data-pagina="home"]` de delante.
   ======================================================================== */

/* --- 🔴 El degradado se pintaba sobre la CAJA, no sobre el texto ---------
   "Tarifas" se veía MORADO. No era el degradado: era que `.letrero-texto` es
   un bloque de ancho completo y el degradado se reparte sobre esa caja, no
   sobre la palabra. Una palabra corta y centrada cae en el medio de la caja, y
   el medio de `--letrero-texto` es justo el violeta del 44%.

   Medido antes de tocar nada, qué tramo del degradado usa cada titular:

     "Tarifas"               39%–61%   ← violeta puro, el del aviso
     "Guías informativas"    19%–81%
     "Preguntas frecuentes"  14%–86%   ← este sí se veía bien

   Con la caja ajustada al texto, TODOS usan 0%–100%: cian a magenta enteros.
   Y no afecta a los que ya llenaban el ancho —si el texto envuelve, fit-content
   vale lo mismo que el ancho disponible—, así que solo cambia lo que estaba mal.

   `margin-inline: auto` porque al encoger la caja hay que devolverla al centro;
   estos titulares van centrados. */
body[data-pagina="home"] .cabeza-seccion > h2.letrero-texto,
body[data-pagina="home"] .cabeza-seccion > h3.letrero-texto,
body[data-pagina="home"] .sedes-cabeza > h2.letrero-texto {
  width: fit-content;
  margin-inline: auto;
  max-width: 100%;
}

/* --- Titulares más grandes en el teléfono -------------------------------
   Se sube el SUELO del clamp, no se mete un @media. Con un corte duro, a 700 px
   el titular seguiría en 35 y a 639 saltaría a 44 de golpe; moviendo el suelo la
   subida es continua y el techo de escritorio no se toca (a 1440 sigue dando los
   mismos 56 y 72 de siempre).

   Los dos a la vez, y en √φ = 1,272, que es la escala del proyecto:
     h2  35 → 44 px   (44/35 = 1,257)
     h1  40 → 56 px   (56/44 = 1,272, la misma razón que el 72/56 de escritorio)

   El h1 sube con el h2 a propósito: `.sedes-cabeza h2` ("Tres sedes en Bogotá")
   usa --t-h1 para ser el titular grande de la home. Si solo subiera el h2, el
   titular pequeño pasaría a medir MÁS que el grande y se rompería la jerarquía. */
body[data-pagina="home"] {
  /* El SUELO tambien se encoge por debajo de ~392 px, y no es un capricho:
     a 56 px la palabra `valoraciones` mide 325 px y la columna de un movil de
     320 solo da 280. Medido: la home se desplazaba de lado 25 px. Con
     `min(3.5rem, 14.3vw)` el titular baja a 45,8 px justo en los telefonos mas
     estrechos y vuelve a 56 en cuanto hay sitio (a partir de 392). Sigue
     siendo el mismo tamano para TODOS los titulares de la home: lo que cambia
     es el peldano entero, no uno solo. */
  --t-h1: clamp(min(3.5rem, 14.3vw), 5.45vw, 4.5rem);
  --t-h2: var(--t-h1);   /* mismo peldano: ver la nota de arriba */
}

/* --- Aire entre secciones ------------------------------------------------
   El hueco que se PERCIBE entre dos secciones no es el relleno de una: es la
   SUMA de las dos, porque se tocan. Medido en el canal, a 1440 px:

     hueco real entre secciones .............. 249–257 px
     alto de la ventana ...................... 900 px
     suma de todos los huecos de la home ..... 1.615 px = 17 % de la página

   Un cuarto de pantalla de nada entre bloque y bloque. Se baja el tope de
   escritorio de 128 a 88 px por lado (hueco 176) y el de móvil de 56 a 44
   (hueco 88). No se toca la proporción entre secciones: el ritmo relativo es
   el mismo, solo cabe más página.

   🔴 Hay que dar TAMBIÉN el valor de móvil. El escalón de abajo lo pone
   `:root` dentro de su media query, y un token declarado en `body` le gana
   siempre —body es descendiente de root—, así que sin esto la home se
   quedaría con el valor de escritorio en el teléfono. */
body[data-pagina="home"] {
  --seccion: clamp(3.5rem, 6.2vw, 5.5rem);
  --aire-cabeza: 2rem;
  --seccion-corta: clamp(2.75rem, 4.8vw, 4.25rem);
}
@media (max-width: 979px) {
  body[data-pagina="home"] {
    --seccion: 2.75rem;
    --seccion-corta: 2.25rem;
  }
}

/* --- Sede Nuestro Bogotá -------------------------------------------------
   La única foto real de una sede de ReconoCer en la home. Estaba tratada como
   un rectángulo suelto y el texto enterraba el dato que vende: que en ese piso
   está TODO. */

/* A partes iguales. Con 1,15/0,85 el titular caía a tres líneas en la columna
   estrecha mientras la foto se quedaba el ancho. */
@media (min-width: 900px) {
  body[data-pagina="home"] .prueba-sede { grid-template-columns: 1fr 1fr; }
}

/* El resplandor de marca detrás de la foto, el mismo gesto que sostiene a los
   gemelos en el héroe: la saca de «rectángulo pegado» y la ata a la paleta.
   🔴 Hay que soltar el `overflow: hidden` de `.prueba figure` —recortaría el
   halo— y llevar el redondeo a la propia imagen, que es lo único que hay que
   redondear. La leyenda va debajo, fuera de la caja de la foto. */
/* 🔴 `.prueba .foto-sede` y no `.foto-sede` a secas: `.prueba figure` pesa
   (0,1,1) y le ganaba a (0,1,0), así que el recorte seguía puesto. Se notaba
   en dos sitios y ninguno parecía un problema de especificidad: el halo no
   aparecía —lo cortaba el figure— y la esquina redondeada se comía la «S» de
   la leyenda, que va dentro del <figure>. */
/* 🔴 `isolation: isolate`, y no es cosmético: arregla un fogonazo (15-09-2026).

   El halo de debajo va en `z-index: -1`, y un z-index negativo sólo se queda
   «detrás del contenido y delante del fondo» si hay un contexto de
   apilamiento que lo contenga. Este <figure> lleva `data-sube`, que le anima
   `opacity` y `transform`: las dos ABREN un contexto mientras dura el tween, y
   `clearProps` lo cierra al terminar. O sea que el halo cambiaba de CAPA a
   mitad de la entrada, sin cambiar de opacidad:

     durante el tween  -> dentro del contexto -> ENCIMA del velo de `.niebla`
     al terminar       -> sin contexto        -> DEBAJO de ese velo

   Y ese velo no es poca cosa en el tema claro: `--velo` es blanco al 62 %
   (en oscuro es blanco al 2,2 %). Medido, el aporte de color del halo en una
   franja al lado de la foto:

                      asentado   durante el tween   salto
       tema claro        23             64            41    <- el fogonazo
       tema oscuro       28             26             2

   Por eso sólo se veía en claro: un destello magenta al entrar que luego se
   apagaba solo. Con `isolate` el contexto es permanente y el halo vive SIEMPRE
   por delante del velo. Es el mismo arreglo que ya lleva `.cierre::before`.

   🔴 Eso obliga a recalibrar la opacidad: por delante del velo el mismo valor
   rinde casi el triple. Los números nuevos están calibrados para que el
   resultado sea IDÉNTICO al estado asentado de antes, que es el bueno. */
.prueba .foto-sede { overflow: visible; border-radius: 0; isolation: isolate; }
.foto-sede img {
  border-radius: var(--r-l);
  /* 3/2 en vez de 4/3: el encuadre original dejaba techo y suelo muertos
     arriba y abajo del local. El 42 % sube el centro de interés al letrero. */
  aspect-ratio: 3 / 2;
  object-position: center 42%;
}
/* 🔴 SIN `filter: blur()` (15-09-2026), por el mismo fallo de Safari que el
   halo de los gemelos (ver `.heroe-gemelos-int::before`): este <figure> lleva
   `data-sube` y `.prueba` lleva `data-entra`; mientras entran, sus transform
   los convierten en CAPAS COMPUESTAS, y Safari de Mac recorta el derrame de
   un blur en el borde de la capa. Salían cantos rectos durante la entrada.

   Mismo remedio: caja 140 px más grande por lado (dos sigmas del blur de 70)
   y el óvalo difuminado dibujado con una MÁSCARA radial que llega a
   transparente dentro de su propia caja. Los colores del degradado,
   recolocados con la caja real para que cada uno caiga donde caía.

   Calibrado contra la regla vieja reinyectada en el mismo render, en los dos
   temas y a 1440 y 390 (`sede-calibra.js`). En escritorio gana el perfil de
   CANTO difuminado con la opacidad al 80 %: diferencia media 0,23/255 en
   oscuro y 0,13 en claro. De ahí .27 (era .34).

   🔴 Y `isolation: isolate` se queda en `.prueba .foto-sede`: es lo que
   arregló el fogonazo del 15-09 y no tiene nada que ver con esto. Las
   opacidades de antes (.34 / .16) ya estaban calibradas con él puesto. */
.foto-sede::before {
  content: ""; position: absolute; z-index: -1; pointer-events: none;
  inset: calc(10% - 140px) calc(-5% - 140px) calc(16% - 140px) calc(-5% - 140px);
  background: linear-gradient(100deg, var(--cian) 16.8%, #6b57c4 51.3%, var(--magenta) 83.2%);
  -webkit-mask-image: radial-gradient(closest-side, #000 40%, rgba(0, 0, 0, .84) 50%, rgba(0, 0, 0, .5) 66%, rgba(0, 0, 0, .16) 83%, rgba(0, 0, 0, .02) 97%, transparent 100%);
          mask-image: radial-gradient(closest-side, #000 40%, rgba(0, 0, 0, .84) 50%, rgba(0, 0, 0, .5) 66%, rgba(0, 0, 0, .16) 83%, rgba(0, 0, 0, .02) 97%, transparent 100%);
  opacity: .27;
}
/* Sobre claro el halo necesita OTRA GEOMETRÍA, no sólo otra opacidad: un
   resplandor sobre casi blanco sólo puede oscurecer. Ensanchar rinde más que
   subir la opacidad, porque el halo se derrama por fuera del canto en vez de
   acumularse detrás de una foto opaca, que es donde no se ve. De ahí el
   `inset` más ancho, que se queda tal cual.

   🔴 La OPACIDAD baja de .45 a .16, y no es que el halo se haya querido más
   flojo: es que ahora se pinta POR DELANTE del velo de `.niebla` —blanco al
   62 %— en vez de por detrás, y por delante el mismo valor rinde casi el
   triple. Ver el bloque de `isolation: isolate` de más arriba.

   Calibrado barriendo la opacidad y comparando el aporte de color contra el
   estado asentado de antes, en una franja al lado de la foto (objetivo: 23):

       .08 -> 12      .14 -> 20
       .10 -> 15      .16 -> 23   <- clavado
       .12 -> 19      .18 -> 26

   O sea: se ve exactamente igual que antes, pero ya no da el salto. */
/* 15-09-2026, sin blur (ver la regla base): el `inset` ancho de claro se
   conserva con la misma holgura de 140 px, los colores se recolocan para esta
   caja, y la opacidad pasa de .16 a .13 —el mismo 80 % que en oscuro, que es
   el que reproduce el render de antes: diferencia media 0,13/255—. */
:root[data-tema="claro"] .prueba .foto-sede::before {
  opacity: .13;
  inset: calc(6% - 140px) calc(-9% - 140px) calc(12% - 140px) calc(-9% - 140px);
  background: linear-gradient(100deg, var(--cian) 16.0%, #6b57c4 51.4%, var(--magenta) 84.0%);
}

/* En el TELÉFONO, otro perfil de máscara. Pasa lo mismo que con el halo de los
   gemelos: con una foto de 350 px y un blur de 70, el desenfoque se comía la
   forma entera y lo que se veía era una MANCHA gaussiana, no un óvalo con el
   canto suave. Calibrado: gaussiana de dispersión 36 % con la opacidad de
   antes (.34 / .16), diferencia media 0,26/255 en oscuro y 0,20 en claro.

   El corte en 599 px y no en el de la rejilla (899): lo que decide el perfil
   es el TAMAÑO DE LA FOTO frente al blur, no si hay una o dos columnas. Entre
   600 y 899 la foto va a una columna pero mide de 560 a 860 px, como en
   escritorio, y ahí el canto es el que acierta.

   La de claro repite el selector largo: la regla de tema pesa (0,3,1) y sin
   él le ganaría a esta. */
@media (max-width: 599px) {
  .foto-sede::before {
    opacity: .34;
    background: linear-gradient(100deg, var(--cian) 21.9%, #6b57c4 51.1%, var(--magenta) 78.1%);
    -webkit-mask-image: radial-gradient(closest-side, #000 0%, rgba(0, 0, 0, .962) 10%, rgba(0, 0, 0, .857) 20%, rgba(0, 0, 0, .707) 30%, rgba(0, 0, 0, .539) 40%, rgba(0, 0, 0, .381) 50%, rgba(0, 0, 0, .249) 60%, rgba(0, 0, 0, .151) 70%, rgba(0, 0, 0, .085) 80%, rgba(0, 0, 0, .044) 90%, transparent 100%);
            mask-image: radial-gradient(closest-side, #000 0%, rgba(0, 0, 0, .962) 10%, rgba(0, 0, 0, .857) 20%, rgba(0, 0, 0, .707) 30%, rgba(0, 0, 0, .539) 40%, rgba(0, 0, 0, .381) 50%, rgba(0, 0, 0, .249) 60%, rgba(0, 0, 0, .151) 70%, rgba(0, 0, 0, .085) 80%, rgba(0, 0, 0, .044) 90%, transparent 100%);
  }
  :root[data-tema="claro"] .prueba .foto-sede::before {
    opacity: .16;
    background: linear-gradient(100deg, var(--cian) 21.0%, #6b57c4 51.2%, var(--magenta) 79.0%);
  }
}

/* Lo que hay en el piso, en lista. Mismo palote que la comparativa: es el
   mismo gesto de «esto está», no hace falta inventar otro.
   `--cian-claro` y no `--cian`: es el token que ya baja a #009fe3 sobre claro
   para cumplir contraste, así que sirve para los dos temas sin duplicar regla. */
.lista-piso { margin-top: 1.25rem; display: grid; gap: .75rem; }
.lista-piso li {
  position: relative; padding-left: 1.75rem;
  font-size: var(--t-menor); color: var(--texto);
}
/* 🔴 El remate va a tamaño de ENTRADILLA, y no es solo jerarquía: es AA.
   `#e6007e` sobre el fondo oscuro da 4,16:1 y sobre el claro 4,40 — por debajo
   del 4,5 que exige el texto normal. A 17 px en negrita NO cuenta como texto
   grande (el listón son 18,66 px en negrita), así que fallaba en los dos temas.
   Medido por el barrido, no supuesto.

   Por eso todos los demás `.resalte-magenta` del sitio viven en una entradilla:
   ahí el tamaño los convierte en texto grande y les basta 3:1. La regla, para
   que no se vuelva a romper: **magenta de resalte, solo de --t-lead-mayor para
   arriba.**

   Y de paso es lo correcto de jerarquía: esta línea es el beneficio de la
   sección, no una nota al pie. */
/* 🔴 `.prueba-sede .lead` (0,2,0) y no una clase suelta (0,1,0): `.lead` ya
   fija font-size con el mismo peso, y a igual peso manda el ORDEN del archivo.
   Con el descendiente delante gana siempre, se mueva donde se mueva la regla. */
.prueba-sede .lead { font-size: var(--t-lead-mayor); line-height: 1.5; text-wrap: pretty; }

.lista-piso li::before {
  content: ""; position: absolute; left: 0; top: .45em; width: 15px; height: 9px;
  border-left: 2px solid var(--cian-claro); border-bottom: 2px solid var(--cian-claro);
  transform: rotate(-45deg);
}


/* --- El hover del botón con marco --------------------------------------
   🔴 SIN HALO desde el 14-09-2026, a petición del cliente: al pasar el cursor,
   los botones del home ya no se difuminan. Lo que queda es el alzado de 2 px y
   la transición — «la animación de Apple», en sus palabras.

   Con él se va `--halo-boton`, que ya no lo usa nadie.

   Historia corta, por si alguien piensa en devolverlo: el halo nació en cian; se
   pasó a magenta porque sobre el tema claro un cian pálido no se percibía
   (medido con `herramientas/halo-fuerza.js`: pico 24/255 contra 52/255); y el
   13-09-2026 se bajó de 20/60 a 6/18 porque parecía un foco encendido detrás del
   botón. Tres rondas de ajuste para acabar quitándolo: la señal de que el gesto
   no lo necesitaba.

   Lo que NO cambia: el marco degradado sigue siendo la identidad de este botón y
   no satura al pasar el cursor, y no hay cambio de relleno, de letra ni de peso
   —subir el peso reajustaría el ancho del texto y el botón daría un salto bajo
   el cursor—. */


/* --- Escalera de precios por categoría ----------------------------------
   Antes: seis filas de las que CUATRO decían el mismo valor, dibujadas como
   seis tarjetas idénticas que ocupaban 925 px de alto en el teléfono. El dato
   que de verdad importa —que A1, A2 y B1 cuestan lo mismo— no se veía por
   ninguna parte.

   Ahora son cuatro bandas agrupadas por precio, separadas por filos finos en
   vez de por cajas. Menos ruido, menos altura, y la tabla cuenta sola que el
   precio solo se mueve en tres casos.

   Sigue siendo un <table>: esto ES una tabla (categoría · uso · valor) y así
   la anuncia el lector de pantalla. Lo que cambia es cómo se dibuja. Y va en
   envoltura propia (.escalera, no .tabla-envoltura) para que el JS de tarjetas
   no la toque: aquí no hacen falta, la banda ya se apila sola. */

/* El titular del bloque, un escalón de √φ por debajo del de sección:
   44/1,272 = 34,6 en móvil · 56/1,272 = 44 en PC. Con --t-h3 (22 px) el salto
   desde «Tarifas» era de 2:1 y no se leía como titular sino como rótulo. */
body[data-pagina="home"] .bloque-categorias { margin-top: clamp(3rem, 6vw, 5rem); }
body[data-pagina="home"] .bloque-categorias .cabeza-seccion > .h3 {
  font-size: var(--t-h1);   /* el mismo peldano que las otras cabeceras */
}

/* === EL EJE DE LA HOME: qué va centrado y qué no ======================
   Auditadas las nueve secciones a 1440 y a 390. Las CAJAS ya estaban todas
   centradas (izquierda = derecha al píxel); lo que no cuadraba era el
   text-align y la MEDIDA. Tres cosas se salian del sistema:

     1. La nota al pie de Tarifas iba a 1144 px y a la izquierda, debajo de
        una tabla de 864 centrada. Era el bloque de texto más ancho de la
        sección y el único que no se alineaba con nada.
     2. `.sedes-cabeza` medía 928 y las otras cinco cabeceras 768. Con el
        titular ya al mismo tamaño, la caja distinta era lo único que hacía
        que uno rompiera renglon donde los demás no.
     3. De las tres rejillas de tarjetas, las de sede iban centradas y las de
        valoraciones y guías a la izquierda.

   El sistema, ahora escrito:
     - cabecera de sección (titular + entradilla): CENTRADA, misma medida
     - tarjetas de contenido: CENTRADAS, como las de sede
     - 🔴 listas con viñeta: SIEMPRE a la izquierda. Centrar una lista rompe
       su propia alineación —los checks dejan de formar columna— y por eso
       las tarjetas de precio se quedan como están: son listas, no prosa.
     - bloques a dos columnas junto a una foto: a la izquierda (la declaración
       y la sede Nuestro Bogotá). Centrar texto contra una foto lo descuadra.
   ==================================================================== */

/* 54rem = la medida de `.escalera`, la tabla que esta nota anota. */
body[data-pagina="home"] .bloque-categorias .menor {
  text-align: center; max-width: 54rem; margin-inline: auto;
}

/* 45,18em y no 48rem: por debajo de 1441 da 768 px EXACTOS (la letra del
   cuerpo vale 17 px fijos ahí) y por encima crece con ella, igual que el
   resto de cabeceras. Ver el bloque de tokens fluidos. */
body[data-pagina="home"] .sedes-cabeza { max-width: 45.18em; }

/* Topada y centrada. A sangre, a 1160 px de ancho, el ojo tenía que cruzar
   casi un metro de vacío entre la categoría y su valor, y la fila dejaba de
   leerse como una fila. Un poco más ancha que la cabecera (48rem) para que no
   parezcan la misma columna. */
.escalera {
  overflow-x: auto; margin-block: clamp(1.75rem, 3vw, 2.5rem);
  max-width: 54rem; margin-inline: auto;
}
/* min-width 0 mata el mínimo de 460 px de las tablas normales: esta no necesita
   deslizar porque en el teléfono se apila. */
.escalera table { width: 100%; min-width: 0; border-collapse: collapse; }

/* La cabecera, sin la losa gris de th: un filo y un rótulo pequeño bastan. */
.escalera thead th {
  background: none; border-bottom: 1px solid var(--borde-fuerte);
  padding: 0 0 .75rem; font-size: var(--t-mini); font-weight: 500; color: var(--suave);
}
.escalera thead th:last-child { text-align: right; }

.escalera tbody td {
  border-bottom: 1px solid var(--borde); padding: 1.25rem 0;
  vertical-align: baseline; color: var(--texto); font-size: var(--t-menor);
}
.escalera tbody tr:last-child td { border-bottom: 0; }

/* Las dos columnas de dato se ciñen a su contenido; la del medio se queda con
   el resto, que es la única que lleva texto de verdad. */
.escalera td:first-child { width: 1%; white-space: nowrap; padding-right: clamp(1rem, 3vw, 2rem); }
.escalera td:last-child { width: 1%; white-space: nowrap; padding-left: clamp(1rem, 3vw, 2rem); text-align: right; }

.escalera .cat {
  font-size: clamp(1.25rem, 1.9vw, 1.5rem); font-weight: 700;
  letter-spacing: -0.02em; color: var(--tinta);
}
/* El CASO, con el disco de marca: es la traducción de los códigos de la
   izquierda a lo que la gente dice de verdad («carro o moto»). Un escalón por
   debajo de `.cat` para que la columna de códigos siga mandando en su fila.
   El disco se dimensiona solo: va en `em` (ver `.precio-nexo`). */
.escalera .cat-caso {
  font-size: clamp(1.0625rem, 1.5vw, 1.25rem); font-weight: 700;
  letter-spacing: -0.02em; color: var(--tinta); white-space: normal;
}
.escalera .cat-detalle {
  display: block; margin-top: .375rem; font-size: var(--t-mini);
  color: var(--suave); white-space: normal;
}
/* El valor es a lo que se vino, pero son cuatro: un escalón por debajo de la
   cifra del bento (40-56 px) para que no griten los cuatro a la vez. */
.escalera .valor {
  font-size: clamp(1.5rem, 2.5vw, 2rem); font-weight: 700;
  letter-spacing: -0.045em; color: var(--tinta);
}

@media (max-width: 680px) {
  /* La banda se apila: código y precio en la MISMA línea —que es como se
     comparan— y el «para qué sirve» debajo, a todo el ancho. */
  .escalera table, .escalera tbody, .escalera tr, .escalera td { display: block; }
  .escalera thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
  .escalera tbody tr {
    display: grid; grid-template-columns: 1fr auto; gap: .25rem clamp(.75rem, 3vw, 1.25rem);
    align-items: baseline; padding: 1.125rem 0; border-bottom: 1px solid var(--borde);
  }
  .escalera tbody tr:last-child { border-bottom: 0; }
  .escalera tbody td { border: 0; padding: 0; }
  /* 🔴 `white-space: normal` obligatorio. La celda de códigos va `nowrap` en
     escritorio para que no se parta la lista, pero al agrupar las OCHO
     categorías en una sola fila esa línea mide ~290 px y a 390 px empujaba el
     precio fuera de la caja: «$238.000» salía cortado y solo se alcanzaba
     arrastrando dentro de la tabla. Ni `cab-ovf` ni `vis-barrido` lo veían,
     porque `.escalera` tiene su propio `overflow-x` y el desborde no llega a
     la página. */
  .escalera td:first-child { grid-column: 1; grid-row: 1; width: auto; padding-right: 0; white-space: normal; }
  .escalera td:nth-child(2) { grid-column: 1 / -1; grid-row: 2; }
  .escalera td:last-child { grid-column: 2; grid-row: 1; width: auto; padding-left: 0; }
}


@media (hover: hover) and (pointer: fine) {
  body[data-pagina="home"] .btn-letrero:hover,
  body[data-pagina="home"] .oscura .btn-letrero:hover {
    /* El alzado, no el halo, es lo que dice «esto se puede pulsar». 2 px, no 6
       como en las tarjetas: un boton es pequeno y el mismo desplazamiento en una
       pieza pequena se lee como un salto. */
    transform: translateY(-2px);
    /* 🔴 El borde, tapado como ya se tapó el relleno. Estos botones llevan
       TAMBIÉN `.btn-secundario`, y su hover pinta `border-color: var(--tinta)`:
       en claro eso es el azul marino de marca, y salía un aro oscuro por FUERA
       del marco degradado (el ::before va `inset: 0`, o sea dentro del borde).
       Sigue haciendo falta aunque el marco ya no se pinte de magenta: el aro
       oscuro del botón secundario aparece igual. */
    border-color: transparent;
  }
  /* Aqui el marco se repintaba de MAGENTA al pasar el cursor. Fuera desde el
     13-09-2026: el marco degradado ES la identidad de este boton, y cambiarle
     el color justo cuando se le presta atencion borraba lo unico que lo
     distingue. Se queda el degradado de marca, que ya se satura de .88 a 1. */

  /* Y el marco tampoco se satura: se queda EXACTAMENTE igual que en reposo.
     La regla general lo sube de .88 a 1 al pasar el cursor; aqui se anula.
     Lo pidio el cliente asi y tiene razon: si el halo y el alzado ya dicen
     «esto responde», mover ademas el contorno son tres senales para un gesto
     que solo necesita una. Es la leccion de la pagina de Apple —nada grita,
     todo responde— aplicada al boton. */
  body[data-pagina="home"] .btn-letrero:hover::before { opacity: .88; }

  /* 🔴 NINGÚN botón del home se difumina al pasar el cursor (14-09-2026).
     Las sombras venían de tres reglas distintas y ninguna vive aquí:
     `.btn-primario:hover` trae `--brillo-cian`, el tema claro se la cambia por
     una sombra azul, y `.btn-letrero:hover` trae otra vez `--brillo-cian`. En
     vez de ir apagándolas una a una —y dejar el arreglo repartido por tres
     sitios de la hoja— se apagan todas aquí, que es el único bloque que es del
     home y solo del home.

     Especificidad (0,4,1): le gana a `:root[data-tema="claro"] .btn-primario:hover`,
     que es (0,4,0) y era la que más pesaba.

     🔴 `:not(.nav-cta)` porque el «Agendar» de la cabecera NO es un botón del
     home: es el mismo en las 16 páginas. Apagárselo solo aquí dejaría la
     cabecera comportándose distinto según en qué página estés. */
  body[data-pagina="home"] .btn:hover:not(.nav-cta) { box-shadow: none; }
}
.h1 { font-size: var(--t-h1); }
.h2 { font-size: var(--t-h2); }
.h3 { font-size: var(--t-h3); }

.lead { font-size: var(--t-lead); line-height: 1.55; color: var(--suave); text-wrap: pretty; }
.menor { font-size: var(--t-menor); }
.mini { font-size: var(--t-mini); }
.suave { color: var(--suave); }
.centro { text-align: center; }

a { color: var(--cian-claro); text-decoration-thickness: 1px; text-underline-offset: 3px; }
a:hover { color: var(--tinta); }

/* --- Estructura --------------------------------------------------------- */
.envoltura { width: 100%; max-width: var(--ancho); margin-inline: auto; padding-inline: var(--canal); }
.estrecho { max-width: var(--ancho-prosa); margin-inline: auto; }
.seccion { padding-block: var(--seccion); }
.seccion-corta { padding-block: var(--seccion-corta); }
.niebla {
  background: var(--velo);
  border-block: 1px solid var(--capa-1);
}

/* Superficie oscura, con profundidad atmosférica en vez de sombras */
.oscura {
  position: relative;
  background: transparent;
  color: var(--texto);
}
.oscura .lead, .oscura .suave { color: var(--sobre-azul); }
.oscura a { color: var(--cian-claro); }
.oscura a:hover { color: var(--tinta); }

/* El trato que se diseñó para la cabecera de «Tres sedes», ahora para TODA
   cabecera de sección: centrada, y la entradilla más grande y en color de
   texto en vez del gris de lo secundario.

   Se replica el TRATO, no la escala: `.sedes-cabeza h2` sigue en --t-h1
   porque preside las tarjetas más grandes de la home, y el resto se queda en
   --t-h2. El degradado lo pone `.letrero-texto` en el HTML, para que cada
   titular diga lo que es y para heredar sus dos respaldos (@supports y
   forced-colors) sin duplicar una sola regla.

   🔴 La marca es `.cabeza-seccion`, que en este sitio ya significa «esto
   encabeza una sección entera». Los h2 que titulan una COLUMNA —los datos de
   una sede, el formulario de contacto— o un párrafo de artículo NO la llevan
   y siguen alineados a la izquierda: un titular centrado sobre un formulario
   alineado a la izquierda se lee como un fallo de maquetado, no como una
   decisión.

   `.centrada` ya no existe: sobrevivía solo por su `.btn-grupo`, y ninguna de
   las tres cabeceras que la llevaban tenía botones dentro. Era una clase que
   no hacía absolutamente nada en las tres páginas donde estaba escrita. */
.cabeza-seccion { max-width: 48rem; margin-inline: auto; text-align: center; }
.cabeza-seccion .lead {
  margin: 1.125rem auto 0; max-width: 40rem;
  font-size: var(--t-lead-mayor); line-height: 1.5;
  color: var(--texto); text-wrap: balance;
}
/* 🔴 QUINTA vez que dos reglas del mismo peso se resuelven por orden en este
   archivo, y la primera que se ve a simple vista.

   Esta regla es (0,1,0) y pone el aire entre una cabecera y su contenido. El
   `margin: 0` con el que `.razones`, `.amano`, `.elige` y `.llegar` se quitan
   los márgenes de fábrica de `<ul>` pesa EXACTAMENTE lo mismo y vive más
   abajo en la hoja: ganaba, y el hueco quedaba en **0 px**. El titular y la
   primera raya se tocaban, y las tres rayas se leían como una sola banda
   cruzando la página.

   Medido con `ritmo.js` en /agendar («Ten esto a mano») y en las tres páginas
   de sede («Por qué la gente elige esta sede» y «¿Te queda mejor otra?»).

   Se arregla acotando —que es la costumbre de esta hoja— y no subiéndole la
   especificidad a la general: la lista de abajo dice QUÉ componentes se
   quitan el margen, así que quien añada uno nuevo sabe que tiene que entrar
   ahí. El valor sale del token para que no haya dos clamps que mantener. */
.cabeza-seccion + * { margin-top: var(--aire-cabeza); }
.cabeza-seccion + .razones,
.cabeza-seccion + .amano,
.cabeza-seccion + .elige,
.cabeza-seccion + .igual,
.cabeza-seccion + .respalda,
.cabeza-seccion + .proximo,
.cabeza-seccion + .oficios,
.cabeza-seccion + .llegar { margin-top: var(--aire-cabeza); }

/* --- Cabecera de sección con la entradilla A LO LARGO ---------------------
   La cabecera normal le pone a la entradilla una columna de 40 rem dentro de
   una cabecera de 48: una medida corta, que es lo correcto cuando la frase da
   para dos o tres líneas. Cuando la frase es UNA y cabe entera, esa columna la
   parte en dos renglones cortos y centrados, y el resultado se lee como un
   hueco en medio de la página en vez de como una entradilla.

   Aquí se le quita el tope a la entradilla y se ensancha la cabecera lo justo
   para que la frase entre en una línea hasta en la pantalla más grande, que es
   donde más crece la letra (28 px por encima de 1441). Medido, no estimado.

   No es el comportamiento por defecto a propósito: solo se pone donde la frase
   cabe. Una entradilla larga a 1000 px de ancho sería una línea de lectura
   imposible — el límite sano son 65-75 caracteres, y esta tiene 66. */
.cabeza-seccion.cabeza-ancha { max-width: 64rem; }
.cabeza-seccion.cabeza-ancha .lead { max-width: none; }

/* --- Cabecera de bloque: la de sección, pero SIN centrar ------------------
   `.cabeza-seccion` centra, y eso solo funciona cuando el bloque que anuncia
   también está centrado. En una columna de prosa (`.estrecho`) o en una de las
   dos mitades de una ficha, un titular centrado sobre un párrafo alineado a la
   izquierda se lee como un error de maquetado. Esta es la misma cabecera, a
   sangre.

   🔴 Lo que de verdad hace falta aquí es la ENTRADILLA GRANDE, y no es
   estética. La regla de la casa dice: «magenta de resalte, solo de
   --t-lead-mayor para arriba». Con un `.lead` normal, en una columna estrecha
   la entradilla cae a 17 px y ahí el magenta deja de contar como texto grande:
   el listón sube de 3:1 a 4,5:1 y da 4,33. Medido con `barrido-contraste` en
   /contacto, y es exactamente por eso que existe esta clase y no un `.lead` a
   secas. */
.cabeza-bloque .lead {
  margin-top: 1.125rem;
  font-size: var(--t-lead-mayor); line-height: 1.5;
  color: var(--texto); text-wrap: pretty;
}
.cabeza-bloque + * { margin-top: clamp(1.75rem, 3.2vw, 2.75rem); }


/* --- Botones ------------------------------------------------------------ */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
  padding: 1rem 1.875rem; border: 1px solid transparent; border-radius: 999px;
  font-size: var(--t-cuerpo); font-weight: 500; line-height: 1.2;
  text-decoration: none; cursor: pointer;
  transition: transform 160ms var(--sal), background-color 220ms ease, border-color 220ms ease, color 220ms ease, box-shadow 220ms ease;
}
.btn:active { transform: scale(.97); }

.btn-primario { background: var(--cian); color: var(--azul-900); font-weight: 700; }
.btn-secundario { background: transparent; color: var(--tinta); border-color: var(--borde-fuerte); }
/* El subrayado aparece SOLO al pasar el cursor. En reposo el enlace ya se
   distingue por el color y por la flecha; subrayado fijo, tres veces seguidas
   en la tira de sedes, ensucia la lectura. Ojo: quien lo subrayaba no era esta
   regla sino el navegador (todo <a href> viene subrayado de fábrica), y por eso
   `.btn .btn-texto` —que hereda el `text-decoration: none` de `.btn`— se veía
   limpio y el suelto no. Ahora los dos se comportan igual. */
.btn-texto { background: none; border: 0; padding: .5rem 0; color: var(--cian-claro); font-weight: 500; text-decoration: none; }

/* Sobre oscuro el cian del manual sí cumple contraste (4.9:1) */
.oscura .btn-primario { background: var(--cian); color: var(--azul-900); font-weight: 700; }
.oscura .btn-texto { color: var(--cian); }

@media (hover: hover) and (pointer: fine) {
  .btn-primario:hover { background: var(--cian-claro); box-shadow: var(--brillo-cian); }
  .btn-secundario:hover { border-color: var(--tinta); background: var(--capa-1); color: var(--tinta); }
  .btn-texto:hover { color: var(--tinta); text-decoration: underline; }
}

/* Botón con el marco del letrero. El relleno queda TRANSPARENTE de verdad
   —dos máscaras que se restan— en vez de pintado del color del fondo: el héroe
   lleva los focos de luz detrás y un relleno sólido se vería como un parche
   rectangular. Sin soporte de máscara se queda con el borde normal, que es
   exactamente el botón secundario de siempre. */
.btn-letrero {
  position: relative; background: transparent;
  color: var(--tinta); border-color: var(--borde-fuerte);
}
/* El color lo pone el MARCO; la etiqueta va neutra. Sin esto `.oscura a`
   (0,2,0) le gana y la pinta de cian: dos cianes compitiendo en el mismo
   botón y ninguno mandando. */
.oscura .btn-letrero { color: var(--tinta); }
@supports ((mask-composite: exclude) or (-webkit-mask-composite: xor)) {
  .btn-letrero { border-color: transparent; }
  .btn-letrero::before {
    content: ""; position: absolute; inset: 0; border-radius: inherit;
    padding: 2px; background: var(--letrero-texto); opacity: .88;
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
            mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
            mask-composite: exclude;
    pointer-events: none;
    transition: opacity 220ms ease;
  }
}
/* Al señalarlo NO se rellena de nada: el marco se enciende y aparece un halo
   por debajo. Nada más.

   Se probaron dos rellenos y los dos se descartaron —un violeta que se salía de
   la paleta y un cian hondo que, aun cumpliendo todos los contrastes, convertía
   un botón secundario en una pastilla maciza que competía con el primario que
   tiene al lado. El marco degradado ES la identidad de este botón; taparlo con
   color justo cuando se le presta atención es borrar lo único que lo distingue.

   La señal se reparte entre tres cosas pequeñas en vez de una grande:
     · el marco pasa de .88 a 1 (se satura),
     · aparece el halo de marca por debajo,
     · el halo tiene el color del tono cian del propio marco.

   Ni relleno, ni cambio de letra, ni cambio de peso: subir el peso reajustaría
   el ancho del texto y el botón daría un salto bajo el cursor. */
@media (hover: hover) and (pointer: fine) {
  .oscura .btn-letrero:hover,
  .btn-letrero:hover {
    /* 🔴 `transparent` explícito. Los cinco botones de tarjeta llevan TAMBIÉN
       `.btn-secundario`, cuyo hover pinta un lavado de --capa-1; pesa lo mismo
       que esta regla (0,2,0) y sin decir nada aquí se colaba. Resultado: cinco
       botones con un tinte y dos sin él, una incoherencia que en una captura no
       se ve pero al pasar el ratón de uno a otro sí. */
    background: transparent;
    box-shadow: var(--brillo-cian);
  }
  .btn-letrero:hover::before { opacity: 1; }
}

.btn-grupo { display: flex; flex-wrap: wrap; gap: .875rem; align-items: center; }


.flecha { transition: transform 200ms var(--sal); }
@media (hover: hover) and (pointer: fine) {
  .btn:hover .flecha, a:hover > .flecha, a:hover .flecha { transform: translateX(4px); }
}

/* --- Navegación: píldora flotante de vidrio ----------------------------- */
/* 🔴 El `position` NO se declara aquí: lo pone el bloque «La píldora flota
   SOBRE el contenido» más abajo en la hoja, que la fija (`fixed`) y a cambio
   reserva su altura en la primera sección de cada página. Aquí decía
   `position: sticky` y no servía de nada —la de abajo, a igual peso y más
   tarde, ganaba siempre—, pero cualquiera que leyese esta regla se iba
   creyendo que la barra es pegajosa, que es otra cosa. */
.nav {
  z-index: var(--z-sticky);
  padding-top: .75rem; padding-bottom: .75rem;
  padding-top: max(.75rem, env(safe-area-inset-top));
  transition: padding 300ms var(--sal);
}
/* Con la hoja abierta, la cabecera entera sube por encima del resto de la
   página. Sin esto la hoja (z-sheet) tapaba la píldora —y con ella el único
   botón que la cierra—, y en un teléfono no hay tecla Escape: el menú se
   convertía en una trampa de la que solo se salía navegando a otra página. */
.nav:has(.nav-hoja[data-abierta="si"]) { z-index: var(--z-sheet-sobre); }
.nav-pildora {
  display: flex; align-items: center; gap: 1.5rem;
  padding: .625rem .75rem .625rem 1.25rem;
  border-radius: 999px;
  border: 1px solid var(--capa-2);
  background: var(--nav-vidrio);
  transition: background-color 300ms ease, border-color 300ms ease, box-shadow 300ms ease;
}
@supports (backdrop-filter: blur(1px)) {
  .nav-pildora { backdrop-filter: saturate(180%) blur(20px); -webkit-backdrop-filter: saturate(180%) blur(20px); }
}
.nav[data-desplazado="si"] .nav-pildora {
  background: var(--nav-vidrio-fijo);
  box-shadow: var(--nav-sombra);
}

.nav-marca { display: inline-flex; align-items: center; margin-right: auto; text-decoration: none; }
.nav-marca img { height: 30px; width: auto; }

.nav-enlaces { display: none; gap: .125rem; align-items: center; }
.nav-enlaces a {
  padding: .5rem .8125rem; border-radius: 999px; text-decoration: none;
  color: var(--sobre-azul); font-size: var(--t-menor);
  transition: color 180ms ease, background-color 180ms ease;
}
.nav-enlaces a[aria-current="page"] { color: var(--tinta); }
@media (hover: hover) and (pointer: fine) {
  .nav-enlaces a:hover { color: var(--tinta); background: var(--capa-1); }
}
.nav .btn { padding: .625rem 1.375rem; font-size: var(--t-menor); }
.nav-cta { display: none; background: var(--cian); color: var(--azul-900); font-weight: 700; }
@media (hover: hover) and (pointer: fine) { .nav-cta:hover { background: var(--cian-claro); } }

.nav-boton {
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; background: none; border: 0; border-radius: 999px;
  cursor: pointer; color: var(--tinta);
}
.nav-boton span, .nav-boton span::before, .nav-boton span::after {
  content: ""; display: block; width: 19px; height: 1.5px; border-radius: 2px;
  background: currentColor; transition: transform 280ms var(--sal), opacity 160ms ease;
}
.nav-boton span::before { transform: translateY(-6px); }
.nav-boton span::after { transform: translateY(4.5px); }
.nav-boton[aria-expanded="true"] span { background: transparent; }
.nav-boton[aria-expanded="true"] span::before { transform: rotate(45deg); }
.nav-boton[aria-expanded="true"] span::after { transform: rotate(-45deg) translateY(0); }

/* La píldora se queda por encima de la hoja: dentro de .nav la envoltura pinta
   después. Es lo que devuelve el logo y la X mientras el menú está abierto. */
.nav > .envoltura { position: relative; z-index: 2; }

.nav-hoja {
  position: fixed; inset: 0; z-index: 1;
  background: var(--fondo);
  padding: calc(6rem + env(safe-area-inset-top)) var(--canal)
           calc(2.5rem + env(safe-area-inset-bottom));
  overflow-y: auto;
  display: flex; flex-direction: column;
  opacity: 0; visibility: hidden; transform: translateY(-10px);
  transition: opacity 240ms var(--sal), transform 280ms var(--sal), visibility 0s linear 280ms;
}
.nav-hoja[data-abierta="si"] { opacity: 1; visibility: visible; transform: none; transition-delay: 0s; }
.nav-hoja a {
  display: flex; align-items: center; min-height: 56px; padding: .75rem 0;
  border-bottom: 1px solid var(--borde);
  color: var(--tinta); text-decoration: none; font-size: 1.375rem; font-weight: 500; letter-spacing: -0.02em;
}
/* Agendar es la razón de ser del sitio: aquí era el objetivo más pequeño de
   toda la hoja (40 px frente a los 73 de cada enlace secundario). Ahora manda,
   y se queda pegado abajo, en la zona del pulgar. */
.nav-hoja .btn {
  width: 100%; min-height: 56px; margin-top: auto; padding-top: 1rem; padding-bottom: 1rem;
  font-size: 1.0625rem;
  background: var(--cian); color: var(--azul-900);
  border-bottom: 0;
}

@media (min-width: 980px) {
  .nav-enlaces { display: flex; }
  .nav-cta { display: inline-flex; }
  .nav-boton, .nav-hoja { display: none; }
}

/* --- HÉROE: asimetría artística -----------------------------------------
   El `padding-top` va en el bloque de la píldora flotante, más abajo: es él
   quien decide cuánto hay que reservar para que el titular no nazca detrás de
   la barra fija. Aquí había otro valor que no llegaba a aplicarse nunca. */
.heroe { position: relative; padding-bottom: 0; }
.heroe-rejilla { display: grid; gap: clamp(2.5rem, 5vw, 4rem); align-items: center; }
@media (min-width: 1000px) {
  .heroe-rejilla { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  /* El héroe ocupa la PANTALLA ENTERA: así el titular de la sección siguiente
     no asoma por abajo al cargar y aparece al bajar, que es lo que pidió el
     cliente (17-09-2026). svh y no vh: en el móvil vh cuenta la barra del
     navegador que todavía no se ha escondido y deja la sección larga de más.
     El contenido va centrado en esa altura, y la foto sigue anclada abajo. */
  .heroe {
    min-height: 100svh; display: grid; align-content: stretch;
    /* Arranca justo debajo de la píldora de navegación (88 px): centrar el
       contenido en la pantalla entera dejaba un claro grande entre la barra y
       el titular. Ahora la rejilla ocupa todo el alto: el texto se centra en
       ella y la foto se apoya en el borde de abajo. */
    padding-top: 88px; padding-bottom: 0;
  }
  .heroe-rejilla { min-height: 100%; }
  /* La columna de texto arranca ARRIBA, no centrada en el alto de la pantalla:
     centrada dejaba ~103 px de claro entre la píldora de navegación y el
     titular, y era justo lo que sobraba. Un respiro corto y a leer. La foto
     sigue apoyada abajo, así que la composición sigue llena de lado a lado. */
  .heroe-rejilla > :first-child { align-self: start; }
  /* El claro que quedaba NO era relleno: era el interlineado propio del
     titular, que reserva espacio por encima de las mayúsculas. Se recorta
     ópticamente para que el bloque empiece donde se ve que empieza. */
  .heroe .display { margin-top: -.14em; }
}

.heroe .display { max-width: 13ch; }
/* Más aire entre el titular y el bloque de abajo (17-09-2026): el titular
   ocupa cuatro líneas y la entradilla arrancaba pegada a la última. Bajar el
   bloque deja respirar al titular y, con la rejilla centrada, sube la
   sensación de espacio de toda la sección. */
.heroe .lead { margin-top: clamp(1.75rem, 4.2vw, 4.25rem); max-width: 42ch; }
/* En portátiles bajos (≤760 px de alto) el aire extra empujaba la línea de
   «Tres sedes · Tarifa» fuera de la primera pantalla. Ahí se recoge. */
@media (min-width: 1000px) and (max-height: 760px) {
  .heroe .lead { margin-top: 1.75rem; }
  .heroe .btn-grupo { margin-top: 1.75rem; }
}
.heroe .btn-grupo { margin-top: 2.5rem; }

/* Diego y Rodrigo, recortados sin fondo. Van anclados ABAJO, no centrados:
   una figura recortada flotando en el aire se lee como un pegote; apoyada en la
   línea de base se lee como si estuviera ahí. */
.heroe-gemelos { align-self: end; }
/* La capa interna es la que se desvanece al bajar, y el resplandor va con ella:
   si el letrero se quedara, al irse los gemelos quedaría un halo flotando. */
.heroe-gemelos-int { position: relative; }
.heroe-gemelos img {
  /* Un punto más grandes de lo que da la columna: crecen hacia la IZQUIERDA,
     hacia el hueco entre las dos columnas, no hacia el borde de la pantalla. */
  display: block; width: 112%; max-width: none; margin-left: -12%; height: auto;
  /* A partir de 1000 px crecen otro punto: el cliente los quiere más
     protagonistas. Crecen hacia la IZQUIERDA, al hueco entre columnas, nunca
     hacia el borde de la pantalla —ahí no hay sitio y saldría barra
     horizontal—. El alto del héroe lo marca esta foto, así que la sección
     entera baja con ella. */
  /* El corte de cintura se difumina AQUÍ, no en el archivo: un canto duro
     horizontal se lee como una pegatina, y así se ve como si salieran del
     fondo. Se hace en CSS para poder moverlo sin rehacer el PNG y para que el
     mismo recorte sirva en otros sitios con otro fondo. */
  -webkit-mask-image: linear-gradient(to bottom, #000 84%, transparent 99%);
          mask-image: linear-gradient(to bottom, #000 84%, transparent 99%);
}
/* 🔴 Va DESPUÉS de la regla de arriba, no dentro del @media de la rejilla: allí
   quedaba antes que la base y la base se lo comía (misma especificidad, gana la
   última). De 112 % a 132 % desde 1000 px. */
@media (min-width: 1000px) {
  .heroe-gemelos img { width: 132%; margin-left: -32%; }
  /* La foto arranca a la MISMA altura que el texto (17-09-2026). Anclada abajo
     quedaba un escalón: el titular empezaba arriba y las caras medio cuerpo más
     abajo. 🔴 Va aquí, DESPUÉS de `.heroe-gemelos { align-self: end }`: en el
     bloque de la rejilla queda antes y la base se la come. */
  .heroe-gemelos { align-self: start; }
}

/* El letrero por DETRÁS de los hombros, no envolviéndolos enteros: es el mismo
   resplandor que sostenía la foto de la fachada, recolocado a su altura.

   🔴 SIN `filter: blur()`, a propósito (15-09-2026). En Safari de Mac el halo
   salía con CANTOS RECTOS arriba y a la derecha, como cortado por una caja.

   Causa: GSAP deja al <figure> del héroe `transform: translate(0,0)` en línea
   para siempre —la entrada es un `from` sin `clearProps`— y eso lo convierte
   en una CAPA COMPUESTA. WebKit calcula el tamaño de esa capa con las cajas
   de sus hijos, pero NO suma lo que un `blur()` derrama por fuera de la suya:
   el desenfoque se pinta y se recorta en el borde de la capa. Chrome sí lo
   suma, y por eso ninguna captura hecha en Chrome lo enseñaba.

   Quitar el `transform` no bastaba: al bajar, el scrub mueve la capa interna
   y el mismo recorte volvería a mitad de scroll. Lo robusto es que no haya
   nada que derramar. El óvalo difuminado se dibuja con una MÁSCARA radial que
   llega a transparente DENTRO de su propia caja, y la caja crece 140 px por
   cada lado —dos sigmas de aquel blur(70px)— para que quepa la cola del
   difuminado. Una caja que desborda sí la cuenta WebKit; un filtro, no.

   Los pasos de la máscara reproducen el perfil de un desenfoque gaussiano
   sobre el canto del óvalo (0,84 a una sigma dentro, 0,5 en el canto, 0,16 a
   una sigma fuera, casi nada a dos). Y el degradado lleva sus colores
   recolocados en 14,7 % y 85,3 %: con la caja más ancha, el `--letrero` de
   siempre estiraría el cian y el magenta hacia fuera. Así cada color cae donde
   caía. Comparado píxel a píxel contra el render de antes, en los dos temas.

   De regalo: un blur de 70 px es de lo más caro que se le puede pedir a Safari
   al hacer scroll, y una máscara es casi gratis. */
.heroe-gemelos-int::before {
  content: ""; position: absolute; z-index: -1; pointer-events: none;
  inset: calc(4% - 140px) calc(-8% - 140px) calc(14% - 140px) calc(-8% - 140px);
  background: linear-gradient(100deg, var(--cian) 14.7%, #6b57c4 51.4%, var(--magenta) 85.3%);
  -webkit-mask-image: radial-gradient(closest-side, #000 40%, rgba(0, 0, 0, .84) 50%, rgba(0, 0, 0, .5) 66%, rgba(0, 0, 0, .16) 83%, rgba(0, 0, 0, .02) 97%, transparent 100%);
          mask-image: radial-gradient(closest-side, #000 40%, rgba(0, 0, 0, .84) 50%, rgba(0, 0, 0, .5) 66%, rgba(0, 0, 0, .16) 83%, rgba(0, 0, 0, .02) 97%, transparent 100%);
  opacity: .42;
}


@media (min-width: 1000px) {
  .heroe-gemelos { margin-right: calc(var(--canal) * -1 - 2rem); }
  /* Ese margen negativo sangra la foto hacia el borde. Por encima de 1440 la
     envoltura ya está topada y centrada, así que hay holgura de sobra; por
     debajo pega con los bordes y la sangría SE SALE DE LA PANTALLA: entre 1000
     y 1366 la página llegaba a desplazarse de lado (74 px a 1100). Se recorta
     en la sección, que ocupa todo el ancho, para conservar la sangría tal cual.
     Descartado quitarle los 2rem al margen: arregla el desborde pero encoge la
     sangría también a 1440+, donde no había ningún problema.
     'clip' y no 'hidden': hidden en un eje fuerza 'auto' en el otro y convierte
     la sección en contenedor de scroll; clip no crea contexto de desplazamiento. */
}
/* 🔴 El recorte sale de ese `@media` y vale en TODOS los anchos. En el teléfono
   el héroe lleva ahora el recorte con su resplandor detrás, y cualquier halo
   desbordado por los lados —o un futuro retoque del ancho de la figura— haría
   el documento más ancho que la pantalla. Eso no se ve en Chrome de escritorio
   (lo recorta el navegador) pero en un iPhone deja arrastrar la página entera.
   Una red, no una decoración. */
section[data-heroe] { overflow-x: clip; }
.heroe-pie {
  margin-top: 1rem; font-size: var(--t-mini); color: var(--sobre-azul);
  display: flex; align-items: center; gap: .5rem;
}
.heroe-pie::before { content: ""; width: 22px; height: 2px; background: var(--letrero); flex-shrink: 0; }


/* --- Cifras --------------------------------------------------------------
   Cada celda se centra sobre sí misma: con los rótulos de largo tan distinto
   ("sedes en Bogotá" contra "de vigencia del certificado"), alinear a la
   izquierda hacía que la fila se viera torcida. Centradas, las cuatro se leen
   como una sola unidad. En el DOM va el rótulo primero y el número después
   —que es el orden válido de un <dl>— y el CSS sube el número. */
.cifras {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: clamp(2rem, 4vw, 2.75rem) 0;
  text-align: center;
}
@media (min-width: 860px) {
  .cifras { grid-template-columns: repeat(4, 1fr); }
  /* Separadores: solo cuando las cuatro caben en una fila. Se desvanecen en
     los extremos para que no corten la sección de arriba abajo. */
  .cifras > div + div { position: relative; }
  .cifras > div + div::before {
    content: ""; position: absolute; left: 0; top: 10%; bottom: 10%; width: 1px;
    background: linear-gradient(to bottom, transparent, var(--capa-2), transparent);
  }
}
.cifras > div {
  display: flex; flex-direction: column; align-items: center; gap: .5rem;
  padding-inline: clamp(.75rem, 2vw, 1.5rem);
}
.cifras dd {
  order: -1;
  display: flex; align-items: baseline; justify-content: center; gap: .25rem;
  font-size: clamp(2.25rem, 4vw, 3.25rem); font-weight: 700;
  letter-spacing: -0.04em; line-height: 1; color: var(--tinta);
  /* El ancho no baila mientras el contador sube de 0 a 180 */
  font-variant-numeric: tabular-nums;
}
.cifras dd small {
  font-size: .42em; font-weight: 500; letter-spacing: -0.01em;
  color: var(--sobre-azul);
}
.cifras dt {
  font-size: var(--t-menor); color: var(--sobre-azul);
  max-width: 17ch; text-wrap: balance;
}

/* --- Sellos de acreditación --------------------------------------------
   El símbolo ONAC es VERDE y choca con la paleta. Se deja chocar: espacio
   propio, neutro, sin filtros. Nunca recolorear ni recortar. */
.acredita { padding-block: clamp(2.5rem, 5vw, 3.5rem); }

/* --- El rótulo, centrado entre las cifras y los logos --------------------
   En la home esta sección va detrás de un bloque que ya aporta su propio aire,
   y el relleno superior de aquí se SUMABA al de arriba: medido, 152 px por
   encima del rótulo contra 28 por debajo. El texto quedaba pegado a los logos
   con un vacío enorme encima.

   Se quita el relleno de arriba —el aire ya lo pone la sección anterior— y se
   le pasa al hueco de DEBAJO. Los logos no se mueven ni un píxel: la altura de
   la sección es la misma, lo único que cambia es dónde cae el rótulo dentro.

   No queda exactamente a la mitad, y es a propósito: queda un poco más cerca de
   los logos que de las cifras, porque el rótulo es la etiqueta DE los logos.
   Centrarlo del todo lo separaría de lo que nombra.

   `.oscura + .acredita` acota esto a la home. En /transparencia la sección va
   bajo la cabecera de página, el hueco de arriba son 56 px y no hay nada que
   arreglar; quitarle ahí el relleno la pegaría al titular. */
.oscura + .acredita { padding-top: 0; }
.oscura + .acredita .acredita-fila { margin-top: clamp(2.25rem, 6.5vw, 5.25rem); }

/* --- La costura de abajo -------------------------------------------------
   Esta sección NO pinta fondo: lo que se ve es el campo de luz de la página.
   En el teléfono, justo debajo empieza una `.niebla`, que sí pinta un velo
   blanco y traía un filo de 1 px. El corte caía a un palmo de los logos y se
   leía como una costura entre dos bloques pegados.

   Solo pasa ahí: en escritorio, y en /transparencia, lo que sigue a los sellos
   es una sección transparente y no hay ningún borde que disimular.

   Se arregla por los dos lados: los sellos respiran más por abajo, y el velo de
   la sección siguiente ENTRA con un degradado en vez de aparecer de golpe. */
@media (max-width: 1023px) {
  .acredita { padding-bottom: clamp(4.5rem, 12vw, 7rem); }
}
.acredita + .niebla {
  /* 🔴 Se quita el ANCHO del borde, no solo su color. Un borde transparente
     sigue ocupando su píxel, y como el fondo se pinta desde la caja del borde,
     ahí quedaba una fila más clara: medida, una raya de 1 px con 6/255 de
     diferencia. Casi invisible, pero era justo la costura que se quería quitar.
     Medido antes y después: el salto en el límite pasa de 0,102 a 0,010 en
     claro y de 0,013 a 0,0004 en oscuro, y deja de estar en el borde. */
  border-top-width: 0;
  /* 🔴 Se parte de blanco con alfa 0, NO de `transparent`. `transparent` es
     negro con alfa cero, y al interpolar hacia un blanco translúcido ensucia el
     degradado de gris por el medio. Los dos temas usan blanco en `--velo` (con
     .022 y .62 de alfa), así que este arranque sirve para los dos. */
  background: linear-gradient(to bottom,
    rgba(255, 255, 255, 0) 0,
    var(--velo) clamp(5rem, 14vw, 9rem));
}
.acredita p { text-align: center; font-size: var(--t-mini); color: var(--suave); }
/* La VENTANA. En escritorio no hace nada; en el teléfono recorta el desfile.
   Es un nivel aparte de la tira a propósito: `data-grupo` vive aquí y el
   escalonado de GSAP le escribe un `y` en línea, o sea un TRANSFORM. El
   desfile también es un transform. En el mismo elemento se pisarían —el mismo
   fallo de la FLIP que ya costó una tarde—, así que GSAP mueve la ventana y el
   CSS mueve la tira, y ninguno se entera del otro. */
.acredita-fila { margin-top: 1.75rem; }

/* La TIRA: lo que se ve, y en el teléfono lo que se mueve. En estrecho se
   parte en varias filas y no lleva separadores: una raya justo donde la fila
   salta se lee como un error, y por eso las cifras tampoco los ponen hasta que
   las cuatro caben en una sola. */
.acredita-tira {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
  gap: clamp(1.75rem, 4vw, 3.5rem);
}
.acredita-tira .sello { display: flex; align-items: center; justify-content: center; }

/* La segunda vuelta solo existe cuando hay desfile. Sin esto, en escritorio
   saldrían diez sellos en la rejilla. */
/* 🔴 `.acredita-tira .acredita-copia`, no `.acredita-copia` a secas: la regla de
   arriba, `.acredita-tira .sello`, es (0,2,0) y le ganaba a un (0,1,0). Las
   copias salían en ESCRITORIO —diez sellos en la rejilla y nueve separadores— y
   también con menos movimiento pedido. Dos selectores de una clase parecen
   equivalentes hasta que uno lleva un ancestro delante. */
.acredita-tira .acredita-copia { display: none; }

/* `max-width: 100%` no es decoración: con la altura fija y el ancho automático,
   un sello ancho (el de la ANSV mide 3,7:1) se saldría de su celda cuando son
   seis en vez de cinco. Con el tope, encoge conservando la proporción.

   Y la altura ESCALA con el ancho: subirlos de 42 a 52 px fijos multiplicaba
   las filas en el teléfono —a 390 px la tira pasaba de 192 a 384 px de alto—
   porque cada logo dejaba de caber de dos en dos. */
.acredita-fila img {
  height: clamp(42px, 5.1vw, 52px);
  width: auto; max-width: 100%; object-fit: contain;
}
/* El de ONAC va más alto porque su logotipo trae caja verde con aire propio:
   a la misma altura de caja, la marca DENTRO se ve más pequeña que las demás. */
.acredita-fila img.sello-onac { height: clamp(52px, 6.25vw, 64px); }

@media (min-width: 1024px) {
  /* Cuando caben todos en una fila, el mismo separador que las cifras: 1 px que
     se desvanece por los dos extremos para no cortar la sección de arriba abajo.

     `grid-auto-flow: column` con `grid-auto-columns: 1fr` y NO `repeat(5, 1fr)`,
     porque la home lleva cinco sellos y /transparencia seis. Una cuenta fija
     habría dejado el sexto en una segunda fila él solo. */
  .acredita-tira {
    display: grid; grid-auto-flow: column; grid-auto-columns: 1fr;
    gap: 0;
  }
  .acredita-tira .sello {
    position: relative; min-height: 72px;
    padding-inline: clamp(1rem, 2.4vw, 2.25rem);
  }
  .acredita-tira .sello + .sello::before {
    content: ""; position: absolute; left: 0; top: 8%; bottom: 8%; width: 1px;
    background: linear-gradient(to bottom, transparent, var(--capa-2), transparent);
  }
}

/* --- El desfile ----------------------------------------------------------
   Va detrás de `prefers-reduced-motion: no-preference`, no detrás de un
   `animation: none` que lo desharía después: así, para quien pide menos
   movimiento, el desfile NO EXISTE —ni la tira sin cortes, ni las copias, ni el
   recorte— y queda la rejilla con separadores de siempre. Una marcha atrás
   siempre se deja algo; no entrar no se deja nada. */
@media (prefers-reduced-motion: no-preference) {
  .acredita-fila {
    overflow: hidden;
    /* Los extremos se difuminan: un sello cortado a hachazo contra el borde se
       lee como un fallo de maquetado, no como algo que entra y sale. */
    -webkit-mask-image: linear-gradient(to right, transparent, #000 8%, #000 92%, transparent);
            mask-image: linear-gradient(to right, transparent, #000 8%, #000 92%, transparent);
  }
  /* 🔴 `display: flex` explícito. Por encima de 1024 px la regla de arriba deja
     la tira en `grid`, y `flex-wrap` sobre una rejilla no hace nada: la tira se
     quedaría quieta y repartida en columnas. */
  .acredita-tira {
    display: flex; flex-wrap: nowrap; justify-content: flex-start;
    width: max-content; gap: 0;
    animation: acredita-desfile 20s linear infinite;
    /* La tira pide capa propia: sin esto, cada fotograma vuelve a rasterizar
       todas las imágenes Y la máscara de la ventana. */
    will-change: transform;
  }
  /* 🔴 El hueco va DENTRO de cada celda y el contenedor lleva `gap: 0`. Con
     `gap`, la tira mide N×contenido + (N-1) huecos, y el salto de -50 % cae
     medio hueco antes de la copia: en cada vuelta se vería un tirón. Con el
     relleno por celda la tira es una repetición exacta. */
  .acredita-tira .sello { flex: 0 0 auto; padding-inline: clamp(.75rem, 3vw, 1.25rem); }
  .acredita-tira .acredita-copia { display: flex; }

  /* En el desfile los sellos crecen, y el motivo es que aquí la razón que los
     tenía pequeños DESAPARECE: en la fila repartida, un logo más ancho obligaba
     a una fila más y la tira se estiraba hacia abajo. En una tira que no se
     parte, lo ancho solo ocupa recorrido. */
  .acredita-fila .acredita-tira img { height: 52px; }
  .acredita-fila .acredita-tira img.sello-onac { height: 64px; }

  .acredita-fila:hover .acredita-tira,
  .acredita-fila:focus-within .acredita-tira,
  .acredita-fila[data-quieto] .acredita-tira { animation-play-state: paused; }

  /* Los cuatro juegos extra sobran en el teléfono: allí media tira ya es más
     ancha que la pantalla con un solo juego. Se ocultan DESPUÉS de la regla que
     enseña las copias, porque las dos pesan lo mismo y manda el orden. */
  .acredita-tira .acredita-copia-ancha { display: none; }
}

/* --- El desfile en pantalla ancha ----------------------------------------
   Mismo mecanismo, dos ajustes que solo tienen sentido aquí. */
@media (min-width: 1024px) and (prefers-reduced-motion: no-preference) {
  .acredita-tira .acredita-copia-ancha { display: flex; }

  /* 60 s y no 20: el salto recorre TRES juegos en vez de uno, así que con la
     misma duración iría al triple de velocidad. Lo que se mantiene igual entre
     el teléfono y el monitor no es el tiempo de vuelta, es el ritmo: unos
     quince sellos por minuto en los dos. */
  .acredita-tira { animation-duration: 60s; }

  /* El separador de las cifras, ahora en TODAS las celdas y no solo a partir de
     la segunda. En una tira sin principio, saltarse el primero deja un hueco en
     el ritmo una vez por vuelta, justo en la costura. */
  .acredita-tira .sello { position: relative; min-height: 72px; }
  .acredita-tira .sello::before {
    content: ""; position: absolute; left: 0; top: 8%; bottom: 8%; width: 1px;
    background: linear-gradient(to bottom, transparent, var(--capa-2), transparent);
  }
}

@keyframes acredita-desfile {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}


/* --- Revelado por scrubbing (GSAP) -------------------------------------- */
.declaracion {
  /* Dos subidas, 13-09-2026. Primero el suelo de 26 a 34, porque en el telefono
     esta frase es el ancla visual de la seccion y se leia como un parrafo largo.
     Despues, a peticion del cliente, los DOS extremos: 40 en movil y 56 en PC.

     El pico pasa a 3,9vw y no se queda en 3,4: con 3,4 el tope de 56 no se
     alcanzaba hasta los 1647 px y a 1440 —la ventana de referencia— se quedaba
     en 49. La pendiente se calcula contra el ancho donde tiene que llegar, no
     se deja al azar.

     Sigue por DEBAJO de los titulares de seccion (56 movil / 72 PC) a
     proposito: es una declaracion, no un titulo. Si igualara, la seccion
     tendria dos voces gritando lo mismo. */
  font-size: clamp(2.5rem, 3.9vw, 3.5rem); font-weight: 500;
  /* Interletrado -22 e interlineado 1, los de la papeleria. Se aplican AQUI y
     no en el cuerpo por lo que ya dice la documentacion: el pariente real del
     subtitulo de la marca (55 px, interlineado 0,95) es esta declaracion, no la
     entradilla. Un parrafo de 17 px con estos numeros se lee apelmazado.

     🔴 Interlineado 1 con degradado recortado al texto es EL caso para el que
     existe el `padding-block` de `.letrero-texto`: la caja de la letra en
     Ubuntu mide ~1,12em y la del renglon 1em, asi que las mayusculas y las
     colas se salen de lo que se pinta. Verificado con `revela-continuidad`
     despues del cambio, no antes. */
  line-height: 1; letter-spacing: -0.022em; color: var(--tinta);
  max-width: 22ch; text-wrap: pretty;
}
/* Una palabra suelta necesita caja propia para animarse sin partirse por la
   mitad al llegar al final de la línea. */
.declaracion .palabra,
[data-enciende] .palabra { display: inline-block; }

/* --- 🔴 Y aquí NO, aquí `inline` -----------------------------------------
   `inline-block` crea una caja ATÓMICA, y el navegador puede cortar la línea
   junto a una caja atómica AUNQUE NO HAYA ESPACIO. Con la entradilla de
   Tarifas —`…categoría</em>. Incluye…`— el punto quedaba en un <span> propio
   pegado al </em>, y entre 428 y 528 px de ancho se caía él solo al renglón
   siguiente: una línea que empezaba por «. Incluye las…». Anchos reales: el
   iPhone 15 Pro Max son 430.

   Medido: desnivel del punto 30 px con inline-block, 0 con inline. Y el
   control decisivo, la misma entradilla SIN partir: no se cae en ningún ancho,
   o sea que era regresión del partido, no algo de antes.

   No se toca `.declaracion` ni `[data-enciende]`: ahí el inline-block lleva
   tiempo funcionando y no tienen puntuación pegada a un <em>.

   Ninguna palabra se parte por la mitad al pasar a `inline`: `overflow-wrap`
   solo está puesto en los enlaces del pie, en ningún titular ni entradilla. */
[data-enciende-palabras] .palabra { display: inline; }

/* 🔴 Y las del titular de [data-enciende] TAMBIÉN, en cuanto llevan degradado.
   Esas nacen `inline-block` (regla de arriba), y el relleno vertical que el
   reparto del degradado le añade a cada palabra SÍ empuja el maquetado en una
   caja inline-block: la línea crecía y los glifos se desplazaban respecto al
   mismo titular sin partir. Medido: media 5,79/255 contra el 0,05 de los que
   están bien. En `inline` el relleno solo agranda la zona pintada, que es para
   lo que está. */
[data-enciende] .letrero-texto .palabra { display: inline; }

/* Y la declaracion igual, por el mismo motivo, desde que lleva el degradado
   repartido: nace `inline-block` por la regla de arriba, y ahi el aire vertical
   del reparto SI empuja el maquetado. */
[data-scrub][data-partido] .palabra { display: inline; }

/* --- La tarjeta «Un servicio con respaldo», mas grande en el telefono ----
   Medido a 390: el titular iba a 22 px y los puntos a 15, dentro de una caja
   de 350. Al lado de una declaracion de 34 px se leia como letra pequena, y
   es justo donde va la prueba de que esto es una IPS acreditada. En PC no se
   toca: alli el titular ya esta en 27,4 y la columna mide 377. */
@media (max-width: 979px) {
  body[data-pagina="home"] .comp-bien .h3 { font-size: 1.625rem; }
  body[data-pagina="home"] .comp-bien li { font-size: var(--t-cuerpo); }
}
/* Aqui vivian dos reglas para `.declaracion em` («la tuya» en cian y luego en
   degradado). Se fueron el 13-09-2026: el degradado es ahora de la frase
   ENTERA, asi que no hay nada que resaltar dentro y el <em> desaparecio del
   HTML. Si vuelve a hacer falta un resalte aqui, ojo: `.declaracion em` pesa
   (0,1,1) y le gana a `.letrero-texto` (0,1,0) en `color`. */

/* El resalte va en 700 y no en regular. En regular, el celeste de marca es
   exactamente el color de los enlaces del sitio: la palabra resaltada se leía
   como algo en lo que hacer clic. El peso la separa de esa lectura. */
.resalte,
.resalte-magenta { font-style: normal; font-weight: 700; }
.resalte { color: var(--resalte-cian); }
.resalte-magenta { color: var(--resalte-magenta); }

/* --- Bento sin huecos --------------------------------------------------- */
.bento { display: grid; gap: 1rem; grid-auto-flow: dense; grid-template-columns: repeat(2, 1fr); }
@media (min-width: 900px) { .bento { grid-template-columns: repeat(4, 1fr); } }
.celda {
  display: flex; flex-direction: column; padding: clamp(1.5rem, 2.4vw, 2.25rem);
  border-radius: var(--r-l); border: 1px solid var(--borde); background: var(--superficie);
  grid-column: span 2;
}
.celda-alta { grid-row: span 2; }
.celda h3 { margin-bottom: .75rem; }
.celda p { font-size: var(--t-menor); color: var(--suave); }
.celda-azul { background: rgba(0, 159, 227, .10); border-color: rgba(0, 159, 227, .35); }
.celda-azul h3, .celda-azul strong { color: var(--tinta); }
.celda-azul p { color: var(--sobre-azul); }
.celda-letrero { background: var(--letrero); border: 0; color: #fff; justify-content: center; }
.celda-letrero h3 { color: #fff; font-size: clamp(1.5rem, 2.6vw, 2.125rem); }
.celda-letrero p { color: rgba(255, 255, 255, .92); }
/* 🔴 Va calificada con `.celda` a propósito (0,2,0). La regla de teléfono
   `.celda { padding: 1.25rem }` es (0,1,0) pero vive MÁS ABAJO en el archivo,
   así que a igual peso ganaba ella y en el móvil esta celda recuperaba el
   relleno: la foto se quedaba encogida en medio de un marco blanco y con las
   esquinas RECTAS —las redondas son las de la celda, que quedaban a 20 px—.
   Se veía como una foto pegada dentro de una tarjeta, no como una tarjeta de
   foto. Con (0,2,0) gana ésta en cualquier tamaño y sin depender del orden. */
.celda.celda-foto { padding: 0; overflow: hidden; }
.celda-foto img { width: 100%; height: 100%; object-fit: cover; min-height: 220px; }
.celda-precio { justify-content: space-between; }
/* Va calificada con .celda a propósito: `.celda p` es (0,2,0) y ganaba a un
   `.precio-cifra` suelto (0,1,0). La cifra se estaba pintando a 15 px en gris
   —más pequeña que el "COP" de al lado— en móvil y en escritorio. Es el dato
   por el que la gente entra a esta sección. */
.celda .precio-cifra {
  display: flex; align-items: baseline; gap: .375rem;
  font-size: clamp(2.5rem, 4.6vw, 3.5rem); font-weight: 700;
  letter-spacing: -0.045em; line-height: 1; color: var(--tinta); margin: .75rem 0 .25rem;
}
.celda-azul .precio-cifra { color: var(--tinta); }
.precio-cifra small { font-size: 1rem; font-weight: 400; letter-spacing: 0; color: var(--suave); }
.celda-azul .precio-cifra small { color: var(--sobre-azul); }
.celda ul { margin-top: 1.25rem; display: grid; gap: .625rem; }
.celda li { position: relative; padding-left: 1.5rem; font-size: var(--t-menor); }
.celda li::before {
  content: ""; position: absolute; left: 0; top: .45em; width: 14px; height: 8px;
  border-left: 2px solid var(--cian-claro); border-bottom: 2px solid var(--cian-claro);
  transform: rotate(-45deg);
}
.celda-azul li::before { border-color: var(--cian); }
.celda .btn { margin-top: 1.5rem; }

/* --- Bloque de prueba real ---------------------------------------------- */
.prueba { display: grid; gap: clamp(2rem, 5vw, 4rem); align-items: center; }
@media (min-width: 900px) { .prueba { grid-template-columns: 1.15fr .85fr; } }
.prueba figure { position: relative; border-radius: var(--r-l); overflow: hidden; }
.prueba img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; }
.prueba figcaption { margin-top: .875rem; font-size: var(--t-mini); color: var(--suave); }

/* --- Guías -------------------------------------------------------------
   Solo queda la REJILLA. La tarjeta plana de antes (.guia, .guia-figura,
   .guia-cuerpo, .guia-pie) murió el 13-09-2026: la home ya usaba `.tarjeta-alta`
   y /guias se quedó con la versión vieja, así que el mismo contenido se veía de
   dos maneras distintas segun por donde se llegara. Ahora las dos usan la alta.
   Si vuelve a hacer falta una tarjeta plana, se escribe de nuevo; no se revive
   esta, que arrastraba dos arreglos de `flex` que ya no aplican a nada. */
.guias { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fit, minmax(290px, 1fr)); }

/* --- FAQ ---------------------------------------------------------------- */
.faq { max-width: 48rem; margin-inline: auto; border-top: 1px solid var(--borde); }
.faq details { border-bottom: 1px solid var(--borde); }
.faq summary {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 1.5rem;
  padding: 1.5rem 0; cursor: pointer; list-style: none;
  font-size: 1.125rem; font-weight: 500; color: var(--tinta);
  transition: color 180ms ease;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: ""; flex-shrink: 0; margin-top: .45em; width: 11px; height: 11px;
  border-right: 2px solid var(--suave); border-bottom: 2px solid var(--suave);
  transform: rotate(45deg); transition: transform 280ms var(--sal), border-color 180ms ease;
}
.faq details[open] summary::after { transform: rotate(-135deg); border-color: var(--cian-claro); }
@media (hover: hover) and (pointer: fine) { .faq summary:hover { color: var(--cian-claro); } }
.faq-cuerpo { padding-bottom: 1.5rem; color: var(--texto); }
.faq-cuerpo p + p { margin-top: .875rem; }


/* === TARJETA ALTA ======================================================
   La foto ES la tarjeta: sin marco, sin cuerpo blanco debajo. El titular va
   ARRIBA, sobre la imagen, y abajo a la derecha un botón redondo que dice que
   hay más. Formato vertical, que es el que deja sitio al titular sin comerse
   la cara de la foto.

   🔴 El titular sobre una foto es frágil: la foto la cambia el cliente y el
   contraste se va con ella. Por eso NO se confía en la imagen —va un velo
   oscuro degradado en la parte de arriba, y el texto en blanco sobre él. Así
   cumple con cualquier foto que entre mañana, y en los dos temas, porque el
   velo lo pone la tarjeta y no la página. Medido con `barrido-contraste`.

   La palabra de acento va con el degradado de marca: sobre el velo oscuro el
   cian da 6,1:1 y el magenta 4,2, los dos por encima del 3:1 de texto grande.
   ==================================================================== */
.tarjeta-alta {
  position: relative;
  display: block;
  isolation: isolate;
  aspect-ratio: 3 / 4.15;
  border-radius: var(--r-xl);
  overflow: hidden;
  /* 🔴 Opaco y OSCURO, no `--capa-1`. La foto va con `loading="lazy"`, y
     mientras no llega la tarjeta enseña su propio fondo: con una capa
     translucida ese fondo era el de la pagina —casi blanco en el tema claro— y
     el titular BLANCO quedaba a 1,06:1, o sea invisible. Con conexion lenta no
     es un instante, son segundos. Medido con `texto-sobre-foto.js` a 390. */
  background: var(--azul-900);
  text-decoration: none;
  color: #fff;
  transition: transform var(--t-entra) var(--mov-entra),
              box-shadow var(--t-entra) var(--mov-entra);
}

.tarjeta-alta > img {
  position: absolute; inset: 0; z-index: -2;
  width: 100%; height: 100%; object-fit: cover;
  transition: transform 1200ms var(--mov-entra);
}

/* El velo. Va de opaco arriba a nada a media tarjeta: tapa lo justo para que
   el titular se lea y deja la foto entera de cintura para abajo. */
.tarjeta-alta::before {
  content: ""; position: absolute; inset: 0 0 auto 0; z-index: -1;
  height: 62%;
  background: linear-gradient(to bottom,
    rgba(7, 12, 26, .86) 0%,
    rgba(7, 12, 26, .62) 38%,
    rgba(7, 12, 26, .22) 72%,
    rgba(7, 12, 26, 0) 100%);
}

/* --- Tarjeta cuyo ARTE ya trae el titular ------------------------------
   Las tres guías de la home llevan una pieza diseñada aparte, con el titular y
   su propio velo dentro del archivo. Así que aquí se apagan los dos que pone la
   web: el velo degradado —se sumaría al del arte y oscurecería el doble— y el
   titular en blanco, que quedaría impreso encima del que ya trae la imagen.
   El círculo del «+» se queda: es lo que dice que la tarjeta se puede pulsar.

   🔴 Y la proporción se unifica, que es lo que de verdad protege el diseño. La
   tarjeta normal se acorta a 3/3,9 por debajo de 980 px, y con `object-fit:
   cover` eso recorta un 3 % por arriba y otro 3 % por abajo. Con una fotografía
   da igual —se pierde cielo—, pero aquí arriba hay TEXTO IMPRESO a menos de un
   7 % del borde. Con una sola proporción no se recorta nada, nunca. Cuesta 25 px
   más de alto en el riel del teléfono, que es un precio barato por no cortarle
   una tilde al titular.

   Especificidad (0,2,0): le gana a la regla de móvil, que es (0,1,0), sin
   depender del orden del archivo. */
.tarjeta-alta[data-arte] { aspect-ratio: 3 / 4.15; }
.tarjeta-alta[data-arte]::before { content: none; }

.tarjeta-alta-texto {
  position: absolute; inset: 0 0 auto 0;
  padding: clamp(1.25rem, 2.2vw, 1.75rem);
}
/* 🔴 BLANCO, no cian. A 13 px en negrita el listan de AA son 4,5:1, y el cian
   de marca sobre el velo daba 3,2-3,6 medido pixel a pixel. Es la misma regla
   que ya rige en el resto del sitio: los colores de marca solo son LETRA donde
   el tamano los sostiene. El acento se conserva en el punto de delante, que es
   un grafico y con 3:1 cumple —da 3,3 sobre el velo—. */
.tarjeta-alta-cifra {
  display: flex; align-items: center; gap: .5rem;
  margin: 0 0 .625rem;
  font-size: var(--t-mini); font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase; color: #fff;
}
.tarjeta-alta-cifra::before {
  content: ""; width: 7px; height: 7px; border-radius: 50%;
  background: var(--cian); flex: 0 0 auto;
}
.tarjeta-alta h3,
.tarjeta-alta .h3 {
  margin: 0;
  font-size: clamp(1.375rem, 1.9vw, 1.75rem);
  line-height: 1.16; letter-spacing: -0.02em; font-weight: 700;
  color: #fff; text-wrap: balance;
}
/* El enfasis lo da el degradado, no la inclinacion: un titular corto en
   cursiva sobre una foto se lee peor, y el resto del sitio ya usa el color
   como marca de enfasis (ver `.declaracion`). */
/* 🔴 CIAN SOLIDO, no el degradado de marca. Medido pixel a pixel el fondo real
   detras de cada palabra de acento y calculado cada parada del degradado contra
   el, con el listan de texto grande (3:1):

                      cian   violeta   magenta
     «renovar»         6,26     3,35      4,13
     «primera licencia» 6,53    3,50      4,31
     «cuesta»          3,83     2,05      2,53   <- no llega

   El velo se aclara donde la foto es clara, y ahi el VIOLETA del medio del
   degradado se hunde. El cian aguanta en las tres, incluso en la peor. Es la
   misma regla que hizo blanco el epigrafe hace unas horas: los colores de marca
   solo son letra donde el fondo los sostiene, y sobre una foto que cambia el
   cliente eso no se puede dar por hecho.

   La cursiva tampoco: aqui el enfasis lo da el color. */
.tarjeta-alta em { font-style: normal; color: var(--cian); }

/* Aquí vivía `.tarjeta-alta[data-resumen]`: la variante que metía el resumen
   ENCIMA de la foto en /guias, con el velo bajado al 82 % para que el párrafo
   se leyera. Murió el 14-09-2026, cuando /guias pasó al arte propio: ese velo
   se habría sumado al que ya trae la pieza. Ahora el resumen va debajo, sobre
   fondo liso (ver `.tarjeta-arte`). No se revive: si vuelve a hacer falta texto
   sobre una foto, se mide otra vez contra la foto que haya entonces. */

/* El botón redondo. En las guías es un adorno (la tarjeta entera es el
   enlace); en las valoraciones es un botón de verdad que abre el texto. */
/* 🔴 `z-index: 2` y el panel en 1: sin esto el detalle que abre el boton se le
   pone ENCIMA y la cruz de cerrar queda medio tapada y sin poder pulsarse. Se
   vio al abrir la primera tarjeta. */
.tarjeta-alta-mas {
  position: absolute; right: 1rem; bottom: 1rem; z-index: 2;
  width: 44px; height: 44px; border: 0; border-radius: 50%;
  background: var(--magenta); color: #fff; cursor: pointer;
  display: grid; place-items: center; padding: 0;
  transition: transform var(--t-toque) var(--mov-empuje),
              background-color var(--t-toque) var(--mov-toque);
}
/* El signo se dibuja con dos barras: así gira a «cerrar» sin cambiar el texto
   ni depender de una fuente de iconos. */
.tarjeta-alta-mas::before,
.tarjeta-alta-mas::after {
  content: ""; position: absolute;
  background: currentColor; border-radius: 2px;
  transition: transform var(--t-despliega) var(--mov-despliega);
}
.tarjeta-alta-mas::before { width: 16px; height: 2px; }
.tarjeta-alta-mas::after { width: 2px; height: 16px; }

/* El panel que se abre en las valoraciones. Nace oculto para el ratón Y para
   el lector de pantalla (`visibility`), que es lo que hace que `aria-expanded`
   diga la verdad. */
.tarjeta-alta-detalle {
  position: absolute; inset: auto 0 0 0; z-index: 1;
  padding: clamp(1.25rem, 2.2vw, 1.75rem);
  padding-bottom: 4.5rem;
  background: linear-gradient(to top,
    rgba(7, 12, 26, .95) 0%, rgba(7, 12, 26, .88) 62%, rgba(7, 12, 26, 0) 100%);
  color: #fff; font-size: var(--t-menor); line-height: 1.5;
  opacity: 0; visibility: hidden; transform: translateY(10px);
  transition: opacity var(--t-despliega) var(--mov-despliega),
              transform var(--t-despliega) var(--mov-despliega),
              visibility 0s linear var(--t-despliega);
}
.tarjeta-alta-detalle p { margin: 0; }

.tarjeta-alta[data-abierta] .tarjeta-alta-detalle {
  opacity: 1; visibility: visible; transform: none;
  transition-delay: 0s;
}
.tarjeta-alta[data-abierta] .tarjeta-alta-mas::before { transform: rotate(135deg); }
.tarjeta-alta[data-abierta] .tarjeta-alta-mas::after { transform: rotate(135deg); }

@media (hover: hover) and (pointer: fine) {
  .tarjeta-alta:hover { transform: translateY(-6px); box-shadow: var(--sombra-alta); }
  .tarjeta-alta:hover > img { transform: scale(1.06); }
  .tarjeta-alta:hover .tarjeta-alta-mas,
  .tarjeta-alta-mas:hover { transform: scale(1.12); }
}
.tarjeta-alta:focus-visible,
.tarjeta-alta-mas:focus-visible {
  outline: 2px solid var(--cian); outline-offset: 3px;
}

/* En el teléfono la tarjeta se ensancha dentro del riel, así que se acorta un
   punto: en 3/4,15 y al 84% del ancho se comía la pantalla entera. */
@media (max-width: 979px) {
  .tarjeta-alta { aspect-ratio: 3 / 3.9; }
  .tarjeta-alta h3, .tarjeta-alta .h3 { font-size: 1.3125rem; }
}

/* Sin movimiento: el estado final es el mismo, solo desaparece el trayecto.
   El panel sigue abriéndose y cerrándose; lo que se va es el deslizamiento. */
@media (prefers-reduced-motion: reduce) {
  .tarjeta-alta,
  .tarjeta-alta > img,
  .tarjeta-alta-mas,
  .tarjeta-alta-mas::before,
  .tarjeta-alta-mas::after,
  .tarjeta-alta-detalle { transition-duration: .01ms; }
  .tarjeta-alta-detalle { transform: none; }
  @media (hover: hover) and (pointer: fine) {
    .tarjeta-alta:hover { transform: none; }
    .tarjeta-alta:hover > img { transform: none; }
  }
}

/* === TARJETA DE ARTE (el índice /guias) =================================
   La variante de /guias, desde el 14-09-2026. Lleva el mismo arte que la home
   —con el titular y el velo ya impresos en el archivo— pero aquí, además, va el
   RESUMEN, que es lo que hace elegir una guía y no otra. Y ese resumen baja
   FUERA de la imagen, al fondo liso de la página.

   🔴 Por qué no se reusó la variante que hacía esto hasta hoy
   (`.tarjeta-alta[data-resumen]`, retirada unas líneas más arriba): allí el
   párrafo iba ENCIMA de la foto, y para que se leyera había que bajar el velo
   hasta el 82 %. Ese velo se sumaría al que ya trae el arte: la
   pieza quedaría oscurecida dos veces y el titular impreso perdería el
   contraste que se diseñó para él. Y hay algo peor: un resumen sobre una imagen
   que el cliente rediseña cuando quiera es contraste PRESTADO. Aquí va sobre un
   fondo que controlamos nosotros, así que cumple 4,5:1 hoy y con cualquier arte
   que entre mañana, sin volver a medir nada.

   La tarjeta entera sigue siendo el enlace, y el círculo del «+» se queda sobre
   el arte igual que en la home: sigue siendo adorno (`aria-hidden`), no un
   segundo botón dentro del enlace. */
.tarjeta-arte {
  position: relative;
  display: flex; flex-direction: column;
  text-decoration: none; color: inherit;
  transition: transform var(--t-entra) var(--mov-entra);
}

/* El marco del arte. `overflow` aquí y no en la tarjeta: así el zoom del hover
   se recorta contra las esquinas redondeadas de la imagen y el resumen de
   debajo se queda quieto y sin recortar. */
.tarjeta-arte-lienzo {
  position: relative; isolation: isolate;
  border-radius: var(--r-xl); overflow: hidden;
  /* Opaco mientras la imagen `lazy` no llega, por la misma razón que en
     `.tarjeta-alta`: con conexión lenta esto no es un instante, son segundos. */
  background: var(--azul-900);
}
/* La proporción se declara aunque el archivo ya venga en 3/4,15: si mañana
   entra una pieza de otra forma, se recorta ella sola en vez de descuadrar la
   fila entera. */
.tarjeta-arte-lienzo img {
  display: block; width: 100%; height: auto;
  aspect-ratio: 3 / 4.15; object-fit: cover;
  transition: transform 1200ms var(--mov-entra);
}

.tarjeta-arte-mas {
  position: absolute; right: 1rem; bottom: 1rem; z-index: 2;
  width: 44px; height: 44px; border-radius: 50%;
  background: var(--magenta); color: #fff;
  display: grid; place-items: center;
  transition: transform var(--t-toque) var(--mov-empuje);
}
.tarjeta-arte-mas::before,
.tarjeta-arte-mas::after {
  content: ""; position: absolute;
  background: currentColor; border-radius: 2px;
}
.tarjeta-arte-mas::before { width: 16px; height: 2px; }
.tarjeta-arte-mas::after { width: 2px; height: 16px; }

/* El sangrado lateral de .25rem no es capricho: alinea el texto con el borde
   óptico de la imagen, que está redondeada. A cero, el párrafo se ve metido
   hacia dentro respecto de la pieza. */
.tarjeta-arte-pie { padding: .9375rem .25rem 0; }
.tarjeta-arte-resumen {
  margin: 0;
  font-size: var(--t-menor); line-height: 1.55;
  color: var(--texto); text-wrap: pretty;
  transition: color var(--t-toque) var(--mov-toque);
}

@media (hover: hover) and (pointer: fine) {
  .tarjeta-arte:hover { transform: translateY(-6px); }
  .tarjeta-arte:hover .tarjeta-arte-lienzo { box-shadow: var(--sombra-alta); }
  .tarjeta-arte:hover .tarjeta-arte-lienzo img { transform: scale(1.06); }
  .tarjeta-arte:hover .tarjeta-arte-mas { transform: scale(1.12); }
  /* El resumen sube a color de titular al pasar por encima: es la única señal
     de que el párrafo también forma parte del enlace. */
  .tarjeta-arte:hover .tarjeta-arte-resumen { color: var(--tinta); }
}
.tarjeta-arte:focus-visible {
  outline: 2px solid var(--cian); outline-offset: 4px;
  border-radius: var(--r-xl);
}

@media (prefers-reduced-motion: reduce) {
  .tarjeta-arte,
  .tarjeta-arte-lienzo img,
  .tarjeta-arte-mas,
  .tarjeta-arte-resumen { transition-duration: .01ms; }
  @media (hover: hover) and (pointer: fine) {
    .tarjeta-arte:hover { transform: none; }
    .tarjeta-arte:hover .tarjeta-arte-lienzo img { transform: none; }
  }
}

/* === PRECIOS ==============================================================
   Segunda pasada, 17-09-2026. La primera montó un tarifario de cuatro filas
   —una por categoría—, y el cliente corrigió el dato de fondo: **el examen
   vale lo mismo para todas las categorías**, particular o público. Lo único
   que mueve el precio es renovar DOS licencias (moto y carro) en una visita.

   Así que no hay tarifario: hay dos casos. Dos cajas, y dentro de la primera
   las OCHO categorías en grande, que son la prueba visual de la frase «un solo
   precio»: ocho fichas, un solo número. */
.precio-doble { display: grid; gap: 1.25rem; align-items: stretch; }
@media (min-width: 900px) {
  /* 6/5 y no 1/1: la caja de la izquierda lleva las ocho categorías y necesita
     ancho para que quepan en dos filas limpias de cuatro. */
  .precio-doble { grid-template-columns: minmax(0, 6fr) minmax(0, 5fr); }
}
.precio-caja {
  position: relative; isolation: isolate;
  display: flex; flex-direction: column;
  margin: 0; padding: clamp(1.5rem, 3vw, 2.25rem);
  border: 1px solid var(--borde); border-radius: var(--r-xl);
  background: var(--superficie);
}
@supports (backdrop-filter: blur(1px)) {
  .precio-caja { backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px); }
}
.precio-etiqueta {
  display: flex; flex-wrap: wrap; align-items: center; gap: .5rem;
  margin: 0; font-size: var(--t-menor); font-weight: 700; color: var(--suave);
}
.precio-numero {
  display: flex; align-items: baseline; gap: .4375rem; margin: .625rem 0 0;
  font-size: clamp(2.5rem, 5vw, 3.5rem); font-weight: 700; line-height: 1;
  letter-spacing: -0.04em; color: var(--tinta); font-variant-numeric: tabular-nums;
}
.precio-numero small { font-size: 1rem; font-weight: 400; letter-spacing: 0; color: var(--suave); }
.precio-sub { margin: .875rem 0 0; font-size: var(--t-menor); color: var(--texto); max-width: 46ch; }

/* Las categorías, GRANDES y en ficha: son códigos que la gente busca con el
   ojo («¿dónde está mi B2?»), no prosa. A tamaño de párrafo había que leerlas
   una por una; así se barren de un vistazo. */
.cats-grandes {
  list-style: none; display: flex; flex-wrap: wrap; gap: .5rem;
  margin: 1.5rem 0 0; padding: 0;
}
.cats-grandes li {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 3.75rem; padding: .4375rem .75rem;
  border: 1px solid var(--capa-2); border-radius: var(--r-m);
  background: var(--capa-1);
  font-size: clamp(1.125rem, 2vw, 1.375rem); font-weight: 700; line-height: 1;
  letter-spacing: -0.01em; color: var(--tinta); font-variant-numeric: tabular-nums;
}
/* La suma A + B, al mismo tamaño que las fichas de al lado: es el mismo dato
   dicho de otra forma, y si se dibuja más pequeño parece una nota al pie. */
.cats-suma {
  display: flex; align-items: center; gap: .625rem; margin: 1.5rem 0 0;
}
.cats-suma span {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 3.75rem; padding: .4375rem .75rem;
  border: 1px solid var(--capa-2); border-radius: var(--r-m);
  background: var(--capa-1);
  font-size: clamp(1.125rem, 2vw, 1.375rem); font-weight: 700; line-height: 1; color: var(--tinta);
}
.cats-suma em { font-style: normal; font-size: 1.25rem; font-weight: 700; color: var(--suave); }
.cats-pie { margin: .875rem 0 0; font-size: var(--t-mini); color: var(--suave); }
/* El botón, pegado abajo: con dos cajas de alto distinto, los dos botones
   quedan en la misma línea y la comparación no se tuerce. */
.precio-btn { margin-top: auto; align-self: flex-start; }
.precio-caja .precio-btn { margin-top: 1.75rem; }
@media (min-width: 900px) {
  /* 🔴 `margin-top: auto` reparte el hueco LIBRE, y la caja más alta de las dos
     no tiene ninguno: ahí el pie de categorías terminaba pegado al botón
     (15 px). El aire mínimo lo pone el propio pie, que es el elemento que
     siempre va justo encima. */
  .precio-caja .cats-pie { margin-bottom: 1.75rem; }
  .precio-caja .precio-btn { margin-top: auto; }
}

/* La caja destacada no es la más cara: es la que AHORRA. Velo del degradado de
   marca al 7 %, no un borde de color. `z-index: -1` con `isolation` en la
   caja: la lección de la tarjeta de sede. */
.precio-caja[data-destacada]::before {
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  border-radius: inherit; background: var(--letrero); opacity: .07;
}
.tarifa-ahorro {
  display: inline-block; padding: .1875rem .5625rem;
  border-radius: 999px; background: var(--magenta); color: #fff;
  font-size: var(--t-mini); font-weight: 700; letter-spacing: 0; white-space: nowrap;
}

/* --- Lo que no está incluido y cómo se paga, en paralelo ----------------- */
.precios-dos { display: grid; gap: clamp(2.5rem, 5vw, 4rem); align-items: start; }
@media (min-width: 980px) {
  .precios-dos { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
}
.precios-col .h2 { font-size: clamp(1.875rem, 3vw, 2.5rem); }

/* Tabla de dos columnas convertida en lista: con dos datos por fila —qué y
   dónde— una tabla es andamiaje de más, y en el teléfono obligaba a un riel. */
.fuera { list-style: none; margin: clamp(1.5rem, 3vw, 2rem) 0 0; padding: 0; }
.fuera li { display: grid; gap: .125rem; padding: .875rem 0; border-top: 1px solid var(--borde); }
.fuera li:first-child { border-top: 0; padding-top: 0; }
.fuera strong { font-size: var(--t-menor); font-weight: 700; color: var(--tinta); }
.fuera span { font-size: var(--t-menor); color: var(--suave); }

/* El TITULAR de cada tarjeta: es lo primero que se lee y lo que separa los dos
   precios. La diferencia es una sola letra —«carro O moto» contra «carro Y
   moto»—, así que esa letra sale del texto y va en su propia ficha: a tamaño de
   párrafo, dentro de la frase, se perdía. «A + B» no lo entiende quien viene a
   renovar; esto sí.

   El mismo titular va en las dos tarjetas de precio de la home (.titulo-nexo),
   para que el gesto que distingue los dos casos se diga igual en toda la web. */
.precio-titulo, .titulo-nexo {
  display: flex; align-items: center; flex-wrap: wrap; gap: .5rem;
}
.precio-titulo {
  margin: 0 0 .75rem;
  font-size: clamp(1.625rem, 3vw, 2.125rem); font-weight: 700;
  letter-spacing: -0.03em; line-height: 1.1; color: var(--tinta);
}
/* CELESTE de marca, por decisión del cliente (17-09-2026), y la letra en el
   azul profundo: es exactamente el par del botón principal sobre oscuro
   (`.btn-primario`), así que el disco no inventa un color nuevo. Da 6,4:1,
   frente a los 4,5:1 del magenta con blanco que había antes.

   Medidas en `em` y no en `rem`: el mismo disco sirve al titular grande de
   /precios y al h3 más pequeño de la home sin una segunda regla, y crece con
   la letra en vez de quedarse suelto dentro de ella. */
.precio-nexo {
  display: inline-flex; align-items: center; justify-content: center;
  width: 1.75em; height: 1.75em; padding: 0;
  border-radius: 999px; background: var(--cian); color: var(--azul-900);
  font-style: normal; font-size: .62em; font-weight: 700; line-height: 1;
  letter-spacing: 0; text-transform: uppercase;
}

/* --- Lo que incluye, con el RUNT delante --------------------------------
   El certificado cargado en el RUNT es lo único de esta lista que decide si el
   trámite le sirve a la persona, y estaba de sexto en una lista de seis. Ahora
   encabeza el bloque, con su escudo, y las valoraciones quedan como detalle. */
/* Va PEGADO a las dos tarjetas —mismo hueco que hay entre ellas— y no en una
   sección aparte: lo que incluye el precio es parte del precio, y a una pantalla
   de distancia se leía como otro tema. */
.incluye-bloque {
  display: grid; gap: clamp(1.25rem, 2.5vw, 2rem);
  margin-top: 1.25rem;
  padding: clamp(1.25rem, 2.5vw, 2rem);
  border: 1px solid var(--borde); border-radius: var(--r-xl);
  background: var(--superficie);
}
@supports (backdrop-filter: blur(1px)) {
  .incluye-bloque { backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px); }
}
@media (min-width: 900px) {
  .incluye-bloque { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); align-items: center; }
}
.incluye-runt { display: flex; align-items: flex-start; gap: 1rem; }
.incluye-icono { flex: none; width: 2.75rem; height: 2.75rem; color: var(--cian-claro); }
.incluye-runt-titulo {
  margin: 0; font-size: clamp(1.125rem, 2vw, 1.375rem); font-weight: 700;
  letter-spacing: -0.02em; color: var(--tinta); text-wrap: balance;
}
.incluye-runt-sub { margin: .5rem 0 0; font-size: var(--t-menor); color: var(--texto); max-width: 52ch; }
/* Un pelo de separación entre las dos mitades, solo cuando van lado a lado. */
@media (min-width: 900px) {
  .incluye-detalle { border-left: 1px solid var(--borde); padding-left: clamp(1.25rem, 2.5vw, 2rem); }
}
.incluye-titulo { margin: 0 0 .75rem; font-size: var(--t-mini); font-weight: 700; color: var(--suave); }
/* La lista de valoraciones, con el mismo palomito que las tarjetas de precio de
   la home: así «incluido» se dice igual en toda la web. En columna estrecha va
   en vertical; si cabe, en dos columnas. */
.tarifario-incluye { list-style: none; margin: 0; padding: 0; display: grid; gap: .5rem; }
@media (min-width: 620px) and (max-width: 899px) { .tarifario-incluye { grid-template-columns: 1fr 1fr; } }
.tarifario-incluye li {
  position: relative; padding-left: 1.5rem; font-size: var(--t-menor); color: var(--texto);
}
.tarifario-incluye li::before {
  content: ""; position: absolute; left: 0; top: .42em; width: 13px; height: 8px;
  border-left: 2px solid var(--cian-claro); border-bottom: 2px solid var(--cian-claro);
  transform: rotate(-45deg);
}

/* --- La banda de medios de pago -----------------------------------------
   Mismo gesto que la banda de acreditaciones de la home, pero con titular de
   sección propio: el rótulo de 13 px que tenía antes lo dejaba como un pie de
   página, y esto es una respuesta a una pregunta que la gente sí se hace.
   Va con el letrero escrito, como los demás titulares de la web.

   Las marcas van en la TINTA del tema, no con sus colores: seis logos ajenos a
   todo color se comen la sección y el bloque deja de parecer de ReconoCer.

   Visa y Mastercard son sus marcas oficiales (Simple Icons, CC0). Las demás van
   escritas con la tipografía de la web hasta que lleguen sus logos: dibujar una
   versión aproximada se vería peor y sería usar mal su marca. */
.pagos-banda .h2 { font-size: clamp(1.875rem, 3vw, 2.5rem); }
.pagos-tira {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
  gap: clamp(1.75rem, 4vw, 3.5rem);
}
.pago-sello { display: flex; align-items: center; justify-content: center; color: var(--tinta); opacity: .85; }
/* 🔴 Cada marca con SU altura, y el viewBox recortado al dibujo. En un cuadro
   de 24×24 el logotipo de Visa ocupa un tercio del alto y el de Mastercard casi
   dos tercios: con el mismo `width` para las dos, una salía a 23 px y la otra a
   45. Se igualan por lo que se VE, no por la caja que las contiene.
   Visa es un logotipo y se mide contra la altura de las palabras de al lado;
   Mastercard es un símbolo y admite un punto más. */
.pago-marca { width: auto; fill: currentColor; }
.pago-visa { height: 1.75rem; }
.pago-mastercard { height: 2.25rem; }
/* Con un titular de sección encima, las palabras a 26 px se quedaban cortas y
   la tira parecía un pie de página. */
.pago-palabra { font-size: clamp(1.375rem, 2.8vw, 2rem); font-weight: 700; letter-spacing: -0.02em; }

/* === RESEÑAS ==============================================================
   Tercer bloque de la home y primer bloque tras la foto en cada sede. Las
   escribe construir.js desde datos/resenas.json (ver allí las reglas).

   Versión SENCILLA, pedida por el cliente: la tarjeta imita la de Google Maps
   (disco de color con la inicial, nombre, perfil, estrellas amarillas, «hace
   7 meses», texto) para que se lean como reseñas reales y no como testimonios
   de marca. La marca queda en el titular y en la sección, no en la tarjeta.

   Arriba, el titular a la izquierda y la fuente a la derecha («Reseñas de
   Google», nota si la hay, «Ver todas»). Debajo, tres columnas; por debajo de
   980 px, riel deslizable como sedes y guías (ver «Rieles»). */
.resenas-cabeza {
  display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between;
  gap: 1.5rem 3rem; margin-bottom: clamp(1.75rem, 3vw, 2.5rem);
}
/* El titular se limita a ~44rem: a todo el ancho ocupaba la fila entera y
   empujaba «Reseñas de Google» debajo, lejos de las tarjetas que respalda. */
.resenas-cabeza > [data-enciende-palabras] { flex: 1 1 30rem; max-width: 44rem; }
.resenas-cabeza .lead { margin-top: 1rem; max-width: 46ch; }

.resenas-resumen { display: flex; flex-direction: column; align-items: flex-start; gap: .5rem; }
@media (min-width: 980px) { .resenas-resumen { align-items: flex-end; } }
.resenas-fuente {
  display: inline-flex; align-items: center; gap: .5rem; margin: 0;
  font-size: var(--t-menor); font-weight: 600; color: var(--tinta);
}
.resenas-fuente svg { width: 1.25rem; height: 1.25rem; flex: none; }
.resenas-nota {
  display: flex; align-items: center; gap: .5rem; margin: 0;
  font-size: var(--t-menor); color: var(--suave);
}
.resenas-nota strong { font-size: 1.5rem; font-weight: 700; color: var(--tinta); letter-spacing: -0.01em; }
.resenas-nota .resena-estrellas { font-size: 1.125rem; }
/* En el teléfono `.btn-texto` es flex, y un contenedor flex se come el espacio
   entre el texto y la flecha: salía «Maps→». */
.resenas-todas { gap: .375rem; }

/* El aviso de maqueta. Sin magenta en la letra: a 13 px en negrita el magenta
   no llega al 4,5:1 en ninguno de los dos temas. El color lo pone el punto.

   🔴 NO BORRAR aunque los limpiadores de CSS la den por muerta. Ésta y
   `.resena-chip` son la mitad VISIBLE del candado contra publicar reseñas
   inventadas: `construir.js` las escribe solo cuando alguna reseña lleva
   `ejemplo: true`. Hoy no hay ninguna —las once son reales— y por eso no
   aparecen en ninguna visita, pero el día que alguien añada una de prueba
   tienen que estar aquí. La otra mitad del candado está en
   `deploy-reconocer.ps1`, que ni siquiera deja publicar a producción. */
.resenas-aviso {
  display: flex; align-items: center; gap: .5rem; margin: 0 0 1rem;
  font-size: var(--t-mini); font-weight: 700; color: var(--texto);
}
.resenas-aviso .aviso-punto { margin-top: 0; }

.resenas-lista { display: grid; gap: 1rem; grid-template-columns: repeat(3, minmax(0, 1fr)); }

.resena {
  display: flex; flex-direction: column; gap: .75rem;
  margin: 0; padding: 1.25rem 1.25rem 1.375rem;
  border: 1px solid var(--borde); border-radius: var(--r-l);
  background: var(--superficie);
}
.resena-cabeza { display: flex; align-items: center; gap: .75rem; }
.resena-inicial {
  flex: none; display: grid; place-items: center;
  width: 2.5rem; height: 2.5rem; border-radius: 50%;
  background: var(--disco, #3949ab); color: #fff;
  font-size: 1.0625rem; font-weight: 500;
}
.resena-quien { display: flex; flex-direction: column; gap: .125rem; min-width: 0; flex: 1; line-height: 1.3; }
.resena-quien strong {
  font-size: var(--t-menor); font-weight: 600; color: var(--tinta);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.resena-quien span {
  font-size: var(--t-mini); color: var(--suave);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* La «G»: 24 px de caja para que sea tocable cuando es enlace. */
.resena-g { flex: none; display: grid; place-items: center; width: 24px; height: 24px; align-self: flex-start; }
.resena-g svg { width: 1.125rem; height: 1.125rem; }
/* 🔴 NO BORRAR: el sello «Ejemplo». Ver la nota larga en `.resenas-aviso`. */
.resena-chip {
  flex: none; align-self: flex-start; padding: .125rem .5rem; border-radius: 999px;
  border: 1px solid var(--borde); font-size: var(--t-mini); font-weight: 700; color: var(--texto);
}

.resena-linea { display: flex; align-items: center; gap: .625rem; margin: 0; font-size: var(--t-mini); color: var(--suave); }

/* Las estrellas: UN elemento, no cinco. Cinco estrellas en máscara; el
   amarillo de Google llena hasta la nota y el resto queda gris, como en Maps
   (4,9 enseña la última casi llena). El número va en `aria-label`. */
.resena-estrellas {
  --estrella-vacia: rgba(255, 255, 255, .22);
  display: block; flex: none;
  width: 5em; height: 1em; font-size: .9375rem;
  background: linear-gradient(90deg, #fbbc04 calc(var(--nota, 5) * 20%), var(--estrella-vacia) 0);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M10 1.4l2.63 5.33 5.87.85-4.25 4.15 1 5.85L10 14.82l-5.25 2.76 1-5.85L1.5 7.58l5.87-.85z'/%3E%3C/svg%3E") 0 50% / 1em 1em repeat-x;
          mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M10 1.4l2.63 5.33 5.87.85-4.25 4.15 1 5.85L10 14.82l-5.25 2.76 1-5.85L1.5 7.58l5.87-.85z'/%3E%3C/svg%3E") 0 50% / 1em 1em repeat-x;
}
:root[data-tema="claro"] .resena-estrellas { --estrella-vacia: rgba(16, 22, 43, .16); }

.resena-texto { margin: 0; }
.resena-texto p {
  margin: 0; font-size: var(--t-cuerpo); line-height: 1.6;
  color: var(--texto); text-wrap: pretty;
}
/* En la home, a qué sede se refiere: abajo y discreto, como un pie. */
.resena-sede { margin: auto 0 0; padding-top: .25rem; font-size: var(--t-mini); color: var(--suave); }

/* --- Aviso -------------------------------------------------------------- */
.aviso {
  display: flex; gap: .875rem; align-items: flex-start;
  padding: 1.125rem 1.375rem; border: 1px solid var(--borde);
  border-radius: var(--r-m); background: var(--superficie); font-size: var(--t-menor); color: var(--texto);
}
.aviso strong { color: var(--tinta); }
.aviso-punto { flex-shrink: 0; width: 8px; height: 8px; margin-top: .55em; border-radius: 999px; background: var(--magenta); }
.oscura .aviso { background: var(--capa-1); border-color: var(--capa-2); color: var(--texto); }
.oscura .aviso strong { color: var(--tinta); }

/* --- Cierre ------------------------------------------------------------- */
.cierre { text-align: center; position: relative; isolation: isolate; }

/* El difuminado de marca por detrás del bloque. Es EL MISMO recurso que ya
   sostiene a los gemelos del héroe y la foto de la sede: degradado del letrero,
   desenfocado a lo bestia y en forma de óvalo. No se inventa nada aquí; se
   repite el gesto de la casa en el sitio que se había quedado sin él.

   🔴 `isolation: isolate` en el padre, y no confiar en el transform de la
   animación. Un `z-index: -1` solo se queda «detrás del contenido y delante del
   fondo» si hay un contexto de apilamiento que lo contenga; el de la animación
   existe MIENTRAS dura y luego `clearProps` lo borra, así que el resplandor se
   iría por detrás de la sección justo al terminar de entrar. Con `isolate` el
   contexto es permanente. */
.cierre::before {
  content: ""; position: absolute; z-index: -1; pointer-events: none;
  inset: -18% 14% 2%;
  background: var(--letrero);
  filter: blur(90px);
  opacity: .30;
  border-radius: 50%;
}
/* 🔴 Sobre claro NO va más fuerte, va más RECOGIDO y más flojo.

   Historia de tres intentos, porque el error se repitió: primero .42 a todo
   el ancho, luego .26 con el óvalo cerrado al centro, y ahora .15. Sobre un
   fondo casi blanco el mismo velo que en oscuro se lee como LUZ, aquí se lee
   como PINTURA: el blanco no tiene margen por arriba, así que todo lo que se
   le suma se ve como un fondo de color y no como un resplandor detrás del
   bloque. A .15 vuelve a ser un tinte y el titular deja de competir con él.

   Sobre oscuro se queda en .30 a propósito: ahí sí hay margen y el velo se
   lee como luz. Que los dos temas lleven el mismo número no es coherencia,
   es no mirar la pantalla. */
:root[data-tema="claro"] .cierre::before { opacity: .15; inset: -10% 26% 6%; }

.cierre .display { margin-inline: auto; max-width: 16ch; }

/* La entradilla sube a `--t-lead-mayor`, y no es decoración: bajo un titular de
   92 px, una entradilla de 21 dejaba la razón en 4,4 y se leía como un pie de
   foto —el mismo agujero de escala que ya obligó a crear este token—. Además es
   lo que permite el resalte magenta: a 20 px en negrita ya cuenta como texto
   grande y el listón baja a 3:1, que el magenta cumple (4,24). A 17 px no
   habría cumplido. */
.cierre .lead { margin: 1.5rem auto 0; max-width: 34ch; font-size: var(--t-lead-mayor); }
.cierre .btn-grupo { margin-top: 2.5rem; justify-content: center; }

/* La cabecera de página recibe el mismo trato que la de sección: centrada y
   con la entradilla en la escala mayor. El h1 va a --t-h1 (60 px), la misma
   altura que el titular de «Tres sedes», así que la entradilla necesita la
   misma corrección: a 17 px bajo un titular de 60 la razón se abre a 3,5 y el
   párrafo se lee como un pie de foto. La medida sigue en `ch` para que crezca
   con la letra y el renglón no se pase de largo. */
/* El `padding-top` lo pone el bloque de la píldora flotante, más abajo: aquí
   había otro valor que nunca se aplicaba. */
.cabecera-pagina {
  padding-bottom: clamp(2rem, 4vw, 3rem);
  text-align: center;
}
.cabecera-pagina .lead {
  margin: 1.25rem auto 0; max-width: 52ch;
  font-size: var(--t-lead-mayor); line-height: 1.5; text-wrap: balance;
  /* --texto, no --suave: la misma corrección que la cabecera de sección. Bajo
     un titular de 60 px el gris de lo secundario convierte la entradilla en un
     pie de foto, y aquí es la frase que decide si la persona sigue leyendo. */
  color: var(--texto);
}
.cabecera-pagina .btn-grupo { justify-content: center; }
.migas { font-size: var(--t-mini); color: var(--suave); margin-bottom: 1.25rem; }
.migas a { color: var(--suave); text-decoration: none; }
.migas a:hover { color: var(--cian-claro); text-decoration: underline; }
.migas span { margin-inline: .5rem; opacity: .55; }

/* --- Formularios -------------------------------------------------------- */
.campo { display: block; margin-bottom: 1.25rem; }
.campo > span { display: block; font-size: var(--t-menor); font-weight: 500; color: var(--tinta); margin-bottom: .5rem; }
.campo input, .campo select, .campo textarea {
  width: 100%; padding: .875rem 1rem; background: var(--superficie);
  border: 1px solid var(--borde-fuerte); border-radius: var(--r-s); color: var(--tinta);
  transition: border-color 180ms ease, box-shadow 180ms ease;
}
.campo input::placeholder, .campo textarea::placeholder { color: var(--suave); opacity: 1; }
.campo input:focus, .campo select:focus, .campo textarea:focus {
  outline: none; border-color: var(--cian); box-shadow: 0 0 0 3px rgba(0, 159, 227, .18);
}
.campo textarea { min-height: 130px; resize: vertical; }
.dos-columnas { display: grid; gap: 0 1.25rem; }
@media (min-width: 620px) { .dos-columnas { grid-template-columns: 1fr 1fr; } }
/* --- Ficha de sede ------------------------------------------------------ */
.ficha { display: grid; gap: clamp(2.5rem, 6vw, 5rem); }
@media (min-width: 860px) { .ficha { grid-template-columns: 1fr 1fr; } }
/* Sin `border-top`: el bloque «la lista de datos deja de flotar», más abajo,
   la convierte en panel con borde completo y lo pone a 0. */
.datos { display: grid; }
.datos > div { display: grid; gap: .25rem 1.5rem; padding: 1.125rem 0; border-bottom: 1px solid var(--borde); }
@media (min-width: 520px) { .datos > div { grid-template-columns: 130px 1fr; } }
/* `.datos dt` y `.datos dd` se declaran una sola vez, en el bloque del panel
   más abajo. Aquí había otro par color/tamaño que no llegaba a aplicarse. */

/* --- Alterno (páginas internas) ----------------------------------------- */
.alterno { display: grid; gap: clamp(2rem, 5vw, 4.5rem); align-items: center; }
.alterno + .alterno { margin-top: clamp(4rem, 9vw, 8rem); }
.alterno-figura { border-radius: var(--r-l); overflow: hidden; background: var(--superficie-2); aspect-ratio: 4 / 3; }
.alterno-figura img { width: 100%; height: 100%; object-fit: cover; }
/* La entradilla del bloque alterno va en la escala MAYOR, igual que la de una
   cabecera de sección, y por el mismo motivo de contraste: con `--t-lead` a
   secas cae a 17 px en cuanto la ventana baja de 1440, y a 17 px el magenta de
   resalte deja de contar como texto grande —el listón pasa de 3:1 a 4,5:1 y da
   4,33—. Es la regla de la casa: magenta de resalte, solo de `--t-lead-mayor`
   para arriba. */
.alterno .lead { font-size: var(--t-lead-mayor); line-height: 1.5; color: var(--texto); }
.alterno h2, .alterno h3 { margin-bottom: 1rem; }
.alterno p + p { margin-top: 1rem; }
@media (min-width: 860px) {
  .alterno { grid-template-columns: 1fr 1fr; }
  .alterno.invertido .alterno-figura { order: 2; }
}

.pasos { display: grid; gap: 2.5rem; counter-reset: paso; }
.paso { counter-increment: paso; }
.paso::before {
  content: counter(paso, decimal-leading-zero); display: block;
  font-size: 2.75rem; font-weight: 300; letter-spacing: -0.04em; line-height: 1;
  color: var(--cian); margin-bottom: 1rem;
}
/* El número lleva el degradado de los titulares, como el resto de cifras
   grandes de la casa: en celeste plano y a peso 300 era el único número de la
   web que no hablaba el idioma de la home (17-09-2026). */
@supports ((background-clip: text) or (-webkit-background-clip: text)) {
  .paso::before {
    font-weight: 500; background-image: var(--letrero-texto);
    -webkit-background-clip: text; background-clip: text;
    color: transparent; -webkit-text-fill-color: transparent;
    width: fit-content; padding-bottom: .06em;
  }
}
.paso h3 { margin-bottom: .5rem; }
@media (min-width: 720px) { .pasos { grid-template-columns: repeat(4, 1fr); gap: 2rem; } }

.rejilla-sedes { display: grid; gap: 1.25rem; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
.sede {
  display: flex; flex-direction: column; background: var(--superficie);
  border: 1px solid var(--borde); border-radius: var(--r-l); overflow: hidden; text-decoration: none;
  transition: transform 300ms var(--sal), box-shadow 300ms var(--sal), border-color 220ms ease;
}
.sede-cuerpo { padding: 1.625rem; display: flex; flex-direction: column; flex: 1; }
.sede h3, .sede .h3 { font-size: 1.1875rem; margin-bottom: .375rem; }
.sede address { font-style: normal; color: var(--suave); font-size: var(--t-menor); }
.sede-ventaja { margin-top: 1rem; padding-top: 1rem; border-top: 1px solid var(--borde); font-size: var(--t-menor); }
.sede-ir { margin-top: 1.25rem; color: var(--cian-claro); font-weight: 500; font-size: var(--t-menor); }
@media (hover: hover) and (pointer: fine) {
  /* Solo el desplazamiento: el filo y la sombra del hover los pone el bloque
     de la tarjeta de sede más abajo, que los tiñe de celeste. */
  .sede:hover { transform: translateY(-4px); }
}

/* Aquí vivía `.precios` / `.precio` / `.precio-destacado` / `.precio-valor`:
   la tarjeta de precio ORIGINAL de /precios, doce reglas. La sustituyeron
   primero el bento de la home (`.celda-precio`) y después `.precio-caja`, y se
   quedó sin un solo uso en las 16 páginas. Retirada en la auditoría del
   17-09-2026; `.precio-cifra`, `.precio-caja` y familia siguen vivas y no
   tienen nada que ver con ésta pese al nombre. */

/* 🔴 UNA columna, no dos. Esto nació como un «esto sí / esto no» de dos
   paneles, y el panel de «esto no» se retiró porque el copy institucional tiene
   prohibido comparar con la competencia. Lo que quedó fue un componente de dos
   columnas con un solo hijo, y el HTML lo peleaba con un `style` en línea
   forzando `1fr`. Se quita la regla de dos columnas y se quita el estilo en
   línea: mismo resultado en pantalla, sin la contradicción. */
.comparativa { display: grid; gap: 1.25rem; }
.comparativa > div { padding: clamp(1.75rem, 3vw, 2.5rem); border-radius: var(--r-l); }
.comp-bien { background: rgba(0, 159, 227, .10); border: 1px solid rgba(0, 159, 227, .35); }
.comp-bien h3 { color: var(--tinta); }
.comparativa ul { margin-top: 1.5rem; display: grid; gap: .875rem; }
.comparativa li { padding-left: 1.75rem; position: relative; font-size: var(--t-menor); }
.comp-bien li::before {
  content: ""; position: absolute; left: 0; top: .45em; width: 15px; height: 9px;
  border-left: 2px solid var(--cian); border-bottom: 2px solid var(--cian); transform: rotate(-45deg);
}

/* --- Prosa -------------------------------------------------------------- */
.prosa { max-width: var(--ancho-prosa); margin-inline: auto; }
.prosa > * + * { margin-top: 1.375rem; }
.prosa h2 { font-size: clamp(1.5rem, 2.6vw, 2rem); margin-top: 3rem; }
.prosa h3 { font-size: 1.25rem; margin-top: 2.25rem; }
.prosa p, .prosa li { text-wrap: pretty; }
.prosa ul, .prosa ol { display: grid; gap: .75rem; padding-left: 1.5rem; }
.prosa ul li { list-style: disc; }
.prosa ol li { list-style: decimal; }
.prosa ul li::marker, .prosa ol li::marker { color: var(--cian-claro); }
.prosa figure { margin-block: 2.5rem; }
.prosa figure img { border-radius: var(--r-l); width: 100%; }
.prosa figcaption { margin-top: .75rem; font-size: var(--t-mini); color: var(--suave); text-align: center; }
.prosa blockquote { padding: 1.5rem 1.75rem; background: var(--superficie); border-radius: var(--r-m); color: var(--tinta); font-size: 1.125rem; }

.tabla-envoltura { overflow-x: auto; margin-block: 2rem; }
table { width: 100%; border-collapse: collapse; font-size: var(--t-menor); min-width: 460px; }
th, td { padding: .875rem 1rem; text-align: left; border-bottom: 1px solid var(--borde); }
th { color: var(--tinta); font-weight: 500; background: var(--superficie); }
td { color: var(--texto); }

/* --- Pie ---------------------------------------------------------------- */
.pie { background: var(--pie-fondo); border-top: 1px solid var(--borde); color: var(--texto); padding-block: clamp(3.5rem, 7vw, 5rem) 2.5rem; }
.pie h2, .pie h3 { color: var(--tinta); }
.pie a { color: var(--sobre-azul); text-decoration: none; font-size: var(--t-menor); }
@media (hover: hover) and (pointer: fine) { .pie a:hover { color: var(--tinta); text-decoration: underline; } }
.pie-rejilla { display: grid; gap: 2.5rem; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }
.pie-rejilla h3 { font-size: var(--t-menor); font-weight: 500; margin-bottom: 1rem; }
.pie-rejilla ul { display: grid; gap: .625rem; }
.pie-logo { height: 34px; width: auto; margin-bottom: 1rem; }
.pie-lema { font-size: var(--t-menor); max-width: 30ch; }
.pie-legal {
  margin-top: 3rem; padding-top: 2rem; border-top: 1px solid var(--borde);
  display: flex; flex-wrap: wrap; gap: 1rem 2rem; justify-content: space-between; align-items: center; font-size: var(--t-mini);
}
.pie-legal p { max-width: 62ch; }

/* --- Utilidades --------------------------------------------------------- */
.oculto-visual { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.pila { display: grid; gap: 1.25rem; }
.mt-s { margin-top: 1rem; }
.mt-m { margin-top: 2rem; }
.mt-l { margin-top: clamp(2.5rem, 5vw, 4rem); }

/* --- Motion -------------------------------------------------------------
   Nada se oculta desde CSS: los estados iniciales los pone GSAP. Si el JS no
   corre, la página se ve entera. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}


/* La píldora flota SOBRE el contenido, no encima de él en el flujo. Por eso la
   primera sección de cada página reserva su altura. */
.nav { position: fixed; top: 0; left: 0; right: 0; }
.heroe { padding-top: clamp(7rem, 12vw, 10rem); }
.cabecera-pagina { padding-top: clamp(7rem, 11vw, 9rem); }
/* Páginas sin cabecera propia que arrancan con una sección normal.

   🔴 La exclusión nombra el MOTIVO, no un color. Decía `:not(.oscura)`, y el
   motivo real es otro: la única sección que no necesita este hueco es la que
   lleva el héroe dentro, porque `.heroe` ya se lo reserva él. Atarlo a
   `.oscura` fue una coincidencia —el héroe de la home es oscuro— y se cobró la
   pieza en cuanto la 404 pasó a abrir con una sección oscura: se quedaba sin
   hueco y el titular nacía debajo de la píldora de navegación, que es fija. */
main > section:first-child:not(.cabecera-pagina):not(:has(.heroe)) { padding-top: clamp(7rem, 11vw, 9rem); }

/* Figura ancha de cabecera, usada en las páginas internas */
/* 🔴 SIN `margin-top`. La tenía —clamp(2.5rem, 6vw, 4.5rem)— y las OCHO
   páginas que usan esta figura la anulaban con `style="margin-top:0"` en línea.
   Cuando todos los usos pelean el valor por defecto, el valor por defecto está
   mal. El aire lo pone la sección que la contiene, que para eso tiene
   `padding-block`. */
.heroe-figura {
  border-radius: var(--r-xl); overflow: hidden;
  background: var(--superficie-2); aspect-ratio: 21 / 9;
}
.heroe-figura img { width: 100%; height: 100%; object-fit: cover; }
@media (max-width: 640px) { .heroe-figura { aspect-ratio: 4 / 3; border-radius: var(--r-l); } }

/* --- Cartel con botón dentro ---------------------------------------------
   Una pieza diseñada aparte (Canva) con el titular dentro, y el botón encima
   como enlace de verdad. La imagen manda la altura: `aspect-ratio` no se fija,
   así que si el cliente exporta otra proporción, no hay recorte ni hueco.

   El botón se coloca en PORCENTAJE del ancho y del alto de la imagen, no en
   píxeles: así viaja con ella al cambiar el tamaño de la pantalla y cae
   siempre en el mismo sitio del diseño. Medido sobre la pieza: en la ancha, el
   hueco libre empieza bajo el subtítulo (65 % del alto) y el texto arranca al
   4,3 % del ancho; en la vertical, bajo el bloque de texto (48 %).

   La letra del botón va en azul oscuro FIJO, no `var(--tinta)`: la pieza tiene
   fondo claro en los dos temas, y con el tema oscuro la etiqueta habría salido
   blanca sobre blanco. El marco degradado sí es el de la casa. */
.cartel {
  --cartel-x: 4.3%;
  --cartel-y: 69%;
  /* Los <figure> traen 40 px de margen del navegador: sin esto el cartel salía
     128 px más estrecho que el resto del contenido y descolocado. */
  margin: 0;
  position: relative;
  border-radius: var(--r-xl); overflow: hidden;
  background: var(--superficie-2);
}
.cartel img { display: block; width: 100%; height: auto; }
.cartel-btn {
  position: absolute; left: var(--cartel-x); top: var(--cartel-y);
  color: #10162b;
}
/* SEÑALADO DE LOS BOTONES DEGRADADOS: se RELLENAN (17-09-2026).

   Decisión del cliente, con referencia visual delante, y sustituye a la de
   «.btn-letrero:hover» de más arriba —que decía no rellenar para no competir
   con el botón primario de al lado—. Se le planteó justo eso y eligió el
   relleno en toda la web.

   Al pasar el ratón: entra el degradado, la letra pasa a blanco, el marco se
   apaga y NO queda ni halo ni canto. Una pastilla lisa, como la referencia.

   Cómo está hecho, y por qué así:
   · El relleno es un pseudo que solo cambia de OPACIDAD. Animar el degradado
     obligaría a repintarlo en cada fotograma; animar el tamaño movería el
     botón bajo el cursor.
   · `inset: -1px`, no `0`: el botón tiene 1 px de borde transparente y el
     relleno llegaba solo al borde interno, dejando ver por debajo una LÍNEA
     fina del fondo de la página —la «línea negra» que se veía sobre la pieza
     clara del cartel—.
   · `isolation: isolate` con el pseudo en z-index -1: la lección de la tarjeta
     de sede, donde un pseudo bajo un elemento que GSAP anima se iba detrás del
     fondo al limpiarse el transform.
   · `:focus-visible` hace lo mismo: con el teclado el botón se señala igual.
   · Nada de esto toca a `.btn-primario`, que sigue siendo el sólido. */
/* 🔴 «Sede más cercana» queda FUERA de todo esto (`:not([data-cerca-btn])`).
   Ese botón lleva el HAZ giratorio, que vive en la misma capa `::after`: al
   ponerle el relleno, el haz ganaba por especificidad y lo que se aplicaba era
   solo la letra blanca... sobre un botón sin relleno y sobre fondo claro. El
   botón desaparecía al pasar el ratón. Se queda con su señalado de siempre. */
.btn-letrero:not([data-cerca-btn]) { isolation: isolate; }
.btn-letrero:not([data-cerca-btn])::after {
  content: ""; position: absolute; inset: -1px; z-index: -1;
  border-radius: inherit; background: var(--letrero);
  opacity: 0;
}
@media (hover: hover) and (pointer: fine) {
  .btn-letrero:not([data-cerca-btn]) { transition: color 260ms var(--sal); }
  .btn-letrero:not([data-cerca-btn])::after,
  .btn-letrero:not([data-cerca-btn])::before { transition: opacity 260ms var(--sal); }
  /* Gana a `.oscura .btn-letrero:hover` (0,2,0) por venir después con el mismo
     peso; el blanco es fijo porque el relleno es el mismo en los dos temas. */
  .oscura .btn-letrero:not([data-cerca-btn]):hover,
  .btn-letrero:not([data-cerca-btn]):hover,
  .btn-letrero:not([data-cerca-btn]):focus-visible {
    color: #fff;
    box-shadow: none;          /* sin halo: lo pidió expresamente */
    /* Estos botones llevan TAMBIÉN `.btn-secundario`, cuyo hover pinta
       `border-color: var(--tinta)`: un aro oscuro por fuera del relleno. */
    border-color: transparent;
  }
  .btn-letrero:not([data-cerca-btn]):hover::after,
  .btn-letrero:not([data-cerca-btn]):focus-visible::after { opacity: 1; }
  .btn-letrero:not([data-cerca-btn]):hover::before,
  .btn-letrero:not([data-cerca-btn]):focus-visible::before { opacity: 0; }
  /* La home tiene su propio bloque (ver arriba) que dejaba el marco en .88 al
     pasar el cursor, y su selector pesa más. Con el relleno, el marco tiene
     que apagarse también allí. */
  body[data-pagina="home"] .btn-letrero:not([data-cerca-btn]):hover::before,
  body[data-pagina="home"] .btn-letrero:not([data-cerca-btn]):focus-visible::before { opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .btn-letrero:not([data-cerca-btn]),
  .btn-letrero:not([data-cerca-btn])::after,
  .btn-letrero:not([data-cerca-btn])::before { transition-duration: 1ms; }
}
/* En el teléfono el botón sale DE la imagen y se pone debajo, a todo el ancho.
   La pieza vertical no tiene hueco libre: el único sitio despejado es la
   columna izquierda, y ahí el botón no cabe (200 px de botón en 300 de caja),
   así que caía sobre la cara del piloto. Medido a 390 y a 360 px. */
@media (max-width: 700px) {
  .cartel { border-radius: var(--r-l); }
  /* 🔴 `position: relative`, NUNCA `static`: el marco degradado de
     `.btn-letrero` es un pseudo con `inset: 0`, y con el botón sin posicionar
     se anclaba al `.cartel` —un aro del tamaño de la imagen entera—. */
  .cartel-btn {
    position: relative; inset: auto;
    display: flex; margin-top: .875rem;
    width: 100%; justify-content: center;
    color: var(--tinta);
  }
  .cartel { overflow: visible; }
  .cartel picture { display: block; border-radius: var(--r-l); overflow: hidden; }
}



/* --- Tarjetas de sede ----------------------------------------------------
   Forma tomada de la referencia: la foto se apoya sobre una cuña de marca que
   asoma en dos esquinas opuestas. Allí la cuña es azul plano; aquí es el
   degradado del letrero, que es lo mismo dicho con los colores de ellos.
   Todo el texto va centrado y la sede es una unidad de conversión completa:
   foto, dirección, por qué esa, y el botón de agendar en el mismo sitio. */
.sedes-tarjetas {
  display: grid;
  gap: clamp(1.25rem, 2.5vw, 1.75rem);
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
}

/* 🔴 Sin relleno: la foto va A SANGRE por arriba y por los lados. El relleno
   que tenía la tarjeta lo asume ahora el cuerpo, sumado al suyo, para que el
   texto se quede exactamente donde estaba. Lo que cambia es la foto. */
.sede-card {
  display: flex;
  flex-direction: column;
  padding: 0;
  text-align: center;
  border: 1px solid var(--borde);
  border-radius: var(--r-xl);
  background: var(--superficie);
  transition: transform 400ms var(--sal), border-color 300ms ease, box-shadow 400ms var(--sal);
}
@supports (backdrop-filter: blur(1px)) {
  .sede-card { backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px); }
}

/* La foto ocupa el ancho ENTERO de la tarjeta y llega hasta el borde de
   arriba. Antes flotaba dentro del relleno, como un rectángulo redondeado
   pegado sobre la tarjeta; ahora es la cabecera de la tarjeta.

   Se fueron con el cambio dos cosas, y las dos por el mismo motivo:

   · La CUÑA del letrero, que asomaba por las esquinas redondas de la foto.
     Con la foto pegada a los bordes, arriba quedaría cortada por la esquina
     de la tarjeta y abajo, contra una línea recta, no tiene dónde asomar.
   El DESVANECIDO de abajo, en cambio, SE QUEDA. Se quitó al pasar la foto a
   sangre con el argumento de que una foto que termina en una línea recta de
   lado a lado es estructura y no un corte. Visto en pantalla, el argumento no
   se sostiene: esa línea recta es el único canto duro de toda la página. El
   mismo gesto —degradado del letrero, máscara que disuelve el borde— sostiene
   el recorte de los gemelos del héroe y la foto de la sede; quitarlo aquí
   dejaba a estas tres tarjetas hablando un idioma distinto al del resto.
   Devuelto el 14-09-2026, con los mismos números que tenía.

   🔴 El radio va en `calc(var(--r-xl) - 1px)`, no en `var(--r-xl)` a secas: la
   tarjeta tiene 1 px de borde, y el radio de la cara INTERNA de un borde es
   el de fuera menos su grosor. Con el radio de fuera asoma un pelo de fondo
   entre el borde y la foto, justo en las dos esquinas de arriba.

   La proporción sigue siendo φ (1,618) y no 16/10 (1,600). Aquí SÍ aplica la
   áurea: un recorte de foto es exactamente el caso para el que sirve —fijar
   un rectángulo agradable de una vez—. La foto crece porque ahora es más
   ancha, no porque se le haya cambiado la forma. */
.sede-card-foto {
  position: relative;
  aspect-ratio: 1.618;
  border-radius: calc(var(--r-xl) - 1px) calc(var(--r-xl) - 1px) 0 0;
  background: var(--capa-1);
  overflow: hidden;
  /* Va con MÁSCARA y no con un degradado pintado encima: un degradado
     necesitaría saber de qué color es el fondo, y aquí hay dos temas y una
     superficie translúcida. La máscara no pinta, quita opacidad, así que deja
     ver lo que haya debajo —el vidrio de la tarjeta— y vale en los dos temas.

     Va sobre el CONTENEDOR y no sobre la <img> por una razón que ahora pesa
     más que antes: la <img> se amplía en el hover, y una máscara montada en
     ella se ampliaría con la foto, así que el punto donde empieza a
     desvanecerse subiría y bajaría al pasar el ratón. En el contenedor se
     queda quieta. */
  -webkit-mask-image: linear-gradient(to bottom, #000 62%, rgba(0, 0, 0, .35) 84%, transparent 100%);
          mask-image: linear-gradient(to bottom, #000 62%, rgba(0, 0, 0, .35) 84%, transparent 100%);
}
/* Sin radio propio: lo pone el contenedor y lo recorta con `overflow`. Si lo
   llevara el <img>, al ampliarse en el hover la esquina redonda se movería
   con la imagen y se saldría del recorte. */
.sede-card-foto img {
  display: block;
  width: 100%; height: 100%; object-fit: cover;
  transition: transform 900ms var(--sal);
}

/* Los laterales son la suma de los dos rellenos que había antes —el de la
   tarjeta (1 a 1,25 rem) y el suyo (0,5 a 1 rem)—, así que el texto no se
   mueve ni un píxel. Abajo pasa lo mismo: recoge el relleno inferior que la
   tarjeta ya no tiene. */
.sede-card-cuerpo {
  display: flex; flex-direction: column; flex: 1;
  padding: clamp(1.375rem, 2vw, 1.75rem) clamp(1.5rem, 3vw, 2.25rem) clamp(1.5rem, 2.6vw, 2rem);
}
.sede-card-cuerpo h3 {
  font-size: 1.1875rem; letter-spacing: -0.015em; color: var(--tinta);
}
.sede-card address {
  font-style: normal; margin-top: .625rem;
  font-size: 0.9375rem; line-height: 1.5; color: var(--suave);
}
.sede-card-ventaja {
  margin-top: 1.125rem;
  font-size: 0.9375rem; line-height: 1.5; font-weight: 500; color: var(--tinta); flex: 1;
}
.sede-card-acciones {
  display: flex; flex-direction: column; align-items: center; gap: .75rem;
  margin-top: 1.5rem;
}
.sede-card-acciones .btn { padding: .8125rem 1.75rem; font-size: 0.9375rem; }
.sede-card-acciones .btn-texto { padding: 0; font-size: 0.875rem; }

/* 🔴 Aquí había una mentira, corregida el 14-09-2026. El comentario decía
   «el filo de resalte es MAGENTA, no cian» y explicaba muy bien por qué —el
   cian es el color de lo que se pulsa; usarlo también para «esta es la
   señalada» mezcla dos mensajes—, pero el código de debajo pintaba CIAN, y
   además metía en la misma regla el hover, el foco y la sede más cercana.
   Resultado: la tarjeta que ganaba se veía exactamente igual que cualquier
   tarjeta con el ratón encima. El estado existía y no se notaba.

   Ahora son dos cosas distintas y se leen distintas:
     · cian  = esto responde (ratón encima, teclado dentro). Se va al salir.
     · magenta = esta es la tuya. Se queda puesto. */
.sede-card:focus-within {
  border-color: rgba(0, 159, 227, .45);
  box-shadow: var(--sombra-media), var(--brillo-cian);
}
@media (hover: hover) and (pointer: fine) {
  .sede-card:hover {
    transform: translateY(-6px);
    border-color: rgba(0, 159, 227, .45);
    box-shadow: var(--sombra-media), var(--brillo-cian);
  }
  .sede-card:hover .sede-card-foto img { transform: scale(1.05); }
}

/* La sede que salió más cercana. Va DESPUÉS del hover a propósito: con la
   misma especificidad gana la última, así que el filo magenta no se lo come
   el cian cuando pasas el ratón por encima de la tarjeta marcada. El
   `:hover` y el `:focus-within` se repiten aquí por lo mismo, que son (0,3,0)
   y si no ganarían ellos.

   Es UN SOLO pelo de 1 px, el borde que la tarjeta ya tenía, cambiado de
   color. Nada de engordarlo: un borde que crece al aparecer movería 1 px el
   contenido de esa tarjeta y sólo de ésa, y la fila entera se desalinearía
   justo en el momento en que se quiere mirar. Hubo un aro extra de 1 px en
   `box-shadow` para esquivar eso; se quitó el 14-09-2026 porque 2 px de
   magenta pleno pesaban más que la píldora, que es la que lleva el dato. */
.sede-card[data-cercana],
.sede-card[data-cercana]:hover,
.sede-card[data-cercana]:focus-within {
  border-color: var(--filo-cercana);
  box-shadow: var(--sombra-media), var(--brillo-magenta);
}

/* El HAZ: una luz celeste→magenta que recorre el filo de la sede más cercana.
   Pedido el 16-09-2026 a partir de un componente «BorderBeam» de React, pasado
   a CSS (sin JS: lo único que hacía su JS era meter estos estilos).

   Por qué AQUÍ y en ningún otro sitio: es el único estado de la página que
   dice «esta es la tuya», y lo aparece el propio usuario al pulsar el botón.
   Un haz en todas las tarjetas sería decoración; en una sola, señala.

   Cómo está hecho:
   · El filo magenta de 1 px de arriba SE QUEDA debajo. El haz va encima y
     solo añade luz: sin `@property`, sin `mask-composite` o con movimiento
     reducido, la tarjeta sigue marcada igual que antes.
   · `conic-gradient` y no el `linear-gradient` del original: uno lineal que
     gira pinta DOS franjas barriendo lados opuestos; el cónico es una sola
     luz que da la vuelta de verdad.
   · Máscara que se resta (el mismo truco que `.btn-letrero`): se ve solo el
     contorno. Va en un pseudo con `inset: -1px` para quedar SOBRE el borde,
     y el radio +1 px por lo mismo. No mueve el maquetado.
   · Anima una propiedad registrada: se repinta el filo en cada fotograma, no
     va por la GPU. Para UN elemento no cuesta nada; por eso no se extiende.
   · Sin `blur()`: no tiene el problema de Safari (ver `blur-guardia.js`). */
@property --giro { syntax: "<angle>"; initial-value: 0deg; inherits: false; }
@keyframes haz-gira { to { --giro: 360deg; } }
@keyframes haz-aparece { from { opacity: 0; } }

@supports ((mask-composite: exclude) or (-webkit-mask-composite: xor)) {
  .sede-card[data-cercana],
  .elige-sede[data-cercana],
  .cerca-ficha { position: relative; }
  .sede-card[data-cercana]::after,
  .elige-sede[data-cercana]::after,
  .cerca-ficha::after {
    content: ""; position: absolute; inset: -1px; z-index: 2; pointer-events: none;
    border-radius: calc(var(--r-xl) + 1px); padding: 1.5px;
    background: conic-gradient(from var(--giro),
      transparent 0 60%, rgba(0, 159, 227, .9) 80%, var(--magenta) 94%, transparent 100%);
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
            mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
            mask-composite: exclude;
    animation: haz-gira 5s linear infinite, haz-aparece .6s ease-out both;
  }
  .cerca-ficha::after,
  .elige-sede[data-cercana]::after { border-radius: calc(var(--r-l) + 1px); }
}
/* El mismo haz en el BOTÓN «Sede más cercana» (pedido el 16-09-2026). Aquí
   invita a pulsar; en la tarjeta señala la respuesta. Por eso la luz PASA del
   uno a la otra: en cuanto hay una sede marcada, el botón la apaga. Dos haces
   a la vez —en el teléfono, botón y ficha quedan uno encima del otro— se
   pisarían, y ninguno diría nada.

   El botón ya lleva un marco DEGRADADO de 2 px (.btn-letrero::before), así
   que un haz celeste→magenta encima no se vería: sería el mismo color sobre
   el mismo color. Aquí el haz es un BRILLO blanco que recorre el marco, con
   colas celeste y magenta para que empalme con él. Mismo grosor que el marco
   e inset: 0, así que tapa el marco exacto y no mueve nada. */
@supports ((mask-composite: exclude) or (-webkit-mask-composite: xor)) {
  .btn-letrero[data-cerca-btn]::after {
    content: ""; position: absolute; inset: 0; pointer-events: none;
    border-radius: inherit; padding: 2px;
    background: conic-gradient(from var(--giro),
      transparent 0 58%, rgba(0, 159, 227, .9) 74%, rgba(255, 255, 255, .95) 86%, var(--magenta) 95%, transparent 100%);
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
            mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
            mask-composite: exclude;
    animation: haz-gira 5s linear infinite, haz-aparece .6s ease-out both;
  }
  body:has(.sede-card[data-cercana]) .btn-letrero[data-cerca-btn]::after,
  body:has(.elige-sede[data-cercana]) .btn-letrero[data-cerca-btn]::after { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .sede-card[data-cercana]::after,
  .elige-sede[data-cercana]::after,
  .cerca-ficha::after,
  .btn-letrero[data-cerca-btn]::after { display: none; }
}

/* La distancia solo existe después de pulsar «cuál me queda más cerca», así
   que nace oculta: sin JS o sin permiso, la tarjeta se ve entera igual. */
.sede-card-cerca {
  margin-top: .75rem; font-size: .875rem; font-weight: 500;
  color: var(--resalte-magenta);
}
.sede-card-cerca[hidden] { display: none; }
/* La etiqueta de la más cercana. Va con texto, no solo con el filo de color:
   un estado que solo se anuncia por color no existe para quien no lo ve.

   Va SOBRE la foto y no dentro del cuerpo. Dentro empujaba el titular de esa
   tarjeta hacia abajo y desalineaba la fila entera: la única tarjeta marcada
   quedaba con el nombre a distinta altura que sus dos hermanas. Sobre la foto
   no ocupa sitio en el flujo, así que aparecer no mueve nada. */
/* 1 rem y no 0,75: la píldora se mide contra el borde de la FOTO, y la foto
   ahora llega al borde de la tarjeta. Con 0,75 quedaba pegada al canto. */
.sede-card-insignia {
  position: absolute; top: 1rem; left: 1rem; z-index: 1;
  display: inline-flex; align-items: center;
  padding: .4375rem .875rem; border-radius: 999px;
  /* Fondo sólido: encima de una foto, un fondo translúcido deja el texto a
     merced de lo que haya debajo y el contraste pasa a ser una lotería.

     Relleno MAGENTA, por petición del cliente (14-09-2026). Antes era azul con
     un aro magenta, porque blanco sobre `--magenta` da 4,5008:1 contra un
     mínimo de 4,5 y no quería publicar en el filo de la norma.

     🔴 Cumple, pero SIN MARGEN: son ocho diezmilésimas. Se asume a sabiendas,
     y por las mismas razones por las que el celeste de marca se quedó sin
     retocar: el color de marca manda. Lo que lo hace sostenible aquí es que
     esta etiqueta NO es la única señal —la tarjeta lleva su filo magenta y
     debajo aparece la distancia escrita—, así que si alguien no la lee bien,
     no se pierde la información, sólo el adorno.

     El aro se va: con el relleno magenta no separaba nada, sólo engordaba la
     píldora. El relleno que se pierde se devuelve en el `padding`, para que
     la etiqueta siga midiendo lo mismo que medía. */
  background: var(--magenta); border: 0;
  font-size: .8125rem; font-weight: 700; color: #fff;
  box-shadow: 0 4px 14px rgba(0, 0, 0, .35);
}
.sede-card-insignia[hidden] { display: none; }

/* --- «¿Cuál me queda más cerca?» ---------------------------------------- */
.sedes-cerca { margin-top: 1.5rem; }
.sedes-cerca[hidden] { display: none; }
.sedes-cerca-aviso {
  margin-top: .75rem; font-size: var(--t-menor); color: var(--texto);
  min-height: 1.5em;   }
/* La letra pequeña. Va aparte del aviso y en tamaño mini porque es una nota al
   pie, no el resultado: el resultado se lee, esto se consulta. */
.sedes-cerca-nota {
  margin-top: .375rem; font-size: var(--t-mini); color: var(--suave);
}
.sedes-cerca-nota[hidden] { display: none; }

/* La tarjeta deja de ser un enlace entero (no se puede meter un botón dentro
   de un <a>), así que el hover se dispara desde la tarjeta, no desde el ancla */
.sede { background: var(--superficie); }
@supports (backdrop-filter: blur(1px)) {
  .sede { backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px); }
}
@media (hover: hover) and (pointer: fine) {
  .sede:hover { border-color: rgba(0, 159, 227, .4); box-shadow: var(--sombra-media), var(--brillo-cian); }
}

/* --- Cita destacada: sobre oscuro necesita un filo, no solo un fondo ----- */
.prosa blockquote { border-left: 3px solid var(--cian); }

/* --- Tablas: la cabecera se apoya en el filo de marca -------------------- */
th { border-bottom-color: var(--borde-fuerte); }


/* --- Bloque de ficha (contacto y páginas de sede) ------------------------
   Aquí el titular a escala de portada no cabía: son datos, no un anuncio. */
.ficha h2, .ficha .h2 {
  font-size: clamp(1.3125rem, 1.9vw, 1.625rem);
  letter-spacing: -0.02em;
}
.ficha .lead { font-size: var(--t-cuerpo); }
/* 🔴 Menos la de una CABECERA DE BLOQUE, que vuelve a la escala mayor.
   `.ficha .lead` pesa (0,2,0) exactamente igual que `.cabeza-bloque .lead`,
   pero vive 1.300 líneas más abajo: ganaba por orden y le bajaba la entradilla
   a 17 px. Y a 17 px el magenta de resalte deja de ser texto grande —el listón
   sube de 3:1 a 4,5:1 y da 4,33—. Medido en /contacto con `barrido-contraste`,
   y es la tercera vez en este archivo que dos reglas del mismo peso se
   resuelven por orden sin que nadie lo quisiera. */
.ficha .cabeza-bloque .lead { font-size: var(--t-lead-mayor); }

/* La lista de datos deja de flotar: es un panel, como cualquier otra tarjeta */
.datos {
  border-top: 0;
  padding: clamp(1.25rem, 2.4vw, 1.75rem) clamp(1.25rem, 2.4vw, 1.75rem) .25rem;
  border: 1px solid var(--borde);
  border-radius: var(--r-l);
  background: var(--superficie);
}
@supports (backdrop-filter: blur(1px)) {
  .datos { backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px); }
}
.datos > div:last-child { border-bottom: 0; }
.datos dt { color: var(--suave); font-size: var(--t-mini); letter-spacing: .01em; }
.datos dd { color: var(--tinta); font-size: var(--t-menor); }
.datos dd a { color: var(--cian-claro); }

/* El botón de agendar va pegado a la dirección, no al final de la página */
.datos-accion { margin-top: 1.5rem; }
.datos-accion .btn { padding: .8125rem 1.5rem; font-size: var(--t-menor); }


/* La cabecera se ensancha (46 → 58rem) porque el titular creció. Con 46rem,
   «Tres sedes en Bogotá» a 60 px se partía en dos líneas y la entradilla
   dejaba «tarifa.» sola en la suya. */
.sedes-cabeza { text-align: center; max-width: 58rem; margin: 0 auto clamp(2rem, 4vw, 3rem); }

/* 60 px (`--t-h1`), no 32. Era el ÚNICO titular de sección de la home por
   debajo de los 50 px de sus hermanos, y encima presidía las tarjetas más
   grandes de la página: se leía como un epígrafe, no como el título de la
   sección. Sube a un paso EXISTENTE de la escala —el de título de página— que
   lo pone por encima de los h2 normales sin llegar a los 88 px del héroe. */
.sedes-cabeza h2 { font-size: var(--t-h1); }

/* 🔴 `> p`, no `p`. Como descendiente, esta regla (0,1,1) le ganaba a
   `.sedes-cerca-aviso` y `.sedes-cerca-nota` (0,1,0) y pintaba el aviso y la
   letra pequeña a 23 px en color de texto: la nota al pie salía del mismo
   tamaño que la entradilla. Es la misma trampa que un día pintó el precio de
   la home a 15 px en gris. Se arregla ACOTANDO la regla a lo que describe —el
   párrafo de la cabecera—, no subiéndole la especificidad a las otras dos. */
.sedes-cabeza > p {
  margin: 1.125rem auto 0; max-width: 40rem;
  font-size: var(--t-lead-mayor); line-height: 1.5; color: var(--texto);
  /* `balance` y no `pretty`: son dos líneas, y `pretty` solo protege la última
     —dejaba «tarifa.» sola—. `balance` reparte el texto entre las dos. */
  text-wrap: balance;
}

/* --- Sellos sin placa ----------------------------------------------------
   Ver nota arriba: blanco monocromo para las marcas de línea, color intacto
   para las que traen caja propia. */
.acredita-fila img,
.respalda-sello img {
  filter: brightness(0) invert(1);
  opacity: .72;
  transition: opacity 240ms ease;
}
.acredita-fila img.sello-color,
.respalda-sello img.sello-color { filter: none; opacity: 1; }
@media (hover: hover) and (pointer: fine) {
  .acredita-fila img:hover { opacity: 1; }
}

/* --- Valoraciones --------------------------------------------------------
   Solo queda la REJILLA. La tarjeta plana (.valoracion, .valoracion-foto,
   .valoracion-cuerpo, .valoracion-num) murió cuando las cuatro valoraciones
   pasaron a `.tarjeta-alta`, y se quedó aquí sin que nadie la mirara: 11
   selectores que no alcanzaban a un solo elemento en ninguna de las 16
   páginas. Medido con `herramientas/codigo-muerto.js`.
   Si vuelve a hacer falta una tarjeta plana, se escribe de nuevo. */
.valoraciones {
  display: grid;
  gap: clamp(1rem, 1.8vw, 1.25rem);
  grid-template-columns: 1fr;
}
@media (min-width: 620px)  { .valoraciones { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1060px) { .valoraciones { grid-template-columns: repeat(4, 1fr); } }


/* ============================================================================
   TEMA CLARO
   La misma página con los tokens dados la vuelta. El atributo vive en <html>
   y lo pone un script en el <head> antes de pintar, para que no haya destello.
   Sin JS no hay atributo y manda el tema oscuro, que es el diseñado.
   ========================================================================== */
:root[data-tema="claro"] {
  color-scheme: light;

  --fondo: #f6f8fc;

  /* Las superficies se invierten: el vidrio deja de ser blanco sobre oscuro y
     pasa a ser blanco sobre un fondo levemente teñido. */
  --superficie: rgba(255, 255, 255, .86);
  --superficie-2: rgba(16, 22, 43, .05);
  --velo: rgba(255, 255, 255, .62);
  --borde: rgba(16, 22, 43, .10);
  --borde-fuerte: rgba(16, 22, 43, .18);
  --capa-1: rgba(16, 22, 43, .05);
  --capa-2: rgba(16, 22, 43, .12);

  /* Sobre claro, la tinta de titular ES el azul de marca. Antes era #10162b,
     un marino casi negro que no salía del manual: se leía como negro azulado
     y desperdiciaba el único sitio donde el azul institucional puede ser
     TEXTO (sobre oscuro es imposible, se hunde en el fondo). Medido contra el
     fondo real compuesto (#f3f5fa, no el token) da 13,2:1. */
  --tinta: var(--azul);

  /* El cuerpo de texto es TAMBIÉN el azul de marca: sobre claro no queda ni un
     solo texto negro en la página. Antes era #3d4763, un pizarra azulado que a
     ojo se lee como negro.

     Contraste: el mismo que `--tinta`, 13,2:1 contra el fondo real compuesto
     (#f3f5fa, no el token) — el listón de AA son 4,5. Sobra.

     Lo que se pierde a cambio es el escalón de COLOR entre titular y párrafo:
     ahora la jerarquía la sostienen el tamaño y el peso, no el tono. Es una
     decisión, no un descuido. Y desde el 13-09-2026 `--suave` tampoco hace de
     tercer nivel: vale este mismo azul. Ver el bloque de aquí abajo. */
  --texto: var(--azul);
  /* === TODO EL TEXTO DEL TEMA CLARO ES EL AZUL DE MARCA ================
     Decisión del cliente, 2026-09-13: lo secundario también va en #19255a.
     Antes era #475473, un gris azulado medido a 4,63:1 en la zona más teñida
     del campo (el original, #5c6b8a, se quedaba en 3,3 y no pasaba).

     En CONTRASTE esto solo mejora: de 4,63:1 sube a 13,2:1.

     Lo que se pierde es el tercer escalón de la jerarquía. `--tinta`,
     `--texto` y `--suave` valen ahora EL MISMO color, así que entradillas,
     pies de foto, direcciones y letra pequeña se pintan igual que el cuerpo y
     que el titular. La jerarquía la sostienen entera el TAMAÑO y el PESO.

     Si algún día se quiere recuperar ese escalón sin salirse del manual, la
     vía es el MISMO azul rebajado contra el fondo
     (`color-mix(in srgb, var(--azul) 72%, var(--fondo))`), no volver a meter
     un gris que no está en la marca. */
  --suave: var(--azul);
  --sobre-azul: var(--azul);

  /* === EL CELESTE DE MARCA TAMBIÉN SOBRE CLARO ==========================
     Decisión del cliente, 2026-09-13: el celeste del manual es #009fe3 y se
     usa TAL CUAL en los dos temas, degradados incluidos. Antes el tema claro
     lo oscurecía a #00719f.

     Lo que cuesta, medido, no estimado. #009fe3 sobre el blanco de este tema
     da 2,79-2,96:1. AA pide 4,5 para texto normal y 3 para texto grande, así
     que el celeste NO llega ni al listón de texto grande, y no es cuestión de
     afinar el fondo: el blanco puro ya es el fondo más favorable que existe.

       - 82 nodos de texto por debajo de 4,5 (12 selectores distintos)
       - 13 titulares con degradado por debajo de 3
       - el tema OSCURO no se toca: ahí el mismo color da 6,1:1

     Queda anotado aquí y no solo en el acta porque el próximo que abra
     `barrido-contraste.js` va a ver 82 fallos y va a pensar que son un bug.
     No lo son: son una decisión de marca tomada con el número delante.

     Si algún día se quiere recuperar AA sin perder el color, la vía NO es
     retocar el celeste: es cambiar lo que hay DETRÁS (llevar esos textos a
     una sección `.oscura`, o darles una pastilla de fondo teñida). */
  --cian-claro: var(--cian);

  /* El arranque del letrero escrito vuelve al celeste de marca. Las otras dos
     paradas ya cumplían sobre claro —el violeta 5,2:1 y el magenta 4,2:1— y
     se quedan igual.

     Aquí NO se aclara el final como en oscuro: sobre blanco el magenta ya es
     la parada más luminosa de las tres, así que el desequilibrio no existe.
     Y aclararlo lo tumbaría: el #ff4da6 del tema oscuro da 2,88:1 sobre este
     fondo. */
  --letrero-texto: linear-gradient(100deg, var(--cian) 0%, #6b57c4 44%, var(--magenta) 100%);

  /* El magenta del manual se queda tal cual: sobre claro da 4,24:1 y, como el
     resalte va en 700 a 18,7 px, el listón son 3:1. Cumple sin retocarlo. */
  --resalte-cian: var(--cian);
  --resalte-magenta: var(--magenta);

  /* Sobre claro el aclarado no vale: #ff4da6 da 2,88:1 contra este fondo. Va
     al revés, oscureciendo. */
  --enlace-magenta: #d4007a;

  --nav-vidrio: rgba(255, 255, 255, .78);
  --nav-vidrio-fijo: rgba(255, 255, 255, .94);
  --nav-sombra: 0 14px 40px rgba(16, 22, 43, .10);
  --pie-fondo: rgba(16, 22, 43, .04);

  /* Sobre claro la elevación vuelve a ser sombra, no luz */
  --sombra-media: 0 2px 6px rgba(16, 22, 43, .05), 0 22px 60px rgba(16, 22, 43, .10);
  --sombra-alta: 0 30px 80px rgba(16, 22, 43, .16);
  --brillo-cian: 0 18px 50px rgba(0, 159, 227, .18);
  --filo-cercana: rgba(230, 0, 126, .72);
  --brillo-magenta: 0 18px 50px rgba(230, 0, 126, .14);
}

/* El campo de luz: los mismos cuatro focos de marca, pero como reflejos sobre
   blanco en vez de resplandores sobre negro. */
:root[data-tema="claro"] body::before {
  background:
    radial-gradient(80% 55% at 50% -6%, rgba(0, 159, 227, .24) 0%, transparent 66%),
    radial-gradient(56% 42% at 98% 20%, rgba(0, 159, 227, .18) 0%, transparent 64%),
    radial-gradient(62% 48% at -2% 54%, rgba(107, 87, 196, .16) 0%, transparent 66%),
    radial-gradient(70% 52% at 90% 92%, rgba(230, 0, 126, .09) 0%, transparent 64%);
}
/* El grano en modo overlay sobre claro emblanquece en vez de texturar */
:root[data-tema="claro"] body::after { opacity: .14; mix-blend-mode: multiply; }

/* Botón principal: sobre claro es el azul de marca. Un botón cian con texto
   marino se lee, pero el azul es el que manda en el manual sobre fondo claro. */
:root[data-tema="claro"] .btn-primario,
:root[data-tema="claro"] .nav-cta,
:root[data-tema="claro"] .nav-hoja .btn { background: var(--azul); color: #fff; font-weight: 500; }
:root[data-tema="claro"] .saltar { background: var(--azul); color: #fff; }
@media (hover: hover) and (pointer: fine) {
  :root[data-tema="claro"] .btn-primario:hover,
  :root[data-tema="claro"] .nav-cta:hover {
    background: var(--azul-700); box-shadow: 0 12px 30px rgba(25, 37, 90, .28);
  }
}

/* `.oscura .btn-texto` fuerza --cian (#009fe3) porque sobre el oscuro cumple
   (6,06:1). Sobre claro ese mismo cian da 2,95:1 y NO cumple AA. Afecta a los
   tres «Ver la sede →» de las tarjetas de sede y a la sección de Tarifas cuando
   sube al héroe en el teléfono. Sobre claro baja al token de texto. */
:root[data-tema="claro"] .oscura .btn-texto { color: var(--cian-claro); }

/* Filos finos en cian puro: sobre claro se quedan cortos */
:root[data-tema="claro"] .celda-azul li::before,
:root[data-tema="claro"] .comp-bien li::before { border-color: var(--cian-claro); }
:root[data-tema="claro"] .paso::before { color: var(--cian-claro); }

/* Los bloques de acento: el tinte cian se aclara para no ensuciar el blanco */
:root[data-tema="claro"] .celda-azul,
:root[data-tema="claro"] .comp-bien { background: rgba(0, 159, 227, .07); border-color: rgba(0, 159, 227, .28); }

/* Los sellos vuelven a su color: en blanco monocromo desaparecerían */
:root[data-tema="claro"] .acredita-fila img,
:root[data-tema="claro"] .respalda-sello img { filter: none; opacity: 1; }

/* El resplandor detrás de la foto del héroe, más contenido sobre claro */
:root[data-tema="claro"] .heroe-gemelos-int::before { opacity: .28; }
/* Mismo motivo que en oscuro: el peor punto del titular pasaba de 3,62:1 a
   3,96:1 al bajar de .26 a .18. Sobre claro el resplandor tiñe el papel y el
   tramo magenta de las letras es el que lo nota. */
:root[data-tema="claro"] .heroe-rejilla::before { opacity: .18; }

/* --- Logo: blanco sobre oscuro, a color sobre claro --------------------- */
.logo-claro { display: none; }
:root[data-tema="claro"] .logo-oscuro { display: none; }
:root[data-tema="claro"] .logo-claro { display: block; }

/* --- Botón de cambio de tema -------------------------------------------- */
.nav-tema {
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; flex-shrink: 0;
  background: none; border: 0; border-radius: 999px;
  color: var(--suave); cursor: pointer;
  transition: background-color 180ms ease, color 180ms ease;
}
.nav-tema svg { width: 18px; height: 18px; }
.nav-tema .icono-luna { display: none; }
:root[data-tema="claro"] .nav-tema .icono-sol { display: none; }
:root[data-tema="claro"] .nav-tema .icono-luna { display: block; }
@media (hover: hover) and (pointer: fine) {
  .nav-tema:hover { background: var(--capa-1); color: var(--tinta); }
}
/* --- Barra de acción: agendar siempre a un dedo -------------------------- */
.barra-movil {
  display: none;
  position: fixed; left: 0; right: 0; bottom: 0; z-index: var(--z-barra);
  gap: .625rem;
  padding: .625rem var(--canal);
  padding-bottom: calc(.625rem + env(safe-area-inset-bottom));
  border-top: 1px solid var(--borde);
  background: var(--nav-vidrio-fijo);
}
@supports (backdrop-filter: blur(1px)) {
  .barra-movil { backdrop-filter: saturate(180%) blur(20px); -webkit-backdrop-filter: saturate(180%) blur(20px); }
}
.barra-movil-cta {
  flex: 1; min-height: 52px; padding-top: .875rem; padding-bottom: .875rem;
  font-size: 1.0625rem;
}
.barra-movil-wa {
  flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center;
  width: 52px; height: 52px; border-radius: 999px;
  border: 1px solid var(--borde-fuerte); color: var(--tinta);
}
.barra-movil-wa svg { width: 23px; height: 23px; }

@media (max-width: 979px) {
  .barra-movil { display: flex; }
  /* Que la barra no se coma el final del pie */
  .pie { padding-bottom: calc(2.5rem + 76px + env(safe-area-inset-bottom)); }
  /* En /agendar la página entera ya es el formulario: la barra sobra y además
     taparía el botón de enviar. */
  body[data-pagina="agendar"] .barra-movil { display: none; }
  body[data-pagina="agendar"] .pie { padding-bottom: calc(2.5rem + env(safe-area-inset-bottom)); }
}
/* Se aparta mientras el menú está abierto: la hoja ya lleva su propio botón.
   La regla va FUERA de la consulta de movimiento —apartarse no es decoración,
   es no tapar el botón de cerrar— y dentro solo queda la transición. Estaba
   escrita dos veces, una dentro y otra fuera; la de dentro no hacía nada. */
body:has(.nav-hoja[data-abierta="si"]) .barra-movil { transform: translateY(120%); }
@media (prefers-reduced-motion: no-preference) {
  .barra-movil { transition: transform 320ms var(--sal); }
}

@media (max-width: 979px) {

  /* --- Ritmo: el mismo diseño, menos aire ------------------------------- */
  :root {
    --seccion: 3.5rem;
    --seccion-corta: 2.75rem;
    --t-display: 2.5rem;
  }
  /* El aire de la cabecera lo baja ahora `--aire-cabeza`, arriba en este
     mismo bloque: la regla suelta que había aquí no alcanzaba a las listas. */

  /* --- Héroe: que la primera pantalla llegue al botón -------------------
     El `padding-top` del héroe en el teléfono se declara UNA vez, más abajo en
     este mismo @media, junto al tamaño del titular: aquí había otro valor
     (88px + .75rem) que la regla posterior pisaba sin que se notara. */
  .heroe .display { max-width: none; }      /* 13ch en 350 px son cuatro líneas */
  .heroe .lead { margin-top: 1.125rem; }
  .heroe .btn-grupo { margin-top: 1.75rem; }
  
/* --- Rieles deslizables ----------------------------------------------
     Tres tarjetas de sede apiladas eran 1.700 px: dos pantallas para elegir
     entre tres opciones. En riel ocupan una y se comparan de un vistazo.
     No se oculta nada: el contenido es el mismo, cambia el eje.
     El sangrado negativo hace que la siguiente tarjeta asome por el borde,
     que es lo que le dice al dedo que hay más. */
  .sedes-tarjetas,
  .valoraciones,
  .guias,
  .resenas-lista {
    display: flex;
    grid-template-columns: none;
    gap: .875rem;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scroll-padding-inline: var(--canal);
    padding-inline: var(--canal);
    margin-inline: calc(var(--canal) * -1);
    padding-bottom: .5rem;           /* aire para la sombra al desplazar */
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .sedes-tarjetas::-webkit-scrollbar,
  .valoraciones::-webkit-scrollbar,
  .guias::-webkit-scrollbar,
  .resenas-lista::-webkit-scrollbar { display: none; }

  .sedes-tarjetas > *,
  .valoraciones > *,
  .guias > *,
  .resenas-lista > * {
    flex: 0 0 84%;
    max-width: 320px;
    scroll-snap-align: center;
  }

  /* En un riel el hover no existe; el desplazamiento ya no debe levantar nada */
  .sede-card { transform: none; }

  /* --- Cifras: una tira, no una parrilla de cuatro filas ---------------- */
  .cifras { gap: 1.25rem 1rem; }
  .cifras dd { font-size: clamp(2rem, 9vw, 2.75rem); }

  /* --- Objetivos táctiles: nada por debajo de 44 px --------------------- */
  .btn-texto { min-height: 44px; display: inline-flex; align-items: center; padding-block: .625rem; }
  .sede-card-acciones .btn-texto { padding: .625rem 1rem; }
  .sede-card-acciones .btn { min-height: 50px; width: 100%; }
  .pie-rejilla a,
  .pie-legal a { display: inline-flex; align-items: center; min-height: 44px; }
  .pie-rejilla ul { gap: 0; }
  /* Sin `min-height` aquí: la regla de más abajo en este mismo @media lo sube
     a los 44 px que pide un objetivo de toque, y ésta ponía 40 sin efecto. */
  .migas a { display: inline-flex; align-items: center; }

  /* --- Tipografía mínima: 13 px es poco para leer con prisa ------------- */
  :root { --t-mini: 0.875rem; }

  /* --- Pie: cinco columnas apiladas son media pantalla cada una --------- */
  .pie-rejilla { grid-template-columns: 1fr 1fr; gap: 1.75rem 1.25rem; }
  .pie-rejilla > :first-child { grid-column: 1 / -1; }
}

/* ============================================================================
   LA VENTANA DE AGENDAR EN EL TELÉFONO
   Medido antes de tocarla: el pie fijo ocupaba 294 de los 844 px de pantalla
   —el 45 %— y dejaba unos 300 px para el formulario, con el calendario naciendo
   ya tapado. El resumen de cuatro filas repetía datos que están a la vista:
   la sede está en la cabecera y el examen, en el paso 1. Aquí queda en una
   línea y una acción; el cuerpo pasa de ~300 a ~510 px.
   ========================================================================== */
/* --- /agendar en el teléfono ---------------------------------------------
   Tres <section> seguidas, cada una con su propio aire, metían 88 px de hueco
   entre bloques que son un mismo asunto: el paso 1 nacía a 750 px, fuera de la
   primera pantalla.

   🔴 Aquí vivía una tercera regla, `[data-nota-maqueta] p`, para achicar una
   «nota de maqueta» que NUNCA EXISTIÓ: ese atributo no está en /agendar ni en
   ninguna otra página, así que la regla no se aplicó jamás. Es el peor tipo de
   código muerto —el que además documenta una intención falsa— porque quien lo
   lea creerá que esa nota se está tratando. */
@media (max-width: 979px) {
  body[data-pagina="agendar"] .cabecera-pagina { padding-bottom: .5rem; }
  body[data-pagina="agendar"] .seccion-corta { padding-block: 1.25rem; }
}

/* --- Tablas como tarjetas en el teléfono ---------------------------------
   Solo se activa cuando el JS ha copiado las cabeceras a cada celda; sin ese
   atributo la tabla sigue siendo una tabla que desliza, que es el
   comportamiento de antes. */
@media (max-width: 680px) {
  [data-tabla-tarjetas] { overflow-x: visible; }
  [data-tabla-tarjetas] table { min-width: 0; display: block; }
  [data-tabla-tarjetas] thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
  [data-tabla-tarjetas] tbody { display: grid; gap: .75rem; }
  [data-tabla-tarjetas] tbody tr {
    display: block;
    border: 1px solid var(--borde); border-radius: var(--r-m);
    background: var(--velo); padding: .875rem 1rem;
  }
  [data-tabla-tarjetas] tbody td { display: block; border: 0; padding: 0; }
  /* La primera celda titula la tarjeta; el resto van etiqueta / dato.
     Algunas filas usan <th scope="row"> como encabezado de fila (el "Total
     aproximado" de las guías): sin esto conservaba el fondo y el filo de <th>
     y salía como una losa gris dentro de la tarjeta. Titula igual que un td. */
  [data-tabla-tarjetas] tbody td:first-child,
  [data-tabla-tarjetas] tbody th {
    display: block; border: 0; padding: 0; background: none; text-align: left;
    font-size: 1.0625rem; font-weight: 500; color: var(--tinta);
    margin-bottom: .5rem;
  }
  [data-tabla-tarjetas] tbody td:not(:first-child) {
    display: flex; justify-content: space-between; align-items: baseline; gap: 1rem;
    padding-top: .375rem;
    font-size: var(--t-menor);
  }
  [data-tabla-tarjetas] tbody td:not(:first-child)::before {
    content: attr(data-etiqueta);
    flex-shrink: 0; color: var(--suave); font-size: var(--t-mini);
  }
  /* El valor es a lo que se vino: que pese */
  [data-tabla-tarjetas] tbody td:last-child { color: var(--tinta); font-weight: 500; text-align: right; }
}

@media (max-width: 979px) {
  /* El logo era un objetivo de 149×30: alto suficiente para leerlo, no para
     acertarle con el pulgar. */
  .nav-marca { min-height: 44px; }

  /* Bento de tarifas: cinco bloques apilados. No se quita ninguno —el precio
     por categoría y lo que incluye son justo lo que se vino a mirar— pero se
     les quita relleno muerto. */
  .celda { padding: 1.25rem; }
  .celda .precio-cifra { font-size: 2.25rem; flex-wrap: wrap; margin: .5rem 0 .25rem; }
  .celda ul { margin-top: .875rem; gap: .5rem; }
  .celda .btn { margin-top: 1.125rem; min-height: 48px; }
  .celda-foto img { min-height: 170px; }
}

@media (max-width: 979px) {
  /* Enlaces sueltos dentro de las listas de datos: los 8 documentos de
     /transparencia, los teléfonos y el WhatsApp de cada sede, las redes de
     /contacto. Medían 17 px de alto. No son enlaces en mitad de un párrafo
     —esos sí están exentos y estirarlos rompería el interlineado—, son
     acciones sueltas, y por ahí se marca un teléfono con el pulgar. */
  .datos dd a {
    display: inline-flex; align-items: center; min-height: 44px;
  }
  .migas a { min-height: 44px; }
}

/* Lista de precios en el teléfono: categoría y valor en la misma línea.
   Se activa solo cuando el JS ha comprobado que la última columna es dinero
   en TODAS las filas; si no, la tabla se apila en líneas separadas, que es lo
   correcto cuando esa columna es texto largo. */
@media (max-width: 680px) {
  [data-tabla-tarjetas="precio"] tbody tr {
    display: grid; grid-template-columns: 1fr auto; align-items: baseline;
    column-gap: 1rem; padding: .8125rem 1rem;
  }
  [data-tabla-tarjetas="precio"] tbody td:first-child { grid-column: 1; grid-row: 1; margin-bottom: 0; }
  [data-tabla-tarjetas="precio"] tbody td:last-child {
    grid-column: 2; grid-row: 1;
    font-size: 1.0625rem; font-weight: 700; font-variant-numeric: tabular-nums;
  }
  /* El valor ya se lee al lado de su categoría: la etiqueta sobra */
  [data-tabla-tarjetas="precio"] tbody td:last-child::before { content: none; }
  [data-tabla-tarjetas="precio"] tbody td:not(:first-child):not(:last-child) {
    grid-column: 1 / -1; grid-row: 2;
    padding-top: .25rem; color: var(--suave);
  }
  [data-tabla-tarjetas="precio"] tbody td:not(:first-child):not(:last-child)::before { display: none; }
}

/* --- Tarifas cuando sube al héroe en el teléfono -------------------------
   `.oscura` no pinta fondo: es un contexto de COLOR que tiñe enlaces y
   entradillas para el bloque del héroe. Al meter ahí la sección de Tarifas,
   esa herencia le cambiaba tres cosas frente a como se ve en escritorio: la
   entradilla, el texto del botón «Agendar» del primer plan y el enlace de
   abajo. Se devuelven a sus valores propios: un mismo componente no debe
   verse distinto según dónde acabe colocado. */
.oscura > [data-tarifas] .lead { color: var(--suave); }
.oscura > [data-tarifas] .btn-secundario { color: var(--tinta); }
.oscura > [data-tarifas] .btn-texto { color: var(--cian-claro); }

/* --- El héroe del teléfono no lleva foto ---------------------------------
   En móvil la fachada sale del héroe: queda el texto con su animación de
   entrada y, justo debajo, las tarifas. La foto sigue en escritorio y sigue
   apareciendo más abajo en la sección de Nuestro Bogotá, así que el archivo se
   descarga igual —es el mismo `fachada.jpeg`, misma entrada de caché— y
   ocultarla aquí no cuesta ancho de banda de más. */
@media (max-width: 979px) {
  /* --- Héroe: que el titular mande -------------------------------------
     El problema no era el tamaño del título: era que la entradilla ocupaba
     casi la misma superficie (133 px contra 105) y no dejaba dominar a nadie.
     Se sube el titular, se acorta la entradilla y los botones pasan a una
     fila: entre las tres cosas el titular pasa a pesar el doble. */
  /* Sube de 3rem fijo a un clamp que llega a 3,5rem (56 px), que es un peldaño
     REAL de la escala áurea —el del h2— en vez de un número suelto.

     El techo se puso midiendo, no a ojo. Lo que decide aquí no es el ancho
     sino si la línea del precio («Tres sedes en Bogotá · Tarifa desde
     $238.000») sigue cabiendo en la primera pantalla por encima de la barra
     fija. A 390 y 360 px aguanta hasta 3,5rem con holhura (acaba en 590 y la
     barra empieza en 771).

     🔴 Y el suelo se queda en 3rem por los 320 px: ahí el titular pasa a cinco
     líneas y el precio se va de la primera pantalla. Conviene saber que en 320
     el precio YA se salía antes de tocar nada (650 contra un tope de 617), así
     que esto no lo rompe; simplemente no lo empeora. */
  .heroe .display { font-size: clamp(3rem, 14.4vw, 3.5rem); line-height: .98; }
  /* Ojo: la píldora de navegación es `position: fixed`, así que este relleno
     no es aire —es lo único que impide que el titular nazca por debajo de
     ella—. La píldora mide 88 px; por debajo de eso el texto se mete detrás. */
  .heroe { padding-top: calc(88px + 1.6rem); }
/* Dos botones apilados comían 123 px de la primera pantalla. En fila caben
     desde 360 px de ancho; por debajo se dejan apilar, que es preferible a
     que el texto se salga. */
  @media (min-width: 360px) {
    .heroe .btn-grupo { flex-wrap: nowrap; gap: .625rem; }
    .heroe .btn-grupo .btn { flex: 1 1 0; padding-inline: .75rem; white-space: nowrap; }
  }

  /* El resplandor del letrero vivía SOLO detrás de los gemelos, así que al
     ocultarlos en el teléfono desaparecía con ellos y el héroe se quedaba
     plano. Aquí va por su cuenta, detrás del titular.
     🔴 Los lados van casi a 0: con -22% el pseudoelemento ensanchaba la página
     a 448 px y la píldora de navegación salía cortada. */
  .heroe-rejilla { position: relative; }
  /* 🔴 El lado derecho va a 0 y no a -6%. Con -6% la caja del resplandor se
     salía 22 px por la derecha y el DOCUMENTO se volvía más ancho que la
     pantalla. En Chrome no se notaba —`overflow-x` lo recorta— pero en un
     iPhone de verdad eso deja ARRASTRAR la página entera con el dedo: la
     barra fija se queda quieta y todo lo demás se corre y se corta.
     El `blur(52px)` sigue sacando el color fuera de la pantalla, así que se
     ve igual; lo que se acaba es el desbordamiento de la CAJA, que es lo que
     el navegador mide. */
  .heroe-rejilla::before {
    content: ""; position: absolute; inset: -6% 0 62% 34%; z-index: -1;
    background: var(--letrero); filter: blur(52px); opacity: .22;
    border-radius: 50%; pointer-events: none;
  }

  /* 19 px y no 17. Dos razones que apuntan a lo mismo: en el teléfono la
     entradilla del héroe es el único texto que explica qué es esto, y a 17 px
     las palabras resaltadas en 700 se quedaban por debajo de los 18,66 px que
     WCAG pide para contar como texto grande, así que el listón les subía a
     4,5:1 justo donde el fondo está más teñido. */
  .heroe .lead { font-size: 1.1875rem; }

  /* 🔴 EN EL TELÉFONO VA EL RECORTE, sin fondo y sin marco    (14-09-2026)

     Antes iba la pieza 16:9 con su propio fondo, dentro de una tarjeta
     redondeada, y rotando con las tres fotos de sede. Se quitaron las dos
     cosas —el marco y las transiciones— por la misma razón: en una pantalla
     estrecha una foto encajonada con esquinas y filo se lee como un cuadro
     pegado en medio de la página. El recorte no tiene canto, así que no hay
     nada que cuadre.

     🔴 Lo que sostenía a la silueta en escritorio vuelve aquí ENTERO, y no es
     opcional: el resplandor del letrero por detrás de los hombros y la máscara
     que difumina el corte de cintura. Sin esas dos cosas el recorte sí se lee
     como una pegatina —que es exactamente por lo que en su día se cambió por
     la foto enmarcada—. Con ellas se lee como si salieran del fondo.

     El resplandor va con los lados a 0 y no al -8% del escritorio: a 390 px ese
     -8% son 31 px de caja fuera de la pantalla y el documento se vuelve más
     ancho que el teléfono, que es el fallo que deja ARRASTRAR la página entera
     con el dedo. El `blur(70px)` derrama el color igual; lo que se acaba es el
     desbordamiento de la caja, que es lo que el navegador mide.

     La imagen va al 110 % con -5 % de margen: un punto más grande que la
     columna, pero sin salirse del canal de 20 px. Medido, no estimado — al
     112 % la caja se pasa 1 px del borde. */
  .heroe-gemelos { display: block; width: 100%; margin: .75rem 0 0; }
  .heroe-gemelos-int { position: relative; border-radius: 0; overflow: visible; }
  .heroe-gemelos-int::after { content: none; }
  /* Con la holgura de 140 px, igual que en escritorio (ver la regla base). El
     desborde lateral lo recorta `section[data-heroe] { overflow-x: clip }`,
     que no crea contenedor de scroll: el documento no se ensancha (medido con
     cab-ovf y ancho-fluido).

     🔴 Y con OTRO PERFIL de máscara, no el de escritorio. Aquel imita el canto
     difuminado de un óvalo grande: en escritorio el óvalo mide unas cinco
     sigmas del blur y lo que se ve es un borde suave. En el teléfono el óvalo
     es de 350 px y el blur seguía siendo de 70: el desenfoque se comía la
     forma entera y quedaba una MANCHA gaussiana. Con la máscara de escritorio
     el halo salía más luminoso y más extendido que antes (diferencia media
     6,33/255 en oscuro, casi la mitad de los píxeles por encima de 3).

     Calibrado barriendo una familia gaussiana —alfa = e^(-(r/s)^2/2)— contra
     la regla vieja reinyectada en el mismo render. Gana s = 36 % con la misma
     opacidad: diferencia media 1,03 en oscuro y 0,69 en claro. Los colores
     del degradado, recolocados con la caja real medida a 390. */
  .heroe-gemelos-int::before {
    display: block; opacity: .46;
    inset: calc(2% - 140px) -140px calc(12% - 140px) -140px;
    background: linear-gradient(100deg, var(--cian) 22.6%, #6b57c4 51.1%, var(--magenta) 77.4%);
    -webkit-mask-image: radial-gradient(closest-side, #000 0%, rgba(0, 0, 0, .962) 10%, rgba(0, 0, 0, .857) 20%, rgba(0, 0, 0, .707) 30%, rgba(0, 0, 0, .539) 40%, rgba(0, 0, 0, .381) 50%, rgba(0, 0, 0, .249) 60%, rgba(0, 0, 0, .151) 70%, rgba(0, 0, 0, .085) 80%, rgba(0, 0, 0, .044) 90%, transparent 100%);
            mask-image: radial-gradient(closest-side, #000 0%, rgba(0, 0, 0, .962) 10%, rgba(0, 0, 0, .857) 20%, rgba(0, 0, 0, .707) 30%, rgba(0, 0, 0, .539) 40%, rgba(0, 0, 0, .381) 50%, rgba(0, 0, 0, .249) 60%, rgba(0, 0, 0, .151) 70%, rgba(0, 0, 0, .085) 80%, rgba(0, 0, 0, .044) 90%, transparent 100%);
  }
  .heroe-gemelos img {
    display: block; width: 110%; max-width: none; margin-left: -5%; height: auto;
    aspect-ratio: auto; object-fit: fill;
    -webkit-mask-image: linear-gradient(to bottom, #000 82%, transparent 99%);
            mask-image: linear-gradient(to bottom, #000 82%, transparent 99%);
  }
  .heroe-rejilla { gap: 0; }

  /* Los dos botones del héroe, a mitades iguales y 56 px de alto. Eran 54 px
     de ancho automático: el principal y el secundario no medían lo mismo y
     ninguno de los dos parecía el importante. El reparto a mitades ya lo hacía
     la regla de 360 px de aquí arriba; esto solo les da cuerpo. */
  @media (min-width: 360px) {
    .heroe .btn-grupo .btn { min-height: 56px; font-size: 1.0625rem; }
  }
}


/* --- Enlaces de texto de las tarjetas de sede ----------------------------
   El «Ver la sede →» va en magenta; el filo de resalte se queda celeste. Los
   dos colores siguen diciendo cosas distintas: el celeste marca la tarjeta,
   el magenta marca la salida a la ficha.

   🔴 Hacen falta DOS reglas y no una. La sección de sedes vive dentro de
   `section.oscura`, y el tema claro trae `:root[data-tema="claro"] .oscura
   .btn-texto` con especificidad (0,4,0). Una regla de (0,2,0) pierde contra
   ella y sobre claro el enlace se quedaba celeste. La segunda empata en
   especificidad y gana por orden, que es el motivo de que este bloque esté al
   final de la hoja. */
.sede-card .btn-texto { color: var(--enlace-magenta); }
:root[data-tema="claro"] .sede-card .btn-texto { color: var(--enlace-magenta); }
@media (hover: hover) and (pointer: fine) {
  .sede-card .btn-texto:hover { color: var(--enlace-magenta); text-decoration: underline; }
}


/* --- «Sede más cercana» cuando vive en el héroe (solo teléfono) ----------
   El JS mueve este bloque bajo la foto de los gemelos por debajo de 980 px.
   Ahí no está en una cabecera centrada sino en el héroe, así que hereda su
   alineación a la izquierda y un botón de ancho automático se queda flotando.
   A ancho completo se lee como lo que es: la siguiente acción del héroe.
   El selector es `> .sedes-cerca` y no `.sedes-cerca` a secas para que solo
   aplique cuando de verdad ha sido movido. */
@media (max-width: 979px) {
  .heroe-rejilla > .sedes-cerca { margin-top: 1.5rem; }
  .heroe-rejilla > .sedes-cerca .btn { width: 100%; }
  .heroe-rejilla > .sedes-cerca .sedes-cerca-aviso,
  .heroe-rejilla > .sedes-cerca .sedes-cerca-nota { text-align: left; }
}

/* --- La ficha de resultado ----------------------------------------------
   Aparece bajo el botón con la sede ganadora, en vez de arrastrar la página
   hasta las tarjetas. Solo se enseña cuando el botón está lejos de ellas
   (el teléfono, donde el bloque sube al héroe); en escritorio están debajo. */
/* La ficha del resultado lleva el MISMO filo magenta que la tarjeta marcada, y
   por una razón práctica: en el teléfono es lo primero —y muchas veces lo
   único— que se ve al pulsar el botón. El riel de tarjetas queda pantallas más
   abajo, así que si el filo viviera sólo allí, en un móvil el resalte no
   existiría. Aquí no hace falta condición: esta ficha sólo aparece con la sede
   ganadora dentro.

   Lleva el halo pero no `--sombra-media`: va pegada bajo el botón, en un hueco
   estrecho, y una sombra de 60 px ahí se lee como suciedad y no como relieve. */
.cerca-ficha {
  margin-top: 1rem; padding: 1.125rem 1.25rem 1.25rem;
  border: 1px solid var(--filo-cercana); border-radius: var(--r-l);
  box-shadow: var(--brillo-magenta);
  background: var(--superficie);
  text-align: left;
}
.cerca-ficha[hidden] { display: none; }
@supports (backdrop-filter: blur(1px)) {
  .cerca-ficha { backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px); }
}
/* La misma píldora que la insignia de la tarjeta, y por eso el mismo relleno:
   las dos dicen «La más cercana» y las dos pueden estar en pantalla a la vez
   —ésta bajo el botón, aquélla sobre la foto de la tarjeta de más abajo—. Dos
   aspectos para la misma frase se leen como dos cosas distintas. */
.cerca-ficha-etiqueta {
  display: inline-flex; padding: .375rem .75rem; border-radius: 999px;
  background: var(--magenta); border: 0;
  font-size: .75rem; font-weight: 700; color: #fff;
}
.cerca-ficha-nombre {
  margin-top: .75rem; font-size: 1.1875rem; font-weight: 700;
  line-height: 1.24; letter-spacing: -0.015em; color: var(--tinta);
}
.cerca-ficha-dist {
  margin-top: .375rem; font-size: .9375rem; font-weight: 500;
  color: var(--enlace-magenta);
}
.cerca-ficha-dir {
  margin-top: .5rem; font-size: .9375rem; line-height: 1.5; color: var(--suave);
}
.cerca-ficha-acciones {
  display: flex; flex-wrap: wrap; gap: .625rem; margin-top: 1.125rem;
}
.cerca-ficha-acciones .btn { flex: 1 1 auto; padding: .75rem 1.25rem; font-size: .9375rem; }

/* --- Foto de la ficha de resultado --------------------------------------- */
.cerca-ficha-foto {
  aspect-ratio: 1.618; border-radius: var(--r-m);
  background: var(--letrero); overflow: hidden; margin-bottom: 1rem;
}
.cerca-ficha-foto:empty { display: none; }   /* sin foto no deja una franja de color */
.cerca-ficha-foto img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* --- Riel de las otras sedes ---------------------------------------------
   Mismo patrón que los rieles de la home: sangrado negativo para que la
   siguiente asome por el borde —que es lo que le dice al dedo que hay más—,
   scroll-snap y la barra oculta.

   Con dos elementos podría ser una fila normal, pero el riel es lo que ya
   conoce quien usa este sitio en el teléfono, y así sigue funcionando si
   algún día son cuatro sedes. */
.cerca-otras { margin-top: 1.5rem; }
.cerca-otras[hidden] { display: none; }
.cerca-otras-titulo {
  font-size: var(--t-mini); font-weight: 700; letter-spacing: .01em;
  color: var(--suave); margin-bottom: .75rem;
}
.cerca-riel {
  display: flex; gap: .75rem; list-style: none; margin: 0;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-padding-inline: 0;
  padding: 0 0 .5rem;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
.cerca-riel::-webkit-scrollbar { display: none; }
.cerca-riel > li { flex: 0 0 58%; max-width: 220px; scroll-snap-align: start; }

.cerca-mini-enlace {
  display: block; text-decoration: none; color: inherit;
  border: 1px solid var(--borde); border-radius: var(--r-m);
  background: var(--velo); padding: .5rem .5rem .75rem;
  transition: border-color 220ms ease;
}
.cerca-mini-foto {
  display: block; aspect-ratio: 1.618; border-radius: var(--r-s);
  background: var(--letrero); overflow: hidden; margin-bottom: .625rem;
}
.cerca-mini-foto img { width: 100%; height: 100%; object-fit: cover; display: block; }
.cerca-mini-nombre {
  display: block; font-size: .875rem; font-weight: 700; line-height: 1.3;
  color: var(--tinta); padding-inline: .25rem;
}
.cerca-mini-dist {
  display: block; margin-top: .25rem; font-size: .8125rem;
  color: var(--suave); padding-inline: .25rem;
}
@media (hover: hover) and (pointer: fine) {
  .cerca-mini-enlace:hover { border-color: rgba(0, 159, 227, .45); }
}

/* === EL SELECTOR DE SEDE (/agendar) ======================================
   Esta es la página que cierra la venta, y su único trabajo es que alguien
   elija una de tres sedes. La versión anterior daba nombre y dirección y ya:
   con eso no se puede decidir, así que la decisión se iba a /sedes o se
   perdía. Aquí cada tarjeta trae lo que de verdad decide —si está ABIERTA
   AHORA, qué nota tiene en Google y a qué distancia queda— y termina en un
   botón sólido, no en un enlace de texto.

   Ya no es la tarjeta entera la que enlaza. Con tres datos y dos acciones
   dentro (agendar y ver la sede), un contenedor pulsable se come los clics de
   lo que lleva dentro y deja al teclado un solo destino para dos caminos. El
   blanco grande de antes lo da ahora el botón, que ocupa el ancho completo. */
.elige {
  list-style: none; margin: 0; padding: 0;
  display: grid; gap: 1rem;
  /* `auto-fit` y no tres columnas fijas: si algún día hay una cuarta sede,
     entra sola y sin tocar la hoja. */
  grid-template-columns: repeat(auto-fit, minmax(18.5rem, 1fr));
}
.elige-item { display: flex; }
.elige-sede {
  position: relative;
  display: flex; flex-direction: column; gap: .5rem;
  width: 100%;
  padding: 1.5rem 1.5rem 1.375rem;
  border: 1px solid var(--borde); border-radius: var(--r-l);
  background: var(--superficie);
  transition: transform 400ms var(--sal), border-color 300ms ease, box-shadow 400ms var(--sal);
}
@supports (backdrop-filter: blur(1px)) {
  .elige-sede { backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px); }
}

/* --- El estado de HOY ----------------------------------------------------
   Lo pinta el JS con la hora de Bogotá y el horario verificado de cada sede.
   Nace `hidden`: sin JS no aparece una pastilla vacía, y el horario semanal
   de más abajo —que está escrito en el HTML— sigue diciendo lo mismo.

   Tres estados y tres colores, y ninguno es un semáforo de marca: el cian es
   el celeste de la casa, el apagado es el gris de texto secundario y el
   festivo va en magenta porque es el único que pide hacer algo (escribir).
   El color NUNCA va solo: cada estado dice su palabra (Abierto ahora,
   Cerrado ahora, Hoy es festivo), que es lo que lee quien no los separa. */
.elige-estado {
  align-self: flex-start;
  display: inline-flex; align-items: center; gap: .4375rem;
  margin-bottom: .125rem;
  padding: .3125rem .6875rem .3125rem .5625rem;
  border: 1px solid var(--borde); border-radius: 999px;
  font-size: .8125rem; font-weight: 600; line-height: 1.3;
  color: var(--tinta);
}
.elige-estado::before {
  content: ""; flex: 0 0 auto;
  width: 7px; height: 7px; border-radius: 50%;
  background: currentColor;
}
/* Abierto: el celeste de marca. Como FONDO del punto y como letra a 13 px en
   600, que sobre el vidrio oscuro da 6,1:1 con `--cian-claro` (el mismo token
   que usan los enlaces, justamente porque el cian plano no llega en claro). */
.elige-estado[data-estado="abierto"] {
  border-color: rgba(0, 159, 227, .38);
  background: rgba(0, 159, 227, .10);
}
.elige-estado[data-estado="abierto"]::before { background: var(--cian); }
/* El punto del abierto respira. Es lo único que se mueve en la tarjeta en
   reposo, y significa algo: esto se está mirando ahora mismo. */
@media (prefers-reduced-motion: no-preference) {
  .elige-estado[data-estado="abierto"]::before { animation: elige-latido 2.4s ease-in-out infinite; }
}
@keyframes elige-latido {
  0%, 100% { opacity: 1;   box-shadow: 0 0 0 0 rgba(0, 159, 227, .55); }
  50%      { opacity: .85; box-shadow: 0 0 0 4px rgba(0, 159, 227, 0); }
}
.elige-estado[data-estado="cerrado"] { color: var(--suave); }
.elige-estado[data-estado="cerrado"]::before { background: currentColor; opacity: .5; }
.elige-estado[data-estado="festivo"] {
  border-color: rgba(230, 0, 126, .34);
  background: rgba(230, 0, 126, .09);
}
.elige-estado[data-estado="festivo"]::before { background: var(--magenta); }

.elige-nombre {
  font-size: 1.1875rem; font-weight: 700; line-height: 1.25;
  letter-spacing: -0.015em; color: var(--tinta);
  margin: 0;
}
.elige-dir {
  font-style: normal;
  font-size: .9375rem; line-height: 1.5; color: var(--suave);
  min-height: 2.8125rem;      /* dos líneas: la más larga de las tres sedes */
}
@media (max-width: 979px) { .elige-dir { min-height: 0; } }

/* La distancia solo existe después de pulsar el botón de ubicación, así que
   nace oculta: sin permiso o sin JS la tarjeta se lee entera igual. */
.elige-dist {
  font-size: .875rem; font-weight: 600; color: var(--enlace-magenta);
}

/* Los dos datos duros, en una lista de definición de verdad: son pares
   etiqueta/valor, no párrafos con dos puntos. */
.elige-datos {
  margin: .75rem 0 0; padding-top: .875rem;
  border-top: 1px solid var(--borde);
  display: grid; gap: .625rem;
  font-size: .875rem;
}
.elige-datos > div { display: grid; grid-template-columns: 5.75rem 1fr; gap: .75rem; align-items: baseline; }
.elige-datos dt { color: var(--suave); }
.elige-datos dd { margin: 0; color: var(--texto); line-height: 1.45; }
.elige-nota-g { font-weight: 700; color: var(--tinta); }
/* La estrella es decorativa (`aria-hidden`): la nota ya está escrita al lado
   en número, que es lo que se anuncia. Va del color de la nota y NO del
   celeste de marca: a 14 px sobre el tema claro el celeste da 2,95:1, y una
   estrella que no se distingue del fondo no adorna nada. El acento de marca
   de esta tarjeta ya lo ponen el punto de la pastilla y el botón. */
.elige-estrella { color: var(--tinta); }

/* `margin-top:auto` empuja el bloque al fondo para que las tres tarjetas
   alineen sus botones aunque las direcciones ocupen una, dos o tres líneas. */
.elige-acciones {
  margin-top: auto; padding-top: 1.125rem;
  display: flex; flex-direction: column; align-items: center; gap: .25rem;
}
/* El botón ocupa el ancho entero de la tarjeta. Es la acción de la página: no
   compite con nada dentro de su caja, y en el teléfono da un blanco de 52 px
   de alto por todo lo ancho, que es el gesto más fácil que hay. */
.elige-cta { width: 100%; min-height: 52px; }

@media (hover: hover) and (pointer: fine) {
  .elige-sede:hover {
    transform: translateY(-6px);
    border-color: rgba(0, 159, 227, .45);
    box-shadow: var(--sombra-media), var(--brillo-cian);
  }
}
/* El realce también con el teclado: `:focus-within` y no `:focus`, porque
   quien tabula entra en el BOTÓN, no en la tarjeta. Sin `transform`: mover la
   caja bajo un foco que acaba de aterrizar desorienta más de lo que ayuda. */
.elige-sede:focus-within {
  border-color: rgba(0, 159, 227, .45);
  box-shadow: var(--sombra-media), var(--brillo-cian);
}

/* --- La más cercana ------------------------------------------------------
   Mismo trato que en la home: filo magenta y el HAZ giratorio. La regla del
   haz vive en el bloque de `.sede-card[data-cercana]`; aquí solo se añade
   este selector a esa lista. Lo que se marca es una sola tarjeta, y la marca
   la pide el propio usuario al pulsar: por eso no es decoración. */
.elige-sede[data-cercana] {
  border-color: var(--filo-cercana);
  box-shadow: var(--sombra-media), var(--brillo-magenta);
}

/* --- El botón de ubicación, en la portada --------------------------------
   El botón y las tarjetas son la misma conversación, así que el aire de
   sección que hay entre la portada y lo que sigue sobra aquí: eran 150 px
   entre la pregunta y las tres respuestas. */
body[data-pagina="agendar"] .cabecera-pagina { padding-bottom: 1.5rem; }
body[data-pagina="agendar"] [data-elige] { padding-top: 0; }
.elige-cerca { margin-top: 1.75rem; }
.elige-cerca-aviso {
  margin-top: .75rem; font-size: var(--t-menor); color: var(--suave);
  min-height: 1.4em;   /* reserva su línea: sin esto la lista salta al responder */
}

/* --- La tarifa y la nota al pie ------------------------------------------ */
.elige-tarifa {
  margin-top: 1.5rem;
  font-size: var(--t-menor); line-height: 1.6; color: var(--texto);
}
.elige-tarifa strong { color: var(--tinta); font-weight: 700; }
.elige-tarifa .btn-texto { margin-left: .25rem; }
/* 🔴 El hueco antes de la flecha. En el teléfono `.btn-texto` pasa a
   `inline-flex` para llegar a los 44 px de objetivo táctil, y un contenedor
   flex se come el nodo de espacio que hay en el HTML: salía «Ver la sede→».
   Es la misma trampa que ya está anotada arriba en `.resenas-todas`, y se
   arregla igual, con `gap`. Va calificado a este componente a propósito:
   `.btn-texto` a secas lo arreglaría también en la home y en las tarjetas de
   sede, que es otra capa y no toca hoy. */
.elige-acciones .btn-texto,
.elige-tarifa .btn-texto { gap: .375rem; }
.elige-pie-nota {
  margin-top: .875rem;
  font-size: .8125rem; line-height: 1.55; color: var(--suave);
}

/* --- Ten esto a mano -----------------------------------------------------
   Cuatro fichas abiertas donde antes había cuatro pestañas cerradas. Es lo
   que evita que alguien abandone el formulario a mitad, así que esconderlo
   detrás de un clic era esconder justo lo útil. Sin tarjeta y sin vidrio: un
   número y una raya bastan, y así no compite con el selector de arriba, que
   es lo único de esta página que tiene que parecer pulsable. */
.amano,
.razones,
.oficios {
  list-style: none; margin: 0; padding: 0;
  display: grid; gap: 1.75rem 2.5rem;
  counter-reset: amano;
}
.amano-item,
.razones-item,
.oficios-item { counter-increment: amano; padding-top: 1rem; border-top: 1px solid var(--borde); }
.amano-item::before {
  content: counter(amano); display: block;
  font-size: .875rem; font-weight: 700; letter-spacing: .02em;
  color: var(--cian-claro); margin-bottom: .5rem;
}
.amano-titulo,
.razones-titulo,
.oficios-titulo {
  font-size: 1.0625rem; font-weight: 700; color: var(--tinta);
  /* `em` y no `rem`: el título sube a 18 px por encima de 760, y el hueco
     tiene que subir con él. A 6 px fijos el párrafo se leía como la segunda
     línea del título en vez de como su explicación. */
  margin-bottom: .5em;
}
.amano-item p,
.razones-item p,
.oficios-item p { color: var(--texto); font-size: var(--t-menor); line-height: 1.6; }
@media (min-width: 760px) { .amano { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1080px) { .amano { grid-template-columns: repeat(4, 1fr); gap: 1.5rem; } }

/* --- Tres pasos, no cuatro ----------------------------------------------
   `.pasos` reparte en cuatro columnas a partir de 720 px. Con tres hijos eso
   deja una celda vacía a la derecha y la fila se lee descuadrada. */
@media (min-width: 720px) { .pasos-3 { grid-template-columns: repeat(3, 1fr); } }

/* --- La barra de acción de /agendar --------------------------------------
   La barra general (`.barra-movil`) está apagada en esta página desde que se
   quitó el formulario falso, y con razón: llevaba a /agendar, que es donde ya
   estás. Pero apagarla dejó el teléfono sin ninguna acción a la vista en
   cuanto el selector se iba por arriba — tres pantallas leyendo, sin sitio
   donde pulsar.

   Esta es la misma barra con otro destino: lleva a la SEDE, no a la página.
   Nace oculta (`hidden` en el HTML) y la enciende el JS solo cuando el
   selector ya no se ve, así que nunca duplica un botón que esté en pantalla.
   Y cuando el usuario ha pedido la sede más cercana, la barra pasa a ser el
   botón de ESA sede, con su nombre escrito. */
.barra-elige {
  display: none;
  position: fixed; left: 0; right: 0; bottom: 0; z-index: var(--z-barra);
  gap: .625rem;
  padding: .625rem var(--canal);
  padding-bottom: calc(.625rem + env(safe-area-inset-bottom));
  border-top: 1px solid var(--borde);
  background: var(--nav-vidrio-fijo);
  /* Entra desde abajo. `transform` y nada más: es lo único que se puede animar
     sin que el navegador vuelva a maquetar la página en cada fotograma. */
  transform: translateY(120%);
}
@supports (backdrop-filter: blur(1px)) {
  .barra-elige { backdrop-filter: saturate(180%) blur(20px); -webkit-backdrop-filter: saturate(180%) blur(20px); }
}
.barra-elige[data-ver] { transform: translateY(0); }
.barra-elige-cta {
  flex: 1; min-height: 52px;
  padding: .875rem 1rem;      /* menos que el 1.875rem de un botón normal:
                                 aquí el ancho es el recurso escaso */
  font-size: 1.0625rem;
  /* El nombre de la sede puede ser largo (Terminal de Transportes El Salitre)
     y la barra no puede crecer ni partir en dos líneas: se recorta. */
  white-space: nowrap; overflow: hidden;
}
.barra-elige-cta > span:first-child { overflow: hidden; text-overflow: ellipsis; }
@media (max-width: 979px) {
  .barra-elige { display: flex; }
  /* Que la barra no se coma el final del pie. La regla general de `.pie` la
     anula `body[data-pagina="agendar"]`, que la puso a cero al apagar la barra
     de siempre; hay que devolverla aquí. */
  body[data-pagina="agendar"] .pie { padding-bottom: calc(2.5rem + 76px + env(safe-area-inset-bottom)); }
}
/* Se aparta mientras el menú está abierto, igual que la barra general: la hoja
   lleva su propio botón de cierre y esta barra se lo taparía. */
body:has(.nav-hoja[data-abierta="si"]) .barra-elige { transform: translateY(120%); }
@media (prefers-reduced-motion: no-preference) {
  .barra-elige { transition: transform 320ms var(--sal); }
}

/* --- El correo del pie no puede ensanchar la página ----------------------
   `contacto@reconocerips.com` es una sola palabra de 194 px sin ningún sitio
   por donde partirla. Por debajo de 340 px de pantalla no cabe en su columna
   y estiraba el DOCUMENTO 9 px, que en iOS es suficiente para poder arrastrar
   la página de lado.

   Hace falta `anywhere` y no `break-word`: solo `anywhere` reduce el ancho
   MÍNIMO que el elemento le pide a su columna, que es justo lo que aquí
   sobra. `break-word` parte la palabra pero sigue reservando el hueco.

   Va sobre los enlaces del pie y no sobre todo el sitio: partir palabras por
   cualquier sitio es feo, y solo se gana algo donde de verdad hay cadenas sin
   espacios. */
.pie li a { overflow-wrap: anywhere; }

/* 🔴 El carrusel solo existe donde el JS lo ENCIENDE, y esa marca no depende
   del ancho. Antes se apagaba con `min-width: 980px`, y eso trata como
   teléfono a cualquier ventana de PC más estrecha de 980 px: en un portátil
   con la ventana a media pantalla las fotos rotaban. El JS pone `data-vivo`
   solo si además el puntero es grueso, o sea pantalla táctil.

   Sin la marca —escritorio, ventana estrecha, o JS caído— solo se ve la
   diapositiva activa, que de fábrica es la de los gemelos. Falla del lado
   seguro: lo que no se enciende, no se mueve.

   Todo el estilo del carrusel vive dentro de `@media (max-width: 979px)`, así
   que estas dos reglas van FUERA de cualquier consulta de medios; si no,
   arriba de 980 las diapositivas extra se apilaban como bloques sueltos. */
[data-carrusel]:not([data-vivo]) .heroe-diapo:not([data-activa]) { display: none; }
[data-carrusel]:not([data-vivo]) .heroe-puntos { display: none; }

/* --- El héroe del teléfono cambia de foto --------------------------------
   Solo en teléfono. En escritorio la figura es el recorte de los gemelos
   integrado en el héroe, y ahí una foto rotando pelearía con el titular.

   Las diapositivas van APILADAS en absoluto y el marco lleva su propia
   `aspect-ratio`. Si la primera se quedara en el flujo dando la altura, al
   desvanecerla se vería el fondo del marco por debajo; y en cuanto hubiera
   tres fotos habría que reescribirlo. Así el alto no depende de ninguna. */
@media (max-width: 979px) {
  /* 🔴 16/9 y no 3/2. La pieza de portada del telefono es una composicion 16:9
     CON su titular impreso; en un hueco de 3/2 el `object-fit: cover` recortaba
     por los lados y se comia justo la franja del texto. Las fotos de sede que
     rotan detras son 16:9 dos de ellas y 3:2 la otra, asi que la que pierde algo
     de alto es una sola, y por arriba, donde solo hay cielo. */
  .heroe-gemelos-int { aspect-ratio: 16 / 9; }

  /* 🔴 Un fundido cruzado normal —una baja mientras la otra sube— tiene un
     punto medio en el que las dos están al 50% y se ven SUPERPUESTAS. Ese
     instante turbio es lo que hace que parezca apresurado: el ojo ve una
     mezcla sucia y la lee como un salto, por lento que vaya.

     Aquí la que entra se funde ENCIMA de la que sale, y la que sale se queda
     opaca por debajo hasta que la nueva la ha tapado del todo. En ningún
     momento hay dos imágenes traslúcidas a la vez: se ve una fotografía
     revelándose sobre otra. Por eso puede ir más rápido sin parecer brusco.

     Requiere tres estados y no dos: la que entra (arriba, fundiéndose), la
     que sale (debajo, opaca, SIN transición) y el resto (invisibles). */
  .heroe-diapo {
    position: absolute; inset: 0;
    opacity: 0; z-index: 0;
    transition: opacity 620ms cubic-bezier(.33, 0, .2, 1);
  }
  .heroe-diapo[data-activa] { opacity: 1; z-index: 2; }
  /* Sin transición: tiene que estar opaca YA, o vuelve el punto turbio. */
  .heroe-diapo[data-saliendo] { opacity: 1; z-index: 1; transition: none; }
  /* 🔴 El <picture> TAMBIEN tiene que llenar la diapositiva.
     Es un envoltorio invisible que se cuela entre `.heroe-diapo` y la <img>, y
     nadie lo dimensionaba: quedaba en alto automatico, asi que el `height: 100%`
     de la imagen no tenia contra que resolverse y caia en tamano intrinseco.
     Medido: la diapositiva 350x197 y la imagen 350x233 dentro. Con `cover`, esos
     36 px de mas la agrandan y le comen 32 px por CADA LADO — justo la franja
     donde va el titular impreso de la pieza de portada.
     Se veia como «la imagen sale recortada» y parecia cosa del recorte o del
     zoom; no era ni lo uno ni lo otro. */
  .heroe-diapo picture { display: block; width: 100%; height: 100%; }
  .heroe-diapo img { width: 100%; height: 100%; object-fit: cover; display: block; }

  /* La curva se eligió midiendo, no a ojo. Con una desaceleración fuerte
     —`cubic-bezier(.22,.6,.3,1)`— el 62% del recorrido ocurría en el primer
     cuarto de tiempo y el último cuarto era un 2%: un tirón al principio y
     luego una foto quieta. Repartido por cuartos:

       .22,.6,.3,1     62%  27%   9%   2%   ← tirón y parón
       .4,.12,.45,1    21%  44%  28%   7%
       .5,.2,.5,.9     17%  36%  34%  13%   ← esta
       linear          25%  25%  25%  25%   ← se mueve, pero sin carácter

     Arranca despacio mientras la foto se está revelando, se ve moverse todo
     el rato, y afloja al final para posarse. */
  .heroe-diapo[data-activa] img { animation: heroe-posarse 4220ms cubic-bezier(.5, .2, .5, .9) forwards; }

  /* 🔴 La PRIMERA diapositiva no se posa: se queda quieta.
     Ese `scale(1.062)` es un acercamiento del 6,2% y recorta un 3% por cada
     lado. En una fotografia no se nota; en esta pieza SI, porque lleva el
     titular impreso cerca del borde y el zoom se lo come. Cualquier zoom, por
     pequeno que sea, se come texto pegado al margen.
     Las fotos de sede que vienen despues lo conservan: ahi no hay texto que
     proteger y el gesto es lo que hace que la foto se sienta viva. */
  .heroe-diapo:first-child img { animation: none; transform: none; }
  @keyframes heroe-posarse {
    from { transform: scale(1.062) translate(-0.9%, 0.55%); }
    to   { transform: scale(1) translate(0, 0); }
  }

  /* Los puntos. Van sobre la foto, dentro de una pastilla oscura: encima de
     una foto cualquiera, un punto blanco suelto puede caer sobre una zona
     clara y desaparecer. La pastilla le garantiza el fondo.
     z-index 3 porque el filo degradado del marco es 2. */
  .heroe-puntos {
    position: absolute; z-index: 3;
    left: 50%; transform: translateX(-50%); bottom: .75rem;
    display: flex; gap: .1875rem; align-items: center;
    padding: .25rem .3125rem; border-radius: 999px;
    /* El azul del manual (#19255a) en vez de un gris neutro: la pastilla deja
       de parecer un control del navegador y pasa a ser de la marca. El filo
       claro la despega de las fotos con zonas oscuras.

       🔴 La opacidad es 0,88 y no 0,6 por una razón medida. La pastilla se
       compone con lo que tenga detrás, y detrás va una foto que cambia. Sobre
       una foto media el punto celeste daba 3,17:1 —justo—, pero sobre una zona
       CLARA caía a 1,46:1 y el punto activo desaparecía. A 0,88 el peor caso
       sube a 3,4:1. Es lo que tiene poner un control encima de contenido que
       no controlas: hay que medir contra el fondo más desfavorable, no contra
       el que se ve ahora. */
    background: rgba(25, 37, 90, .88);
    border: 1px solid rgba(255, 255, 255, .16);
  }
  @supports (backdrop-filter: blur(1px)) {
    .heroe-puntos { backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); }
  }
  /* El punto se ve de 8 px pero el botón mide 24: por debajo de eso el dedo
     falla. El área de toque no tiene por qué ser lo que se ve. */
  .heroe-punto {
    width: 24px; height: 24px; padding: 0; border: 0; background: none;
    cursor: pointer; display: grid; place-items: center;
    -webkit-tap-highlight-color: transparent;
  }
  .heroe-punto::before {
    content: ""; width: 7px; height: 7px; border-radius: 50%;
    background: rgba(255, 255, 255, .5);
    transition: background-color 300ms ease, width 300ms var(--sal);
  }
  /* 🔴 `#ff4da6` y NO el `#e6007e` del manual, y no es un capricho: sobre la
     pastilla azul el magenta del manual da 2,84:1 con una foto media y 2,28:1
     con una foto clara. El mínimo de un control es 3:1. Ni subiendo la
     pastilla al 94% llega. `#ff4da6` da 4,18 / 3,35 y es el mismo magenta que
     el sitio ya usa sobre oscuro —los «Ver la sede →» y el final del degradado
     del titular—, así que no entra un color nuevo.

     Va escrito y no como `var(--enlace-magenta)` a propósito: ese token cambia
     a #d4007a en tema claro, y esta pastilla es azul oscuro en los DOS temas.
     Un color fijo sobre un fondo fijo no puede depender del tema.

     El activo se distingue por color Y por forma (alargado), no solo por
     brillo: quien no separa bien los tonos lo ve igual. */
  .heroe-punto[aria-current="true"]::before {
    background: #ff4da6; width: 18px; border-radius: 999px;
    box-shadow: 0 0 0 1px rgba(255, 77, 166, .3);
  }
  .heroe-punto:focus-visible { outline: 2px solid #fff; outline-offset: -2px; border-radius: 999px; }
}

/* Quien pide menos movimiento se queda con la primera foto y nada se mueve:
   ni el cambio ni el acercamiento. El JS tampoco arranca el reloj. */
@media (prefers-reduced-motion: reduce) {
  .heroe-diapo { transition: none; }
  .heroe-diapo[data-activa] img { animation: none; }
}


/* 🔴 El halo de la foto del local ARRASTRABA LA PÁGINA sobre el tema claro.
   Sobre claro el halo necesita otra geometría y se ensancha a `-9%` por los
   lados (ver el bloque de `.foto-sede::before`). En un teléfono de 390 px eso
   son 31 px de caja fuera del canal por la derecha, y el DOCUMENTO pasaba a
   medir 402: la barra fija se quedaba quieta y todo lo demás se corría con el
   dedo. Medido: 402 sobre claro, 390 sobre oscuro, donde el inset es `-5%`.

   Es el mismo fallo que ya se documentó en `.heroe-rejilla::before`, y se
   arregla igual que allí: recortando en X la sección que lo contiene, no la
   geometría del halo. El `blur(70px)` sigue derramando el color hasta el borde
   de la pantalla, así que se ve exactamente igual; lo que se acaba es el
   desbordamiento de la CAJA, que es lo que el navegador mide. */
section:has(.foto-sede) { overflow-x: clip; }

/* === PÁGINA DE SEDE ======================================================
   Tres páginas que existen para una sola cosa: que quien ya sabe a cuál va,
   agende ahí. La versión anterior no lo cumplía, y no por diseño: **dos de
   las tres llamadas «Agendar en esta sede» apuntaban a `/agendar` a secas**,
   o sea al selector, a que volvieras a elegir la sede en la que ya estabas.
   Lo mismo hacía la barra del teléfono. Solo el botón enterrado dentro de
   «Los datos» llevaba de verdad a la agenda de esa sede.

   Corregido eso, el resto es hacer que la página se lea en el orden en que se
   decide: qué sede es y si está abierta → por qué esta y no otra → qué dice
   la gente → los datos duros → y, si no te sirve, las otras dos. */

/* --- La línea de estado del héroe ---------------------------------------
   Va entre la entradilla y los botones, y es lo que la primera pantalla no
   tenía: si está abierta AHORA y qué nota tiene. Dos datos, en una línea, sin
   caja: un bloque de cifras en el héroe convierte una página de sede en una
   ficha de producto. */
.sede-estado {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
  gap: .625rem 1rem;
  margin-top: 1.5rem;
}
.sede-estado-nota {
  display: inline-flex; align-items: baseline; gap: .375rem;
  font-size: .9375rem; color: var(--suave);
}
.sede-estado-nota strong { font-size: 1.0625rem; font-weight: 700; color: var(--tinta); }
/* La estrella va del color de la nota y no del celeste de marca: a 15 px el
   celeste da 2,95:1 sobre el tema claro. Misma razón que en /agendar. */
.sede-estado-nota .elige-estrella { color: var(--tinta); }

/* --- Por qué esta sede ---------------------------------------------------
   Sube de la penúltima sección a justo debajo de la foto: es el argumento de
   la página, no un apéndice. Y deja de ser tres `.aviso` grises en columna —un
   componente pensado para advertencias— para ser tres fichas en fila.

   Comparte declaraciones con `.amano` de /agendar en vez de copiarlas: es la
   misma idea (raya arriba, título, texto, sin tarjeta) y tiene que verse
   igual. Lo único que cambia es que aquí NO van numeradas: tres razones no son
   una secuencia, y numerarlas insinúa un orden que no existe. */
.razones { list-style: none; margin: 0; padding: 0; }
@media (min-width: 760px) { .razones { grid-template-columns: repeat(3, 1fr); gap: 1.75rem; } }

/* --- La ficha de datos ---------------------------------------------------
   El horario deja de ser texto muerto: lleva la misma pastilla en vivo que el
   selector, que es el único dato de esta página que cambia durante el día. */
.datos .elige-estado {
  display: flex; width: fit-content;   /* su propia línea: pegada a «Domingos,
                                          cerrado» se leía como lo contrario */
  margin: .75rem 0 0;
}

/* WhatsApp y teléfono salían dentro de la lista de datos, en la columna de la
   derecha y en letra de dato. Son ACCIONES: una llama y el otro abre un chat.
   Salen de la `<dl>` y se ponen donde se ponen las acciones. */
.datos-contacto {
  display: flex; flex-wrap: wrap; gap: .625rem;
  margin-top: .875rem;
}
/* Los dos de contacto SÍ son menores que el de agendar, y a propósito: son el
   plan B. Antes pasaba al revés —el primario iba debajo y con menos relleno
   que ellos—, y la acción de la página parecía la tercera opción. */
.datos-contacto .btn {
  padding: .6875rem 1.125rem; font-size: var(--t-menor);
  min-height: 44px;            /* el mínimo táctil; con el relleno solo daba 42 */
}

/* La tarifa, en una línea y no en una sección: quien llega a una sede desde
   Google quiere confirmarla, no comparar. El mismo trato que en /agendar. */
/* Cruza las dos columnas de la ficha, no vive dentro de una. Ver la nota del
   HTML: es una confirmación de precio y en una columna de 600 px partía en dos
   líneas lo que a lo ancho cabe en una. */
.sede-tarifa {
  margin-top: clamp(1.75rem, 3vw, 2.5rem);
  padding-top: 1.25rem;
  border-top: 1px solid var(--borde);
  font-size: var(--t-menor); line-height: 1.6; color: var(--texto);
}
/* Mismo arreglo que en `.elige-tarifa`: en el teléfono `.btn-texto` pasa a
   `inline-flex` y se come el espacio antes de la flecha. */
.sede-tarifa .btn-texto { gap: .375rem; margin-left: .25rem; }
.sede-tarifa strong { color: var(--tinta); font-weight: 700; }

/* --- Cómo llegar ---------------------------------------------------------
   Tres párrafos seguidos sin más jerarquía que un h3. Pasan a fichas con la
   misma raya que las razones, para que se vean como una lista de opciones —que
   es lo que son— y no como un texto corrido. */
.llegar { list-style: none; margin: 0; padding: 0; display: grid; gap: 1.25rem; }
.llegar-item { padding-top: .875rem; border-top: 1px solid var(--borde); }
.llegar-titulo {
  font-size: 1rem; font-weight: 700; color: var(--tinta);
  margin-bottom: .5em;
}
.llegar-item p { color: var(--texto); font-size: var(--t-menor); line-height: 1.6; }
.llegar-accion { margin-top: 1.25rem; }
.llegar-accion .btn { padding: .75rem 1.25rem; font-size: var(--t-menor); }

/* --- Las otras dos sedes -------------------------------------------------
   Si ésta no te sirve, la salida no puede ser un «Ver las otras sedes» al
   final del todo: son dos tarjetas con su horario en vivo y su botón, las
   mismas del selector de /agendar. Mismo componente, misma información y el
   mismo motor de estado — aquí solo hay dos, y `auto-fit` las reparte. */
.otras-sedes { max-width: 52rem; margin-inline: auto; }

/* Las dos sedes hermanas, en riel en el teléfono. Entran en el patrón de la
   casa (`.sedes-tarjetas`, `.valoraciones`, `.guias`, `.resenas-lista`), pero
   NO pueden ir en aquel bloque: está 470 líneas más arriba y `.elige { display:
   grid }` pesa lo mismo (0,1,0), así que le gana por orden y el riel se
   escribía sin aplicarse. Tiene que vivir DESPUÉS del componente que pisa.

   🔴 Aquí sí y en /agendar no, y la diferencia es de fondo: allí las tres
   tarjetas SON la decisión, y meter dos detrás de un gesto es esconder dos
   tercios de las opciones. Aquí son la salida para quien ya vio que ésta no le
   sirve, y apiladas costaban media pantalla de una página que ya es larga. */
@media (max-width: 979px) {
  .otras-sedes {
    display: flex;
    grid-template-columns: none;
    gap: .875rem;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scroll-padding-inline: var(--canal);
    padding-inline: var(--canal);
    /* El sangrado negativo hace que la segunda tarjeta asome por el borde:
       es lo que le dice al dedo que hay más. */
    margin-inline: calc(var(--canal) * -1);
    max-width: none;
    padding-bottom: .5rem;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .otras-sedes::-webkit-scrollbar { display: none; }
  .otras-sedes > * { flex: 0 0 84%; max-width: 320px; scroll-snap-align: center; }
  /* En un riel el hover no existe, y `.elige-sede` levanta 6 px al señalarlo:
     con el dedo se dispara al rozar y la tarjeta salta mientras desplazas.
     Misma corrección que ya lleva `.sede-card` en el bloque de rieles. */
  .otras-sedes .elige-sede { transform: none; }
}

/* === RITMO DE LAS PÁGINAS REDISEÑADAS (18-09-2026) ======================
   Medido con `ritmo.js`, no mirado. Dos cosas salieron de ahí. */

/* --- La foto de sede va CON el héroe -------------------------------------
   Vive en su propia `<section class="seccion-corta">`, así que entre los
   botones del héroe y la foto había 48 px del héroe + 96 px de la sección =
   **144 px**, y la foto se leía como un bloque suelto en vez de como la
   imagen de esa portada. Debajo sí se queda el aire completo, que es donde
   de verdad empieza otra cosa. */
body[data-pagina^="sede-"] .cabecera-pagina + .seccion-corta { padding-top: 0; }

/* --- La costura entre la foto y lo que sigue -----------------------------
   Éste es el hueco que se ve en la página: **96 px del final de la foto + 128
   del principio de la sección siguiente = 224 px** de fondo vacío antes de
   «Por qué la gente elige esta sede». Con el titular centrado encima, la
   pantalla entera se lee como un descanso.

   Es la ÚNICA costura de estas páginas en la que el fondo no cambia. En las
   otras tres lo hace —entra o sale una banda `.niebla` o `.oscura`— y ahí el
   aire no sobra: es el respiro de la banda, y recortarlo la deja apretada.

   🔴 La primera versión de esta regla no hacía NADA: decía
   `.seccion:not(.niebla) + .seccion:not(.niebla)`, y la sección de la foto no
   es `.seccion` sino `.seccion-corta`. Lo delató medirla, no leerla. Por eso
   va nombrando las dos clases y cada una con SU token, que no valen lo mismo
   (`--seccion-corta` es 6rem y `--seccion` 8). */
body[data-pagina^="sede-"] .seccion-corta:has(+ .seccion:not(.niebla):not(.oscura)) {
  padding-bottom: calc(var(--seccion-corta) * .55);
}
body[data-pagina^="sede-"] .seccion-corta + .seccion:not(.niebla):not(.oscura) {
  padding-top: calc(var(--seccion) * .55);
}

/* --- Las fichas de tres columnas, con presencia --------------------------
   `.razones` ocupaba 116 px dentro de una sección de 586: el 80 % de la caja
   era aire, y el bloque —titular de 17 px y texto de 15— se leía como una
   nota al pie de un titular de 56. No se arregla quitando aire, se arregla
   dándole cuerpo al texto, que además es el que lleva el argumento.

   `--t-cuerpo` y no `--t-menor`: en tres columnas de 373 px, 15 px se queda
   corto y la línea sale de 60 caracteres, por debajo del mínimo cómodo. */
@media (min-width: 760px) {
  .razones-titulo,
  .amano-titulo,
  .oficios-titulo { font-size: 1.125rem; }
  .razones-item p,
  .amano-item p,
  .oficios-item p { font-size: var(--t-cuerpo); line-height: 1.65; }
  /* Y la raya respira: 1 rem entre el filo y el título dejaba el título
     colgando de la línea. */
  .razones-item,
  .amano-item,
  .oficios-item { padding-top: 1.25rem; }
}

/* ============================================================================
   /SEDES: LAS TRES, CON LO QUE DE VERDAD LAS DIFERENCIA

   La página tenía tres tarjetas con nombre, dirección y una frase, y debajo
   una tabla comparativa de cinco filas de las que TRES decían «Sí · Sí · Sí».
   O sea: la mitad de la página repetía que no hay ninguna diferencia, en la
   única página del sitio que existe para contarlas.

   Ahora el dato vive en la tarjeta —horario, parqueadero, TransMilenio y nota
   de Google, las mismas cuatro filas y en el mismo orden en las tres— y la
   tabla se fue. Tres tarjetas en fila con filas idénticas SON la comparación,
   con la ventaja de que cada columna termina en su propio botón.

   🔴 Nada de esto toca `.sede-card`: la home y /contacto usan el mismo
   componente y son otra capa. Lo que cambia va colgado de
   `body[data-pagina="sedes"]`, que es (0,2,0) y gana sin subirle la
   especificidad a nadie, o son elementos nuevos que solo existen aquí.
   ========================================================================== */

/* El botón de ubicación y las tarjetas son la misma conversación: el aire de
   sección entre la portada y lo que sigue sobra, igual que en /agendar. */
body[data-pagina="sedes"] .cabecera-pagina { padding-bottom: 1.5rem; }
body[data-pagina="sedes"] [data-elige] { padding-top: 0; }

/* --- La tarjeta pasa a alinearse a la izquierda --------------------------
   `.sede-card` centra su texto, y en la home está bien: allí es un cartel de
   tres líneas. Aquí lleva cuatro pares etiqueta/valor, y un par centrado no
   se puede leer en columna —el ojo pierde el punto de partida en cada fila—.
   Los botones siguen centrados: `.sede-card-acciones` es flex con
   `align-items: center` y no hereda esto. */
body[data-pagina="sedes"] .sede-card { text-align: left; }
body[data-pagina="sedes"] .sede-card address { margin-top: .5rem; }

/* --- Que las tres tarjetas lean como una tabla ---------------------------
   🔴 Medido, no supuesto: «Autopista Norte 106» cabe en UNA línea y los otros
   dos nombres en dos, y la frase de Salitre ocupa tres líneas donde las otras
   ocupan dos. Resultado: la fila «Horario» empezaba 53 px más arriba en la
   tercera tarjeta que en las otras dos, y con ella las cuatro filas de datos.

   Eso no es un detalle estético: el argumento entero de esta página es que
   tres tarjetas con las MISMAS cuatro filas en el mismo orden son la tabla
   comparativa que se quitó. Si las filas no se alinean, no lo son.

   Se reserva el alto de las líneas que hacen falta, que es lo mismo que ya
   hace `.elige-dir` en /agendar. En `em` y multiplicando por el interlineado
   declarado aquí al lado: así el hueco sube solo si algún día sube la letra,
   en vez de quedarse en un número que nadie recuerda de dónde salió.

   Solo de 980 px para arriba: en el riel del teléfono las tarjetas van una
   detrás de otra y no hay ninguna fila que alinear —reservar alto ahí sería
   dejar huecos vacíos dentro de cada tarjeta. */
@media (min-width: 980px) {
  body[data-pagina="sedes"] .sede-card-cuerpo .h3 {
    line-height: 1.25;
    min-height: calc(2 * 1.25em);       /* dos líneas de nombre */
  }
  body[data-pagina="sedes"] .sede-card-ventaja {
    line-height: 1.55;
    min-height: calc(3 * 1.55em);       /* tres líneas de argumento */
  }
  /* La dirección más larga (la de Salitre, con módulo, locales y piso) cabe en
     dos líneas a partir de unos 1.200 px y pide tres por debajo. Se reserva lo
     que hace falta en cada tramo en vez de reservar siempre tres: una línea
     vacía en las tres tarjetas a 1.440 px es justo el aire muerto que esta
     pasada vino a quitar. La medida es del texto real, no del caso teórico. */
  body[data-pagina="sedes"] .sede-card address {
    line-height: 1.5;
    min-height: calc(3 * 1.5em);
  }
}
@media (min-width: 1200px) {
  body[data-pagina="sedes"] .sede-card address { min-height: calc(2 * 1.5em); }
}

/* La pastilla de estado va ARRIBA del todo, antes del nombre: es el único
   dato de la tarjeta que cambia durante el día, y lo primero que se pregunta
   quien mira una sede a las 5 de la tarde. Nace `hidden`; lo destapa el JS. */
body[data-pagina="sedes"] .sede-card-cuerpo .elige-estado { margin-bottom: .75rem; }

/* La frase que diferencia a esta sede de las otras dos. Perdió el `flex: 1`
   —ahora el que empuja los botones al fondo es el bloque de acciones— y ganó
   una raya debajo, que separa el argumento de los datos duros. */
body[data-pagina="sedes"] .sede-card-ventaja {
  flex: none;
  margin-top: 1rem;
  font-size: var(--t-menor); line-height: 1.55;
}
/* `margin-top: auto` en las acciones: las tres tarjetas alinean sus botones
   aunque la dirección ocupe una línea o tres. Antes lo hacía el `flex: 1` de
   la ventaja, que ya no lo tiene. */
body[data-pagina="sedes"] .sede-card-acciones {
  margin-top: auto; padding-top: 1.25rem; gap: .5rem;
}
body[data-pagina="sedes"] .sede-card-acciones .btn { width: 100%; min-height: 52px; }

/* Los dos enlaces de texto van EN FILA, no apilados: son el mismo rango —ver
   la ficha completa y abrir el mapa— y uno debajo del otro parecían una
   escalera de tres acciones con el botón. */
.sede-card-secundarias {
  display: flex; flex-wrap: wrap; justify-content: center;
  gap: .25rem 1.25rem;
  margin: 0;
}
/* Misma trampa anotada en `.elige-tarifa`: en el teléfono `.btn-texto` pasa a
   `inline-flex` para llegar a los 44 px de objetivo táctil y se come el nodo
   de espacio del HTML, así que salía «Cómo llegar→». Calificado a este
   componente: `.btn-texto` a secas lo arreglaría también en la home, que es
   otra capa. */
.sede-card-secundarias .btn-texto { gap: .375rem; }

/* --- La zona, sobre la foto ---------------------------------------------
   Occidente, noroccidente y norte es el eje por el que de verdad se elige, y
   hasta hoy solo estaba dicho de pasada en la entradilla. Va sobre la foto y
   no en el cuerpo por lo mismo que la insignia de «la más cercana»: ahí no
   ocupa sitio en el flujo, así que no desalinea los titulares de la fila.

   Fondo SÓLIDO y no translúcido. Encima de una foto, un fondo translúcido
   deja el contraste del texto a merced de lo que haya debajo, y estas tres
   fotos no son ni del mismo sitio ni de la misma luz. Negro al 88 % contra
   blanco puro compone un gris de 44, y #fff sobre él da 10,5:1.

   Y NO es magenta: el magenta de esta hoja significa «ésta es la tuya» y lo
   pone el usuario al pedir la más cercana. Una etiqueta de zona es un rótulo
   de mapa, no un estado. */
.sede-card-zona {
  position: absolute; top: 1rem; left: 1rem; z-index: 1;
  display: inline-flex; align-items: center;
  margin: 0; padding: .375rem .8125rem;
  border-radius: 999px;
  background: rgba(10, 14, 20, .88);
  border: 1px solid rgba(255, 255, 255, .22);
  font-size: .8125rem; font-weight: 700; line-height: 1.3;
  color: #fff;
  box-shadow: 0 4px 14px rgba(0, 0, 0, .3);
}

/* --- La distancia ---------------------------------------------------------
   🔴 Cambia de token, y es una corrección de contraste, no un retoque.
   `--resalte-magenta` (#e6007e) a 14 px y 500 da 3,99:1 sobre el vidrio
   oscuro y 4,46:1 en el claro: las dos por debajo del 4,5 que pide la norma
   para texto normal. `--enlace-magenta` existe justo para esto y es el que
   ya arregló `.elige-dist` en /agendar.

   Va calificado a esta página: la home y /contacto usan el mismo elemento y
   tienen el mismo fallo, pero son otra capa y se avisa aparte. */
body[data-pagina="sedes"] .sede-card-cerca {
  color: var(--enlace-magenta); font-weight: 600;
}

/* --- Las cuatro filas de datos -------------------------------------------
   Se reusa `.elige-datos` tal cual, sin tocarlo: es el mismo objeto —pares
   etiqueta/valor con una raya encima— y tiene que verse igual que en /agendar
   y que en las fichas de sede. Lo único que cambia es que aquí va pegado al
   fondo de la tarjeta, así que se le quita el margen de arriba. */
body[data-pagina="sedes"] .elige-datos { margin-top: 1rem; }

/* --- La banda de lo idéntico ---------------------------------------------
   Lo que queda de la tabla: sus tres filas de «Sí · Sí · Sí», dichas una sola
   vez. Sin tarjetas y sin vidrio a propósito —es una garantía, no una oferta—
   y con una marca de verificación en vez de un número, porque no es una
   secuencia. Mismo dibujo que las listas de `.celda`, para que una marca de
   «esto lo tienes» se vea igual en todo el sitio. */
.igual {
  list-style: none; margin: 0; padding: 0;
  display: grid; gap: 1rem 2.5rem;
}
.igual li {
  position: relative; padding-left: 2rem;
  font-size: var(--t-cuerpo); line-height: 1.55; color: var(--texto);
}
.igual li strong { color: var(--tinta); font-weight: 700; }
/* El palito de la marca de verificación, dibujado con dos bordes y un giro.
   Es un adorno: lo que informa es el texto, y por eso no lleva ni `content`
   con texto ni papel accesible. */
.igual li::before {
  content: ""; position: absolute;
  left: .3125rem; top: .5rem;
  width: .4375rem; height: .8125rem;
  border: solid var(--cian); border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}
@media (min-width: 720px) { .igual { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1080px) { .igual { grid-template-columns: repeat(4, 1fr); gap: 1.5rem; } }

.igual-pie {
  margin-top: 2rem; padding-top: 1.25rem;
  border-top: 1px solid var(--borde);
  font-size: var(--t-menor); line-height: 1.6; color: var(--suave);
}
.igual-pie .btn-texto { gap: .375rem; margin-left: .25rem; }

/* --- El teléfono ---------------------------------------------------------
   Por debajo de 980 px las tarjetas son un riel horizontal de 320 px de ancho
   máximo. Ahí una etiqueta de 92 px a la izquierda le deja 180 al valor, y
   «Cubierto, la primera hora sin costo» salía en tres renglones colgando de
   una palabra. En una columna estrecha el par se apila: la etiqueta encima,
   pequeña, y el valor debajo a todo el ancho. */
@media (max-width: 979px) {
  body[data-pagina="sedes"] .elige-datos > div {
    grid-template-columns: 1fr; gap: .1875rem;
  }
  body[data-pagina="sedes"] .elige-datos dt { font-size: var(--t-mini); }

  /* La barra general lleva a /agendar, que es el selector — y esta página ya
     es un selector, con la ventaja de que sabe cuál te queda más cerca. Se
     apaga y manda `.barra-elige`, igual que en /agendar. */
  body[data-pagina="sedes"] .barra-movil { display: none; }
  /* Y se devuelve el hueco del pie que la barra general reservaba: la regla
     general lo cuenta con `.barra-movil` a la vista. */
  body[data-pagina="sedes"] .pie { padding-bottom: calc(2.5rem + 76px + env(safe-area-inset-bottom)); }
}


/* ============================================================================
   /NOSOTROS: LA PIEZA DE MARCA Y LO QUE RESPALDA A LA CASA

   La página era una columna de prosa: cinco de sus siete secciones eran texto
   dentro de `.estrecho`, con los dos lados de la pantalla vacíos. Y la página
   que tiene que decir quién eres no traía **ni un sello, ni una norma, ni un
   organismo**: todo eso vivía en /transparencia, que es donde se va a buscar un
   documento, no donde se llega a saber con quién estás tratando.
   ========================================================================== */

/* --- La pieza del cliente y su relevo en el teléfono ---------------------
   `.cartel` ya existe (lo estrenó /el-examen) y no se toca: fondo claro en los
   dos temas, esquinas redondas y la imagen a sangre. Lo único propio de aquí
   es CUÁNDO se ve.

   La pieza mide 2.960 × 1.240 (2,39:1). A 390 px de pantalla son 163 px de
   alto, y el titular de 100 px baja a 13: ilegible. No hay versión vertical,
   así que el relevo del teléfono no es una imagen más pequeña, es el MISMO
   mensaje en texto de verdad — que además se puede seleccionar, ampliar y leer
   en voz alta, cosa que un texto dibujado dentro de un PNG no.

   `display: none` y no `visibility` ni `opacity`: saca el bloque también del
   árbol de accesibilidad, así que nadie oye el mensaje dos veces. */
.cartel-nosotros { display: none; }
@media (min-width: 980px) { .cartel-nosotros { display: block; } }

/* --- La pieza, de portada -------------------------------------------------
   Ya no ilustra un titular: ES la portada. Arriba solo van las migas, que son
   navegación y miden 13 px.

   El relleno de arriba es el de una cabecera de página menos lo que ocupan las
   migas, para que la pieza empiece donde empezaría un h1. */
.pieza-portada {
  padding-top: clamp(4.5rem, 8vw, 7rem);
  padding-bottom: clamp(2rem, 4vw, 3.5rem);
  /* 🔴 El halo sangra un 6 % a cada lado de una caja que a 1.440 px ya mide
     1.344: el documento se estiraba hasta 1.473 px y la página se arrastraba de
     lado. A 390 px pasaba lo mismo por un píxel. Lo cazó medir el ancho del
     documento, no mirarlo: 1 px de arrastre no se ve, se nota al deslizar.

     `clip` y no `hidden`: `hidden` crea un contenedor de scroll y rompería
     cualquier `position: sticky` que se meta aquí dentro; `clip` solo recorta.
     Y solo en X, para que el halo siga sangrando por arriba y por abajo. */
  overflow-x: clip;
}
.pieza-portada .migas { margin-bottom: clamp(1rem, 2vw, 1.5rem); }

/* La caja de la pieza es MÁS ANCHA que el resto del contenido. Con 2,39:1 de
   proporción, dentro de la columna de 1.240 la pieza medía 479 px de alto:
   menos que la tarjeta de una sede, para lo que es el mensaje de la marca.
   A 1.400 mide 585 y ya sostiene una pantalla.

   No va a sangre completa a propósito: la pieza trae su propio margen blanco
   dibujado y pegada a los cantos del navegador se leería como un error de
   recorte, no como una portada. */
.pieza-caja {
  position: relative;
  width: min(1400px, 100% - var(--canal) * 2);
  margin-inline: auto;
}

/* --- El halo de marca -----------------------------------------------------
   La pieza tiene fondo casi blanco y sobre el pozo oscuro del sitio se pegaba
   como un recorte de papel. El halo la ilumina desde detrás con los dos
   colores de la casa.

   🔴 Sin `filter: blur()`: son dos degradados radiales con parada suave. Un
   desenfoque dentro de una capa compuesta —y aquí hay una, porque GSAP anima
   la pieza— sale con cantos rectos en Safari y Chrome no lo enseña. Es la
   lección que vigila `blur-guardia.js`.

   `pointer-events: none` y `aria-hidden`: es luz, no contenido. */
.pieza-halo {
  position: absolute; z-index: 0; pointer-events: none;
  inset: -12% -6%;
  border-radius: 50%;
  background:
    radial-gradient(45% 55% at 22% 45%, rgba(0, 159, 227, .38), transparent 70%),
    radial-gradient(45% 55% at 78% 55%, rgba(230, 0, 126, .30), transparent 70%);
  opacity: 0;
}
/* Entra DESPUÉS de la pieza, no con ella: primero se lee el mensaje y luego se
   enciende la luz. Y respira muy despacio —14 s— porque una luz de fondo que
   late deprisa se convierte en el protagonista, y la protagonista es la pieza. */
@media (prefers-reduced-motion: no-preference) {
  .pieza-halo { animation: pieza-halo-entra 1.4s ease-out .9s forwards, pieza-halo-late 14s ease-in-out 2.3s infinite; }
}
@media (prefers-reduced-motion: reduce) {
  .pieza-halo { opacity: .55; animation: none; }
}
@keyframes pieza-halo-entra { to { opacity: .55; } }
@keyframes pieza-halo-late {
  0%, 100% { opacity: .55; transform: scale(1); }
  50%      { opacity: .75; transform: scale(1.04); }
}
/* En el tema claro el halo sobra: sobre un fondo casi blanco, iluminar una
   pieza casi blanca no hace nada y deja dos manchas de color alrededor. */
:root[data-tema="claro"] .pieza-halo { display: none; }

/* La pieza va ENCIMA del halo. Sin esto el halo, que es un hermano posterior
   en el HTML... no lo es —va antes—, pero el `position: absolute` lo saca del
   flujo y sin `z-index` en la pieza quedaría por encima en cuanto la pieza no
   cree contexto propio. Se declara y se acabó. */
.cartel-nosotros,
body[data-pagina="nosotros"] .manifiesto { position: relative; z-index: 1; }

/* --- La costura con lo que sigue ------------------------------------------
   Debajo de la pieza va «Detrás de cada certificado», y el fondo no cambia:
   son los mismos 224 px de nada que ya se corrigieron en las páginas de sede
   —allí entre la foto y «Por qué esta sede»—. El relleno de abajo de la
   portada ya está acotado arriba; aquí se acota el de arriba de la sección. */
body[data-pagina="nosotros"] .pieza-portada + .seccion { padding-top: calc(var(--seccion) * .62); }

/* Y la otra costura sin cambio de fondo de esta página: entre la presentación
   y «Por qué existimos». Dos `.seccion` lisas seguidas suman sus dos rellenos
   —256 px a 1.440— y ahí no separan nada que no separe ya el propio contenido.
   Es la única pareja lisa que queda: en las otras cinco costuras entra o sale
   una banda (`.niebla` o `.oscura`) y ese aire SÍ es el respiro de la banda.

   🔴 La regla nombra las dos clases reales. La primera versión de esto en las
   páginas de sede decía `.seccion` cuando el elemento era `.seccion-corta`, y
   compiló, pasó el validador y no tocó un píxel. */
body[data-pagina="nosotros"] .seccion:not(.niebla):not(.oscura):has(+ .seccion:not(.niebla):not(.oscura)) {
  padding-bottom: calc(var(--seccion) * .62);
}
body[data-pagina="nosotros"] .seccion:not(.niebla):not(.oscura) + .seccion:not(.niebla):not(.oscura) {
  padding-top: calc(var(--seccion) * .62);
}
@media (min-width: 980px) { .manifiesto { display: none; } }

.manifiesto {
  border: 1px solid var(--borde);
  border-radius: var(--r-l);
  padding: clamp(1.5rem, 6vw, 2.25rem);
  background: var(--superficie);
}
@supports (backdrop-filter: blur(1px)) {
  .manifiesto { backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px); }
}
/* No es un `<h2>`: es la misma frase que la pieza lleva dibujada, y en esta
   página el titular de sección de más abajo («Lo que nos respalda») sí es un
   h2. Meter aquí otro h2 metía un nivel en la escalera de titulares que no
   corresponde a ninguna sección. Va con la clase, no con la etiqueta. */
.manifiesto-titular {
  font-size: clamp(1.75rem, 7.5vw, 2.25rem);
  font-weight: 700; line-height: 1.1;
}
/* 🔴 `--t-lead-mayor`, no `--t-lead`. Es la regla de la casa y aquí se rompió:
   el magenta de resalte solo cuenta como TEXTO GRANDE —listón 3:1 en vez de
   4,5— a partir de 18,66 px en peso 700. `--t-lead` da 17 px en el teléfono, y
   ahí «aprender» se quedaba en 3,99:1 sobre el vidrio oscuro. Medido, no
   supuesto. A 20 px el mismo magenta pasa con margen. */
.manifiesto-lema {
  margin-top: .75rem;
  font-size: var(--t-lead-mayor); line-height: 1.45; color: var(--tinta);
}
/* La cita, con el filo de marca a la izquierda. Es el único sitio de la página
   donde una raya vertical significa algo —«esto es una cita», que es su uso de
   toda la vida en tipografía— y no un adorno de tarjeta. */
.manifiesto-cita {
  margin: 1.5rem 0 0; padding-left: 1rem;
  border-left: 2px solid transparent;
  border-image: var(--letrero-texto) 1;
  font-size: var(--t-menor); line-height: 1.6; color: var(--texto);
}
.manifiesto-cita p { margin: 0; }
.manifiesto-cita footer {
  margin-top: .375rem;
  font-size: var(--t-mini); color: var(--enlace-magenta); font-weight: 600;
}
/* La píldora que la pieza trae dibujada, aquí dibujada con CSS. No es un enlace
   y no lo parece: sin flecha, sin color de enlace y sin cursor de mano. Es una
   firma. */
.manifiesto-firma {
  position: relative; isolation: isolate;
  display: inline-flex; align-items: center;
  margin-top: 1.5rem; padding: .625rem 1.25rem;
  border: 1px solid var(--borde); border-radius: 999px;
  font-size: var(--t-menor); font-weight: 700; color: var(--tinta);
}
@supports ((mask-composite: exclude) or (-webkit-mask-composite: xor)) {
  .manifiesto-firma { border-color: transparent; }
  .manifiesto-firma::before {
    content: ""; position: absolute; inset: 0; z-index: -1;
    border-radius: inherit; padding: 1px;
    background: var(--letrero-texto);
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
            mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
            mask-composite: exclude;
    pointer-events: none;
  }
}

/* --- Lo que nos respalda -------------------------------------------------
   No es el desfile de logos de la home repetido por tercera vez. Un logo solo
   dice que un sello existe; aquí cada ficha dice QUÉ es, QUÉ autoriza y a quién
   acudir si algo no cuadra, que es lo que de verdad respalda. Los cuatro
   textos salen de /transparencia: aquí no se ha inventado ninguno.

   Cuatro columnas a partir de 1080 y dos entre 640 y 1080. Con tarjeta y
   vidrio, para que se lean como credenciales y no como los cuatro párrafos de
   «Cuatro cosas que no negociamos», que van sin caja dos secciones más abajo. */
.respalda {
  list-style: none; margin: 0; padding: 0;
  display: grid; gap: 1rem;
}
.respalda-item {
  display: flex; flex-direction: column;
  padding: 1.5rem 1.5rem 1.625rem;
  border: 1px solid var(--borde); border-radius: var(--r-l);
  background: var(--superficie);
}
@supports (backdrop-filter: blur(1px)) {
  .respalda-item { backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px); }
}
/* El sello vive en una caja de alto FIJO. Los cinco logotipos tienen
   proporciones muy distintas (el de ONAC trae caja verde con aire propio), y
   sin un alto común cada ficha empezaba su titular a una altura. */
.respalda-sello {
  display: flex; align-items: center;
  height: 44px; margin-bottom: 1.25rem;
}
.respalda-sello img {
  height: 34px; width: auto; max-width: 100%; object-fit: contain;
}
/* El de ONAC va más alto, por la misma razón que en el desfile de la home: su
   logotipo trae caja con aire propio y a la misma altura la marca de DENTRO se
   ve más pequeña que las demás. */
.respalda-sello img.sello-onac { height: 42px; }
.respalda-titulo {
  font-size: 1.0625rem; font-weight: 700; line-height: 1.3; color: var(--tinta);
  margin: 0;
}
/* La norma o el organismo: el dato duro. En magenta de ENLACE y no de resalte
   —a 13 px el de resalte da 3,99:1 sobre el vidrio oscuro—, y en versalitas no,
   que a este tamaño se leen peor de lo que decoran. */
.respalda-norma {
  margin-top: .25rem;
  font-size: var(--t-mini); font-weight: 600; color: var(--enlace-magenta);
}
.respalda-texto {
  margin-top: .875rem; padding-top: .875rem;
  border-top: 1px solid var(--borde);
  font-size: var(--t-menor); line-height: 1.6; color: var(--texto);
}
.respalda-texto strong { color: var(--tinta); font-weight: 700; }
@media (min-width: 640px)  { .respalda { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1080px) { .respalda { grid-template-columns: repeat(4, 1fr); } }

/* 🔴 En el teléfono las cuatro fichas apiladas medían **1.329 px**: casi dos
   pantallas para leer cuatro credenciales que se comparan de un vistazo. En
   riel ocupan una. No se oculta nada —el contenido es el mismo—, cambia el eje;
   es lo mismo que ya hacen las tarjetas de sede y las guías.

   Va en `max-width: 639px` y no dentro del bloque de rieles compartido de más
   arriba: aquel vive 1.100 líneas ANTES que `.respalda { display: grid }`, y con
   el mismo peso habría ganado la rejilla por orden. Es la trampa que ya mordió
   con `.otras-sedes`. Aquí los dos tramos no se solapan, así que no pueden
   pelearse. */
@media (max-width: 639px) {
  .respalda {
    display: flex;
    gap: .875rem;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scroll-padding-inline: var(--canal);
    padding-inline: var(--canal);
    margin-inline: calc(var(--canal) * -1);
    padding-bottom: .5rem;           /* aire para la sombra al desplazar */
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .respalda::-webkit-scrollbar { display: none; }
  /* El sangrado negativo hace que la siguiente ficha asome por el borde, que es
     lo que le dice al dedo que hay más. */
  .respalda > * { flex: 0 0 84%; max-width: 320px; scroll-snap-align: center; }
}

.respalda-pie {
  margin-top: 1.75rem;
  font-size: var(--t-menor); line-height: 1.6; color: var(--suave);
  text-align: center;
}
/* El hueco antes de la flecha: en el teléfono `.btn-texto` pasa a `inline-flex`
   y el contenedor flex se come el nodo de espacio del HTML. Misma trampa ya
   anotada en `.elige-tarifa` y en `.sede-card-secundarias`, y acotada igual. */
.respalda-pie .btn-texto { gap: .375rem; margin-left: .25rem; }

/* --- Las cuatro profesiones ---------------------------------------------
   Iban en una frase corrida («médicos, optómetras, fonoaudiólogos y
   psicólogos») donde se leían como una enumeración de adorno. Son las cuatro
   personas distintas que te van a atender, una por cada valoración del examen,
   y eso es una LISTA. El nombre de la profesión y lo que hace van en la misma
   línea desde 520 px: dos columnas de ancho desigual, la etiqueta fija. */
/* Cuatro columnas, no dos ni tres: son cuatro profesiones y una por valoración,
   así que la cuenta de columnas ES el dato. En una fila de tres, la cuarta
   quedaría sola debajo y la correspondencia se pierde. */
@media (min-width: 760px)  { .oficios { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1080px) { .oficios { grid-template-columns: repeat(4, 1fr); gap: 1.5rem; } }

/* El párrafo de credenciales va al pie y no dentro de una ficha: habla de las
   cuatro a la vez. Medida de lectura acotada y centrado bajo la fila, que es
   como se cierra un bloque de columnas sin abrir otra sección. */
.oficios-pie {
  max-width: 46rem; margin: 2.25rem auto 0;
  font-size: var(--t-menor); line-height: 1.6; color: var(--suave);
  text-align: center;
}

/* --- Lo que viene --------------------------------------------------------
   Eran dos `.aviso` apilados dentro de una columna estrecha. `.aviso` es el
   componente de ADVERTENCIA —punto magenta, caja gris— y estos dos no advierten
   de nada: anuncian un servicio que va a abrir. Pasan a dos fichas a lo ancho,
   con su estado escrito en vez de insinuado por un punto de color. */
.proximo {
  list-style: none; margin: 0; padding: 0;
  display: grid; gap: 1rem;
}
.proximo-item {
  padding: 1.5rem;
  border: 1px dashed var(--borde);
  border-radius: var(--r-l);
}
/* Borde DISCONTINUO, y es lo único de la página que lo lleva: dice «esto
   todavía no está» sin tener que escribirlo dos veces. La frase de debajo lo
   dice con palabras, que es lo que lee quien no ve el borde. */
.proximo-estado {
  display: inline-flex; align-items: center; gap: .4375rem;
  margin-bottom: .75rem;
  font-size: var(--t-mini); font-weight: 600; color: var(--suave);
}
.proximo-estado::before {
  content: ""; width: 7px; height: 7px; border-radius: 50%;
  border: 1.5px solid var(--suave);
}
.proximo-titulo {
  margin: 0 0 .5em;
  font-size: 1.125rem; font-weight: 700; color: var(--tinta); line-height: 1.3;
}
.proximo-item p:last-child {
  margin: 0; font-size: var(--t-menor); line-height: 1.6; color: var(--texto);
}
.proximo-pie {
  margin-top: 1.5rem;
  font-size: var(--t-menor); color: var(--suave); text-align: center;
}
@media (min-width: 760px) { .proximo { grid-template-columns: repeat(2, 1fr); gap: 1.25rem; } }


/* El sello de una credencial va al 100 %, no al 72 % del desfile: allí es un
   adorno de fondo y aquí es lo primero que se mira de la ficha. Lo único que
   se hereda del desfile es el TRATAMIENTO —blanco monocromo sobre oscuro para
   las marcas de línea, color intacto para las que traen caja—, que es lo que
   tiene que ser igual en todo el sitio. */
.respalda-sello img { opacity: 1; }


/* --- La presentación: el titular sostiene, el texto explica ---------------
   Era un h1 y un párrafo de cinco líneas, centrados en una columna estrecha.
   El párrafo decía DOS cosas —qué somos en lenguaje de norma y qué significa
   eso en lenguaje de persona— y las decía seguidas, así que la segunda, que es
   la que se entiende, quedaba enterrada al final.

   Dos columnas: el titular a la izquierda y las dos frases a la derecha,
   separadas y con pesos distintos. La de norma en escala de entradilla; la de
   persona con una etiqueta delante que dice exactamente qué es. */
.presenta { display: grid; gap: clamp(1.5rem, 3vw, 2rem); }
.presenta-titular { margin: 0; }
.presenta-cuerpo { display: grid; gap: clamp(1.25rem, 2.4vw, 1.75rem); }
.presenta .lead { font-size: var(--t-lead-mayor); line-height: 1.5; color: var(--texto); }
/* La frase llana va SOBRE una raya y no dentro de una caja: no es un aviso ni
   una cita, es la misma idea dicha de otra manera. Una raya basta para decir
   «aquí cambia el registro». */
.presenta-llano {
  padding-top: clamp(1.25rem, 2.4vw, 1.75rem);
  border-top: 1px solid var(--borde);
  /* 🔴 `--t-lead-mayor` y no `--t-cuerpo`. Segunda vez en esta página con la
     misma regla de la casa: el magenta de resalte solo cuenta como TEXTO
     GRANDE —listón 3:1 en vez de 4,5— a partir de 18,66 px con peso 700, y
     `--t-cuerpo` son 17. Medido: 4,33:1 sobre el vidrio oscuro.

     La jerarquía entre las dos frases no se pierde: no la llevaba el tamaño,
     la llevan la raya y la etiqueta. Y que la frase que de verdad se entiende
     no sea más pequeña que la de lenguaje de norma es, si acaso, más correcto. */
  font-size: var(--t-lead-mayor); line-height: 1.6; color: var(--texto);
}
/* La etiqueta en su propia línea y en magenta de enlace (no el de resalte, que
   a 13 px no llega al contraste). Es un rótulo de registro, no un titular. */
.presenta-etiqueta {
  display: block; margin-bottom: .375rem;
  font-size: var(--t-mini); font-weight: 700; color: var(--enlace-magenta);
}
@media (min-width: 900px) {
  .presenta {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr);
    gap: clamp(2.5rem, 6vw, 5rem);
    align-items: start;
  }
}

/* --- Las credenciales responden al cursor ---------------------------------
   Pedido: que se sientan tarjetas sin convertirse en botones. Por eso lleva
   lo que dice «esto responde» y NADA de lo que dice «esto se pulsa»: se
   levanta y se enciende, pero no hay cursor de mano, ni flecha, ni enlace.
   Dentro no hay nada enfocable, así que tampoco hay estado de teclado que
   inventar: el que no usa ratón no se pierde ninguna información, porque el
   señalado no informa de nada que no esté ya escrito.

   El mismo gesto que las tarjetas de sede y las del selector —6 px de subida,
   filo celeste y halo— para que una tarjeta se comporte igual en todo el
   sitio. */
@media (hover: hover) and (pointer: fine) {
  .respalda-item {
    transition: transform 400ms var(--sal), border-color 300ms ease, box-shadow 400ms var(--sal);
  }
  .respalda-item:hover {
    transform: translateY(-6px);
    border-color: rgba(0, 159, 227, .45);
    box-shadow: var(--sombra-media), var(--brillo-cian);
  }
  /* Y el sello recupera su color de verdad. Es el detalle que hace que el
     señalado signifique algo en vez de solo moverse: en reposo los sellos van
     monocromos para que la fila se lea como un bloque, y al mirar uno aparece
     el sello REAL, que es lo que respalda. */
  .respalda-sello img { transition: filter 320ms ease; }
  .respalda-item:hover .respalda-sello img { filter: none; }
}
@media (prefers-reduced-motion: reduce) {
  .respalda-item { transition-duration: 1ms; }
  .respalda-item:hover { transform: none; }
}
