/* Mobile primero: la mayoría de los presupuestos se arman desde el celular,
   en el depósito o en lo del cliente. El escritorio es la excepción, no al
   revés.

   Los colores y las tipografías salen del manual de marca de HOMIQ
   (source/marca/MARCA.md). No inventar valores nuevos acá: si hace falta un
   tono que no está en la paleta, derivarlo con color-mix() del que
   corresponda, así sigue siendo el mismo azul. */

/* Open Sans es la tipografía secundaria de la marca y acá hace el trabajo
   pesado: es la que se lee mejor en pantallas chicas. Se sirve desde la
   propia app y no desde Google: la app tiene que funcionar sin internet, y
   además no hay por qué contarle a Google quién abre un presupuesto. */
@font-face {
  font-family: 'Open Sans'; font-style: normal; font-weight: 400;
  font-display: swap; src: url('/fuentes/OpenSans-400-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Open Sans'; font-style: normal; font-weight: 400;
  font-display: swap; src: url('/fuentes/OpenSans-400-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Open Sans'; font-style: normal; font-weight: 600;
  font-display: swap; src: url('/fuentes/OpenSans-600-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Open Sans'; font-style: normal; font-weight: 600;
  font-display: swap; src: url('/fuentes/OpenSans-600-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0,
    U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Open Sans'; font-style: normal; font-weight: 700;
  font-display: swap; src: url('/fuentes/OpenSans-700-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Open Sans'; font-style: normal; font-weight: 700;
  font-display: swap; src: url('/fuentes/OpenSans-700-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0,
    U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* MAAX es la tipografía principal de la marca, pero es comercial y no se
   puede redistribuir. Los .ttf están en el Drive de HOMIQ; ver
   source/marca/fuentes/LEEME.md para instalarlos. Mientras no estén, los
   títulos caen a Open Sans 700, que sigue siendo tipografía de marca — se
   nota menos de lo que parece. */
@font-face {
  font-family: 'Maax'; font-style: normal; font-weight: 500;
  font-display: swap; src: url('/fuentes/Maax-Medium.ttf') format('truetype');
}
@font-face {
  font-family: 'Maax'; font-style: normal; font-weight: 700;
  font-display: swap; src: url('/fuentes/Maax-Bold.ttf') format('truetype');
}

:root {
  /* --- Paleta institucional HOMIQ --- */
  --blanco:        #FCFCFC;  /* White       */
  --azul-hielo:    #DFE6EC;  /* Alice Blue  */
  --azure:         #007AFF;  /* Azure       */
  --gris-cadete:   #95A4B9;  /* Cadet Gray  */
  --glauco:        #5F7696;  /* Glaucous    */
  --negro-pasa:    #1F212D;  /* Raisin Black*/

  /* --- Roles --- */
  --fondo:   #F2F5F8;
  --panel:   var(--blanco);
  --panel-2: #F6F8FA;
  --tinta:   var(--negro-pasa);
  --suave:   var(--glauco);
  /* El gris de marca (Cadet Gray) da 2,47:1 sobre blanco: por debajo incluso
     del mínimo para texto grande, y acá se usa en textos de 11 y 12 px. Juan
     lo marcó el 2026-09-27: «la font gris clara hace que no veas nada».
     Éste da 4,64:1 y pasa el mínimo para texto normal.
     `--gris-cadete` sigue intacto para lo que NO es texto —bordes, chips,
     decoración—, que es donde el manual de marca lo pide. */
  --tenue:   #64748B;
  --linea:   var(--azul-hielo);
  --acento:  var(--azure);
  --acento-tinta: #FFFFFF;

  /* Semánticos: son otra familia que el acento a propósito. Si "aceptado"
     fuera azul como el botón principal, el estado dejaría de leerse de un
     golpe de vista. Van desaturados para convivir con el azul de marca. */
  --ok:          #0F7B52;
  --ok-fondo:    #E4F2EB;
  --alerta:      #8A5200;
  --alerta-fondo:#FBF0DF;
  --error:       #AE2B25;
  --error-fondo: #FBE9E7;

  --sombra: 0 1px 2px rgba(31,33,45,.05), 0 6px 20px rgba(31,33,45,.07);
  --radio: 12px;
  --barra-abajo: 62px;

  /* --- Tipografía --- */
  --fuente-titulos: 'Maax', 'Open Sans', -apple-system, BlinkMacSystemFont,
                    'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  --fuente-texto:   'Open Sans', -apple-system, BlinkMacSystemFont,
                    'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  --fuente-datos:   ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}

/* El tema oscuro invierte los roles sin salirse de la paleta: el fondo pasa a
   ser el Raisin Black de la marca. El Azure puro pierde contraste sobre
   oscuro, así que se aclara — es el mismo tono, más luminoso. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --fondo:   #14161F;
    --panel:   var(--negro-pasa);
    --panel-2: #272A38;
    --tinta:   #E8EDF3;
    --suave:   var(--gris-cadete);
    /* En oscuro el anterior (#7C8AA0) ya pasaba con 4,57:1, justo sobre el
       mínimo. Éste da 7,03:1 y se lee cómodo en los textos de 11 px. */
    --tenue:   #9FADC2;
    --linea:   #333749;
    --acento:  #4D9BFF;
    --acento-tinta: #0A1626;

    --ok:          #5FD39B;
    --ok-fondo:    #10291E;
    --alerta:      #F0B876;
    --alerta-fondo:#2B2113;
    --error:       #FF9A91;
    --error-fondo: #2E1816;

    --sombra: 0 1px 2px rgba(0,0,0,.45), 0 6px 20px rgba(0,0,0,.35);
  }
}

:root[data-theme="dark"] {
  --fondo:   #14161F;
  --panel:   var(--negro-pasa);
  --panel-2: #272A38;
  --tinta:   #E8EDF3;
  --suave:   var(--gris-cadete);
  --tenue:   #7C8AA0;
  --linea:   #333749;
  --acento:  #4D9BFF;
  --acento-tinta: #0A1626;

  --ok:          #5FD39B;
  --ok-fondo:    #10291E;
  --alerta:      #F0B876;
  --alerta-fondo:#2B2113;
  --error:       #FF9A91;
  --error-fondo: #2E1816;

  --sombra: 0 1px 2px rgba(0,0,0,.45), 0 6px 20px rgba(0,0,0,.35);
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }

/* La barra de scroll ocupa lugar SIEMPRE, aparezca o no.

   Sin esto, filtrar una lista larga a tres resultados la hace desaparecer, y
   como el contenido va centrado con `margin: 0 auto` todo se corre unos
   píxeles hacia la derecha. Se ve como si la pantalla se reacomodara sola
   mientras escribís. */
html { scrollbar-gutter: stable; }

body {
  margin: 0;
  font: 15px/1.55 var(--fuente-texto);
  background: var(--fondo);
  color: var(--tinta);
  -webkit-font-smoothing: antialiased;
  /* El área segura es por el notch y la barra de gestos del celular. */
  padding-bottom: calc(var(--barra-abajo) + env(safe-area-inset-bottom));
}

h1, h2, h3 {
  margin: 0; font-family: var(--fuente-titulos); font-weight: 700;
  letter-spacing: -.018em; text-wrap: balance;
}
h1 { font-size: 22px; }
h2 { font-size: 17px; }
h3 { font-size: 15px; }
a { color: var(--acento); }

.oculto { display: none !important; }

/* --- Estructura --- */

.encabezado {
  position: sticky; top: 0; z-index: 30;
  background: var(--panel); border-bottom: 1px solid var(--linea);
  /* Sin padding horizontal: ese lo pone el interior, para que coincida con
     el de <main> y las dos columnas queden alineadas al píxel. */
  padding: 12px 0; padding-top: calc(12px + env(safe-area-inset-top));
}
/* La banda de fondo ocupa todo el ancho, pero el título se alinea con la
   columna de contenido. Sin esto, en escritorio el título quedaba pegado a la
   izquierda mientras las tarjetas estaban centradas y nada coincidía.

   El max-width y el padding son LOS MISMOS que los de <main>. Si se cambia
   uno, hay que cambiar los dos o se vuelven a desalinear. */
.encabezado-interior {
  display: flex; align-items: center; gap: 12px;
  width: 100%; max-width: 900px; margin: 0 auto; padding: 0 16px;
}
.encabezado .titulo { flex: 1; min-width: 0; }
.encabezado .titulo h1 { font-size: 18px; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; }
.encabezado .titulo .sub { font-size: 12.5px; color: var(--tenue); }
/* Las acciones de la pantalla, a la derecha del título. Desde la 1.272.0 el
   cotizador pone acá «Descartar» y «Guardar», así que puede haber más de un
   botón y hace falta la separación. No se encogen: el que cede ancho es el
   título, que para eso tiene ellipsis. */
#accion-encabezado { display: flex; gap: 8px; align-items: center; flex-shrink: 0; }

/* --- Selector de tema claro / oscuro ---
   Vive en el encabezado y no en Cuenta porque es algo que se toca cuando a uno
   le molesta la pantalla, no algo que se configure una vez. Desde acá es un
   click esté donde esté.
   En el celular queda sólo el icono: la palabra le robaría el ancho al
   título, que es lo que dice en qué pantalla estás. */
.btn-tema {
  flex-shrink: 0; display: flex; align-items: center; gap: 6px;
  background: var(--panel); border: 1px solid var(--linea); color: var(--tenue);
  border-radius: 99px; padding: 5px 11px 5px 9px; cursor: pointer;
  font: inherit; font-size: 12.5px; font-weight: 600;
}
.btn-tema:hover { color: var(--tinta); border-color: var(--acento); }
.btn-tema svg {
  width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.8;
  stroke-linecap: round; stroke-linejoin: round; flex-shrink: 0;
}
@media (max-width: 720px) {
  .btn-tema .txt { display: none; }
  .btn-tema { padding: 6px; }
}

/* El `width: 100%` no es decorativo y NO se puede sacar.

   `margin: 0 auto` centra, pero en un contenedor grid o flex los márgenes
   automáticos **desactivan el estiramiento** del item: sin un ancho
   explícito, `main` se dimensiona según su contenido (`fit-content`) con
   techo de 900px. Con 285 filas de nombres largos llegaba al techo; al
   filtrar a 7 filas cortas se encogía a ~340px y toda la pantalla se
   reacomodaba mientras se escribía.

   Con `width: 100%` llena la columna, el techo lo pone `max-width` y los
   márgenes sólo centran. El ancho deja de depender de cuántos resultados
   haya. */
main { padding: 16px; width: 100%; max-width: 900px; margin: 0 auto; }

/* Una zona de resultados que no cambia de alto al filtrar.

   Sin el mínimo, pasar de 285 filas a 3 acorta la página de golpe: el scroll
   salta y da la sensación de que todo se encogió. El espacio vacío de abajo
   es mejor que ese salto. */
.zona-resultados { min-height: 55vh; }

.barra-nav {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 40;
  display: flex; background: var(--panel);
  border-top: 1px solid var(--linea);
  padding-bottom: env(safe-area-inset-bottom);
}
.barra-nav button {
  flex: 1; border: 0; background: none; color: var(--tenue);
  font: inherit; font-size: 11px; font-weight: 600;
  padding: 8px 2px 10px; cursor: pointer;
  display: flex; flex-direction: column; align-items: center; gap: 3px;
}
/* Iconos de la barra: SVG, no caracteres.
   Los glifos Unicode que había (☺ para Clientes, ⚙ para Cuenta) iOS los
   dibujaba como EMOJI —amarillos y redondos— en medio de una barra sobria, y
   eso no se puede evitar desde CSS: gana la fuente de emoji del sistema.
   Con `stroke: currentColor` el icono toma el color del estado del botón,
   incluido el azul del que está activo, sin una regla más. */
.barra-nav button .icono { display: flex; line-height: 0; }
.barra-nav button .icono svg {
  width: 22px; height: 22px;
  fill: none; stroke: currentColor; stroke-width: 1.7;
  stroke-linecap: round; stroke-linejoin: round;
}
.barra-nav button[aria-current="page"] { color: var(--acento); }
/* Con siete botones (el séptimo es Cobros) las etiquetas no entran en un
   teléfono angosto: "Presupuestos" a 11px mide más que su sexto de pantalla.
   `min-width: 0` deja que el botón se encoja —sin eso flex usa el ancho del
   contenido como piso— y la elipsis corta en vez de desbordar la barra. */
.barra-nav button { min-width: 0; }
.barra-nav button { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
@media (max-width: 420px) {
  .barra-nav button { font-size: 10px; letter-spacing: -0.2px; padding-inline: 1px; }
}

@media (min-width: 860px) {
  /* `grid-template-rows: auto 1fr`: sin eso, en una pantalla con poco
     contenido el alto sobrante de los 100vh se repartía también en la fila del
     encabezado, que quedaba de 325 px en blanco (se vio en Bancos, 1.69.0; le
     pasaba a cualquier pantalla corta, incluido el «cargando»). */
  body { padding-bottom: 0; display: grid; grid-template-columns: 208px 1fr;
         grid-template-rows: auto 1fr; min-height: 100vh; }
  .encabezado { grid-column: 2; }
  /* El padding del encabezado acompaña al de main: los dos son cajas de
     900px con el mismo padding, así el título cae sobre el borde de las
     tarjetas. */
  .encabezado-interior { padding: 0 24px; }
  main { grid-column: 2; padding: 24px; }
  .barra-nav {
    position: sticky; top: 0; grid-row: 1 / 3; grid-column: 1;
    flex-direction: column; height: 100vh; align-self: start;
    border-top: 0; border-right: 1px solid var(--linea); padding: 16px 10px;
    gap: 2px;
  }
  .barra-nav button { flex: 0 0 auto; flex-direction: row; justify-content: flex-start;
    gap: 10px; font-size: 14px; padding: 10px 12px; border-radius: 9px; }
  .barra-nav button .icono svg { width: 19px; height: 19px; }
  .barra-nav button[aria-current="page"] { background: var(--panel-2); }
  .barra-nav .marca { padding: 4px 12px 16px; font-weight: 700; font-size: 16px; }
}
/* --- Mobile: la barra de abajo es parte del layout, no flota ---------------

   Con `position: fixed; bottom: 0` iOS despega la barra durante el scroll: se
   queda a media pantalla con contenido abajo. Pasa igual en la PWA, y no se
   arregla con trucos de repintado.

   Acá la barra deja de flotar y pasa a ser el último hijo de un body de
   altura fija: `main` scrollea adentro y la barra, simplemente, no se puede
   mover. `dvh` es lo que sigue a la barra de Safari cuando aparece y
   desaparece; `vh` primero, de respaldo para navegadores viejos. */
@media (max-width: 859px) {
  .barra-nav .marca { display: none; }

  body {
    height: 100vh;
    height: 100dvh;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    padding-bottom: 0;
  }

  /* El DOM trae la barra primero (por accesibilidad y por el escritorio);
     en el celular va abajo. */
  .encabezado { order: 1; flex: 0 0 auto; position: static; }
  main {
    order: 2;
    flex: 1 1 auto;
    min-height: 0;              /* sin esto un hijo alto no deja encoger el flex */
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-y: contain;   /* corta el rebote que arrastra la página */
    /* En el celular el que scrollea es `main`, así que el hueco de la barra
       va acá. En iOS la barra es flotante y no ocupa lugar, pero en Android
       sí, y ahí filtrar también corría el contenido. */
    scrollbar-gutter: stable;
  }
  .barra-nav { order: 3; position: static; flex: 0 0 auto; }

}

/* El login es su propia pantalla completa y no convive con la barra.
   **`position: fixed` no es decorativo: sin eso queda de 208px de ancho.**
   A partir de 860px el `body` es una grilla de dos columnas —la barra de
   navegación de 208px y el contenido—, y este div, que no declara columna,
   caía en la PRIMERA. O sea que el login se dibujaba dentro del ancho de la
   barra lateral: tarjeta de 168px, pegada a la izquierda, con el texto partido
   en dos renglones. Lo encontró Juan el 2026-09-27 y se midió: el contenedor
   tenía 208px exactos en una pantalla de 1920.
   Sacarlo del flujo es además lo correcto conceptualmente: es una pantalla que
   TAPA la app, no una sección de ella. */
.pantalla-login {
  position: fixed; inset: 0; z-index: 100;
  display: grid; place-items: center; padding: 24px;
  background: var(--fondo); overflow-y: auto;
}

/* Más grande en escritorio, que es donde se entra todos los días. En el
   celular el tamaño de antes estaba bien: agrandarlo ahí sólo obliga a
   scrollear para llegar al botón. */
@media (min-width: 860px) {
  .pantalla-login .tarjeta { max-width: 420px !important; padding: 34px 32px; }
  .marca-login { height: 42px; margin-bottom: 20px; }
  .titulo-login { font-size: 30px; }
  .sub-login { font-size: 14.5px; margin-bottom: 24px; }
  .pantalla-login .campo input { padding: 12px 13px; font-size: 15.5px; }
  .pantalla-login button[type=submit] { padding: 13px; font-size: 15.5px; }
}

/* El logo se pinta con una máscara y no con <img>: así toma el color del
   tema —tinta en claro, casi blanco en oscuro— con un solo archivo. El SVG
   de marca es monocromo, que es justo lo que esta técnica necesita. */
.marca, .marca-login {
  background-color: currentColor;
  -webkit-mask: var(--logo) no-repeat left center / contain;
  mask: var(--logo) no-repeat left center / contain;
}
.barra-nav .marca {
  --logo: url('/marca/homiq-logotipo.svg');
  height: 30px; margin: 4px 12px 20px; color: var(--tinta);
}
.marca-login {
  --logo: url('/marca/homiq-logotipo.svg');
  height: 38px; width: 130px; margin: 0 0 20px; color: var(--tinta);
}
.titulo-login { margin-bottom: 4px; }
.sub-login { color: var(--tenue); font-size: 13px; margin: 0 0 18px; }

/* El monograma, para donde no entra el logotipo. */
.isotipo {
  display: inline-block; width: 1em; height: 1.55em; vertical-align: -.35em;
  background-color: currentColor;
  -webkit-mask: url('/marca/homiq-isotipo.svg') no-repeat center / contain;
  mask: url('/marca/homiq-isotipo.svg') no-repeat center / contain;
}

/* --- Bloques --- */

.tarjeta {
  background: var(--panel); border: 1px solid var(--linea);
  border-radius: var(--radio); padding: 16px; box-shadow: var(--sombra);
  margin-bottom: 14px;
}
.tarjeta > h2, .tarjeta > h3 { margin-bottom: 10px; }

/* Dos tarjetas lado a lado en pantalla ancha, apiladas en el celular.
   `align-items: start` para que cada una conserve su alto: estiradas al alto
   de la más grande quedaría media tarjeta vacía. El margen de las tarjetas se
   anula porque acá la separación la pone el `gap`. */
.dos-columnas { display: grid; gap: 14px; align-items: start; margin-bottom: 14px; }
.dos-columnas > .tarjeta { margin-bottom: 0; }
@media (min-width: 860px) { .dos-columnas { grid-template-columns: 1fr 1fr; } }
/* Cuando una de las dos mitades no existe —la cotización del dólar sólo sale
   si la lista está en dólares— la que queda ocupa todo en vez de dejar la
   derecha vacía. */
.dos-columnas.una-sola { grid-template-columns: 1fr; }
@media (min-width: 860px) { .dos-columnas.una-sola { grid-template-columns: 1fr; } }
.rotulo { font-family: var(--fuente-titulos); font-size: 11px; font-weight: 700;
  letter-spacing: .12em; text-transform: uppercase; color: var(--tenue);
  margin-bottom: 6px; }

.fila { display: flex; gap: 10px; align-items: center; }
.fila.entre { justify-content: space-between; }
.rejilla { display: grid; gap: 10px; }
@media (min-width: 620px) { .rejilla.dos { grid-template-columns: 1fr 1fr; } }

/* Cifras sueltas que se acomodan solas: tantas por fila como quepan.
   Con `dos` fijo, tres cifras dejaban la mitad de una fila vacía y la
   tarjeta quedaba más alta de lo necesario — se veía en el bloque de Ventas,
   con «Devoluciones» solo abajo y un hueco al lado. `auto-fit` las mete en
   una fila en el escritorio y en dos en el celular, sin media queries. */
.cifras { display: grid; gap: 10px 18px;
  grid-template-columns: repeat(auto-fit, minmax(135px, 1fr)); }

/* --- Accesos directos de la portada --- */
/* Un renglón por grupo, con el rótulo a la IZQUIERDA y los atajos envolviendo
   a su derecha. Apilado —rótulo arriba, atajos abajo— la misma lista medía el
   doble de alto, y el alto de la portada se paga en cada entrada a la app;
   el ancho ya está pago. Abajo de 560px no hay lugar para las dos columnas y
   se apila solo. */
.atajos { display: grid; gap: 2px 14px; }
@media (min-width: 560px) { .atajos { grid-template-columns: max-content 1fr; } }
.atajos .rotulo { margin: 0; padding-top: 9px; }
.atajos .grupo { display: flex; flex-wrap: wrap; gap: 6px; padding-bottom: 8px; }
.atajos .grupo:last-child { padding-bottom: 0; }
a.atajo {
  display: inline-block; text-decoration: none;
  color: var(--suave); font-size: 13px; font-weight: 600;
  background: var(--panel-2); border: 1px solid var(--linea);
  border-radius: 9px; padding: 6px 10px;
}
a.atajo:hover { border-color: var(--acento); color: var(--acento); }

/* --- Elegir la cuenta de Mercado Libre --- */
/* Dos opciones grandes, una al lado de la otra, que pasan a apiladas cuando no
   hay 220px para cada una. Son enlaces y no botones: así se abren en otra
   pestaña con el botón del medio. El mismo bloque va adentro del popup y detrás
   de él, para que cerrarlo no deje una pantalla sin salida. */
.elegir-cuenta { display: grid; gap: 12px;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
.elegir-cuenta a {
  display: block; text-decoration: none; color: inherit; cursor: pointer;
  background: var(--panel-2); border: 1px solid var(--linea);
  border-radius: var(--radio); padding: 18px 20px;
}
.elegir-cuenta a:hover { border-color: var(--acento); background: var(--panel); }
.elegir-cuenta .titular { font-size: 18px; font-weight: 700; }
.elegir-cuenta .cuenta { font-size: 12.5px; color: var(--tenue); margin-top: 3px; }

/* --- Formularios --- */

label { display: block; font-size: 12.5px; font-weight: 600;
  color: var(--suave); margin-bottom: 4px; }

input, select, textarea, button {
  font: inherit; color: var(--tinta);
}
input, select, textarea {
  width: 100%; background: var(--panel-2);
  border: 1px solid var(--linea); border-radius: 9px;
  padding: 11px 12px;
  /* 16px mínimo: abajo de eso Safari hace zoom al enfocar el campo. */
  font-size: 16px;
}
input:focus, select:focus, textarea:focus {
  outline: 2px solid var(--acento); outline-offset: -1px; border-color: var(--acento);
}
textarea { min-height: 78px; resize: vertical; }
input[type="number"] { text-align: right; font-variant-numeric: tabular-nums; }
.campo { margin-bottom: 12px; }

button {
  cursor: pointer; border-radius: 9px; border: 1px solid var(--linea);
  background: var(--panel); padding: 11px 16px; font-weight: 600;
}
button:disabled { opacity: .5; cursor: not-allowed; }
/* Un enlace que se ve como botón. Existe para "Abrir" en Cobros: tiene que
   ser un <a> de verdad y no un button con window.open, porque en el celular
   mantener apretado un enlace da "abrir en pestaña nueva" y "copiar
   dirección", y un botón no. Todos los estilos de botón cuelgan del selector
   de elemento `button`, así que un <a> no los hereda. */
a.boton {
  display: inline-block; text-decoration: none; color: inherit;
  cursor: pointer; border-radius: 9px; border: 1px solid var(--linea);
  background: var(--panel); padding: 11px 16px; font-weight: 600;
}
a.boton.chico { padding: 7px 11px; font-size: 13px; }
button.principal { background: var(--acento); border-color: var(--acento);
  color: var(--acento-tinta); }
button.grande { width: 100%; padding: 15px; font-size: 16px; }
button.chico { padding: 7px 11px; font-size: 13px; }
button.fantasma { background: none; border-color: transparent; color: var(--acento); }
/* Acción importante pero NO la principal de la pantalla.
   Una pantalla tiene un solo botón azul lleno. En «nuevo presupuesto» ese
   lugar es de «Guardar»: si «Agregar producto» también fuera azul lleno, los
   dos compiten y encima quedan uno sobre otro cuando la barra de guardar se
   pega al fondo. */
button.secundario { background: none; color: var(--acento);
  border-color: color-mix(in srgb, var(--acento) 45%, transparent); }
button.secundario:hover { background: color-mix(in srgb, var(--acento) 8%, transparent); }
button.peligro { color: var(--error); }

/* --- Listas de resultados --- */

.lista { border: 1px solid var(--linea); border-radius: var(--radio);
  overflow: hidden; background: var(--panel); }
.lista .item {
  display: flex; gap: 12px; align-items: center; width: 100%;
  padding: 12px 14px; border: 0; border-bottom: 1px solid var(--linea);
  background: none; text-align: left; border-radius: 0; font-weight: 400;
}
.lista .item:last-child { border-bottom: 0; }
.lista .item:hover { background: var(--panel-2); }
.lista .item .cuerpo { flex: 1; min-width: 0; }
.lista .item .principal-txt { font-weight: 600; }
.lista .item .sub { font-size: 12.5px; color: var(--tenue);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lista .item .derecha { text-align: right; white-space: nowrap;
  font-variant-numeric: tabular-nums; }

.miniatura {
  width: 46px; height: 46px; border-radius: 8px; object-fit: cover;
  background: var(--panel-2); border: 1px solid var(--linea); flex: none;
}
.miniatura.vacia { display: grid; place-items: center; color: var(--tenue);
  font-size: 11px; }

.vacio { text-align: center; color: var(--tenue); padding: 32px 16px; }

/* --- Chips de estado --- */

.chip { display: inline-block; font-size: 11.5px; font-weight: 700;
  padding: 3px 9px; border-radius: 99px; background: var(--panel-2);
  color: var(--suave); }
.chip.borrador  { background: var(--panel-2); color: var(--tenue); }
.chip.enviado   { background: #e7effd; color: #14509e; }
.chip.aceptado  { background: var(--ok-fondo); color: var(--ok); }
.chip.rechazado { background: var(--error-fondo); color: var(--error); }
.chip.vencido   { background: var(--alerta-fondo); color: var(--alerta); }
@media (prefers-color-scheme: dark) { .chip.enviado { background: #16243d; color: #8ab4ff; } }
/* MercadoLibre, en su amarillo. Juan lo pidió el 2026-10-02: los mails que
   genera MercadoLibre son ilegibles y larguísimos —46 caracteres de dígitos—
   pero son la única señal de que ese cliente vino de ahí. En vez de mostrar el
   mail se muestra esto, que dice lo mismo y ocupa la décima parte.
   El amarillo es el de la marca (#FFE600) y el texto va oscuro porque sobre
   ese amarillo cualquier otro color no se lee. En oscuro se mantiene igual: es
   un color de marca, no de la paleta de la app. */
.chip.meli { background: #FFE600; color: #2D3277; }
/* Un dato que falta: naranja, el mismo de todo lo que alguien tiene que
   completar. No es un error —nadie se equivocó— es una casilla vacía, y por eso
   no va en rojo. Se usa en la lista de presupuestos para «sin WhatsApp» y «sin
   mail», que son los dos que después frenan algo. */
.chip.falta { background: var(--falta-fondo); color: var(--falta);
  font-size: 10.5px; padding: 2px 7px; vertical-align: 1px; }
@media (prefers-color-scheme: dark) { .chip.meli { background: #FFE600; color: #2D3277; } }

/* Estados de stock. "Sin dato" es gris a propósito: no es lo mismo que no
   haya stock que que no sepamos cuánto hay, y el color no los tiene que
   confundir. */
.chip.st-ok        { background: var(--ok-fondo);     color: var(--ok); }
.chip.st-bajo      { background: var(--alerta-fondo); color: var(--alerta); }
.chip.st-sin_stock { background: var(--error-fondo);  color: var(--error); }
.chip.st-ambiguo   { background: var(--alerta-fondo); color: var(--alerta); }
.chip.st-sin_dato  { background: var(--panel-2);      color: var(--tenue); }

/* Números de stock en la tabla: tabulares para que las columnas se alineen. */
td.num { text-align: right; font-variant-numeric: tabular-nums;
  font-family: var(--fuente-datos); }

/* --- Avisos --- */

.aviso { border-radius: 10px; padding: 11px 13px; font-size: 13.5px;
  margin-bottom: 12px; border: 1px solid transparent; }
.aviso.error { background: var(--error-fondo); color: var(--error);
  border-color: color-mix(in srgb, var(--error) 25%, transparent); }
.aviso.ok { background: var(--ok-fondo); color: var(--ok);
  border-color: color-mix(in srgb, var(--ok) 25%, transparent); }
.aviso.nota { background: var(--alerta-fondo); color: var(--alerta);
  border-color: color-mix(in srgb, var(--alerta) 25%, transparent); }

/* --- Ítems del presupuesto --- */

.item-presu {
  border: 1px solid var(--linea); border-radius: 10px; padding: 12px;
  margin-bottom: 10px; background: var(--panel);
}
.item-presu .cabecera { display: flex; gap: 10px; align-items: flex-start;
  margin-bottom: 10px; }
.item-presu .cabecera .cuerpo { flex: 1; min-width: 0; }
.item-presu .sku { font-family: var(--fuente-datos);
  font-size: 11.5px; color: var(--tenue); }
.item-presu .controles { display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr)) auto;
  gap: 8px; align-items: end; }
.item-presu .controles select { padding: 11px 8px; }
.item-presu .controles label { font-size: 11px; }
.item-presu .importe { font-weight: 700; font-variant-numeric: tabular-nums;
  text-align: right; white-space: nowrap; padding-bottom: 11px; }
@media (max-width: 760px) {
  .item-presu .controles { grid-template-columns: 1fr 1fr; }
  .item-presu .importe { grid-column: 1 / -1; text-align: right; padding: 0;
    border-top: 1px solid var(--linea); padding-top: 9px; margin-top: 2px; }
}

/* --- Totales --- */

.totales { display: grid; gap: 6px; font-variant-numeric: tabular-nums; }
.totales .linea.final { font-family: var(--fuente-titulos); }
.totales .linea { display: flex; justify-content: space-between; gap: 16px;
  color: var(--suave); }
.totales .linea.final { border-top: 2px solid var(--tinta); margin-top: 6px;
  padding-top: 10px; color: var(--tinta); font-size: 21px; font-weight: 700; }
.totales .ref { font-size: 12.5px; color: var(--tenue); }
/* El descuento en el azul de marca: es lo que el cliente busca en el total. */
.totales .linea.descuento { color: var(--acento); font-weight: 600; }

/* Por defecto va en el flujo, al final del formulario. Se pega al fondo sólo
   con la clase `pegada`, que la pone el formulario cuando hay ítems: con el
   presupuesto vacío no hay nada que guardar y flotar ahí sólo tapaba
   «Forma de pago». */
/* `.barra-accion` se borró en la 1.272.0 junto con la barra al pie del
   cotizador: los botones de descartar y guardar se mudaron al encabezado, que
   ya es pegajoso, y ninguna otra pantalla la usaba. Si vuelve a hacer falta una
   barra de acciones, el lugar natural hoy es el encabezado. */

/* --- Gráficos -------------------------------------------------------------

   Sin librería: barras con CSS. Son responsivas sin calcular un viewBox, que
   en el celular es donde se rompen los SVG con ancho fijo.

   Los colores salen de la paleta validada con el script de la guía de
   visualización (checks de banda de luminosidad, piso de croma, separación
   para daltonismo y contraste contra el panel). NO cambiarlos a ojo: el aqua
   más oscuro que probé rompió la separación protan. Los tres de abajo pasan
   todos los checks en claro y en oscuro. */
.viz {
  --s1: #007AFF;   /* azure de marca */
  --s2: #EB6834;   /* naranja */
  --s3: #1BAF7A;   /* aqua */
  --pista: color-mix(in srgb, var(--linea) 70%, transparent);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .viz { --s1: #3987E5; --s2: #D95926; --s3: #199E70; }
}
:root[data-theme="dark"] .viz { --s1: #3987E5; --s2: #D95926; --s3: #199E70; }

/* Columnas: mes a mes, día de la semana. */
.g-cols { display: flex; align-items: flex-end; gap: 3px; height: 150px;
  border-bottom: 1px solid var(--linea); padding-bottom: 0; }
.g-col { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column;
  justify-content: flex-end; height: 100%; background: none; border: 0;
  padding: 0; cursor: pointer; }
/* Extremo redondeado de 4px y anclado a la base, como pide la guía. */
.g-col i { display: block; background: var(--s1); border-radius: 4px 4px 0 0;
  min-height: 2px; transition: background .12s; }
/* El importe encima de cada columna. Va en millones y sin unidad —la aclara
   el rótulo— porque con trece columnas en un teléfono "$ 87,9 M" no entra y
   "88" sí. */
.g-cima { display: block; font-size: 9px; line-height: 1.2; color: var(--tenue);
  font-variant-numeric: tabular-nums; margin-bottom: 3px;
  overflow: hidden; white-space: nowrap; }
.g-col[aria-pressed="true"] .g-cima { color: var(--tinta); font-weight: 700; }
.g-col[aria-pressed="true"] i { background: var(--tinta); }
.g-cols-pies { display: flex; gap: 3px; margin-top: 5px; }
.g-cols-pies span { flex: 1 1 0; min-width: 0; text-align: center;
  font-size: 9.5px; color: var(--tenue); overflow: hidden; }

/* Barras horizontales: cómo pagan, de dónde vienen, top clientes. */
.g-filas { display: grid; gap: 9px; }
.g-fila { display: grid; grid-template-columns: 1fr auto; gap: 2px 10px;
  align-items: baseline; }
.g-fila .et { font-size: 12.5px; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; }
.g-fila .va { font-size: 12.5px; font-weight: 600;
  font-variant-numeric: tabular-nums; white-space: nowrap; }
.g-fila .pista { grid-column: 1 / -1; height: 7px; background: var(--pista);
  border-radius: 4px; overflow: hidden; }
.g-fila .pista i { display: block; height: 100%; background: var(--s1);
  border-radius: 4px; }

/* Barra apilada: el reparto entre facturado, sin factura y devoluciones.
   El hueco de 2px entre segmentos es de la guía: sin él, dos fills contiguos
   se leen como uno. */
.g-apilada { display: flex; height: 13px; border-radius: 4px; overflow: hidden;
  gap: 2px; background: var(--pista); }
.g-apilada i { display: block; height: 100%; min-width: 3px; }
.g-leyenda { display: flex; flex-wrap: wrap; gap: 4px 16px; margin-top: 10px;
  font-size: 12px; }
.g-leyenda span { display: inline-flex; align-items: center; gap: 6px; }
.g-leyenda b { width: 9px; height: 9px; border-radius: 3px; flex: none; }

/* --- Modal --- */

.modal-fondo {
  position: fixed; inset: 0; background: rgba(8,10,14,.5); z-index: 60;
  display: flex; align-items: flex-end; justify-content: center;
  padding: 0; backdrop-filter: blur(2px);
}
.modal {
  background: var(--panel); width: 100%; max-width: 560px;
  /* Menos aire arriba: con el encabezado fijo, esos 18px eran una banda
     blanca antes del contenido. */
  border-radius: 16px 16px 0 0; padding: 10px 18px 18px;
  /* dvh por lo mismo que la barra de abajo: con la barra de Safari a la
     vista, 92vh se sale de la pantalla. */
  max-height: 92vh;
  max-height: 92dvh;
  overflow-y: auto;
  padding-bottom: calc(18px + env(safe-area-inset-bottom));
}
@media (min-width: 620px) {
  .modal-fondo { align-items: center; padding: 20px; }
  .modal { border-radius: var(--radio); }
}

/* Un modal para trabajar, no para leer un aviso. La ficha de un comprobante
   tiene una tabla de once columnas adentro: con 560px queda todo apretado y
   con scroll horizontal dentro de un scroll vertical, que es lo peor de los
   dos mundos. */
@media (min-width: 900px) {
  .modal.ancho { max-width: min(1180px, 94vw); padding: 12px 24px 24px; }
  .modal.ancho .dos-columnas { grid-template-columns: repeat(4, 1fr); }
}
/* En un monitor grande no hay razón para dejar la tabla con scroll horizontal
   adentro del modal: se le da el ancho que la tabla necesita y la barra
   desaparece sola. Once columnas con el artículo sin cortar piden ~1.300px;
   el tope es holgado para que un título largo tampoco la reviente. Lo pidió
   Juan el 2026-09-27: «arreglás la barra esa, no hay necesidad de eso,
   hacelo más grande de última». */
@media (min-width: 1400px) {
  .modal.ancho { max-width: min(1600px, 96vw); }
}
.modal.ancho { text-align: left; }
/* Adentro del modal las tarjetas van más juntas y con menos relleno: son
   cinco o seis apiladas y cada 6px de más se multiplica por seis. La idea es
   que la ficha entre sin scroll (Juan, 2026-09-27). */
.modal.ancho .tarjeta { margin-bottom: 10px; padding: 12px 14px; }
.modal.ancho .tarjeta .rotulo { margin-bottom: 6px; }
/* **El encabezado del modal queda FIJO arriba.**
   La cruz se iba con el scroll y no había otra forma evidente de salir: en
   una ficha de comprobante, que es larga, quedabas abajo sin saber cómo
   cerrar (Juan, 2026-09-27: «la cruz, si scrolleás, desaparece y no es
   intuitivo cómo salir»). Con `sticky` acompaña, y el fondo propio evita que
   el contenido se lea por debajo.

   El margen de abajo baja de 14 a 8 y el título se achica: era aire muerto
   antes de lo que se viene a mirar. */
.modal .cabecera-modal { display: flex; justify-content: space-between;
  align-items: center; gap: 12px; margin-bottom: 8px;
  position: sticky; top: 0; z-index: 2;
  background: var(--panel); padding: 2px 0 8px; }
.modal .cabecera-modal h2 { font-size: 16px; }
/* La cruz, más grande y más fácil de acertar que un texto de 13px. */
.modal .cabecera-modal button { font-size: 18px; line-height: 1; padding: 4px 10px; }

/* --- Tabla de mapeo de columnas --- */

.tabla-envoltorio { overflow-x: auto; -webkit-overflow-scrolling: touch;
  border: 1px solid var(--linea); border-radius: 10px; }
table.datos { border-collapse: collapse; width: 100%; font-size: 13px; }
table.datos th, table.datos td { padding: 7px 10px; text-align: left;
  border-bottom: 1px solid var(--linea); white-space: nowrap; }
table.datos th { background: var(--panel-2); font-size: 11px;
  text-transform: uppercase; letter-spacing: .06em; color: var(--tenue); }
table.datos tr:last-child td { border-bottom: 0; }

.cargando { display: inline-block; width: 15px; height: 15px;
  border: 2px solid var(--linea); border-top-color: var(--acento);
  border-radius: 50%; animation: girar .7s linear infinite; }
@keyframes girar { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .cargando { animation-duration: 2s; } }

/* Barra de avance de la descarga de fotos. */
.barra-progreso {
  height: 8px; border-radius: 99px; background: var(--panel-2);
  overflow: hidden; border: 1px solid var(--linea);
}
.barra-progreso .relleno {
  height: 100%; background: var(--acento); border-radius: 99px;
  transition: width .4s ease;
}
@media (prefers-reduced-motion: reduce) { .barra-progreso .relleno { transition: none; } }

/* ── Conciliación ──
   `main` está limitado a 900px para que el texto de las otras pantallas no
   quede larguísimo. En conciliación esa restricción sobra: son 18 columnas.
   Se suelta el ancho de `main` para ESA vista y listo.

   El primer intento fue sacar la tabla del envoltorio con `100vw` y márgenes
   negativos, y quedó mal: en escritorio la navegación es una columna fija a
   la izquierda, así que el ancho disponible es `100vw` MENOS esa columna. La
   tabla se metía abajo del menú y se cortaba. Soltando `main` el navegador
   calcula el ancho real solo. */
main.ancha { max-width: none; }
main.media { max-width: 1200px; }
.ancho-completo { width: 100%; }
/* El encabezado tiene que acompañar o el título queda flotando a la
   izquierda mientras la tabla llega hasta el borde. Los dos comparten
   ancho y padding: es lo que hace que el título caiga justo sobre el borde
   de las tarjetas. */
body.vista-ancha .encabezado-interior { max-width: none; }
body.vista-media .encabezado-interior { max-width: 1200px; }

/* Naranja para el dato que falta: no es un error —nadie se equivocó— es una
   casilla que alguien tiene que completar. El rojo se reserva para lo que
   está mal. */
:root {
  --falta: #B26A00;
  --falta-fondo: #FCF0DC;
}
@media (prefers-color-scheme: dark) {
  :root { --falta: #E0A346; --falta-fondo: #3A2C12; }
}
td.falta, .valor-falta {
  background: var(--falta-fondo);
  color: var(--falta);
  font-weight: 600;
}
td.falta { box-shadow: inset 0 -2px 0 var(--falta); }
.celda-editable { cursor: pointer; }
.celda-editable:hover { background: var(--panel-2); }

table.datos td.num-fuerte { font-weight: 700; font-variant-numeric: tabular-nums; }
table.datos tr.clicable { cursor: pointer; }
table.datos tr.clicable:hover td { background: var(--panel-2); }
table.compacta th, table.compacta td { padding: 6px 8px; font-size: 12.5px; }

/* El encabezado de la tabla de precios queda fijo al hacer scroll.
 *
 * Son 286 renglones y 8 columnas: sin esto, a mitad de la tabla ya no se sabe
 * qué columna es cuál ni por cuál se está ordenando. `background` explícito
 * porque una fila que pase por debajo de un `th` transparente se ve encima.
 * El `z-index` lo deja arriba de las celdas pero no de los modales, que
 * viven mucho más alto. */
table.datos.encabezado-pegado thead th {
  position: sticky; top: 0; z-index: 2; background: var(--panel-2);
}

/* Un chip para DATOS, no para estados.
 *
 * La ficha de una venta de MercadoLibre usaba `borrador` para seis cosas
 * distintas —logística, provincia, medio de pago, seguimiento, estado del
 * envío y etiquetas— y `borrador` es gris claro con texto gris: todo el
 * recuadro quedaba de un solo color y no se distinguía nada. Lo marcó Juan el
 * 2026-09-26: «cuando clickeás en una venta está todo gris».
 *
 * Éste tiene borde y texto legible. Los de estado (aceptado, rechazado,
 * vencido) siguen reservados para lo que ES un estado, que es lo que les da
 * sentido: si todo se pinta, nada resalta. */
.chip.dato {
  background: var(--panel); color: var(--suave);
  border: 1px solid var(--linea); font-weight: 600;
}

/* La primera fila de cada venta lleva una línea más gruesa.
 *
 * La tabla es un renglón por PRODUCTO, así que una venta de tres artículos son
 * tres filas seguidas que parecen tres ventas. Juan el 2026-09-26: «podés
 * hacer una línea más gruesa cuando cambia, como para que los ojos lo lleven
 * mejor». */
table.datos tr.venta-nueva td { border-top: 2px solid var(--borde-venta, #95A4B9); }
table.datos tr.venta-nueva:first-child td { border-top: 0; }

/* --- Bancos: movimientos (1.70.0) ---
   Lista por día en vez de tabla: el nombre de quien manda o recibe es lo que
   se busca con la vista, y en una tabla quedaba perdido en la descripción
   cruda del banco. Colores derivados de la paleta; nada de hex nuevos. */

.mov-filtros { display: flex; flex-direction: column; gap: 10px; }
.mov-filtros .fila { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; }
.mov-filtros .fila .etiqueta { font-size: 11px; font-weight: 700; color: var(--tenue);
  text-transform: uppercase; letter-spacing: .04em; margin-right: 4px; min-width: 64px; }
.pastilla-filtro { border: 1px solid var(--linea); background: var(--panel); color: var(--suave);
  border-radius: 999px; padding: 5px 12px; font-size: 12.5px; font-weight: 600; cursor: pointer;
  min-height: 0; line-height: 1.3; }
.pastilla-filtro[aria-pressed="true"] { background: var(--acento); border-color: var(--acento);
  color: var(--acento-tinta); }
.pastilla-filtro .cuenta { opacity: .7; font-weight: 500; margin-left: 4px; }
.pastilla-filtro.quitar { background: color-mix(in srgb, var(--acento) 12%, var(--panel));
  border-color: color-mix(in srgb, var(--acento) 35%, transparent); color: var(--acento); }

.mov-resumen { display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: 10px; }
.mov-resumen .dato { background: var(--panel-2); border-radius: 12px; padding: 12px 14px; }
.mov-resumen .dato .valor { font-size: 18px; font-weight: 700; font-variant-numeric: tabular-nums; }
.mov-resumen .dato .que { font-size: 11.5px; color: var(--tenue); margin-top: 2px; }

.mov-dia { display: flex; justify-content: space-between; align-items: baseline; gap: 10px;
  padding: 14px 16px 6px; font-size: 12px; font-weight: 700; color: var(--tenue);
  text-transform: uppercase; letter-spacing: .04em; border-top: 1px solid var(--linea); }
.mov-dia:first-child { border-top: 0; }
.mov-dia .neto { font-variant-numeric: tabular-nums; text-transform: none; letter-spacing: 0; }

.mov { display: flex; gap: 12px; align-items: flex-start; padding: 10px 16px; cursor: pointer; }
.mov:hover { background: var(--panel-2); }
.mov-avatar { flex: none; width: 38px; height: 38px; border-radius: 50%; display: grid;
  place-items: center; font-size: 13px; font-weight: 700; letter-spacing: .02em;
  background: color-mix(in srgb, var(--acento) 12%, var(--panel)); color: var(--acento); }
.mov-avatar.entrada { background: var(--ok-fondo); color: var(--ok); }
.mov-avatar.salida  { background: var(--error-fondo); color: var(--error); }
.mov-cuerpo { flex: 1; min-width: 0; }
.mov-nombre { font-weight: 700; font-size: 14px; overflow-wrap: anywhere; }
.mov-nombre .cortado { color: var(--tenue); font-weight: 500; }
.mov-datos { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; margin-top: 4px;
  font-size: 12px; color: var(--suave); }
.pastilla { display: inline-block; border-radius: 999px; padding: 2px 9px; font-size: 11.5px;
  font-weight: 700; background: color-mix(in srgb, var(--acento) 11%, var(--panel)); color: var(--acento); }
.pastilla.gris { background: var(--panel-2); color: var(--suave); font-weight: 600; }
.pastilla.futuro { background: var(--alerta-fondo); color: var(--alerta); }
.mov-id { font-family: var(--fuente-datos); cursor: pointer; border-bottom: 1px dotted var(--tenue); }
.mov-id:hover { color: var(--acento); border-color: var(--acento); }
.mov-monto { text-align: right; flex: none; }
.mov-monto .importe { font-weight: 700; font-size: 15px; font-variant-numeric: tabular-nums; white-space: nowrap; }
.mov-monto .importe.entrada { color: var(--ok); }
.mov-monto .importe.salida  { color: var(--error); }
.mov-monto .saldo { font-size: 11.5px; color: var(--tenue); white-space: nowrap; margin-top: 2px; }
.mov-crudo { margin-top: 6px; font-family: var(--fuente-datos); font-size: 11.5px; color: var(--tenue);
  overflow-wrap: anywhere; }
@media (max-width: 520px) {
  .mov { padding: 10px 12px; gap: 10px; }
  .mov-avatar { width: 32px; height: 32px; font-size: 11.5px; }
}

/* Una venta pagada sin factura subida a MercadoLibre.
 *
 * Es lo único de esa tabla sobre lo que hay que HACER algo, y estaba escondido
 * en un chip que sólo se veía abriendo la venta. Lo pidió Juan el 2026-09-26.
 *
 * El `:hover` pisa al de `clicable` porque si no, al pasar el mouse el
 * renglón perdía el amarillo justo cuando lo estás por tocar. */
table.datos tr.sin-factura td { background: var(--alerta-fondo); }

/* Una venta revisada contra el panel de MercadoLibre y dada por buena.
   Juan la pidió en verde el 2026-09-27: un tilde chico al lado del número no
   se ve barriendo una tabla de 400 filas, y el sentido de la marca es
   justamente poder ver de un vistazo qué está controlado y qué no.

   El amarillo de «sin factura» gana: si una venta está validada PERO le falta
   la factura, lo que hay que hacer es subir la factura. El verde dice «ya está
   mirado» y no manda a hacer nada. */
table.datos tr.validada td { background: var(--ok-fondo); }
table.datos tr.validada.clicable:hover td {
  background: color-mix(in srgb, var(--ok-fondo) 80%, var(--ok));
}
table.datos tr.sin-factura.validada td { background: var(--alerta-fondo); }

/* Marcada como INCORRECTA: alguien la miró y dice que está mal. Rojo, y con
   un filete a la izquierda para que se distinga de la de abajo —que también
   es roja— y para que se encuentre barriendo la tabla con la vista. */
table.datos tr.marcada-mal td { background: var(--error-fondo); }
table.datos tr.marcada-mal td:first-child {
  box-shadow: inset 3px 0 0 var(--error);
}
table.datos tr.marcada-mal.clicable:hover td {
  background: color-mix(in srgb, var(--error-fondo) 80%, var(--error));
}

/* Validada, pero el número cambió desde que se validó. Es lo contrario de una
   tranquilidad: hay que volver a mirarla. */
table.datos tr.validada-cambio td { background: var(--error-fondo); }
table.datos tr.validada-cambio.clicable:hover td {
  background: color-mix(in srgb, var(--error-fondo) 80%, var(--error));
}
table.datos tr.sin-factura.clicable:hover td {
  background: color-mix(in srgb, var(--alerta-fondo) 80%, var(--alerta));
}

/* ---------------------------------------------------------------------------
 * ARCA: pestañas por razón social, gráfico de facturación y límites del
 * monotributo. Barras en el azul de marca; en oscuro, un paso más oscuro
 * (#3D8BFA) porque #4D9BFF queda fuera de la banda de luminosidad para una
 * marca de datos (validado con la guía de visualización, 2026-09-27).
 * ------------------------------------------------------------------------- */
:root { --grafico-barra: #007AFF; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) { --grafico-barra: #3D8BFA; } }
:root[data-theme="dark"] { --grafico-barra: #3D8BFA; }

/* Las pestañas ENVUELVEN en vez de scrollear. Son tres razones sociales y en
   una pantalla angosta quedaba una barra horizontal para ver la tercera: una
   barra para mostrar un botón que entra si se lo deja bajar de renglón (Juan,
   2026-09-27). En el celular, donde de verdad no entran, envolver es mejor que
   esconder la que falta. */
.arca-pestanas { display: flex; gap: 6px; border-bottom: 1px solid var(--linea);
  flex-wrap: wrap; }
.arca-pestanas button { background: none; border: 0; border-bottom: 3px solid transparent; border-radius: 0;
  padding: 10px 14px 8px; color: var(--suave); text-align: left; white-space: nowrap; }
.arca-pestanas button[aria-selected="true"] { color: var(--tinta); border-bottom-color: var(--acento); }
.arca-pestanas .nombre { font-weight: 700; font-size: 15px; }
.arca-pestanas .sub { font-size: 11.5px; color: var(--tenue); font-family: var(--fuente-datos); }

.grafico-barras { position: relative; }
.grafico-barras svg { display: block; width: 100%; height: auto; overflow: visible; }
.grafico-barras .barra { fill: var(--grafico-barra); }
.grafico-barras .barra.en-curso { fill: color-mix(in srgb, var(--grafico-barra) 55%, var(--panel)); }
.grafico-barras .blanco { fill: transparent; cursor: pointer; }
/* La barra no captura el mouse: lo recibe el rectángulo de toda la columna,
 * que es más grande (si no, pasar sobre la barra misma apagaba el tooltip). */
.grafico-barras .barra { pointer-events: none; }
.grafico-barras .barra.encima, .grafico-barras .barra.activa { filter: brightness(1.12); }
.grafico-barras .grilla { stroke: var(--linea); stroke-width: 1; }
.grafico-barras .eje { fill: var(--tenue); font-size: 11px; font-family: var(--fuente-texto); }
.grafico-barras .etiqueta { fill: var(--tinta); font-size: 11px; font-weight: 700; font-family: var(--fuente-texto); }
.grafico-barras .etiqueta.secundaria { font-weight: 600; font-size: 10.5px; }
.grafico-barras .sin-datos { fill: var(--tenue); font-size: 10px; font-family: var(--fuente-texto); }
.grafico-tooltip { position: absolute; pointer-events: none; background: var(--panel); color: var(--tinta);
  border: 1px solid var(--linea); border-radius: 8px; box-shadow: var(--sombra); padding: 6px 9px;
  font-size: 12px; white-space: nowrap; transform: translate(-50%, -100%); margin-top: -8px; z-index: 5; }
.grafico-tooltip .v { font-weight: 700; font-size: 13px; }

.medidor { margin-top: 12px; }
.medidor .fila-medidor { display: flex; justify-content: space-between; gap: 10px; font-size: 12.5px; flex-wrap: wrap; }
.medidor .pista { height: 10px; border-radius: 5px; margin-top: 5px; overflow: hidden;
  background: color-mix(in srgb, var(--medidor, var(--acento)) 16%, var(--panel)); }
.medidor .relleno { height: 100%; border-radius: 5px; background: var(--medidor, var(--acento)); }
.medidor.atencion, .medidor.peligro { --medidor: var(--alerta); }
.medidor.excedido { --medidor: var(--error); }
.estado-mono { display: flex; gap: 10px; align-items: flex-start; border-radius: 10px; padding: 10px 12px; margin-top: 12px; font-size: 13px; }
.estado-mono .icono-estado { font-size: 18px; line-height: 1.1; }
.estado-mono.ok { background: var(--ok-fondo); color: var(--ok); }
.estado-mono.atencion, .estado-mono.peligro { background: var(--alerta-fondo); color: var(--alerta); }
.estado-mono.excedido { background: var(--error-fondo); color: var(--error); }

/* ARCA: el renglón bajo el mouse se marca, para seguir un comprobante de punta a punta. */
.arca-tabla tbody tr:hover td { background: color-mix(in srgb, var(--acento) 8%, var(--panel)); }

/* Bancos (2026-09-28): tarjetas cortas en filas, en el orden que pidió Juan. */
.bancos-fila { display: grid; gap: 12px; margin-top: 12px; grid-template-columns: 1fr; }
@media (min-width: 700px) { .bancos-fila { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1100px) { .bancos-fila { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.bancos-fila .banco-tarjeta { margin: 0; cursor: pointer; border-left: 4px solid var(--rs);
  background: color-mix(in srgb, var(--rs) 7%, var(--panel)); }
/* Un color por razón social (Juan, 2026-09-28). Salen de la paleta: el azul de marca para la SRL y los
   tonos semánticos para las personas, que se distinguen bien entre sí y en el tema oscuro. */
.bancos-fila { --rs: var(--gris-cadete); }
.bancos-fila.rs-srl { --rs: var(--azure); }
.bancos-fila.rs-clara { --rs: var(--ok); }
.bancos-fila.rs-margarita { --rs: var(--alerta); }
.bancos-fila.rs-jorge { --rs: var(--glauco); }
.bancos-rs { grid-column: 1 / -1; margin: 6px 0 -4px; font-size: 12px; font-weight: 700; letter-spacing: .04em;
  text-transform: uppercase; color: var(--rs); }
.bancos-total { margin-top: 16px; display: flex; justify-content: space-between; align-items: center; gap: 12px; flex-wrap: wrap; }

/* Barra de «Actualizar todo»: se llena a medida que terminan las cuentas. */
.pila-fila { display: flex; align-items: center; gap: 12px; margin-top: 10px; }
.pila { flex: 1; max-width: 420px; height: 14px; border-radius: 7px; background: var(--panel-2);
  border: 1px solid var(--linea); overflow: hidden; }
.pila-relleno { height: 100%; width: 0; background: var(--ok); border-radius: 7px; transition: width .6s ease; }

/* ===========================================================================
 * WHATSAPP — las conversaciones de Kommo
 * ===========================================================================
 *
 * Esta pantalla venía de una aplicación aparte con su propia paleta OSCURA y
 * clavada: `--fondo:#0f1218`, sin modo claro posible. Juan: «no me gustan los
 * fondos negros».
 *
 * Acá no se tradujo color por color. Los roles se atan a los tokens
 * institucionales (`--panel`, `--linea`, `--tinta`, `--acento`), así que el
 * tema claro sale solo Y el oscuro de la app también, sin mantener dos
 * paletas. Lo único propio son los cuatro colores de QUIÉN habla, que no
 * existen en la paleta de la app porque ninguna otra pantalla los necesita.
 *
 * Todo va dentro de `.wa`: ni una regla de acá puede tocar otra pantalla.
 * Las clases que la app ya tiene —`.chip`, `.vacio`— se reusan en vez de
 * duplicarse; sólo se agregan los modificadores propios.
 */

.wa {
  /* Quién habla. Cuatro familias bien separadas: si el agente y el bot
     compartieran tono, la pregunta «¿esto lo contestó una persona?» —que es
     para lo que se mira— dejaría de responderse de un golpe de vista.
     Medidos sobre --panel (#FCFCFC): todos por encima de 4,5:1. */
  --wa-cliente: #1E5FBF;   /* azul, distinto del Azure de marca para no confundirse con un botón */
  --wa-agente:  #0F7B52;   /* el verde de --ok: una persona de HOMIQ contestó */
  --wa-bot:     #6A3FB5;   /* violeta */
  --wa-celular: #0E6E86;   /* petróleo: salió del celular, no de la app */

  /* --- El hilo: lienzo y burbujas ---
     Juan, 2026-10-01: «me gusta que la app sea blanca pero me cuesta leer en
     este caso (…) quizá meter alguna azul cada tanto para delimitar».

     Lo que había eran cuatro tintes pastel, uno por cada quién, sobre un
     lienzo del mismo valor. Medido: la burbuja del cliente se separaba del
     fondo del chat en **1,028** — o sea que no se veía, y el hilo entero
     quedaba en una sola banda de luminancia. Y los cuatro tintes tampoco se
     distinguían ENTRE SÍ (1,016 a 1,050): mucho color, ninguna información.

     Ahora: **todas las burbujas blancas sobre un lienzo más hundido**, y el
     color lo lleva el BORDE, del lado del que habló. Eso hace tres cosas de
     una: el texto se lee sobre blanco puro (15,99:1 contra 13,48), cada
     burbuja se despega del fondo (1,154), y el color pasa a ser un ritmo que
     delimita en vez de un lavado — que es justo lo que pedía Juan.

     El rótulo de quién habla sigue en su color y ahora todos pasan cómodos
     sobre blanco: cliente 6,10, agente 5,28, bot 7,02, celular 5,84. */
  --wa-lienzo:  #EBEFF5;   /* el fondo del hilo; 1,154 contra la burbuja blanca */
  --wa-burbuja: var(--panel);

  /* Lo resaltado de la búsqueda de texto. Amarillo y no el acento: el acento
     ya significa «se puede clickear». */
  --wa-marca-fondo: #FFF2C2;
  --wa-marca-tinta: #6B4E00;

  /* --- Legibilidad: por qué esta pantalla tiene sus propios grises ---
     Juan, 2026-10-01: «las letras todas claritas con fondo clarito dificulta
     la vista». Medido, tenía razón y era peor de lo que parecía: el gris
     secundario de la app da 4,64:1, que es el PISO de la norma, y acá se usa
     en textos de 10, 11 y 12 px. Tres pares directamente no llegaban: el texto
     de los chips (4,37), el azul de los enlaces (3,92) y la hora dentro de la
     burbuja (4,01).

     El arreglo de fondo no es «oscurecer el gris». Es que esta pantalla usaba
     el COLOR como única herramienta de jerarquía: todo lo que no era principal
     era el mismo gris, así que para bajarle importancia a algo había que
     aclararlo, y aclararlo es perder contraste. Acá la jerarquía la hacen el
     tamaño y el peso —el nombre va 13 px negrita, la vista previa 12 px
     normal— y entonces el gris puede ser oscuro sin que la vista previa
     compita con el nombre.

     Queda UN gris secundario, a 7:1, en vez de uno al límite. */
  --wa-tenue:  #4C586A;   /* 7,03:1 sobre el panel; 6,24:1 sobre la fila resaltada */
  --wa-enlace: #0063CF;   /* 5,55:1 como texto. El Azure de marca da 3,92 ahí */

  /* El mismo problema al revés, y es el que nadie mira: el Azure de marca
     COMO FONDO con letra blanca da 4,02:1 — tampoco pasa, y es el relleno de
     todos los botones llenos de esta pantalla (Aplicar, Enviar, Ver ahora, el
     embudo abierto, el modo de envío). Un tono más abajo lo lleva a 5,70 sin
     dejar de ser el azul de HOMIQ.
     El borde SÍ sigue siendo el Azure puro: ahí no hay texto encima. */
  --wa-boton: #0063CF;    /* blanco encima: 5,70:1 */

  /* --- Superficies ---
     El otro motivo del cansancio, y el que no se ve mirando un color solo: la
     fila, la fila resaltada y el fondo de la página estaban dentro del 4% de
     luminancia entre sí. La fila seleccionada se separaba de la normal en
     1,038 — o sea, nada. El ojo no tenía de dónde agarrarse.

     Hace falta ~1,10 para distinguir dos superficies pegadas y ~1,25 para que
     un separador se vea. */
  --wa-fila-sel:    #EAEFF5;   /* 1,127 contra la fila normal: se ve */
  --wa-separador:   #D5DEE7;   /* 1,326 contra la fila: se ve sin rayar */

  /* Alto de la zona de trabajo. La lista de conversaciones y el hilo scrollean
     por dentro: lo que NO se quiere es que scrollee la página entera y se vaya
     la lista arriba mientras se lee un chat. */
  --wa-alto: calc(100vh - 210px);

  display: flex;
  flex-direction: column;
  gap: 12px;
}

/* --- La barra de pestañas: lo que antes era el menú de la izquierda ---
   Mismo subrayado que ARCA, para que se lea como «estoy adentro de WhatsApp» y
   no como una segunda barra de navegación de la app. ENVUELVE en vez de
   scrollear: son cinco y en un celular angosto entran en dos filas. */
.wa-cab { display: flex; align-items: flex-end; gap: 12px; flex-wrap: wrap;
  border-bottom: 1px solid var(--linea); }
.wa-pestanas { display: flex; gap: 4px; flex-wrap: wrap; flex: 1; }
.wa-pestanas button {
  background: none; border: 0; border-radius: 0; cursor: pointer;
  border-bottom: 3px solid transparent; padding: 6px 12px 7px;
  color: var(--wa-tenue); font: inherit; text-align: left;
  display: flex; flex-direction: column; gap: 1px;
}
.wa-pestanas button:hover { color: var(--tinta); }
.wa-pestanas button[aria-selected="true"] { color: var(--tinta); border-bottom-color: var(--acento); }
.wa-pestanas .nombre { font-weight: 700; font-size: 14.5px; }
.wa-pestanas .sub { font-size: 11px; color: var(--wa-tenue); }
/* El contador de conversaciones esperando respuesta. Ocupa el lugar del
   subtítulo en vez de sumar uno: es lo mismo que dice, pero con el número. */
.wa-pestanas .pill { font-size: 11px; font-weight: 700; color: var(--alerta); }
/* El toggle Academy / Ventas / Todo, en la cabecera, visible en las cinco
   pantallas. Tres botones pegados, el elegido relleno. Es el mismo filtro
   `linea` del panel: ver elegirLinea() en chats.js. */
.wa-toggle { display: inline-flex; border: 1px solid var(--linea); border-radius: 8px;
  overflow: hidden; margin-bottom: 8px; }
.wa-toggle button { background: var(--panel); border: 0; border-right: 1px solid var(--linea);
  padding: 6px 13px; font: inherit; font-size: 13px; font-weight: 600; cursor: pointer;
  color: var(--wa-tenue); }
.wa-toggle button:last-child { border-right: 0; }
.wa-toggle[hidden] { display: none; }
.wa-toggle button:hover { color: var(--tinta); }
.wa-toggle button[aria-pressed="true"] { background: var(--acento); color: #fff; }
.wa-estado { font-size: 12px; color: var(--wa-tenue); padding-bottom: 8px; }
.wa-estado.error { color: var(--error); font-weight: 600; }

.wa-pantalla { display: none; }
.wa-pantalla.activa { display: flex; flex-direction: column; gap: 14px; }

/* --- Que el tablero de embudos no estire la página entera ---
   Juan mandó una captura del tablero preguntando «me falta la sección de
   Academy». Academy estaba —son tres embudos— y el toggle de línea estaba en
   Ventas. El problema de verdad era que en esa pestaña **el toggle no se podía
   ver ni tocar**. Medido en el navegador a 1500 px de ancho:

     Embudos ......... #toggleLinea en x=4123
     Resumen ......... x=1237
     Conversaciones .. x=1237
     Tabla ........... x=1237

   O sea: existía, el CSS lo daba por visible, y estaba a 2.600 px afuera de la
   ventana. No había forma de enterarse de que el filtro estaba puesto, ni de
   sacarlo.

   LA CAUSA, QUE NO ESTÁ EN ESTE ARCHIVO
   `main#vista` es un item de grid, y un item de grid arranca con
   `min-width: auto`: crece hasta lo que mida su contenido. El tablero de 15
   columnas mide 4.115 px y estiraba la página a 4.371. El `overflow-x: auto`
   que #tablero ya tenía nunca se activaba, porque su padre no le ponía un
   ancho que lo limitara. Es el mismo «no quiero tener que hacer scroll a la
   derecha» de la lista de conversaciones, en otra pestaña.

   Con esto el toggle vuelve a x=1237, la página a 1.485 px sin scroll
   horizontal, y el tablero conserva su propio scroll.

   `main#vista` lo usan TODAS las pantallas de la app, así que se verificaron
   las nueve antes de tocarlo: inicio, presupuestos, clientes, stock, precios,
   cobros, meli, concil y bancos. Ninguna queda con contenido cortado, y
   precios mejora —pasa de 1.615 px con scroll horizontal a 1.485 sin él. */
main#vista { min-width: 0; }
.wa .wa-pantalla { min-width: 0; }

/* --- Barra de mensajes nuevos --- */
.wa #barraNuevos {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  background: var(--alerta-fondo); color: var(--alerta);
  border: 1px solid var(--alerta); border-radius: var(--radio);
  padding: 8px 14px; font-size: 13px; font-weight: 600;
}
.wa #barraNuevos[hidden] { display: none; }
.wa #barraNuevos .quienes { flex: 1; min-width: 0; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; font-weight: 400; }
.wa #barraNuevos > button {
  background: var(--alerta); color: var(--panel); border: 0; padding: 4px 12px;
  border-radius: 7px; cursor: pointer; font: inherit; font-size: 12px; font-weight: 700;
}
/* El resumen se toca y despliega un renglón por chat; tocar uno lo abre. */
.wa #barraNuevos .resumen { flex: 1; min-width: 0; display: flex; gap: 12px; align-items: center;
  cursor: pointer; }
.wa #barraNuevos .lista { flex-basis: 100%; display: flex; flex-direction: column; gap: 2px;
  margin-top: 4px; border-top: 1px solid var(--alerta); padding-top: 6px; }
.wa #barraNuevos .lista[hidden] { display: none; }
.wa #barraNuevos .lista .item { display: flex; gap: 10px; align-items: baseline; width: 100%;
  text-align: left; background: transparent; border: 0; padding: 4px 6px; border-radius: 6px;
  font: inherit; font-size: 13px; color: var(--tinta); cursor: pointer; }
.wa #barraNuevos .lista .item:hover { background: var(--panel); }
.wa #barraNuevos .lista .item b { color: var(--alerta); white-space: nowrap; }
.wa #barraNuevos .lista .item span { color: var(--wa-tenue); font-weight: 400; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* --- Cajas y rejillas ---
   `auto-fit` y no columnas fijas: en el monitor de Juan entran tres y en el
   celular caen una debajo de otra, sin media query. */
.wa .caja { background: var(--panel); border: 1px solid var(--linea);
  border-radius: var(--radio); padding: 14px; box-shadow: var(--sombra); }
.wa .caja h2 { font-size: 11.5px; margin: 0 0 12px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .5px; color: var(--wa-tenue);
  font-family: var(--fuente-titulos); }
.wa .caja h2 small { text-transform: none; letter-spacing: 0; font-weight: 400;
  color: var(--wa-tenue); margin-left: 6px; }
.wa .rejilla { display: grid; grid-template-columns: 2fr 1fr; gap: 14px; }
.wa .rejilla.mitades { grid-template-columns: 1fr 1fr; }
@media (max-width: 1100px) { .wa .rejilla, .wa .rejilla.mitades { grid-template-columns: 1fr; } }

/* --- Lo que hay que hacer ahora --- */
.wa .destacado { display: flex; align-items: center; gap: 18px; flex-wrap: wrap;
  padding: 14px 18px; border-radius: var(--radio);
  border: 1px solid var(--linea); background: var(--panel); box-shadow: var(--sombra); }
.wa .destacado.urgente { border-color: var(--alerta); background: var(--alerta-fondo); }
.wa .destacado .grande { font-size: 38px; font-weight: 700; line-height: 1;
  font-variant-numeric: tabular-nums; font-family: var(--fuente-titulos); }
.wa .destacado.urgente .grande { color: var(--alerta); }
.wa .destacado .txt { flex: 1; min-width: 180px; }
.wa .destacado .txt b { display: block; font-size: 14px; }
.wa .destacado .txt span { color: var(--wa-tenue); font-size: 12px; }
.wa .destacado button { background: var(--wa-boton); color: #FFF;
  border: 0; border-radius: 8px; padding: 8px 16px; font: inherit;
  font-weight: 700; font-size: 12px; cursor: pointer; }

/* --- Selector de línea de negocio --- */
.wa .lineas { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 10px; }
.wa .lineaBtn { background: var(--panel); border: 2px solid var(--linea);
  border-radius: var(--radio); padding: 13px 16px; cursor: pointer;
  text-align: left; color: var(--tinta); font: inherit;
  transition: border-color .12s, background .12s; }
.wa .lineaBtn:hover { background: var(--panel-2); border-color: var(--gris-cadete); }
.wa .lineaBtn.activa { border-color: var(--acento); background: var(--panel-2); }
.wa .lineaBtn .t { font-size: 15px; font-weight: 700; }
.wa .lineaBtn .n { font-size: 26px; font-weight: 700; line-height: 1.2;
  font-variant-numeric: tabular-nums; margin-top: 2px; font-family: var(--fuente-titulos); }
.wa .lineaBtn .s { color: var(--wa-tenue); font-size: 11px; }
.wa .lineaNota { color: var(--wa-tenue); font-size: 11px; }
.wa .lineaNota:empty { display: none; }

/* --- Números del resumen --- */
.wa .kpis { display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: 10px; }
.wa .kpi { background: var(--panel); border: 1px solid var(--linea);
  border-radius: var(--radio); padding: 11px 13px; }
.wa .kpi .n { font-size: 23px; font-weight: 700; line-height: 1.15;
  font-variant-numeric: tabular-nums; font-family: var(--fuente-titulos); }
.wa .kpi .l { color: var(--wa-tenue); font-size: 11px; }
.wa .kpi .delta { font-size: 11px; margin-top: 2px; }
.wa .kpi .delta.sube { color: var(--ok); }
.wa .kpi .delta.baja { color: var(--error); }

/* --- Gráfico de barras en CSS, no en SVG ---
   El SVG anterior estiraba un lienzo de 100x40 a ~900x170 con
   preserveAspectRatio="none": 9x a lo ancho y 4x a lo alto, y con ese estirado
   no uniforme el texto y los bordes salían deformados. */
.wa .graf { display: flex; align-items: flex-end; gap: 2px; height: 150px;
  /* Lugar para la cifra de la barra más alta: la barra llena el 100% de la
     columna y el número queda arriba, en este margen, en vez de recortado.
     24 px y no 12 porque la cifra escalonada (abajo) sube un renglón más. */
  padding-top: 24px; box-sizing: content-box; }
/* `overflow: visible` y no hidden: el recorte cortaba las cifras («1.790» en
   «1.79»). Las puntas redondeadas van en el primer tramo de la barra.
   `container-type: inline-size` deja medir el ancho de la columna desde CSS
   para achicar o escalonar la cifra cuando no entra (ver abajo). */
.wa .graf .col { flex: 1; display: flex; flex-direction: column;
  justify-content: flex-end; height: 100%; cursor: pointer; min-width: 4px;
  container-type: inline-size; }
.wa .graf .col:hover { outline: 1px solid var(--acento); outline-offset: 1px; }
/* `flex-shrink: 0`: si no, cuando la barra llena la columna el flexbox
   acorta la barra para hacerle lugar a la cifra, y entonces todas las barras
   altas quedan con su número a la misma altura, pegado al tope, y se pisan.
   Sin encoger, la cifra sobresale hacia arriba, al margen de .graf. */
.wa .graf .col i { display: block; width: 100%; flex-shrink: 0; }
.wa .graf .col i:first-of-type { border-radius: 3px 3px 0 0; }
/* La cifra arriba de cada barra. Juan: «por cada columna arriba ponele la
   cantidad en números, así entiendo mejor el gráfico».
   `margin-top: auto` la empuja contra el tope de la columna, que es flex en
   columna con justify-content:flex-end — así queda pegada a la barra y no
   flotando arriba de todo. */
.wa .graf .col .cifra {
  font-size: 10px; font-weight: 700; color: var(--wa-tenue);
  text-align: center; line-height: 1.1; margin-top: auto; padding-bottom: 2px;
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
/* Siempre de frente, nunca rotada. La versión anterior giraba la cifra 90°
   cuando la columna era angosta (writing-mode + rotate) y Juan la devolvió el
   2026-10-01: «no quedaron nítidos y se sobreponen». El giro cae en medio
   píxel y sale borroso, y 30 cifras verticales pegadas se pisan entre sí.
   En vez de girar, la cifra mide la columna:
   - hasta 34 px de ancho: letra más chica y apretada;
   - hasta 26 px: además se escalonan, una pegada a la barra y la vecina un
     renglón más arriba, así cada número tiene dos columnas de ancho para sí;
   - hasta 13 px: ni así entra, y se saca. El título de la columna (tooltip)
     sigue teniendo el número.
   Con la pestaña a pantalla ancha (WhatsApp está en ANCHAS en app.js) las
   columnas miden 40-47 px y no hace falta ninguna de las tres. */
@container (max-width: 34px) {
  .wa .graf .col .cifra { font-size: 8.5px; letter-spacing: -.3px; }
}
@container (max-width: 26px) {
  .wa .graf .col:nth-child(even) .cifra { margin-bottom: 10px; }
}
@container (max-width: 13px) {
  .wa .graf .col .cifra { display: none; }
}
/* El gráfico del año necesita más alto: las cifras de arriba se comen espacio
   y con 150px las barras quedaban de dos píxeles. */
.wa .graf.alto { height: 190px; }
.wa-mas { color: var(--ok); font-weight: 700; font-size: 11px; }
.wa .ejeX { display: flex; gap: 2px; margin-top: 5px; }
.wa .ejeX span { flex: 1; text-align: center; font-size: 10px; color: var(--wa-tenue);
  white-space: nowrap; overflow: hidden; min-width: 4px; }
.wa .leyenda { display: flex; gap: 14px; flex-wrap: wrap; font-size: 11px;
  color: var(--wa-tenue); margin-top: 8px; }
.wa .leyenda i { display: inline-block; width: 9px; height: 9px;
  border-radius: 2px; margin-right: 5px; }

/* --- Filas con barra de proporción --- */
.wa .filas { display: flex; flex-direction: column; gap: 9px; }
.wa .fila2 { cursor: pointer; }
.wa .fila2:hover .rotulo { color: var(--acento); }
.wa .fila2 .cab { display: flex; justify-content: space-between; gap: 10px;
  align-items: baseline; font-size: 13px; }
.wa .fila2 .rotulo { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.wa .fila2 .val { color: var(--wa-tenue); font-variant-numeric: tabular-nums;
  flex-shrink: 0; font-size: 12px; }
.wa .fila2 .pista { height: 5px; background: var(--panel-2); border-radius: 3px;
  overflow: hidden; margin-top: 3px; }
.wa .fila2 .pista i { display: block; height: 100%; background: var(--acento); border-radius: 3px; }
.wa .punto { display: inline-block; width: 9px; height: 9px; border-radius: 2px; margin-right: 7px; }

.wa-grande { font-size: 32px; font-weight: 700; line-height: 1; font-family: var(--fuente-titulos); }
.wa-sub { color: var(--wa-tenue); font-size: 12px; margin-top: 2px; }
.wa-nota { color: var(--wa-tenue); font-size: 11px; margin-top: 8px; }
.wa-enlace { color: var(--wa-enlace); font-size: 12px; margin-top: 8px; cursor: pointer; font-weight: 600; }
.wa-tenue { color: var(--wa-tenue); }
.wa-alerta { color: var(--alerta); font-weight: 600; }
.wa-tabla-chica { margin-top: 12px; }

/* --- Etiquetas clickeables --- */
.wa .tags { display: flex; flex-wrap: wrap; gap: 6px; }
.wa .tags button { background: var(--panel-2); border: 1px solid var(--linea);
  color: var(--wa-tenue); border-radius: 99px; padding: 3px 10px; font: inherit;
  font-size: 11px; cursor: pointer; }
.wa .tags button:hover { border-color: var(--acento); color: var(--tinta); }
.wa .tags button b { color: var(--tinta); margin-left: 5px; font-variant-numeric: tabular-nums; }

/* --- Tablas --- */
.wa table { width: 100%; border-collapse: collapse; font-size: 13px; }
.wa th { text-align: left; color: var(--wa-tenue); font-weight: 600; font-size: 10px;
  text-transform: uppercase; letter-spacing: .5px; padding: 0 8px 6px 0; }
.wa th.num, .wa td.num { text-align: right; font-variant-numeric: tabular-nums; }
.wa td { padding: 6px 8px 6px 0; border-top: 1px solid var(--linea); }
.wa tr.clic { cursor: pointer; }
.wa tr.clic:hover td { background: var(--panel-2); }

/* --- Chips ---
   El `.chip` base es el de la app (pastilla, --panel-2) y se reusa, pero su
   texto —--suave sobre --panel-2— daba 4,37:1 y NO pasa el mínimo a 11,5 px.
   Era el peor par de la pantalla, y es el que más se repite: dos o tres chips
   por cada conversación de la lista. */
.wa .chip { color: var(--wa-tenue); }
.wa .chip.debemos  { background: var(--alerta-fondo); color: var(--alerta); }
.wa .chip.difusion { background: #EFE9FA; color: #5A32A3; }
/* A cuál de nuestros dos números escribió. Gris y sin peso: es contexto,
   no un estado de la conversación como «espera respuesta» o «ganado». */
.wa .chip.wa-numero { background: var(--panel-2); color: var(--tenue); }
.wa .chip.academy  { background: #E2F1F5; color: #0E6E86; }
.wa .chip.ventas   { background: var(--ok-fondo); color: var(--ok); }
.wa .chip.proveedores { background: #EFE6FA; color: #5B3A9B; }
.wa .chip.otros    { background: var(--panel-2); color: var(--wa-tenue); }
.wa .chip.ganado   { background: var(--ok-fondo); color: var(--ok); }
.wa .chip.perdido  { background: var(--error-fondo); color: var(--error); }

/* ===================== CONVERSACIONES =====================
   Dos columnas que scrollean por dentro: la lista a la izquierda y el hilo a
   la derecha. Si scrolleara la página, leer un chat largo se llevaría la lista
   fuera de la pantalla y volver atrás sería scrollear hasta arriba. */
.wa #chats.activa { flex-direction: row; gap: 0; height: var(--wa-alto);
  border: 1px solid var(--linea); border-radius: var(--radio);
  overflow: hidden; background: var(--panel); }
.wa #lista { width: 330px; flex-shrink: 0; display: flex; flex-direction: column;
  border-right: 1px solid var(--linea); min-height: 0; }
/* Ancla del panel de filtros: el panel es hijo de esta caja y se posiciona
   contra ella. Si fuera hermano se anclaría al <main> y tomaría el ancho de la
   página entera. */
.wa .filtrosCab { position: relative; }
.wa #detalle { flex: 1; display: flex; flex-direction: column; min-width: 0; min-height: 0; }

/* La cabecera: buscar siempre a la vista, el resto detrás de un botón.
   Es el reparto que importa — buscar por nombre se hace todo el tiempo;
   elegir un embudo, de vez en cuando. */
.wa .filtrosCab { display: flex; align-items: center; gap: 6px; padding: 8px 10px;
  border-bottom: 1px solid var(--linea); }
.wa .filtrosCab input[type="search"] {
  flex: 1; min-width: 0; padding: 7px 10px; border-radius: 8px; font: inherit;
  font-size: 12.5px; border: 1px solid var(--linea); background: var(--panel);
  color: var(--tinta);
}
.wa .filtrosCab input[type="search"]:focus { outline: none; border-color: var(--acento); }
.wa .filtrosCab button {
  flex-shrink: 0; display: flex; align-items: center; gap: 5px;
  background: var(--panel-2); border: 1px solid var(--linea); color: var(--tinta);
  cursor: pointer; font: inherit; font-size: 12.5px; font-weight: 600;
  padding: 7px 11px; border-radius: 8px;
}
.wa .filtrosCab button:hover { border-color: var(--acento); }
.wa .filtrosCab button.abierto { background: var(--wa-boton); color: #FFF;
  border-color: var(--wa-boton); }
/* El contador va adentro del botón: así dice «Filtros 2» de un vistazo, sin
   ocupar un renglón aparte ni depender de que el panel esté abierto. */
.wa .filtrosCab .activos { font-size: 11px; color: #FFF;
  background: var(--wa-boton); border-radius: 99px; padding: 0 6px; font-weight: 700;
  min-width: 17px; text-align: center; }
.wa .filtrosCab button.abierto .activos { background: #FFF; color: var(--wa-boton); }

/* El panel SE SUPERPONE a la lista, no la empuja.
   Antes estaba siempre abierto y se comía 470 px: las conversaciones
   arrancaban más abajo de la mitad de la pantalla. Y es más ancho que la
   columna a propósito: en 330 px los dos campos de fecha quedaban apretados
   contra el borde. */
.wa .filtros {
  position: absolute; top: 100%; left: 0; z-index: 20;
  min-width: 100%; width: 384px; max-width: calc(100vw - 32px);
  padding: 12px; border: 1px solid var(--linea);
  border-radius: 0 0 var(--radio) var(--radio);
  background: var(--panel); box-shadow: var(--sombra);
  display: flex; flex-direction: column; gap: 8px;
}
.wa .filtros.oculto { display: none; }
.wa .filtros input, .wa .filtros select {
  width: 100%; padding: 6px 9px; border-radius: 7px; font: inherit; font-size: 12px;
  border: 1px solid var(--linea); background: var(--panel); color: var(--tinta);
}
.wa .filtros input:focus, .wa .filtros select:focus { outline: none; border-color: var(--acento); }
.wa .filtros .fila { display: flex; gap: 6px; }
.wa .filtros label { font-size: 10px; color: var(--wa-tenue); text-transform: uppercase; letter-spacing: .4px; }
.wa .filtros .primario { flex: 2; padding: 7px; border-radius: 7px; border: 0;
  cursor: pointer; background: var(--wa-boton); color: #FFF;
  font: inherit; font-weight: 700; font-size: 12px; }
.wa .filtros .secundario { flex: 1; padding: 7px; border-radius: 7px; cursor: pointer;
  font: inherit; font-size: 12px; background: var(--panel-2); color: var(--wa-tenue);
  border: 1px solid var(--linea); }

.wa .chipsActivos { display: flex; flex-wrap: wrap; gap: 5px; padding: 8px 12px;
  border-bottom: 1px solid var(--linea); }
.wa .chipsActivos:empty { display: none; padding: 0; border: 0; }
.wa .chipsActivos button { background: var(--panel-2); border: 1px solid var(--linea);
  color: var(--tinta); border-radius: 99px; padding: 2px 8px; font: inherit;
  font-size: 10px; cursor: pointer; }
.wa .chipsActivos button::after { content: ' ×'; color: var(--wa-tenue); }
.wa .chipsActivos button:hover { border-color: var(--error); }

.wa .conteo { padding: 6px 12px; font-size: 11px; color: var(--wa-tenue);
  border-bottom: 1px solid var(--linea); }
.wa #conversaciones { overflow-y: auto; flex: 1; min-height: 0; }
/* La franja de la izquierda dice en qué estado está la conversación, de un
   vistazo y sin leer. Es franja y no fondo a propósito: pintar el renglón
   entero de ámbar hace que la lista se lea como una alarma continua y deja de
   mirarse, que es exactamente lo que pasaba con el cartel que decía 670.

   Sólo se marcan dos estados, y los dos son accionables:
     ámbar = el cliente escribió último, el lead sigue abierto y es reciente
     verde = lead ganado
   «Perdido» NO se marca: ya lo dice su chip y no hay nada que hacer con él. */
.wa .conv { padding: 9px 12px; border-bottom: 1px solid var(--wa-separador);
  cursor: pointer; border-left: 4px solid transparent; }
.wa .conv.espera { border-left-color: var(--alerta); background: var(--alerta-fondo); }
.wa .conv.ganado { border-left-color: var(--ok); }
.wa .conv:hover { background: var(--panel-2); }
.wa .conv.espera:hover { background: var(--alerta-fondo); filter: brightness(.98); }
/* La seleccionada: fondo que de verdad se distingue (1,127 contra la fila)
   más una barra de 4 px. Con --panel-2 la separación era 1,038 y había que
   buscar con la vista cuál estaba abierta. */
/* La seleccionada le gana a cualquier estado: es la que estás leyendo, y si
   una conversación en ámbar no cambiara al abrirla no se sabría cuál es. */
.wa .conv.sel,
.wa .conv.espera.sel { background: var(--wa-fila-sel); border-left-color: var(--acento); }
.wa .conv.sel .nombre { font-weight: 800; }
.wa .conv .fila { display: flex; justify-content: space-between; gap: 8px; align-items: baseline; }
.wa .conv .nombre { font-weight: 700; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.wa .conv .fecha { color: var(--wa-tenue); font-size: 11px; flex-shrink: 0; }
.wa .conv .previo { color: var(--wa-tenue); font-size: 12px; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; }
.wa .conv .chips { display: flex; gap: 4px; margin-top: 4px; flex-wrap: wrap; }
.wa .conv .atendidoPor { font-size: 11px; color: var(--ok); margin-top: 2px; }
/* Origen del lead en la cabecera del chat: Meta/Google con campaña, u Orgánico. */
.wa .chip.wa-origen.pago { background: var(--panel-2); color: var(--tinta); border: 1px solid var(--acento); }
.wa .chip.wa-origen.organico { background: transparent; color: var(--wa-tenue); border: 1px dashed var(--linea); }
/* Pestaña Cuota API: cuánto queda del paquete de envíos del complemento. */
/* Pestaña Seguimientos: una fila por seguimiento, lo vencido arriba. */
.wa #seguimientos { display: none; flex-direction: column; gap: 12px; }
.wa #seguimientos.activa { display: flex; }
.wa .wa-seg-grupo.vencido h2 { color: var(--error); }
.wa .wa-seg-grupo.hoy h2 { color: var(--alerta); }
.wa .wa-seg { display: grid; grid-template-columns: 120px 1fr auto; gap: 12px; align-items: start;
  padding: 8px 0; border-top: 1px solid var(--wa-separador); }
.wa .wa-seg.vencido .cuando { color: var(--error); font-weight: 700; }
.wa .wa-seg.hoy .cuando { color: var(--alerta); font-weight: 700; }
.wa .wa-seg .cuando { font-variant-numeric: tabular-nums; font-size: 13px; }
.wa .wa-seg .hace, .wa .wa-seg .quien { font-size: 11px; color: var(--wa-tenue); }
.wa .wa-seg .cab { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
.wa .wa-seg .nota { margin-top: 3px; white-space: pre-wrap; font-size: 13.5px; }
.wa .wa-seg .resumen { margin-top: 3px; font-size: 12px; color: var(--wa-tenue); }
.wa .wa-seg .c3 { display: flex; gap: 6px; flex-wrap: wrap; justify-content: flex-end; }
.wa .wa-seg .c3 button { padding: 5px 10px; font-size: 12px; }
.wa .wa-seg.cerrado { display: flex; gap: 10px; align-items: baseline; flex-wrap: wrap; font-size: 13px; }
.wa .wa-seg.cerrado .nota { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--wa-tenue); margin: 0; }
@media (max-width: 900px) { .wa .wa-seg { grid-template-columns: 1fr; } }
.wa #cuota { display: none; flex-direction: column; gap: 12px; }
.wa #cuota.activa { display: flex; }
.wa .cuotaBarra { height: 10px; background: var(--panel-2); border-radius: 5px; overflow: hidden; margin: 8px 0 6px; }
.wa .cuotaBarra i { display: block; height: 100%; background: var(--acento); border-radius: 5px; }
.wa .cuotaCaja.alerta .cuotaBarra i { background: var(--error); }
.wa .cuotaAclara { margin-top: 6px; }
.wa .cuotaForm { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-top: 8px; }
.wa .cuotaForm input { width: 200px; }
.wa .cuotaForm button { padding: 7px 14px; border: 0; border-radius: 8px; background: var(--acento); color: #fff;
  font: inherit; font-weight: 600; cursor: pointer; }
.wa .wa-tabla { width: 100%; border-collapse: collapse; font-size: 13px; margin-top: 6px; }
.wa .wa-tabla th { text-align: left; font-size: 10px; text-transform: uppercase; letter-spacing: .5px;
  color: var(--wa-tenue); padding: 4px 8px; border-bottom: 1px solid var(--linea); }
.wa .wa-tabla td { padding: 5px 8px; border-bottom: 1px solid var(--wa-separador); }
.wa .wa-tabla .num { text-align: right; font-variant-numeric: tabular-nums; }
.wa #conversaciones .masLista { display: block; width: 100%; padding: 10px; border: 0;
  background: var(--panel-2); color: var(--acento); font: inherit; font-size: 13px; font-weight: 600;
  cursor: pointer; }
.wa #conversaciones .masLista:hover { filter: brightness(.97); }
.wa #mensajes .masMensajes { align-self: center; padding: 6px 14px; border: 1px solid var(--linea); border-radius: 8px;
  background: var(--panel); color: var(--acento); font: inherit; font-size: 12px; font-weight: 600; cursor: pointer; }
.wa #mensajes .masMensajes:disabled { opacity: .6; cursor: progress; }

/* Resultados de buscar DENTRO del texto de los mensajes */
.wa .hit { padding: 9px 12px; border-bottom: 1px solid var(--wa-separador); cursor: pointer; }
.wa .hit:hover { background: var(--panel-2); }
.wa .hit .cab { display: flex; justify-content: space-between; gap: 8px; font-size: 12px; }
.wa .hit .nombre { font-weight: 700; }
.wa .hit .fecha { color: var(--wa-tenue); font-size: 11px; }
.wa .hit .extracto { font-size: 12px; color: var(--wa-tenue); margin-top: 3px; }
.wa .hit .extracto mark { background: var(--wa-marca-fondo); color: var(--wa-marca-tinta);
  padding: 0 2px; border-radius: 3px; }

.wa #ficha { padding: 10px 16px; border-bottom: 1px solid var(--linea); flex-shrink: 0; }
.wa #ficha[hidden] { display: none; }
.wa #ficha { min-width: 0; }
.wa #ficha .nom { font-size: 16px; font-weight: 700; font-family: var(--fuente-titulos);
  overflow-wrap: anywhere; }
.wa #ficha .meta { color: var(--wa-tenue); font-size: 12px; margin-top: 3px;
  display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
/* Las fechas, con cifras de ancho fijo. En una fila donde conviven texto y
   números, los dígitos proporcionales hacen que dos fechas del mismo largo se
   vean de distinto ancho y la fila se lea irregular. */
.wa #ficha .meta .wa-fecha { font-variant-numeric: tabular-nums; }

/* --- El hilo --- */
.wa #mensajes { flex: 1; overflow-y: auto; min-height: 0; min-width: 0; padding: 16px;
  display: flex; flex-direction: column; gap: 8px; background: var(--wa-lienzo); }
/* El borde de color va del lado del que habló: a la izquierda el cliente, a la
   derecha todo lo que sale de HOMIQ. Leído de arriba abajo, esa franja de
   color es la que deja ver de un vistazo quién llevó la conversación, sin
   leer una palabra. */
.wa .msg { max-width: 66%; min-width: 0; padding: 7px 11px; border-radius: 12px;
  background: var(--wa-burbuja);
  border: 1px solid var(--linea); box-shadow: 0 1px 2px rgba(31,33,45,.06); }
.wa .msg .quien { font-size: 10px; text-transform: uppercase; letter-spacing: .6px;
  font-weight: 700; margin-bottom: 2px; }
/* UNA URL LARGA ENSANCHABA LA PÁGINA ENTERA.
   Un cliente manda `https://registration.cediaexpo.com/...` sin un espacio;
   el texto no corta, la burbuja se estira a 1.556 px, eso estira #mensajes,
   que estira la columna del grid, que estira el encabezado. Resultado: 2.977
   px de ancho en una ventana de 1.500 y scroll horizontal en toda la app.
   Lo marcó Juan el 2026-10-01: «se ensanchó todo, no quiero tener que hacer
   scroll a la derecha».

   Va `anywhere` y NO `break-word`, que es lo que estaba. Los dos cortan la
   palabra al pintar, pero sólo `anywhere` cuenta para el tamaño INTRÍNSECO
   que el navegador usa al repartir el ancho. Con `break-word` la burbuja
   seguía pidiendo el ancho de la URL entera, y `max-width: 66%` no ayudaba
   porque el 66% se calcula sobre un contenedor que ya había crecido. */
.wa .msg .txt { white-space: pre-wrap; overflow-wrap: anywhere; }
.wa .msg .hora { font-size: 10px; color: var(--wa-tenue); margin-top: 3px; text-align: right; }
.wa .msg .sinTexto { font-style: italic; color: var(--wa-tenue); }
/* Buscar dentro del chat: la barra arriba del hilo, y los mensajes que
   coinciden resaltados; los demás se atenúan pero no se ocultan, porque la
   respuesta está en el mensaje de al lado. */
/* «Tenés un presupuesto a medias · Volver»: arriba del hilo, sólo cuando el
   borrador del presupuesto salió de este chat. En el embebido no va: ya
   estás en el presupuesto. */
.wa .volverPresu { display: flex; gap: 10px; align-items: center; padding: 6px 10px; margin-top: 6px;
  border: 1px solid var(--acento); border-radius: 8px; background: var(--panel-2); font-size: 13px; }
.wa .volverPresu button { padding: 4px 10px; border: 0; border-radius: 6px; background: var(--acento);
  color: #fff; font: inherit; font-size: 12px; font-weight: 600; cursor: pointer; }
.wa .volverPresu[hidden], .wa.embebida .volverPresu { display: none; }
.wa .buscarChat { display: flex; gap: 6px; align-items: center; padding: 6px 0; }
.wa .buscarChat input { flex: 1; min-width: 0; max-width: 360px; padding: 6px 9px;
  border: 1px solid var(--linea); border-radius: 8px; font: inherit; font-size: 13px;
  background: var(--panel); color: inherit; }
.wa .buscarChat .n { font-size: 12px; color: var(--wa-tenue); min-width: 56px; }
.wa .buscarChat button { padding: 4px 9px; border: 1px solid var(--linea); border-radius: 6px;
  background: var(--panel); font: inherit; cursor: pointer; color: inherit; }
.wa .buscarChat button:hover { border-color: var(--acento); }
.wa .msg.opaco { opacity: .38; }
.wa .msg.hit { outline: 2px solid var(--alerta); outline-offset: 1px; }
.wa .msg.hitActual { outline-color: var(--acento); box-shadow: 0 0 0 4px var(--panel-2); }
/* Adjuntos dentro de la burbuja (fotos, audios, PDF, video). Ancho acotado
   para que una foto apaisada no se coma la columna; el alto también, para
   que diez fotos seguidas no sean diez pantallas. */
.wa .msg .adj { margin: 2px 0 4px; }
.wa .msg .adj img { display: block; max-width: 100%; max-height: 260px; border-radius: 8px;
  cursor: zoom-in; background: var(--panel-2); }
.wa .msg .adj.sticker img { max-height: 120px; background: transparent; }
.wa .msg .adj audio { display: block; width: 280px; max-width: 100%; height: 36px; }
.wa .msg .adj video { display: block; max-width: 100%; max-height: 300px; border-radius: 8px;
  background: #000; }
.wa .msg .adj a.doc { display: inline-block; padding: 6px 10px; border-radius: 8px;
  background: var(--panel-2); border: 1px solid var(--linea); color: inherit;
  text-decoration: none; font-size: 13px; overflow-wrap: anywhere; }
.wa .msg .adj a.doc:hover { border-color: var(--acento); }
/* La transcripción del audio, debajo del reproductor. Dudosa = confianza < 0,5. */
.wa .msg .adj .transcripcion { margin-top: 4px; padding: 5px 8px; border-left: 2px solid var(--linea);
  font-size: 12.5px; }
.wa .msg .adj .transcripcion .rot { display: block; font-size: 10px; text-transform: uppercase;
  letter-spacing: .5px; color: var(--wa-tenue); margin-bottom: 2px; }
.wa .msg .adj .transcripcion .txt { white-space: pre-wrap; }
.wa .msg .adj .transcripcion.dudosa { opacity: .7; border-left-style: dashed; }
.wa .msg .adj .transcripcion.sinVoz { font-style: italic; color: var(--wa-tenue); }
.wa .msg .adj .transcribirBtn { margin-top: 4px; padding: 3px 9px; border: 1px solid var(--linea); border-radius: 6px;
  background: var(--panel); font: inherit; font-size: 11.5px; cursor: pointer; color: var(--wa-tenue); }
.wa .msg .adj .transcribirBtn:hover { border-color: var(--acento); color: var(--tinta); }
.wa .msg .adj .transcribirBtn:disabled { opacity: .6; cursor: progress; }
.wa .hit .chip.audioHit { background: var(--panel-2); color: var(--wa-tenue); font-size: 10px; }

/* El cliente a la izquierda; todo lo que sale de HOMIQ, a la derecha. Es la
   convención de cualquier app de mensajería y no hay razón para romperla. */
.wa .msg.cliente { align-self: flex-start; border-left: 3px solid var(--wa-cliente); }
.wa .msg.cliente .quien { color: var(--wa-cliente); }
.wa .msg.agente { align-self: flex-end; border-right: 3px solid var(--wa-agente); }
.wa .msg.agente .quien { color: var(--wa-agente); }
.wa .msg.bot { align-self: flex-end; border-right: 3px solid var(--wa-bot); }
.wa .msg.bot .quien { color: var(--wa-bot); }
.wa .msg.app_celular { align-self: flex-end; border-right: 3px solid var(--wa-celular); }
.wa .msg.app_celular .quien { color: var(--wa-celular); }
/* Los 4 mensajes de 176.000 que Kommo no supo atribuir. Se ven como anomalía a
   propósito: clasificarlos a ciegas sería peor que dejarlos visibles. */
.wa .msg.sin-clasificar { background: var(--panel-2); border-style: dashed;
  align-self: center; box-shadow: none; }

.wa .dia { align-self: center; font-size: 11px; font-weight: 600;
  color: var(--wa-tenue); background: var(--panel); border: 1px solid var(--linea);
  padding: 3px 12px; border-radius: 99px; margin: 8px 0; box-shadow: var(--sombra); }

/* --- Compositor --- */
.wa #enviar { border-top: 1px solid var(--linea); background: var(--panel);
  padding: 10px 16px; flex-shrink: 0; }
.wa #enviar[hidden] { display: none; }
.wa #enviar .tabs { display: flex; gap: 6px; margin-bottom: 7px; }
.wa #enviar .tabs button { padding: 4px 12px; font: inherit; font-size: 12px;
  cursor: pointer; border-radius: 7px; background: var(--panel-2);
  color: var(--wa-tenue); border: 1px solid var(--linea); }
.wa #enviar .tabs button.activo { background: var(--wa-boton); color: #FFF;
  border-color: var(--wa-boton); }
.wa #enviar .tabs button:disabled { opacity: .45; cursor: not-allowed; }
.wa #enviar textarea, .wa #enviar input { width: 100%; background: var(--panel);
  color: var(--tinta); border: 1px solid var(--linea); border-radius: 8px;
  padding: 8px 10px; font: inherit; resize: vertical; }
.wa #enviar .adjuntar { display: flex; align-items: center; gap: 8px; margin-top: 6px; font-size: 12px;
  color: var(--wa-tenue); }
.wa #enviar .adjuntar button { padding: 4px 10px; border: 1px solid var(--linea); border-radius: 6px;
  background: var(--panel); font: inherit; font-size: 12px; cursor: pointer; color: inherit; }
.wa #enviar .adjuntar button:hover { border-color: var(--acento); }
.wa #enviar .adjuntar button[hidden] { display: none; }
/* Grabando una nota de voz: punto rojo que late, el tiempo, parar/cancelar,
   y el reproductor para escucharla antes de mandarla. */
.wa #enviar .grabando { display: flex; align-items: center; gap: 10px; margin-top: 6px; font-size: 13px;
  font-variant-numeric: tabular-nums; flex-wrap: wrap; }
.wa #enviar .grabando[hidden] { display: none; }
.wa #enviar .grabando .punto { width: 10px; height: 10px; border-radius: 50%; background: var(--error);
  animation: latir 1s ease-in-out infinite; }
.wa #enviar .grabando button { padding: 4px 10px; border: 1px solid var(--linea); border-radius: 6px;
  background: var(--panel); font: inherit; font-size: 12px; cursor: pointer; color: inherit; }
.wa #enviar .grabando button[hidden], .wa #enviar .grabando audio[hidden], .wa #enviar .grabando span[hidden] { display: none; }
.wa #enviar .grabando audio { height: 34px; max-width: 320px; }
@keyframes latir { 0%, 100% { opacity: 1; } 50% { opacity: .25; } }
/* Embebida en #presupuestar: sólo el hilo. Sin pestañas, sin toggle, sin la
   lista de la izquierda; la conversación ocupa toda la columna. */
.wa.embebida .wa-cab, .wa.embebida #lista, .wa.embebida #barraNuevos { display: none; }
.wa.embebida #chats.activa { height: auto; min-height: 60vh; }
/* Solapa Nota: la misma caja, pero interna. Borde punteado para que se note
   que no sale al cliente. */
.wa #enviar #panelNota textarea { border-style: dashed; }
.wa #enviar #notasRecientes { margin-top: 5px; }
.wa #enviar #notasRecientes:empty { display: none; }
.wa #enviar .notaReciente { margin-top: 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.wa #enviar .notaReciente b { font-weight: 600; color: var(--tinta); }
.wa #enviar .notaReciente button.chico { margin-left: 4px; padding: 0 6px; font-size: 10.5px; border: 1px solid var(--linea);
  border-radius: 4px; background: var(--panel); color: var(--wa-tenue); cursor: pointer; font-family: inherit; }
/* Reloj de la ventana de Meta y seguimientos, en la cabecera del chat. */
.wa .chip.wa-ventana { background: var(--ok-fondo); color: var(--ok); font-variant-numeric: tabular-nums; }
.wa .chip.wa-ventana.porCerrar { background: var(--alerta-fondo); color: var(--alerta); }
.wa .chip.wa-ventana.cerrada { background: var(--panel-2); color: var(--wa-tenue); }
.wa .chip.wa-chip-accion.seguimiento { border-color: var(--alerta); color: var(--alerta); }
.wa .chip.wa-chip-accion.difusiones.apagado { background: var(--error-fondo); color: var(--error); border-color: var(--error); border-style: solid; }
.wa .chip.wa-chip-accion.seguimiento.vencido { background: var(--error-fondo); color: var(--error); border-color: var(--error); }
/* El chip de datos cuando no hay ninguno: presente pero apagado. Tiene que
   verse que la función está y que lo vacío es el dato, no la pantalla. */
.wa-chip-vacio { opacity: .55; }

.wa-atajos { display: flex; gap: 6px; flex-wrap: wrap; margin: 4px 0 6px; }
.wa-atajos button.chico { padding: 3px 9px; font-size: 12px; border: 1px solid var(--linea); border-radius: 6px;
  background: var(--panel); cursor: pointer; font-family: inherit; color: inherit; }
.wa-atajos button.chico:hover { border-color: var(--acento); }
.wa #enviar .pie { display: flex; align-items: center; gap: 10px; margin-top: 7px; }
.wa #enviar .pie button { padding: 7px 18px; border-radius: 8px; border: 0;
  cursor: pointer; background: var(--wa-boton); color: #FFF; font-weight: 700; }
.wa #enviar .pie button:disabled { opacity: .5; cursor: not-allowed; }
.wa .aviso { font-size: 12px; color: var(--wa-tenue); }
.wa .aviso.error { color: var(--error); font-weight: 600; }
.wa .aviso.ok { color: var(--ok); font-weight: 600; }
/* Una aclaración, no un freno: el contacto sin lead se puede atender igual. */
.wa .aviso.nota { color: var(--alerta); }
.wa #vars { display: flex; flex-direction: column; gap: 6px; }
.wa #vars label { font-size: 11px; color: var(--wa-tenue); }

/* ===================== EMBUDOS (tablero) ===================== */
.wa #pipelines.activa { height: var(--wa-alto); gap: 0; }
.wa .pipeBarra { display: flex; align-items: center; gap: 14px; padding: 8px 2px 10px;
  flex-shrink: 0; overflow-x: auto; }
.wa .pipeGrupo { display: flex; align-items: center; gap: 6px; }
.wa .pipeGrupo > b { font-size: 10px; text-transform: uppercase; letter-spacing: .5px;
  color: var(--wa-tenue); margin-right: 2px; }
.wa .pipeGrupo button { background: var(--panel); border: 1px solid var(--linea);
  color: var(--wa-tenue); border-radius: 99px; padding: 4px 12px; font: inherit;
  font-size: 12px; cursor: pointer; white-space: nowrap; }
.wa .pipeGrupo button:hover { color: var(--tinta); border-color: var(--acento); }
/* El embudo abierto. Juan: «cuando abrís, cuál te abre por defecto, lo
   tendrías que colorear para saber y poder cambiar».
   Tres señales a la vez y no una, porque esta barra se mira de reojo mientras
   se busca otra cosa: relleno azul, el nombre en negrita y un anillo que lo
   despega de los de al lado. Con sólo el relleno, a 12 px entre nueve
   pastillas iguales, se pierde. */
.wa .pipeGrupo button.activo {
  background: var(--wa-boton); color: #FFF; border-color: var(--wa-boton);
  font-weight: 700;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--wa-boton) 22%, transparent);
}
.wa .pipeGrupo button.activo:hover { color: #FFF; border-color: var(--wa-boton); }
.wa .pipeGrupo button small { opacity: .75; margin-left: 5px; }
.wa .pipeGrupo button.activo small { opacity: .85; }

.wa #tablero { flex: 1; min-height: 0; overflow-x: auto; overflow-y: hidden;
  display: flex; gap: 10px; padding-bottom: 6px; }
.wa .columna { width: 265px; flex-shrink: 0; display: flex; flex-direction: column;
  background: var(--panel); border: 1px solid var(--linea); border-radius: var(--radio);
  min-height: 0; }
.wa .columna > header { padding: 9px 11px; border-bottom: 1px solid var(--linea);
  flex-shrink: 0; display: flex; align-items: baseline; gap: 8px; }
.wa .columna > header .t { font-size: 12px; font-weight: 700; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; }
.wa .columna > header .n { margin-left: auto; font-size: 11px; color: var(--wa-tenue);
  font-variant-numeric: tabular-nums; flex-shrink: 0; }
.wa .columna.ganado > header { border-bottom-color: var(--ok); }
.wa .columna.ganado > header .t { color: var(--ok); }
.wa .columna.perdido > header { border-bottom-color: var(--error); }
.wa .columna.perdido > header .t { color: var(--error); }
.wa .columna .cuerpo { overflow-y: auto; min-height: 0; padding: 7px;
  display: flex; flex-direction: column; gap: 6px; }
.wa .columna .masCosas { padding: 5px 11px 9px; font-size: 11px;
  color: var(--wa-tenue); text-align: center; }

/* --- Arrastrar para cambiar de etapa ---
   La columna destino se resalta mientras tenés la tarjeta encima; sin eso uno
   suelta a ciegas y no sabe en cuál cayó. Y la tarjeta que se está arrastrando
   se atenúa para que se vea de dónde salió. */
.wa .columna.destino { border-color: var(--acento); background: var(--wa-fila-sel); }
.wa .columna.destino > header { border-bottom-color: var(--acento); }
.wa-tarjeta.arrastrando { opacity: .4; }
.wa-tarjeta[draggable="true"] { cursor: grab; }
.wa-tarjeta[draggable="true"]:active { cursor: grabbing; }

/* --- Cambiar de etapa desde el panel de conversaciones ---
   El chip de embudo/etapa ES el botón: el dato se muestra y el mismo dato lo
   abre. Un botón «Mover» aparte ocuparía lugar sin decir dónde está parado el
   negocio. Se le nota que es clickeable por el borde, no por un color nuevo. */
.wa .wa-chip-accion { border: 1px dashed var(--gris-cadete); cursor: pointer;
  font: inherit; font-size: 11.5px; font-weight: 700; }
.wa .wa-chip-accion:hover { border-style: solid; border-color: var(--acento);
  color: var(--acento); }

/* --- Presupuestar, flotando sobre el hilo ---
   Estaba como un chip más en la fila `.meta` de la ficha y Juan no lo
   encontraba: en un chat con lead y datos cargados hay siete chips antes que
   él, todos del mismo tamaño y del mismo color, así que el ojo no lo separa de
   los que son sólo información. Flotando arriba a la derecha queda en el único
   lugar vacío del encabezado: se ve al abrir cualquier conversación y no agrega
   un renglón, que es lo que Juan pide siempre de las pantallas.

   El espacio se RESERVA con padding en la ficha en vez de dejar que el botón
   tape los chips: con `position: absolute` el botón no empuja nada y los chips
   envuelven, así que sin el padding un chat con muchos chips termina con el
   nombre del embudo abajo del botón. */
.wa #detalle { position: relative; }
.wa:not(.embebida) #ficha { padding-right: 150px; }
.wa .wa-flotante {
  position: absolute; top: 9px; right: 16px; z-index: 3;
  padding: 7px 13px; border: 0; border-radius: 8px;
  background: var(--wa-boton); color: #FFF;
  font: inherit; font-size: 12px; font-weight: 700; cursor: pointer;
  box-shadow: 0 1px 3px rgb(0 0 0 / .18);
}
.wa .wa-flotante:hover { filter: brightness(1.08); }
.wa .wa-flotante[hidden] { display: none; }
/* Embebido en #presupuestar no tiene sentido: ya estás en el presupuesto. */
.wa.embebida .wa-flotante { display: none; }

.wa-rot { display: block; font-size: 10px; text-transform: uppercase;
  letter-spacing: .5px; color: var(--wa-tenue); margin-bottom: 4px; }
.wa-etapas { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 6px; }
.wa-etapa { text-align: left; background: var(--panel); border: 1px solid var(--linea);
  border-radius: 8px; padding: 8px 10px; cursor: pointer; font: inherit;
  color: var(--tinta); display: flex; flex-direction: column; gap: 1px; }
.wa-etapa:hover:not(:disabled) { border-color: var(--acento); }
.wa-etapa .n { font-size: 13px; font-weight: 600; }
.wa-etapa .d { font-size: 11px; color: var(--wa-tenue); }
.wa-etapa.elegida { border-color: var(--wa-boton); background: var(--wa-fila-sel);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--wa-boton) 20%, transparent); }
/* Donde ya está: se muestra para ubicarse, pero no se puede elegir. */
.wa-etapa.aca, .wa-etapa:disabled { opacity: .55; cursor: default; }

/* --- Datos del cliente ---
   Cada renglón dice el dato Y de dónde salió. El origen va chico y tenue a la
   derecha: tiene que estar, pero no competir con el número que se vino a ver. */
.wa-dato { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
  padding: 7px 0; border-bottom: 1px solid var(--linea); }
.wa-dato:last-of-type { border-bottom: 0; }
/* Ventana «Info»: contacto a la izquierda, todos sus leads a la derecha. */
.wa-info { display: grid; grid-template-columns: 1fr 1.2fr; gap: 18px; align-items: start; }
@media (max-width: 900px) { .wa-info { grid-template-columns: 1fr; } }
.wa-info h3 { margin: 0 0 8px; font-size: 15px; }
.wa-info h4 { margin: 14px 0 4px; font-size: 11px; text-transform: uppercase; letter-spacing: .5px; color: var(--wa-tenue); }
.wa-info .wa-dato { padding: 4px 0; }
.wa-info .wa-dato .val { font-size: 13.5px; font-weight: 500; overflow-wrap: anywhere; }
.wa-info .wa-dato .val.vacio { color: var(--wa-tenue); font-weight: 400; }
.wa-info-lead h4 { margin: 8px 0 2px; font-size: 10.5px; text-transform: uppercase; letter-spacing: .5px; color: var(--wa-tenue); }
.wa-info-lead { border: 1px solid var(--linea); border-radius: 8px; padding: 8px 10px; margin-bottom: 10px; background: var(--panel); }
.wa-info-lead.ganado { border-left: 3px solid var(--ok); }
.wa-info-lead.perdido { border-left: 3px solid var(--error); }
.wa-info-lead .cab { display: flex; justify-content: space-between; gap: 8px; align-items: center; margin-bottom: 4px; flex-wrap: wrap; }
.wa-info-lead a.wa-nota { display: inline-block; margin-top: 4px; color: var(--acento); }
/* Notas del cliente, dentro de Info. */
.wa-notas { display: flex; flex-direction: column; gap: 6px; margin-bottom: 8px; }
.wa-nota-item { background: var(--panel-2); border-radius: 8px; padding: 7px 10px; }
.wa-nota-item .txt { white-space: pre-wrap; overflow-wrap: anywhere; font-size: 13.5px; }
.wa-nota-item .pie { display: flex; gap: 8px; align-items: center; margin-top: 4px; font-size: 11px; color: var(--wa-tenue); }
.wa-nota-item .pie span { flex: 1; }
.wa-nota-item .pie button.chico { padding: 1px 7px; font-size: 11px; border: 1px solid var(--linea); border-radius: 5px;
  background: var(--panel); color: var(--wa-tenue); cursor: pointer; font-family: inherit; }
.wa-nota-item .pie button.chico:hover { color: var(--tinta); border-color: var(--acento); }
.wa-info textarea { width: 100%; box-sizing: border-box; padding: 7px 10px; border: 1px solid var(--linea); border-radius: 8px;
  font: inherit; font-size: 13.5px; background: var(--panel); color: inherit; resize: vertical; }
.wa-nota-acciones { display: flex; gap: 8px; align-items: center; margin-top: 6px; flex-wrap: wrap; }
/* Info v2: leads en una línea; detalle del elegido; campos editables. */
.wa-leads { display: flex; flex-direction: column; gap: 3px; margin-bottom: 10px; }
.wa-lead-linea { display: flex; gap: 10px; align-items: center; width: 100%; text-align: left; padding: 5px 9px;
  border: 1px solid var(--linea); border-radius: 7px; background: var(--panel); font: inherit; font-size: 13px;
  cursor: pointer; color: inherit; }
.wa-lead-linea:hover { border-color: var(--acento); }
.wa-lead-linea.elegida { border-color: var(--acento); background: var(--panel-2); }
.wa-lead-linea.ganado { border-left: 3px solid var(--ok); }
.wa-lead-linea.perdido { border-left: 3px solid var(--error); opacity: .75; }
.wa-lead-linea .et { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; }
.wa-lead-linea .val, .wa-lead-linea .fec { color: var(--wa-tenue); font-size: 12px; white-space: nowrap; font-variant-numeric: tabular-nums; }
.wa-lead-linea .chip { font-size: 10px; }
.wa-lead-detalle { border-top: 1px solid var(--linea); padding-top: 8px; }
.wa-lead-detalle .cab { display: flex; justify-content: space-between; gap: 8px; align-items: center; flex-wrap: wrap; margin-bottom: 4px; }
.wa-lead-detalle .cab .acc { display: flex; gap: 10px; align-items: center; }
.wa-lead-detalle .cab .acc button.principal { padding: 5px 12px; font-size: 12px; }
.wa-info .wa-dato.editable { align-items: center; }
.wa-info .wa-dato.editable .val { flex: 1; min-width: 0; padding: 3px 7px; border: 1px solid var(--linea); border-radius: 6px;
  background: var(--panel); font: inherit; font-size: 13px; color: inherit; }
.wa-info .wa-dato.editable.error .val { border-color: var(--error); }
.wa-info .wa-dato.editable .val:disabled { opacity: .6; }
.wa-info .wa-estado-campos:empty { display: none; }
.wa-info .wa-estado-campos { color: var(--ok); margin-top: 4px; }
.wa-arca { margin-top: 8px; }
.wa-arca .wa-dato { flex-wrap: wrap; }
.wa-arca .wa-dato .val.vacio { color: var(--wa-tenue); font-weight: 400; }
.wa-arca .wa-aviso-modal { flex-basis: 100%; margin: 4px 0 0; }
.wa .chip.wa-chip-accion.activo { background: var(--acento); color: #fff; border-style: solid; border-color: var(--acento); }
.wa-dato .rot { min-width: 90px; font-size: 11px; text-transform: uppercase;
  letter-spacing: .5px; color: var(--wa-tenue); }
.wa-dato .val { font-size: 15px; font-weight: 600; font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere; }
.wa-dato .org { font-size: 11px; color: var(--wa-tenue); margin-left: auto; font-style: italic; }

/* El aviso de error adentro de la ventana de confirmación. */
.wa-aviso-modal:empty { display: none; }
.wa-aviso-modal { font-size: 12.5px; margin-bottom: 12px; padding: 8px 10px;
  border-radius: 8px; }
.wa-aviso-modal.error { background: var(--error-fondo); color: var(--error); font-weight: 600; }

/* `wa-tarjeta` y no `tarjeta`: la app ya tiene `.tarjeta` para sus paneles. */
.wa-tarjeta { background: var(--panel-2); border: 1px solid var(--linea);
  border-radius: 8px; padding: 7px 9px; cursor: pointer; }
.wa-tarjeta:hover { border-color: var(--acento); }
.wa-tarjeta.espera { border-left: 3px solid var(--alerta); }
.wa-tarjeta .nom { font-size: 12.5px; font-weight: 700; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; }
.wa-tarjeta .tel { font-size: 10.5px; color: var(--wa-tenue);
  font-variant-numeric: tabular-nums; font-family: var(--fuente-datos); }
.wa-tarjeta .ult { font-size: 11px; color: var(--wa-tenue); margin-top: 3px;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.wa-tarjeta .pie { display: flex; align-items: center; gap: 5px; margin-top: 5px; flex-wrap: wrap; }
.wa-tarjeta .fecha { font-size: 10px; color: var(--wa-tenue); margin-left: auto; }

/* ===================== TABLA ===================== */
.wa #tabla.activa { height: var(--wa-alto); gap: 6px; }
.wa .barraSup { display: flex; align-items: center; flex-shrink: 0; }
.wa .barraSup .der { margin-left: auto; color: var(--wa-tenue); font-size: 12px; }
.wa #tablaScroll { overflow: auto; flex: 1; min-height: 0;
  border: 1px solid var(--linea); border-radius: var(--radio); background: var(--panel); }
.wa #tablaScroll table { font-size: 12.5px; }
.wa #tablaScroll th { position: sticky; top: 0; background: var(--panel); z-index: 1;
  padding: 10px 10px 7px; cursor: pointer; border-bottom: 1px solid var(--linea); }
.wa #tablaScroll th:hover { color: var(--tinta); }
.wa #tablaScroll td { padding: 6px 10px; }
.wa #tablaScroll tr:hover td { background: var(--panel-2); }

/* ===================== AVISOS ===================== */
.wa #avisos.activa { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: 14px; align-items: start; }
.wa .formCaja label { display: block; font-size: 10px; text-transform: uppercase;
  letter-spacing: .5px; color: var(--wa-tenue); margin: 10px 0 4px; }
.wa .formCaja input, .wa .formCaja select { width: 100%; padding: 7px 10px;
  border-radius: 8px; font: inherit; font-size: 13px; border: 1px solid var(--linea);
  background: var(--panel); color: var(--tinta); }
.wa .formCaja input:focus, .wa .formCaja select:focus { outline: none; border-color: var(--acento); }
.wa .formCaja label.check { display: flex; align-items: center; gap: 9px;
  text-transform: none; letter-spacing: 0; font-size: 13px; color: var(--tinta);
  margin: 10px 0 0; cursor: pointer; }
.wa .formCaja label.check input { width: auto; margin: 0; accent-color: var(--acento); }
.wa .formCaja .fila2 { display: flex; gap: 8px; align-items: center; cursor: default; }
.wa .formCaja .fila2 select { flex: 1; }
.wa .formCaja input[type=range] { padding: 0; accent-color: var(--acento); }
.wa .formCaja small.nota { display: block; color: var(--wa-tenue); font-size: 11px; margin-top: 4px; }
.wa .formCaja .msj { font-size: 12px; margin-top: 10px; }
.wa .formCaja .msj.error { color: var(--error); font-weight: 600; }
.wa .formCaja .msj.ok { color: var(--ok); font-weight: 600; }
.wa .accion { background: var(--panel-2); border: 1px solid var(--linea);
  color: var(--wa-tenue); border-radius: 7px; padding: 7px 14px; font: inherit;
  font-size: 12px; cursor: pointer; }
.wa .accion:hover { color: var(--tinta); border-color: var(--acento); }

/* --- En un celular la lista y el hilo no entran al lado ---
   Se apilan y cada uno toma su alto. Es la única media query que hace falta:
   todo lo demás ya usa `auto-fit`. */
@media (max-width: 760px) {
  .wa { --wa-alto: auto; }
  .wa #chats.activa { flex-direction: column; height: auto; }
  .wa #lista { width: auto; border-right: 0; border-bottom: 1px solid var(--linea); }
  .wa #conversaciones { max-height: 45vh; }
  .wa #mensajes { max-height: 60vh; }
  .wa #pipelines.activa, .wa #tabla.activa { height: auto; }
  .wa #tablero { max-height: 70vh; }
  .wa .msg { max-width: 85%; }
}

/* --- Tema oscuro ---
   Los roles ya salen de los tokens de la app, así que acá sólo se redefinen
   los cuatro colores de quién habla y los fondos de burbuja: sobre oscuro los
   tintes claros brillarían y el texto se perdería. Se repite el mismo bloque
   para `prefers-color-scheme` y para `data-theme`, igual que :root. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .wa {
    --wa-cliente: #7FB4FF;
    --wa-agente:  #5FD39B;
    --wa-bot:     #C0A6F5;
    --wa-celular: #6FD2E8;
    /* Mismo criterio que en claro: la burbuja es la superficie elevada y el
       lienzo el fondo hundido. Separación 1,128, y el texto encima 13,58. */
    --wa-lienzo:  #14161F;
    --wa-burbuja: var(--panel);
    --wa-tenue:   #A8B5C7;
    --wa-enlace:  #7FB4FF;
    --wa-boton:   #1F6FD8;
    --wa-fila-sel:  #2A3042;
    --wa-separador: #333749;
    --wa-marca-fondo: #4A3D10;
    --wa-marca-tinta: #FFD98A;
  }
}
:root[data-theme="dark"] .wa {
  --wa-cliente: #7FB4FF;
  --wa-agente:  #5FD39B;
  --wa-bot:     #C0A6F5;
  --wa-celular: #6FD2E8;
  --wa-lienzo:  #14161F;
  --wa-burbuja: var(--panel);
  --wa-tenue:   #A8B5C7;
  --wa-enlace:  #7FB4FF;
  --wa-boton:   #1F6FD8;
  --wa-fila-sel:  #2A3042;
  --wa-separador: #333749;
  --wa-marca-fondo: #4A3D10;
  --wa-marca-tinta: #FFD98A;
}

/* ── Cobros: la tarjeta de cada link (1.190) ──────────────────────────────
   Antes era una línea gris de 11px con todo pegado y el nombre de quién lo
   hizo casi no se veía. Ahora cada dato tiene su casillero con rótulo, a lo
   ancho, para no estirar la tarjeta hacia abajo. */
.cobro-busca { width: 100%; margin-bottom: 10px; }
.cobro-datos {
  display: grid; gap: 8px 16px; margin-top: 10px;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
}
.cobro-rotulo {
  font-size: 10.5px; text-transform: uppercase; letter-spacing: .04em;
  color: var(--tenue);
}
.cobro-valor { font-size: 13px; font-weight: 600; color: var(--tinta); overflow-wrap: anywhere; }
.cobro-quien .cobro-valor { color: var(--acento); }
.cobro-ok .cobro-valor { color: var(--ok); }
.cobro-alerta .cobro-valor { color: var(--alerta); }

/* Bancos: la ruedita de configuración, arriba a la derecha (1.19x). */
.bancos-engranaje { display: inline-flex; align-items: center; justify-content: center; padding: 6px 8px; line-height: 0; }

/* --- Presupuesto con el chat al lado (#presupuestar/<contact_id>) --- */
/* Dos columnas, con la del presupuesto un poco más ancha: es donde se escribe.
   Abajo de 1100px se apilan — el chat primero sería tapar lo que se vino a
   hacer, así que queda abajo. */
.presupuestar { display: grid; gap: 16px; align-items: start; }
@media (min-width: 1100px) {
  .presupuestar { grid-template-columns: 1.15fr 1fr; }
}
/* El chat no puede crecer con la conversación hasta empujar el presupuesto
   fuera de la pantalla: se queda del alto de la ventana y scrollea solo. */
@media (min-width: 1100px) {
  .presupuestar > :last-child {
    position: sticky; top: 12px; max-height: calc(100vh - 90px); overflow: auto;
  }
}
