/* ==========================================================================
   LeadSync - Mensajes rapidos
   El buscador que abre "/" en el composer y su pantalla de gestion (item 125).

   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 rápidos (item 125)
   ========================================================================== */

/* --- El buscador que abre "/" en el composer --- */

/* Anclado al TOPE del composer, como la bandeja de emojis: crece el editor, sube él.
   La entrada va por ANIMATION y no por una transición disparada desde JS: una animación
   sin fill-mode termina siempre en el estado natural del elemento, así que si el navegador
   no llega a correr el primer frame (pestaña de fondo) no queda invisible para siempre. */
.qr-picker {
  position: absolute;
  bottom: calc(100% - 6px);
  left: 12px;
  right: 12px;
  /* MÁS ANCHO QUE ANTES (560px) PORQUE AHORA LLEVA DOS COLUMNAS: la lista y la previa. Solo
     lo usa si lo tiene: con `left`/`right` puestos, el ancho lo decide el hueco del chat, y
     este tope es el techo. */
  max-width: 860px;
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: 0 8px 24px var(--shadow);
  overflow: hidden;
  z-index: 40;
  animation: qr-in 160ms ease-out;
  /* LA PREVIA SE PARTE POR LO QUE MIDE EL BUSCADOR, NO LA VENTANA. El chat es una columna
     entre otras —con el panel de la derecha abierto se queda en la mitad—, así que una
     `@media` acertaría en el escritorio del que la escribió y fallaría en el de al lado.
     Es seguro contener aquí: el ancho ya venía de fuera (`left`/`right`/`max-width`) y no
     de lo que lleva dentro. */
  container-type: inline-size;
  container-name: qr-picker;
  /* EL ALTO DE LA LISTA, ESCRITO UNA VEZ. Lo necesitan dos reglas —la propia lista y, en dos
     columnas, la fila que la iguala con la previa— y escribirlo dos veces es la forma
     conocida de que una cambie y la otra no (NO_REPETIR 37). */
  --qr-alto-lista: 260px;
}
.qr-cols {
  display: flex;
  /* EN ESTRECHO, LA PREVIA VA ARRIBA. Invertido, no reordenado: la lista sigue siendo lo
     primero del marcado —que es el orden en que se lee y se tabula— y queda pegada al
     composer, que es donde está la vista y el dedo. */
  flex-direction: column-reverse;
}
/* LA PREVIA ES LA MISMA PIEZA QUE LA DEL EDITOR, no una parecida: `previaDeMensajeRapido`
   pinta aquí dentro. Lo que cambia es el marco, y hasta eso comparte el título. */
.qr-previa {
  padding: 8px 10px 10px;
  background: var(--bg-elev);
  border-bottom: 1px solid var(--border);
  overflow-y: auto;
  /* Un mensaje con lista y ocho filas es más alto que la propia lista de atajos: se recorta
     aquí dentro en vez de estirar el buscador hasta tapar la conversación. */
  max-height: 34vh;
}
.qr-previa-tit {
  display: block;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .3px;
  text-transform: uppercase;
  color: var(--text-dim);
  margin-bottom: 6px;
}
@container qr-picker (min-width: 620px) {
  .qr-cols {
    flex-direction: row;

    /* ALTO FIJO, NO UN TOPE, Y ESTE ES EL ARREGLO DE UN BUCLE (item A98).
       Él lo describió entero: con el ratón —no con las flechas— pasar por encima de un
       atajo lo previsualiza, la previa cambia de alto, la FILA cambia de alto con ella, las
       filas de la lista se desplazan bajo el cursor, el cursor cae sobre otro atajo, que
       previsualiza, que cambia el alto… y así sin parar.

       La causa es que con `max-height` el alto de la fila lo decidía el contenido, o sea la
       previa, o sea justo lo que cambia al pasar el ratón. Fijándolo, mover el ratón no
       puede mover nada: la previa crece hacia dentro y se desplaza sola, que para eso lleva
       su `overflow-y`. La lista queda quieta, que es lo único que el cursor necesita.

       El estrecho no necesita esto: allí la previa va encima y el buscador crece hacia
       arriba, así que la lista no se mueve de sitio pase lo que pase con el alto. */
    height: var(--qr-alto-lista);
  }
  .qr-list { flex: 1 1 auto; min-width: 0; }
  .qr-previa {
    flex: 0 0 300px;
    border-bottom: 0;
    border-left: 1px solid var(--border);
    max-height: none;
  }
}
.qr-picker.leaving { animation: qr-out 140ms ease-in forwards; }
@keyframes qr-in {
  from {
    opacity: 0;
    transform: translateY(8px) scale(.985);
  }
}
@keyframes qr-out {
  to {
    opacity: 0;
    transform: translateY(6px) scale(.985);
  }
}
.qr-list {
  max-height: var(--qr-alto-lista);
  overflow-y: auto;
  padding: 4px;
}
.qr-item {
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 8px 10px;
  border-radius: 8px;
  cursor: pointer;

  /* Cambio de estado, no de sitio: 120 ms y solo el color (el mandato de movimiento pide
     animar lo que se desplaza; un hover que se mueve marea). */
  transition: background-color 120ms ease;
}
.qr-item.active,
.qr-item:hover {
  background: var(--bg-hover);
}
.qr-shortcut {
  flex: 0 0 auto;
  font-weight: 700;
  font-size: 13px;
  color: var(--accent);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}
.qr-preview {
  flex: 1;
  min-width: 0;
  font-size: 13px;
  color: var(--text-dim);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Las pildoras del popover de «/» son LAS MISMAS que las de la lista de gestion y por eso
   llevan la misma clase (item A70): son el mismo dato -de que clase es el mensaje y de quien
   es-, y dos formas distintas para lo mismo se leen como dos cosas distintas.

   LO UNICO QUE CAMBIA ES QUIEN MANDA EN EL HUECO. En la fila de gestion la caja CRECE para
   llegar hasta la flecha, que es lo que hace que el desvanecido caiga sobre hueco vacio
   cuando todo cabe. Aqui el que crece es el texto de la previa, asi que las pildoras se
   quedan con lo suyo y solo ceden cuando no cabe -pero el desvanecido se hereda y sigue
   haciendo falta: un nombre de plantilla largo no puede empujar al atajo fuera-. */
.qr-item .qr-row-pills {
  flex: 0 1 auto;
  /* El desvanecido son los últimos 20px de la caja: sin este hueco se comía SIEMPRE el final
     de la última píldora («EQUIP…»), también cuando todo cabía. */
  padding-right: 20px;
  margin-right: -10px;
}
/* LA FORMA DE LA PILDORA, con nombre propio. Las dos que lleva una fila -de que clase es
   el mensaje, y de quien es- van pegadas en la misma linea, asi que cualquier diferencia de
   tipografia entre ellas se lee como un descuido: estuvieron escritas por separado y una
   salio en negrita y la otra no. Lo vio el: "no entiendo por que no tienen el mismo bold".
   Lo que las distingue es el color y el icono; la forma se escribe UNA vez y aqui. */
.qr-pill {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .3px;
  text-transform: uppercase;
  padding: 2px 6px;
  border-radius: 999px;
  color: var(--text-dim);
}
.qr-tag {
  border: 1px solid var(--border);
}

/* El cajón se distingue por la FORMA además del color (relleno vs. contorno): quien no
   separa bien los tonos sigue leyendo cuál es del equipo. */
.qr-tag-team {
  background: var(--bg-hover);
  color: var(--text);
}
.qr-tag-mine { background: transparent; }

/* LA PILDORA DEL BOT: si lo puede usar o no, de un vistazo (15-09).

   LOS DOS ESTADOS SE VEN, y se distinguen por FORMA ademas de por color -relleno frente a
   contorno tenue-, no solo por el tono: quien no separa bien los colores sigue leyendo cual
   es cual. El icono es el mismo en los dos; lo que cambia es el peso. */
.qr-pill-bot {
  border: 1px solid transparent;
  gap: 3px;
}
.qr-pill-bot .ic { width: 11px; height: 11px; }
.qr-pill-bot.on {
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  border-color: color-mix(in srgb, var(--accent) 35%, transparent);
  color: var(--accent);
}
/* Apagada NO es un error -la mayoria de los mensajes rapidos no son del bot-, asi que se
   queda en gris y sin peso: dice el estado sin llamar la atencion. */
.qr-pill-bot.off {
  background: transparent;
  border-color: var(--border);
  color: var(--text-dim);
  opacity: .75;
}
.qr-empty {
  padding: 18px 14px;
  font-size: 13px;
  color: var(--text-dim);
  text-align: center;
}
.qr-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 6px 10px;
  border-top: 1px solid var(--border);
  background: var(--bg-elev);
}
.qr-hint {
  font-size: 11px;
  color: var(--text-dim);
}
.qr-manage {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  background: none;
  border: 0;
  cursor: pointer;
  font-size: 12px;
  color: var(--text-dim);
  padding: 4px 6px;
  border-radius: 6px;
  transition: background-color 120ms ease, color 120ms ease;
}
.qr-manage:hover {
  background: var(--bg-hover);
  color: var(--text);
}
.qr-manage .ic {
  width: 14px;
  height: 14px;
}

/* --- Gestión (la misma pieza en Configuración y en la modal del composer) --- */
/* UN SOLO SCROLL Y LA PAGINACIÓN. Antes la lista se metía en el alto que quedara y
   scrolleaba POR DENTRO; dentro de la modal eso eran dos barras anidadas (NO_REPETIR 65).
   Ahora es LA TABLA, como
   Contactos: mide lo que miden sus filas y se recorre con la paginación de arriba. Quien
   scrollea, si hace falta, es el panel o el cuerpo de la modal, y nadie más. */
.qr-gestion { display: block; }
/* LA FILA ES UN <tr> DE LA TABLA. Lo que antes colocaba la fila —flex, relleno— va
   en sus dos celdas: un `<tr>` en flex deja de casar con su tabla y descuelga las columnas
   (el fallo de la agenda del 07-09). La entrada animada es la del componente. */
.qr-tabla { table-layout: auto; }
.qr-tabla td {
  padding: 10px 8px 10px 12px;
  vertical-align: top;
  /* El texto desplegado se lee entero: el recorte de celda del componente no aplica aquí. */
  overflow: visible;
}
.qr-td-acciones {
  width: 1%;
  white-space: nowrap;
}
.qr-td-rapido { max-width: 0; }

/* La entrada de tarjetas y avisos que comparten métricas, departamentos y el aviso de copia. */
@keyframes qr-row-in {
  from {
    opacity: 0;
    transform: translateY(-4px);
  }
}

/* La cabecera de la fila ES el disparador del acordeón (item 19), así que es un <button>:
   un <div> con onclick no se alcanza con el teclado ni lo anuncia un lector de pantalla.
   Se le quitan los estilos de botón porque no parece uno ni debe parecerlo. */
.qr-row-main {
  display: block;
  width: 100%;
  min-width: 0;
  background: none;
  border: 0;
  padding: 0;
  margin: 0;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
}
.qr-row-top {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 3px;
}

/* --- Las pildoras de la fila, cuando no caben (movil) ------------------------

   EL ATAJO NO CEDE. Es lo unico que identifica la fila; las pildoras son contexto. Sueltas
   en la fila, al no caber empujaban a "/ubicacion" fuera de la pantalla y la lista dejaba de
   poder leerse. En su propia caja, la que se recorta es la caja.

   CERRADA se ve lo que quepa, y que hay MAS se dice con el degradado del borde: es la misma
   señal que usa la lista de chats, se entiende sin tocar nada y no cuesta medir cada fila en
   cada repintado. ABIERTA caen debajo del atajo, en su propia linea y ya completas, que es
   como el lo dibujo. */
.qr-row-pills {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  overflow: hidden;
  flex-wrap: nowrap;
  /* CRECE HASTA LLENAR LO QUE QUEDE, y ese es el truco para que el degradado no se vea
     cuando todo cabe: el desvanecido son los ultimos 20px de la CAJA, asi que si la caja
     llega hasta la flecha y las pildoras terminan mucho antes, el degradado cae sobre
     hueco vacio y no se nota. Con la caja pegada al contenido se comia siempre el final de
     la ultima etiqueta, tambien en una pantalla ancha, que es lo que el vio. */
  flex: 1 1 auto;
  -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 20px), transparent);
  mask-image: linear-gradient(to right, #000 calc(100% - 20px), transparent);
}
.qr-row.abierta .qr-row-top { flex-wrap: wrap; }
.qr-row.abierta .qr-row-pills {
  /* `100%` la manda a su propia linea; el atajo y la flecha se quedan arriba. */
  flex-basis: 100%;
  flex-wrap: wrap;
  row-gap: 6px;
  overflow: visible;
  -webkit-mask-image: none;
  mask-image: none;
}
/* La flecha se queda en la PRIMERA linea, con el atajo. En el marcado va detras de las
   pildoras -que es su sitio cuando todo cabe-, asi que al desplegar se adelanta con `order`:
   atajo, flecha, y las pildoras debajo. */
.qr-row.abierta .qr-chevron { order: 1; }
.qr-row.abierta .qr-row-pills { order: 2; }
.qr-chevron {
  margin-left: auto;
  display: inline-flex;
  color: var(--text-dim);
  transition: transform 160ms ease;
}
.qr-chevron .ic {
  width: 15px;
  height: 15px;
}
.qr-row.abierta .qr-chevron { transform: rotate(180deg); }

/* CERRADA una línea; ABIERTA el texto entero. Se anima el max-height y no se cambia el
   white-space de golpe: el salto de "nowrap" a "pre-wrap" sin transición es justo lo que
   hace que un acordeón se sienta roto. */
.qr-row-text {
  font-size: 13px;
  color: var(--text-dim);
  line-height: 1.5;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-height: 1.5em;
  transition: max-height 180ms ease;
}
.qr-row.abierta .qr-row-text {
  white-space: pre-wrap;
  max-height: 30em;
}

/* El texto CRUDO (con sus {{variables}}) solo cuando está desplegada: quien gestiona
   necesita ver dónde están, pero cerrada sería una segunda línea de ruido en cada fila. */
.qr-row-crudo {
  font-size: 11.5px;
  color: var(--text-dim);
  line-height: 1.5;
  max-height: 0;
  opacity: 0;
  overflow: hidden;
  transition: max-height 180ms ease, opacity 180ms ease, margin-top 180ms ease;
}
.qr-row.abierta .qr-row-crudo {
  max-height: 12em;
  opacity: 1;
  margin-top: 6px;
}
.qr-row-crudo code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  color: var(--accent-strong);
}
/* --- Detalle por tipo (ubicación y producto) -------------------------------- */
/* Se despliega con la fila, igual que el texto crudo y con la misma animación: es el mismo
   gesto, así que tiene que sentirse igual. El max-height generoso cabe lo que hay (tres
   datos y una nota) sin recortarlo, y el `overflow: hidden` es lo que permite animarlo.

   OJO AL AÑADIR UN TIPO NUEVO DE DETALLE: hay que ponerlo en ESTAS DOS LISTAS. `qr-detalle-media`
   faltaba, y el resultado era que la foto de un mensaje rápido con adjunto se veía SIEMPRE, con
   la fila plegada (item B75). Es una lista escrita en dos sitios —el marcado y esto— y por eso
   se desincronizó; si vuelve a pasar, lo que toca es una clase común, no un cuarto renglón. */
.qr-detalle,
.qr-detalle-nota,
.qr-detalle-prod,
.qr-detalle-inter {
  max-height: 0;
  opacity: 0;
  overflow: hidden;
  transition: max-height 180ms ease, opacity 180ms ease, margin-top 180ms ease;
}
.qr-row.abierta .qr-detalle,
.qr-row.abierta .qr-detalle-nota,
.qr-row.abierta .qr-detalle-prod,
.qr-row.abierta .qr-detalle-inter,
.qr-row.abierta .qr-detalle-media {
  max-height: 32em;
  opacity: 1;
  margin-top: 8px;
}
/* Anidado dentro de otro detalle, el hijo ya lo anima el padre: dejarle su propio
   max-height a 0 lo mantendría cerrado dentro de un contenedor abierto. */
.qr-row .qr-detalle-inter .qr-detalle,
.qr-row .qr-detalle-prod .qr-detalle {
  max-height: none;
  opacity: 1;
  margin-top: 0;
  transition: none;
}
/* LA FICHA DE DATOS: rótulo a la izquierda, valor a la derecha, una fila por dato.
   `.qr-detalle-dl` —la del archivo adjunto— entra aquí y NO tiene reglas propias: tenía solo
   un `margin: 0`, así que sus `dt`/`dd` caían uno debajo de otro como texto corrido, sin
   distinguir el rótulo del valor. No se veía porque ese bloque estaba oculto por otro fallo
   (item B75); al destaparlo salió esto. Dos marcados que enseñan lo mismo comparten las
   reglas, no las copian. */
.qr-detalle {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 12px;
  margin: 0;
}
.qr-detalle > div,
.qr-detalle-dl > div {
  display: flex;
  gap: 8px;
  align-items: baseline;
}
.qr-detalle dt,
.qr-detalle-dl dt {
  flex: 0 0 84px;
  color: var(--text-dim);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .02em;
}
.qr-detalle dd,
.qr-detalle-dl dd {
  margin: 0;
  min-width: 0;
  color: var(--text);
  line-height: 1.45;
  overflow-wrap: anywhere; /* una dirección larga no puede desbordar la fila */
}
.qr-detalle code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 11.5px;
  color: var(--accent-strong);
}
.qr-detalle-nota {
  font-size: 11.5px;
  color: var(--text-dim);
  font-style: italic;
  line-height: 1.45;
}
.qr-detalle-prod {
  display: flex;
  gap: 10px;
  align-items: flex-start;
}
/* El hueco de la foto se reserva antes de que llegue: si no, la fila crece de golpe al
   aparecer y empuja las de abajo mientras se está leyendo. */
.qr-foto {
  flex: 0 0 auto;
  width: 64px;
  height: 64px;
  border-radius: 8px;
  overflow: hidden;
  background: var(--bg-hover);
  border: 1px solid var(--border);
  display: grid;
  place-items: center;
}
.qr-foto img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  animation: qrFotoEntra 180ms ease both;
}
.qr-foto img:not([src]) { display: none; }
.qr-foto[data-falla]::after {
  content: "no carga";
  font-size: 9.5px;
  color: var(--text-dim);
  text-align: center;
  padding: 2px;
}

@keyframes qrFotoEntra {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* --- Eco de la foto en el editor -------------------------------------------- */
/* Aparece cuando hay algo que decir de la foto. Nace plegado y crece: si estuviera
   siempre ocupando sitio, el formulario tendría un hueco vacío que no se entiende. */
.qr-foto-eco {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 0;
  max-height: 0;
  opacity: 0;
  overflow: hidden;
  transition: max-height 180ms ease, opacity 180ms ease, margin-top 180ms ease;
}
.qr-foto-eco[data-listo],
.qr-foto-eco[data-falla],
.qr-foto-eco[data-aviso] {
  max-height: 90px;
  opacity: 1;
  margin-top: 8px;
}
.qr-foto-verdicto {
  font-size: 12px;
  color: var(--text-dim);
  line-height: 1.4;
}
/* Los tres estados se distinguen por COLOR y por texto, nunca solo por color: quien no
   distingue el ámbar del verde tiene que poder leerlo igual. */
.qr-foto-eco[data-aviso] .qr-foto-verdicto { color: var(--warn, #d97706); }
.qr-foto-eco[data-falla] .qr-foto-verdicto { color: var(--danger, #dc2626); }
/* Sin foto cargada, el cuadro sobra: el mensaje se lee mejor solo. */
.qr-foto-eco:not([data-listo]) .qr-foto { display: none; }

/* --- Etiqueta de tipo ------------------------------------------------------- */
/* Solo la llevan los tipos que HACEN algo distinto (ubicación y producto). Marcarlos
   importa: son los dos que se ENVÍAN al pulsarlos en vez de insertarse en el composer. */
/* La forma la pone .qr-pill; aqui solo su fondo, que es lo que la separa de la de
   "de quien es". */
.qr-tipo {
  background: var(--bg-hover);
}
.qr-tipo .ic {
  width: 11px;
  height: 11px;
}

/* EL BADGE DE TIPO ES AZUL, TODOS. Dicen la misma clase de cosa -que ES ese mensaje
   rapido: una lista, un enlace, una foto, una ubicacion, una plantilla de Meta-, asi que un
   color por tipo convertia una etiqueta informativa en un semaforo que no significaba nada.
   Lo vio el: "el badge [clip] Foto deberia ser azul, es el tipo... igual ubicacion, no?".

   Y ADEMAS DOS DE ELLOS NO TENIAN REGLA: `.qr-tipo-ubi` y `.qr-tipo-media` se quedaban en el
   gris de `.qr-tipo` a secas. No era una decision, era un hueco -por eso "Foto" se veia
   apagada al lado de "ENLACE"-.

   EL COLOR DISTINTO SE RESERVA PARA LO QUE NO ES UN TIPO: un estado. Ver `.qr-tipo-roto` y
   `.qr-tipo-borrador` mas abajo. Asi el color vuelve a querer decir algo. */
.qr-tipo-inter,
.qr-tipo-ubi,
.qr-tipo-media,
.qr-tipo-plt {
  background: color-mix(in srgb, var(--info) 16%, transparent);
  color: var(--info);
}



/* El hueco {{n}} sobre el que caera la proxima variable. Hace falta una CLASE y no basta
   con :focus porque pulsar el chip de variable es un clic, y al clicar el contenteditable
   pierde el foco: sin esto, el operador no sabria en cual va a escribir. */
.tmpl-var-chip.enfocado {
  box-shadow: inset 0 0 0 2px var(--accent);
  background: var(--accent-dim);
  color: var(--text);
}

/* La plantilla puede ser larga y el editor ya tiene su propio scroll: se le pone techo para
   que no empuje la fila de variables fuera de la vista, que es donde hay que llegar. */
#qr-f-plt-vista {
  max-height: 180px;
  overflow-y: auto;
}

/* DESACTIVADO: el flow que hay detras ya no esta en Meta. Se dice AQUI y no solo al
   intentar enviarlo: enterarse con el cliente delante es enterarse tarde. Lleva el rojo de
   error porque no es una etapa mas del atajo, es que no se puede usar. */
.qr-tipo-roto {
  background: color-mix(in srgb, var(--danger) 16%, transparent);
  color: var(--danger);
}

/* UN FORMULARIO EN BORRADOR NO ES UN TIPO, ES UN ESTADO, y por eso rompe el azul (item B73):
   un flow marcado como borrador SOLO le llega a los numeros de prueba de Meta, asi que
   dejarlo puesto por descuido es un mensaje que nunca le llega al cliente. Va en ambar
   porque no esta roto -funciona, y es lo que se quiere mientras se prueba- pero no puede
   pasar desapercibido el dia que se publique. */
.qr-tipo-borrador {
  background: color-mix(in srgb, var(--warn) 18%, transparent);
  color: var(--warn);
}

.qr-uses {
  font-size: 11px;
  color: var(--text-dim);
  /* NI SE PARTE NI SE ENCOGE. Al sacarlo de la caja que se recorta -para que no se
     desvaneciera a mitad de "sin usar"- quedo a merced del sitio que hubiera, y en movil
     caia en dos lineas: "sin / usar". Son dos palabras; o caben o no, pero enteras. */
  flex: 0 0 auto;
  white-space: nowrap;
}
.qr-uses-none {
  font-style: italic;
  opacity: .75;
}

/* Editar y borrar de una fila/tarjeta (departamentos y mensajes rápidos: la misma pieza).
   El dibujo era de 15px dentro de un botón de 34: en un móvil eso es un blanco que se falla,
   y son las dos únicas acciones de la tarjeta. */
.qr-row-acts {
  display: flex;
  gap: 4px;
  flex: 0 0 auto;
}
.qr-copia-aviso {
  margin: 0 0 16px;
  padding: 10px 14px;
  border-radius: var(--radius-sm, 6px);
  background: var(--warn-bg);
  border: 1px solid var(--border);
  color: var(--text);
  font-size: 13px;
  line-height: 1.45;
  animation: qr-row-in 180ms ease-out;
}
@media (prefers-reduced-motion: reduce) {
  .qr-copia-aviso { animation: none; }
}
.qr-row-acts .ic {
  width: 17px;
  height: 17px;
}

/* En táctil, 44px de área — el mínimo de Apple HIG y Material, y aquí se nota porque el
   vecino es "eliminar". */
@media (max-width: 720px) {
  /* Tres acciones juntas no deben quitarle el ancho al contenido del rápido: en la tabla se
     apilan en su columna en vez de partir la fila (un <tr> no se parte). */
  .qr-td-acciones .qr-row-acts { flex-direction: column; }
  .qr-row-acts .icon-btn {
    width: 44px;
    height: 44px;
  }
  .qr-row-acts .ic {
    width: 19px;
    height: 19px;
  }
}
.qr-locked {
  font-size: 11px;
  color: var(--text-dim);
  font-style: italic;
  white-space: nowrap;
  padding: 0 4px;
}

/* --- Editor --- */
.qr-shortcut-field {
  display: flex;
  align-items: center;
}
.qr-slash {
  padding: 11px 2px 11px 12px;
  font-weight: 700;
  color: var(--text-dim);
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-right: 0;
  border-radius: 8px 0 0 8px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}
.qr-shortcut-field input {
  flex: 1;
  border-radius: 0 8px 8px 0 !important;
}
.qr-modal .modal-card,
.qr-edit-modal {
  max-width: 620px;
}
.qr-edit-modal textarea {
  width: 100%;
  /* PROHIBIDO EL TIRADOR: pisaba el `resize: none` global de modal.css por ser más
     específica y cargarse después. El alto lo decide el contenido (autoAltoTextarea). */
  resize: none;
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 11px 13px;
  color: var(--text);
  font-size: 14px;
  font-family: inherit;
  transition: border-color 120ms ease;
}
.qr-edit-modal textarea:focus {
  border-color: var(--accent);
  outline: none;
}
.qr-vars {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
  margin: -4px 0 12px;
}
/* LA FILA DEL MENSAJE CON OPCIONES SE QUEDA PEGADA ABAJO hasta que le toca su sitio.
   Ese formulario es largo -encabezado, mensaje, pie, y el texto y el identificador de cada
   boton- y la fila de chips vive al final: para meter una variable en el PRIMER campo habia
   que bajar hasta abajo, pulsar, y volver a subir. En movil eso es media pantalla de ida y
   otra de vuelta por cada variable.
   Con `bottom: 0` se comporta como una barra de herramientas mientras esta fuera de vista y
   se asienta en su posicion en cuanto se llega a ella, sin saltos.
   EL FONDO ES OPACO porque el formulario pasa por debajo; y el relleno de abajo del panel
   deja sitio para que no tape el ultimo campo. */
.qr-vars[data-destino="opciones"] {
  position: sticky;
  /* SE DESCUENTA EL RELLENO DE ABAJO DEL SCROLLPORT. Con `bottom: 0` la fila se pegaba al
     borde del RELLENO, no al del contenedor, y por esos 8px se veia pasar el formulario por
     debajo: "quedo mal pegado abajo, se visualiza detras". El relleno se compensa con el
     mismo numero, que vive en una variable para que no puedan separarse. */
  bottom: calc(-1 * var(--modal-body-pad-b, 0px));
  z-index: 1;
  margin: -4px 0 0;
  padding: 8px 0 calc(8px + var(--modal-body-pad-b, 0px));
  background: var(--bg-panel);
}
#panel-opciones { padding-bottom: 4px; }

.qr-var {
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 3px 9px;
  font-size: 11.5px;
  color: var(--text-dim);
  cursor: pointer;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  transition: background-color 120ms ease, color 120ms ease, border-color 120ms ease;
}
.qr-var:hover {
  background: var(--bg-hover);
  color: var(--text);
  border-color: var(--accent);
}
/* --- El repertorio del bot (item A76) -------------------------------------
   VA SEPARADO DEL RESTO DEL FORMULARIO a proposito. Todo lo de arriba responde "que se
   manda"; esto responde "quien puede usarlo", que es otra pregunta. Sin la linea de arriba
   se leia como un campo mas del mensaje, y el ojo no encontraba donde acababa una cosa y
   empezaba la otra. */
.qr-bot {
  margin-top: 16px;
  padding-top: 14px;
  border-top: 1px solid var(--border);
}

.qr-bot-linea {
  display: flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
  /* Pisa el `label` de .modal-field, que va en gris pequeno: aqui la etiqueta ES la
     decision, no el nombre de un campo. */
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
}

.qr-bot-linea input {
  /* El checkbox no hereda el ancho completo que .modal-field da a los input. */
  width: auto;
  margin: 0;
  accent-color: var(--accent);
  cursor: pointer;
}

.qr-bot input:disabled + span {
  color: var(--text-dim);
  cursor: default;
}

.qr-bot-veto {
  /* El motivo del veto se distingue del consejo de al lado: uno explica, el otro impide. */
  border-left: 2px solid var(--border-strong);
  padding-left: 9px;
}

/* LA NOTA ES DEL MENSAJE RAPIDO y esta siempre a la vista, asi que ya no aparece ni
   desaparece: no hay nada que animar. */
.qr-nota textarea {
  /* El alto lo decide el contenido, como en el composer: nada de tirador. */
  resize: none;
}

/* EL CONTADOR VA PEGADO AL CAMPO Y A LA DERECHA, que es donde acaba de escribir la vista.
   Suelto a la izquierda -como estaba- se leia como un dato del formulario y no como el
   estado de ese textarea. */
.qr-cuenta {
  align-self: flex-end;
  margin-top: -2px;
  font-size: 11px;
  color: var(--text-dim);
  font-variant-numeric: tabular-nums;
}

/* Al llegar al tope el navegador deja de aceptar teclas SIN DECIR NADA. El color es lo unico
   que explica por que; sin esto, parece que el teclado se rompio. */
.qr-nota.al-tope .qr-cuenta {
  color: var(--warn);
  font-weight: 600;
}

.qr-preview-box { margin-top: 4px; }
.qr-preview-box label {
  font-size: 12px;
  color: var(--text-dim);
  font-weight: 600;
}
.qr-preview-text {
  margin-top: 6px;
  padding: 10px 12px;
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-radius: 8px;
  font-size: 13.5px;
  color: var(--text);
  white-space: pre-wrap;
  word-break: break-word;
  min-height: 42px;
}
.qr-preview-text.empty {
  color: var(--text-dim);
  font-style: italic;
}

/* El movimiento explica de dónde sale algo; a quien pide menos movimiento no le explica
   nada y le molesta. Se quedan los cambios de color, que no desplazan nada. */
@media (prefers-reduced-motion: reduce) {
  .qr-picker,
  .qr-picker.leaving,
  .qr-row {
    animation: none;
  }
  .qr-chevron,
  .qr-row-text,
  .qr-row-crudo {
    transition: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .qr-detalle,
  .qr-detalle-nota,
  .qr-detalle-prod,
  .qr-foto-eco { transition: none; }
  .qr-foto img { animation: none; }
}

/* --- Editor en dos columnas (item A9) ---------------------------------------- */

/* EL ANDAMIO DE DOS COLUMNAS SE MUDO A components/vistaprevia.css (item A18): lo usan el
   editor de mensajes rapidos y el de plantillas, y dos copias divergen a la primera.
   OJO: `modalClass` se le pone a la PROPIA tarjeta, asi que el selector lleva las dos
   clases pegadas. */
.modal-card.qr-edit-modal { max-width: 880px; width: 100%; }

/* --- El adjunto del mensaje rapido (item A36) -------------------------------
   Sustituye al bloque del viejo "producto". Aqui no hay tarjeta compuesta ni nada
   inventado: se enseña QUE archivo hay, de que tipo y cuanto pesa, y si es una imagen se
   ve. Lo que le llega al cliente es un adjunto normal con su pie, y la previa de la
   derecha ya lo enseña asi. */
/* EL SELECTOR DE ARCHIVO ES UN COMPONENTE, no el control del sistema (item B50).
   El `input type=file` se dibuja distinto en cada sistema, no acepta casi estilos y en
   Windows sale como un boton gris con "Sin archivos seleccionados" al lado: no se parece a
   nada de esta consola. El pidio que se viera como una pieza mas.

   LO QUE NO SE HACE ES SUSTITUIRLO. El input sigue ahi dentro -es quien abre el selector del
   sistema y quien lleva el archivo-, solo que no se pinta; la caja ES su etiqueta, asi que
   pulsar cualquier parte lo activa. Y no se oculta con `display: none`, que ademas lo saca
   del recorrido del tabulador: se deja medible y enfocable, y el foco se ve en la caja con
   `:focus-within`. */
.qr-file-caja {
  position: relative;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px;
  border: 1px dashed var(--border-strong);
  border-radius: 8px;
  background: var(--bg-elev);
  cursor: pointer;
  transition: border-color .12s ease, background-color .12s ease;
}
.qr-file-caja:hover {
  border-color: var(--accent);
  background: var(--bg-hover);
}
.qr-file-caja:focus-within {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}
.qr-file-ic {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: var(--accent-dim);
  color: var(--accent-strong);
}
.qr-file-ic .ic { width: 17px; height: 17px; }
.qr-file-txt {
  display: flex;
  flex-direction: column;
  min-width: 0;
  line-height: 1.35;
}
.qr-file-txt b { font-size: 13.5px; }
.qr-file-txt small {
  font-size: 11.5px;
  color: var(--text-dim);
}

/* El input nativo: presente y enfocable, pero sin dibujo. */
.qr-file {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

@media (prefers-reduced-motion: reduce) {
  .qr-file-caja { transition: none; }
}

.qr-media-eco {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 8px;
  min-height: 0;
}
.qr-media-eco:empty { display: none; }
.qr-media-eco[data-estado="subiendo"] { opacity: .7; }
.qr-media-eco[data-estado="mal"] .qr-media-txt { color: var(--danger); }

.qr-media-img {
  flex: 0 0 auto;
  width: 56px;
  height: 56px;
  border-radius: 8px;
  overflow: hidden;
  background: var(--bg-hover);
}
.qr-media-img img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.qr-media-txt {
  min-width: 0;
  font-size: 13px;
  color: var(--text);
  overflow: hidden;
  text-overflow: ellipsis;
}
.qr-media-sub {
  display: block;
  color: var(--text-dim);
  font-size: 12px;
}

/* EL DETALLE DE UN MENSAJE CON OPCIONES enseña lo que le llega al cliente, dibujado con el
   mismo componente que la vista previa y que el chat. Debajo, en una lista, lo unico que NO
   se ve mirando: el identificador con el que responde cada boton y la direccion de los de
   enlace. Antes desplegarlo no enseñaba nada, porque lo unico que habia era el cuerpo, que
   es justo lo que ya se lee plegado. */
.qr-detalle-inter { font-size: 12.5px; }
.qr-detalle-enc { font-weight: 700; }
.qr-detalle-pie { color: var(--text-dim); font-size: 11.5px; }
/* UNA SOLA REGLA PARA ESTA CLASE, y no dos: la colocacion y el plegado viven juntos. Estaban
   separadas -el plegado arriba, con los demas detalles; el `display:flex` aqui- y eso es
   exactamente lo que caza check-clases-duplicadas.py: quien lee la de arriba da por hecho que
   ya sabe como se coloca esto, y no es verdad. */
.qr-detalle-media {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  max-height: 0;
  opacity: 0;
  overflow: hidden;
  transition: max-height 180ms ease, opacity 180ms ease, margin-top 180ms ease;
}
.qr-detalle-media .qr-media-img {
  width: 96px;
  height: 96px;
}
/* La ficha del archivo: misma presentacion que `.qr-detalle` -rotulo en versalita a la
   izquierda, valor a la derecha- y ademas crece para que un nombre largo no empuje la foto.
   Todo en UNA regla, por lo dicho en .qr-detalle-media. */
.qr-detalle-dl {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 12px;
  margin: 0;
  flex: 1 1 auto;
  min-width: 0;
}

/* --- El formulario en dos niveles (rediseño del 09-09) ---
   Antes era un `select` de cuatro tipos, y "con opciones" abria OTRA modal encima con OTRA
   vista previa. Ahora la pestania dice la CLASE y el segmentado la FORMA, y el editor de
   opciones se monta aqui mismo. */

/* EL RITMO VERTICAL, en la escala de 8. Estaba en 12 / 11 / 14 px: tres huecos distintos
   entre cosas que se leen como una secuencia, y eso se nota aunque nadie sepa decir por que.

   La jerarquia es la que manda el numero: 16 px entre BLOQUES (las pestanias, el segmentado,
   los campos) y los 12 px que ya usa `.modal-field` DENTRO de un bloque. Mas separacion entre
   grupos que entre hermanos es lo que hace que se lean como grupos. */

/* El editor de opciones montado dentro pierde su maquetacion de modal: aqui ya esta en una
   columna con su ancho, y sus dos columnas propias lo partirian por la mitad otra vez. */
.qr-edit-modal .ed-form #inter-form .inter-cols { display: block; }

/* LOS CHIPS DE VARIABLE VAN PEGADOS A SU CAMPO, no sueltos al final del formulario. Cuando
   habia una sola fila daba igual donde estuviera; con una por campo, la distancia es lo que
   dice a cual pertenece cada una. */
.modal-field > .qr-vars {
  margin-top: 6px;
}

/* El texto de la conversacion exportada (item A56), para cuando el navegador no deja copiar
   solo y hay que seleccionarlo a mano. Monoespaciado porque lleva JSON de herramientas, y con
   techo de alto para que la ventana no crezca hasta salirse de la pantalla. */
.qr-exportado {
  width: 100%;
  height: 340px;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 11.5px;
  line-height: 1.45;
  white-space: pre;
  overflow: auto;
}

/* --- Los huecos que rellena una persona (item B48) --------------------------------- */

/* EL TEXTO DEL MODAL ES EL MENSAJE, no un formulario al lado: se rellena escribiendo dentro
   de la propia frase, que es lo que deja ver cómo va a quedar mientras se escribe. Por eso
   conserva los saltos de línea del original (`pre-wrap`) y se lee como se va a enviar.

   El chip en sí lo estiliza `.tmpl-var-chip`, que ya existía para las plantillas de Meta: es
   el mismo gesto y tiene que verse igual, o serían dos cosas distintas que se hacen igual. */
/* El rotulo de la previa y su linea de ayuda. Espaciado en la escala de 4/8/12: el titulo se
   pega a su subtitulo -son la misma frase partida en dos- y es el bloque entero el que separa
   de la burbuja. Sin subtitulo, el titulo carga con ese aire el solo. */
.qr-enviar-tit {
  margin: 0 0 4px;
  font-size: 15px;
  font-weight: 700;
}
.qr-enviar-sub { margin: 0 0 12px; }
.qr-enviar-tit + .huecos-texto { margin-top: 12px; }

/* LA DIRECCION DEL ENLACE, EN LA MODAL DE ENVIO (item B94).
   Va FUERA del globo y con su rotulo porque el cliente NO LA VE: dentro se leeria como parte
   del mensaje y la previa estaria mintiendo, que es lo unico que una previa no puede hacer.
   Se viste como una ficha aparte -fondo distinto, monoespaciada- para que ni de reojo se
   confunda con lo que se envia. */
.qr-enviar-url {
  display: flex;
  flex-direction: column;
  gap: 3px;
  margin-top: 10px;
  padding: 8px 10px;
  border: 1px dashed var(--border-strong);
  border-radius: 8px;
  background: var(--bg-elev);
}
.qr-enviar-url-et {
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .3px;
  text-transform: uppercase;
  color: var(--text-dim);
}
/* MONOESPACIADA Y QUE PARTA POR DONDE SEA: una URL larga sin `overflow-wrap` empuja la modal
   a lo ancho y en el movil se sale de la pantalla. */
.qr-enviar-url-val {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--text);
  overflow-wrap: anywhere;
}

/* LA PREVIA ES LO QUE SE EDITA: los huecos viven DENTRO de la burbuja de verdad, con su
   boton y su tarjeta. Una lista de campos rotulados dice QUE se envia; no dice COMO SE VE, y
   "asi le llega al cliente" es las dos cosas (me lo corrigio el).

   Asi que esta caja no pinta nada propio: deja que la previa se vea tal cual y el marco lo
   trae ella.

   Y NO LLEVA SCROLL PROPIO. Tenia `max-height: 46vh` + `overflow-y: auto`, y como
   `.modal-body` ya scrollea, quedaban DOS BARRAS ANIDADAS: la rueda mueve una u otra segun
   donde este el raton, no se sabe cual se ha llegado al final, y con el teclado se navega la
   que tenga el foco. El lo pidio como regla: *"es mejor que el scroll no sea en el wa-prev,
   si no en el container, y solo el externo, no doble scroll [...] (no repetir: no dejar dos
   scroll en una modal)"*.

   El alto lo acota la modal, que es quien sabe cuanto cabe en la pantalla. */

/* El aviso de los dos grupos, bajo el campo del mensaje rápido. Va en dos renglones y no en
   uno porque la distinción ES el contenido: lo que se rellena solo y lo que te van a pedir. */
/* Los chips de las variables que rellena una persona van EN LA MISMA FILA que los del
   catalogo, en ambar: puestas aparte habia que volver a teclear el nombre, y una letra
   distinta las convierte en dos preguntas distintas (item B52, diseno suyo). */
.qr-var-mano {
  background: var(--warn-bg);
  color: var(--warn);
  border-color: var(--warn);
}
.qr-vars-nota { flex-basis: 100%; }

/* El rotulo de cada campo dentro del modal que rellena las variables, y el aviso del tope.
   El aviso va JUNTO A SU CAMPO y en vivo: dicho al pulsar Enviar obliga a adivinar cual de
   los cinco textos era, y como toast desaparece justo mientras escribes el valor nuevo. */
.huecos-rotulo {
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--text-dim);
  margin: 10px 0 2px;
}
.huecos-rotulo:first-child { margin-top: 0; }
.huecos-linea + .huecos-rotulo { margin-top: 12px; }
.huecos-tope {
  margin-top: 4px;
  font-size: 11.5px;
  color: var(--warn);
}

/* La que se rellena sola llega con su valor puesto: se distingue de un hueco vacio para que
   se vea de un vistazo que ahi no hay nada pendiente, solo algo que se PUEDE retocar. */
.tmpl-var-chip.tmpl-var-auto {
  background: var(--accent-dim);
  color: var(--text);
  box-shadow: inset 0 0 0 1px var(--accent);
}

/* En una difusión (B132) las automáticas dependen de cada destinatario: salen con su rótulo,
   en gris y sin poder escribirse, para que no parezca un hueco pendiente. */
.tmpl-var-chip.tmpl-var-fija {
  background: var(--bg-hover);
  color: var(--text-dim);
  box-shadow: inset 0 0 0 1px var(--border);
  font-style: italic;
  cursor: default;
}

/* EL TIRON AL LLEGAR AL TOPE (item B52, pedido suyo). Sin el, la tecla no hace nada y parece
   que el teclado se colgo; el tiron dice "te he leido, pero ahi ya no cabe" — es lo mismo que
   hace un movil al llegar al final de una lista.

   ES UNA ANIMACION Y NO UNA TRANSICION disparada por codigo: una transicion que no llega a
   arrancar deja el elemento con estilos a medias para siempre, y una animacion, corra o no,
   termina en el estado natural. */
.tmpl-var-chip.tmpl-var-tope {
  animation: tironTope .18s ease;
}
@keyframes tironTope {
  0%   { transform: translateX(0); }
  30%  { transform: translateX(3px); }
  60%  { transform: translateX(-2px); }
  100% { transform: translateX(0); }
}

@media (prefers-reduced-motion: reduce) {
  .tmpl-var-chip.tmpl-var-tope { animation: none; }
}
