/* ==========================================================
   CRM - SELECTOR DE COLOR Y CHAT LIGERO

   Va ultimo de todo: son correcciones sobre capas anteriores
   y necesitan ganar en cascada sin ensuciar todo con !important.
   ========================================================== */

/* ==========================================================
   1. SELECTOR DE COLOR PROPIO

   Reemplaza al <input type="color"> nativo, que abria un
   cuadro del sistema operativo con estilo claro imposible de
   tocar y que, al robar el foco, disparaba el click en
   document que cierra el panel: arrastrar el tono cerraba la
   ventana. Este vive adentro y usa las mismas variables.
   ========================================================== */

.ap-personalizado {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    margin-top: 10px;
    font-size: 0.82rem;
    color: var(--text-muted);
}

.ap-muestra {
    width: 34px;
    height: 26px;
    padding: 0;
    border: 1px solid var(--borde-luz, var(--border-color));
    border-radius: 8px;
    background: var(--muestra, var(--primary));
    cursor: pointer;
    transition: border-color 140ms ease;
}

.ap-muestra:hover { border-color: var(--primary); }

.ap-picker {
    margin-top: 10px;
    padding: 10px;
    border: 1px solid var(--borde-luz, var(--border-color));
    border-radius: 12px;
    background: var(--surf-2, rgba(255, 255, 255, 0.04));
}

.ap-picker[hidden] { display: none; }

.ap-picker-campo {
    position: relative;
    height: 118px;
    border-radius: 9px;
    overflow: hidden;
    cursor: crosshair;
    /* Sin esto el navegador se queda el gesto para hacer scroll
       y en pantalla tactil no se puede arrastrar el punto. */
    touch-action: none;
}

.ap-picker-tono,
.ap-picker-blanco,
.ap-picker-negro {
    position: absolute;
    inset: 0;
    pointer-events: none;
}

.ap-picker-blanco { background: linear-gradient(to right, #fff, rgba(255, 255, 255, 0)); }
.ap-picker-negro  { background: linear-gradient(to top, #000, rgba(0, 0, 0, 0)); }

.ap-picker-marca {
    position: absolute;
    width: 13px;
    height: 13px;
    margin: -7px 0 0 -7px;
    border: 2px solid #fff;
    border-radius: 50%;
    box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.5);
    pointer-events: none;
}

.ap-picker-hue {
    width: 100%;
    height: 12px;
    margin: 10px 0 0;
    padding: 0;
    appearance: none;
    -webkit-appearance: none;
    border-radius: 999px;
    background: linear-gradient(to right,
        #f00 0%, #ff0 17%, #0f0 33%, #0ff 50%, #00f 67%, #f0f 83%, #f00 100%);
    cursor: pointer;
}

.ap-picker-hue::-webkit-slider-thumb {
    -webkit-appearance: none;
    width: 15px;
    height: 15px;
    border-radius: 50%;
    background: var(--surf-1, #16181c);
    border: 2px solid #fff;
    box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.5);
}

.ap-picker-hue::-moz-range-thumb {
    width: 15px;
    height: 15px;
    border-radius: 50%;
    background: var(--surf-1, #16181c);
    border: 2px solid #fff;
}

.ap-picker-pie {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 10px;
}

.ap-picker-vista {
    flex: 0 0 24px;
    height: 24px;
    border-radius: 7px;
    border: 1px solid var(--borde-luz, var(--border-color));
}

.ap-picker-hex {
    flex: 1;
    min-width: 0;
    height: 28px;
    padding: 0 9px;
    border: 1px solid var(--borde-luz, var(--border-color));
    border-radius: 8px;
    background: var(--surf-1, rgba(0, 0, 0, 0.25));
    color: var(--text-main);
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-size: 12px;
    text-transform: uppercase;
}

.ap-picker-hex:focus {
    outline: none;
    border-color: var(--primary);
}

/* ==========================================================
   2. CHAT LIGERO

   El panel es una capa fija con scroll propio. Aislarlo evita
   que cada mensaje nuevo obligue a recalcular el diseno de la
   pagina que hay debajo, y el fondo opaco evita componerlo
   contra todo lo que tiene detras en cada repintado.
   ========================================================== */

/* --- El chat es una VENTANA, no un panel lateral ------------

   Antes ocupaba el alto entero de la pantalla y traia un velo
   oscuro detras: eso es un modal, y un modal dice "atende esto
   y despues segui". Una conversacion del equipo no es eso: uno
   escribe mientras mira una consulta. Ahora es una caja chica
   apoyada abajo a la derecha, y el CRM sigue vivo detras. */
html body .chat-panel {
    top: auto !important;
    bottom: 16px !important;
    right: 16px !important;
    width: 340px !important;
    max-width: calc(100vw - 32px) !important;
    /* Alto propio, no el de la pantalla. El minimo evita que con
       dos mensajes quede una ventana ridiculamente chata. */
    height: 460px !important;
    max-height: calc(100vh - 96px) !important;
    min-height: 280px !important;
    border: 1px solid var(--borde-luz, var(--border-color)) !important;
    border-radius: 14px !important;
    overflow: hidden !important;
    box-shadow: 0 12px 40px rgba(0, 0, 0, 0.45) !important;

    /* Entra desde abajo, que es de donde viene la ventana. */
    transform: translateY(calc(100% + 24px)) !important;

    contain: layout paint style;
    will-change: transform;
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
    background: var(--surf-1, #16181c) !important;
}

html body .chat-panel.abierto {
    transform: none !important;
}

/* El velo se va del todo: con la ventana abierta se tiene que
   poder tocar el CRM. Ademas era una capa a pantalla completa
   componiendose sobre el fondo animado. */
html body .chat-fondo {
    display: none !important;
}

/* En el celular no hay lugar para una ventanita: vuelve a ser
   una hoja que sube desde abajo, que es lo que se espera ahi. */
@media (max-width: 560px) {
    html body .chat-panel {
        left: 0 !important;
        right: 0 !important;
        bottom: 0 !important;
        width: 100% !important;
        max-width: 100% !important;
        height: 82vh !important;
        max-height: 82vh !important;
        border-radius: 16px 16px 0 0 !important;
    }
}

html body .chat-mensajes {
    contain: content;
    overscroll-behavior: contain;
    padding: 10px 12px !important;
}

/* La cabecera de una ventana chica no puede medir 64px: se lleva
   un septimo del alto util. */
html body .chat-cabecera {
    height: auto !important;
    flex: 0 0 auto !important;
    padding: 8px 10px 8px 12px !important;
}

html body .chat-titulo strong { font-size: 0.88rem; }
html body .chat-titulo > i { display: none; }
html body .chat-cabecera #chat-estado { font-size: 0.68rem; }

/* El vacio era una tarjeta con su propio fondo flotando dentro
   de la ventana: caja dentro de caja otra vez. */
html body .chat-mensajes .estado-vacio {
    background: none !important;
    border: none !important;
    box-shadow: none !important;
    min-height: 0 !important;
    padding: 1.5rem 1rem !important;
}

html body .chat-mensajes .estado-vacio i { font-size: 1.6rem !important; }
html body .chat-mensajes .estado-vacio strong { font-size: 0.9rem !important; }
html body .chat-mensajes .estado-vacio p { font-size: 0.78rem !important; }

html body .chat-envio {
    flex: 0 0 auto !important;
    padding: 8px 10px !important;
}

html body .chat-fondo {
    transition: opacity 140ms linear !important;
    will-change: opacity;
}

/* ==========================================================
   2b. LA FICHA DE CONSULTA, MAS CHICA

   El modal se comia la pantalla entera para ocho campos: campos
   de 44px, separaciones de seccion entre uno y otro y un
   historial sin techo que lo estiraba sin limite. Se aprieta
   todo sin sacar nada.
   ========================================================== */

/* legibilidad.css fija `.modal-card { max-width: 650px !important }`
   y varias capas mas ponen alturas de control con !important. Para
   ganar sin subir la especificidad a lo bruto, estas van con
   !important a proposito: es la capa final. */
html body #lead-modal .modal-card {
    max-width: 520px !important;
    width: 100% !important;
    max-height: 82vh !important;
    display: flex !important;
    flex-direction: column !important;
    overflow: hidden !important;
    padding: 0.9rem 1rem 1rem !important;
    border-radius: 14px !important;
}

html body #lead-modal .modal-header {
    margin-bottom: 0.7rem !important;
    padding-bottom: 0.5rem !important;
}

html body #lead-modal .modal-header h3 {
    font-size: 0.95rem !important;
}

/* El formulario es lo unico que scrollea: cabecera y botones
   quedan siempre a la vista. */
html body #lead-modal #lead-form {
    display: flex !important;
    flex-direction: column !important;
    overflow-y: auto !important;
    min-height: 0 !important;
    padding-right: 4px;
}

html body #lead-modal .form-row {
    display: grid !important;
    grid-template-columns: 1fr 1fr !important;
    gap: 0.6rem !important;
}

html body #lead-modal .form-group {
    margin-bottom: 0.55rem !important;
}

html body #lead-modal label {
    font-size: 0.72rem !important;
    margin-bottom: 2px !important;
}

html body #lead-modal input,
html body #lead-modal select,
html body #lead-modal textarea {
    min-height: 30px !important;
    height: auto !important;
    padding: 4px 8px !important;
    font-size: 0.8rem !important;
    border-radius: 8px !important;
}

html body #lead-modal textarea {
    min-height: 48px !important;
    resize: vertical;
}

html body #lead-modal .atajos-fecha {
    gap: 4px;
    margin-top: 4px;
}

html body #lead-modal .atajos-fecha button {
    height: 24px;
    padding: 0 8px;
    font-size: 11px;
}

html body #lead-modal .bloque-timeline {
    margin-top: 0.4rem !important;
    padding-top: 0.6rem !important;
}

html body #lead-modal .bloque-timeline h4 {
    font-size: 0.75rem !important;
    margin-bottom: 0.4rem !important;
}

html body #lead-modal .interaccion-nueva {
    display: grid !important;
    grid-template-columns: minmax(0, 110px) minmax(0, 1fr) auto !important;
    gap: 5px !important;
}

html body #lead-modal .interaccion-nueva .btn {
    height: 30px !important;
    min-height: 30px !important;
    padding: 0 10px !important;
    font-size: 0.75rem !important;
}

/* En el telefono las tres columnas no entran: el boton "Registrar"
   quedaba montado encima del campo de texto y tapaba lo que se estaba
   escribiendo. Abajo de 460px el boton baja a su propia fila y ocupa
   el ancho completo, que ademas es mas facil de pulsar con el pulgar. */
@media (max-width: 460px) {
    html body #lead-modal .interaccion-nueva {
        grid-template-columns: minmax(0, 110px) minmax(0, 1fr) !important;
    }

    html body #lead-modal .interaccion-nueva .btn {
        grid-column: 1 / -1 !important;
        justify-content: center !important;
    }
}

/* El historial reservaba media pantalla en blanco esperando
   interacciones que todavia no existen. Ahora crece hasta 120px
   y de ahi scrollea. */
html body #lead-modal #lead-timeline {
    max-height: 120px !important;
    min-height: 0 !important;
    overflow-y: auto;
    overscroll-behavior: contain;
    margin-top: 6px;
}

html body #lead-modal #lead-timeline:empty {
    display: none;
}

html body #lead-modal .modal-actions {
    margin-top: 0.85rem;
    padding-top: 0.75rem;
    gap: 8px;
}

html body #lead-modal .modal-actions .btn {
    min-height: 34px !important;
    height: 34px;
    padding: 0 14px !important;
    font-size: 0.82rem !important;
}

@media (max-width: 620px) {
    html body #lead-modal .form-row { grid-template-columns: 1fr; }
}

/* ==========================================================
   2e. CALENDARIO

   La rejilla se veia igual a las 8 que a las 19: nada decia
   donde estaba parado uno. Eso lo arregla la linea de ahora
   (la pone js/agenda.js). El resto es hacer legible lo que ya
   estaba: la columna de hoy, las horas fuera de la jornada y
   los eventos, que eran rectangulos planos.
   ========================================================== */

/* --- La linea de la hora actual ---------------------------- */
.cal-ahora {
    position: absolute;
    left: calc(var(--d) * (100% / var(--cal-dias)));
    width: calc(100% / var(--cal-dias));
    height: 0;
    border-top: 2px solid var(--danger, #ef4444);
    pointer-events: none;
    z-index: 3;
}

/* El punto del extremo: sin el, con un evento debajo la linea
   se lee como el borde del evento y no como la hora. */
.cal-ahora::before {
    content: '';
    position: absolute;
    left: -4px;
    top: -4px;
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--danger, #ef4444);
}

/* --- La columna de hoy ------------------------------------- */
html body .cal-dia-cab.hoy .cal-dia-nombre {
    color: var(--primary);
}

/* --- Fuera de la jornada ----------------------------------- */
/* Sabado y domingo apagados: la semana laboral se lee sola. */
html body .cal-fila .cal-celda:nth-last-child(-n+2) {
    background: rgba(0, 0, 0, 0.14);
}

/* --- Los eventos ------------------------------------------- */
html body .cal-evento {
    /* La barra de color va al costado y no de borde completo:
       distingue el evento sin encerrarlo. */
    box-shadow: inset 3px 0 0 var(--ev-color, var(--primary));
    border-left: none;
    padding-left: 9px;
    /* Sin transicion en `transform` sobre elementos posicionados
       en porcentaje: al repintar la semana saltan. Solo el brillo. */
    transition: filter 140ms ease, box-shadow 140ms ease;
}

html body .cal-evento:hover {
    transform: none;
    filter: brightness(1.18);
    box-shadow: inset 3px 0 0 var(--ev-color, var(--primary)),
                0 2px 10px rgba(0, 0, 0, 0.35);
}

/* La celda vacia invita a hacer click, pero recien cuando el
   mouse esta encima: antes se pintaba toda la fila. */
html body .cal-celda {
    transition: background 100ms linear;
}

html body .cal-celda:hover {
    background: rgba(var(--acento-rgb), 0.10);
    box-shadow: inset 0 0 0 1px rgba(var(--acento-rgb), 0.25);
}

/* La cabecera de dias no se va con el scroll de las horas */
html body .cal-cabecera {
    position: sticky;
    top: 0;
    z-index: 4;
}

/* Barra de scroll fina: dos calendarios lado a lado con la
   barra gorda del sistema comen 34px de rejilla. */
html body .cal-horas {
    scrollbar-width: thin;
    overscroll-behavior: contain;
}

html body .cal-horas::-webkit-scrollbar { width: 7px; }
html body .cal-horas::-webkit-scrollbar-track { background: transparent; }
html body .cal-horas::-webkit-scrollbar-thumb {
    background: var(--borde-luz, var(--border-color));
    border-radius: 999px;
}

/* ==========================================================
   2f. PIE DE LA FICHA DE PROYECTO

   Dos grupos, no cuatro botones repartidos por el ancho:
   a la izquierda lo que le pasa AL PROYECTO (borrarlo,
   terminarlo), a la derecha lo que uno hace ahora (agendar,
   guardar). `space-between` con cuatro hijos los separaba a
   todos por igual y no se leia ningun grupo.
   ========================================================== */

html body .pr-ficha-pie {
    justify-content: flex-start !important;
    flex-wrap: wrap;
}

/* Este es el que parte el pie en dos: todo lo que viene
   despues se va contra el borde derecho. */
html body .pr-ficha-pie #pr-reunion {
    margin-left: auto !important;
}

/* ==========================================================
   2g. CALENDARIOS: MENOS REJA, MAS AGENDA

   La version anterior dibujaba una cuadricula completa: linea
   vertical y horizontal en cada celda, con el mismo peso. Eso
   hace que la pantalla se lea como una planilla y que los
   eventos, que son lo unico que importa, compitan con el
   fondo.

   El criterio de Google Calendar es al reves: la hora se marca
   con una linea horizontal tenue, el dia con una vertical
   apenas visible, y todo el contraste se guarda para lo que
   esta agendado.
   ========================================================== */

/* El marco exterior se va: la reja ya delimita sola. */
html body .cal-rejilla {
    border: none !important;
    border-radius: 0 !important;
}

/* Cabecera de dias: sin caja gris, solo una linea de base. */
html body .cal-cabecera {
    background: transparent !important;
    border-bottom: 1px solid var(--borde-luz, var(--border-color)) !important;
}

html body .cal-dia-cab {
    border-left: none !important;
    padding: 6px 4px 8px !important;
}

html body .cal-dia-nombre {
    font-size: 10px !important;
    letter-spacing: 0.06em !important;
    font-weight: 500 !important;
}

html body .cal-dia-num {
    font-size: 17px !important;
    font-weight: 400 !important;
    margin-top: 2px !important;
}

/* Hoy: el circulo lleno es la marca que ya entendemos todos. */
html body .cal-dia-cab.hoy .cal-dia-num {
    min-width: 28px !important;
    height: 28px !important;
    font-weight: 500 !important;
    background: var(--primary) !important;
    color: #0a0a0b !important;
}

/* --- La reja ----------------------------------------------- */

/* La linea de la hora es la unica que se ve de verdad. */
html body .cal-fila {
    height: 44px !important;
}

html body .cal-celda {
    border-top: 1px solid color-mix(in srgb, var(--borde-luz, #2a2a2e) 55%, transparent) !important;
    /* La vertical, a la mitad de peso: separa dias sin dibujar
       una cuadricula. */
    border-left: 1px solid color-mix(in srgb, var(--borde-luz, #2a2a2e) 28%, transparent) !important;
}

/* La primera columna de cada dia no necesita su propia linea:
   la del borde ya esta. */
html body .cal-fila .cal-celda:first-of-type {
    border-left: none !important;
}

/* La columna de horas: numeros chicos, alineados con la linea
   que nombran, sin borde propio. */
html body .cal-hora {
    border-top: none !important;
    padding: 0 8px 0 0 !important;
    font-size: 10px !important;
    font-variant-numeric: tabular-nums;
    /* Medio renglon hacia arriba para que el numero quede
       montado sobre su linea, no debajo. Con !important porque
       hay una capa previa que pone `transform: none`. */
    transform: translateY(-6px) !important;
}

/* --- Los eventos ------------------------------------------- */

/* Bloque lleno del color del evento, como en cualquier agenda:
   se lee de un vistazo cuanto ocupa y de que es. */
html body .cal-evento {
    padding: 3px 7px !important;
    border-radius: 6px !important;
    border: none !important;
    box-shadow: none !important;
    background: color-mix(in srgb, var(--ev-color, var(--primary)) 88%, #000) !important;
    color: #0a0a0b !important;
    font-size: 11px !important;
    font-weight: 500 !important;
    left: calc(var(--d) * (100% / var(--cal-dias)) + 2px) !important;
    width: calc((100% / var(--cal-dias)) - 5px) !important;
}

html body .cal-evento strong { font-weight: 600 !important; }
html body .cal-evento span { color: rgba(0, 0, 0, 0.62) !important; }

html body .cal-evento:hover {
    filter: brightness(1.1) !important;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.4) !important;
}

/* Los del equipo se distinguen por una barra al costado, no
   por otro color: el color ya lo usa el evento. */
html body .cal-evento.de-equipo {
    border-left: 3px solid rgba(0, 0, 0, 0.45) !important;
    padding-left: 6px !important;
}

/* --- Buscar en el calendario -------------------------------- */

.cal-buscador {
    position: relative;
    display: flex;
    align-items: center;
    gap: 7px;
    height: 30px;
    padding: 0 10px;
    margin-left: 10px;
    border: 1px solid var(--borde-luz, var(--border-color));
    border-radius: 9px;
    background: var(--surf-1, rgba(0, 0, 0, 0.2));
    flex: 0 1 230px;
    min-width: 150px;
}

.cal-buscador > i {
    font-size: 11px;
    color: var(--text-dim, var(--text-muted));
    flex: 0 0 auto;
}

.cal-buscador input {
    flex: 1;
    min-width: 0;
    height: 26px !important;
    min-height: 0 !important;
    padding: 0 !important;
    border: none !important;
    outline: none !important;
    box-shadow: none !important;
    background: transparent !important;
    color: var(--text-main);
    font-size: 12px !important;
    font-family: inherit;
}

.cal-buscador:focus-within {
    border-color: rgba(var(--acento-rgb), 0.55);
}

.cal-buscador:focus-within > i { color: var(--primary); }

/* La lista cuelga del campo y tapa el calendario: es momentanea
   y desaparece al elegir o al tocar afuera. */
.cal-resultados {
    position: absolute;
    top: calc(100% + 6px);
    left: 0;
    right: 0;
    min-width: 280px;
    max-height: 320px;
    overflow-y: auto;
    z-index: 30;
    padding: 5px;
    border: 1px solid var(--borde-luz, var(--border-color));
    border-radius: 11px;
    background: var(--surf-1, #16181c);
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.5);
}

.cal-resultados[hidden] { display: none; }

.cal-resultado {
    display: flex;
    align-items: center;
    gap: 9px;
    width: 100%;
    padding: 7px 9px;
    border: none;
    border-radius: 8px;
    background: transparent;
    color: var(--text-main);
    font-family: inherit;
    text-align: left;
    cursor: pointer;
}

.cal-resultado:hover,
.cal-resultado:focus-visible {
    background: rgba(var(--acento-rgb), 0.12);
}

.cal-resultado-punto {
    flex: 0 0 8px;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--c, var(--primary));
}

.cal-resultado.es-fecha > i {
    color: var(--primary);
    font-size: 12px;
}

.cal-resultado-txt {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.cal-resultado strong {
    font-size: 12.5px;
    font-weight: 600;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.cal-resultado small {
    font-size: 10.5px;
    color: var(--text-muted);
}

.cal-sin-resultados {
    margin: 0;
    padding: 10px;
    font-size: 12px;
    color: var(--text-muted);
}

/* En el telefono el buscador toma toda la fila de la barra. */
@media (max-width: 720px) {
    .cal-buscador {
        flex: 1 1 100% !important;
        margin-left: 0 !important;
        order: 10;
    }
}

/* --- Plegar una columna ------------------------------------ */

html body .cal-columna-cab {
    cursor: pointer;
    user-select: none;
    border-radius: 8px;
    transition: background 140ms ease;
}

html body .cal-columna-cab:hover {
    background: rgba(var(--acento-rgb), 0.07);
}

html body .cal-plegar-flecha {
    margin-left: 8px;
    font-size: 10px;
    color: var(--text-dim, var(--text-muted));
    transition: transform 180ms ease;
}

html body .cal-columna.plegada .cal-plegar-flecha {
    transform: rotate(180deg);
}

/* Plegada: queda solo la cabecera, y el ancho lo cede al otro
   calendario en vez de dejar un hueco. */
html body .cal-columna.plegada .cal-cuerpo {
    display: none !important;
}

/* El contenedor hereda `transition-property: all`, y eso incluye
   `grid-template-columns`. Los valores de esta reja no son
   interpolables entre si (`1fr 1fr` contra `minmax(0,1fr) auto`),
   asi que el navegador se quedaba con el valor viejo: el cambio
   de anchos no llegaba a aplicarse nunca, ni siquiera forzandolo
   con un estilo en linea con !important. Sin transicion, entra
   en el acto. */
html body .cal-dobles {
    transition: none !important;
}

/* El contenedor es un grid de `1fr 1fr`: para que el calendario
   abierto se lleve el ancho, hay que cambiar la reja del padre,
   no el hijo. Las clases las pone js/agenda.js al plegar. */
html body .cal-dobles.sin-privado {
    grid-template-columns: auto minmax(0, 1fr) !important;
}

html body .cal-dobles.sin-equipo {
    grid-template-columns: minmax(0, 1fr) auto !important;
}

/* Los dos plegados: no hay ancho que repartir, asi que las dos
   cabeceras van a la par. Sin esta regla ganaria la ultima de
   las dos de arriba y un calendario cerrado quedaria estirado
   al doble que el otro, sin motivo. */
html body .cal-dobles.sin-privado.sin-equipo {
    grid-template-columns: 1fr 1fr !important;
}

html body .cal-columna.plegada {
    min-width: 0 !important;
}

/* Plegada, la cabecera se pone vertical: ocupa el ancho de una
   pestaña lateral en vez de una franja horizontal muerta. */
html body .cal-columna.plegada .cal-columna-cab h4 {
    white-space: nowrap;
}

html body .cal-dobles {
    align-items: start;
}

/* En el telefono los dos calendarios ya van uno debajo del
   otro, asi que plegar solo esconde el cuerpo. */
@media (max-width: 720px) {
    html body .cal-dobles,
    html body .cal-dobles.sin-privado,
    html body .cal-dobles.sin-equipo {
        grid-template-columns: 1fr !important;
    }
}

/* ==========================================================
   2c. BUSCADORES

   La cruz azul de la esquina era el boton nativo de
   ::-webkit-search-cancel-button: no se hereda del tema, no
   respeta el acento y aparece con su propio color y su propia
   transicion. Se saca y la cruz la pone el CRM cuando hace
   falta. El subrayado rojo era el corrector del navegador
   marcando nombres propios como errores.
   ========================================================== */

html body input[type="search"]::-webkit-search-cancel-button,
html body input[type="search"]::-webkit-search-decoration {
    -webkit-appearance: none;
    appearance: none;
    display: none;
}

/* El desborde del anillo verde.

   sistema.css le pone `box-shadow: 0 0 0 3px accent-glow` y borde
   de acento a TODO input con foco, e index.css repite lo mismo.
   En un buscador eso se ve mal: el input vive dentro de una caja
   que ya tiene su propio borde, asi que aparecian dos anillos, y
   el de adentro se salia por arriba y por abajo porque el input
   mide casi lo mismo que su contenedor.

   La regla: el que muestra el foco es el CONTENEDOR. El input de
   adentro no lleva ni borde, ni anillo, ni fondo propio. */
html body .buscador input:focus,
html body .buscador input:focus-visible,
html body .buscador input {
    border: none !important;
    outline: none !important;
    box-shadow: none !important;
    background: transparent !important;
    border-radius: 0 !important;
}

html body .buscador:focus-within {
    border-color: rgba(var(--acento-rgb), 0.55) !important;
    box-shadow: 0 0 0 2px rgba(var(--acento-rgb), 0.12) !important;
}

html body .buscador:focus-within i {
    color: var(--primary) !important;
}

/* Lo mismo para los buscadores armados a mano dentro de modales,
   que no usan la clase .buscador pero tienen la misma forma. */
html body .modal-card input[type="search"]:focus,
html body .modal-card input[type="search"]:focus-visible {
    box-shadow: none !important;
}

/* El anillo general se achica de 3px a 2px y deja de pintar el
   borde: a 3px, en cualquier control pegado a otro, se monta
   encima del vecino. */
html body input:focus-visible,
html body select:focus-visible,
html body textarea:focus-visible,
html body .campo:focus-visible {
    box-shadow: 0 0 0 2px rgba(var(--acento-rgb), 0.28) !important;
}

/* ==========================================================
   2d. CHAT: BORRAR Y MINIMIZAR
   ========================================================== */

.chat-acciones {
    display: flex;
    align-items: center;
    gap: 2px;
}

/* La papelera del historial no compite con cerrar: se apaga
   hasta que la buscas, y recien ahi se pone roja. */
#chat-vaciar { color: var(--text-dim, var(--text-muted)); }
#chat-vaciar:hover { color: var(--danger, #ef4444); }

/* --- Borrar un mensaje propio -------------------------------
   El boton vive al costado de la burbuja y aparece al pasar por
   encima: estando siempre visible, una conversacion de veinte
   mensajes son veinte papeleras compitiendo con el texto. */
html body .chat-msj {
    position: relative;
}

html body .chat-borrar {
    position: absolute;
    /* Al borde izquierdo de la fila: los mensajes propios se
       pegan a la derecha, asi que ese costado esta libre y el
       boton no se le encima a nada. */
    top: 50%;
    left: 0;
    transform: translateY(-50%);
    width: 26px;
    height: 26px;
    display: grid;
    place-items: center;
    border: none;
    border-radius: 50%;
    background: var(--surf-2, rgba(255, 255, 255, 0.08));
    color: var(--text-dim, var(--text-muted));
    font-size: 11px;
    cursor: pointer;
    opacity: 0;
    transition: opacity 120ms ease, color 120ms ease;
}

html body .chat-msj:hover .chat-borrar,
html body .chat-borrar:focus-visible {
    opacity: 1;
}

html body .chat-borrar:hover { color: var(--danger, #ef4444); }

/* En pantalla tactil no hay hover: la papelera queda a la vista. */
@media (hover: none) {
    html body .chat-borrar { opacity: 0.65; }
}

/* La lapida del mensaje eliminado: se nota que hubo algo ahi,
   sin gritar. */
html body .chat-msj.borrado .chat-burbuja {
    background: transparent !important;
    border: 1px dashed var(--border-color) !important;
    color: var(--text-dim, var(--text-muted)) !important;
}

html body .chat-msj.borrado .chat-burbuja p {
    font-style: italic;
    opacity: 0.75;
}

/* --- La pastilla del chat minimizado ------------------------
   Abajo a la izquierda, fuera del camino, pero con el contador
   a la vista: minimizar no es dejar de recibir. */
/* La pastilla queda del mismo lado que la ventana: minimizar es
   guardar la ventana, no mudarla a la otra punta de la pantalla.
   Al restaurar, la caja crece desde donde estaba la pastilla. */
.chat-pildora {
    position: fixed;
    right: 16px;
    bottom: 16px;
    z-index: 62;
    display: inline-flex;
    align-items: center;
    gap: 9px;
    height: 40px;
    padding: 0 16px 0 13px;
    border: 1px solid var(--borde-luz, var(--border-color));
    border-radius: 999px;
    background: var(--surf-1, #16181c);
    color: var(--text-main);
    font-family: inherit;
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
    box-shadow: 0 6px 20px rgba(0, 0, 0, 0.35);
    transition: transform 140ms ease, border-color 140ms ease;
}

.chat-pildora[hidden] { display: none; }

.chat-pildora:hover {
    transform: translateY(-2px);
    border-color: var(--primary);
}

.chat-pildora > i { color: var(--primary); }

.chat-pildora-badge {
    min-width: 19px;
    height: 19px;
    padding: 0 5px;
    display: inline-grid;
    place-items: center;
    border-radius: 999px;
    background: var(--danger, #ef4444);
    color: #fff;
    font-size: 11px;
    font-weight: 800;
}

.chat-pildora-badge[hidden] { display: none; }

@media (max-width: 620px) {
    .chat-pildora span:not(.chat-pildora-badge) { display: none; }
    .chat-pildora { padding: 0 13px; }
}

/* ==========================================================
   5. MOVIL: QUE NADA SE DESBORDE

   La barra de abajo era una tira con scroll horizontal: seis
   pestañas de ancho libre no entran en 390px, asi que al tocar
   "Mi Perfil" el navegador arrastraba la barra para traerlo a
   la vista y "Dashboard" se iba de pantalla. Una barra de
   navegacion que se mueve sola no es navegacion.

   Se cambia por una reja de seis columnas iguales: cada
   pestaña ocupa un sexto y no se mueve nunca. El texto se
   achica y el icono va arriba, que es la forma que ya tiene
   cualquier app en el telefono.
   ========================================================== */

@media (max-width: 768px) {

    html body .main-tabs {
        display: grid !important;
        /* Tantas columnas como pestañas visibles, no seis fijas.
           Con `repeat(6, 1fr)` el usuario comun —que no tiene la
           pestaña de Usuarios— dejaba la sexta columna vacia y la
           barra quedaba corrida, con un hueco a la derecha. */
        grid-auto-flow: column !important;
        grid-auto-columns: 1fr !important;
        grid-template-columns: none !important;
        justify-content: stretch !important;
        gap: 0 !important;
        overflow: hidden !important;
        /* Sin scroll: no hay nada que arrastrar. */
        overflow-x: hidden !important;
        scroll-snap-type: none !important;

        /* La barra crece con su contenido en vez de medir 56px fijos.

           sistema.css le pone `height: 56px` y ademas un
           `padding-bottom` del area segura. Con `box-sizing:
           border-box` ese padding se descuenta de los 56px: los
           botones se corrian hacia arriba y quedaba una franja
           oscura debajo, dentro de la propia barra. Parecia que la
           barra no llegaba al fondo de la pantalla, cuando en
           realidad llegaba y estaba vacia por dentro. */
        height: auto !important;
        min-height: 56px !important;

        /* El area segura sola, sin sumarle nada: es la distancia
           minima para no quedar debajo de la franja de gestos de
           Android. Cualquier pixel extra es hueco. */
        padding: 4px 2px env(safe-area-inset-bottom) !important;
    }

    html body .main-tabs .tab-btn {
        /* El contador se posiciona contra esta caja. */
        position: relative !important;
        overflow: visible !important;
        flex: 1 1 0 !important;
        width: auto !important;
        min-width: 0 !important;
        /* sistema.css les pone `height: 100%`, que contra una barra
           de alto automatico no significa nada util. */
        height: auto !important;
        display: flex !important;
        flex-direction: column !important;
        align-items: center !important;
        justify-content: center !important;
        gap: 2px !important;
        min-height: 46px !important;
        padding: 5px 2px !important;
        font-size: 0.6rem !important;
        line-height: 1.1 !important;
        border-radius: 10px !important;
        scroll-snap-align: none !important;
    }

    html body .main-tabs .tab-btn i {
        font-size: 1rem !important;
    }

    /* El nombre no puede empujar la columna: si no entra, se
       corta con puntos suspensivos y la reja no se deforma. */
    html body .main-tabs .tab-btn > span:not(.tab-badge) {
        display: block !important;
        max-width: 100% !important;
        overflow: hidden !important;
        text-overflow: ellipsis !important;
        white-space: nowrap !important;
    }

    /* El contador se metia por encima del borde de la barra.
       Ahora vive pegado al icono, dentro de la celda. */
    html body .main-tabs .tab-badge {
        position: absolute !important;
        top: 2px !important;
        right: 50% !important;
        margin-right: -20px !important;
        min-width: 15px !important;
        height: 15px !important;
        padding: 0 4px !important;
        font-size: 0.58rem !important;
        line-height: 15px !important;
    }

    /* --- El chat en el telefono ---------------------------- */

    /* La ventana se apoya sobre la barra de navegacion, no
       encima: tapaba las pestañas justo cuando uno quiere
       cambiar de pantalla. */
    html body .chat-panel {
        bottom: calc(56px + env(safe-area-inset-bottom)) !important;
        height: calc(100vh - 56px - env(safe-area-inset-bottom) - 70px) !important;
        max-height: none !important;
        border-radius: 16px 16px 0 0 !important;
    }

    html body .chat-pildora {
        bottom: calc(64px + env(safe-area-inset-bottom)) !important;
        right: 12px !important;
        z-index: 41 !important;
    }

    /* --- La barra de arriba --------------------------------

       Se estaba encimando: el nombre del usuario, el cartel de
       Realtime y los iconos ocupaban mas ancho del que hay, y
       como la barra no envuelve ni recorta, cada cosa se
       dibujaba arriba de la anterior.

       Criterio para decidir que se va: en 390px de ancho solo
       entra lo accionable. El logo dice donde estas, los
       iconos son los que se tocan. "Realtime", la pastilla CRM
       y tu propio nombre son informacion que ya sabes. */

    html body .top-navbar {
        display: flex !important;
        align-items: center !important;
        flex-wrap: nowrap !important;
        gap: 6px !important;
        padding: 8px 10px !important;
        overflow: hidden !important;
    }

    html body .top-navbar .brand-container {
        display: flex !important;
        align-items: center !important;
        gap: 4px !important;
        flex: 1 1 auto !important;
        min-width: 0 !important;
    }

    /* El logotipo se achica pero no se recorta, y cede lugar
       antes que los botones. */
    html body .top-navbar .logo-wrapper {
        flex: 0 1 auto !important;
        min-width: 0 !important;
        overflow: hidden !important;
    }

    /* El tope de ancho es lo que evita el encimado, no el alto:
       el logotipo es una palabra larga y con 18px de alto medía
       164px de ancho, que es mas de lo que sobra despues de los
       cuatro iconos y la chapa del rol. */
    html body .top-navbar .logo-wrapper img {
        height: 16px !important;
        width: auto !important;
        max-width: 104px !important;
        object-fit: contain !important;
        object-position: left center !important;
    }

    html body .top-navbar .crm-badge-pill,
    html body .top-navbar .status-indicator,
    html body .top-navbar .user-name,
    html body .rotativo {
        display: none !important;
    }

    /* La chapa del rol se queda: es lo unico de la barra que no
       podes deducir mirando la pantalla. */
    html body .top-navbar .user-meta {
        flex: 0 0 auto !important;
        margin-left: 0 !important;
    }

    html body .top-navbar .badge {
        font-size: 0.58rem !important;
        padding: 2px 6px !important;
        white-space: nowrap !important;
    }

    /* Los iconos: medida pareja, sin encimarse, y el ultimo
       pegado al borde. */
    html body .top-navbar .btn-icon {
        flex: 0 0 auto !important;
        width: 32px !important;
        height: 32px !important;
        min-width: 32px !important;
        min-height: 32px !important;
        max-height: 32px !important;
        margin: 0 !important;
        padding: 0 !important;
        display: inline-flex !important;
        align-items: center !important;
        justify-content: center !important;
        position: relative !important;
    }

    html body .top-navbar .btn-icon i { font-size: 13px !important; }

    /* Los contadores de los iconos se salian de la barra. */
    html body .top-navbar .btn-icon .chat-pendientes,
    html body .top-navbar .btn-icon .contador,
    html body .top-navbar .btn-icon > span:not(.dot) {
        position: absolute !important;
        top: -2px !important;
        right: -2px !important;
        min-width: 14px !important;
        height: 14px !important;
        padding: 0 3px !important;
        font-size: 0.55rem !important;
        line-height: 14px !important;
        border-radius: 999px !important;
    }

    /* --- Nada mas se desborda ------------------------------ */

    /* El ancho de la ventana manda: cualquier reja de dos o mas
       columnas pasa a una sola en vez de empujar la pagina. */
    html body .clientes-split,
    html body .form-row-grid,
    html body .bitacora-grid,
    html body #lead-modal .form-row,
    html body .contactar-alta {
        grid-template-columns: 1fr !important;
    }

    html body .contactar-alta .btn-fila { width: 100% !important; }

    /* Los numeros largos de las tarjetas de resumen partian la
       reja: se dejan encoger. */
    html body .metric-card,
    html body .resumen-item,
    html body .cliente-ficha,
    html body .glass-panel {
        min-width: 0 !important;
        max-width: 100% !important;
        box-sizing: border-box !important;
    }

    /* La cabecera de cada seccion: titulo arriba, acciones
       abajo a todo el ancho. En una fila, el boton "Cargar
       consulta" y el buscador se aplastaban hasta ser
       ilegibles. */
    html body .section-head {
        flex-direction: column !important;
        align-items: stretch !important;
        justify-content: flex-start !important;
        gap: 10px !important;
        min-height: 0 !important;
    }

    /* El `flex: 1 1 320px` del texto esta pensado para la fila de
       escritorio, donde 320px es un ANCHO minimo. Al girar el
       contenedor a columna, ese mismo numero pasa a ser un ALTO:
       el titulo reclamaba 320px de alto y dejaba media pantalla en
       blanco antes de los botones. En vertical el bloque tiene que
       medir lo que mide su texto. */
    html body .section-head__texto {
        flex: 0 0 auto !important;
        min-height: 0 !important;
    }

    html body .section-head__texto h2 { margin-bottom: 4px !important; }
    html body .section-head__texto p { margin: 0 !important; }

    html body .section-head__acciones {
        display: flex !important;
        flex-wrap: wrap !important;
        gap: 8px !important;
        width: 100% !important;
    }

    html body .section-head__acciones .btn,
    html body .section-head__acciones .buscador,
    html body .section-head__acciones select {
        flex: 1 1 100% !important;
        max-width: 100% !important;
        width: 100% !important;
    }

    /* Los filtros de proyecto si van en una fila: son tres
       palabras cortas y funcionan como un solo control. */
    html body .section-head__acciones .pr-filtros {
        flex: 1 1 100% !important;
        justify-content: center !important;
    }

    html body .pr-filtro { flex: 1 1 0 !important; }

    /* La barra de filtros de consultas, uno abajo del otro. */
    html body .barra-filtros {
        display: grid !important;
        grid-template-columns: 1fr !important;
        gap: 8px !important;
    }

    /* El pie de la ficha de proyecto: los cuatro botones
       entraban a la fuerza y quedaban de 20px de ancho. */
    html body .pr-ficha-pie,
    html body .modal-actions {
        flex-wrap: wrap !important;
        gap: 8px !important;
    }

    html body .pr-ficha-pie .btn,
    html body .modal-actions .btn {
        flex: 1 1 auto !important;
    }

    html body .pr-ficha-pie #pr-reunion {
        margin-left: 0 !important;
    }

    /* Las fichas de consulta y los modales usan el ancho real
       del telefono, con aire a los costados. */
    html body .modal-card,
    html body #lead-modal .modal-card,
    html body .pr-ficha {
        max-width: calc(100vw - 20px) !important;
        max-height: calc(100vh - 80px) !important;
    }

    /* Las tablas anchas scrollean solas en vez de estirar la
       pagina entera. */
    html body .table-wrapper,
    html body .tabla-scroll {
        overflow-x: auto !important;
        -webkit-overflow-scrolling: touch;
    }

    /* --- Aire de mas ---------------------------------------

       En una pantalla de 390x844 el espacio vertical es el
       recurso escaso: cada bloque que respira de mas empuja
       al siguiente fuera de la vista y obliga a scrollear
       para ver cuatro numeros. */

    /* Los paneles traen 20px de padding pensados para monitor. */
    html body .glass-panel,
    html body .chart-card {
        padding: 14px !important;
    }

    /* Las cifras de resumen, de a dos por fila. Apiladas en una
       sola columna median 533px: media pantalla para cuatro
       numeros de una cifra. */
    html body .clientes-resumen,
    html body .consultas-resumen,
    html body .metrics-grid {
        display: grid !important;
        grid-template-columns: 1fr 1fr !important;
        gap: 8px !important;
    }

    html body .clientes-col .clientes-resumen .resumen-item {
        padding: 8px !important;
    }

    /* Con dos columnas, la linea divisoria vertical de escritorio
       queda cortando en el lugar equivocado. */
    html body .clientes-col .clientes-resumen .resumen-item + .resumen-item {
        border-left: none !important;
    }

    html body .metric-card { padding: 10px 12px !important; }
    html body .metric-value { font-size: 1.3rem !important; }
    html body .metric-data h3 { font-size: 0.7rem !important; }
    html body .metric-subtext { font-size: 0.63rem !important; }

    /* Los estados vacios reservaban 280px de alto minimo mas 40px
       de padding arriba y abajo. En el telefono, un cartel que
       dice "todavia no hay nada" no necesita media pantalla. */
    html body .tab-content > .estado-vacio,
    html body .tab-content > div > .estado-vacio,
    html body .estado-vacio,
    html body .empty-state {
        min-height: 0 !important;
        padding: 24px 14px !important;
    }

    html body .tabla-vacia {
        padding: 24px 14px !important;
    }

    html body .estado-vacio i,
    html body .empty-state i { font-size: 1.5rem !important; }

    /* Separacion entre bloques de una vista: 24px entre cada uno
       suma una pantalla entera a lo largo de la pagina. */
    html body .tab-content > * + * {
        margin-top: 12px !important;
    }

    html body .clientes-split { gap: 12px !important; }

    /* Ultimo cinturon: nada puede ser mas ancho que la pantalla
       ni provocar scroll lateral en el documento. */
    html, body {
        overflow-x: hidden !important;
        max-width: 100% !important;
    }

    html body img,
    html body table,
    html body pre {
        max-width: 100% !important;
    }
}

/* ==========================================================
   6. EL CARTEL DE "EN QUE ESTA TRABAJANDO EL EQUIPO"
   ========================================================== */

.rotativo {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    max-width: 320px;
    height: 28px;
    margin-right: 8px;
    padding: 0 12px;
    border: 1px solid var(--borde-luz, var(--border-color));
    border-radius: 999px;
    background: var(--surf-2, rgba(255, 255, 255, 0.05));
    font-size: 11.5px;
    line-height: 1;
    overflow: hidden;
    white-space: nowrap;
}

.rotativo[hidden] { display: none; }

.rotativo > i {
    color: var(--primary);
    font-size: 10px;
    flex: 0 0 auto;
}

.rotativo-quien {
    color: var(--primary);
    font-weight: 700;
    flex: 0 0 auto;
}

.rotativo-texto {
    color: var(--text-muted);
    overflow: hidden;
    text-overflow: ellipsis;
    /* El ancho lo pone el texto que se va escribiendo, por eso no
       hay `width` fijo: la caja crece con las letras. */
}

/* El cursor solo existe mientras se teclea. Un cursor parpadeando
   sobre una frase quieta durante ocho segundos es ruido. */
.rotativo-texto.tecleando::after {
    content: '';
    display: inline-block;
    width: 1px;
    height: 11px;
    margin-left: 2px;
    vertical-align: -1px;
    background: var(--primary);
    animation: rotativo-cursor 700ms steps(1) infinite;
}

@keyframes rotativo-cursor {
    0%, 50%   { opacity: 1; }
    51%, 100% { opacity: 0; }
}

/* En pantallas chicas la barra no tiene lugar: el cartel se va
   antes que los botones, que son los que hacen falta. */
@media (max-width: 900px) {
    .rotativo { display: none !important; }
}

@media (prefers-reduced-motion: reduce) {
    .rotativo-texto.tecleando::after { animation: none; }
}

/* ==========================================================
   7. SPOTIFY EN MI PERFIL
   ========================================================== */

.spotify-bloque {
    margin-top: 1rem;
    padding-top: 0.9rem;
    border-top: 1px solid var(--border-color);
}

.spotify-bloque[hidden] { display: none; }

.spotify-ayuda {
    margin: 0 0 0.7rem;
    font-size: 0.76rem;
    color: var(--text-muted);
}

.spotify-fila {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}

.spotify-estado {
    flex: 1 1 160px;
    min-width: 0;
    font-size: 0.8rem;
    color: var(--text-main);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.spotify-estado i { color: #1db954; margin-right: 5px; }

/* ==========================================================
   8. PANTALLA DE CARGA

   Tenia tres colores compitiendo: el halo turquesa alrededor
   de la tarjeta, el verde del acento y un degradado a naranja
   en la barra (`linear-gradient(90deg, var(--primary), #f59e0b)`
   en index.css). Tres colores para decir "espera un segundo".

   Queda uno solo —el acento de la marca— y el movimiento lo da
   un pulso: la tarjeta late y el halo late con ella. Nada de
   barras de progreso: la barra prometia un avance medible que
   no existe, porque no sabemos cuanto falta.
   ========================================================== */

/* La tarjeta con el PNG adentro se fue: el nombre ahora se
   escribe con letras y toma el color de acento sin ayuda. Lo
   que sobrevive de aquella idea es el criterio —un solo color,
   nada de barras que prometan un avance que nadie mide— y eso
   ya vive en index.css, en .marca-splash.

   Aca solo queda lo que el tema tiene que decir sobre el
   arranque, sin duplicar la definicion. */

html body .splash-overlay {
    /* El arranque usa el mismo fondo que la aplicacion: en claro
       era un rectangulo casi blanco sobre casi blanco. */
    background: var(--bg-main, var(--surf-0)) !important;
}

html body .splash-content {
    gap: 1.25rem !important;
}

/* Quien pidio menos movimiento ve el nombre puesto, no escrito.
   No se apaga la pantalla: se apaga la coreografia. */
@media (prefers-reduced-motion: reduce) {
    html body .marca-splash span span {
        animation: none !important;
        opacity: 1 !important;
        transform: none !important;
    }

    html body .marca-splash__cursor,
    html body .splash-subtext {
        animation: none !important;
        opacity: 1 !important;
    }

    html body .splash-linea span {
        animation: none !important;
        width: 100% !important;
    }
}

/* ==========================================================
   3. NADA DE DESENFOQUE EN NINGUN LADO

   Se venia apagando el blur archivo por archivo y siempre
   quedaba alguno prendido en otra capa. Esta regla lo corta
   de raiz para toda la aplicacion.

   Por que pesa tanto:

   - `backdrop-filter` obliga al navegador a LEER lo que hay
     detras del elemento y desenfocarlo de nuevo en cada
     cuadro, porque no puede saber si cambio.
   - `filter: blur()` sobre un contenedor grande obliga a
     rasterizar todo su arbol en una textura aparte; cualquier
     cambio adentro la invalida entera. Es lo que hacia caer
     los cuadros al cambiar de pestana: el contenido nuevo
     obligaba a rehacer el desenfoque completo.

   La separacion visual la dan el color, el borde y la sombra,
   que se resuelven en el compositor y no cuestan por cuadro.
   ========================================================== */

html body *,
html body *::before,
html body *::after {
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
}

/* El desenfoque del fondo al abrir un modal se cambia por un
   oscurecido: misma intencion (mandar el fondo atras), sin
   rasterizar nada. */
html.hay-modal #crm-workspace,
html.hay-modal #fondo-imagen,
html.hay-modal #fondo-codigo,
html.hay-modal #ambient-background-glow,
html:not(.hay-modal) #crm-workspace,
html:not(.hay-modal) #fondo-imagen,
html:not(.hay-modal) #fondo-codigo,
html:not(.hay-modal) #ambient-background-glow {
    filter: none !important;
    transform: none !important;
}

/* El workspace no se toca ni con opacidad: bajarla tambien
   obliga a rasterizar el arbol entero en una capa. El que manda
   el fondo atras es el velo oscuro del propio modal. */

/* El orbe de ambiente animaba `filter: blur()` entre 25px y
   50px sobre una mancha de 950x700, en bucle infinito: el
   navegador rehacia ese desenfoque en cada cuadro durante toda
   la sesion. El degradado radial ya es difuso por si mismo, no
   necesita blur; queda solo el latido de escala y opacidad,
   que corre en el compositor. */
html body #ambient-background-glow::before {
    filter: none !important;
    animation-name: ap-latido !important;
}

@keyframes ap-latido {
    0%   { transform: translate(-50%, -50%) scale(0.85); opacity: 0.45; }
    50%  { transform: translate(-50%, -50%) scale(1.2);  opacity: 0.85; }
    100% { transform: translate(-50%, -50%) scale(0.9);  opacity: 0.5; }
}

/* ==========================================================
   4. CAMBIO DE PESTANA SIN CASCADA

   Al activar una pestana corrian tres animaciones encimadas:
   la de la seccion entera (ui.css), una escalonada por cada
   hijo directo (micro.css y ui.css otra vez) y una por cada
   pastilla de etapa. En una pestana con tablas eso son decenas
   de animaciones de opacidad al mismo tiempo, y cada una
   necesita su propia capa: por eso el cambio de pestana se
   sentia pesado justo al entrar.

   Queda UNA sola, corta, sobre la seccion. La sensacion de
   "se armo" se pierde poco; lo que se gana es que entre de
   una en cualquier maquina.
   ========================================================== */

html body .tab-content.active > *,
html body .tab-content.active > .section-head,
html body .tab-content.active > .consultas-resumen,
html body .tab-content.active > .barra-filtros,
html body .tab-content.active > .barra-etapas,
html body .tab-content.active > #consultas-grid,
html body .etapa-pill {
    animation: none !important;
}

html body .tab-content.active {
    animation: ap-entrada 160ms ease-out both !important;
}

@keyframes ap-entrada {
    from { opacity: 0; }
    to   { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
    html body .tab-content.active { animation: none !important; }
}

html body #ambient-background-glow::after {
    /* Una drop-shadow sobre un PNG de 650px se recalcula cada vez
       que la capa se repinta y no aporta nada sobre un logo en
       marca de agua al 12% de opacidad. */
    filter: none !important;
}

/* ==========================================================
   .hidden TIENE QUE GANARLE A LAS PESTAÑAS

   `.hidden { display:none !important }` (index.css) pierde por
   especificidad contra `.main-tabs .tab-btn { display:inline-flex
   !important }` (ui.css:499) y contra `html body .main-tabs
   .tab-btn { display:flex !important }` (ajustes.css:1163).

   El resultado era que la pestaña Usuarios seguia visible para
   quien no es admin, aunque auth.js le pusiera la clase. Esconder
   el boton no era la seguridad —la Edge Function y RLS ya
   rechazan a los que no son admin— pero mostraba una pestaña que
   al abrirse no tiene nada que mostrar.

   Va en picker.css porque es la ultima hoja que carga index.html:
   a igual especificidad gana la que se declara despues.
   ========================================================== */

html body .main-tabs .tab-btn.hidden,
html body .main-tabs .tab-btn.admin-only.hidden {
    display: none !important;
}

/* ==========================================================
   FILTROS Y TARJETA DE CONSULTA: LEGIBLES Y COMPACTOS

   La barra de filtros son un buscador y cinco listas. En el
   telefono cada una ocupaba el ancho completo, una debajo de
   otra: seis controles de 48px apilados que empujaban la lista
   de consultas fuera de la pantalla. Antes de ver una sola
   consulta habia que scrollear toda la botonera.

   Y las etiquetas se cortaban ("Todas las categor…") porque el
   ancho lo repartia el contenido y no una medida fija.

   Va al final de picker.css porque seis hojas distintas opinan
   sobre .barra-filtros y a igual especificidad gana la ultima.
   ========================================================== */

/* --- Escritorio: una sola fila que envuelve si no entra ----- */
@media (min-width: 769px) {
    html body .barra-filtros {
        display: flex !important;
        flex-wrap: wrap !important;
        align-items: center !important;
        gap: 8px !important;
    }

    /* El buscador manda y se estira; las listas van todas del
       mismo ancho para que la barra se lea como una sola cosa. */
    html body .barra-filtros .buscador {
        flex: 1 1 260px !important;
        min-width: 220px !important;
    }

    html body .barra-filtros .select-field {
        flex: 0 1 168px !important;
        min-width: 148px !important;
        max-width: 200px !important;
    }
}

/* --- Telefono: dos por fila, el buscador entero ------------- */
@media (max-width: 768px) {
    html body .barra-filtros {
        display: grid !important;
        grid-template-columns: 1fr 1fr !important;
        gap: 8px !important;
    }

    html body .barra-filtros .buscador {
        grid-column: 1 / -1 !important;
    }

    html body .barra-filtros .select-field {
        min-width: 0 !important;
        max-width: none !important;
        width: 100% !important;
    }
}

/* Una lista que no puede recortar su texto ensancha la fila y
   descoloca al resto. Se recorta con puntos suspensivos, que es
   lo que el navegador no hace solo en un <select>. */
html body .barra-filtros .select-field {
    text-overflow: ellipsis !important;
    padding-right: 26px !important;
}


/* --- La tarjeta de consulta en el telefono ------------------
   Sacada la columna Presupuesto (ver COLUMNAS en js/leads.js),
   la fila 'monto resp fecha' quedaba con un guion suelto a la
   izquierda. Ahora responsable y fecha comparten esa fila.
   ----------------------------------------------------------- */
@media (max-width: 768px) {
    html body .grid-fila {
        grid-template-areas:
            'cliente cliente etapa'
            'canal   tipo    prio'
            'resp    fecha   fecha'
            'acc     acc     acc' !important;
        gap: 6px !important;
    }

    html body .celda-responsable {
        text-align: left !important;
    }
}

/* La cabecera y las filas pasan de nueve columnas a ocho. */
@media (min-width: 769px) {
    html body .grid-head,
    html body .grid-fila {
        grid-template-columns:
            var(--col-cliente) var(--col-chip) var(--col-chip) var(--col-chip)
            var(--col-etapa) var(--col-resp) var(--col-fecha) var(--col-acc) !important;
    }
}

/* ==========================================================
   TELEFONO: TERMOMETRO Y FILTROS MAS CHICOS

   El termometro (Consultas activas / Prioridad media / Carga
   manual) y la barra de filtros ocupaban juntos casi una
   pantalla completa antes de la primera consulta. En una
   pantalla de telefono, tres tarjetas de 88px de alto con un
   numero de 24px son un encabezado, no un resumen.

   El numero sigue siendo lo mas grande de la tarjeta —es el
   dato— pero deja de competir con el titulo de la seccion.

   Las medidas van en px y no en tokens de espaciado porque
   .resumen-item las trae con !important desde ajustes.css y hay
   que igualar el peso para poder bajarlas.
   ========================================================== */

@media (max-width: 768px) {

    /* --- Termometro --------------------------------------- */
    html body .consultas-resumen,
    html body .clientes-resumen {
        grid-template-columns: 1fr 1fr !important;
        gap: 6px !important;
        margin-bottom: 10px !important;
    }

    html body .resumen-item {
        min-height: 0 !important;
        padding: 8px 10px !important;
        gap: 1px !important;
        border-radius: 10px !important;
    }

    html body .resumen-item strong,
    html body .resumen-item .valor,
    html body .resumen-item b {
        font-size: 17px !important;
        line-height: 1.1 !important;
    }

    html body .resumen-item span,
    html body .resumen-item .etiqueta {
        margin-top: 1px !important;
        font-size: 10.5px !important;
        line-height: 1.25 !important;
    }

    html body .resumen-item small,
    html body .resumen-item .apoyo {
        font-size: 9.5px !important;
        line-height: 1.2 !important;
    }

    /* El realce al pasar el dedo no aporta en tactil y en una
       tarjeta chica el desplazamiento se ve como un salto. */
    html body .resumen-item:hover {
        transform: none !important;
    }

    /* --- Barra de filtros --------------------------------- */
    html body .filtros-toggle {
        min-height: 34px !important;
        height: 34px !important;
        padding: 0 12px !important;
        font-size: 0.8rem !important;
        border-radius: 10px !important;
    }

    html body .barra-filtros {
        gap: 6px !important;
    }

    html body .barra-filtros .buscador,
    html body .barra-filtros .select-field,
    html body .barra-filtros > * {
        height: 34px !important;
        min-height: 34px !important;
        border-radius: 10px !important;
    }

    html body .barra-filtros .buscador input,
    html body .barra-filtros .select-field {
        font-size: 0.78rem !important;
    }

    html body .barra-filtros .select-field {
        padding-left: 8px !important;
        padding-right: 22px !important;
    }

    html body .barra-filtros .buscador i {
        font-size: 0.78rem !important;
    }
}

/* ==========================================================
   PANEL DE CONFIGURACION: CABECERA, CIERRE Y PALETA CHICA

   Tres cosas:

   1. No tenia cabecera ni boton de cerrar. Se cerraba con
      Escape o con un clic afuera, dos cosas que no se ven: si
      alguien no las conoce, el panel parece trabado.

   2. Las ocho muestras de color se repartian el ancho completo
      del panel con aspect-ratio 1, o sea que su alto crecia con
      el ancho: quedaban ocho circulos enormes que empujaban
      todo lo demas fuera de la vista. El acento se elige una
      vez y no se toca mas; no merece ser lo mas grande.

   3. El titulo de cada seccion y los espacios, mas ajustados,
      para que el panel entre de una en pantallas de portatil.
   ========================================================== */

html body .ap-cab {
    display: flex !important;
    align-items: center !important;
    justify-content: space-between !important;
    gap: 8px !important;
    padding-bottom: 8px !important;
    margin-bottom: 4px !important;
    border-bottom: 1px solid var(--border-color) !important;
}

html body .ap-cab h4 {
    margin: 0 !important;
    font-size: 13px !important;
    font-weight: 700 !important;
    display: flex !important;
    align-items: center !important;
    gap: 7px !important;
}

html body .ap-cab h4 i { color: var(--primary) !important; }

/* --- Paleta al tamaño de un boton, no de una tarjeta -------- */
html body .ap-colores {
    grid-template-columns: repeat(8, 1fr) !important;
    gap: 5px !important;
    margin-bottom: 8px !important;
}

html body .ap-color {
    aspect-ratio: auto !important;
    height: 22px !important;
    width: 22px !important;
    justify-self: center !important;
    border-width: 2px !important;
}

html body .ap-seccion {
    margin-bottom: 12px !important;
}

html body .ap-seccion h4 {
    font-size: 12px !important;
    margin-bottom: 7px !important;
}

html body .ap-personalizado {
    margin-bottom: 4px !important;
}

/* --- Tonos --------------------------------------------------- */
html body .ap-tono {
    display: block !important;
    margin-bottom: 8px !important;
    font-size: 11px !important;
    color: var(--text-muted) !important;
}

html body .ap-tono > span:first-child {
    display: block !important;
    margin-bottom: 4px !important;
}

html body .ap-tono-fila {
    display: flex !important;
    align-items: center !important;
    gap: 6px !important;
}

html body .ap-tono-fila .select-field {
    flex: 1 1 auto !important;
    min-width: 0 !important;
    height: 30px !important;
    min-height: 30px !important;
    font-size: 11.5px !important;
}

html body .ap-tono-fila .ap-probar {
    flex: 0 0 auto !important;
    width: 30px !important;
    height: 30px !important;
    background: rgba(var(--acento-rgb), 0.10) !important;
    color: var(--primary) !important;
    border: 1px solid rgba(var(--acento-rgb), 0.28) !important;
    border-radius: 8px !important;
}

/* --- Listo --------------------------------------------------- */
html body .ap-listo {
    display: flex !important;
    align-items: center !important;
    justify-content: center !important;
    gap: 7px !important;
    width: 100% !important;
    /* Alto forzado, igual que .ap-reset (ver ajustes.css): sin el
       !important la caja se achicaba por debajo de los 34px que dice
       ac, y con un radio de 10px sobre una caja mas baja que eso el
       boton se ve pastilla en vez de rectangulo. */
    height: 38px !important;
    min-height: 38px !important;
    border-radius: 10px !important;
    font-size: 12px !important;
    font-weight: 700 !important;
    cursor: pointer !important;
    background: var(--primary) !important;
    color: var(--bg-card) !important;
    border: 1px solid var(--primary) !important;
}

/* ==========================================================
   AVISO DE EVENTO NUEVO EN EL CALENDARIO DEL EQUIPO

   El cartel de proximidad ("empieza en 5 minutos") es una
   linea: titulo y hora. Este dice tres cosas —quien, que y
   cuando— asi que necesita alto y no puede recortar el texto
   con puntos suspensivos como hace .aviso-cartel strong.

   El nombre de quien lo cargo es el dato que cambia lo que uno
   hace con el aviso, asi que se resalta y entra con su propia
   animacion: un destello del color de acento que se apaga.
   ========================================================== */

html body .aviso-cartel.aviso-nuevo {
    align-items: flex-start !important;
    width: 340px !important;
    padding: 12px 13px !important;
}

html body .aviso-cartel.aviso-nuevo > i {
    margin-top: 2px !important;
}

/* El titulo de este cartel envuelve: son varias palabras y
   cortarlas en "Nacho agregó un evento al calen…" pierde justo
   la parte que importa. */
html body .aviso-cartel.aviso-nuevo strong {
    white-space: normal !important;
    overflow: visible !important;
    text-overflow: clip !important;
    line-height: 1.35 !important;
    font-weight: 600 !important;
}

html body .aviso-cartel.aviso-nuevo .aviso-detalle,
html body .aviso-cartel.aviso-nuevo .aviso-nota {
    display: block !important;
    margin-top: 3px !important;
}

html body .aviso-cartel.aviso-nuevo .aviso-detalle {
    color: var(--text-main) !important;
    font-weight: 600 !important;
}

html body .aviso-cartel.aviso-nuevo .aviso-nota {
    color: var(--text-dim) !important;
    font-size: 11px !important;
    /* La descripcion puede ser larga: dos lineas y corta. */
    display: -webkit-box !important;
    -webkit-line-clamp: 2 !important;
    -webkit-box-orient: vertical !important;
    overflow: hidden !important;
}

/* --- El nombre --------------------------------------------- */
html body .aviso-quien {
    display: inline-block !important;
    padding: 1px 7px !important;
    border-radius: 6px !important;
    font-size: 12.5px !important;
    font-weight: 800 !important;
    color: var(--primary) !important;
    background: rgba(var(--acento-rgb), 0.14) !important;
    border: 1px solid rgba(var(--acento-rgb), 0.35) !important;
    animation: aviso-quien-entra 1400ms cubic-bezier(0.22, 1, 0.36, 1) both !important;
}

@keyframes aviso-quien-entra {
    0% {
        transform: scale(0.82);
        background: rgba(var(--acento-rgb), 0.75);
        color: #10151a;
        box-shadow: 0 0 0 0 rgba(var(--acento-rgb), 0.55);
    }
    35% {
        transform: scale(1.06);
        background: rgba(var(--acento-rgb), 0.55);
        color: #10151a;
        box-shadow: 0 0 0 7px rgba(var(--acento-rgb), 0);
    }
    100% {
        transform: scale(1);
        background: rgba(var(--acento-rgb), 0.14);
        color: var(--primary);
        box-shadow: 0 0 0 0 rgba(var(--acento-rgb), 0);
    }
}

/* Quien pidio menos movimiento en el sistema operativo no quiere
   un nombre que rebota. Queda el resaltado, sin animacion. */
@media (prefers-reduced-motion: reduce) {
    html body .aviso-quien { animation: none !important; }
}

/* ==========================================================
   PULGAR ARRIBA EN EL CHAT

   Una pastilla chica debajo de la burbuja. No va dentro de la
   burbuja porque el texto de un mensaje puede ser largo y el
   contador quedaria perdido en medio del parrafo.

   Se ve siempre, tambien en cero: un boton que aparece solo con
   el mouse encima no existe en el telefono, que es donde mas se
   usa este chat. En cero queda tenue; con reacciones se enciende.
   ========================================================== */

html body .chat-pulgar {
    align-self: flex-start;
    margin-top: -2px;
    display: inline-flex;
    align-items: center;
    gap: 5px;
    height: 22px;
    padding: 0 8px;
    border: 1px solid transparent;
    border-radius: 999px;
    background: var(--surf-2, rgba(255, 255, 255, 0.07));
    color: var(--text-dim, var(--text-muted));
    font-size: 11px;
    font-weight: 600;
    line-height: 1;
    cursor: pointer;
    opacity: 0.45;
    transition: opacity 120ms ease, color 120ms ease,
                background 120ms ease, border-color 120ms ease;
}

/* Los mensajes propios se pegan a la derecha: su pulgar tambien. */
html body .chat-msj.mio .chat-pulgar {
    align-self: flex-end;
}

html body .chat-pulgar:hover,
html body .chat-pulgar:focus-visible {
    opacity: 1;
}

/* Con al menos una reaccion deja de ser un boton en espera y pasa
   a ser informacion: se muestra entero aunque nadie lo toque. */
html body .chat-pulgar.con-gente {
    opacity: 1;
    color: var(--text-main);
}

/* El propio, marcado con el color de acento. Es la unica forma de
   saber de un vistazo si ya reaccionaste o no. */
html body .chat-pulgar.puesto {
    opacity: 1;
    background: color-mix(in srgb, var(--primary) 18%, transparent);
    border-color: color-mix(in srgb, var(--primary) 45%, transparent);
    color: var(--primary);
}

html body .chat-pulgar i {
    font-size: 11px;
}

/* El dedo necesita mas superficie que el puntero. */
@media (hover: none) {
    html body .chat-pulgar {
        height: 26px;
        padding: 0 10px;
        font-size: 12px;
        opacity: 0.6;
    }
}

/* ==========================================================
   LA PAPELERA DEL CHAT, AL COSTADO Y BAJO DEMANDA

   Estaba en `left: 0` con la fila en position relative: sobre un
   mensaje propio corto la burbuja tambien queda a la izquierda de
   ese borde, asi que el boton le caia encima y tapaba el texto.
   Y se mostraba con `:hover`, que en un telefono no existe: por
   eso terminaba siempre visible.

   Ahora sale FUERA de la caja del mensaje —al lado, en el hueco
   que deja el `max-width` del 82%— y solo cuando se toca el
   mensaje. js/chat.js pone la clase `seleccionado`.
   ========================================================== */

html body .chat-borrar {
    /* Mensaje propio: la burbuja se pega a la derecha, el boton va
       a su izquierda, fuera de la caja. */
    left: auto !important;
    right: calc(100% + 6px) !important;
    opacity: 0 !important;
    pointer-events: none;
}

/* Mensaje ajeno: espejado, el hueco libre esta del otro lado. */
html body .chat-msj:not(.mio) .chat-borrar {
    right: auto !important;
    left: calc(100% + 6px) !important;
}

html body .chat-msj.seleccionado .chat-borrar,
html body .chat-borrar:focus-visible {
    opacity: 1 !important;
    pointer-events: auto;
}

/* El mensaje elegido se marca, para que se entienda que la
   papelera pertenece a ese y no al de al lado. */
html body .chat-msj.seleccionado .chat-burbuja {
    outline: 1px solid color-mix(in srgb, var(--primary) 45%, transparent);
    outline-offset: 2px;
}

/* Con el mouse encima tambien aparece: en escritorio seguir
   teniendo que hacer clic para ver el boton seria un paso de mas. */
@media (hover: hover) {
    html body .chat-msj:hover .chat-borrar {
        opacity: 1 !important;
        pointer-events: auto;
    }
}

/* ==========================================================
   EL CARTEL DE "EN QUE ANDA EL EQUIPO" EN EL TELEFONO

   Estaba oculto por debajo de 900px. Es informacion del equipo,
   no un adorno, asi que tiene que verse tambien en el telefono.

   El primer intento fue mandarlo a un segundo renglon: entraba,
   pero la barra pasaba a medir el doble y eso rompe la cabecera.
   Una barra de navegacion es una linea; si crece, deja de ser un
   marco y se convierte en contenido.

   Asi que va en la MISMA linea, y el ancho se reparte por
   prioridad en vez de por orden de llegada:

     1. La chapa del rol   - fija, nunca se toca
     2. Los botones        - fijos, son las acciones
     3. El cartel          - elastico, se corta con puntos
     4. El logotipo        - el primero que cede

   El logotipo cede primero porque es lo unico redundante: la
   marca ya esta en el icono de la app y en la pantalla de carga.
   ========================================================== */

@media (max-width: 900px) {
    html body .top-navbar {
        /* Una sola linea, sin excepciones. */
        flex-wrap: nowrap !important;
        height: auto !important;
        min-height: 52px !important;
        gap: 6px !important;
        /* Nada se recorta contra el borde de la barra: cada pieza
           se encarga de su propio limite. */
        overflow: visible !important;
    }

    /* --- 4. El logotipo: el primero que cede ---------------- */
    html body .top-navbar .brand-container {
        flex: 0 1 auto !important;
        min-width: 0 !important;
        overflow: hidden !important;
    }

    html body .top-navbar .logo-wrapper img,
    html body .top-navbar .splash-logo-img,
    html body .top-navbar img[data-marca-logo] {
        max-width: 108px !important;
        min-width: 0 !important;
        object-fit: contain !important;
        object-position: left center !important;
    }

    /* --- 2. Los botones: fijos ------------------------------ */
    html body .top-navbar .btn-icon {
        flex: 0 0 auto !important;
    }

    /* --- 3. El cartel: elastico, cerrado, con puntos -------- */
    html body .top-navbar .rotativo,
    html body .rotativo {
        display: flex !important;
        order: 10 !important;
        /* Crece con lo que sobre y se achica hasta 84px antes que
           empujar a nadie. Menos de eso no se lee: ahi conviene
           que desaparezca, y de eso se ocupa el bloque de 560px. */
        flex: 1 1 auto !important;
        width: auto !important;
        min-width: 84px !important;
        max-width: none !important;
        height: 30px !important;
        margin: 0 !important;
        padding: 0 10px !important;
        border-radius: 999px !important;
        font-size: 11px !important;
        gap: 5px !important;
        /* Se cierra sobre si mismo: el padding entra en la medida
           y lo que sobra se recorta ADENTRO, contra su borde. Sin
           esto el texto se iba de la caja y la pastilla quedaba
           abierta de un lado, sin la curva. */
        box-sizing: border-box !important;
        overflow: hidden !important;
        border: 1px solid var(--borde-luz, var(--border-color)) !important;
    }

    html body .rotativo[hidden] {
        display: none !important;
    }

    /* El icono y el nombre miden lo que miden. */
    html body .rotativo > i,
    html body .rotativo .rotativo-quien {
        flex: 0 0 auto !important;
    }

    /* El texto es lo unico elastico de adentro. */
    html body .rotativo .rotativo-texto {
        flex: 1 1 auto !important;
        min-width: 0 !important;
        overflow: hidden !important;
        text-overflow: ellipsis !important;
        white-space: nowrap !important;
    }

    /* --- 1. La chapa del rol: intocable --------------------- */
    html body .top-navbar .user-meta,
    html body .top-navbar #user-role-badge {
        flex: 0 0 auto !important;
        order: 11 !important;
        min-width: 0 !important;
        margin-left: 0 !important;
        white-space: nowrap !important;
        overflow: visible !important;
    }
}

/* Pantallas muy angostas: el cartel se va.

   Por debajo de 560px, entre el logotipo, cuatro botones y la
   chapa del rol no quedan los 84px minimos para que la frase se
   entienda. Un cartel de tres letras y puntos suspensivos no
   informa nada y encima aprieta al resto. Lo que se anda
   trabajando se sigue viendo en la pestaña Mi Perfil. */
@media (max-width: 560px) {
    html body .top-navbar .rotativo,
    html body .rotativo {
        display: none !important;
    }
}

/* ==========================================================
   LA BARRA DE ESCRIBIR DEL CHAT

   1. El <textarea> traia el agarre de redimensionar del
      navegador —esa pastillita gris en la esquina—. Ademas de
      quedar burdo, dejaba estirar la caja a mano y romper el
      alto del panel. El campo ya crece solo con el texto
      (js/chat.js lo ajusta al escribir), asi que el agarre no
      hacia falta para nada.

   2. La zona se afina: era mas alta que el boton de enviar y se
      comia lugar de la conversacion, que es lo que importa.
   ========================================================== */

html body #chat-texto {
    resize: none !important;
    /* Sin el agarre de WebKit, que no respeta `resize`. */
    -webkit-appearance: none;
    appearance: none;
    padding: 7px 13px !important;
    min-height: 34px !important;
    max-height: 96px !important;
    font-size: 13.5px !important;
    line-height: 1.35 !important;
    /* La barra propia dentro de un campo de tres renglones es
       ruido: se desplaza igual con el dedo o la rueda. */
    scrollbar-width: none;
}

html body #chat-texto::-webkit-scrollbar { display: none; }
html body #chat-texto::-webkit-resizer { display: none; }

html body .chat-envio {
    gap: 6px !important;
    padding: 6px 8px !important;
    align-items: flex-end !important;
}

html body .chat-envio .chat-enviar,
html body .chat-envio .chat-clip {
    height: 34px !important;
    width: 34px !important;
    min-height: 34px !important;
    flex: 0 0 auto !important;
}

/* ==========================================================
   EL PANEL DEL CHAT CON EL TECLADO ABIERTO

   js/chat.js publica en `--teclado` cuantos pixeles tapa el
   teclado del telefono, medidos con `visualViewport`. Aca el
   panel se levanta esa misma cantidad y se acorta en la misma
   proporcion, asi la barra de escribir queda justo encima del
   teclado y la conversacion no pierde altura util de mas.

   La transicion es corta a proposito: acompaña el movimiento
   del teclado sin agregar una animacion que se note.
   ========================================================== */

:root {
    --teclado: 0px;
}

@media (max-width: 768px) {
    html body .chat-panel {
        bottom: var(--teclado, 0px) !important;
        /* `dvh` y no `vh`: en el telefono `vh` cuenta la barra de
           direcciones del navegador aunque no este a la vista. */
        height: calc(82dvh - var(--teclado, 0px) * 0.45) !important;
        max-height: calc(100dvh - var(--teclado, 0px) - 12px) !important;
        transition: bottom 140ms ease-out, height 140ms ease-out !important;
    }

    /* El fondo oscuro cubre todo igual: si se moviera con el panel
       se veria una franja clara abajo mientras sube el teclado. */
    html body .chat-fondo {
        bottom: 0 !important;
        height: 100dvh !important;
    }
}

/* Quien pidio menos movimiento no quiere que el panel se deslice
   detras del teclado: salta a la posicion final y listo. */
@media (prefers-reduced-motion: reduce) {
    html body .chat-panel { transition: none !important; }
}

/* ==========================================================
   PUBLICAR / ELIMINAR DEL ANUNCIO, EN LA MISMA LINEA

   No estaban desalineados por el contenedor: `.btn-primary`
   trae de index.css un `margin-top: 0.5rem` y un padding
   propio mas grande, y `.btn-danger` no. Resultado: el boton
   azul arrancaba medio centimetro mas abajo y media distinto
   que el rojo, en escritorio y en el telefono.

   Aca se igualan los dos y se les saca el margen. El alto lo
   fija la fila, no cada boton por su cuenta.
   ========================================================== */

html body #btn-save-announcement,
html body #btn-delete-announcement {
    margin: 0 !important;
    height: 42px !important;
    min-height: 42px !important;
    padding: 0 16px !important;
    font-size: 0.85rem !important;
    font-weight: 700 !important;
    border-radius: 10px !important;
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
    gap: 8px !important;
    box-shadow: none !important;
    white-space: nowrap !important;
}

/* El contenedor es el que manda: una sola linea, sin envolver.
   Con `flex-wrap: wrap` en un telefono angosto "Eliminar" se
   caia a un renglon propio. */
html body #btn-save-announcement {
    flex: 1 1 auto !important;
    min-width: 0 !important;
}

html body #btn-delete-announcement {
    flex: 0 0 auto !important;
}

html body #btn-save-announcement:not(.hidden) ~ #btn-delete-announcement,
html body #btn-delete-announcement {
    align-self: stretch !important;
}

/* ==========================================================
   CLIENTES EN EL TELEFONO: PRIMERO LA CARTERA

   En escritorio "A contactar" es una columna al costado y no
   estorba. Apilado en el telefono queda arriba de todo, asi que
   para llegar a la cartera —que es el titulo de la pantalla—
   hay que pasar antes por la cola de pendientes.

   Se invierte: primero el resultado, despues la cola.
   ========================================================== */

@media (max-width: 900px) {
    html body .clientes-split {
        display: flex !important;
        flex-direction: column !important;
    }

    html body .clientes-split .clientes-col   { order: 1 !important; }
    html body .clientes-split .contactar-panel { order: 2 !important; }
}

/* ==========================================================
   LA BANDEJA DE CONSULTAS EN EL TELEFONO

   Antes de ver la primera consulta habia que pasar tres tarjetas
   de metricas apiladas, un buscador, cinco listas desplegables y
   una tira de pastillas que se salia de la pantalla.

   El criterio: cada control ocupa lo que necesita y ni un pixel
   mas, y lo que no se usa todo el tiempo se pliega.
   ========================================================== */

/* --- El boton de filtros --------------------------------- */

html body .filtros-toggle {
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
    gap: 7px !important;
    flex: 0 0 auto !important;
    width: auto !important;
    height: 38px !important;
    padding: 0 12px !important;
    margin: 0 !important;
    border: 1px solid var(--borde-luz, var(--border-color)) !important;
    border-radius: 10px !important;
    background: var(--surf-2, rgba(255, 255, 255, 0.05)) !important;
    color: var(--text-muted) !important;
    font-size: 12.5px !important;
    font-weight: 600 !important;
    line-height: 1 !important;
    cursor: pointer !important;
    transition: border-color 140ms ease, color 140ms ease;
}

html body .filtros-toggle:hover,
html body .filtros-toggle[aria-expanded=true],
html body .filtros-toggle.con-filtros {
    border-color: var(--primary) !important;
    color: var(--primary) !important;
}

html body .filtros-cuenta {
    display: inline-flex !important;
    align-items: center;
    justify-content: center;
    min-width: 16px;
    height: 16px;
    padding: 0 4px;
    border-radius: 999px;
    background: var(--primary);
    color: #0a0a0b;
    font-size: 9.5px;
    font-weight: 800;
    line-height: 1;
}

html body .filtros-cuenta[hidden] { display: none !important; }

/* En escritorio el ancho sobra: nada se pliega. */
@media (min-width: 901px) {
    html body .filtros-toggle { display: none !important; }
    html body .etapa-movil    { display: none !important; }
}

@media (max-width: 900px) {

    /* --- 1. Metricas en el mismo renglon que importar/exportar.
       Eran tres tarjetas de 80px de alto, una debajo de la otra.
       Ahora son tres pastillas de una linea dentro del encabezado. */
    html body #tab-pipeline .section-head {
        display: flex !important;
        flex-wrap: wrap !important;
        align-items: center !important;
        gap: 8px !important;
        margin-bottom: 10px !important;
    }

    html body #tab-pipeline .section-head__texto {
        flex: 1 0 100% !important;
    }

    /* La bajada explicativa se lee una vez y despues estorba. */
    html body #tab-pipeline .section-head__texto p {
        display: none !important;
    }

    html body #tab-pipeline .section-head__acciones {
        flex: 1 0 100% !important;
        display: flex !important;
        flex-wrap: nowrap !important;
        align-items: center !important;
        gap: 8px !important;
        width: 100% !important;
    }

    html body #tab-pipeline #open-create-lead-btn {
        flex: 1 1 auto !important;
        min-width: 0 !important;
        height: 38px !important;
        min-height: 38px !important;
        margin: 0 !important;
        padding: 0 12px !important;
        font-size: 13px !important;
        border-radius: 10px !important;
        box-shadow: none !important;
    }

    html body #tab-pipeline .btn-grupo {
        flex: 0 0 auto !important;
        display: flex !important;
        gap: 6px !important;
    }

    html body #tab-pipeline .btn-grupo .btn {
        width: 38px !important;
        height: 38px !important;
        min-height: 38px !important;
        padding: 0 !important;
        margin: 0 !important;
        border-radius: 10px !important;
    }

    html body .consultas-resumen {
        flex: 1 0 100% !important;
        display: flex !important;
        flex-wrap: nowrap !important;
        gap: 6px !important;
        overflow-x: auto !important;
        scrollbar-width: none;
        margin: 0 !important;
        padding: 0 !important;
        background: none !important;
        border: none !important;
        box-shadow: none !important;
    }

    html body .consultas-resumen::-webkit-scrollbar { display: none; }

    /* Cada metrica en una linea. El subtitulo se va: en tres
       palabras no aporta y duplica la altura del bloque. */
    html body .consultas-resumen .resumen-item {
        flex: 0 0 auto !important;
        display: inline-flex !important;
        align-items: center !important;
        gap: 5px !important;
        width: auto !important;
        min-width: 0 !important;
        min-height: 0 !important;
        height: 30px !important;
        padding: 0 10px !important;
        border-radius: 999px !important;
        white-space: nowrap !important;
    }

    html body .consultas-resumen .resumen-item strong {
        font-size: 13px !important;
        line-height: 1 !important;
        margin: 0 !important;
    }

    html body .consultas-resumen .resumen-item span {
        font-size: 11px !important;
        line-height: 1 !important;
    }

    html body .consultas-resumen .resumen-item small {
        display: none !important;
    }

    /* --- 2. Buscar y filtrar: una fila, dos piezas ---------- */
    html body .consultas-busqueda {
        display: flex !important;
        align-items: center !important;
        gap: 8px !important;
        margin-bottom: 8px !important;
    }

    /* El buscador vuelve a ser lo que era: una caja con la lupa
       adentro y el campo al lado. El max-width global de 320px lo
       dejaba corto y el boton flotaba en el medio de la fila. */
    html body .consultas-busqueda .buscador {
        flex: 1 1 auto !important;
        display: flex !important;
        align-items: center !important;
        gap: 8px !important;
        width: auto !important;
        min-width: 0 !important;
        max-width: none !important;
        height: 38px !important;
        margin: 0 !important;
        padding: 0 12px !important;
        border-radius: 10px !important;
    }

    html body .consultas-busqueda .buscador i {
        flex: 0 0 auto !important;
        font-size: 12.5px !important;
        opacity: 0.6;
    }

    html body .consultas-busqueda .buscador input {
        flex: 1 1 auto !important;
        width: 100% !important;
        min-width: 0 !important;
        height: 100% !important;
        margin: 0 !important;
        padding: 0 !important;
        border: none !important;
        background: none !important;
        font-size: 13px !important;
    }

    /* Solo el icono: la palabra le roba ancho al buscador, que es
       lo que se usa todo el tiempo. El aria-label ya lo nombra. */
    html body .consultas-busqueda .filtros-texto {
        display: none !important;
    }

    html body .consultas-busqueda .filtros-toggle {
        width: 38px !important;
        padding: 0 !important;
    }

    html body .consultas-busqueda .filtros-toggle.con-filtros {
        width: auto !important;
        padding: 0 9px !important;
    }

    /* --- 3. La etapa: un desplegable, no una tira ----------- */
    html body .barra-etapas {
        display: none !important;
    }

    html body .etapa-movil {
        display: block !important;
        margin-bottom: 10px !important;
    }

    html body .etapa-movil[hidden] {
        display: none !important;
    }

    html body .etapa-movil select {
        width: 100% !important;
        max-width: none !important;
        height: 38px !important;
        margin: 0 !important;
        padding: 0 12px !important;
        border-radius: 10px !important;
        font-size: 13px !important;
        font-weight: 600 !important;
    }

    /* --- 4. Los otros cuatro filtros, plegados -------------- */
    html body .barra-filtros {
        display: none !important;
    }

    html body .barra-filtros.desplegada {
        display: grid !important;
        grid-template-columns: 1fr 1fr !important;
        gap: 8px !important;
        margin-bottom: 10px !important;
        padding: 0 !important;
        background: none !important;
        border: none !important;
    }

    html body .barra-filtros.desplegada > * {
        width: auto !important;
        min-width: 0 !important;
        max-width: none !important;
        height: 38px !important;
        margin: 0 !important;
        font-size: 12.5px !important;
    }
}

/* ==========================================================
   AJUSTES 20260807_626
   ========================================================== */

/* Logo de WhatsApp en SVG: no depende de la fuente de iconos de
   marcas, que a veces no llegaba y dejaba un cuadrado vacio. */
.ico-wa {
    width: 1em;
    height: 1em;
    vertical-align: -0.125em;
    flex: none;
}

.btn-fila .ico-wa {
    width: 16px;
    height: 16px;
    color: #25d366;
}

/* El boton "Filtros" se saco: las listas van siempre a la vista. */
.filtros-toggle { display: none !important; }

html body .barra-filtros {
    display: flex !important;
    flex-wrap: wrap;
    gap: 8px;
}

/* ==========================================================
   ESCRITORIO: EL CONTENIDO MIDE LO MISMO QUE LA BARRA
   20260807_627

   La barra superior y la fila de pestañas van de borde a borde,
   pero .tab-content estaba topado en 1320px y centrado: en un
   monitor ancho el contenido quedaba mas angosto que la barra
   que tiene encima, con dos franjas vacias a los costados. Se
   suelta el tope y se le da EL MISMO padding lateral que la
   barra (--e-5), asi los bordes coinciden en la misma linea.

   Solo de 900px para arriba: en el telefono no cambia nada.
   ========================================================== */

@media (min-width: 900px) {
    html body .tab-content {
        max-width: none !important;
        width: 100% !important;
        margin: 0 !important;
        padding-left: var(--e-5) !important;
        padding-right: var(--e-5) !important;
    }

    /* La cartera de clientes tenia su propio tope de 1180px, mas
       angosto todavia que el resto. Mismo criterio. */
    html body .clientes-wrap {
        max-width: none !important;
        margin-left: 0 !important;
        margin-right: 0 !important;
    }
}


/* El resumen de tres tarjetas del encabezado de la bandeja se
   quito por completo (ver index.html y js/triage.js): las cifras
   ya estan en la barra de etapas y en los filtros, y en el
   telefono las etiquetas quedaban cortadas. Con el se van sus
   estilos moviles, que existian solo para apretarlo. */
/* ==========================================================
   FOCO DEL EQUIPO: CAPTACION Y PROYECTOS
   20260807_629

   Reemplaza al ranking de facturacion. La tarjeta es la misma
   —misma posicion, mismo ancho, misma reja de dos columnas—:
   lo unico que cambia es lo que hay adentro. Las medidas estan
   elegidas para que el alto total quede igual o menor que el
   del bloque anterior: cinco pasos de embudo ocupan lo que
   ocupaban tres filas de ranking con su meta de tres lineas.
   ========================================================== */

/* --- Barras, comunes a los tres bloques --- */
.foco-barra {
    position: relative;
    height: 8px;
    border-radius: 999px;
    /* El riel iba con un blanco al 6%: sobre el tema claro eso es
       invisible y las barras quedaban flotando sin escala contra la
       que leerlas. Con el acento lavado funciona en los dos temas. */
    background: rgba(var(--acento-rgb), 0.12);
    overflow: hidden;
}

.foco-barra.fina { height: 6px; }

.foco-barra-fill {
    height: 100%;
    /* Todas las barras del mismo color: el acento. Lo que las
       distingue es la opacidad, que la pone el JS segun la
       posicion (ver CampaignsManager._opacidad). */
    background: var(--primary);
    border-radius: 999px;
    /* Sin transicion de ancho: estas barras se repintan cada vez
       que llegan leads nuevos y animarlas es trabajo del GPU por
       un dato que ya estaba a la vista. */
    /* Una etapa con un solo lead sobre miles da un ancho de 0,02%: sin
       piso, la barra desaparece y se lee como cero. Tres pixeles es lo
       minimo que se ve y sigue siendo honesto —se ve que es poquito. */
    min-width: 3px;
}

/* --- 1. Embudo --- */
.foco-paso { margin-bottom: 10px; }
.foco-paso:last-child { margin-bottom: 0; }

.foco-paso-head,
.foco-linea-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 10px;
    margin-bottom: 4px;
}

.foco-paso-label,
.foco-linea-label {
    font-size: 0.8rem;
    font-weight: 700;
    color: var(--text-main);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.foco-paso-cifra {
    font-size: 0.95rem;
    font-weight: 800;
    color: var(--text-main);
    font-variant-numeric: tabular-nums;
}

.foco-paso-pie {
    margin-top: 3px;
    font-size: 0.68rem;
    color: var(--text-dim);
}

/* --- 2. Canales --- */
.foco-linea { margin-bottom: 9px; }
.foco-linea:last-child { margin-bottom: 0; }

.foco-linea-cifra {
    font-size: 0.72rem;
    font-weight: 700;
    color: var(--text-dim);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* --- 3. Aporte del equipo --- */
.foco-persona { margin-bottom: 9px; }
.foco-persona:last-of-type { margin-bottom: 0; }

/* La barra apilada: tres tramos pegados, sin huecos. Se lee de
   una: cuanto es carga nueva, cuanto es seguimiento y cuanto
   termino en un cliente captado. */
.foco-barra.apilada {
    display: flex;
    height: 9px;
}

.foco-tramo { height: 100%; }
.foco-tramo:first-child { border-radius: 999px 0 0 999px; }
.foco-tramo:last-child { border-radius: 0 999px 999px 0; }

/* Los tres tramos eran celeste, violeta y acento. Ahora son el
   mismo acento en tres intensidades: el orden ya cuenta la
   historia (lo que se carga, lo que se mueve, lo que se cierra)
   y el mas cerrado es el mas brillante. */
.foco-tramo.cargadas,
.foco-punto.cargadas { background: rgba(var(--acento-rgb), 0.34); }

.foco-tramo.movimientos,
.foco-punto.movimientos { background: rgba(var(--acento-rgb), 0.62); }

.foco-tramo.captados,
.foco-punto.captados { background: var(--primary); }

/* El icono de cada fila: blanco, del tamaño del texto y con un
   ancho fijo para que las etiquetas arranquen todas alineadas
   aunque el icono sea mas angosto o mas ancho. */
.foco-ico {
    display: inline-block;
    width: 1.05em;
    margin-right: 5px;
    text-align: center;
    color: var(--text-main);
    opacity: 0.9;
}

.foco-leyenda {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    margin-top: 10px;
    padding-top: 8px;
    border-top: 1px solid var(--border-color);
    font-size: 0.66rem;
    color: var(--text-dim);
}

.foco-leyenda span {
    display: inline-flex;
    align-items: center;
    gap: 5px;
}

.foco-punto {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    display: inline-block;
}

/* En el telefono la reja de la tarjeta ya se apila sola; solo se
   aprieta un poco el interlineado para no ganar alto. */
@media (max-width: 899px) {
    .foco-paso { margin-bottom: 8px; }
    .foco-paso-pie { font-size: 0.64rem; }
    .foco-paso-label,
    .foco-linea-label { font-size: 0.76rem; }
}


/* ==========================================================
   LOGO DE WHATSAPP: TAMBIEN EN LAS OTRAS PANTALLAS
   20260807_630

   El SVG ya reemplazaba al icono de fuente en la bandeja, pero
   quedaban cinco lugares con el <i class="fa-brands"> viejo:
   "A contactar" y las fichas de la cartera, la lista de
   usuarios, la agenda de seguimiento y el campo del perfil. En
   todos se veia el mismo cuadrado vacio. Ahora todos usan
   CRM_ICONO_WA (js/schema.js) y solo hace falta darle medida
   segun el boton que lo contiene.
   ========================================================== */

.btn-mini .ico-wa,
.btn-xs .ico-wa,
.contactar-alta .btn-fila .ico-wa {
    width: 15px;
    height: 15px;
}

/* Dentro de un boton redondo el logo va centrado y en verde;
   suelto en un texto hereda el color de la linea. */
.btn-fila .ico-wa,
.btn-mini .ico-wa {
    color: #25d366;
}

/* En la tarjeta "A contactar" el boton es chico y redondo: el
   logo tiene que quedar centrado, no apoyado en la linea de
   base del texto. */
.contactar-item .btn-fila,
.contactar-alta .btn-fila {
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
}


/* ==========================================================
   LLAMADA DEL EQUIPO + SUBIDA DE ARCHIVOS
   20260807_633
   ========================================================== */

/* --- La ventana de la llamada ---------------------------------

   No es un modal comun: una videollamada quiere pantalla, no una
   tarjeta centrada con aire alrededor. Ocupa casi todo, con un
   borde para que se siga viendo que es una ventana del CRM. */
.llamada-modal {
    position: fixed;
    inset: 20px;
    z-index: 3000;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    background: #040405;
    border: 1px solid var(--borde-luz, rgba(255, 255, 255, 0.1));
    border-radius: 16px;
    box-shadow: 0 30px 90px rgba(0, 0, 0, 0.7);
}

.llamada-modal.hidden { display: none !important; }

.llamada-cabecera {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    flex: none;
    padding: 10px 14px;
    background: var(--surf-1, #17171a);
    border-bottom: 1px solid var(--border-color, #26262a);
}

.llamada-cabecera strong {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-size: 0.88rem;
    color: var(--text-main);
}

.llamada-cabecera i { color: var(--primary); }

/* Salir es rojo y esta solo: es la unica accion de esta barra y
   conviene que no se confunda con nada de adentro de Jitsi. */
.llamada-cerrar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    border: 1px solid rgba(239, 68, 68, 0.35);
    border-radius: 8px;
    background: rgba(239, 68, 68, 0.12);
    color: #f87171;
    cursor: pointer;
    transition: background 140ms ease;
}

.llamada-cerrar:hover { background: rgba(239, 68, 68, 0.22); }

/* Achicar es gris al lado del rojo de salir: son dos acciones muy
   distintas y equivocarse en una cuesta caro. */
.llamada-achicar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    margin-left: auto;
    border: 1px solid var(--border-color, #26262a);
    border-radius: 8px;
    background: rgba(255, 255, 255, 0.06);
    color: var(--text-dim);
    cursor: pointer;
    transition: background 140ms ease, color 140ms ease;
}

.llamada-achicar:hover {
    background: rgba(255, 255, 255, 0.12);
    color: var(--text-main);
}

/* Numeros de ancho fijo: si no, el reloj baila con cada segundo. */
.llamada-reloj {
    font-size: 0.78rem;
    font-variant-numeric: tabular-nums;
    color: var(--text-dim);
    letter-spacing: 0.04em;
}

.llamada-reloj.cerca { color: #f87171; }

/* --- La llamada achicada --------------------------------------

   Una ventanita abajo a la derecha, del tamaño de un video de
   chat. El CRM queda entero a la vista y se sigue trabajando con
   la llamada abierta, que era lo que faltaba. */
/* El lugar y la medida los pone el JS: la ventana se arrastra de la
   cabecera y se estira de la esquina, y donde uno la deja es donde
   vuelve a aparecer. `inset:auto` deja mandar a left/top. */
.llamada-modal.mini {
    inset: auto;
    border-radius: 12px;
    box-shadow: 0 16px 40px rgba(0, 0, 0, 0.6);

    /* Estirable desde la esquina de abajo a la derecha. Los minimos
       son el piso donde la barra de botones de Daily todavia entra:
       mas chico que esto no se lee nada. */
    resize: both;
    min-width: 260px;
    min-height: 190px;
    max-width: 100vw;
    max-height: 100vh;
}

/* Mover la ventana se agarra de la cabecera. */
.llamada-modal.mini .llamada-cabecera {
    padding: 6px 8px;
    gap: 6px;
    cursor: grab;
    touch-action: none;   /* que arrastrar no scrollee la pagina */
    user-select: none;
}

.llamada-modal.mini.arrastrando .llamada-cabecera { cursor: grabbing; }
.llamada-modal.mini .llamada-cabecera strong { font-size: 0.72rem; }

/* En chico no entra el titulo largo, solo el icono. */
.llamada-modal.mini .llamada-cabecera strong span { display: none; }

.llamada-modal.mini .llamada-achicar,
.llamada-modal.mini .llamada-cerrar { width: 24px; height: 24px; }

/* El icono se da vuelta: en chico ese boton agranda. */
.llamada-modal.mini .llamada-achicar i { transform: rotate(180deg); }

/* Mientras se arrastra, el iframe no se come el puntero: es de otro
   dominio y el movimiento se cortaba apenas el cursor lo pisaba. */
.llamada-modal.mini.arrastrando .llamada-marco { pointer-events: none; }

/* La esquina para estirar, a la vista: `resize` sin marca no se
   descubre nunca. Va encima del iframe. */
.llamada-modal.mini::after {
    content: "";
    position: absolute;
    right: 2px;
    bottom: 2px;
    width: 14px;
    height: 14px;
    pointer-events: none;
    background:
        linear-gradient(135deg, transparent 48%, var(--text-dim) 48%, var(--text-dim) 56%, transparent 56%),
        linear-gradient(135deg, transparent 68%, var(--text-dim) 68%, var(--text-dim) 76%, transparent 76%);
    opacity: 0.65;
}

@media (max-width: 899px) {
    /* En el telefono achicar no tiene sentido: la ventana chica
       ocuparia casi lo mismo y no queda CRM detras para mirar. El
       boton se esconde y la llamada va siempre a pantalla completa. */
    .llamada-achicar { display: none; }

    .llamada-modal.mini {
        inset: 0 !important;
        left: 0 !important;
        top: 0 !important;
        width: 100% !important;
        height: 100% !important;
        resize: none;
        border-radius: 0;
    }

    .llamada-modal.mini::after { display: none; }
}

.llamada-marco {
    flex: 1;
    min-height: 0;
    position: relative;
}

/* El iframe lo inyecta Jitsi: tiene que llenar el hueco. */
.llamada-marco iframe {
    width: 100% !important;
    height: 100% !important;
    border: 0 !important;
    display: block;
}

/* Centrado con transform y NO con flex.

   Con `display:flex` cada pedacito suelto del texto —cada frase,
   cada <br>, cada <code>— se convierte en un item y se acomoda
   en fila: el mensaje quedaba partido y descolocado. En flujo
   normal el texto se comporta como texto. */
.llamada-cargando {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: min(90%, 420px);
    margin: 0;
    text-align: center;
    color: var(--text-dim);
    font-size: 0.85rem;
    line-height: 1.7;
}

/* Los nombres de archivo y de ajuste, legibles: son para copiar. */
.llamada-cargando code {
    padding: 1px 5px;
    border-radius: 5px;
    background: rgba(255, 255, 255, 0.07);
    color: var(--text-main);
    font-size: 0.92em;
    white-space: nowrap;
}

/* En el telefono va a pantalla completa: 20px de margen en una
   pantalla de 6 pulgadas es lugar tirado. */
@media (max-width: 899px) {
    .llamada-modal {
        inset: 0;
        border: none;
        border-radius: 0;
    }
}

/* --- El chip del archivo mientras sube ------------------------

   Sin esto, elegir un archivo de 40 MB no muestra nada durante
   varios segundos y uno vuelve a tocar el clip pensando que no
   registro. La barra recorre en bucle porque Storage no informa
   el progreso real: dice "estoy trabajando", no "vas por 60%",
   que es la unica promesa que se puede cumplir. */
.chat-adjunto.subiendo {
    position: relative;
    overflow: hidden;
    opacity: 0.75;
}

.chat-adjunto.subiendo::after {
    content: '';
    position: absolute;
    left: 0;
    bottom: 0;
    width: 40%;
    height: 2px;
    background: var(--primary);
    animation: chat-subiendo 1.1s ease-in-out infinite;
}

@keyframes chat-subiendo {
    0%   { transform: translateX(-100%); }
    100% { transform: translateX(350%); }
}

/* El boton de enviar apagado mientras viaja el archivo. */
.chat-enviar:disabled {
    opacity: 0.45;
    cursor: not-allowed;
}

/* --- Imagen del chat que todavia no tiene su URL firmada ------
   Un rectangulo tenue en vez de un hueco roto: la burbuja ya
   tiene su tamaño y el texto no salta cuando entra la foto. */
.chat-imagen.cargando {
    display: block;
    min-height: 120px;
    border-radius: 10px;
    background: rgba(255, 255, 255, 0.05);
}

.chat-imagen.cargando img { opacity: 0; }


/* ==========================================================
   LLAMADAS: PANTALLA PROPIA, TIMBRE Y ENTRANTE
   20260807_634

   Todo lo que envuelve a la llamada usa la paleta del CRM: el
   acento sale de --primary / --acento-rgb, o sea que sigue el
   color que cada uno eligio en Apariencia. El unico pedazo que
   no se puede pintar es el interior del recuadro de video, que
   lo dibuja otro dominio (ver el comentario de js/llamada.js).
   ========================================================== */

/* --- 1. ELEGIR A QUIEN LLAMAR --------------------------------- */

.llamada-selector {
    position: fixed;
    inset: 0;
    z-index: 3100;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px;
    background: rgba(4, 4, 5, 0.72);
}

.llamada-selector.hidden,
.llamada-entrante.hidden,
.llamada-modal.hidden { display: none !important; }

.llamada-selector-caja {
    width: 100%;
    max-width: 400px;
    max-height: 85vh;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    /* Mismo degradado sutil que los paneles del CRM: la tarjeta se
       lee como parte de la aplicacion y no como una ventana del
       navegador pegada encima. */
    background:
        linear-gradient(180deg, rgba(255, 255, 255, 0.035) 0%, rgba(255, 255, 255, 0) 40%),
        var(--surf-1, #17171a);
    border: 1px solid var(--borde-luz, rgba(255, 255, 255, 0.1));
    border-radius: 18px;
    box-shadow: 0 30px 80px rgba(0, 0, 0, 0.65);
}

.llamada-selector-caja > header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    flex: none;
    padding: 15px 16px;
    border-bottom: 1px solid var(--border-color, #26262a);
}

.llamada-selector-caja > header strong {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    font-size: 0.95rem;
    font-weight: 700;
    color: var(--text-main);
}

/* El icono en su propia pastilla, como los encabezados de
   seccion del CRM. */
.llamada-selector-caja > header strong i {
    display: grid;
    place-items: center;
    width: 28px;
    height: 28px;
    border-radius: 8px;
    background: rgba(var(--acento-rgb), 0.14);
    color: var(--primary);
    font-size: 0.82rem;
}

/* "Todo el equipo" va separado y arriba: es la opcion que se
   usa el 90% de las veces y no tiene que competir con la lista. */
.llamada-todos {
    display: flex;
    align-items: center;
    gap: 11px;
    flex: none;
    margin: 14px 16px 6px;
    padding: 11px 13px;
    border: 1px solid rgba(var(--acento-rgb), 0.3);
    border-radius: 11px;
    background: rgba(var(--acento-rgb), 0.07);
    cursor: pointer;
    transition: background 140ms ease, border-color 140ms ease;
}

.llamada-todos:hover { background: rgba(var(--acento-rgb), 0.12); }

.llamada-todos span { display: flex; flex-direction: column; gap: 1px; }
.llamada-todos strong { font-size: 0.85rem; color: var(--text-main); }
.llamada-todos small { font-size: 0.7rem; color: var(--text-dim); }

.llamada-lista {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    padding: 4px 10px 10px;
}

.llamada-persona {
    display: flex;
    align-items: center;
    gap: 11px;
    padding: 9px 8px;
    border-radius: 10px;
    cursor: pointer;
    transition: background 140ms ease;
}

.llamada-persona:hover { background: rgba(255, 255, 255, 0.045); }

/* El punto de conectado.

   Gris apagado es "no tiene el CRM abierto", y eso importa: a esa
   persona el timbre no le llega a ningun lado. Verde es que suena.
   El nombre tambien se apaga, para que no haga falta interpretar
   un punto de seis pixeles. */
.llamada-punto {
    flex: 0 0 auto;
    width: 8px;
    height: 8px;
    margin-left: auto;
    border-radius: 50%;
    background: var(--text-dim);
    opacity: 0.4;
}

.llamada-persona.conectado .llamada-punto {
    background: #2be58b;
    opacity: 1;
    box-shadow: 0 0 0 3px rgba(43, 229, 139, 0.16);
}

.llamada-persona:not(.conectado) .llamada-nombre { opacity: 0.55; }

/* LA CASILLA, DIBUJADA POR NOSOTROS

   `accent-color` solo tiñe la casilla nativa: el cuadrado blanco
   del sistema seguia ahi y al lado de las tarjetas del CRM se
   veia prestado. Con `appearance: none` se apaga el dibujo del
   navegador y se hace de cero. */
/* Con `html body` y !important porque moderno.css le da a TODO
   input —con !important— alto de 36px, fondo de panel y esquinas
   redondeadas. Esa regla esta pensada para campos de texto, y una
   casilla no es un campo de texto. Empatando en !important gana el
   selector mas especifico, y por eso hace falta el prefijo: es el
   mismo recurso que ya usa ajustes.css en todo el proyecto. */
html body .llamada-persona input[type="checkbox"],
html body .llamada-todos input[type="checkbox"] {
    appearance: none !important;
    -webkit-appearance: none !important;
    flex: none;
    position: relative;
    width: 20px !important;
    height: 20px !important;
    min-height: 20px !important;
    max-height: 20px !important;
    margin: 0 !important;
    padding: 0 !important;
    border: 1.5px solid var(--borde-luz, rgba(255, 255, 255, 0.18)) !important;
    border-radius: 6px !important;
    background: rgba(255, 255, 255, 0.03) !important;
    cursor: pointer;
    transition: background 130ms ease, border-color 130ms ease;
}

html body .llamada-persona input[type="checkbox"]:hover,
html body .llamada-todos input[type="checkbox"]:hover {
    border-color: rgba(var(--acento-rgb), 0.5) !important;
}

html body .llamada-persona input[type="checkbox"]:checked,
html body .llamada-todos input[type="checkbox"]:checked {
    background: var(--primary) !important;
    border-color: var(--primary) !important;
}

/* El tilde: dos lineas y una rotacion, sin imagen ni fuente. */
html body .llamada-persona input[type="checkbox"]:checked::after,
html body .llamada-todos input[type="checkbox"]:checked::after {
    content: '';
    position: absolute;
    top: 2px;
    left: 6px;
    width: 5px;
    height: 10px;
    border: solid #06231a;
    border-width: 0 2.5px 2.5px 0;
    transform: rotate(43deg);
}

.llamada-persona input[type="checkbox"]:focus-visible,
.llamada-todos input[type="checkbox"]:focus-visible {
    outline: 2px solid rgba(var(--acento-rgb), 0.55);
    outline-offset: 2px;
}

/* La fila entera se enciende cuando esta elegida: el estado se lee
   de un vistazo, no hay que ir a mirar la casilla. */
.llamada-persona:has(input:checked) {
    background: rgba(var(--acento-rgb), 0.09);
}

.llamada-persona:has(input:checked) .llamada-nombre strong {
    color: var(--primary);
}

.llamada-todos:has(input:checked) {
    border-color: rgba(var(--acento-rgb), 0.55);
    background: rgba(var(--acento-rgb), 0.14);
}

.llamada-avatar {
    flex: none;
    display: grid;
    place-items: center;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    background: rgba(var(--acento-rgb), 0.16);
    color: var(--primary);
    font-weight: 800;
    font-size: 0.8rem;
}

.llamada-nombre { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.llamada-nombre strong {
    font-size: 0.84rem;
    color: var(--text-main);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.llamada-nombre small { font-size: 0.68rem; color: var(--text-dim); }

.llamada-vacio {
    margin: 0;
    padding: 22px 12px;
    text-align: center;
    font-size: 0.8rem;
    color: var(--text-dim);
}

.llamada-selector-caja > footer {
    display: flex;
    align-items: stretch;
    justify-content: flex-end;
    gap: 10px;
    flex: none;
    padding: 14px 16px;
    border-top: 1px solid var(--border-color, #26262a);
}

/* LOS DOS BOTONES, DEL MISMO ALTO Y EN LA MISMA LINEA

   Heredaban de `.btn` y `.btn-primary` del CRM, que traen
   rellenos distintos —uno tiene icono y el otro no—, asi que
   cada uno calculaba su alto y quedaban corridos entre si. Aca
   se les fija el alto y se centra el contenido, que es lo unico
   que hace falta para que se apoyen en la misma linea. */
.llamada-selector-caja > footer .btn {
    display: inline-flex !important;
    align-items: center;
    justify-content: center;
    gap: 8px;
    /* Con !important porque ajustes.css fija alturas de boton para
       toda la app; sin esto quedaban en 36px, mas chicos de lo que
       pide un dialogo que se toca desde el telefono. */
    height: 42px !important;
    min-height: 42px !important;
    padding: 0 20px !important;
    margin: 0 !important;
    border-radius: 11px !important;
    font-size: 0.85rem;
    font-weight: 700;
    line-height: 1;
    white-space: nowrap;
}

/* Llamar es la accion principal: va lleno, no delineado. Antes
   era un contorno del mismo peso visual que Cancelar y no se
   distinguia cual era cual. */
/* Con `html body` delante por lo mismo que las casillas: el
   `.btn-primary` del proyecto es delineado y gana por
   especificidad. Aca tiene que ir LLENO —es la accion principal
   del dialogo— para que se distinga de Cancelar de un vistazo. */
html body .llamada-selector-caja > footer .btn-primary {
    background: var(--primary) !important;
    background-image: none !important;
    border: 1px solid var(--primary) !important;
    color: #06231a !important;
    box-shadow: 0 4px 16px rgba(var(--acento-rgb), 0.28) !important;
}

html body .llamada-selector-caja > footer .btn-primary i {
    color: #06231a !important;
}

html body .llamada-selector-caja > footer .btn-primary:hover {
    filter: brightness(1.07);
}

html body .llamada-selector-caja > footer .btn:not(.btn-primary) {
    background: rgba(255, 255, 255, 0.05) !important;
    background-image: none !important;
    border: 1px solid var(--borde-luz, rgba(255, 255, 255, 0.12)) !important;
    color: var(--text-main) !important;
    box-shadow: none !important;
}

html body .llamada-selector-caja > footer .btn:not(.btn-primary):hover {
    background: rgba(255, 255, 255, 0.09) !important;
}

.llamada-selector-caja > footer .btn i {
    font-size: 0.9em;
    line-height: 1;
}

/* --- 2. LLAMADA ENTRANTE -------------------------------------- */

/* Va por encima de todo, incluso de un modal abierto: si suena,
   es lo unico que importa en ese momento. */
.llamada-entrante {
    position: fixed;
    inset: 0;
    z-index: 3500;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px;
    background: rgba(4, 4, 5, 0.8);
}

.llamada-entrante-caja {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 5px;
    width: 100%;
    max-width: 330px;
    padding: 30px 24px 24px;
    text-align: center;
    background: var(--surf-1, #17171a);
    border: 1px solid rgba(var(--acento-rgb), 0.35);
    border-radius: 20px;
    box-shadow: 0 24px 70px rgba(0, 0, 0, 0.7);
}

/* El circulo late: un cartel quieto no se lee como un telefono
   sonando. Es transform sobre un solo elemento, o sea que lo
   resuelve el compositor y no cuesta nada. */
.llamada-entrante-icono {
    display: grid;
    place-items: center;
    width: 64px;
    height: 64px;
    margin-bottom: 8px;
    border-radius: 50%;
    background: rgba(var(--acento-rgb), 0.15);
    color: var(--primary);
    font-size: 1.5rem;
    animation: llamada-latido 1.4s ease-in-out infinite;
}

@keyframes llamada-latido {
    0%, 100% { transform: scale(1);    box-shadow: 0 0 0 0 rgba(var(--acento-rgb), 0.35); }
    50%      { transform: scale(1.06); box-shadow: 0 0 0 14px rgba(var(--acento-rgb), 0); }
}

.llamada-entrante-caja > strong { font-size: 1.1rem; color: var(--text-main); }
.llamada-entrante-caja > small { font-size: 0.78rem; color: var(--text-dim); }

.llamada-entrante-botones {
    display: flex;
    gap: 10px;
    width: 100%;
    margin-top: 18px;
}

.llamada-atender,
.llamada-rechazar {
    flex: 1;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    height: 42px;
    border-radius: 11px;
    font-size: 0.85rem;
    font-weight: 700;
    cursor: pointer;
    border: 1px solid transparent;
    transition: filter 140ms ease, background 140ms ease;
}

.llamada-atender {
    background: var(--primary);
    color: #06231a;
}

.llamada-atender:hover { filter: brightness(1.08); }

.llamada-rechazar {
    background: rgba(239, 68, 68, 0.12);
    border-color: rgba(239, 68, 68, 0.35);
    color: #f87171;
}

.llamada-rechazar:hover { background: rgba(239, 68, 68, 0.2); }

/* En el telefono los botones se agrandan: se atiende con el
   pulgar y a veces sin mirar. */
@media (max-width: 899px) {
    .llamada-atender,
    .llamada-rechazar { height: 50px; font-size: 0.9rem; }
    .llamada-selector-caja { max-height: 90vh; }
}


/* El reloj de la llamada.

   Va en la cabecera, al lado del titulo. No es decoracion: Daily
   cobra por minuto y por persona, y ver que la llamada lleva 40
   minutos es lo que hace que alguien la corte. Cerca del limite
   se pone ambar, sin alarmismo. */
.llamada-reloj {
    margin-left: auto;
    margin-right: 12px;
    padding: 2px 9px;
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.06);
    color: var(--text-dim);
    font-size: 0.75rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    letter-spacing: 0.02em;
}

.llamada-reloj:empty { display: none; }

.llamada-reloj.cerca {
    background: rgba(245, 158, 11, 0.15);
    color: #fbbf24;
}

/* ==========================================================
   GRILLA DE CONSULTAS: MONOCROMA, DE CONTORNO Y CUADRADA

   Antes cada fila tenia hasta cinco colores propios: el canal
   rosa, el tipo verde, la prioridad ambar, la etapa celeste y
   el borde del estado. Cinco colores compitiendo es lo mismo
   que ninguno —la vista no sabe donde posarse— y ademas
   chocaban con el acento que cada uno elige en Apariencia.

   Ahora todo se dibuja con el acento de la app y SOLO en el
   contorno: el relleno queda transparente. Lo que distingue a
   un canal de otro pasa a ser el icono, que se lee sin tener
   que aprenderse una clave de colores.

   Va al final de picker.css, la ultima hoja que carga
   index.html: a igual especificidad gana la que se declara
   despues.
   ========================================================== */

/* --- Pastillas del triage (canal / tipo / prioridad) --------- */

html body .triage-chip {
    display: inline-flex !important;
    align-items: center !important;
    gap: 6px !important;
    /* Cuadrada, apenas matada la esquina. El pill de 999px era
       parte de lo que hacia ver la fila como un semaforo. */
    border-radius: 6px !important;
    padding: 4px 8px !important;
    font-size: 0.68rem !important;
    font-weight: 700 !important;
    line-height: 1 !important;
    white-space: nowrap !important;

    background: transparent !important;
    border: 1px solid rgba(var(--acento-rgb), 0.34) !important;
    color: var(--text-main) !important;
    box-shadow: none !important;
}

/* El icono es lo unico que lleva el acento a fondo: hace de
   ancla para el ojo sin pintar la pastilla entera. */
html body .triage-chip i {
    color: var(--primary) !important;
    font-size: 0.78em !important;
    line-height: 1 !important;
}

html body .grid-fila:hover .triage-chip {
    border-color: rgba(var(--acento-rgb), 0.55) !important;
}

/* --- Select de etapa dentro de la fila ---------------------- */

/* Estaba cortado: 148px minimos para "Reunión Agendada" con su
   emoji adelante no alcanzan, y el texto se comia la flecha del
   desplegable. Se achica la letra, se le saca el emoji al ancho
   pedido y se deja que la celda mande. */
html body .quick-status-select,
html body .etapa-select {
    width: 100% !important;
    min-width: 0 !important;
    max-width: 100% !important;
    box-sizing: border-box !important;
    height: 28px !important;
    min-height: 28px !important;
    max-height: 28px !important;
    padding: 0 6px !important;
    font-size: 11.5px !important;
    font-weight: 700 !important;

    border-radius: 6px !important;
    background: transparent !important;
    border: 1px solid rgba(var(--acento-rgb), 0.28) !important;
    color: var(--text-main) !important;

    /* Sin esto el texto largo empuja la flecha fuera de la caja
       en vez de recortarse. */
    text-overflow: ellipsis !important;
}

html body .etapa-select:hover,
html body .etapa-select:focus {
    background: transparent !important;
    border-color: rgba(var(--acento-rgb), 0.6) !important;
    color: var(--primary) !important;
    outline: none !important;
}

/* --- Botones de accion de la fila --------------------------- */

html body .btn-fila {
    border-radius: 6px !important;
    width: 28px !important;
    height: 28px !important;
    min-height: 28px !important;
    max-height: 28px !important;
}

/* --- La barra lateral de color del estado ------------------- */

/* La franja de la izquierda de cada fila tambien era del color
   del estado. Con la fila ya monocroma, ese unico trazo de
   color se volvia el elemento mas ruidoso de la pantalla. */
html body .grid-fila {
    --estado-color: rgba(var(--acento-rgb), 0.55);
    --prio-color: rgba(var(--acento-rgb), 0.55);
}

/* ==========================================================
   CERRAR SESION: QUIETO

   El boton se agrandaba y soltaba un halo verde al apuntarlo.
   Vive pegado al logotipo, o sea en la parte de la pantalla que
   uno cruza con el mouse cien veces por dia yendo a otra cosa:
   cada paso encendia una luz que pedia atencion para una accion
   que nadie quiere hacer por accidente.

   Se queda quieto. Al apuntarlo solo se marca el contorno, que
   es suficiente para saber que es pulsable.
   ========================================================== */

html body .brand-container #logout-btn {
    border-radius: 8px !important;
    width: 30px !important;
    height: 30px !important;
    background: transparent !important;
    border: 1px solid rgba(var(--acento-rgb), 0.28) !important;
    color: var(--primary) !important;
    box-shadow: none !important;
    transform: none !important;
    transition: border-color 0.15s ease !important;
}

html body .brand-container #logout-btn:hover,
html body .brand-container #logout-btn:focus,
html body .brand-container #logout-btn:active {
    background: transparent !important;
    color: var(--primary) !important;
    border-color: rgba(var(--acento-rgb), 0.65) !important;
    transform: none !important;
    box-shadow: none !important;
}

/* El orden en el DOM no alcanza: el cartel rotativo, el chat, la
   llamada y el selector de apariencia se inyectan por JS dentro de
   .brand-container y se meten entre el "CRM" y el boton. El orden
   visual se fija aca, que es donde se decide como se ve la barra y
   no en cinco archivos que no saben uno del otro. */
html body .brand-container > * { order: 5; }
html body .brand-container .logo-wrapper { order: 1; }
html body .brand-container .crm-badge-pill { order: 2; }
html body .brand-container #logout-btn { order: 3; }
html body .brand-container #realtime-status { order: 4; }

/* ==========================================================
   UNA SOLA FORMA DE VER UNA CONSULTA: LA FICHA

   Habia dos disenos para lo mismo: tabla de ocho columnas en la
   compu y ficha en el telefono. Dos disenos son dos cosas que
   mantener, dos que se desincronizan —la columna Presupuesto ya
   habia quedado en una y no en la otra— y, para el que usa las
   dos pantallas, dos lugares distintos donde buscar el mismo
   dato.

   Gana la ficha. La tabla ordena bien cuando se comparan filas
   entre si; pero acá casi nunca se compara: se busca una consulta
   y se hace algo con ella. Para eso la ficha es mejor, porque
   agrupa lo que se lee junto —nombre y telefono, los tres chips,
   la fecha y el plazo— y deja los botones de accion a lo ancho,
   que se pulsan igual con el mouse que con el pulgar.

   Va al final de picker.css para ganarle a la regla de ocho
   columnas de mas arriba en esta misma hoja.
   ========================================================== */

/* La cabecera de columnas no tiene sentido sin columnas. El orden
   se sigue eligiendo, pero desde el desplegable de la barra de
   filtros. */
html body .grid-head {
    display: none !important;
}

/* El contenedor deja de ser una tabla con marco: cada ficha trae
   el suyo. */
html body .grid-consultas {
    background: transparent !important;
    border: none !important;
    box-shadow: none !important;
    overflow: visible !important;
    border-radius: 0 !important;
}

html body .grid-fila {
    display: grid !important;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr) !important;
    grid-template-areas:
        'cliente cliente etapa'
        'canal   tipo    prio'
        'resp    fecha   fecha'
        'acc     acc     acc' !important;
    gap: 8px !important;
    padding: 14px 14px 14px 18px !important;
    margin-bottom: 10px !important;
    min-height: 0 !important;

    border: 1px solid var(--borde-luz) !important;
    border-radius: 14px !important;
    background:
        linear-gradient(180deg, rgba(255, 255, 255, 0.03), transparent 45%),
        var(--surf-1) !important;
    box-shadow: var(--elev-1) !important;
}

/* La franja del estado sigue el radio de la ficha; si no, sobresale
   por las esquinas de arriba y de abajo. */
html body .grid-fila::before {
    border-radius: 14px 0 0 14px !important;
}

/* Cada celda a su area. Compartir area y separar con justify-self
   no alcanza: los items se apilan en el mismo track y se pisan. */
html body .celda-cliente { grid-area: cliente !important; }
html body .celda-etapa   { grid-area: etapa !important; justify-self: end !important; }

html body .grid-fila > .grid-td:nth-child(2) { grid-area: canal !important; }
html body .grid-fila > .grid-td:nth-child(3) { grid-area: tipo !important; }
html body .grid-fila > .grid-td:nth-child(4) { grid-area: prio !important; }

html body .celda-responsable {
    grid-area: resp !important;
    font-size: 0.76rem !important;
    text-align: left !important;
}

html body .celda-fecha {
    grid-area: fecha !important;
    flex-direction: row !important;
    justify-content: flex-end !important;
    align-items: baseline !important;
    gap: 6px !important;
    font-size: 0.76rem !important;
}

/* Los tres botones a lo ancho, repartidos en partes iguales.
   Visibles siempre: en la tabla se atenuaban hasta pasar el mouse,
   pero en una ficha son el motivo por el que se la mira. */
html body .celda-acciones {
    grid-area: acc !important;
    display: flex !important;
    justify-content: stretch !important;
    gap: 8px !important;
    opacity: 1 !important;
    padding-top: 8px !important;
    border-top: 1px solid rgba(255, 255, 255, 0.05) !important;
}

html body .celda-acciones .btn-fila {
    flex: 1 !important;
    width: auto !important;
    height: 38px !important;
    max-height: 38px !important;
}

/* El select de etapa se encoge para no empujar al nombre: arriba a
   la derecha comparte fila con el, y el nombre es lo que se busca. */
html body .celda-etapa .etapa-select {
    width: auto !important;
    max-width: 190px !important;
    height: 32px !important;
    max-height: 32px !important;
    font-size: 12px !important;
}

/* --- La prioridad, en grande -------------------------------------
   La inicial de la prioridad ocupa el hueco vacio de la derecha de la
   ficha, a la altura del nombre y del rubro. Es la letra que ordena la
   lectura de la lista: se ve antes de leer nada.

   Sale del flujo con position: absolute, asi que no entra en las areas
   de la grilla y no empuja a ninguna celda. Y no recibe clics: la ficha
   entera se abre al tocarla, la letra no puede comerse ese toque. */
html body .grid-fila > .fila-prio-letra {
    position: absolute !important;
    top: 50% !important;
    right: 13% !important;
    transform: translateY(-62%) !important;
    z-index: 0 !important;

    /* Roboto es la tipografia del logotipo de Solutions Code. Va con
       !important porque moderno.css impone la sans de la interfaz a
       todo lo que sea un span. */
    font-family: 'Roboto', 'Inter', system-ui, sans-serif !important;
    font-size: clamp(40px, 13vw, 56px) !important;
    line-height: .82 !important;
    font-weight: 900 !important;
    letter-spacing: -.02em !important;
    color: rgb(var(--acento-rgb)) !important;
    /* Casi opaca: es el dato que ordena la lectura de la lista, no una
       marca de agua. Vive en el hueco de la derecha, asi que no le
       compite a nada. */
    opacity: .92 !important;
    pointer-events: none !important;
    user-select: none !important;
}

/* Alta pesa mas que baja, y la letra lo dice sin decirlo. */
html body .grid-fila > .fila-prio-letra[data-prio="alta"]  { opacity: 1 !important; }
html body .grid-fila > .fila-prio-letra[data-prio="baja"]  { opacity: .72 !important; }

/* La pastilla de prioridad se va de la ficha: la letra dice lo mismo
   sin gastar un renglon. La celda sigue en el DOM para no correr los
   nth-child del resto. */
html body .grid-fila > .celda-prio { display: none !important; }

/* Los chips no pueden ensanchar su columna ni recortarse feo. */
html body .grid-fila > .grid-td:nth-child(2) .triage-chip,
html body .grid-fila > .grid-td:nth-child(3) .triage-chip,
html body .grid-fila > .grid-td:nth-child(4) .triage-chip {
    display: flex !important;
    justify-content: center !important;
    overflow: hidden !important;
}

/* ==========================================================
   LA FICHA, CON MATERIAL

   Efectos que no dependen del tamaño de pantalla ni del puntero:
   nada que se rompa en telefono, tablet o compu. La regla que
   seguimos: los efectos de reposo son iguales en todos lados, y
   solo lo que necesita mouse va detras de @media (hover: hover).
   ========================================================== */

/* La ficha se vuelve el contexto de posicionamiento de sus capas
   y recorta lo que sobresalga: sin esto el brillo de arriba se
   escapa por las esquinas redondeadas. */
html body .grid-fila {
    position: relative !important;
    overflow: hidden !important;
    isolation: isolate !important;
    transition:
        transform 200ms cubic-bezier(0.22, 1, 0.36, 1),
        border-color 200ms ease,
        box-shadow 200ms ease !important;
}

/* 1. FILO DE LUZ. Una linea de 1px mas clara que el borde, del
      ancho de la ficha y desvanecida en las puntas. Es lo que
      hace que la caja se lea como material y no como un
      rectangulo de color. */
html body .grid-fila::after {
    content: '' !important;
    position: absolute !important;
    top: 0 !important;
    left: 14% !important;
    right: 14% !important;
    height: 1px !important;
    pointer-events: none !important;
    z-index: 1 !important;
    background: linear-gradient(90deg,
        transparent,
        rgba(255, 255, 255, 0.18),
        transparent) !important;
}

/* 2. LA FRANJA DEL ESTADO deja de ser un bloque plano: se
      degrada hacia abajo, como si la luz entrara desde arriba. */
html body .grid-fila::before {
    background: linear-gradient(180deg,
        rgba(var(--acento-rgb), 0.85),
        rgba(var(--acento-rgb), 0.25)) !important;
    width: 3px !important;
    border-radius: 14px 0 0 14px !important;
}

/* 3. AL APOYAR EL DEDO / SOLTAR EL CLICK. Va sin media query
      porque :active funciona igual en tactil y con mouse: es el
      unico acuse de recibo que tiene el telefono. */
html body .grid-fila:active {
    transform: scale(0.995) !important;
}

/* 4. AL APUNTAR CON EL MOUSE. Solo donde hay mouse de verdad:
      en tactil, :hover se queda pegado despues de tocar y la
      ficha quedaria levantada hasta que toques otra cosa. */
@media (hover: hover) and (pointer: fine) {
    html body .grid-fila {
        cursor: pointer !important;
    }

    html body .grid-fila:hover {
        transform: translateY(-2px) !important;
        border-color: rgba(var(--acento-rgb), 0.32) !important;
        box-shadow:
            0 1px 1px rgba(0, 0, 0, 0.3),
            0 8px 24px rgba(0, 0, 0, 0.34),
            0 0 0 1px rgba(var(--acento-rgb), 0.08) !important;
    }

    /* Un resplandor tenue que nace de la franja del estado y se
       apaga a un tercio del ancho. Aparece solo al apuntar: en
       reposo seria una mancha permanente. */
    html body .grid-fila:hover::before {
        box-shadow: 0 0 18px rgba(var(--acento-rgb), 0.45) !important;
    }
}

/* 5. EL NOMBRE, que es lo que se busca al barrer la lista. */
html body .fila-nombre {
    font-size: 0.95rem !important;
    font-weight: 800 !important;
    letter-spacing: -0.01em !important;
    line-height: 1.25 !important;
}

html body .fila-sub {
    font-size: 0.74rem !important;
    color: var(--text-dim, var(--text-muted)) !important;
}

/* La fecha con ancho de cifra fijo: al ordenar por ingreso, los
   numeros no bailan de fila en fila. */
html body .celda-fecha > span:first-child {
    font-variant-numeric: tabular-nums !important;
    font-feature-settings: 'tnum' 1 !important;
    letter-spacing: 0.02em !important;
}

/* ==========================================================
   EL SELECT DE ETAPA, CON SU ICONO AFUERA
   ========================================================== */

html body .etapa-caja {
    display: inline-flex !important;
    align-items: center !important;
    gap: 6px !important;
    max-width: 100% !important;
    padding: 0 8px !important;
    height: 32px !important;
    border-radius: 8px !important;
    border: 1px solid rgba(var(--acento-rgb), 0.28) !important;
    background: transparent !important;
    transition: border-color 150ms ease !important;
}

html body .etapa-caja:hover,
html body .etapa-caja:focus-within {
    border-color: rgba(var(--acento-rgb), 0.6) !important;
}

html body .etapa-ico-select {
    flex: 0 0 auto !important;
    font-size: 0.76rem !important;
    color: var(--primary) !important;
}

/* El select pierde su propia caja: la caja ahora es el contenedor
   que comparte con el icono. */
html body .etapa-caja .etapa-select {
    border: 0 !important;
    border-radius: 0 !important;
    background: transparent !important;
    padding: 0 !important;
    height: 100% !important;
    max-height: 100% !important;
    min-width: 0 !important;
    width: auto !important;
    max-width: 100% !important;
}

/* ==========================================================
   BARRA DE FILTROS: ICONO AFUERA Y ESQUINAS MAS SECAS

   Cada filtro es ahora un <i> y un <select> compartiendo una
   caja. El icono no puede ir adentro del <select> porque un
   <option> nativo no admite HTML: solo texto, y por eso lo unico
   que entraba era un emoji de colores.

   La caja toma el aspecto que antes tenia el select —borde,
   fondo, alto— y el select adentro se queda desnudo.
   ========================================================== */

html body .filtro-caja {
    display: inline-flex !important;
    align-items: center !important;
    gap: 7px !important;
    box-sizing: border-box !important;

    /* Las seis se reparten una sola fila y se encogen parejo. El
       `width: 100%` que habia aca antes hacia que cada una ocupara
       un renglon entero: seis filtros, seis renglones, media
       pantalla comida antes de la primera consulta. */
    flex: 1 1 120px !important;
    width: auto !important;
    min-width: 0 !important;

    height: 32px !important;
    padding: 0 9px !important;

    /* 8px en vez de la pastilla de antes: mas seco, y hace juego
       con las fichas y las pastillas de etapa. */
    border-radius: 8px !important;
    border: 1px solid var(--borde-luz) !important;
    background: var(--surf-0) !important;
    transition: border-color 150ms ease !important;
}

html body .filtro-caja:hover,
html body .filtro-caja:focus-within {
    border-color: rgba(255, 255, 255, 0.18) !important;
}

/* Con un valor elegido, el contorno y el icono toman el acento.
   Es el reemplazo de `.filtro-activo`, que pintaba el select
   entero. */
html body .filtro-caja.con-valor {
    border-color: rgba(var(--acento-rgb), 0.5) !important;
}

html body .filtro-ico {
    flex: 0 0 auto !important;
    width: 14px !important;
    font-size: 0.8rem !important;
    text-align: center !important;
    color: var(--text-muted) !important;
    transition: color 150ms ease !important;
}

html body .filtro-caja.con-valor .filtro-ico {
    color: var(--primary) !important;
}

/* El select pierde su caja: la caja es el contenedor. Sin
   min-width:0 el texto largo lo ensancha y desborda la barra. */
html body .filtro-caja .select-field {
    flex: 1 1 auto !important;
    min-width: 0 !important;
    width: 100% !important;
    height: 100% !important;
    padding: 0 !important;
    padding-right: 2px !important;
    border: 0 !important;
    border-radius: 0 !important;
    background: transparent !important;
    box-shadow: none !important;
    font-size: 0.8rem !important;
    text-overflow: ellipsis !important;
}

/* El halo verde de "filtro activo" ahora lo lleva la caja. */
html body .filtro-caja .select-field.filtro-activo {
    background: transparent !important;
    border: 0 !important;
    box-shadow: none !important;
    color: var(--primary) !important;
}

/* La barra reparte a los seis filtros en columnas iguales. */
html body .barra-filtros {
    align-items: center !important;
}

/* En el telefono, la etapa se muda a su propio hueco arriba de la
   lista. Se muda con caja y todo, asi que la caja tiene que ocupar
   el ancho completo ahi adentro igual que lo hacia el select solo. */
html body .etapa-movil .filtro-caja {
    width: 100% !important;
    height: 38px !important;
    margin-bottom: 10px !important;
}

/* --- La fila de filtros, mas compacta ------------------------ */

/* Sin wrap en compu y tablet: los seis en una sola linea. Se
   encogen antes que bajar, y el texto largo se recorta con
   puntos suspensivos. Bajar de a uno era peor que recortar:
   ocupaba seis renglones para decir "no hay ningun filtro
   puesto". */
/* Con el id delante, no por gusto: `.barra-filtros.desplegada`
   (dos clases) le ganaba por especificidad a `.barra-filtros` y
   dejaba la barra en grilla de dos columnas, o sea tres renglones
   de filtros en una tablet. Un `#` termina la discusion.

   Flex y no grid a proposito: abajo de 900px el filtro de etapa se
   muda a su propio hueco (js/filtros.js) y en la barra quedan
   cinco en vez de seis. Con `flex: 1 1 0` se reparten lo que haya
   sin que sobre una columna vacia. */
@media (min-width: 700px) {
    html body #consultas-filtros {
        display: flex !important;
        flex-wrap: nowrap !important;
        align-items: center !important;
        gap: 7px !important;
    }

    html body #consultas-filtros > .filtro-caja {
        flex: 1 1 0 !important;
        min-width: 0 !important;
        max-width: none !important;
    }
}

/* Debajo de 700px vuelven a envolverse, de a dos por renglon.
   Uno por renglon desperdicia la mitad del ancho; tres no entran
   sin cortar el texto al ras. */
/* Debajo de 700px vuelven a envolverse, de a dos por renglon.
   Uno por renglon desperdicia la mitad del ancho; tres no entran
   sin cortar el texto al ras. */
@media (max-width: 699px) {
    html body #consultas-filtros {
        display: flex !important;
        flex-wrap: wrap !important;
        gap: 7px !important;
    }

    html body #consultas-filtros > .filtro-caja {
        flex: 1 1 calc(50% - 4px) !important;
        max-width: none !important;
    }
}

html body .filtro-ico {
    width: 13px !important;
    font-size: 0.74rem !important;
}

html body .filtro-caja .select-field {
    font-size: 0.76rem !important;
    font-weight: 600 !important;
}

/* La etapa mudada al telefono ocupa su renglon entero: ahi esta
   sola y es el filtro principal de esa pantalla. */
html body .etapa-movil .filtro-caja {
    flex: 1 1 100% !important;
    width: 100% !important;
    height: 36px !important;
    margin-bottom: 10px !important;
}

/* Algo aguas arriba le pone min-height a todo lo que cuelga de la
   barra de filtros, y un min-height le gana a un height. Se fija
   la altura por los tres lados para que 32 sea 32. */
html body #consultas-filtros .filtro-caja {
    height: 32px !important;
    min-height: 32px !important;
    max-height: 32px !important;
}

html body #consultas-filtros .filtro-caja .select-field {
    height: 100% !important;
    min-height: 0 !important;
    max-height: 100% !important;
}

/* El select de adentro no puede tener caja propia: la caja es el
   `.filtro-caja` que comparte con el icono. Dos cajas anidadas es
   lo que se veia como "un boton adentro de otro boton".

   Va con el id delante a proposito. La regla que le devolvia el
   borde vive en otra hoja con la misma especificidad que la
   nuestra (`html body .algo .select-field`), y a igual peso gana
   la ultima declarada — que no siempre es esta. Con `#` de por
   medio, el empate se termina.

   Se cubren los dos lugares donde puede vivir un filtro: la barra
   y el hueco al que se muda la etapa en el telefono. */
html body #consultas-filtros .filtro-caja > .select-field,
html body #etapa-movil .filtro-caja > .select-field {
    border: 0 !important;
    border-width: 0 !important;
    border-style: none !important;
    border-radius: 0 !important;
    background: none !important;
    background-color: transparent !important;
    box-shadow: none !important;
    outline: none !important;

    /* Los anchos fijos de la barra tampoco valen aca dentro: el
       ancho lo pone la caja y el select la llena. */
    flex: 1 1 auto !important;
    width: 100% !important;
    min-width: 0 !important;
    max-width: none !important;
    padding: 0 !important;
}

/* La linea de ayuda bajo el selector de prioridad: dice que
   prioridad le pondria el triage. Chica y apagada a proposito —es
   contexto para decidir, no una instruccion. */
html body .ayuda-campo {
    display: block !important;
    margin-top: 5px !important;
    font-size: 0.7rem !important;
    line-height: 1.35 !important;
    color: var(--text-dim, var(--text-muted)) !important;
}

/* ==========================================================
   LA CONSULTA COMO TARJETA DE CRÉDITO

   Antes cada dato venia dentro de su propia cajita con borde:
   tres chips que parecian botones, el select con marco, los
   accesos con marco. Seis rectangulos compitiendo, y ninguno
   era lo que se busca al barrer la lista.

   Una tarjeta de credito resuelve lo mismo sin un solo borde
   interno: jerarquia por tamaño y por peso, todo sobre una
   misma superficie. El numero grande y espaciado, el titular
   abajo en versalitas, y la letra chica arriba, apagada.

   Sin iconos de color: el color queda para el estado, que es
   el unico dato que cambia solo.
   ========================================================== */

html body .grid-fila {
    grid-template-areas:
        'canal   tipo    prio'
        'cliente cliente cliente'
        'resp    fecha   etapa'
        'acc     acc     acc' !important;
    gap: 0 !important;
    padding: 16px 18px 14px !important;
    margin-bottom: 12px !important;
    border-radius: 16px !important;

    /* Superficie con luz diagonal, como el plastico satinado de
       una tarjeta. El brillo nace arriba a la izquierda y muere
       antes de la mitad: si cruza entera, parece un boton. */
    background:
        linear-gradient(135deg,
            rgba(255, 255, 255, 0.055) 0%,
            rgba(255, 255, 255, 0.018) 26%,
            transparent 52%),
        var(--surf-1) !important;
    border-color: rgba(255, 255, 255, 0.07) !important;
}

/* La franja de estado ocupaba el lomo entero. Ahora es un punto
   al ras del borde: se ve de reojo, no compite con el nombre. */
html body .grid-fila::before {
    top: 18px !important;
    bottom: auto !important;
    left: 0 !important;
    width: 3px !important;
    height: 26px !important;
    border-radius: 0 3px 3px 0 !important;
}

/* --- Letra chica: canal, tipo y prioridad -------------------
   Sin caja, sin icono, sin color. Versalitas apagadas, como el
   "DEBIT" impreso arriba de una tarjeta. Se leen si las buscas
   y desaparecen si no. */
html body .grid-fila > .grid-td:nth-child(2),
html body .grid-fila > .grid-td:nth-child(3),
html body .grid-fila > .grid-td:nth-child(4) {
    min-width: 0 !important;
    margin-bottom: 12px !important;
}

html body .grid-fila > .grid-td:nth-child(2) .triage-chip,
html body .grid-fila > .grid-td:nth-child(3) .triage-chip,
html body .grid-fila > .grid-td:nth-child(4) .triage-chip {
    display: block !important;
    padding: 0 !important;
    border: 0 !important;
    background: none !important;
    box-shadow: none !important;
    justify-content: flex-start !important;
    text-align: left !important;

    font-size: 0.62rem !important;
    font-weight: 700 !important;
    letter-spacing: 0.1em !important;
    text-transform: uppercase !important;
    color: var(--text-dim, var(--text-muted)) !important;
    white-space: nowrap !important;
    text-overflow: ellipsis !important;
}

/* Los iconos de los chips se van: eran tres colores distintos
   discutiendo arriba de todo. */
html body .grid-fila > .grid-td:nth-child(2) .triage-chip i,
html body .grid-fila > .grid-td:nth-child(3) .triage-chip i,
html body .grid-fila > .grid-td:nth-child(4) .triage-chip i,
html body .grid-fila > .grid-td:nth-child(2) .triage-chip svg,
html body .grid-fila > .grid-td:nth-child(3) .triage-chip svg,
html body .grid-fila > .grid-td:nth-child(4) .triage-chip svg {
    display: none !important;
}

html body .grid-fila > .grid-td:nth-child(3) .triage-chip { text-align: center !important; }
html body .grid-fila > .grid-td:nth-child(4) .triage-chip { text-align: right !important; }

/* --- El bloque grande: nombre arriba, telefono abajo --------
   El nombre va primero y es lo mas grande de la ficha: es con
   lo que se busca a alguien al barrer la lista. El telefono
   queda debajo, en el lugar del numero impreso de la tarjeta:
   mas chico, pero con ancho de cifra fijo y espaciado, que es
   lo que lo hace legible de un vistazo al ir a marcar. */
html body .celda-cliente {
    display: flex !important;
    flex-direction: column !important;
    align-items: flex-start !important;
    gap: 5px !important;
    margin-bottom: 14px !important;
}

html body .celda-cliente .fila-nombre {
    font-size: 1.02rem !important;
    font-weight: 700 !important;
    letter-spacing: 0.01em !important;
    text-transform: none !important;
    color: var(--text-main) !important;
}

html body .celda-cliente .fila-sub {
    font-size: 0.8rem !important;
    font-weight: 500 !important;
    letter-spacing: 0.07em !important;
    color: var(--text-muted) !important;
    font-variant-numeric: tabular-nums !important;
    font-feature-settings: 'tnum' 1 !important;
}

/* --- Pie: responsable, plazo y etapa ------------------------ */
html body .celda-responsable,
html body .celda-fecha {
    font-size: 0.7rem !important;
    color: var(--text-dim, var(--text-muted)) !important;
    align-self: center !important;
}

html body .celda-fecha {
    justify-content: center !important;
}

html body .celda-etapa {
    justify-self: end !important;
    align-self: center !important;
}

/* El select pierde el marco: queda el texto y la flecha, que
   ya alcanzan para saber que se puede tocar. */
html body .celda-etapa .etapa-caja {
    padding: 0 !important;
    border: 0 !important;
    height: auto !important;
}

html body .celda-etapa .etapa-caja:hover,
html body .celda-etapa .etapa-caja:focus-within {
    border: 0 !important;
}

html body .celda-etapa .etapa-select {
    font-size: 0.7rem !important;
    font-weight: 700 !important;
    letter-spacing: 0.04em !important;
    text-transform: uppercase !important;
    color: var(--primary) !important;
}

/* --- Accesos: sin marco, separados por una hairline --------- */
html body .celda-acciones {
    margin-top: 14px !important;
    padding-top: 10px !important;
    border-top: 1px solid rgba(255, 255, 255, 0.06) !important;
    gap: 0 !important;
}

html body .celda-acciones .btn-fila {
    height: 32px !important;
    max-height: 32px !important;
    border: 0 !important;
    border-radius: 8px !important;
    background: transparent !important;
    color: var(--text-muted) !important;
    opacity: 0.75 !important;
    transition: opacity 150ms ease, background 150ms ease !important;
}

html body .celda-acciones .btn-fila + .btn-fila {
    box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.06) !important;
}

html body .celda-acciones .btn-fila:hover {
    opacity: 1 !important;
    background: rgba(255, 255, 255, 0.04) !important;
}

/* ==========================================================
   LA TARJETA EN EL TELEFONO

   El pie de la ficha era una sola fila de tres columnas
   (responsable, plazo, etapa). En una pantalla angosta no
   entran: el select de etapa se salia de su columna y quedaba
   encima del "sin responder", y la fecha se partia en dos
   renglones ("09-" / "ago").

   La etapa pasa a su propio renglon, a lo ancho y alineada a
   la izquierda. Es el unico dato de la ficha que se toca para
   cambiarlo, asi que gana lugar propio en vez de pelearlo.
   ========================================================== */

@media (max-width: 899px) {
    html body .grid-fila {
        grid-template-areas:
            'canal   tipo    prio'
            'cliente cliente cliente'
            'etapa   etapa   etapa'
            'resp    fecha   fecha'
            'acc     acc     acc' !important;
    }

    html body .celda-etapa {
        justify-self: start !important;
        max-width: 100% !important;
        margin-bottom: 10px !important;
    }

    /* Mas chico y con la caja de vuelta, apenas insinuada: en el
       telefono no hay hover que avise que se puede tocar. */
    html body .celda-etapa .etapa-caja {
        height: 28px !important;
        padding: 0 10px !important;
        border: 1px solid rgba(var(--acento-rgb), 0.28) !important;
        border-radius: 8px !important;
    }

    html body .celda-etapa .etapa-select {
        max-width: 100% !important;
        height: 28px !important;
        max-height: 28px !important;
        font-size: 0.64rem !important;
    }

    html body .celda-etapa .etapa-ico-select {
        font-size: 0.68rem !important;
    }

    /* El plazo vuelve a la derecha y no se parte al medio. */
    html body .celda-fecha {
        justify-content: flex-end !important;
        white-space: nowrap !important;
        min-width: 0 !important;
    }

    html body .celda-responsable,
    html body .celda-fecha {
        font-size: 0.68rem !important;
    }

    html body .celda-cliente .fila-nombre {
        font-size: 0.96rem !important;
    }

    html body .celda-cliente .fila-sub {
        font-size: 0.76rem !important;
        letter-spacing: 0.05em !important;
    }
}

/* El buscador del calendario ya tiene su propio borde en el
   contenedor: el input de adentro no debe dibujar el suyo ni el
   anillo de foco global, porque se ven dos cuadros uno dentro
   del otro. */
html body .cal-buscador > input#cal-buscar,
html body .cal-buscador > input#cal-buscar:focus,
html body .cal-buscador > input#cal-buscar:focus-visible {
    border: none !important;
    outline: none !important;
    box-shadow: none !important;
    background: transparent !important;
    transform: none !important;
}

/* La capa de eventos vive dentro de la pista, que si tiene el alto
   real de las 24 filas. Antes colgaba del contenedor con scroll y
   los % de `top` se median contra el alto visible: todo aparecia
   varias horas mas arriba de lo que era. */
html body .cal-pista {
    position: relative;
    min-height: 100%;
}

/* Igual para cualquier input dentro del buscador, incluido el
   anillo `outline` global de focus-visible: el marco lo pone el
   contenedor y nada mas. */
html body .cal-buscador,
html body .cal-buscador *,
html body .cal-buscador *:focus,
html body .cal-buscador *:focus-visible {
    outline: none !important;
    outline-offset: 0 !important;
}

html body .cal-buscador input,
html body .cal-buscador input:focus,
html body .cal-buscador input:focus-visible {
    border: 0 !important;
    box-shadow: none !important;
    background: transparent !important;
    transform: none !important;
}

/* Mismo criterio para el campo "ir a una fecha": el marco lo pone
   el label. El input de adentro traia borde, fondo y anillo de
   foco propios de las reglas globales y se veia una caja dentro
   de otra, ademas de desbordar a la derecha. */
html body .cal-ir,
html body .cal-ir *,
html body .cal-ir *:focus,
html body .cal-ir *:focus-visible {
    outline: none !important;
    outline-offset: 0 !important;
}

html body .cal-ir input[type="date"],
html body .cal-ir input[type="date"]:focus,
html body .cal-ir input[type="date"]:focus-visible {
    min-width: 0 !important;
    height: auto !important;
    min-height: 0 !important;
    padding: 0 !important;
    margin: 0 !important;
    border: 0 !important;
    box-shadow: none !important;
    background: transparent !important;
    transform: none !important;
}


/* ==========================================================
   LA PANTALLA DE ENTRADA

   Segunda version. La primera le habia dado presencia con una
   malla en perspectiva, dos luces de color y una tarjeta con
   borde iluminado y resplandor alrededor. Cada pieza estaba
   bien resuelta por separado, pero juntas hacian una pantalla
   que no se parecia en nada a la de carga que viene justo
   antes: el CRM cambiaba de cara entre una pantalla y la
   siguiente.

   Manda la de carga. Ahi hay un nombre sobre un fondo liso, y
   alcanza. Aca queda el mismo nombre, escrito de la misma
   forma —letra por letra—, y debajo lo minimo para entrar. La
   tarjeta ya no se dibuja: la sostiene el espacio en blanco.

   Se mantiene el criterio de rendimiento de la version
   anterior, que era lo bueno que tenia: todo lo que se mueve
   anima transform u opacity, nada corre en bucle, y despues
   de un segundo la pantalla queda quieta.
   ========================================================== */

#auth-screen {
    position: relative;
    overflow: hidden;
    background: var(--bg-main);
}

/* El fondo decorativo no se dibuja antes de entrar.

   Aca vivia una malla inclinada con perspectiva, y ademas se
   veia por debajo la trama que el usuario tenga elegida en
   Apariencia. Dos cuadriculas superpuestas detras de dos
   campos de texto. Ninguna de las dos aporta a lo unico que
   esta pantalla tiene que lograr, que es que alguien escriba
   su correo y entre. */
#auth-screen::before,
#auth-screen::after {
    content: none !important;
}

html:has(#auth-screen.active) body::before {
    background-image: none !important;
}

html:has(#auth-screen.active) #fondo-codigo,
html:has(#auth-screen.active) #fondo-imagen,
html:has(#auth-screen.active) #ambient-background-glow,
html:has(#auth-screen.active) .watermark-logo-glow-wrapper {
    display: none !important;
}

/* GARANTIA DURA: el login y el workspace nunca se ven juntos.
   auth.js los turna con classList (ver setupUserSession/showAuthScreen
   en js/auth.js), pero eso depende de que esa funcion termine de correr
   entera. Si una consulta a Supabase se cuelga o tira error a mitad de
   camino -mas facil de lo que parece con la base bajo estres-, `active`
   puede quedar puesto en el login mientras `hidden` ya se le saco al
   workspace unas lineas antes: los dos renderizan a la vez, uno arriba
   del otro en el flujo normal del documento, porque #auth-screen no es
   un overlay (`position: relative`, no `fixed`).

   Esto no depende de que el JS termine bien: mientras el login tenga
   `.active`, el workspace queda forzado a esconderse, sin importar que
   clases tenga puestas. */
html:has(#auth-screen.active) #crm-workspace {
    display: none !important;
}

/* --- La tarjeta que ya no es una tarjeta --------------------- */

html body .auth-card-3d {
    width: min(370px, 90vw) !important;
    max-width: none !important;
    padding: 0 !important;
    background: none !important;
    border: none !important;
    box-shadow: none !important;
    overflow: visible;

    /* La entrada del conjunto. Nada de latidos ni de anillos que se
       expanden: el bloque emerge una sola vez, desde un poco mas
       lejos y un poco mas abajo, mientras sus piezas se van armando
       adentro. El movimiento del contenedor es minimo a proposito
       —un 1.5% de escala— porque lo que tiene que llamar la atencion
       es el nombre escribiendose, no la caja moviendose.

       Dura 760 ms y termina. Despues de eso la pantalla esta quieta:
       nadie deberia buscar su contraseña sobre algo que se mueve. */
    animation: auth-emerge 760ms cubic-bezier(.16, 1, .3, 1) both !important;
}

@keyframes auth-emerge {
    from { opacity: 0; transform: translate3d(0, 16px, 0) scale(.985); }
    to   { opacity: 1; transform: none; }
}

/* --- El nombre ----------------------------------------------- */

html body .auth-card-3d .brand-header-3d {
    display: flex;
    justify-content: center;
    margin-bottom: 2.6rem;
    padding: 0 !important;
    border: none !important;
    background: none !important;
    animation: none !important;
}

html body .auth-card-3d .marca-splash {
    font-size: clamp(1.35rem, 5vw, 1.9rem);
}

/* --- Los campos: una linea, no una caja ---------------------- */

html body .auth-card-3d .form-group-3d {
    margin-bottom: 1.35rem;
    animation: auth-sube 520ms cubic-bezier(.16, 1, .3, 1) both;
}

html body .auth-card-3d .form-group-3d:nth-of-type(1) { animation-delay: 640ms; }
html body .auth-card-3d .form-group-3d:nth-of-type(2) { animation-delay: 710ms; }

/* Los campos entran despues del nombre: las trece letras
   terminan de escribirse a los 585 ms. */
html body .auth-card-3d .form-3d button[type="submit"] {
    animation: auth-sube 520ms cubic-bezier(.16, 1, .3, 1) 780ms both;
}

html body .auth-card-3d .auth-footer-3d {
    animation: auth-sube 520ms cubic-bezier(.16, 1, .3, 1) 850ms both;
}

@keyframes auth-sube {
    from { opacity: 0; transform: translate3d(0, 12px, 0); }
    to   { opacity: 1; transform: none; }
}

html body .auth-card-3d .form-group-3d label {
    display: block !important;
    font-size: 0.62rem !important;
    font-weight: 700 !important;
    letter-spacing: 0.18em !important;
    text-transform: uppercase;
    color: var(--text-dim) !important;
    margin-bottom: 0.55rem !important;
}

html body #auth-screen .input-glow-wrapper {
    position: relative;
    display: block;
    background: none !important;
    /* La raya de abajo no es un `border-bottom`: es la linea de
       ::before, que se dibuja sola al entrar. Un borde aparece hecho
       y no hay forma de trazarlo. */
    border: none !important;
    border-radius: 0 !important;
    box-shadow: none !important;
    padding: 0 !important;
}

/* Cada linea se traza de izquierda a derecha, una detras de la otra,
   como si el formulario se estuviera armando mientras lo mirás. Es
   scaleX con origen a la izquierda: lo resuelve el compositor, no
   repinta y no corre a nadie de lugar.

   Los tiempos entran detras del nombre —las trece letras terminan de
   escribirse a los 585 ms— y adelante del boton. */
html body #auth-screen .input-glow-wrapper::before {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 1px;
    background: var(--border-color);
    transform: scaleX(0);
    transform-origin: left center;
    animation: auth-traza 560ms cubic-bezier(.16, 1, .3, 1) both;
}

html body #auth-screen .form-group-3d:nth-of-type(1) .input-glow-wrapper::before { animation-delay: 660ms; }
html body #auth-screen .form-group-3d:nth-of-type(2) .input-glow-wrapper::before { animation-delay: 760ms; }

@keyframes auth-traza {
    from { transform: scaleX(0); }
    to   { transform: scaleX(1); }
}

html body #auth-screen .input-glow-wrapper input {
    width: 100%;
    background: transparent !important;
    border: none !important;
    box-shadow: none !important;
    outline: none !important;
    padding: 0.6rem 0 !important;
    height: auto !important;
    font-size: 0.92rem !important;
    color: var(--text-main) !important;
}

/* La linea del acento crece de punta a punta al enfocar. Es un
   scaleX sobre un pseudo-elemento: no mueve a nadie de lugar y
   lo resuelve el compositor. */
html body #auth-screen .input-glow-wrapper::after {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    bottom: -1px;
    height: 1px;
    background: rgb(var(--acento-rgb));
    transform: scaleX(0);
    transition: transform 300ms cubic-bezier(.2, .7, .3, 1);
}

html body #auth-screen .input-glow-wrapper:focus-within::after {
    transform: scaleX(1);
}

/* --- El boton ------------------------------------------------- */

/* Contorneado y no pintado. Un bloque de color solido es lo unico que
   pesa en una pantalla que por lo demas son dos rayas y un nombre: se
   comia el conjunto. El contorno pide lo mismo sin gritar, y deja que
   el color del acento se lea como acento y no como fondo. */
html body #auth-screen button[type="submit"] {
    position: relative;
    overflow: hidden;
    width: 100%;
    margin-top: 2rem;
    padding: 0.85rem 1rem !important;
    background: transparent !important;
    border: 1px solid rgba(var(--acento-rgb), 0.55) !important;
    border-radius: 10px !important;
    color: rgb(var(--acento-rgb)) !important;
    font-weight: 700 !important;
    font-size: 0.86rem !important;
    letter-spacing: 0.04em;
    box-shadow: none !important;
    transition: border-color 200ms ease, color 200ms ease, transform 180ms ease;
}

/* Al pasar por encima se rellena, pero desde adentro: una capa que
   crece en escala en vez de un cambio de color de fondo. El relleno
   es tenue —no invierte el texto— asi que no hay salto de contraste
   entre los dos estados. */
html body #auth-screen button[type="submit"]::before {
    content: '';
    position: absolute;
    inset: 0;
    z-index: 0;
    background: rgba(var(--acento-rgb), 0.14);
    transform: scaleY(0);
    transform-origin: bottom center;
    transition: transform 260ms cubic-bezier(.16, 1, .3, 1);
}

html body #auth-screen button[type="submit"] > * {
    position: relative;
    z-index: 1;
}

html body #auth-screen button[type="submit"]:hover {
    border-color: rgb(var(--acento-rgb)) !important;
    transform: translateY(-1px);
}

html body #auth-screen button[type="submit"]:hover::before {
    transform: scaleY(1);
}

html body #auth-screen button[type="submit"]:active {
    transform: translateY(0);
}

/* Mientras valida, el boton dice que esta trabajando. La clase la
   pone auth.js. */
html body #auth-screen button[type="submit"].entrando {
    pointer-events: none;
    opacity: .85;
}

html body #auth-screen button[type="submit"].entrando i {
    animation: auth-gira 900ms linear infinite;
}

@keyframes auth-gira {
    to { transform: rotate(360deg); }
}

/* --- El pie --------------------------------------------------- */

html body .auth-card-3d .auth-footer-3d {
    margin-top: 2rem;
    padding-top: 1.1rem;
    border-top: 1px solid var(--border-color);
    text-align: center;
    font-size: 0.7rem;
    color: var(--text-dim);
}

/* --- El aviso de error ---------------------------------------- */

html body #auth-screen .alert-box.error:not(.hidden) {
    margin-top: 1rem;
    animation: auth-sacude 420ms cubic-bezier(.36, .07, .19, .97) both;
}

/* Sacudida corta y chica: un error tiene que llamar la atencion
   sin parecer que la pantalla se rompio. */
@keyframes auth-sacude {
    0%, 100% { transform: translate3d(0, 0, 0); }
    20%      { transform: translate3d(-6px, 0, 0); }
    40%      { transform: translate3d(5px, 0, 0); }
    60%      { transform: translate3d(-3px, 0, 0); }
    80%      { transform: translate3d(2px, 0, 0); }
}

/* --- Sin movimiento -------------------------------------------
   Quien pidio no ver animaciones ve la misma pantalla, armada de
   una. No se pierde nada: son todas de entrada. */
@media (prefers-reduced-motion: reduce) {
    html body .auth-card-3d,
    html body .auth-card-3d .brand-header-3d,
    html body .auth-card-3d .form-group-3d,
    html body .auth-card-3d .marca-splash span span,
    html body .auth-card-3d .marca-splash__cursor,
    html body #auth-screen button[type="submit"],
    html body .auth-card-3d .auth-footer-3d {
        animation: none !important;
        opacity: 1 !important;
        transform: none !important;
    }
}

/* ==========================================================
   QUE ESTA RINDIENDO
   20260814_1

   Reusa entero el vocabulario del "Foco del equipo" —.foco-linea,
   .foco-barra, .campaign-grid— porque es la misma tarjeta con
   otro contenido. Aca solo va lo que ese bloque no tenia: la
   frase de lectura y la marca de muestra chica.
   ========================================================== */

/* La conclusion escrita, arriba de las dos columnas. Va con el
   acento lavado de fondo y no como parrafo suelto: es lo unico
   de la tarjeta que se lee en dos segundos y tiene que ganarle
   visualmente a las dos tablas que estan abajo. */
.rinde-lectura:not(:empty) {
    display: flex;
    align-items: flex-start;
    gap: 9px;
    margin: 0 0 1.1rem;
    padding: 10px 13px;
    border-radius: 12px;
    background: rgba(var(--acento-rgb), 0.09);
    border-left: 3px solid var(--primary);
    font-size: 0.78rem;
    line-height: 1.45;
    color: var(--text-main);
}

.rinde-lectura i {
    color: var(--primary);
    margin-top: 2px;
    flex-shrink: 0;
}

/* Un porcentaje sacado de tres leads no es un porcentaje. Cuando
   no hay muestra la cifra se reemplaza por un guion y el pie lo
   dice con todas las letras, para que nadie lea el "—" como un
   cero. */
.rinde-flojo {
    font-style: italic;
    opacity: 0.75;
}
