/* Contactos (item V1) — la agenda.
   Se parece A PROPÓSITO a la lista de chats: es la misma clase de objeto (una persona con
   su avatar, su nombre y cuándo se supo de ella), y hacerla distinta obligaría a aprender
   dos lecturas para lo mismo. Lo que cambia es lo que se lee a la derecha: allí es el
   estado de la conversación, aquí es de dónde se sabe de esa persona. */

.ag-intro { margin: 0 0 10px; }

/* LA FILA ES UN <tr>, NO UNA TARJETA, y aqui no lleva NADA de colocacion. Lo tuvo: antes
   del item U3 la agenda era una lista de tarjetas y `.ag-fila` era un `display: flex` con su
   gap y su padding. Al pasar a tabla de verdad, el bloque se quedo atras aplicandose al
   `<tr>`, y un `<tr>` en flex DEJA DE CASAR CON SU `<thead>`: las columnas se descuelgan y
   la cabecera apunta a cualquier sitio (fallo del 07-09).

   Todo lo que necesita la fila —borde, cursor, hover, foco y la animacion de entrada— vive
   con el resto de la tabla, mas abajo, en `.ag-tabla tbody tr`. Aqui no se repite: repetirlo
   es como se llega a dos sitios que dicen cosas distintas del mismo elemento. */

.ag-nombre {
  font-size: 13.5px;
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ag-cuando {
  font-size: 11px;
  color: var(--text-dim);
}
.ag-tags {
  display: flex;
  gap: 4px;
}
.ag-tag {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  padding: 2px 7px;
  border-radius: 10px;
  font-size: 10.5px;
  font-weight: 700;
  white-space: nowrap;
}
.ag-tag svg {
  width: 11px;
  height: 11px;
}
.ag-tag-chat {
  background: var(--accent-dim);
  color: var(--author-bot);
}
.ag-tag-odoo {
  background: var(--bg-hover);
  color: var(--text-dim);
}

/* "Escribir" (item A96) es el único chip que HACE algo nuevo, así que va lleno con el
   verde de la marca y no en el tono suave de "Conversación": uno lleva a un sitio donde ya
   hay algo, el otro empieza un mensaje a un cliente. Que se distingan sin leerlos es lo que
   evita mandarle un "hola" a quien no tocaba. */
.ag-tag-escribir {
  background: var(--accent);
  color: var(--on-accent);
}
.ag-tag-escribir[disabled] { opacity: .55; cursor: default; }
/* "SIN FICHAR" ES EL ÚNICO QUE PIDE ALGO: es un cliente real que el negocio no tiene en su
   agenda. Por eso lleva el color de aviso y los otros dos no — si los tres gritaran, no
   se distinguiría cuál hay que atender. */
.ag-tag-falta {
  background: var(--warn-bg);
  color: var(--warn);
}

/* EN ESTRECHO NO SE REACOMODA LA FILA: la tabla scrollea de lado dentro de su caja
   (.ag-tabla-caja). Aqui hubo un `@media (max-width: 620px)` que le ponia `flex-wrap` a
   `.ag-fila` para bajar las insignias debajo del nombre; con la fila hecha `<tr>` eso volvia
   a descolgar las columnas, asi que se quito con el resto de la maquetacion de tarjeta. */

/* --- LA AGENDA COMO TABLA (item U3) ---------------------------------------
   Era una lista de filas que PARECÍA una tabla: se leía como una, y no tenía ni
   cabeceras, ni columnas alineadas, ni orden, ni paginación. Con casi 3.000 contactos
   eso es un muro por el que solo se puede bajar. */

/* LA AGENDA: SOLO DOS BARRAS DE SCROLL, y esto es la TERCERA vuelta de A31.

   Las dos primeras intentaron REPARTIR el alto de la ventana: primero un `max-height: 62vh`
   en el scrollport, luego una cadena flex desde `.panel-body` con `flex: 1` y un
   `min-height: 420px`. Las dos fallaron por el mismo sitio: para repartir hay que fijar un
   alto en algun eslabon, y en cuanto ese alto no coincide con el contenido salen las dos
   caras del mismo problema — hueco muerto debajo de la tabla, o una barra de scroll de mas.

   La segunda dejo el panel scrolleando POR DENTRO ademas de la tabla, asi que en la misma
   zona habia dos barras verticales anidadas y una tercera fuera. Lo reporto asi:

     "parece que hiciste otro contenedor dentro del contenedor y ahora hay 3 scrollbars [...]
      simplemente que la tabla contactos tenga un max height, el ancho del contenedor, el
      contenedor un ancho maximo fijo [...] pero la altura de ese contenedor sea segun los
      hijos [...] y asi solo hay dos scroll, el mas externo y el de la tabla"

   Tiene razon, y ademas es mas simple: NADIE reparte el alto. El alto lo manda el contenido.

     .app-panel      -> el scroll de fuera, el de la derecha del todo. Ya lo era.
     .panel-body     -> ancho maximo fijo, alto SEGUN SUS HIJOS. No scrollea.
     .ag-tabla-scroll-> ancho del contenedor y un TOPE de alto. Solo scrollea si se pasa.

   Con `max-height` y no `height`, cuatro contactos ocupan cuatro filas -sin hueco muerto- y
   tres mil se quedan en el tope y scrollean dentro. Es lo que se venia buscando desde la
   primera vuelta, sin repartir nada.

   ESTO YA NO ES LO QUE HACE EL CODIGO: queda como historia de por donde se paso. Lo vigente
   es el bloque de la QUINTA vuelta, aqui debajo — la tabla dejo de tener scroll propio. */

/* EL PANEL ES EL UNICO SCROLL, Y LA TABLA SE VE ENTERA (15-09, dictado por el).

   Las cuatro vueltas anteriores intentaban lo mismo por caminos distintos: meter la tabla
   dentro del alto de la ventana. Todas acababan igual —la tabla encogida a cuatro filas, o
   el suelo de ocho desbordando el panel— porque la premisa estaba mal. Su frase:

     "yo te habia pedido explicitamente que contactos abarcara al menos 8 registros, porque
      si lo limitas solo a lo que le quede de la altura del viewport casi no se ve [...] el
      hijo panel body se limita al viewport y no abarca esas 8 filas como altura maxima,
      dejando que el padre se ajuste a ese tamano y asi hay un solo scroll externo, y la
      tabla internamente NO TIENE SCROLL si no que cabe los registros exactamente y se maneja
      con la paginacion y ya"

   O sea, al reves de lo que yo hacia:

     .app-panel   -> el UNICO scroll (ya lo era: overflow-y auto)
     .panel-body  -> NO se limita al viewport: mide lo que mida su contenido
     .ag-lista    -> igual
     .ag-tabla-scroll -> sin alto y SIN SCROLL VERTICAL: las filas se ven enteras

   Y el "no caben" no lo resuelve una barra dentro de la tabla: lo resuelve LA PAGINACION,
   que para eso esta y para eso tiene selector de cuantas por pagina. */
.panel-body[data-seccion="contactos"] {
  /* Ni columna flex ni min-height: 0. Eso era lo que la ataba al alto de la ventana. */
  display: block;
  /* `flex: 0 0 auto` y no `1 1 auto`: dentro del panel, este bloque mide su contenido y no
     se reparte nada. Sin esto vuelve a encogerse hasta el viewport. */
  flex: 0 0 auto;
}

.ag-tabla-caja {
  /* SIN SCROLL VERTICAL Y SIN ALTO: la tabla mide lo que midan sus filas y se ve entera.
     Quien scrollea es el panel, que es el unico que tiene barra.

     EL SCROLL HORIZONTAL SE QUEDA, que es otra cosa: la tabla es ancha y en movil no cabe, y
     lo que no puede pasar es que se mueva de lado la pagina entera.

     OJO CON LA CABECERA PEGAJOSA: `thead th` es `position: sticky` y un sticky se pega a su
     SCROLLPORT MAS CERCANO. Con `overflow-x: auto` esta caja YA es un scroller -aunque el eje
     que interese sea el otro-, asi que la cabecera se pegaria a ella, que no se desplaza en
     vertical, y no haria nada (es el fallo que costo la segunda vuelta de A31). Por eso el
     scroll horizontal se activa SOLO donde hace falta -cuando la tabla no cabe a lo ancho- y
     en escritorio la caja no es scroller: asi la cabecera se pega AL PANEL y los titulos de
     columna siguen ahi despues de bajar veinte filas. */
  overflow: visible;
  border: 1px solid var(--border);
  border-radius: 10px;
}

/* En estrecho manda que la tabla no se salga de la pantalla; ahi se renuncia a la cabecera
   pegajosa, que es lo que menos duele de las dos. */
@media (max-width: 900px) {
  .ag-tabla-caja { overflow-x: auto; }
}
/* LA TABLA ES EL COMPONENTE (components/tabla.css). De aquella definicion propia solo se
   queda lo que de verdad es de la agenda: el `padding: 0` de la cabecera -porque aqui el
   `<th>` no lleva texto sino un BOTON que ordena, y el relleno lo pone el boton- y el fondo
   elevado, que es el de la caja y no el tono de cabecera de las demas: esta tabla se lee
   larga y con la cabecera pegada, y el gris encima del gris cansa.

   Lo pegajoso tambien es del componente: la tabla pide `.tabla--pegajosa` y lleva su
   `.tabla-tapa` delante. */
/* LOS ANCHOS DE COLUMNA, FIJOS, y esto es un arreglo suyo: *"La tabla no deberia cambiar el
   ancho de sus columnas cada que cambie su contenido, debe ajustarse una vez y quedar fijo,
   porque cuando cambio de pagina, o ajusto el orden en una columna me mueve todo y es
   incomodo y molesto"*. Con `table-layout: fixed` (en el componente) el ancho lo mandan estas
   reglas y no el contenido de la pagina que toque, asi que cambiar de intervalo u ordenar ya
   no mueve nada de sitio.

   El nombre se lleva lo que sobra: es lo unico de largo variable y lo que se lee primero. */
.ag-col-nombre { width: auto; }
.ag-col-telefono { width: 150px; }
.ag-col-empresa { width: 150px; }
/* El estado lleva DOS insignias a la vez ("Conversacion" + "Sin fichar"), que es el caso que
   manda: con menos, la segunda se recorta -y es justo la que pide accion-. */
.ag-col-estado { width: 210px; }
.ag-col-actividad { width: 110px; }

/* Y un suelo para la tabla entera: por debajo de esto las columnas dejan de ser legibles y
   es mejor que la caja scrollee de lado, que para eso esta. EL SUELO ES DE LAS CINCO COLUMNAS
   de la pantalla de Contactos: la agenda de dos (Contacto y Teléfono, en el editor de
   difusiones) cabe en mucho menos, y con 780 px salía scroll lateral con media tabla vacía.
   Se mide por la columna de empresa, que solo está en la de cinco. */
.ag-tabla:has(.ag-col-empresa) { min-width: 780px; }
.ag-tabla { min-width: 360px; }

/* --- El reparto de ancho entre columnas -------------------------------------

   EL TELEFONO NO SE PARTE. Es un identificador que se lee de un tirón, y cortado en dos
   líneas —"+58 412 838-" / "7802"— hay que recomponerlo con la vista para compararlo con
   otro. Además hacía la fila un 20% más alta, que es justo lo que le quitaba sitio a la
   tabla. Con `width: 1%` y `nowrap`, la columna pide EXACTAMENTE lo que mide su contenido.

   Y "ULTIMA ACTIVIDAD" DEJA DE ACAPARAR. Su contenido son tres caracteres ("32d") y su
   rótulo, veinte. Con la cabecera en `nowrap` el ancho lo mandaba el rótulo, así que la
   columna se llevaba 160 px para enseñar "7d" mientras el teléfono se partía. Aquí su
   rótulo SÍ puede caer a dos líneas: la cabecera crece una vez y lo que se gana lo ganan
   todas las filas. */
.ag-tabla .ag-td-telefono,
.ag-tabla .ag-td-actividad {
  width: 1%;
  white-space: nowrap;
}
.ag-tabla thead th:last-child { white-space: normal; }

.ag-celda-contacto {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}
.ag-celda-contacto .ag-nombre {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 26ch;
}
/* Los teléfonos con cifras de ancho fijo: así los números quedan en columna y se comparan
   de un vistazo en vez de bailar según los dígitos que toquen. */
.ag-tel { font-variant-numeric: tabular-nums; }
/* Teléfono al que no se puede escribir (incompleto en Odoo): en tono de aviso y con el motivo. */
.ag-tel-mal { color: var(--warn); display: inline-flex; align-items: center; gap: 4px; }
.ag-tel-mal .ic { width: 14px; height: 14px; }
.ag-nada { color: var(--text-dim); }
.ag-td-actividad { white-space: nowrap; }

/* LA PAGINACION ES DEL COMPONENTE (components/tabla.css + components/tabla.js): intervalo
   escribible y una flecha a cada lado. Lo que habia aqui -"Mostrando 1-25 de 2.953", los
   botones numerados y el desplegable de tamanos- se fue con ella. */

/* Etiqueta que solo leen los lectores de pantalla. El <select> de "filas por página" se
   entiende viéndolo, pero sin label no tiene nombre accesible y se anuncia como "combo"
   a secas. No se usa `display:none` ni `visibility:hidden`: eso lo saca también del
   árbol de accesibilidad, que es justo lo contrario de lo que hace falta. */
/* TEXTO SOLO PARA EL LECTOR DE PANTALLA. Se ve por ningun lado y ocupa 1px, pero ese 1px
   TIENE SITIO EN LA PAGINA, y ahi estaba el segundo scroll de Contactos (15-09).

   Un `position: absolute` SIN NINGUN ANCESTRO POSICIONADO cuelga del bloque contenedor
   inicial —o sea, de la pagina— y no del panel. Y `overflow: clip` no recorta lo que no
   cuelga de el. Con la tabla entera pintada, este rotulo de la paginacion se quedaba a 1.937
   px de altura, estiraba el DOCUMENTO hasta ahi y aparecia una segunda barra vertical al
   lado de la del panel: medido, el documento se movia 500 px y el panel otros 400.

   Un pixel invisible sacando una barra de scroll es de los fallos que no se encuentran
   mirando: se encuentra preguntandole al navegador quien mide mas que la ventana. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}
/* EL ANCLA VA EN EL PADRE QUE LO LLEVA, no aquí: hoy el único de esta pantalla vive en el
   pie de la tabla, y su ancla está con él (`.tabla-pag-campo`, en components/tabla.css).

   Se ancla así y no con un selector global tipo `:has(> .sr-only)` porque eso le pondría
   `position: relative` a cualquier caja de la consola que llevara uno dentro, y un
   `position: relative` inesperado cambia de sitio a los hijos absolutos que ya tenga. El
   apaño barato de hoy no puede salirle caro a una pantalla que no tiene nada que ver. */


/* --- La ficha del contacto (item U4) --------------------------------------- */

.ficha-modal .modal-body { max-height: min(70vh, 640px); overflow-y: auto; }

.ficha-cab {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 16px;
}
.ficha-nombre {
  font-size: 16px;
  font-weight: 700;
  margin-bottom: 4px;
}
.ficha-tags .ag-tags { margin: 0; }

.ficha-datos {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 8px 16px;
  margin: 0 0 16px;
}
.ficha-datos dt {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .02em;
  color: var(--text-dim);
  margin-bottom: 2px;
}
.ficha-datos dd { margin: 0; font-size: 13px; }

.ficha-sec { margin-top: 20px; }
.ficha-sec h3 {
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: .02em;
  color: var(--text-dim);
  margin: 0 0 8px;
}
.ficha-vacio, .ficha-mas {
  font-size: 12.5px;
  color: var(--text-dim);
  margin: 0;
}

/* El resumen va ARRIBA porque es lo que se lee de un vistazo antes de escribirle; el
   detalle, debajo, para quien necesite el número de pedido. */
.ficha-resumen {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 10px;
}
.ficha-resumen > div {
  flex: 1 1 100px;
  padding: 8px 10px;
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-radius: 8px;
}
.ficha-resumen span {
  display: block;
  font-size: 11px;
  color: var(--text-dim);
  margin-bottom: 2px;
}
.ficha-resumen b { font-size: 14px; font-variant-numeric: tabular-nums; }

.ficha-tabla-scroll { overflow-x: auto; }
/* La forma la pone el componente (components/tabla.css). Aquí solo el apretado: esta tabla
   va dentro de una ficha estrecha, donde el relleno grande deja tres filas por pantalla. */
.ficha-tabla { font-size: 12.5px; }
.ficha-tabla th { padding: 4px 8px; background: transparent; }
.ficha-tabla td { padding: 6px 8px; }
.ficha-ref { font-weight: 600; }
/* El importe SÍ va a la derecha: es una cantidad que se compara por magnitud, al revés que
   un teléfono, que es un identificador y se lee dígito a dígito. */
.ficha-monto { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.ficha-fecha { white-space: nowrap; color: var(--text-dim); }

.ficha-estado {
  display: inline-block;
  padding: 1px 7px;
  border-radius: 999px;
  font-size: 11px;
  border: 1px solid var(--border);
  white-space: nowrap;
}
/* Los colores de estado siguen la convención universal, no un gusto: verde confirmado,
   ámbar en curso, rojo cancelado. */
.ficha-estado.est-sale, .ficha-estado.est-done { color: var(--ok); border-color: var(--ok); }
.ficha-estado.est-draft, .ficha-estado.est-sent { color: var(--warn); border-color: var(--warn); }
.ficha-estado.est-cancel { color: var(--danger); border-color: var(--danger); }

.ficha-chat {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 8px 10px;
  border: 1px solid var(--border);
  border-radius: 8px;
  margin-bottom: 6px;
}
.ficha-chat-nom { display: block; font-size: 13px; font-weight: 600; }
.ficha-chat-sub { display: block; font-size: 11.5px; color: var(--text-dim); }

.ficha-cargando, .ficha-error {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 0;
  font-size: 12.5px;
  color: var(--text-dim);
}
.ficha-error { color: var(--danger); }
.ficha-cargando svg, .ficha-error svg { width: 16px; height: 16px; flex: 0 0 auto; }
/* El icono de carga gira: sin movimiento, "cargando" y "colgado" se ven igual. */
.ficha-cargando svg { animation: ficha-gira 1s linear infinite; }
@keyframes ficha-gira { to { transform: rotate(360deg); } }

/* La insignia de conversación es un botón de verdad: hereda el aspecto de la insignia y
   solo añade lo que la hace pulsable. */
.ag-tag-btn {
  border: 0;
  font: inherit;
  cursor: pointer;
  transition: filter .12s ease;
}
.ag-tag-btn:hover { filter: brightness(1.12); }
.ag-tag-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

@media (prefers-reduced-motion: reduce) {
  .ficha-cargando svg { animation: none; }
  .ag-tag-btn { transition: none; }
}

.ficha-chat-acts { display: flex; align-items: center; gap: 6px; flex: 0 0 auto; }
/* "Vinculada" es un ESTADO, no un botón: se ve que ya está hecho y no invita a pulsarlo. */
.ficha-vinculada {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 11.5px;
  color: var(--ok);
  white-space: nowrap;
}
.ficha-vinculada svg { width: 14px; height: 14px; }
