/* ==========================================================================
   LeadSync - Burbuja de mensaje
   La burbuja y lo que va dentro: autor, hora, adjunto y la tarjeta de ubicacion.

   OJO CON EL ORDEN: estos ficheros se enlazan en index.html en un orden concreto y
   ese orden ES la cascada. Mover un enlace de sitio cambia que regla gana entre dos
   de la misma especificidad. Si anades uno nuevo, ponlo donde le toque, no al final.
   ========================================================================== */

/* --- Mensajes --- */
.messages {
  flex: 1;
  overflow-y: auto;
  padding: 20px 8%;
  display: flex;
  flex-direction: column;
  gap: 8px;
  background: var(--chat-bg);
}

/* El globo conserva espacio solo mientras el modelo trabaja; el cierre muestra adónde se fue. */
.bot-thinking {
  /* CAUSA REAL del globo cortado (medido con la consola de una operadora): #messages es una
     columna flex con scroll y un hijo con overflow:hidden puede encogerse hasta 0 cuando el
     historial es largo; el globo medía 56 px y su contenedor 2. No debe encogerse nunca. */
  flex: 0 0 auto;
  align-self: flex-start;
  padding-bottom: 2px; /* deja sitio al borde inferior y a las esquinas redondeadas */
  max-height: 0;
  opacity: 0;
  overflow: hidden;
  transform: translateY(6px);
  transition: max-height .18s ease, opacity .18s ease, transform .18s ease;
  pointer-events: none;
}
.bot-thinking.active {
  /* 64px recortaba el borde de abajo del globo con la fuente grande del sistema; el tope solo
     existe para poder animar la altura, así que se deja holgado. */
  max-height: 160px;
  opacity: 1;
  transform: none;
}
.bot-thinking-bubble {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 10px 14px;
  border-radius: 14px 14px 14px 4px;
  background: var(--bg-elev);
  border: 1px solid var(--border);
  color: var(--text-dim);
  font-size: 13px;
}
.bot-thinking-quien { margin-right: 5px; }
/* Una compañera escribiendo: en el LADO DE SU GLOBO, la derecha del equipo, con la forma y el
   color de un mensaje del equipo y su nombre en su tono. El del bot sigue a la izquierda; si
   escriben los dos a la vez se ven los dos, cada uno en su fila. */
.bot-thinking.humano { align-self: flex-end; }
.bot-thinking.humano .bot-thinking-bubble {
  background: var(--operator);
  border-radius: 14px 14px 4px 14px;
  /* El texto del globo del equipo: el atenuado sobre el verde oscuro del tema oscuro no se lee. */
  color: var(--text);
}
.bot-thinking.humano[class*="autor-av-"] .bot-thinking-quien {
  color: color-mix(in srgb, var(--av-tono, var(--text)) 55%, var(--text));
  font-weight: 600;
}
.bot-thinking.training .bot-thinking-bubble {
  color: var(--modo-entrenamiento);
  border-color: var(--modo-entrenamiento);
  background: var(--modo-entrenamiento-bg);
}
.bot-thinking-dots { display: inline-flex; gap: 3px; align-items: center; height: 10px; }
.bot-thinking-dots i {
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: currentColor;
  animation: botThinkingPulse 1s ease-in-out infinite;
}
.bot-thinking-dots i:nth-child(2) { animation-delay: .16s; }
.bot-thinking-dots i:nth-child(3) { animation-delay: .32s; }
@keyframes botThinkingPulse {
  0%, 70%, 100% { opacity: .4; transform: translateY(0); }
  35% { opacity: 1; transform: translateY(-3px); }
}
@media (prefers-reduced-motion: reduce) {
  .bot-thinking { transition: none; }
  .bot-thinking-dots i { animation: none; opacity: .8; }
}

/* Fila de mensaje: ocupa todo el ancho para que el menú/responder/pulsación larga
   funcionen en el espacio horizontal completo, no solo sobre la burbuja (item 34). */

/* item 38: touch-action pan-y deja el arrastre vertical al navegador (es el scroll del
   chat) y nos entrega el horizontal, que es el gesto de responder. position:relative por
   el icono que asoma al arrastrar. */
.msg-row {
  display: flex;
  width: 100%;
  gap: 8px;
  touch-action: pan-y;
  position: relative;
}

/* La flecha aparece a la izquierda según se arrastra y se enciende al llegar al límite:
   así se sabe cuándo soltar sin tener que adivinar. */
.msg-row::before {
  content: "↩";
  position: absolute;
  left: 6px;
  top: 50%;
  transform: translateY(-50%);
  color: var(--text-dim);
  font-size: 17px;
  line-height: 1;
  opacity: 0;
  transition: opacity .12s ease, color .12s ease;
  pointer-events: none;
}
.msg-row.swiping::before { opacity: .45; }
.msg-row.swipe-reply::before {
  opacity: 1;
  color: var(--accent);
}
.msg-row.client,
.msg-row.bot,
.msg-row.system {
  justify-content: flex-start;
}
.msg-row.operator { justify-content: flex-end; }

/* Adjunto saliente que aún se está subiendo: la burbuja ya se ve con el archivo y su
   relojito, y el archivo lleva encima un spinner mientras dura la subida (item 46). */
.bubble-media.pending-media { position: relative; }
.media-uploading {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, .35);
  border-radius: inherit;
}

/* Botón de reenviar junto a la burbuja de un adjunto, fuera de ella (item 42).
   Va centrado con la burbuja, como en WhatsApp (fa_25.png). */
.msg-forward-btn {
  flex: 0 0 auto;
  align-self: center;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: var(--bg-elev);
  border: 1px solid var(--border);
  color: var(--text-dim);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: background-color .15s ease, color .15s ease;
}
.msg-forward-btn:hover {
  background: var(--bg-hover);
  color: var(--text);
}
.msg-forward-btn .ic {
  width: 15px;
  height: 15px;
}

/* En los salientes el botón va a la IZQUIERDA de la burbuja (su lado libre). Se hace
   con order y NO con flex-direction:row-reverse: row-reverse invierte también el eje
   principal, así que justify-content:flex-end empujaba TODA la fila a la izquierda y
   los mensajes propios dejaban de salir a la derecha (regresión de la Fase 58). */
.msg-row.operator .msg-forward-btn { order: -1; }

/* En modo selección el clic debe seleccionar el mensaje, no reenviarlo. */
.messages.selecting .msg-forward-btn { display: none; }
/* El encabezado y el pie de un mensaje con opciones o plantilla. WhatsApp los pinta dentro del globo:
   el encabezado en negrita arriba y el pie en gris pequeño debajo del texto. */
.bubble-enc {
  display: block;
  font-weight: 700;
  margin-bottom: 3px;
}
.bubble-pie {
  display: block;
  margin-top: 3px;
  font-size: 12px;
  color: var(--text-dim);
}

.bubble {
  max-width: 68%;
  padding: 8px 12px;
  border-radius: 10px;
  position: relative;
  word-wrap: break-word;
  white-space: pre-wrap;
  line-height: 1.4;
}
.bubble .meta {
  display: block;
  font-size: 10px;
  color: var(--text-dim);
  margin-top: 4px;
  text-align: right;
}
.bubble .author {
  display: block;
  font-size: 11px;
  font-weight: 600;
  margin-bottom: 2px;
}

/* Multimedia entrante (item 2): marcador de descarga, media renderizada, lightbox. */
.bubble-media {
  margin: 2px 0 6px;
  border-radius: 8px;
  overflow: hidden;
}
.bubble-media.placeholder,
.bubble-media.loading,
.bubble-media.error {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 40px;
  padding: 8px 10px;
  background: rgba(0, 0, 0, .16);
  border-radius: 8px;
}
.bubble-media .media-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  text-align: left;
  background: none;
  border: none;
  color: inherit;
  cursor: pointer;
  font: inherit;
  padding: 0;
}
.bubble-media .media-kind {
  font-size: 12.5px;
  font-weight: 600;
}
.bubble-media .media-hint {
  margin-left: auto;
  display: inline-flex;
  opacity: .8;
}
.bubble-media .ic {
  width: 18px;
  height: 18px;
  flex: 0 0 auto;
}
.bubble-media.error { color: var(--text-dim); }

/* --- Tarjeta de contacto compartida por el cliente (item B114) ------------ */

/* Como WhatsApp: la inicial en un círculo y los datos al lado. Mismo tope de ancho que la
   ubicación y las fotos, para que una burbuja no crezca con un correo largo. */
.bubble-contacto {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin: 2px 0 6px;
  padding: 8px 10px;
  max-width: 260px;
  box-sizing: border-box;
  background: rgba(0, 0, 0, .16);
  border-radius: 8px;
}
.bubble-contacto + .bubble-contacto { margin-top: 0; }
.ctc-avatar {
  flex: 0 0 auto;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  background: var(--bg-hover);
  color: var(--text);
}
.ctc-datos {
  display: flex;
  flex-direction: column;
  min-width: 0;
  gap: 1px;
}
.ctc-nombre { font-size: 13.5px; font-weight: 600; line-height: 1.3; overflow-wrap: anywhere; }
.ctc-empresa { font-size: 11.5px; opacity: .75; }
.ctc-dato { font-size: 12.5px; overflow-wrap: anywhere; user-select: text; }
.ctc-wa { font-size: 10px; font-weight: 600; color: var(--accent); margin-left: 2px; }

/* --- Ubicación compartida por el cliente ---------------------------------- */

/* Es un enlace y se comporta como tal: al pulsarlo se abre el mapa real fuera. El
   dibujo de dentro es de adorno (ver locationHTML en media.js: pedir la miniatura a un
   servidor de mapas le contaría a un tercero dónde vive cada cliente del negocio). */
.bubble-loc {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 2px 0 6px;
  padding: 8px 10px;

  /* EL TOPE ES LO QUE HACE QUE LOS PUNTOS SUSPENSIVOS SIRVAN. Sin él, un flex se
     dimensiona por su contenido: una dirección larga ensanchaba la burbuja de 253 a
     495 px y recortaba DESPUÉS de haber crecido. Mismo ancho que .media-img, para que
     una foto y una ubicación no den dos anchos distintos de burbuja. */
  max-width: 260px;
  box-sizing: border-box;
  background: rgba(0, 0, 0, .16);
  border-radius: 8px;
  color: inherit;
  text-decoration: none;

  /* Micro-estado: 120 ms, dentro del rango de hover/check. */
  transition: background-color .12s ease, transform .12s ease;
}
.bubble-loc:hover,
.bubble-loc:focus-visible {
  background: rgba(0, 0, 0, .26);
}
.bubble-loc:active { transform: scale(.985); }
.bubble-loc .loc-mapa {
  display: inline-flex;
  flex: 0 0 auto;
  border-radius: 6px;
  overflow: hidden;
}

/* min-width:0 es obligatorio: sin él un hijo flex no baja de su contenido y el
   text-overflow no llega a aplicarse nunca. */
.bubble-loc .loc-datos {
  display: flex;
  flex-direction: column;
  min-width: 0;
  flex: 1 1 auto;
  gap: 1px;
}

/* Una dirección larga no puede ensanchar la burbuja: se corta con puntos suspensivos. */
.bubble-loc .loc-titulo {
  font-size: 13px;
  font-weight: 600;
  line-height: 1.25;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.bubble-loc .loc-sub {
  font-size: 11.5px;
  opacity: .75;
  line-height: 1.25;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
@media (prefers-reduced-motion: reduce) {
  .bubble-loc { transition: none; }
  .bubble-loc:active { transform: none; }
}

/* --- Sugerencia del bot (modo asistencia, item Q2) --------------------------- */
/* --- Mensajes con opciones dentro del chat (NO_REPETIR 35) -------------------

   EL CHAT ES UN ESPEJO DEL DE WHATSAPP. Si al cliente le llegó con botones, aquí se ve con
   botones; si no, quien lee la consola cree que el envío falló y lo manda otra vez — que es
   exactamente lo que pasó el 14-09.

   Los botones los dibuja el MISMO componente que la vista previa (`opcionesDeInteractivo`,
   clases `.wa-prev-*`), así que aquí solo se recolocan: van pegados al borde de la burbuja,
   debajo de la hora, que es donde los pinta WhatsApp. El margen negativo cancela el
   `padding: 8px 12px` de la burbuja para que ocupen todo su ancho. */
/* La columna que comparte el globo con sus botones. Toma el ancho maximo de la burbuja y
   se lo cede a los dos, para que los botones midan lo mismo que el globo. */
.msg-col {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  max-width: 68%;
  min-width: 0;
}
.msg-col .bubble { max-width: 100%; }
.msg-opciones { margin-top: 2px; }
.msg-opciones .wa-prev-btn {
  /* Tiene cursor de mano porque SÍ hace algo: dice qué es ese botón. Lo que no hace es
     mandarlo — eso lo pulsa el cliente en su teléfono. */
  cursor: pointer;
  background: var(--bg-panel);
  border-radius: 8px;
  transition: background-color .12s ease;
}
.msg-opciones .wa-prev-btn:hover,
.msg-opciones .wa-prev-fila:hover { background: var(--bg-hover); }
.msg-opciones .wa-prev-fila { cursor: pointer; }

/* LA ACCION DEL GLOBO (enlace, lista, formulario) SE PULSA, ASI QUE LO PARECE — pero SOLO EN
   EL CHAT, y por eso la regla vive aqui y no junto al resto de su estilo.

   En la consola no manda a ninguna parte -quien lo pulsa es el cliente, en su telefono- pero
   si HACE algo: dice a donde lleva, y en una lista abre sus opciones. En la PREVIA del editor
   no hace nada, y ahi un cursor de mano prometeria algo que no pasa. Es la misma distincion
   que ya tiene `.wa-prev-btn` dos lineas mas arriba. */
.bubble .wa-cta {
  cursor: pointer;
  /* LAS ESQUINAS DE ABAJO SE REDONDEAN COMO EL GLOBO. El bloque llega a los bordes -lleva
     margenes negativos para que la linea cruce entero-, asi que al pintarle un fondo sus
     esquinas CUADRADAS asomaban por fuera del globo, que es redondo. El globo no puede llevar
     `overflow: hidden` -se comeria la cola y las reacciones-, asi que se redondea el que
     sobresale. Lo vio el, ampliando la captura. */
  border-radius: 0 0 10px 10px;
  transition: background-color 120ms ease;
}

/* EL HOVER SALE DEL PROPIO COLOR DEL BOTON, no de un gris fijo. Con `--bg-hover` se pintaba
   un rectangulo GRIS encima de un globo VERDE: se veia como una mancha pegada. Tinendo con
   `currentColor` -que aqui es el verde del boton- el resaltado pertenece al globo, y funciona
   igual en los dos temas y sobre cualquier color de burbuja, la del cliente y la nuestra. */
.bubble .wa-cta:hover { background: color-mix(in srgb, currentColor 10%, transparent); }
/* La lista NO se despliega en WhatsApp: se abre en un panel aparte al pulsar el botón. El
   borde punteado lo recuerda sin prometer que el cliente las ve de golpe.

   LLEVA FONDO, COMO EL BOTÓN DE ARRIBA (item B47). Estuvo transparente, y la intención era
   la de la línea anterior — pero lo que transmite "esto no se despliega" es el BORDE
   PUNTEADO, no la falta de fondo. Sin él, el botón de arriba se ve como una tarjeta y la
   lista justo debajo como un agujero en el chat: parece que falta de pintar.

   Él lo reportó antes de grabar un vídeo para los operadores, y con razón: en una pieza que
   vas a enseñar como ejemplo, "parece roto" es un problema aunque no lo esté. */
.msg-opciones .wa-prev-filas { background: var(--bg-panel); }

/* NO ES UNA BURBUJA, y esa distinción es todo el punto: una burbuja dice "esto se dijo", y
   aquí no se ha dicho nada todavía. Por eso va a lo ancho, con borde PUNTEADO (la
   convención de "provisional") y su etiqueta encima. Si se pareciera a un mensaje enviado,
   el operador acabaría creyendo que el cliente ya tiene respuesta. */
.sugerencia {
  align-self: stretch;
  margin: 6px 0 2px;
  padding: 10px 12px;
  border: 1px dashed color-mix(in srgb, var(--accent) 55%, transparent);
  border-radius: 10px;
  background: color-mix(in srgb, var(--accent) 7%, transparent);
  display: flex;
  flex-direction: column;
  gap: 8px;
  /* Entra animada porque APARECE SOLA, sin que nadie pulse nada: el bot la redacta cuando
     llega un mensaje del cliente. Sin movimiento, aparece de la nada mientras lees. */
  animation: sugerenciaEntra 200ms ease;
}
@keyframes sugerenciaEntra {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .sugerencia { animation: none; }
}
.sug-etiqueta {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .02em;
  text-transform: uppercase;
  color: var(--author-bot);
}
.sug-texto {
  font-size: 13.5px;
  line-height: 1.45;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

/* LO QUE EL BOT QUERIA HACER Y NO HIZO (item A2). Va ENCIMA del texto porque es lo que
   cambia la decision: quien lee primero la respuesta y despues descubre que ademas se
   cambia de cola, ya decidio.

   Se ve distinto del texto —fondo propio y el icono— para que no se lea como parte de lo
   que se le va a mandar al cliente: esto no sale, esto se aprueba. */
.sug-accion {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 6px 9px;
  border-radius: 8px;
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  font-size: 12.5px;
  line-height: 1.35;
}
.sug-accion .ic {
  flex: 0 0 auto;
  width: 15px;
  height: 15px;
  color: var(--author-bot);
}
.sug-accion b { font-weight: 600; }
/* EL RAPIDO PROPUESTO NO SE PINTA COMO SU CONTENIDO, y es a proposito: lo que sale al
   pulsar Enviar puede ser un archivo, unos botones o una plantilla, y ensenarlo como texto
   prometeria una cosa y mandaria otra. Se ensena CUAL es —el atajo, que es lo que se
   aprueba— y en una linea que manda; el contenido lo ensena su confirmacion. */
.sug-rapido {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 4px 8px;
}
.sug-rapido-atajo {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 13px;
  font-weight: 700;
  color: var(--accent);
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  border-radius: 6px;
  padding: 2px 7px;
}
.sug-rapido-vista {
  font-size: 12.5px;
  color: var(--text-dim);
  overflow-wrap: anywhere;
}

.sug-acciones {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}
.sug-btn {
  padding: 5px 12px;
  border-radius: 14px;
  border: 1px solid var(--border);
  background: var(--bg-panel);
  color: var(--text);
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
  transition: background-color .12s ease, border-color .12s ease;
}
.sug-btn:hover { background: var(--bg-hover); }
/* ENVIAR ES EL ÚNICO RELLENO. Los tres botones pesan distinto: enviar es lo que se hace
   nueve de cada diez veces, y descartar destruye trabajo. Que se distingan de un vistazo
   es lo que evita el clic equivocado con prisa. */
.sug-btn.sug-enviar {
  background: var(--accent);
  border-color: transparent;
  color: var(--on-accent);
}
.sug-btn.sug-enviar:hover { filter: brightness(1.08); }
.sug-btn.sug-descartar { color: var(--danger); }
.sug-btn.sug-descartar:hover {
  background: color-mix(in srgb, var(--danger) 12%, transparent);
  border-color: color-mix(in srgb, var(--danger) 40%, transparent);
}
/* Mientras se envía, la tarjeta deja de aceptar clics: pulsar "Enviar" dos veces mandaría
   el mismo mensaje dos veces al cliente. */
.sugerencia.sug-enviando {
  opacity: .55;
  pointer-events: none;
}
.media-img {
  display: block;
  max-width: 260px;
  max-height: 320px;
  width: 100%;
  border-radius: 8px;
  cursor: zoom-in;
  object-fit: cover;
}
.bubble-media.kind-sticker .media-img { max-width: 140px; }
.media-video {
  display: block;
  max-width: 280px;
  max-height: 340px;
  border-radius: 8px;
  background: #000;
}

/* --- La ubicacion con el mapa de Google en la burbuja (items A37 y A31b) ----
   NO ES UNA TARJETA: ES UN ADJUNTO CON PIE. WhatsApp pinta el mapa como IMAGEN y debajo el
   nombre y la direccion como texto normal del mensaje. Aqui hubo una caja con su fondo y su
   relleno -corregido el 08-09-, y esa caja es justo lo que hacia que se pareciera a la de
   WhatsApp sin ser la misma. Es el mismo error que ya se habia senalado con el mensaje
   rapido "producto".

   Asi que el enlace del mapa se comporta como `.media-img` -bloque, ancho completo, sin
   fondo- y el pie es `.bubble-text`, la MISMA clase que cualquier texto de burbuja: si
   manana cambia el aspecto del texto, este cambia con el. */
.bubble-loc.con-mapa {
  position: relative;
  display: block;
  width: 100%;
  max-width: none;
  height: 150px;
  margin: 0 0 4px;
  padding: 0;
  border-radius: 8px;
  overflow: hidden;
  background: none;
  /* Sin hover propio: es una imagen del mensaje, y las imagenes no cambian de color al
     pasar por encima. El cursor ya dice que se puede pulsar. */
  transition: none;
}
.bubble-loc.con-mapa:hover,
.bubble-loc.con-mapa:focus-visible { background: none; }
.bubble-loc.con-mapa:active { transform: none; }

.bubble-loc.con-mapa .loc-iframe {
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
}
/* El mapa de Google viene siempre claro. En tema oscuro, un rectangulo blanco en medio del
   chat deslumbra: se le baja un punto el brillo. No es un "modo oscuro" del mapa, es bajar
   el faro. */
:root[data-theme="dark"] .bubble-loc.con-mapa .loc-iframe,
:root:not([data-theme="light"]) .bubble-loc.con-mapa .loc-iframe {
  filter: brightness(.88) contrast(1.04);
}
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) .bubble-loc.con-mapa .loc-iframe { filter: none; }
}

/* EL VELO ES OBLIGATORIO, no es decoracion: un iframe se come la rueda del raton y el
   arrastre. Sin el, bajar por el chat con el cursor encima del mapa hace ZOOM en el mapa, y
   arrastrar para seleccionar texto lo mueve. Con el velo el iframe se ve y no se toca; para
   manejarlo de verdad esta el visor grande, que se abre al pulsar. */
.bubble-loc.con-mapa .loc-velo {
  position: absolute;
  inset: 0;
  display: block;
}

/* El pie: texto del mensaje y nada mas. El nombre es un enlace -lleva a un sitio- y la
   direccion un dato, como se ve en WhatsApp. */
.loc-pie {
  display: block;
}
.loc-nombre {
  color: var(--enlace, var(--accent));
  text-decoration: none;
  font-weight: 500;
}
.loc-nombre:hover { text-decoration: underline; }
.loc-dir {
  display: block;
  color: inherit;
}
