/* ==========================================================================
   COMPONENTES
   ========================================================================== */

/* --------------------------------------------------------------------------
   HEADER
   -------------------------------------------------------------------------- */

.sitio-header {
  background: var(--fondo-oscuro);
  color: var(--texto-sobre-oscuro);
}

.sitio-header a {
  color: inherit;
}

/* LAS DOS FILAS DEL HEADER COMPARTEN ANCHO.

   El núcleo tiene width: fit-content, y el menú es la fila más ancha, así que
   es él quien fija ese ancho. La fila de arriba lo ocupa entero.

   Con eso, el ícono de Instagram queda alineado con la I de «Inicio» y el
   extremo derecho del selector de idioma con la g de «Blog», que es lo pedido.
   El logo va en la columna del medio y queda centrado respecto del menú. */
.header-nucleo {
  width: fit-content;
  max-width: calc(100% - var(--e-6));
  margin-inline: auto;
  position: relative;
}

.header-barra {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: var(--e-4);
  padding-block: var(--e-4);
}

.header-barra .marca {
  justify-self: center;
}

.header-instagram {
  display: inline-flex;
  padding: var(--e-2);
  color: rgba(255, 255, 255, 0.75);
  transition: color var(--transicion);
}

.header-instagram:hover,
.header-instagram:focus-visible {
  color: var(--papel);
}

/* ---- El fade al hacer scroll ---------------------------------------------
   Lo enciende assets/js/header.js, que es lo único que necesita JavaScript en
   todo el sitio junto con el parallax. Sin JS, esta clase nunca se aplica y el
   header queda visible: no se pierde navegación. */

/* El header FLOTA sobre el carrusel, no ocupa espacio propio: así, cuando hace
   fade, no deja una franja del color de fondo donde antes estaba la barra. El
   carrusel arranca en el borde superior de la página y el header queda encima.
   En las páginas interiores sí empuja el contenido, con el padding de abajo. */
.sitio-header {
  position: fixed;
  inset-inline: 0;
  top: 0;
  z-index: 50;
  /* Transparencia reducida un 40%: de 0,28 y 0,58 de aire a 0,17 y 0,35. */
  background: linear-gradient(rgb(0 0 0 / 0.83), rgb(0 0 0 / 0.65) 70%, rgb(0 0 0 / 0.25));
  transition: opacity 0.35s ease, translate 0.35s ease;
}

/* EN LAS PÁGINAS INTERIORES EL HEADER OCUPA SU LUGAR, NO FLOTA.

   Antes iba fijo también acá, y a main se le daba un padding-top de 8,5 rem
   calculado a ojo para dejarle el hueco. En el teléfono el header mide más que
   eso, así que el título de la página quedaba tapado por el menú: se veía en
   primera consulta, en contacto y en blog. Con position: sticky el hueco lo
   reserva el navegador con la altura real, y el header se sigue quedando
   pegado arriba al hacer scroll, que era lo que se quería.

   No hay número que mantener, así que no puede volver a desincronizarse
   cuando cambie el tamaño del logo, el cuerpo del menú o la traducción de una
   etiqueta. La portada sigue con el header flotando sobre el carrusel. */
body:not(.con-hero) .sitio-header {
  position: sticky;
}

body:not(.con-hero) main {
  padding-top: var(--e-5);
}

/* Una página interior que abre con una franja oscura a todo el ancho
   (/oralmapp, con heroPropio: true en su front matter) no deja ese aire: la
   franja arranca pegada al header, que es del mismo color, y se leen como una
   sola pieza. El header sigue sticky y opaco como en el resto del interior. */
body.con-hero-propio main {
  padding-top: 0;
}

/* EN LAS PÁGINAS INTERIORES EL HEADER ES OPACO.

   El degradado existe para la portada, donde el header flota sobre el carrusel
   y tiene que dejar ver la foto. En contacto, primera consulta y las demás no
   hay imagen detrás: el degradado sólo dejaba asomar el fondo de la página por
   encima del contenido, y se leía como una franja translúcida sin motivo.

   Acá va el color plano, sin transparencia. */
body:not(.con-hero) .sitio-header {
  background: var(--fondo-oscuro);
}

/* El nav vive dentro del núcleo, que es angosto, pero la línea de separación
   tiene que cruzar toda la pantalla como en el sitio viejo. Se dibuja con un
   pseudo-elemento que se estira más allá del núcleo. */
.nav-principal {
  position: relative;
}

.nav-principal::before {
  content: "";
  position: absolute;
  top: 0;
  left: 50%;
  translate: -50% 0;
  width: 100vw;
  border-top: 1px solid rgba(255, 255, 255, 0.14);
}

.sitio-header--oculto {
  opacity: 0;
  translate: 0 -100%;
  pointer-events: none;
}

/* Si alguien llega con el teclado a un enlace del header escondido, vuelve. */
.sitio-header:focus-within {
  opacity: 1;
  translate: 0;
  pointer-events: auto;
}

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

.marca {
  display: inline-flex;
  align-items: center;
  text-decoration: none;
}

.marca__logo {
  width: auto;
  height: clamp(2.25rem, 1.7rem + 2.2vw, 3.5rem);
}

.header-acciones {
  display: flex;
  align-items: center;
  gap: var(--e-5);
}

/* El header es sticky, así que el ancla #nosotros no puede quedar debajo. */
:target {
  scroll-margin-top: 7rem;
}

/* Navegación principal ----------------------------------------------------- */

.nav-lista {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--e-2) var(--e-6);
  margin: 0;
  padding: var(--e-3) 0;
  list-style: none;
}

.nav-lista a {
  display: inline-block;
  padding-block: var(--e-2);
  font-size: var(--tam-chico);
  letter-spacing: 0.04em;
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: border-color var(--transicion), color var(--transicion);
}

.nav-lista a:hover {
  color: var(--arena);
  border-bottom-color: var(--arena);
}

.nav-lista a[aria-current="page"] {
  color: var(--arena);
  border-bottom-color: var(--arena);
}

/* Selector de idioma ------------------------------------------------------- */
/* Sin JavaScript: tres enlaces. El vigente se marca con aria-current. */

.selector-idioma {
  display: flex;
  align-items: center;
  gap: var(--e-1);
}

.selector-idioma__opcion {
  padding: var(--e-1) var(--e-2);
  font-size: var(--tam-micro);
  font-weight: 500;
  letter-spacing: 0.08em;
  text-decoration: none;
  color: rgba(255, 255, 255, 0.62);
  border-radius: var(--radio);
  transition: color var(--transicion), background-color var(--transicion);
}

.selector-idioma__opcion:hover {
  color: var(--papel);
  background: rgba(255, 255, 255, 0.1);
}

/* El idioma vigente lleva el mismo estilo que el botón AGENDA ONLINE del
   hero: fondo oscuro translúcido, borde claro y texto blanco. Antes era un
   chip arena, que no se parecía a nada más del sitio. */
.selector-idioma__opcion[aria-current="true"] {
  color: var(--papel);
  background: rgb(0 0 0 / 0.55);
  border: 1px solid rgb(255 255 255 / 0.75);
  border-radius: 2rem;
  padding: var(--e-1) var(--e-4);
  backdrop-filter: blur(2px);
}

.selector-idioma__separador {
  color: rgba(255, 255, 255, 0.28);
  font-size: var(--tam-micro);
}

/* ESTE BLOQUE VA AL FINAL, DESPUES DE .marca__logo, .nav-lista y del
   selector de idioma. Con la misma especificidad gana la ultima regla
   declarada: puesto antes, el alto del logo y el cuerpo del menu los
   seguian fijando las reglas base y esto no hacia nada. Mismo tropiezo
   que tuvo .boton--hero contra .boton. */
/* EN PANTALLA ANGOSTA, TODO EN UNA FILA.

   Antes el logo se iba a una fila propia y los dos íconos quedaban debajo. Con
   el menú en dos líneas, el header ocupaba unos 190 px: en un teléfono de 915
   px de alto es más de la quinta parte de la pantalla, sólo para el encabezado.

   Acá va la misma estructura que en escritorio —Instagram, logo, idiomas— pero
   apretada: el núcleo ocupa el ancho completo en vez de ajustarse al menú, el
   logo baja a 2 rem y el aire se reduce. */
@media (max-width: 34rem) {
  .header-nucleo {
    width: 100%;
    max-width: 100%;
    padding-inline: var(--e-4);
  }

  .header-barra {
    grid-template-columns: auto 1fr auto;
    gap: var(--e-2);
    padding-block: var(--e-3);
  }

  .header-instagram {
    padding: var(--e-1);
  }

  .marca__logo {
    height: 2rem;
  }

  /* EL MENU EN DOS FILAS, A PROPOSITO: CUATRO Y TRES.

     Los destinos no entran en una línea de teléfono sin bajar el cuerpo a
     13 px, y ahí los enlaces quedan con menos de 30 px de alto: incómodos de
     tocar. Con flex-wrap, además, el corte lo decidía el ancho de cada
     pantalla: a 412 px quedaba «Blog» solo en la segunda fila, como un error.

     Con grid el reparto es siempre el mismo, en cualquier ancho y en los tres
     idiomas. Se lee como una decisión y no como un desborde.

     Eran seis destinos en 3 y 3. El 11 de octubre de 2026 entró el séptimo,
     OralmAPP, y con tres columnas quedaba 3, 3 y uno solo abajo: eso sí se
     lee como un desborde. Con cuatro columnas queda 4 y 3. La primera fila es
     la más larga en los tres idiomas —«Inicio · Nosotros · Servicios ·
     OralmAPP»— y entra en 360 px con el cuerpo de 14 px; «Primera consulta»,
     el destino más largo, va en la segunda, que tiene más aire.

     Descartado el botón de hamburguesa: son siete destinos, entran a la vista,
     y esconderlos agrega un toque para llegar a cualquier lado y JavaScript
     que hoy no hace falta. Descartado también el desplazamiento lateral, que
     deja «Blog» fuera de la pantalla sin avisar. */
  .nav-lista {
    display: grid;
    grid-template-columns: repeat(4, auto);
    justify-content: center;
    gap: 0 var(--e-4);
    padding: var(--e-1) 0 var(--e-2);
  }

  .nav-lista li {
    text-align: center;
  }

  .nav-lista a {
    font-size: 0.875rem;
    letter-spacing: 0.02em;
    padding-block: var(--e-1);
  }
}

/* --------------------------------------------------------------------------
   SECCIONES
   -------------------------------------------------------------------------- */

.seccion {
  padding-block: var(--ritmo-seccion);
}

.seccion--tibia {
  background: var(--fondo-seccion);
}

.seccion--gris {
  background: var(--gris);
}

.seccion--oscura {
  background: var(--fondo-oscuro);
  color: var(--texto-sobre-oscuro);
}

/* Los enlaces sueltos de una sección oscura van en arena, pero NO los botones:
   un .boton--acento tiene fondo arena, y si además se le pinta el texto de
   arena queda invisible. El :not() evita toda esa familia de errores. */
.seccion--oscura a:not(.boton) {
  color: var(--arena);
}

.seccion__kicker {
  display: block;
  margin-bottom: var(--e-3);
  font-family: var(--fuente-cuerpo);
  font-size: var(--tam-micro);
  font-weight: 600;
  letter-spacing: var(--tracking-etiqueta);
  text-transform: uppercase;
  color: var(--texto-acento);
}

/* Sobre fondo oscuro el acento va en --arena, no en --arena-texto: el token
   oscurecido existe para leerse sobre claro, y acá haría lo contrario. */
.seccion--oscura .seccion__kicker,
.hero .seccion__kicker {
  color: var(--arena);
}

/* El sitio viejo pone los títulos de sección en color arena, no en tinta:
   rgb(192,178,160), que es --marca-arena exacto, a 40px.

   Acá se usa --arena-texto (#76634c) y NO el #C0B2A0 del viejo. Ese tono sobre
   los fondos claros da 1.87:1, y WCAG AA pide 3:1 para texto grande. Es el
   mismo criterio con el que se resolvió el botón de acento: se copia la
   intención de la marca, no el incumplimiento. Ver la excepción documentada en
   tokens.css. */
/* Centrados y en versalitas, como el sitio viejo. El punto decorativo que
   llevaban debajo se quitó por decisión del cliente. */
/* El más oscuro de la paleta de marca: --marca-carbon (#4c4843). Sobre los
   fondos claros da 8,2:1, muy por encima del 3:1 que WCAG AA pide para texto
   grande. Antes era --arena-texto, que es un marrón derivado. */
.seccion__titulo {
  margin-bottom: var(--e-6);
  text-align: center;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  color: var(--marca-carbon);
}



/* El kicker acompaña al título, así que también va centrado. */
.seccion__kicker {
  text-align: center;
}

/* ---- Nosotros en dos columnas -------------------------------------------- */

.nosotros__columnas {
  columns: 2;
  column-gap: var(--e-9);
  column-rule: 1px solid var(--borde);
  margin-top: var(--e-6);
}

.nosotros__columnas p {
  margin: 0 0 var(--e-5);
  /* Sin esto un párrafo se puede partir dejando una línea sola arriba de la
     otra columna. */
  break-inside: avoid;
}

/* En pantalla angosta, una sola columna: dos columnas de 3 líneas cada una no
   se leen. */
@media (max-width: 52rem) {
  .nosotros__columnas {
    columns: 1;
  }
}

/* ---- La cita de cierre ---------------------------------------------------
   Centrada y en itálica, fuera de las columnas, como el sitio viejo. No lleva
   el borde lateral del blockquote general. */

.cita-cierre {
  max-width: 46rem;
  margin: var(--e-8) auto 0;
  padding: 0;
  border: 0;
  text-align: center;
  font-style: italic;
  color: var(--texto-secundario);
}

/* Sobre fondo oscuro, blanco. El carbón de la paleta no se leería, y el arena
   quedaba apagado contra la foto y el fondo oscuro. */
.seccion--oscura .seccion__titulo {
  color: var(--papel);
}

.seccion__intro {
  max-width: var(--ancho-lectura);
  color: var(--texto-secundario);
}

/* --------------------------------------------------------------------------
   HERO — carrusel de 7, sin JavaScript

   La pista es un contenedor con scroll horizontal y scroll-snap. Cada slide
   ocupa el 100% del ancho y lleva sus propias flechas, que son anclas al slide
   anterior y al siguiente; el primero y el último cierran el círculo.

   Sin JS: no hay autoplay ni puntos de posición. Con el teclado, las flechas
   son enlaces y entran en el orden de tabulación como cualquier otro.
   -------------------------------------------------------------------------- */

.hero {
  position: relative;
  background: var(--fondo-oscuro);
  overflow: hidden;
  /* Sin margen arriba: el carrusel arranca en el borde de la página y el
     header flota encima. */
  margin-top: 0;
}

.hero__pista {
  display: flex;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  /* Sin barra visible: la navegación son las flechas. Se sigue pudiendo
     arrastrar con el dedo, que es como se usa en teléfono. */
  scrollbar-width: none;
}

.hero__pista::-webkit-scrollbar {
  display: none;
}

.hero__slide {
  position: relative;
  flex: 0 0 100%;
  scroll-snap-align: center;
  /* Sin esto, el ancla del navegador desplaza también la página vertical. */
  scroll-margin: 0;
}

.hero__imagen {
  width: 100%;
  /* ALTO COMPLETO DE LA VENTANA, a propósito.

     Antes era min(78vh, 40rem): en una ventana de 735 px daba 573, y los 162
     px que sobraban dejaban ver el blanco de la sección siguiente debajo del
     carrusel. Con el header flotando encima, ese blanco aparecía y desaparecía
     al hacer scroll junto con el fade, que es la franja reportada.

     Con el alto completo, el carrusel llega hasta el borde inferior de la
     ventana y el header queda encima de la imagen en todo momento.

     svh y no vh: en el teléfono, vh mide la ventana SIN la barra del navegador,
     así que el hero queda más alto que lo visible y empuja el contenido. svh es
     el alto chico, el que de verdad se ve. El vh de arriba es el respaldo para
     los navegadores que no entienden svh. */
  height: 100vh;
  height: 100svh;
  object-fit: cover;
  object-position: 50% 40%;
  display: block;
}

/* Quien pidió menos movimiento no recibe el desplazamiento suave. */
@media (prefers-reduced-motion: reduce) {
  .hero__pista {
    scroll-behavior: auto;
  }
}

/* ---- Las flechas ---------------------------------------------------------- */

.hero__flecha {
  position: absolute;
  top: 50%;
  translate: 0 -50%;
  display: grid;
  place-items: center;
  width: 3rem;
  height: 3rem;
  font-size: 2.5rem;
  line-height: 1;
  text-decoration: none;
  color: var(--papel);
  /* Sombra en vez de fondo: sobre una foto clara el blanco puro desaparece,
     y un fondo sólido taparía la imagen, que es lo que se quiere mostrar. */
  text-shadow: 0 1px 6px rgb(0 0 0 / 0.55);
  opacity: 0.85;
  transition: opacity var(--transicion);
}

.hero__flecha:hover,
.hero__flecha:focus-visible {
  opacity: 1;
}

.hero__flecha--ant {
  left: var(--e-3);
}

.hero__flecha--sig {
  right: var(--e-3);
}

/* En pantallas angostas el botón ocupa el ancho y las flechas se achican, para
   no comerse la foto. */
@media (max-width: 40rem) {
  /* EN PANTALLA ANGOSTA sube por encima del botón del chat, que abajo ocupa
     todo el ancho útil. Ancho completo menos los márgenes, como estaba, pero
     despegado del piso: el chat mide unos 3 rem más su separación. */
  .boton--hero {
    left: var(--e-4);
    right: var(--e-4);
    transform: none;
    bottom: calc(var(--e-4) + 4.25rem);
  }

  .hero__flecha {
    width: 2.25rem;
    height: 2.25rem;
    font-size: 2rem;
  }
}

/* --------------------------------------------------------------------------
   BOTONES
   -------------------------------------------------------------------------- */

.boton {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--e-2);
  padding: var(--e-3) var(--e-6);
  min-height: 2.875rem;
  font-family: var(--fuente-cuerpo);
  font-size: var(--tam-chico);
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  text-decoration: none;
  text-align: center;
  border: 1px solid transparent;
  border-radius: var(--radio);
  transition: background-color var(--transicion), color var(--transicion),
    border-color var(--transicion);
}

/* Acento sobre oscuro: 6.09:1. */
.boton--acento {
  background: var(--arena);
  color: var(--tinta);
}

.boton--acento:hover {
  background: var(--papel);
  color: var(--tinta);
}

.boton--primario {
  background: var(--tinta);
  color: var(--papel);
}

.boton--primario:hover {
  background: var(--arena-texto);
  color: var(--papel);
}

.boton--contorno {
  background: transparent;
  border-color: currentColor;
  color: inherit;
}

.boton--contorno:hover {
  background: rgba(255, 255, 255, 0.1);
  color: inherit;
}

/* ---- El botón sobre la imagen del hero -----------------------------------

   Vive fuera de la pista del carrusel, así que queda quieto mientras los
   slides pasan por detrás.

   CENTRADO, Y NO ABAJO A LA DERECHA COMO EL SITIO VIEJO. Ahí es donde vive el
   botón del chat, que es fijo y flota por encima de todo: los dos se pisaban, y
   el globo de saludo tapaba el botón entero. El sitio viejo no tenía chat.

   VA ACÁ, DESPUÉS DE .boton, y no en la sección del hero. Estaba antes y la
   regla general lo pisaba: misma especificidad, gana la que va después en el
   archivo. Por eso salía con esquinas rectas y fondo sólido en vez de la
   píldora con borde fino del original. */

.boton--hero {
  position: absolute;
  /* El translate y no `margin: auto` con left/right en 0: así el ancho lo sigue
     dando el contenido y el botón no se estira a todo el hero. */
  left: 50%;
  transform: translateX(-50%);
  bottom: clamp(var(--e-5), 6vh, var(--e-8));
  z-index: 2;
  background: rgb(0 0 0 / 0.55);
  color: var(--papel);
  border-color: rgb(255 255 255 / 0.75);
  backdrop-filter: blur(2px);
  border-radius: 2rem;
  padding-inline: var(--e-7);
}

.boton--hero:hover,
.boton--hero:focus-visible {
  background: var(--papel);
  color: var(--tinta);
  border-color: var(--papel);
}


.boton--bloque {
  width: 100%;
}

/* --------------------------------------------------------------------------
   GRILLAS Y TARJETAS
   -------------------------------------------------------------------------- */

.grilla {
  display: grid;
  gap: var(--e-6);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr));
}

.tarjeta {
  display: flex;
  flex-direction: column;
  gap: var(--e-3);
  padding: var(--e-6);
  background: var(--papel);
  border: var(--borde-acento);
  border-radius: var(--radio-grande);
  transition: all 0.4s ease-in-out;
}

/* La sombra y la duración salen medidas de las tarjetas de servicio del sitio
   viejo. Ver docs/relevamiento-visual.md §6. */
.tarjeta:hover {
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.6);
}

/* --------------------------------------------------------------------------
   SECCIÓN CON FOTO DE FONDO, Y TARJETAS DE VIDRIO ENCIMA

   Réplica del sitio viejo. El fondo es un <img> recortado por el contenedor,
   no un background-image: ver partials/fondo-parallax.njk.
   -------------------------------------------------------------------------- */

.seccion--foto {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  background: var(--fondo-oscuro);
}

.fondo-foto {
  position: absolute;
  inset: 0;
  z-index: -1;
}

/* EL <picture> TIENE QUE TENER ALTO DEFINIDO.

   Acá estaba el bug del parallax. El <img> llevaba height: 160%, pero su
   contenedor es el <picture>, que tenía alto automático. Un porcentaje contra
   un alto indefinido se resuelve como 'auto', así que la imagen quedaba en su
   alto natural, sin ningún margen para desplazarse: el parallax movía la
   imagen exactamente lo mismo que se movía la sección y no se percibía nada.

   Con el picture en absoluto e inset: 0, el alto queda definido y el 120% del
   img se resuelve de verdad. */
.fondo-foto picture {
  position: absolute;
  inset: 0;
  display: block;
}

.fondo-foto__img {
  position: absolute;
  left: 0;
  width: 100%;
  /* 120% con -10% arriba: la imagen sobresale un 10% por arriba y otro 10% por
     abajo, y ése es todo el margen que el parallax necesita para desplazarse.

     No más que eso a propósito: la caja de la franja tiene la proporción de la
     foto para que se vea entera, y cada punto de sobreancho vuelve a recortarla.
     120% es el equilibrio entre que el efecto se note y que la cara se vea
     completa. */
  top: -10%;
  height: 120%;
  object-fit: cover;
  will-change: transform;
}

/* Un velo oscuro entre la foto y el contenido. Sin esto el texto blanco choca
   con las zonas claras de la foto y deja de leerse. */
.seccion--foto::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: rgb(0 0 0 / 0.62);
}

.seccion__sobre-foto,
.seccion--foto .seccion__titulo,
.seccion--foto .seccion__kicker,
.seccion--foto .seccion__intro {
  color: var(--texto-sobre-oscuro);
}

.seccion--foto .seccion__titulo,
.seccion--foto .seccion__kicker {
  color: var(--papel);
}

/* Dos columnas, como el viejo, no tres. */
.grilla--dos {
  grid-template-columns: repeat(auto-fit, minmax(min(24rem, 100%), 1fr));
}

/* ---- La tarjeta de vidrio ------------------------------------------------ */

.tarjeta--vidrio {
  position: relative;
  background: rgb(20 18 16 / 0.34);
  border: 1px solid rgb(255 255 255 / 0.28);
  backdrop-filter: blur(3px);
  color: var(--texto-sobre-oscuro);
}

.tarjeta--vidrio .tarjeta__titulo,
.tarjeta--vidrio .tarjeta__texto {
  color: var(--papel);
  transition: transform 0.4s ease-in-out, color 0.4s ease-in-out,
    left 0.4s ease-in-out;
}

/* EL TÍTULO SE CENTRA CON UNA TRANSICIÓN, y eso no se puede hacer con
   text-align: esa propiedad no interpola, salta de golpe.

   Se mueve con POSICIÓN RELATIVA, no con margen. Es la diferencia entre que la
   página se recomponga o no:

   · con margin-left: 50%, al título le queda la mitad del ancho disponible, y
     uno largo como «Medicina Estética – No quirúrgica» pasa a dos líneas. Eso
     cambia el alto de la tarjeta, el de la fila y el de la sección, y el
     parallax recalcula contra esa altura nueva. Se veía como un salto de zoom
     en la foto de fondo al pasar de una tarjeta a la de al lado.

   · left es un desplazamiento de posición relativa: no toca el ancho usado ni
     el flujo, así que el texto envuelve igual en reposo y en hover. El alto no
     se mueve, y la foto tampoco.

   left y transform interpolan las dos, así que la animación se conserva. */
.tarjeta--vidrio .tarjeta__titulo {
  position: relative;
  width: fit-content;
  left: 0;
}

/* SIN @media (hover: hover), Y A PROPÓSITO.

   Estas reglas estaban dentro de esa media query para evitar el hover pegajoso
   en táctil. El problema es que un equipo de escritorio con pantalla táctil
   —un portátil común hoy— puede reportar hover: none, y entonces el efecto no
   aparece en ningún lado. Pasó: en el equipo del cliente sólo se veía la
   sombra genérica, que es la única regla que quedaba fuera.

   El intercambio es claro: el hover pegajoso al tocar en un teléfono es un
   detalle cosmético que se corrige tocando otro lado; que el efecto no exista
   en el escritorio del cliente no. Va sin condición. */
.tarjeta--vidrio:hover {
  background: rgb(242 242 242 / 0.97);
  border-color: rgb(242 242 242 / 0.97);
}

/* El título se va al centro de la tarjeta, y en el mismo movimiento pasa de
   blanco a tinta junto con el cuerpo. */
.tarjeta--vidrio:hover .tarjeta__titulo {
  color: var(--tinta);
  left: 50%;
  transform: translateX(-50%) translateY(-2px);
}

.tarjeta--vidrio:hover .tarjeta__texto {
  color: var(--tinta);
  transform: translateY(-6px);
}

/* En táctil el botón no se puede revelar con hover, y como no lleva a ningún
   lado tampoco hace falta: la tarjeta se ve completa desde el principio. */
@media (prefers-reduced-motion: reduce) {
  .tarjeta--vidrio,
  .tarjeta--vidrio .tarjeta__titulo,
  .tarjeta--vidrio .tarjeta__texto {
    transition: none;
  }

  .fondo-foto__img {
    transform: none !important;
  }
}

/* Quien pidió menos movimiento no lo recibe. */
@media (prefers-reduced-motion: reduce) {
  .tarjeta {
    transition: none;
  }
}

.seccion--tibia .tarjeta {
  background: var(--papel);
}

.tarjeta__titulo {
  margin: 0;
  font-size: var(--tam-h3);
}

.tarjeta__texto {
  margin: 0;
  color: var(--texto-secundario);
  font-size: var(--tam-chico);
}

/* Ficha de persona --------------------------------------------------------- */

/* --------------------------------------------------------------------------
   FICHAS DEL EQUIPO

   Réplica del sitio viejo, medida en docs/relevamiento-visual.md §2:
   foto 372×368 sin radio, y debajo un panel oscuro con el texto en blanco.

   El panel es una capa aparte (.ficha__panel), no el contenedor del texto. En
   el hover se escala verticalmente, y si el texto viviera dentro se estiraría
   con él un 30%. En el sitio viejo son hermanos por el mismo motivo.
   -------------------------------------------------------------------------- */

/* LAS TRES FICHAS, DEL MISMO ALTO.

   La grilla ya las estira a la altura de la mas alta, pero eso solo movia el
   borde de la caja: el panel oscuro seguia terminando donde terminaba su texto,
   asi que los tres cerraban a distinta altura. Betzabeth es la mas larga porque
   su cargo ocupa dos lineas y su bio es mayor.

   Con height: 100% en la ficha y flex: 1 en el bloque de texto, el panel toma
   el alto sobrante y los tres cierran en la misma linea. */
.ficha {
  position: relative;
  height: 100%;
  display: flex;
  flex-direction: column;
  /* El panel crece hacia arriba sobre la foto: sin esto se sale de la ficha. */
  overflow: hidden;
}

.ficha__retrato {
  aspect-ratio: 372 / 368;
  width: 100%;
  object-fit: cover;
  border-radius: 0;
  background: var(--gris);
  display: block;
}

.ficha__texto {
  position: relative;
  /* Toma todo el alto que sobre, para que las tres fichas cierren parejas. */
  flex: 1;
  /* Ajustado contra las capturas del sitio viejo (MIGRACION WEB/153253): el
     panel arranca pegado a la foto, con el nombre cerca del borde superior, y
     deja más aire abajo. Ese aire de abajo es además el margen que el texto
     necesita para subir en el hover sin salirse. */
  padding: var(--e-4) var(--e-5) var(--e-7);
}

.ficha__panel {
  position: absolute;
  inset: 0;
  z-index: 0;
  background: var(--tinta);
  /* Origen abajo, no al centro: así el scaleY crece SÓLO hacia arriba, sobre la
     foto, y el borde inferior de la ficha no se mueve. Ver la nota del hover. */
  transform-origin: bottom;
}

.ficha__nombre,
.ficha__rol,
.ficha__bio {
  position: relative;
  z-index: 1;
  margin: 0;
  color: var(--texto-sobre-oscuro);
}

/* Los tres tamaños salen medidos del sitio viejo, en px y no en tokens: son
   los valores exactos de la ficha, no los de la escala tipográfica del sitio. */
.ficha__nombre {
  font-size: 23px;
  line-height: 1.2;
}

/* En las capturas el rol va pegado al nombre, casi sin aire, y la bio sí
   arranca separada. */
.ficha__rol {
  margin-top: var(--e-1);
  font-size: 15px;
  line-height: 1.3;
}

.ficha__bio {
  margin-top: var(--e-3);
  font-size: 14px;
  line-height: 19.6px;
}

/* ---- El hover -------------------------------------------------------------

   Los valores salen medidos del sitio viejo, con UNA corrección necesaria.

   El sitio viejo aplica al panel scaleY(1.3) MÁS translateY(+26px), con origen
   al centro. Copiado literal, eso no funciona acá: con origen centro el panel
   crece 0,15 × su altura hacia arriba y el +26px se la come casi entera. Con el
   panel de 206 px que dan nuestras bios, el borde superior sube 4,9 px mientras
   el nombre sube 38: el nombre se escapa del panel y queda en blanco sobre la
   foto. Probado y visto.

   El motivo de la diferencia es que en Wix hay DOS paneles: sus reglas traen
   "opacity: 1; visibility: visible" en el hover, o sea que el que se escala
   está oculto en reposo y aparece encima del otro. Nuestro marcado tiene uno
   solo, y la altura la define el texto, no un valor fijo.

   La corrección conserva el 1.3 medido y descarta el translateY, que sólo
   existía para compensar el origen al centro: con transform-origin: bottom el
   panel crece 0,3 × su altura hacia arriba, entre 57 y 62 px según la ficha, y
   contiene con margen la subida más grande, que es la de la bio (53 px).

   Sólo se aplica donde el hover existe de verdad: en táctil, :hover queda
   pegado después de tocar, y con un panel que crece 30% eso se lee como un
   defecto, no como un efecto.

   En móvil no se pierde nada: el hover no revela contenido. En reposo ya se
   ven el nombre, el rol y la bio; el movimiento es decorativo.
   -------------------------------------------------------------------------- */

/* Mismo criterio que las tarjetas de servicio: sin media query, porque un
   escritorio con pantalla táctil puede reportar hover: none y quedarse sin el
   efecto. Ver la nota de .tarjeta--vidrio:hover. */
.ficha__panel,
.ficha__nombre,
.ficha__rol,
.ficha__bio {
  transition: all 0.4s ease-in-out;
}

/* scaleY(1.3) con origen abajo hace crecer el panel 0,3 × su altura hacia
   arriba: entre 57 y 62 px con las tres bios actuales. Alcanza para contener
   la subida más grande, que es la de la bio (53 px). */
.ficha:hover .ficha__panel {
  transform: scaleY(1.3);
}

.ficha:hover .ficha__nombre {
  transform: translateY(-38px);
}

.ficha:hover .ficha__rol {
  transform: translateY(-41px);
}

.ficha:hover .ficha__bio {
  transform: translateY(-53px);
}

/* Quien pidió menos movimiento no lo recibe. */
@media (prefers-reduced-motion: reduce) {
  .ficha__panel,
  .ficha__nombre,
  .ficha__rol,
  .ficha__bio {
    transition: none;
  }

  .ficha:hover .ficha__panel,
  .ficha:hover .ficha__nombre,
  .ficha:hover .ficha__rol,
  .ficha:hover .ficha__bio {
    transform: none;
  }
}

/* Marcador de imagen todavía no cargada. */
.marcador-imagen {
  display: grid;
  place-items: center;
  aspect-ratio: 1 / 1;
  background: repeating-linear-gradient(
    45deg,
    var(--gris),
    var(--gris) 10px,
    var(--papel-tibio) 10px,
    var(--papel-tibio) 20px
  );
  border: 1px dashed var(--linea);
  border-radius: var(--radio-grande);
  color: var(--texto-secundario);
  font-size: var(--tam-micro);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

/* --------------------------------------------------------------------------
   RESUMEN DE LA CONSULTA — versión corta de la home
   Precio, una línea, y el botón al detalle. Sin formas de pago.
   -------------------------------------------------------------------------- */

.consulta-resumen {
  max-width: var(--ancho-lectura);
  margin-top: var(--e-6);
  padding: var(--e-6) var(--e-7);
  background: var(--papel);
  border: 2px solid var(--arena);
  border-radius: var(--radio-grande);
}

.consulta-resumen__precio {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: var(--e-3);
  margin-bottom: var(--e-4);
}

.consulta-resumen__monto {
  font-family: var(--fuente-titulo);
  font-size: var(--tam-h1);
  line-height: 1;
}

.consulta-resumen__duracion {
  font-size: var(--tam-chico);
  letter-spacing: var(--tracking-etiqueta);
  text-transform: uppercase;
  color: var(--texto-secundario);
}

.consulta-resumen__incluye {
  margin-bottom: var(--e-5);
  color: var(--texto-secundario);
}

.consulta-resumen__accion {
  margin-bottom: 0;
}

/* --------------------------------------------------------------------------
   BLOQUE DE PAGO DE LA PRIMERA CONSULTA — sólo en /primera-consulta

   Diseño pedido por el cliente el 5 de septiembre de 2026 sobre su captura:
   dos tarjetas iguales lado a lado y, debajo, una franja aparte con la
   coordinación del horario.

   Sin colores nuevos. Todo sale de tokens.css: el papel de las tarjetas, la
   línea de los bordes, el arena-texto de las etiquetas, la tinta de los
   títulos y los importes, y el papel-tibio de la franja de abajo.
   -------------------------------------------------------------------------- */

.bloque-pago__kicker {
  margin: 0 0 var(--e-3);
  font-size: var(--tam-micro);
  font-weight: 600;
  letter-spacing: var(--tracking-etiqueta);
  text-transform: uppercase;
  color: var(--texto-acento);
}

.bloque-pago__titulo {
  margin: 0 0 var(--e-4);
  font-size: var(--tam-h2);
}

.bloque-pago__intro {
  max-width: var(--ancho-lectura);
  margin: 0 0 var(--e-7);
}

/* --- Las dos tarjetas ----------------------------------------------------- */

.pagos {
  display: grid;
  gap: var(--e-5);
}

@media (min-width: 52rem) {
  .pagos {
    grid-template-columns: 1fr 1fr;
    align-items: stretch;
  }
}

.pago {
  display: flex;
  flex-direction: column;
  padding: var(--e-6);
  background: var(--papel);
  border: var(--borde-fino);
}

/* La recomendada se distingue por una sola cosa: el filete de arriba. Ni un
   fondo distinto ni un color nuevo, que competirían con el importe. */
.pago--recomendada {
  border-top: 3px solid var(--arena-texto);
}

.pago__etiqueta {
  margin: 0 0 var(--e-3);
  font-size: var(--tam-micro);
  font-weight: 600;
  letter-spacing: var(--tracking-etiqueta);
  text-transform: uppercase;
  color: var(--texto-acento);
}

.pago--alternativa .pago__etiqueta {
  color: var(--texto-secundario);
}

.pago__titulo {
  margin: 0 0 var(--e-3);
  font-size: var(--tam-h3);
  font-weight: 400;
}

.pago__monto {
  margin: 0 0 var(--e-5);
  font-family: var(--fuente-titulo);
  font-size: var(--tam-h2);
  line-height: 1;
}

/* El dato de cada opción —el alias en una, los medios en la otra— separado por
   una línea, para que las dos tarjetas se lean a la misma altura. */
.pago__dato {
  padding-top: var(--e-4);
  border-top: var(--borde-fino);
}

.pago__dato-etiqueta {
  margin: 0 0 var(--e-2);
  font-size: var(--tam-micro);
  font-weight: 600;
  letter-spacing: var(--tracking-etiqueta);
  text-transform: uppercase;
  color: var(--texto-secundario);
}

.pago__dato-valor {
  margin: 0;
}

/* El alias en monoespaciada y seleccionable de un clic: así se copia sin un
   botón que dependa de JavaScript. */
.pago__dato-valor--alias {
  font-family: ui-monospace, "SFMono-Regular", "Cascadia Mono", Menlo, monospace;
  font-size: 1.0625rem;
  letter-spacing: 0.01em;
  user-select: all;
}

/* El botón se pega abajo: con textos de distinto largo, las dos tarjetas
   terminan igual. */
.pago__accion {
  margin-top: auto;
  padding-top: var(--e-3);
}

.pago .pago__accion {
  margin-top: auto;
}

.pago__dato + .pago__accion {
  margin-top: var(--e-6);
}

/* El de contorno hereda el color del texto, y acá el fondo es claro. */
.pago--alternativa .pago__accion {
  color: var(--tinta);
}

/* --- La franja del horario ------------------------------------------------ */

.agenda {
  display: grid;
  gap: var(--e-5);
  margin-top: var(--e-6);
  padding: var(--e-6);
  background: var(--fondo-seccion);
}

@media (min-width: 52rem) {
  .agenda {
    grid-template-columns: 1fr auto;
    align-items: center;
  }
}

.agenda__titulo {
  margin: 0 0 var(--e-2);
  font-size: var(--tam-h3);
  font-weight: 400;
}

.agenda__bajada {
  margin: 0;
  color: var(--texto-secundario);
}

.agenda__acciones {
  display: flex;
  flex-wrap: wrap;
  gap: var(--e-3);
}

.agenda__acciones .boton {
  color: var(--tinta);
}


/* --------------------------------------------------------------------------
   AVISO DE IDIOMA EN LAS PÁGINAS LEGALES
   -------------------------------------------------------------------------- */

.aviso-idioma {
  max-width: var(--ancho-lectura);
  margin-bottom: var(--e-7);
  padding: var(--e-5) var(--e-6);
  background: var(--papel-tibio);
  border-left: 3px solid var(--arena-texto);
  border-radius: 0 var(--radio-grande) var(--radio-grande) 0;
}

.aviso-idioma__titulo {
  margin-bottom: var(--e-3);
  font-size: var(--tam-h3);
}

.aviso-idioma p {
  margin-bottom: var(--e-4);
  font-size: var(--tam-chico);
  color: var(--texto-secundario);
}

.aviso-idioma p:last-child {
  margin-bottom: 0;
}

.aviso-idioma__enlace {
  font-size: var(--tam-chico);
  font-weight: 500;
  color: var(--texto-acento);
}

/* --------------------------------------------------------------------------
   PROSA · páginas legales y artículos
   -------------------------------------------------------------------------- */

.prosa {
  max-width: var(--ancho-lectura);
}

.prosa > * + * {
  margin-top: var(--e-4);
}

/* La linea de cada h2 separa una seccion de la anterior. En el PRIMERO no hay
   nada antes que separar: justo arriba esta el borde del encabezado de la
   pagina, asi que quedaban dos lineas seguidas con un hueco vacio entre ellas.
   El primero va sin linea y sin el aire de separacion. */
.prosa > h2:first-child {
  margin-top: 0;
  padding-top: 0;
  border-top: 0;
}

.prosa h2 {
  margin-top: var(--e-7);
  padding-top: var(--e-5);
  border-top: var(--borde-fino);
  font-size: var(--tam-h3);
}

.prosa h3 {
  margin-top: var(--e-6);
  font-size: var(--tam-base);
  font-weight: 500;
}

.prosa ul,
.prosa ol {
  padding-left: var(--e-5);
}

.prosa li + li {
  margin-top: var(--e-2);
}

.prosa table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--tam-chico);
}

.prosa th,
.prosa td {
  padding: var(--e-3);
  text-align: left;
  border-bottom: var(--borde-fino);
}

.prosa th {
  font-weight: 600;
  color: var(--texto-secundario);
}

/* Cualquier tabla ancha scrollea sola, sin empujar la página. */
.tabla-scroll {
  overflow-x: auto;
}

.fecha-documento {
  margin-bottom: var(--e-6);
  font-size: var(--tam-chico);
  color: var(--texto-secundario);
}

/* --------------------------------------------------------------------------
   ENCABEZADO DE PÁGINA INTERIOR
   -------------------------------------------------------------------------- */

.encabezado-pagina {
  padding-block: var(--e-8) var(--e-6);
  border-bottom: var(--borde-fino);
}

.encabezado-pagina__titulo {
  margin-bottom: 0;
}

.encabezado-pagina__bajada {
  max-width: var(--ancho-lectura);
  margin-top: var(--e-4);
  margin-bottom: 0;
  color: var(--texto-secundario);
}

/* --------------------------------------------------------------------------
   FOOTER
   Sin H2 sueltos: los rótulos de columna son <h2> reales solo cuando
   corresponde, y la navegación va en <nav> + <ul>, como debe ser.
   -------------------------------------------------------------------------- */

/* El pie arranca pegado al bloque de contacto, que es del mismo color: entre
   los dos se acumulaban el padding-bottom de la sección —hasta 112 px— y estos
   64 px de arriba, y como no hay costura visible el conjunto se leía como una
   franja vacía de casi 180 px. Ver también la regla de #contacto más abajo. */
.sitio-footer {
  padding-block: var(--e-5) var(--e-6);
  background: var(--fondo-oscuro);
  color: var(--texto-sobre-oscuro);
  font-size: var(--tam-chico);
}

.sitio-footer a {
  color: rgba(255, 255, 255, 0.82);
}

.sitio-footer a:hover {
  color: var(--arena);
}

.footer-grilla {
  display: grid;
  gap: var(--e-7);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 13rem), 1fr));
}

.footer-columna__titulo {
  margin-bottom: var(--e-4);
  font-family: var(--fuente-cuerpo);
  font-size: var(--tam-micro);
  font-weight: 600;
  letter-spacing: var(--tracking-etiqueta);
  text-transform: uppercase;
  color: var(--arena);
}

.footer-lista {
  margin: 0;
  padding: 0;
  list-style: none;
}

.footer-lista li + li {
  margin-top: var(--e-2);
}

.footer-lista a {
  text-decoration: none;
}

.footer-lista a:hover {
  text-decoration: underline;
}

.footer-datos {
  font-style: normal;
  color: rgba(255, 255, 255, 0.82);
}

.footer-datos p {
  margin-bottom: var(--e-2);
}

.footer-cierre {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--e-4);
  margin-top: var(--e-8);
  padding-top: var(--e-5);
  border-top: 1px solid rgba(255, 255, 255, 0.14);
  font-size: var(--tam-micro);
  color: rgba(255, 255, 255, 0.62);
}

.footer-cierre p {
  margin: 0;
}

.footer-legales {
  display: flex;
  flex-direction: column;
  gap: var(--e-1);
}

/* --------------------------------------------------------------------------
   MARCADOR DE ANDAMIAJE
   Se saca cuando entre el contenido real.
   -------------------------------------------------------------------------- */

.banda-andamiaje {
  padding: var(--e-3) 0;
  background: repeating-linear-gradient(
    45deg,
    #2b2723,
    #2b2723 12px,
    #3a352f 12px,
    #3a352f 24px
  );
  color: var(--arena);
  font-family: ui-monospace, "SFMono-Regular", Menlo, monospace;
  font-size: var(--tam-micro);
  letter-spacing: 0.06em;
  text-align: center;
}

/* --------------------------------------------------------------------------
   TANDA 7 — Contacto en dos columnas, mapa y pie
   -------------------------------------------------------------------------- */

/* Dos columnas con divisoria vertical, como el sitio viejo. */
.contacto__columnas {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--e-9);
  margin-top: var(--e-6);
  text-align: center;
}

.contacto__columnas > * + * {
  border-inline-start: 1px solid rgb(255 255 255 / 0.18);
  padding-inline-start: var(--e-9);
}

@media (max-width: 46rem) {
  .contacto__columnas {
    grid-template-columns: 1fr;
    gap: var(--e-6);
  }

  .contacto__columnas > * + * {
    border-inline-start: 0;
    padding-inline-start: 0;
    border-top: 1px solid rgb(255 255 255 / 0.18);
    padding-top: var(--e-6);
  }
}

/* ---- El mapa -------------------------------------------------------------
   Imagen estática enlazada. Nunca un iframe: ver la nota del marcado. */

.mapa {
  display: block;
  margin-top: var(--e-8);
  text-decoration: none;
  color: inherit;
}

.mapa__marcador {
  aspect-ratio: 2 / 1;
  width: 100%;
  border-radius: var(--radio);
}

.mapa__imagen {
  width: 100%;
  aspect-ratio: 2 / 1;
  object-fit: cover;
  border-radius: var(--radio);
  display: block;
}

.mapa__pie {
  display: block;
  margin-top: var(--e-3);
  text-align: center;
  font-size: var(--tam-chico);
  text-decoration: underline;
  text-underline-offset: 0.25em;
}

/* ---- Divisorias entre las columnas del pie ------------------------------- */

.footer-grilla > * + * {
  border-inline-start: 1px solid var(--borde);
  padding-inline-start: var(--e-6);
}

@media (max-width: 52rem) {
  .footer-grilla > * + * {
    border-inline-start: 0;
    padding-inline-start: 0;
  }
}

.footer-instagram {
  display: inline-flex;
  align-items: center;
  gap: var(--e-2);
}

/* --------------------------------------------------------------------------
   RESUMEN DE LA CONSULTA EN LA PORTADA

   Sin precio y centrada. El número vive en /primera-consulta.
   -------------------------------------------------------------------------- */

.consulta-resumen {
  max-width: 44rem;
  margin: 0 auto;
  padding: var(--e-7) var(--e-6);
  text-align: center;
  background: var(--papel);
  border: var(--borde-acento);
  border-radius: var(--radio-grande);
}

.consulta-resumen__incluye {
  margin: 0 auto;
  max-width: 34rem;
}

.consulta-resumen__accion {
  margin: var(--e-6) 0 0;
}

/* --------------------------------------------------------------------------
   EL MAPA EMBEBIDO

   Ver la nota del marcado en home.njk: suma a Google como tercero y eso está
   declarado en la Política de Privacidad §8.
   -------------------------------------------------------------------------- */

.mapa-embebido {
  margin-top: var(--e-8);
  border-radius: var(--radio);
  overflow: hidden;
  background: var(--gris);
}

.mapa-embebido iframe {
  display: block;
  width: 100%;
  height: clamp(16rem, 34vh, 24rem);
  border: 0;
}

.mapa-embebido__pie {
  display: block;
  margin-top: var(--e-3);
  text-align: center;
  font-size: var(--tam-chico);
}

/* --------------------------------------------------------------------------
   CONTACTO — la disposición marcada por el cliente

   Dos columnas. A la izquierda el título CONTACTO y, debajo, dirección y
   horarios uno al lado del otro. A la derecha, al mismo nivel del título,
   PRIMERA CONSULTA y su tarjeta. El mapa cruza las dos columnas y el botón va
   centrado abajo.

   Se declaran áreas con nombre en vez de contar filas y columnas: así el
   marcado puede reordenarse sin recalcular índices, y en móvil basta con
   reescribir el mapa de áreas.
   -------------------------------------------------------------------------- */

.contacto-grilla {
  display: grid;
  /* Columnas IGUALES. Antes la izquierda era 1,55 veces la derecha, y por eso
     el bloque de datos y la tarjeta de la consulta no se leían como un par:
     empezaban en la misma línea pero ocupaban anchos distintos. */
  grid-template-columns: 1fr 1fr;
  grid-template-areas:
    "titulo      tituloConsulta"
    "datos       consulta"
    "mapa        mapa"
    "pie         pie"
    "accion      accion";
  column-gap: clamp(var(--e-6), 5vw, var(--e-9));
  row-gap: var(--e-5);
  align-items: start;
}

.contacto-grilla__titulo {
  grid-area: titulo;
}

.contacto-grilla__titulo-consulta {
  grid-area: tituloConsulta;
}

.contacto-grilla__datos {
  grid-area: datos;
}

.contacto-grilla__consulta {
  grid-area: consulta;
}

.contacto-grilla__mapa {
  grid-area: mapa;
}

.contacto-grilla__pie {
  grid-area: pie;
}

/* El botón, centrado en todo el ancho de la sección. */
.contacto-grilla__accion {
  grid-area: accion;
  margin: var(--e-4) 0 0;
  text-align: center;
}

/* EL BLOQUE DE DATOS, DEL MISMO TAMAÑO QUE LA TARJETA.

   Toma el mismo relleno que .consulta-resumen y ocupa su columna entera, así
   los dos arrancan en la misma línea, terminan a la misma altura y tienen el
   mismo ancho. Lo pedido: que se lean como un par y no como dos bloques
   sueltos de distinto peso.

   Sin fondo ni borde: la tarjeta de la consulta es blanca porque es la llamada
   a la acción; los datos de contacto son información y van sobre el fondo de
   la sección. La simetría la da la caja, no el color. */
.contacto-grilla__datos {
  height: 100%;
  padding: var(--e-7) var(--e-6);
}

.contacto-grilla .contacto__columnas {
  margin-top: 0;
  /* Los huecos de adentro se achican: dentro de una caja más angosta, el
     separado de 96 px que traían dejaba las dos sub-columnas casi pegadas a
     los bordes. */
  gap: var(--e-6);
}

.contacto-grilla .contacto__columnas > * + * {
  padding-inline-start: var(--e-6);
}

/* La tarjeta de la consulta ocupa su columna entera y pierde el ancho máximo
   que tenía cuando iba centrada y sola. */
.contacto-grilla__consulta {
  height: 100%;
}

.contacto-grilla__consulta .consulta-resumen {
  max-width: none;
  margin: 0;
  height: 100%;
}

/* En pantalla angosta todo se apila en una sola columna, en el orden en que se
   lee: contacto, sus datos, el mapa, después la consulta, y el botón al final. */
@media (max-width: 60rem) {
  .contacto-grilla {
    grid-template-columns: 1fr;
    grid-template-areas:
      "titulo"
      "datos"
      "mapa"
      "pie"
      "tituloConsulta"
      "consulta"
      "accion";
  }
}

/* --------------------------------------------------------------------------
   AJUSTES DE CONTACTO
   -------------------------------------------------------------------------- */

/* El teléfono y cada día de atención no se parten a mitad de línea: un número
   cortado en dos renglones no se lee como número, y un horario partido obliga
   a rearmarlo con la vista. Pueden bajar enteros a la línea siguiente, eso sí. */
.no-cortar {
  white-space: nowrap;
}

/* EL MAPA, A TODO EL ANCHO DE LA PÁGINA.

   Sale del contenedor con la técnica de sangrado completo: 100vw de ancho y un
   margen negativo que lo corre hasta el borde. El calc(50% - 50vw) mide desde
   el centro del contenedor hasta el borde de la ventana, así que funciona sin
   saber cuánto mide el contenedor. */
.contacto-grilla__mapa {
  width: 100vw;
  max-width: 100vw;
  margin-inline: calc(50% - 50vw);
  border-radius: 0;
}

.contacto-grilla__mapa iframe {
  height: clamp(18rem, 42vh, 30rem);
}

/* 100vw incluye la barra de desplazamiento, así que sin esto la sección podría
   provocar scroll horizontal. */
#contacto {
  overflow-x: clip;
}

/* El botón de contacto: fondo blanco y letras en el más oscuro de la paleta. */
.boton--claro {
  background: var(--papel);
  color: var(--marca-carbon);
  border-color: var(--papel);
}

.boton--claro:hover,
.boton--claro:focus-visible {
  background: var(--marca-crema);
  border-color: var(--marca-crema);
  color: var(--marca-carbon);
}

/* La dirección, el email y el teléfono de la sección de contacto van en blanco,
   como el resto del bloque sobre fondo oscuro. --texto-secundario es un gris
   pensado para fondo claro y sobre oscuro queda apagado. */
#contacto .footer-datos,
#contacto .footer-datos a,
#contacto .footer-lista {
  color: var(--papel);
}

.footer-legajo {
  margin: var(--e-5) 0 0;
  font-size: var(--tam-micro);
  color: var(--texto-secundario);
}

/* La sección de contacto cierra el cuerpo de la página y el pie sigue con el
   mismo fondo, así que no necesita el respiro completo de una sección suelta.
   Se recorta el de abajo; el de arriba se mantiene, que ahí sí hay un cambio de
   fondo contra la sección del equipo. */
#contacto {
  padding-bottom: var(--e-6);
}

/* --------------------------------------------------------------------------
   BLOG: TARJETAS DEL LISTADO, FICHA DE AUTOR, VIDEO Y ENTRADAS RECIENTES

   La forma sale de las capturas del blog viejo (INTEGRA/MIGRACION WEB/, 5 de
   septiembre de 2026): portada a la izquierda, y a la derecha el avatar del
   autor con su nombre, la fecha, los minutos de lectura, el título y la
   bajada. No están los contadores de visitas ni el corazón: eran de Wix y no
   tenemos de dónde sacar esos números.
   -------------------------------------------------------------------------- */

.lista-articulos {
  margin: 0;
  padding: 0;
  list-style: none;
}

.tarjeta-articulo {
  display: grid;
  gap: var(--e-5);
  align-items: start;
}

/* Una sola columna en móvil; la portada arriba. A partir de 52rem entra el
   formato del sitio viejo, con la imagen a la izquierda. */
@media (min-width: 52rem) {
  .tarjeta-articulo {
    grid-template-columns: 26rem 1fr;
    gap: var(--e-6);
    align-items: center;
  }
}

.tarjeta-articulo + .tarjeta-articulo {
  margin-top: var(--e-6);
  padding-top: var(--e-6);
  border-top: var(--borde-fino);
}

.tarjeta-articulo__medio {
  display: block;
  overflow: hidden;
}

/* Recorte a 4/3, que es la proporción a la que Wix llevaba las cuatro
   portadas por más que sus originales midieran cosas distintas. */
.portada-articulo {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  background: var(--wix-linea, #e6e2dc);
}

.tarjeta-articulo__titulo {
  margin: 0 0 var(--e-3);
  font-size: var(--tam-h3);
}

.tarjeta-articulo__titulo a {
  text-decoration: none;
}

.tarjeta-articulo__titulo a:hover {
  text-decoration: underline;
}

.tarjeta-articulo__bajada {
  max-width: var(--ancho-lectura);
  margin: 0;
}

/* --- Ficha del autor ------------------------------------------------------ */

.ficha-autor {
  display: flex;
  gap: var(--e-3);
  align-items: center;
  margin: 0 0 var(--e-4);
  font-size: var(--tam-chico);
  color: var(--texto-secundario);
}

.ficha-autor__avatar {
  display: block;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  object-fit: cover;
}

.ficha-autor__texto {
  display: flex;
  flex-direction: column;
  gap: 0.15em;
}

.ficha-autor__nombre {
  color: var(--arena-texto);
}

/* --- Encabezado del artículo ---------------------------------------------- */

.encabezado-articulo {
  padding-top: var(--e-6);
}

.encabezado-articulo__titulo {
  margin: 0;
  font-size: var(--tam-h1);
}

.encabezado-articulo__actualizado {
  margin: var(--e-3) 0 0;
  font-size: var(--tam-chico);
  color: var(--texto-secundario);
}

/* --- Video de portada ------------------------------------------------------

   Va con preload="none" y poster: los dos archivos pesan varios MB y no se
   baja nada hasta que alguien le da al play. */

.video-articulo {
  display: block;
  width: 100%;
  height: auto;
  margin-top: var(--e-6);
  background: #000;
}

.video-articulo__pie {
  margin: var(--e-3) 0 0;
  font-size: var(--tam-chico);
  color: var(--texto-secundario);
}

/* --- Foto dentro del artículo ---------------------------------------------- */

.prosa__figura {
  margin: var(--e-5) 0;
}

.prosa__figura img {
  display: block;
  width: 100%;
  height: auto;
}

/* Flotada a la derecha como en el sitio viejo, y sólo cuando hay ancho para
   que el texto siga leyéndose al lado. */
@media (min-width: 52rem) {
  .prosa__figura--derecha {
    float: right;
    width: 22rem;
    margin: var(--e-2) 0 var(--e-5) var(--e-6);
  }
}

/* --- Entradas recientes ---------------------------------------------------- */

.entradas-recientes {
  display: grid;
  gap: var(--e-5);
  margin: 0;
  padding: 0;
  list-style: none;
  grid-template-columns: 1fr;
}

@media (min-width: 44rem) {
  .entradas-recientes { grid-template-columns: repeat(3, 1fr); }
}

.entrada-reciente__enlace {
  display: block;
  color: inherit;
  text-decoration: none;
}

.entrada-reciente .portada-articulo {
  aspect-ratio: 16 / 9;
}

.entrada-reciente__titulo {
  display: block;
  margin-top: var(--e-3);
  font-size: var(--tam-chico);
}

.entrada-reciente__enlace:hover .entrada-reciente__titulo {
  text-decoration: underline;
}

.volver-blog {
  margin-top: var(--e-7);
}

/* Las paginas interiores no necesitan el respiro completo de una seccion entre
   el encabezado y el cuerpo: el borde del encabezado ya marca el corte. */
body:not(.con-hero) main > .contenedor.seccion:first-of-type {
  padding-top: var(--e-6);
}

/* La foto flotada del artículo tiene que quedar contenida en la prosa: sin
   esto, si el texto de la sección es más corto que la imagen, se derrama sobre
   lo que viene abajo. */
.prosa::after {
  content: "";
  display: block;
  clear: both;
}

/* El pie del artículo —el enlace de volver y las entradas recientes— es un
   solo bloque. Con el ritmo de sección entero en los dos, más el margen del
   enlace, entre el final del texto y «Entradas recientes» quedaba una franja
   vacía de casi 300 px. Sólo se aplica cuando hay entradas recientes debajo:
   si el artículo es el único de su idioma, el cierre conserva su respiro. */
.seccion--cierra-en-recientes {
  padding-bottom: var(--e-5);
}

.seccion--recientes {
  padding-top: 0;
}

.volver-blog {
  margin-top: var(--e-6);
  margin-bottom: 0;
}


/* ---------------------------------------------------------------------------
   EL CHAT DEL SITIO

   El botón es un <a> a WhatsApp que el JavaScript intercepta. Sin JS sigue
   llevando a WhatsApp, así que nada de esto puede dejar un botón muerto.

   El globo de saludo aparece solo con animation-delay: no hay JavaScript
   esperando cuatro segundos, y se cierra con un checkbox y su <label>.
   --------------------------------------------------------------------------- */

.chat-lanzador {
  position: fixed;
  right: var(--e-5);
  bottom: max(var(--e-5), env(safe-area-inset-bottom));
  z-index: 60;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: var(--e-3);
}

.chat-boton {
  display: inline-flex;
  align-items: center;
  gap: var(--e-3);
  padding: var(--e-3) var(--e-5);
  min-height: 3.25rem;
  background: var(--tinta);
  color: var(--papel);
  border-radius: 2rem;
  text-decoration: none;
  font-size: var(--tam-chico);
  letter-spacing: 0.04em;
  box-shadow: 0 6px 20px rgb(0 0 0 / 0.22);
  transition: background var(--transicion);
}

.chat-boton:hover,
.chat-boton:focus-visible {
  background: var(--arena-texto);
  color: var(--papel);
}

.chat-boton--cargando {
  opacity: 0.7;
  pointer-events: none;
}

/* ---- El punto de estado ---------------------------------------------------

   Verde cuando el chat puede contestar, gris cuando no. GRIS ES EL DEFECTO,
   escrito en el HTML: el verde afirma disponibilidad y sin JavaScript no hay
   forma de verificarla. Mejor gris honesto que verde inventado.

   No lleva animacion. Un punto que late dice "en vivo" con mas enfasis del que
   el dato aguanta: se comprobo una vez al abrir la pagina, no es un latido.     */

.chat-boton__punto {
  flex: none;
  width: 0.55rem;
  height: 0.55rem;
  border-radius: 50%;
  background: #9aa0a6;
  /* El halo despega el punto del fondo oscuro del boton sin agregar un borde
     que a 8 px se veria como un anillo. */
  box-shadow: 0 0 0 2px rgb(255 255 255 / 0.18);
}

[data-chat-estado="online"] .chat-boton__punto {
  background: #35c759;
  box-shadow: 0 0 0 2px rgb(53 199 89 / 0.28);
}

/* ---- El globo, sin una línea de JavaScript ---- */

.chat-globo {
  position: relative;
  max-width: 17rem;
  padding: var(--e-4) var(--e-6) var(--e-4) var(--e-4);
  background: var(--papel);
  border: var(--borde-fino);
  border-radius: 0.75rem;
  box-shadow: 0 6px 20px rgb(0 0 0 / 0.14);
  opacity: 0;
  translate: 0 0.5rem;
  animation: chat-globo-entra 0.45s ease 4s forwards;
}

@keyframes chat-globo-entra {
  to {
    opacity: 1;
    translate: 0 0;
  }
}

/* Quien pidió menos movimiento igual ve el globo: aparece sin desplazarse. */
@media (prefers-reduced-motion: reduce) {
  .chat-globo {
    animation: chat-globo-entra 0.01s linear 4s forwards;
    translate: none;
  }
}

.chat-globo__texto {
  margin: 0;
  font-size: var(--tam-chico);
  line-height: 1.5;
}

.chat-globo__cerrar {
  position: absolute;
  top: 0.15rem;
  right: 0.35rem;
  padding: 0.15rem 0.35rem;
  cursor: pointer;
  color: var(--texto-secundario);
  font-size: 1.1rem;
  line-height: 1;
}

/* El checkbox oculto que lo cierra. Sin JavaScript. */
#chat-globo-cerrado:checked ~ .chat-globo {
  display: none;
}

/* ---- El panel ---- */

.chat-panel {
  position: fixed;
  right: var(--e-5);
  bottom: max(var(--e-5), env(safe-area-inset-bottom));
  z-index: 70;
  display: flex;
  flex-direction: column;
  width: 23rem;
  max-width: calc(100vw - var(--e-6));
  height: 34rem;
  max-height: calc(100vh - var(--e-7));
  background: var(--papel);
  border: var(--borde-fino);
  border-radius: 0.75rem;
  box-shadow: 0 12px 40px rgb(0 0 0 / 0.24);
  overflow: hidden;
}

/* En el teléfono ocupa la pantalla entera: un panel de 23rem sobre 360 px de
   ancho deja el texto en una columna de doce caracteres. */
@media (max-width: 34rem) {
  .chat-panel {
    inset: 0;
    width: 100%;
    max-width: 100%;
    height: 100%;
    max-height: 100%;
    border: 0;
    border-radius: 0;
  }

  /* Con el panel abierto, el fondo no se desplaza detrás. */
  body.chat-abierto {
    overflow: hidden;
  }

  /* EN ANGOSTO LA ETIQUETA SE QUEDA, y antes no.

     El boton era un circulo de 3.5 rem con el globo de dialogo adentro. Sacado
     el globo, ese circulo quedaria con un punto de 0.55 rem en el medio y nada
     mas: un punto gris sin palabra al lado no significa nada para nadie.

     Con la etiqueta el boton mide unos 150 px de ancho, que en una pantalla de
     390 entra sobrado — y ademas es la unica forma de que el estado se pueda
     leer en el telefono, que es donde entra la mayoria. */
  .chat-boton {
    padding: var(--e-3) var(--e-4);
  }

  .chat-globo {
    max-width: calc(100vw - var(--e-7));
  }
}

.chat-cab {
  display: flex;
  align-items: center;
  gap: var(--e-3);
  padding: var(--e-4) var(--e-4) var(--e-4) var(--e-5);
  background: var(--fondo-oscuro);
  color: var(--texto-sobre-oscuro);
}

.chat-cab__quien {
  display: flex;
  flex-direction: column;
  flex: 1;
  line-height: 1.2;
}


.chat-cab__accion,
.chat-cab__cerrar {
  background: none;
  border: 0;
  color: inherit;
  cursor: pointer;
  font: inherit;
  opacity: 0.75;
}

.chat-cab__accion {
  font-size: var(--tam-micro);
  text-decoration: underline;
}

.chat-cab__cerrar {
  font-size: 1.5rem;
  line-height: 1;
  padding: 0 0.25rem;
}

.chat-cab__accion:hover,
.chat-cab__cerrar:hover {
  opacity: 1;
}

.chat-cuerpo {
  flex: 1;
  overflow-y: auto;
  padding: var(--e-4);
  display: flex;
  flex-direction: column;
  gap: var(--e-3);
}

.chat-msg__texto {
  margin: 0;
  padding: var(--e-3) var(--e-4);
  border-radius: 0.75rem;
  font-size: var(--tam-chico);
  line-height: 1.5;
  white-space: pre-wrap;
}

.chat-msg--sofi .chat-msg__texto {
  background: var(--gris);
  border-bottom-left-radius: 0.2rem;
  margin-right: 15%;
}

.chat-msg--yo .chat-msg__texto {
  background: var(--tinta);
  color: var(--papel);
  border-bottom-right-radius: 0.2rem;
  margin-left: 15%;
}

.chat-msg--escribiendo .chat-msg__texto {
  opacity: 0.6;
  font-style: italic;
}

.chat-salida {
  margin: 0;
  text-align: center;
}

.chat-salida__enlace {
  display: inline-block;
  padding: var(--e-3) var(--e-5);
  background: var(--arena-texto);
  color: var(--papel);
  border-radius: 2rem;
  text-decoration: none;
  font-size: var(--tam-chico);
}


.chat-entrada {
  display: flex;
  gap: var(--e-2);
  padding: var(--e-3);
  border-top: var(--borde-fino);
}

.chat-entrada__campo {
  flex: 1;
  padding: var(--e-3);
  border: var(--borde-fino);
  border-radius: 0.5rem;
  font: inherit;
  font-size: var(--tam-chico);
}

.chat-entrada__enviar {
  padding: var(--e-3) var(--e-5);
  background: var(--tinta);
  color: var(--papel);
  border: 0;
  border-radius: 0.5rem;
  font: inherit;
  font-size: var(--tam-chico);
  cursor: pointer;
}

/* En la portada, el botón «Agenda online» del hero vive abajo a la derecha, en
   el mismo lugar que el lanzador del chat. Se movió el lanzador y no el botón
   del hero: el hero replica el sitio viejo y está aprobado contra capturas; el
   chat es lo nuevo y es lo que tiene que acomodarse.

   Sube lo suficiente para despejar el botón del hero, y se queda ahí también al
   hacer scroll. Es una diferencia de cuatro centímetros entre la portada y el
   resto, y es preferible a taparle a alguien el botón que lleva a reservar. */
body.con-hero .chat-lanzador {
  bottom: calc(max(var(--e-5), env(safe-area-inset-bottom)) + 5rem);
}

@media (max-width: 34rem) {
  /* En el teléfono el botón del hero ocupa casi todo el ancho, así que el
     lanzador tiene que despejarlo por completo. */
  body.con-hero .chat-lanzador {
    bottom: calc(max(var(--e-5), env(safe-area-inset-bottom)) + 4.5rem);
  }
}

/* ==========================================================================
   ORALMAPP — la página del producto (/oralmapp) y su bloque en la portada

   Agregado el 11 de octubre de 2026. Sin colores nuevos para el sitio: todo
   sale de tokens.css. La única excepción, documentada abajo, es la
   ilustración del teléfono, que muestra OTRO producto con su propia paleta.
   ========================================================================== */

/* ---- El bloque de la portada --------------------------------------------- */

.oralmapp-portada__texto {
  max-width: var(--ancho-lectura);
  margin: 0 auto;
  text-align: center;
  color: var(--texto-secundario);
}

.oralmapp-portada__accion {
  margin: var(--e-6) 0 0;
  text-align: center;
}

/* ---- Portada de la página ------------------------------------------------
   Misma receta que la franja de servicios: foto detrás, velo, contenido
   encima. El velo va un poco más cerrado que allá (0,62) porque acá hay un
   H1 grande y un párrafo largo que leer, no cuatro tarjetas de vidrio. */

.oralmapp-hero {
  padding-block: clamp(var(--e-7), 4rem + 3vw, var(--e-10));
}

.oralmapp-hero::before {
  background: rgb(0 0 0 / 0.66);
}

/* EL VELO TIENE QUE QUEDAR ENTRE LA FOTO Y EL TEXTO, Y EN LA RECETA GENERAL
   NO QUEDA: el ::before y .fondo-foto llevan los dos z-index: -1, y con el
   mismo nivel pinta último el que va después en el árbol, que es la foto.
   El velo queda DEBAJO de la foto y no oscurece nada. En la franja de
   servicios no se nota tanto porque esa foto ya es oscura y está aprobada
   contra capturas, así que no se toca allá. Acá la foto de la clínica es
   casi blanca y el H1 no se leería: la foto baja un nivel y el velo queda
   encima, que es lo que el comentario de .seccion--foto::before siempre
   describió. */
.oralmapp-hero .fondo-foto {
  z-index: -2;
}

.oralmapp-hero__grilla {
  display: grid;
  gap: var(--e-8);
  align-items: center;
}

@media (min-width: 52rem) {
  .oralmapp-hero__grilla {
    grid-template-columns: minmax(0, 1.2fr) minmax(0, 0.8fr);
    gap: var(--e-9);
  }
}

/* El kicker general va centrado; acá acompaña a un título alineado a la
   izquierda. Sobre la foto va en arena, como en las franjas oscuras. */
.oralmapp-hero .seccion__kicker {
  margin: 0 0 var(--e-4);
  text-align: left;
  color: var(--arena);
}

.oralmapp-hero__titulo {
  margin: 0 0 var(--e-3);
  font-size: var(--tam-display);
  color: var(--papel);
}

.oralmapp-hero__subtitulo {
  margin: 0 0 var(--e-5);
  font-size: var(--tam-h3);
  line-height: var(--interlinea-titulo);
  color: var(--papel);
}

.oralmapp-hero__bajada {
  max-width: 34rem;
  margin: 0 0 var(--e-6);
  color: rgb(255 255 255 / 0.85);
}

.oralmapp-hero__acciones {
  display: flex;
  flex-wrap: wrap;
  gap: var(--e-3);
}

/* El de contorno hereda el color del texto; sobre la foto es blanco. */
.oralmapp-hero__acciones .boton--contorno {
  color: var(--papel);
}

/* En el teléfono los dos botones no entran en una fila: van uno debajo del
   otro y a todo el ancho, para que no queden de distinto largo. */
@media (max-width: 40rem) {
  .oralmapp-hero__acciones .boton {
    flex: 1 1 100%;
  }
}

.oralmapp-hero__estado {
  display: flex;
  align-items: center;
  gap: var(--e-2);
  margin: var(--e-5) 0 0;
  font-size: var(--tam-micro);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: rgb(255 255 255 / 0.72);
}

.oralmapp-hero__punto {
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background: var(--arena);
  box-shadow: 0 0 0 3px rgb(192 178 160 / 0.25);
}

.oralmapp-hero__visual {
  display: flex;
  justify-content: center;
}

/* ---- Las secciones de la página ------------------------------------------ */

/* El intro general es de ancho de lectura y alineado a la izquierda; acá
   acompaña a títulos centrados, así que se centra con ellos. */
.oralmapp-intro {
  margin: 0 auto var(--e-7);
  text-align: center;
}

.oralmapp-grilla {
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Sobre fondo blanco la tarjeta general es blanca con borde arena; se le da
   el tibio para que se despegue del fondo sin un color nuevo. */
.oralmapp-tarjeta {
  background: var(--fondo-seccion);
  border-color: transparent;
}

.oralmapp-tarjeta .tarjeta__texto {
  color: var(--texto);
}

/* ---- Los dos productos --------------------------------------------------- */

.oralmapp-productos {
  display: grid;
  gap: var(--e-5);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr));
  margin: 0;
  padding: 0;
  list-style: none;
}

.oralmapp-producto {
  padding: var(--e-6);
  background: var(--papel);
  border: var(--borde-fino);
}

/* El primero en salir se distingue por el filete de arriba, igual que la
   forma de pago recomendada en /primera-consulta. */
.oralmapp-producto--destacado {
  border-top: 3px solid var(--arena-texto);
}

.oralmapp-producto__estado {
  margin: 0 0 var(--e-3);
  font-size: var(--tam-micro);
  font-weight: 600;
  letter-spacing: var(--tracking-etiqueta);
  text-transform: uppercase;
  color: var(--texto-secundario);
}

.oralmapp-producto--destacado .oralmapp-producto__estado {
  color: var(--texto-acento);
}

.oralmapp-producto__titulo {
  margin: 0 0 var(--e-5);
  font-size: var(--tam-h3);
}

.oralmapp-producto__filas {
  margin: 0;
}

.oralmapp-producto__fila + .oralmapp-producto__fila {
  margin-top: var(--e-4);
  padding-top: var(--e-4);
  border-top: var(--borde-fino);
}

.oralmapp-producto__fila dt {
  margin: 0 0 var(--e-1);
  font-size: var(--tam-micro);
  font-weight: 600;
  letter-spacing: var(--tracking-etiqueta);
  text-transform: uppercase;
  color: var(--texto-secundario);
}

.oralmapp-producto__fila dd {
  margin: 0;
  font-size: var(--tam-chico);
}

/* ---- Cómo funciona: los cuatro pasos ------------------------------------- */

.oralmapp-pasos {
  display: grid;
  gap: var(--e-6) var(--e-7);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr));
  margin: var(--e-7) 0 0;
  padding: 0;
  list-style: none;
}

.oralmapp-paso__numero {
  display: block;
  margin-bottom: var(--e-3);
  font-family: var(--fuente-titulo);
  font-size: var(--tam-h1);
  line-height: 1;
  color: var(--arena);
}

.oralmapp-paso__titulo {
  margin: 0 0 var(--e-3);
  font-size: var(--tam-h3);
  color: var(--papel);
}

.oralmapp-paso__texto {
  margin: 0;
  font-size: var(--tam-chico);
  color: rgb(255 255 255 / 0.82);
}

/* ---- Datos --------------------------------------------------------------- */

.oralmapp-datos {
  display: grid;
  gap: var(--e-6);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr));
  margin: 0;
  padding: 0;
  list-style: none;
}

.oralmapp-dato {
  padding-top: var(--e-4);
  border-top: 2px solid var(--arena);
}

.oralmapp-dato__titulo {
  margin: 0 0 var(--e-2);
  font-size: var(--tam-h3);
}

.oralmapp-dato__texto {
  margin: 0;
  font-size: var(--tam-chico);
  color: var(--texto-secundario);
}

/* ---- Para clínicas y lanzamiento: texto centrado ------------------------- */

.oralmapp-clinicas__texto,
.oralmapp-lanzamiento__texto {
  max-width: var(--ancho-lectura);
  margin: 0 auto;
  text-align: center;
}

.oralmapp-clinicas__texto {
  color: var(--texto-secundario);
}

.oralmapp-clinicas__accion {
  margin: var(--e-6) 0 0;
  text-align: center;
}

.oralmapp-lanzamiento__texto {
  color: rgb(255 255 255 / 0.85);
}

/* El lanzamiento y el pie son del mismo color y no hay costura: mismo
   criterio que #contacto en la portada, menos aire abajo para que no se lea
   como una franja vacía. */
.oralmapp-lanzamiento {
  padding-bottom: var(--e-7);
}

/* ---- El formulario de lanzamiento ----------------------------------------
   Sin JavaScript. Los avisos de gracias y de error viven siempre en el HTML
   y se muestran por :target, según el ancla con la que vuelve la función
   (ver la nota en layouts/oralmapp.njk). */

.oralmapp-form {
  max-width: var(--ancho-angosto);
  margin: var(--e-6) auto 0;
}

.oralmapp-form__etiqueta {
  display: block;
  margin-bottom: var(--e-2);
  font-size: var(--tam-micro);
  font-weight: 600;
  letter-spacing: var(--tracking-etiqueta);
  text-transform: uppercase;
  color: var(--arena);
}

.oralmapp-form__fila {
  display: flex;
  flex-wrap: wrap;
  gap: var(--e-3);
}

.oralmapp-form__campo {
  flex: 1 1 14rem;
  min-width: 0;
  padding: var(--e-3) var(--e-4);
  min-height: 2.875rem;
  background: var(--papel);
  color: var(--tinta);
  border: 1px solid var(--papel);
  border-radius: var(--radio);
  font-size: var(--tam-base);
}

.oralmapp-form__campo::placeholder {
  color: var(--texto-secundario);
}

.oralmapp-form__campo:focus-visible {
  outline-color: var(--arena);
}

/* El botón va como campo de formulario: sin el aire extra del enlace. */
.oralmapp-form .boton {
  border: 1px solid var(--arena);
  cursor: pointer;
}

.oralmapp-form__consentimiento {
  margin: var(--e-4) 0 0;
  font-size: var(--tam-micro);
  color: rgb(255 255 255 / 0.62);
}

.oralmapp-form__consentimiento a {
  color: rgb(255 255 255 / 0.82);
}

/* La trampa para robots: fuera de la vista y fuera del orden de tabulación,
   pero NO display: none, que algunos robots también respetan. */
.oralmapp-form__trampa {
  position: absolute;
  left: -200vw;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.oralmapp-aviso {
  display: none;
  max-width: var(--ancho-angosto);
  margin: var(--e-6) auto 0;
  padding: var(--e-5) var(--e-6);
  border: 1px solid rgb(255 255 255 / 0.28);
  border-left: 3px solid var(--arena);
}

.oralmapp-aviso:target {
  display: block;
}

/* Con el de gracias a la vista, el formulario ya cumplió: se esconde. El de
   error deja el formulario para reintentar. */
#gracias:target ~ .oralmapp-form {
  display: none;
}

.oralmapp-aviso--error {
  border-left-color: var(--alerta-borde);
}

.oralmapp-aviso__titulo {
  margin: 0 0 var(--e-2);
  font-size: var(--tam-h3);
  color: var(--papel);
}

.oralmapp-aviso__texto {
  margin: 0;
  color: rgb(255 255 255 / 0.85);
}

.oralmapp-aviso__texto a {
  color: var(--arena);
}


/* ---- Estado: hoy y próximo, en dos columnas ------------------------------ */

.oralmapp-estado {
  display: grid;
  gap: var(--e-7);
  max-width: 56rem;
  margin: 0 auto;
}

/* La divisoria es un pseudo-elemento centrado, no un borde de la segunda
   columna: con borde más padding la columna derecha quedaba más angosta que
   la izquierda y las dos listas no se leían a la par. */
@media (min-width: 46rem) {
  .oralmapp-estado {
    position: relative;
    grid-template-columns: 1fr 1fr;
    gap: var(--e-9);
  }

  .oralmapp-estado::before {
    content: "";
    position: absolute;
    top: 0;
    bottom: 0;
    left: 50%;
    border-left: var(--borde-fino);
  }
}

.oralmapp-estado__titulo {
  margin: 0 0 var(--e-4);
  font-family: var(--fuente-cuerpo);
  font-size: var(--tam-micro);
  font-weight: 600;
  letter-spacing: var(--tracking-etiqueta);
  text-transform: uppercase;
  color: var(--texto-acento);
}

.oralmapp-estado__lista {
  margin: 0;
  padding-left: var(--e-5);
}

.oralmapp-estado__lista li + li {
  margin-top: var(--e-3);
}

/* ---- La autora ----------------------------------------------------------- */

.oralmapp-autora {
  display: grid;
  gap: var(--e-6);
  max-width: 56rem;
  margin: 0 auto;
  align-items: center;
}

@media (min-width: 52rem) {
  .oralmapp-autora {
    grid-template-columns: minmax(0, 18rem) 1fr;
    gap: var(--e-8);
  }
}

.oralmapp-autora__foto {
  width: min(100%, 16rem);
  margin: 0 auto;
}

@media (min-width: 52rem) {
  .oralmapp-autora__foto {
    width: 100%;
  }
}

/* Mismo recorte que la ficha del equipo: sin radio, la marca es angulosa. */
.oralmapp-autora__retrato {
  aspect-ratio: 372 / 368;
  width: 100%;
  object-fit: cover;
  background: var(--gris);
}

.oralmapp-autora__nombre {
  margin: 0 0 var(--e-1);
  font-size: var(--tam-h3);
}

.oralmapp-autora__rol {
  margin: 0 0 var(--e-4);
  font-size: var(--tam-micro);
  font-weight: 600;
  letter-spacing: var(--tracking-etiqueta);
  text-transform: uppercase;
  color: var(--texto-acento);
}

.oralmapp-autora__equipo {
  margin: var(--e-4) 0 0;
  font-size: var(--tam-chico);
  color: var(--texto-secundario);
}

/* --------------------------------------------------------------------------
   LA ILUSTRACIÓN DEL TELÉFONO

   Dibuja una Lectura Oral Sistémica, la pantalla de resultado de OralmAPP,
   con HTML y CSS. Es una ilustración, no una captura: cuando haya capturas
   reales, partials/oralmapp-mock.njk se reemplaza por un <picture> y este
   bloque entero se borra.

   ÚNICA EXCEPCIÓN A «NINGÚN COLOR A MANO» DE tokens.css, Y POR QUÉ.
   Lo que se ve adentro del teléfono es OTRO producto con su propia paleta:
   la app sigue el manual de marca de Biozone (azul náutico #30475E, crema
   #F6F1E9, beluga #3D3935). Pintarla con los tokens del sitio sería mostrar
   una app que no existe. Es el mismo criterio que una foto de producto: la
   foto no cambia de color para combinar con la página. Los tres de perfil
   —verde, ámbar, rojo— están elegidos para leerse sobre el crema (AA).
   Por lo mismo va en la sans del sistema y no en Larken: la app no usa la
   tipografía del sitio, y el contraste ayuda a que se lea como un objeto
   distinto, no como un recuadro de la página.

   Estas variables viven SÓLO dentro de .app-mock. Nada del sitio las usa.
   -------------------------------------------------------------------------- */

.app-mock {
  --app-tinta: #3d3935;
  --app-tinta-suave: #6f6963;
  --app-papel: #f6f1e9;
  --app-azul: #30475e;
  --app-linea: #e2dbd1;
  --app-pista: #e9e3da;
  --app-verde: #3e7a5a;
  --app-ambar: #8a5a12;
  --app-ambar-fondo: #f3e6cf;
  --app-rojo: #a63f33;
  --app-rojo-fondo: #f6e4e1;

  width: min(100%, 19rem);
  padding: 0.55rem;
  background: #16130f;
  border-radius: 2.4rem;
  box-shadow:
    0 30px 60px rgb(0 0 0 / 0.45),
    inset 0 0 0 1px rgb(255 255 255 / 0.14);
  color: var(--app-tinta);
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  font-size: 0.78rem;
  line-height: 1.35;
  text-align: left;
}

.app-mock__pantalla {
  display: flex;
  flex-direction: column;
  gap: 0.65rem;
  padding: 1.35rem 1rem 1rem;
  background: var(--app-papel);
  border-radius: 1.9rem;
}

.app-mock__barra {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding-bottom: 0.5rem;
  border-bottom: 1px solid var(--app-linea);
}

.app-mock__marca {
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--app-azul);
}

.app-mock__mos {
  padding: 0.1rem 0.45rem;
  border: 1px solid var(--app-azul);
  border-radius: 999px;
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  color: var(--app-azul);
}

.app-mock__titulo {
  margin: 0.2rem 0 0;
  font-size: 0.92rem;
  font-weight: 600;
}

.app-mock__puntaje {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.25rem 0.4rem;
}

.app-mock__total {
  font-size: 2.6rem;
  font-weight: 700;
  line-height: 1;
  color: var(--app-azul);
}

.app-mock__escala {
  font-size: 0.78rem;
  color: var(--app-tinta-suave);
}

.app-mock__perfil {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  width: 100%;
  margin-top: 0.3rem;
  padding: 0.25rem 0.6rem;
  background: var(--app-ambar-fondo);
  border-radius: 999px;
  font-size: 0.7rem;
  font-weight: 600;
  color: var(--app-ambar);
}

.app-mock__perfil-punto {
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background: var(--app-ambar);
}

.app-mock__rotulo {
  margin: 0.25rem 0 -0.25rem;
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--app-tinta-suave);
}

.app-mock__bloques {
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.app-mock__bloque {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 0.2rem 0.5rem;
  font-size: 0.7rem;
}

.app-mock__bloque-valor {
  font-variant-numeric: tabular-nums;
  color: var(--app-tinta-suave);
}

.app-mock__bloque-pista {
  grid-column: 1 / -1;
  height: 0.38rem;
  background: var(--app-pista);
  border-radius: 999px;
  overflow: hidden;
}

.app-mock__bloque-relleno {
  display: block;
  height: 100%;
  background: var(--app-azul);
  border-radius: 999px;
}

/* El bloque en carga alta (6 o más sobre 9) se pinta de ámbar: es lo que en
   la app dispara pasos adicionales del protocolo. */
.app-mock__bloque--alto .app-mock__bloque-relleno {
  background: var(--app-ambar);
}

.app-mock__bloque--alto .app-mock__bloque-valor {
  font-weight: 700;
  color: var(--app-ambar);
}

.app-mock__alerta {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  padding: 0.5rem 0.65rem;
  background: var(--app-rojo-fondo);
  border-left: 3px solid var(--app-rojo);
  border-radius: 0 0.4rem 0.4rem 0;
  font-size: 0.68rem;
}

.app-mock__alerta-etiqueta {
  font-size: 0.6rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--app-rojo);
}

.app-mock__boton {
  display: block;
  margin-top: 0.2rem;
  padding: 0.6rem;
  background: var(--app-azul);
  border-radius: 0.5rem;
  text-align: center;
  font-size: 0.76rem;
  font-weight: 600;
  color: var(--app-papel);
}

.app-mock__aviso {
  margin: 0;
  font-size: 0.6rem;
  text-align: center;
  color: var(--app-tinta-suave);
}
