/* =============================================================================
   CHAT.CSS — el widget de Sofía

   No introduce un sistema visual nuevo: se ciñe a los dieciséis tokens que
   define main.css y a las convenciones que ya usa components.css.

   Dos consecuencias de esa paleta que explican decisiones de aquí:

   - No hay token de superficie elevada, y --paper (#F4F4F4) y --paper-2
     (#F2F2F2) se separan un 0,8 % de luminancia: apilarlas no se ve. Igual que
     components.css, lo que flota —burbujas, tarjetas, fichas— va en blanco y el
     hilo baja a --paper-2.
   - No hay una variante oscura del acento. --clay sobre fondo claro da 2,98:1,
     que no cumple AA para texto pequeño; main ya lo usa así en .eyebrow, así
     que se sigue esa convención para rótulos decorativos, pero lo que hay que
     leer o pulsar —enlaces del mensaje, acciones de un aviso— va en --ink.

   Capas: el header del sitio está en z-index 60 y el modal de ficha en 1000.
   El widget se pone en medio (900): tapa la página, pero la ficha de una
   propiedad abierta desde el chat lo tapa a él.
============================================================================= */

/* El widget oculta el panel y la barra de envío con el atributo `hidden`, y las
   dos son `display:flex`. Una regla de autor le gana a la del navegador para
   [hidden], así que sin esto seguirían viéndose. */
.sofia [hidden] { display: none }

.sofia {
  position: fixed;
  right: clamp(16px, 3vw, 28px);
  bottom: clamp(16px, 3vw, 28px);
  z-index: 900;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 12px;
}

/* --- Lanzador ------------------------------------------------------------- */
.sofia-launcher {
  display: inline-flex;
  align-items: center;
  gap: .55rem;
  padding: .5rem 1.3rem .5rem .5rem;
  border-radius: 999px;
  background: var(--ink);
  color: var(--paper);
  font-family: var(--body);
  font-size: .88rem;
  font-weight: 600;
  letter-spacing: .02em;
  /* Sombra más presente que la de una tarjeta: tiene que despegarse de la
     página, no fundirse con ella. */
  box-shadow: 0 6px 18px rgba(33,30,27,.16), 0 16px 40px -14px rgba(33,30,27,.28);
  transition: transform .4s var(--ease), background .35s, opacity .25s, box-shadow .35s;
}
.sofia-launcher-avatar {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  object-fit: cover;
  background: var(--clay);
  flex-shrink: 0;
}

/* Mientras la invitación está en pantalla, el lanzador respira para que el ojo
   los relacione. Se para en cuanto se descarta. */
.sofia-launcher.llama { animation: sofia-latido 2.6s ease-in-out infinite }
@keyframes sofia-latido {
  0%, 100% { box-shadow: 0 6px 18px rgba(33,30,27,.16), 0 16px 40px -14px rgba(33,30,27,.28), 0 0 0 0 var(--clay-soft) }
  50%      { box-shadow: 0 6px 18px rgba(33,30,27,.16), 0 16px 40px -14px rgba(33,30,27,.28), 0 0 0 14px transparent }
}

/* --- Invitación ----------------------------------------------------------- */
.sofia-invitacion {
  position: relative;
  max-width: 300px;
  padding: .85rem 2rem .85rem 1rem;
  border-radius: 16px 16px 4px 16px;
  background: var(--paper);
  border: 1px solid var(--line);
  box-shadow: 0 6px 18px rgba(33,30,27,.14), 0 16px 40px -16px rgba(33,30,27,.26);
  opacity: 0;
  transform: translateY(10px) scale(.97);
  transform-origin: bottom right;
  transition: opacity .3s var(--ease), transform .3s var(--ease);
}
.sofia-invitacion.visible { opacity: 1; transform: none }
.sofia-invitacion-txt {
  margin: 0;
  font-size: .85rem;
  line-height: 1.5;
  color: var(--ink);
  cursor: pointer;
}
.sofia-invitacion-cerrar {
  position: absolute;
  top: .45rem;
  right: .45rem;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  color: var(--muted);
  transition: background .2s, color .2s;
}
.sofia-invitacion-cerrar:hover { background: var(--paper-2); color: var(--ink) }
.sofia-launcher:hover { background: var(--clay); transform: translateY(-2px) }
.sofia-launcher.oculto {
  opacity: 0;
  pointer-events: none;
  transform: translateY(8px) scale(.96);
}

/* --- Panel ---------------------------------------------------------------- */
.sofia-panel {
  display: flex;
  flex-direction: column;
  /* Más ancho y más alto: las tarjetas de propiedad con foto no respiran en
     400px, y en una conversación con fichas se ve muy poco de una vez. */
  width: min(460px, calc(100vw - 32px));
  height: min(720px, calc(100vh - 110px));
  /* El ancho del panel no se negocia: nada de lo que se le ponga al lado puede
     estrecharlo y reajustar el texto de la conversación. */
  flex-shrink: 0;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 18px;
  box-shadow: var(--shadow);
  overflow: hidden;
  opacity: 0;
  transform: translateY(16px) scale(.98);
  transform-origin: bottom right;
  transition: opacity .26s var(--ease), transform .26s var(--ease);
}
.sofia-panel.abierto { opacity: 1; transform: none }

.sofia-head {
  display: flex;
  align-items: center;
  gap: .7rem;
  padding: .9rem 1rem;
  background: var(--ink);
  color: var(--paper);
  flex-shrink: 0;
}
.sofia-retrato-caja { position: relative; flex-shrink: 0; display: block; line-height: 0 }
.sofia-avatar {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  object-fit: cover;
  background: var(--clay);
  border: 2px solid var(--clay);
  flex-shrink: 0;
}
/* En escritorio la cabecera se queda con el círculo: la figura entera está al
   lado, y repetirla en pequeño sería decir dos veces lo mismo. */
.sofia-retrato { display: none }
.sofia-quien { display: flex; flex-direction: column; line-height: 1.25; flex: 1 }
.sofia-quien strong { font-family: var(--display); font-size: 1.05rem; font-weight: 600 }
.sofia-quien small {
  font-family: var(--mono);
  font-size: .6rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--beige);
}
.sofia-cerrar {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  color: var(--beige);
  transition: background .25s, color .25s;
}
.sofia-cerrar:hover { background: rgba(244,244,244,.15); color: var(--paper) }

/* --- Hilo ----------------------------------------------------------------- */
.sofia-hilo {
  flex: 1;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 1.1rem 1rem;
  display: flex;
  flex-direction: column;
  gap: .7rem;
  background: var(--paper-2);
}

.sofia-msg {
  max-width: 86%;
  flex-shrink: 0;        /* mismo motivo que en .sofia-prop */
  padding: .7rem .9rem;
  border-radius: 14px;
  font-size: .87rem;
  line-height: 1.6;
  overflow-wrap: anywhere;
}
.sofia-msg p + p { margin-top: .5rem }
.sofia-msg ul,
.sofia-msg ol { margin: .4rem 0 0; padding-left: 1.1rem }
.sofia-msg li { margin-bottom: .25rem }

/* Un encabezado dentro de una burbuja de chat: una línea de título, no la
   estructura de un documento. Se separa de lo anterior y pesa un poco más,
   nada más. Si fuera un <h3> de verdad competiría en tamaño con el nombre de
   Sofía en la cabecera del panel. */
.sofia-msg .md-titulo {
  font-weight: 600;
  margin-top: .7rem;
  letter-spacing: .01em;
}
.sofia-msg .md-titulo:first-child { margin-top: 0 }

.sofia-msg hr {
  border: 0;
  border-top: 1px solid var(--line-soft);
  margin: .7rem 0;
}

/* El copiloto compara propiedades en tabla y el chat público hereda el mismo
   formateador: sin esto salían las celdas sueltas, sin rejilla. */
.sofia-msg .md-tabla { overflow-x: auto; margin: .5rem 0 0 }
.sofia-msg .md-tabla table { border-collapse: collapse; font-size: .74rem; min-width: 100% }
.sofia-msg .md-tabla th,
.sofia-msg .md-tabla td {
  border: 1px solid var(--line-soft);
  padding: .3rem .45rem;
  text-align: left;
}
.sofia-msg .md-tabla th {
  font-family: var(--mono);
  font-size: .6rem;
  text-transform: uppercase;
  letter-spacing: .05em;
}

.sofia-msg--ella {
  align-self: flex-start;
  background: #fff;
  border: 1px solid var(--line-soft);
  color: var(--ink);
  border-bottom-left-radius: 4px;
}
.sofia-msg--yo {
  align-self: flex-end;
  background: var(--ink);
  color: var(--paper);
  border-bottom-right-radius: 4px;
  white-space: pre-wrap;
}

/* Enlace a una propiedad dentro de un mensaje */
.sofia-ancla,
.sofia-msg a {
  color: var(--ink);
  font: inherit;
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 2px;
  padding: 0;
}
.sofia-ancla:hover, .sofia-msg a:hover { color: var(--clay) }

/* Puntos de "escribiendo" — el ritmo y el rebote vienen del widget anterior
   (.typing/.dot de chat-widget.css). Es lo que hace tolerable una espera de
   quince segundos, así que se conserva tal cual; sólo cambia el color, que
   pasa del #bfa38a suelto al token de la paleta. */
.sofia-escribiendo { display: flex; align-items: center; gap: 5px; padding: .85rem .9rem }
.sofia-escribiendo span {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--clay);
  opacity: .4;
  animation: sofia-rebote 1.4s infinite ease-in-out both;
}
.sofia-escribiendo span:nth-child(2) { animation-delay: .2s }
.sofia-escribiendo span:nth-child(3) { animation-delay: .4s }
@keyframes sofia-rebote {
  0%, 80%, 100% { transform: scale(.6); opacity: .4 }
  40%           { transform: scale(1.1); opacity: 1 }
}

/* --- La figura de Sofía ----------------------------------------------------
   Va abajo, al lado del cuadro de texto, y no se mueve de ahí: así reacciona a
   lo que pasa durante toda la conversación en vez de desaparecer al segundo
   mensaje.

   Las cinco poses van APILADAS y sólo una es visible. Se funden entre ellas en
   vez de saltar, porque son poses distintas y no fotogramas de un movimiento:
   un corte seco se vería como un fallo. */
/* La escena. El panel es el ÚNICO que ocupa sitio; la figura va colgada de él
   en posición absoluta.
   
   Así estaba antes y por eso había que cambiarlo: los dos compartían una fila
   flex, de modo que la figura —450px de ancho— le disputaba el espacio al
   panel. El panel se estrechaba y el texto del chat se reajustaba a un ancho
   menor. Fuera del flujo no puede empujar nada. */
.sofia-escena { position: relative; display: flex; justify-content: flex-end }

/* El hueco sólo aparece con el panel abierto: sin panel al lado no hay altura
   que igualar, y la figura quedaría flotando sola en la esquina. */
.sofia-figura-hueco { display: none }
.sofia-escena.abierta .sofia-figura-hueco {
  display: block;
  position: absolute;
  /* Pegada al borde izquierdo del panel, creciendo hacia la izquierda. */
  right: calc(100% + 10px);
  bottom: 0;
  height: 100%;
  /* Nunca intercepta un clic: por grande que sea, lo que hay debajo se sigue
     pudiendo leer y pulsar. */
  pointer-events: none;
}

.sofia-figura {
  position: relative;
  height: 100%;
  /* El ancho sale de la proporción del lienzo normalizado (424x712), así que
     basta con decir la altura: la del panel. Si se regeneran las poses hay que
     mirar el tamaño real del archivo, no darlo por sabido. */
  aspect-ratio: 424 / 712;
  /* La sombra en el suelo la asienta: sin ella parece recortada y pegada. */
  filter: drop-shadow(0 10px 10px rgba(33,30,27,.18));
  animation: sofia-respira 5s ease-in-out infinite;
}
.sofia-pose {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  opacity: 0;
  transition: opacity .45s ease;
}
.sofia-pose.visible { opacity: 1 }

/* Tres píxeles en cinco segundos. Es lo que separa una figura viva de una
   calcomanía, sin convertirla en un dibujo animado. */
@keyframes sofia-respira {
  0%, 100% { transform: translateY(0) }
  50%      { transform: translateY(-3px) }
}

/* --- Aviso del sitio (no de Sofía) ---------------------------------------
   Otro color y otra forma a propósito: un fallo del servidor no puede leerse
   como algo que dijo una asesora. */
.sofia-aviso {
  align-self: stretch;
  background: var(--beige);
  border: 1px dashed var(--line);
  border-radius: 12px;
  padding: .8rem .9rem;
  font-size: .8rem;
  color: var(--muted);
}
.sofia-aviso-btn {
  margin-top: .6rem;
  font-family: var(--mono);
  font-size: .66rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--ink);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.sofia-aviso-btn:hover { color: var(--clay) }

/* --- Tarjetas de formulario (registro y test) ----------------------------- */
.sofia-tarjeta {
  align-self: stretch;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 1rem;
  box-shadow: 0 1px 2px rgba(33,30,27,.06), 0 2px 8px rgba(33,30,27,.04);
}
.sofia-tarjeta-tit {
  font-family: var(--display);
  font-size: 1.2rem;
  font-weight: 600;
  margin-bottom: .35rem;
}
.sofia-tarjeta-txt { font-size: .82rem; color: var(--muted); margin-bottom: .9rem }

.sofia-campo { display: block; margin-bottom: .8rem }
.sofia-campo-tit {
  display: block;
  font-family: var(--mono);
  font-size: .62rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: .3rem;
}
.sofia-campo input {
  width: 100%;
  padding: .6rem .75rem;
  border: 1px solid var(--line);
  border-radius: 9px;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--body);
  font-size: .87rem;
  transition: border-color .25s;
}
.sofia-campo input:focus { border-color: var(--clay); outline: none }

.sofia-nose {
  margin-top: .35rem;
  font-family: var(--mono);
  font-size: .62rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--muted);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.sofia-nose:hover { color: var(--clay) }
.sofia-nose.activo { color: var(--clay); font-weight: 700 }
.sofia-campo input[readonly] { background: var(--paper-2); color: var(--muted) }

/* Disclaimers: van antes del botón y se leen. */
.sofia-disclaimers {
  margin: .9rem 0;
  padding: .7rem .8rem;
  background: var(--paper-2);
  border-radius: 10px;
  font-size: .74rem;
  line-height: 1.55;
  color: var(--muted);
}
.sofia-disclaimers p + p { margin-top: .45rem }

.sofia-consent { display: flex; flex-direction: column; gap: .55rem; margin-bottom: .5rem }
.sofia-check {
  display: flex;
  align-items: flex-start;
  gap: .55rem;
  font-size: .78rem;
  line-height: 1.5;
  color: var(--muted);
  cursor: pointer;
}
.sofia-check input {
  margin-top: .18rem;
  width: 15px;
  height: 15px;
  accent-color: var(--clay);
  flex-shrink: 0;
}
.sofia-consent-version {
  font-family: var(--mono);
  font-size: .6rem;
  letter-spacing: .1em;
  color: var(--muted);
  margin-bottom: .8rem;
}

.sofia-btn {
  width: 100%;
  margin-top: .5rem;
  padding: .8em 1.2em;
  border-radius: 999px;
  background: var(--ink);
  color: var(--paper);
  font-size: .8rem;
  font-weight: 600;
  letter-spacing: .04em;
  transition: background .3s;
}
.sofia-btn:hover:not(:disabled) { background: var(--clay) }
.sofia-btn:disabled { opacity: .55; cursor: default }

.sofia-error {
  margin-top: .6rem;
  font-size: .76rem;
  color: #9B2C2C;                 /* 6,1:1 sobre --paper */
}

.sofia-hecho {
  align-self: flex-start;
  font-family: var(--mono);
  font-size: .64rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--muted);
}

/* --- Capacidad -----------------------------------------------------------
   Los supuestos y las advertencias de un rango exploratorio van en tamaño de
   lectura, no en letra chica: es lo que impide que el visitante lea el rango
   como una capacidad de compra que nunca declaró. */
.sofia-capacidad {
  align-self: stretch;
  background: #fff;
  border: 1px solid var(--line);
  border-left: 3px solid var(--ink);
  border-radius: 12px;
  padding: .95rem 1rem;
}
.sofia-capacidad.es-exploratoria {
  border-left-color: var(--clay);
  background: var(--clay-soft);
}
.sofia-capacidad-metodo {
  display: block;
  font-family: var(--mono);
  font-size: .6rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--clay);
  margin-bottom: .3rem;
}
.sofia-capacidad-rango {
  font-family: var(--display);
  font-size: 1.4rem;
  font-weight: 600;
  line-height: 1.2;
}
.sofia-capacidad-eng { font-size: .78rem; color: var(--muted); margin-top: .15rem }

.sofia-supuestos, .sofia-advertencias { margin-top: .85rem }
.sofia-supuestos h4, .sofia-advertencias h4 {
  font-family: var(--mono);
  font-size: .6rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: .35rem;
}
.sofia-supuestos ul, .sofia-advertencias ul { padding-left: 1.05rem }
.sofia-supuestos li, .sofia-advertencias li {
  font-size: .81rem;             /* tamaño de lectura, no de nota al pie */
  line-height: 1.55;
  color: var(--muted);
  margin-bottom: .35rem;
}
.sofia-advertencias {
  border-top: 1px solid var(--line);
  padding-top: .75rem;
}
.sofia-advertencias h4 { color: var(--clay) }
.sofia-advertencias li { color: var(--ink) }

/* --- Ficha de propiedad dentro del chat ----------------------------------- */
.sofia-prop {
  align-self: stretch;
  /* `.sofia-hilo` es un flex en columna, y un hijo de flex se encoge por
     defecto cuando el contenido no cabe. Con `overflow: hidden` encima, la
     tarjeta se aplastaba hasta quedar en una línea: la foto cargaba, el
     navegador la recortaba a unos pocos píxeles y parecía que no había imagen.
     Se ve peor cuanto más largo es el mensaje que va encima. */
  flex-shrink: 0;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 14px;
  overflow: hidden;
  box-shadow: 0 1px 2px rgba(33,30,27,.06), 0 2px 8px rgba(33,30,27,.04);
  transition: box-shadow .3s, transform .3s var(--ease);
}
.sofia-prop:hover { box-shadow: 0 4px 12px rgba(33,30,27,.08), 0 12px 32px -12px rgba(33,30,27,.14); transform: translateY(-2px) }
.sofia-prop-foto { height: 168px; border-radius: 0 }
.sofia-prop-cuerpo { padding: .85rem .95rem 1rem }
.sofia-prop-nombre {
  font-family: var(--display);
  font-size: 1.12rem;
  font-weight: 600;
  line-height: 1.25;
}
.sofia-prop-precio {
  font-family: var(--mono);
  font-size: .9rem;
  color: var(--clay);
  margin-top: .25rem;
}
.sofia-prop-datos { font-size: .78rem; color: var(--muted); margin-top: .3rem }
.sofia-prop-eng { font-size: .74rem; color: var(--muted); margin-top: .15rem }

/* Por debajo del precio en peso visual, y a propósito: el precio es la única
   cifra firme de la tarjeta y la mensualidad es un estimado. Sin esto hereda
   el tamaño del cuerpo y acaba pesando más que el precio, que va en .9rem. */
.sofia-prop-mes {
  font-family: var(--mono);
  font-size: .76rem;
  color: var(--muted);
  margin-top: .2rem;
}

/* Un dato estimado por el proveedor no se presenta como confirmado. */
.sofia-prop-tag {
  margin-left: .45rem;
  padding: .15em .5em;
  border-radius: 999px;
  background: var(--clay-soft);
  color: var(--ink);
  font-family: var(--mono);
  font-size: .58rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  vertical-align: .12em;
}
.sofia-prop-falta {
  margin-top: .4rem;
  font-size: .72rem;
  color: var(--muted);
  font-style: italic;
}
.sofia-prop-ver { margin-top: .8rem; width: 100%; justify-content: center; font-size: .76rem }

/* --- Barra de envío ------------------------------------------------------- */
.sofia-envio {
  display: flex;
  align-items: flex-end;
  gap: .5rem;
  padding: .7rem .8rem;
  border-top: 1px solid var(--line);
  background: #fff;
  flex-shrink: 0;
}
.sofia-envio textarea {
  flex: 1;
  resize: none;
  max-height: 120px;
  padding: .6rem .8rem;
  border: 1px solid var(--line);
  border-radius: 18px;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--body);
  font-size: .86rem;
  line-height: 1.5;
  transition: border-color .25s;
}
.sofia-envio textarea:focus { border-color: var(--clay); outline: none }
.sofia-enviar {
  width: 38px;
  height: 38px;
  flex-shrink: 0;
  border-radius: 50%;
  background: var(--ink);
  color: var(--paper);
  display: grid;
  place-items: center;
  transition: background .3s, transform .3s var(--ease);
}
.sofia-enviar:hover:not(:disabled) { background: var(--clay); transform: scale(1.05) }
.sofia-enviar:disabled { opacity: .5; cursor: default }

/* --- Móvil: el panel ocupa la pantalla ------------------------------------
   Con el panel a 460px, la figura a su altura ronda los 450px de ancho: los
   dos juntos piden unos 950px. Por debajo de eso ya no hay un "al lado".

   Medido en el panel de 390x844: la tarjeta de registro ocupa 614 de los 775px
   del hilo, y conversando las fichas desbordan. O sea que dentro tampoco sobra
   sitio... salvo en un momento: mientras se espera la respuesta del backend, el
   hilo está vacío. Ahí se planta ella, y se retira en cuanto hay algo que leer.

   Lo que queda fijo es el retrato de la cabecera, que pasa de círculo a medio
   cuerpo y sí cambia de gesto. */
@media (max-width: 1000px) {
  .sofia { --sofia-cabecera: 116px }

  .sofia-escena.abierta .sofia-figura-hueco { display: none }
  .sofia-escena.abierta:is(.esperando, .retirando) .sofia-figura-hueco {
    display: block;
    /* Ocupa el hilo, nunca la cabecera: se planta debajo de ella. */
    top: var(--sofia-cabecera);
    right: 0;
    left: auto;
    bottom: 0;
    height: auto;
    width: min(460px, calc(100vw - 32px));
    z-index: 1;                       /* por encima del panel, dentro de .sofia */
    animation: sofia-llega .55s var(--ease) both;
  }
  /* Se aparta cuando llega el contenido, en vez de esfumarse en un fotograma. */
  .sofia-escena.abierta.retirando .sofia-figura-hueco {
    animation: sofia-se-aparta .4s var(--ease) both;
  }
  /* `contain` la encaja sola en el hueco que haya, apoyada abajo: no hay que
     calcular anchos ni preocuparse del apaisado. */
  .sofia-escena.abierta:is(.esperando, .retirando) .sofia-figura {
    width: 100%;
    height: 100%;
    aspect-ratio: auto;
  }
  .sofia-escena.abierta:is(.esperando, .retirando) .sofia-pose { object-position: bottom center }

  /* La cabecera lleva medio cuerpo en lugar del círculo. */
  .sofia-head {
    min-height: var(--sofia-cabecera);
    box-sizing: border-box;
    padding: .7rem 1rem;
    gap: .9rem;
  }
  .sofia-retrato-caja {
    width: 92px;
    height: 92px;
    overflow: hidden;
    border-radius: 14px;
    background: rgba(255, 255, 255, .05);
  }
  /* El busto sólo se ve si las poses no cargaron: si estuviera debajo de ellas
     asomaría por las zonas transparentes como un fantasma. */
  .sofia-retrato-caja.con-poses .sofia-avatar { display: none }
  .sofia-avatar { width: 100%; height: 100%; border: 0; border-radius: 14px }

  .sofia-retrato { display: block; position: absolute; inset: 0 }
  .sofia-retrato-pose {
    position: absolute;
    /* Escala 0.2875: enseña del lienzo de 712 los 320 primeros píxeles, que es
       de la coronilla a la cintura. */
    /* Sólo se fija el ancho: el alto lo saca de la proporción del archivo. Dos
       medidas a mano son dos oportunidades de deformarla. */
    width: 122px;
    height: auto;
    /* El reajuste global de main.css pone `img { max-width: 100% }`, y aquí eso
       recortaba el ancho a los 92px de la caja: la achataba un 24,6% sin
       avisar. El recorte lo hace el `overflow` de la caja, no la imagen. */
    max-width: none;
    top: 4px;
    left: var(--dx);
    opacity: 0;
    transition: opacity .45s ease;
  }
  .sofia-retrato-pose.visible { opacity: 1 }
  /* Un desplazamiento por pose, para que la cabeza no baile dentro del recorte.
     Salen de medir el centro de la cabeza en cada archivo (228 a 251 px sobre
     el lienzo de 424) y llevarlo al centro de la caja. */
  .sofia-retrato-pose[data-pose="saludo"]     { --dx: -20px }
  .sofia-retrato-pose[data-pose="escuchando"] { --dx: -25px }
  .sofia-retrato-pose[data-pose="pensando"]   { --dx: -24px }
  .sofia-retrato-pose[data-pose="presenta"]   { --dx: -26px }
  .sofia-retrato-pose[data-pose="reposo"]     { --dx: -24px }
}

/* Pantalla baja —el móvil de lado, sobre todo— la cabecera de medio cuerpo no
   se paga: con el panel en 280px de alto se llevaría el 42%. Vuelve el círculo,
   que dice lo mismo en 40px. */
@media (max-width: 1000px) and (max-height: 560px) {
  .sofia { --sofia-cabecera: 64px }
  .sofia-head { min-height: 0; padding: .9rem 1rem }
  .sofia-retrato { display: none }
  .sofia-retrato-caja { width: 40px; height: 40px; border-radius: 50%; background: none }
  .sofia-retrato-caja.con-poses .sofia-avatar { display: block }
  .sofia-avatar { border: 2px solid var(--clay); border-radius: 50% }
}

/* Entra desde abajo, como si se acercara. */
@keyframes sofia-llega {
  from { opacity: 0; transform: translateY(24px) }
  to   { opacity: 1; transform: none }
}
@keyframes sofia-se-aparta {
  from { opacity: 1; transform: none }
  to   { opacity: 0; transform: translateY(20px) }
}
@keyframes sofia-aparece    { from { opacity: 0 } to { opacity: 1 } }
@keyframes sofia-desaparece { from { opacity: 1 } to { opacity: 0 } }

@media (max-width: 560px) {
  .sofia { right: 12px; bottom: 12px; left: 12px; align-items: stretch }
  /* En móvil se conserva el nombre: un círculo sin texto no dice quién es.
     Sólo se recorta el relleno para que no coma pantalla. */
  .sofia-launcher { align-self: flex-end; padding: .4rem 1rem .4rem .4rem; font-size: .82rem }
  .sofia-launcher-avatar { width: 32px; height: 32px; font-size: 1rem }
  .sofia-invitacion { max-width: none }
  /* Aquí el panel sale del flujo (fixed, a pantalla completa), así que el
     contenedor de la escena se queda sin altura y colgar la figura de él no
     serviría: tiene que ir fija ella también, midiendo contra la pantalla. */
  .sofia-escena.abierta:is(.esperando, .retirando) .sofia-figura-hueco {
    position: fixed;
    left: 0;
    right: 0;
    width: auto;
  }
  .sofia-panel {
    position: fixed;
    inset: 0;
    width: 100%;
    height: 100%;
    max-height: none;
    border: none;
    border-radius: 0;
    transform-origin: bottom center;
  }
  .sofia-msg { max-width: 92% }
}

/* --- La ficha se aparta cuando el chat está abierto -----------------------
   Heredado del widget anterior. Sin esto, en escritorio el modal de propiedad
   queda centrado y el panel del chat le tapa el borde derecho: justo cuando el
   visitante abre una ficha desde la conversación. */
@media (min-width: 1200px) {
  body.chat-open .modal-overlay.active .modal-container { transform: translate(-150px, 0) scale(1) }
}
@media (min-width: 1025px) and (max-width: 1199px) {
  body.chat-open .modal-overlay.active .modal-container { transform: translate(-80px, 0) scale(1) }
}

@media (prefers-reduced-motion: reduce) {
  .sofia-panel, .sofia-launcher, .sofia-prop, .sofia-enviar,
  .sofia-invitacion { transition: none }
  /* Nada de latido ni de entrada animada para quien pidió menos movimiento. */
  .sofia-launcher.llama { animation: none }
  /* La figura se queda quieta: una silueta respirando en bucle es
     exactamente lo que esta preferencia existe para apagar. */
  .sofia-figura { animation: none }
  .sofia-pose { transition: none }
  /* Aparece y se retira sin desplazarse: sólo el desvanecido, que es lo que
     evita que una persona se esfume en un fotograma. */
  .sofia-escena.abierta:is(.esperando, .retirando) .sofia-figura-hueco {
    animation-name: sofia-aparece;
  }
  .sofia-escena.abierta.retirando .sofia-figura-hueco { animation-name: sofia-desaparece }
  .sofia-retrato-pose { transition: none }
  .sofia-invitacion { opacity: 1; transform: none }
  .sofia-escribiendo span { animation: none; opacity: .6 }
}
