/* ==========================================================
   CRM - AJUSTES DE CONGRUENCIA
   Correcciones puntuales, cada una medida en el DOM antes de
   escribirla. Va ultima de todas.

   El criterio: dos elementos que hacen lo mismo tienen que
   medir lo mismo en toda la aplicacion. Un select de filtro
   mide igual en Consultas que en Clientes que en Proyectos.
   ========================================================== */

/* ==========================================================
   1. BARRA DE FILTROS
   Los select median 1198px cada uno (heredaban width 100%),
   asi que la barra se partia en una fila por filtro. De ahi
   venia la sensacion de "esto esta enorme al pedo".

   Reparto: el buscador crece, los filtros tienen ancho fijo.
   El buscador es el unico que se usa escribiendo, es el unico
   que necesita espacio.
   ========================================================== */

.barra-filtros,
.filtros-acciones,
.section-head__acciones {
    display: flex !important;
    flex-wrap: wrap !important;
    align-items: center !important;
    gap: var(--e-2) !important;
    width: 100% !important;
}

/* El buscador manda y se estira */
.barra-filtros .buscador,
.buscador {
    flex: 1 1 240px !important;
    min-width: 200px !important;
    max-width: 320px !important;
    width: auto !important;
    height: var(--h-md) !important;
    display: flex !important;
    align-items: center !important;
    gap: var(--e-2) !important;
    padding: 0 var(--e-3) !important;
}

.buscador input {
    flex: 1 1 auto !important;
    width: 100% !important;
    min-width: 0 !important;
    height: 100% !important;
    padding: 0 !important;
    text-overflow: ellipsis;
}

/* Los filtros: ancho fijo, todos iguales, sin crecer */
.barra-filtros .select-field,
.barra-filtros select,
.filtros-acciones select,
.section-head__acciones select {
    /* 168px entra "Todos los usuarios" completo y los seis
       filtros caben en una sola linea a 1280 de ancho. */
    flex: 0 1 168px !important;
    width: 168px !important;
    min-width: 132px !important;
    max-width: 168px !important;
    height: var(--h-md) !important;
    padding: 0 var(--e-4) 0 var(--e-3) !important;
    text-overflow: ellipsis;
}

/* Los botones de la barra no se estiran nunca */
.barra-filtros .btn,
.filtros-acciones .btn,
.section-head__acciones .btn {
    flex: 0 0 auto !important;
    width: auto !important;
    height: var(--h-md) !important;
    padding: 0 var(--e-4) !important;
}

/* ==========================================================
   2. CABECERA DE SECCION
   Texto a la izquierda, acciones a la derecha, alineadas
   arriba. Las acciones no pueden ocupar un tercio del ancho.
   ========================================================== */

.section-head {
    display: flex !important;
    align-items: flex-start !important;
    justify-content: space-between !important;
    gap: var(--e-4) !important;
    flex-wrap: wrap !important;
    margin-bottom: var(--e-4) !important;
}

.section-head__texto {
    flex: 1 1 320px !important;
    min-width: 0 !important;
}

.section-head__texto h2,
.section-head__texto h3 {
    margin: 0 0 4px 0 !important;
    font-size: 18px !important;
}

/* La bajada: una sola linea de ancho legible, no 76 caracteres */
.section-head__texto p {
    margin: 0 !important;
    font-size: 13px !important;
    line-height: 1.5 !important;
    color: var(--text-muted) !important;
    max-width: 62ch;
}

.section-head__acciones {
    flex: 0 1 auto !important;
    width: auto !important;
    justify-content: flex-end !important;
}

/* ==========================================================
   3. TARJETAS DE RESUMEN
   Median 133px de alto para mostrar un numero y dos palabras.
   Con 88px alcanza y entran las cuatro sin dominar la vista.
   El numero baja de 28 a 24: sigue siendo el heroe del bloque
   sin comerse la pantalla.
   ========================================================== */

/* Todo alineado al margen izquierdo, sin excepciones.
   El problema no era el numero: era que el icono estaba
   centrado y el texto no. Con el bloque de datos midiendo
   menos que la tarjeta, quedaba flotando en el medio con el
   texto pegado a su propia izquierda. Se lee como un error
   aunque cada pieza este "bien" por separado.

   Los dashboards que se leen rapido alinean todo a la misma
   vertical: el ojo baja en linea recta. */
.resumen-item,
.stat-card,
.metric-card {
    min-height: 0 !important;
    height: auto !important;
    padding: var(--e-4) !important;
    display: flex !important;
    flex-direction: column !important;
    align-items: flex-start !important;
    justify-content: flex-start !important;
    text-align: left !important;
    gap: var(--e-2) !important;
}

.resumen-item > *,
.stat-card > *,
.metric-card > * {
    align-self: stretch !important;
    text-align: left !important;
    margin-left: 0 !important;
    margin-right: 0 !important;
}

/* El icono es lo unico que no se estira: caja de 32 arriba
   a la izquierda, con el contenido centrado adentro. */
.metric-card > .metric-icon,
.stat-card > .metric-icon,
.resumen-item > .metric-icon,
.metric-icon {
    align-self: flex-start !important;
    margin-bottom: var(--e-1) !important;
}

.metric-data,
.resumen-item > div {
    display: flex !important;
    flex-direction: column !important;
    gap: 2px !important;
    width: 100% !important;
    text-align: left !important;
}

.resumen-item {
    min-height: 88px !important;
}

.resumen-item .valor,
.resumen-item strong,
.resumen-item b,
.stat-value,
.metric-value {
    font-size: 24px !important;
    line-height: 1.15 !important;
    font-weight: 600 !important;
    letter-spacing: -0.02em !important;
}

.resumen-item .etiqueta,
.resumen-item span,
.stat-label,
.metric-label {
    font-size: 12px !important;
    font-weight: 500 !important;
    line-height: 1.4 !important;
    color: var(--text-muted) !important;
}

/* La aclaracion de abajo ("en la cartera", "historico") es
   texto de apoyo: sans, 11px, tono apagado. Estaba en mono y
   por eso competia con el numero. */
.resumen-item small,
.resumen-item .apoyo,
.stat-card small,
.metric-card small {
    font-family: var(--ui-sans) !important;
    font-size: 11px !important;
    color: var(--text-dim) !important;
    letter-spacing: 0 !important;
    text-transform: none !important;
}

/* Grilla de resumen: mismo minimo en todas las secciones */
.clientes-resumen,
.consultas-resumen,
.metrics-grid,
.stats-grid {
    display: grid !important;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)) !important;
    gap: var(--e-3) !important;
    margin-bottom: var(--e-5) !important;
}

/* ==========================================================
   4. PERFIL
   La cabecera ocupaba 180px para decir un nombre y un mail.
   Se compacta a una fila: avatar 56, nombre, badges, mail.
   Lo que se gana en alto se usa para el contenido real.
   ========================================================== */

.profile-header-card {
    display: flex !important;
    align-items: center !important;
    gap: var(--e-4) !important;
    padding: var(--e-4) var(--e-5) !important;
    margin-bottom: var(--e-4) !important;
    min-height: 0 !important;
    flex-wrap: wrap !important;
}

#profile-avatar-preview,
.profile-header-card > img,
.profile-header-card .avatar {
    width: 56px !important;
    height: 56px !important;
    flex: 0 0 56px !important;
    object-fit: cover !important;
    padding: 0 !important;
}

/* La estructura real es: [ avatar + datos ] [ boton ].
   El primer bloque va en fila (el avatar al lado del nombre,
   no encima), y el interno en columna. Asi la cabecera pasa
   de 163px a una franja de ~88. */
.profile-header-card > div:first-child {
    flex: 1 1 320px !important;
    min-width: 0 !important;
    display: flex !important;
    flex-direction: row !important;
    align-items: center !important;
    gap: var(--e-4) !important;
    height: auto !important;
}

.profile-header-card > div:first-child > div:not(.profile-avatar-wrapper) {
    display: flex !important;
    flex-direction: column !important;
    gap: 4px !important;
    min-width: 0 !important;
}

.profile-avatar-wrapper {
    width: 56px !important;
    height: 56px !important;
    flex: 0 0 56px !important;
    padding: 0 !important;
    margin: 0 !important;
    display: block !important;
    line-height: 0 !important;
}

/* El bloque del boton no ocupa una fila entera para si */
.profile-header-card > div:last-child {
    flex: 0 0 auto !important;
    margin-left: auto !important;
    width: auto !important;
}

#profile-header-name {
    font-size: 18px !important;
    line-height: 1.2 !important;
    margin: 0 !important;
}

#profile-header-email {
    font-size: 12px !important;
    margin: 0 !important;
    color: var(--text-muted) !important;
}

/* Los badges del perfil comparten alto con los de todo el
   resto de la aplicacion: 20px, ni uno mas. */
.profile-header-card .badge {
    height: 20px !important;
    font-size: 11px !important;
    padding: 0 var(--e-2) !important;
}

/* El boton de la derecha no se estira */
.profile-header-card .btn,
.profile-header-card a.btn {
    flex: 0 0 auto !important;
    margin-left: auto !important;
    height: var(--h-md) !important;
}

/* ==========================================================
   5. ESTADO VACIO
   Estaba pegado a la izquierda porque el bloque no tenia
   ancho: ahora ocupa la fila completa y centra su contenido.
   ========================================================== */

/* El comodin [class*="vacio"] agarraba cualquier clase con esa
   palabra, incluidos los avisos de una linea adentro de una
   ficha (.pr-vacio, .avisos-vacio, .bitacora-vacio). Se listan
   solo los vacios de pantalla completa. */
.estado-vacio,
.empty-state,
.clientes-vacio,
.timeline-vacio {
    grid-column: 1 / -1 !important;
    width: 100% !important;
    margin: 0 auto !important;
    padding: var(--e-7) var(--e-5) !important;
    text-align: center !important;
}

.estado-vacio > *,
.empty-state > * {
    margin-left: auto !important;
    margin-right: auto !important;
}

/* El parrafo explicativo no puede tener 8 renglones de 30
   caracteres: se ensancha y se acorta a 3 renglones. */
.estado-vacio p,
.estado-vacio span,
.empty-state p,
.empty-state span {
    max-width: 52ch !important;
    font-size: 13px !important;
    line-height: 1.55 !important;
}

/* Los nombres de seccion citados en el texto son referencias,
   no codigo: mismo peso que el resto, solo con color. */
.estado-vacio strong,
.estado-vacio b,
.empty-state strong {
    font-family: var(--ui-sans) !important;
    font-weight: 600 !important;
    letter-spacing: 0 !important;
}

/* ==========================================================
   6. FICHAS
   Todas iguales de alto dentro de su fila, y el contenido
   pegado arriba: si una tiene un dato menos, no queda con un
   hueco en el medio.
   ========================================================== */

.clientes-lista,
.fichas-grid {
    display: grid !important;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)) !important;
    gap: var(--e-3) !important;
    align-items: stretch !important;
}

.cliente-ficha {
    display: flex !important;
    flex-direction: column !important;
    gap: var(--e-2) !important;
    padding: var(--e-4) !important;
    min-height: 0 !important;
}

.cliente-ficha > *:last-child { margin-top: auto !important; }

/* ==========================================================
   7. TIPOGRAFIA: CERRAR LAS FUGAS DE MONO
   Quedaban textos en monoespaciada sueltos (bajadas, ayudas,
   etiquetas de grafico). La mono es solo para cifras.
   ========================================================== */

p, small, label, li, td, th,
.text-muted, .small, .ayuda, .apoyo,
.section-head__texto p,
.estado-vacio p, .estado-vacio span,
figcaption, caption {
    font-family: var(--ui-sans) !important;
    letter-spacing: 0 !important;
}

/* Las etiquetas de dias del grafico: sans, 11px, apagadas */
.grafico-dia,
[class*="chart"] text,
[class*="grafico"] span {
    font-family: var(--ui-sans) !important;
    font-size: 11px !important;
}

/* ==========================================================
   8. ANCHO DE LECTURA
   El contenido no se estira hasta el borde en pantallas
   anchas: la vista queda centrada con un maximo. Sin esto,
   una tabla de 1900px obliga a mover la cabeza.
   ========================================================== */

@media (min-width: 900px) {
    .tab-content {
        max-width: 1320px !important;
        margin: 0 auto !important;
        padding: var(--e-5) var(--e-5) var(--e-7) !important;
    }
}

/* ==========================================================
   9b. TRES FAMILIAS DE ALTURA, Y NADA MAS
   Medido en el DOM: convivian controles de 16, 32, 36, 38, 42
   y 44px. Cinco alturas para tres funciones distintas.

   Queda asi:
     36px  control de pantalla (boton, input, select, filtro)
     30px  control dentro de una fila de tabla
     20px  badge

   Los selectores llevan html body adelante porque varias de
   las alturas viejas vienen de reglas de dos niveles con
   !important, y a igual especificidad no alcanzaba con estar
   ultimo en la cascada.
   ========================================================== */

html body .btn,
html body .btn-primary,
html body .btn-secondary,
html body .btn-primary-3d,
html body a.btn,
html body button.btn,
html body .modal-actions .btn,
html body input:not([type="checkbox"]):not([type="radio"]),
html body select,
html body .select-field,
html body .campo:not(textarea) {
    height: var(--h-md) !important;
    min-height: var(--h-md) !important;
    max-height: var(--h-md) !important;
    line-height: 1 !important;
    padding-top: 0 !important;
    padding-bottom: 0 !important;
}

/* El textarea es el unico que crece: se lo saca de la regla */
html body textarea,
html body textarea.campo {
    height: auto !important;
    min-height: 76px !important;
    max-height: none !important;
    line-height: 1.5 !important;
    padding: var(--e-3) !important;
}

/* El input del buscador no tiene caja propia: la caja es el
   contenedor. Ocupa el alto completo y no dibuja borde. */
html body .buscador input {
    height: 34px !important;
    min-height: 34px !important;
    max-height: 34px !important;
    border: none !important;
    background: transparent !important;
    box-shadow: none !important;
}

/* Controles de fila: 30px, la escala chica. Los dos que hay
   (el select de etapa y el boton de editar) median 38 y 32. */
html body .btn-fila,
html body .quick-status-select,
html body .etapa-select,
html body .custom-table td .btn,
html body .custom-table td select,
html body .custom-table td button {
    height: 30px !important;
    min-height: 30px !important;
    max-height: 30px !important;
    font-size: 12px !important;
    padding: 0 var(--e-2) !important;
    line-height: 1 !important;
}

html body .btn-fila {
    width: 30px !important;
    padding: 0 !important;
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
}

/* El select de etapa necesita algo mas de aire por el texto */
html body .quick-status-select,
html body .etapa-select {
    width: auto !important;
    min-width: 148px !important;
    max-width: 190px !important;
    padding: 0 var(--e-3) !important;
}

/* Segmentado (Semanal / Mensual): es un control de pantalla,
   pero de los chicos. Entra en la escala de fila: 30px, con
   el par metido en una sola caja como un unico control. */
html body .toggle-pill-btn {
    height: 28px !important;
    min-height: 28px !important;
    max-height: 28px !important;
    padding: 0 var(--e-3) !important;
    font-size: 12px !important;
    font-weight: 500 !important;
    line-height: 1 !important;
    border-radius: calc(var(--rr-md) - 2px) !important;
    background: transparent !important;
    border: none !important;
    color: var(--text-muted) !important;
}

html body .toggle-pill-btn.active {
    background: var(--surf-3) !important;
    color: var(--text-main) !important;
}

/* La caja que los contiene queda a 36, como todo lo demas */
html body .toggle-pill,
html body .toggle-pill-group,
html body .toggle-pill-btn:first-child {
    align-items: center !important;
}

html body .toggle-pill-btn:first-child {
    margin-left: 0 !important;
}

/* Badges: una sola altura en toda la aplicacion */
html body .badge,
html body .tab-badge {
    height: 20px !important;
    min-height: 20px !important;
    max-height: 20px !important;
    line-height: 1 !important;
}

/* ==========================================================
   9c. ICONOS Y CONTADORES CENTRADOS
   Un icono dentro de una caja tiene que estar en el centro
   optico de esa caja, no en el centro de su propia linea de
   texto: la fuente de iconos trae altura de linea propia y
   por eso quedaban corridos hacia arriba.
   ========================================================== */

html body .metric-icon,
html body .icono-caja,
html body .estado-vacio i,
html body .empty-state i {
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
    line-height: 0 !important;
    text-align: center !important;
    flex: 0 0 auto !important;
}

html body .metric-icon i,
html body .icono-caja i {
    display: block !important;
    line-height: 1 !important;
    margin: 0 !important;
    width: auto !important;
}

/* El contador de la pestaña: caja cuadrada, cifra al centro.
   Con line-height heredada el numero se apoyaba en la base. */
html body .tab-badge {
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
    min-width: 20px !important;
    padding: 0 6px !important;
    line-height: 1 !important;
    font-size: 11px !important;
    font-variant-numeric: tabular-nums;
    border-radius: var(--rr-pill) !important;
    align-self: center !important;
}

html body .tab-btn {
    align-items: center !important;
}

/* Todo icono que acompaña texto comparte eje vertical con el */
html body .btn i,
html body .tab-btn i,
html body h2 i,
html body h3 i,
html body .badge i {
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
    line-height: 1 !important;
    vertical-align: middle !important;
}

/* ==========================================================
   9d. ESTADO VACIO: CENTRADO REAL
   No alcanza con text-align: el bloque tiene que ocupar todo
   el ancho disponible y recien ahi centrar su contenido.
   ========================================================== */

html body .estado-vacio,
html body .empty-state,
html body .clientes-vacio,
html body .timeline-vacio {
    display: flex !important;
    flex-direction: column !important;
    align-items: center !important;
    justify-content: center !important;
    grid-column: 1 / -1 !important;
    width: 100% !important;
    max-width: none !important;
    margin: 0 !important;
    padding: var(--e-7) var(--e-5) !important;
    text-align: center !important;
    min-height: 320px;
}

html body .estado-vacio i,
html body .empty-state i {
    width: 48px !important;
    height: 48px !important;
    font-size: 20px !important;
    border-radius: var(--rr-lg) !important;
    margin-bottom: var(--e-3) !important;
}

html body .estado-vacio strong,
html body .empty-state strong,
html body .estado-vacio h3,
html body .empty-state h3 {
    display: block !important;
    margin: 0 0 var(--e-2) 0 !important;
    font-size: 15px !important;
}

html body .estado-vacio p,
html body .empty-state p {
    margin: 0 auto var(--e-4) auto !important;
    max-width: 46ch !important;
}

html body .estado-vacio .btn,
html body .empty-state .btn {
    margin: 0 auto !important;
}

/* ==========================================================
   9e. SELECTOR DE AVATAR
   Las tres tarjetas se ven igual; solo cambia la elegida, y
   con el borde y un fondo al 8%, no con blanco puro.
   ========================================================== */

html body .avatar-preset-btn {
    display: flex !important;
    flex-direction: column !important;
    align-items: center !important;
    justify-content: center !important;
    gap: var(--e-2) !important;
    padding: var(--e-3) !important;
    min-height: 110px !important;
    background: var(--surf-1) !important;
    border: 1px solid var(--border-color) !important;
    border-radius: var(--rr-lg) !important;
    box-shadow: none !important;
    cursor: pointer;
    transition: border-color var(--d-fast) var(--c-inout),
                background var(--d-fast) var(--c-inout) !important;
}

html body .avatar-preset-btn:hover {
    background: var(--surf-2) !important;
    border-color: var(--text-dim) !important;
}

/* El elemento arrastra tres clases (avatar-card-item,
   avatar-preset-btn, tarjeta-opcion) y index.css pinta el
   borde desde .tarjeta-opcion. Se nombran las dos juntas
   para ganar sin depender del orden de los archivos. */
html body .avatar-preset-btn.seleccionado,
html body .tarjeta-opcion.seleccionado,
html body .avatar-preset-btn.tarjeta-opcion.seleccionado {
    background: color-mix(in srgb, var(--primary) 8%, var(--surf-1)) !important;
    border-color: var(--primary) !important;
    box-shadow: inset 0 0 0 1px var(--primary) !important;
}

/* Marca de elegido: tilde en la esquina. Sin esto, la unica
   diferencia es un borde de 1px, que en una grilla de tres
   iguales no se lee de un vistazo. */
html body .avatar-preset-btn { position: relative !important; }

html body .avatar-preset-btn.seleccionado::after {
    content: '\f00c';
    font-family: 'Font Awesome 6 Free';
    font-weight: 900;
    position: absolute;
    top: 6px;
    right: 6px;
    width: 18px;
    height: 18px;
    display: grid;
    place-items: center;
    font-size: 9px;
    border-radius: 50%;
    background: var(--primary);
    color: var(--bg-main);
}

/* Un solo anillo de foco en toda la aplicacion, del color del
   acento. Habia otro blanco de 3px dando vueltas. */
html body *:focus-visible {
    outline: 2px solid var(--primary) !important;
    outline-offset: 2px !important;
    box-shadow: none !important;
}

html body input:focus-visible,
html body select:focus-visible,
html body textarea:focus-visible {
    outline: none !important;
    border-color: var(--primary) !important;
    box-shadow: 0 0 0 3px var(--accent-glow) !important;
}

/* La etiqueta de la tarjeta no elegida tambien se leia mal:
   iba en blanco sobre blanco. */
html body .avatar-preset-btn span,
html body .avatar-preset-btn small {
    font-size: 12px !important;
    font-weight: 500 !important;
    color: var(--text-muted) !important;
}

html body .avatar-preset-btn.seleccionado span,
html body .avatar-preset-btn.seleccionado small {
    color: var(--text-main) !important;
}

html body .avatar-preset-btn img {
    width: 48px !important;
    height: 48px !important;
    border-radius: var(--rr-pill) !important;
    object-fit: cover !important;
}

/* ==========================================================
   10. ESPACIO MUERTO
   Medido en Mi Perfil: 830px vacios en un panel y 407px en
   otro. Mas de mil pixeles de scroll sin nada adentro.

   La causa no es el padding: es que una grilla estira todas
   sus celdas a la altura de la fila. Si a la izquierda hay un
   formulario de 900px y a la derecha una tarjeta de 274px, la
   tarjeta se infla a 900 y queda hueca.

   align-items: start lo resuelve entero: cada panel mide lo
   que mide su contenido.
   ========================================================== */

html body .bitacora-grid,
html body .form-row-grid,
html body .metrics-grid,
html body .clientes-resumen,
html body .consultas-resumen,
html body .stats-grid,
html body .historial-grid,
html body [class*="-grid"]:not(.clientes-lista):not(.fichas-grid) {
    align-items: start !important;
    align-content: start !important;
}

/* Las grillas de dos columnas se apoyan arriba, no al medio */
html body .bitacora-grid > *,
html body .form-row-grid > * {
    align-self: start !important;
    height: auto !important;
}

/* --- Paneles: menos aire interno --------------------------
   24px de padding en un panel que ya vive dentro de otro
   panel es aire duplicado. 20px alcanza y se nota la
   diferencia sumada a lo largo de la pagina. */
html body .glass-panel {
    padding: 20px !important;
}

html body .glass-panel .glass-panel {
    padding: 16px !important;
}

/* Un panel dentro de otro no repite el fondo ni el borde:
   se distingue por el espacio, no por dibujar otra caja. */
html body .glass-panel > .glass-panel:only-child {
    border: none !important;
    padding: 0 !important;
    background: transparent !important;
}

/* --- Titulos de bloque: pegados a su contenido ------------- */
html body .glass-panel > h2,
html body .glass-panel > h3,
html body .glass-panel > h4 {
    margin: 0 0 var(--e-3) 0 !important;
}

html body .glass-panel > p,
html body .glass-panel > .ayuda {
    margin: 0 0 var(--e-4) 0 !important;
}

/* --- Formularios: filas de 12px, no de 24 ------------------ */
html body form,
html body .campo-grupo,
html body .form-row-grid form {
    display: flex;
    flex-direction: column;
    gap: var(--e-3) !important;
}

html body form > div,
html body .campo-grupo {
    margin-bottom: 0 !important;
}

html body label,
html body .campo-label {
    margin-bottom: 4px !important;
    display: block;
}

/* --- Textareas: 3 renglones, no media pantalla ------------- */
html body textarea,
html body textarea.campo {
    min-height: 72px !important;
    max-height: 160px !important;
}

/* La caja de la bitacora ocupaba 400px para un boton.
   Se recorta a la altura del contenido real. */
html body .bitacora-estado,
html body .bitacora-caja,
html body #bitacora-panel {
    min-height: 0 !important;
    height: auto !important;
    padding: var(--e-4) !important;
}

/* --- Vacios chicos: dentro de un panel no llevan 320px ----- */
html body .glass-panel .estado-vacio,
html body .glass-panel .empty-state,
html body .bitacora-grid .estado-vacio,
html body .chat-mensajes .estado-vacio {
    min-height: 0 !important;
    padding: var(--e-5) var(--e-4) !important;
}

html body .glass-panel .estado-vacio i,
html body .glass-panel .empty-state i {
    width: 36px !important;
    height: 36px !important;
    font-size: 15px !important;
    margin-bottom: var(--e-2) !important;
}

/* El vacio de pantalla completa si mantiene su altura: ahi el
   espacio es intencional, no sobra. */
html body .tab-content > .estado-vacio,
html body .tab-content > div > .estado-vacio {
    min-height: 280px !important;
}

/* --- Separacion entre bloques de una vista ----------------- */
html body .tab-content > * + * {
    margin-top: var(--e-4) !important;
}

html body .metrics-grid,
html body .clientes-resumen,
html body .consultas-resumen {
    margin-bottom: 0 !important;
}

/* --- Graficos: alto fijo y razonable -----------------------
   El comodin [class*="chart-"] tambien agarraba .chart-card,
   o sea la TARJETA entera: quedaba capada en 240px mientras su
   contenido (titulo + grafico de 280) media mas, y el grafico
   se salia por abajo pisando el panel siguiente. El tope va
   sobre el lienzo, no sobre el contenedor. */
html body canvas,
html body .grafico,
html body .chart-body > canvas {
    max-height: 240px !important;
}

/* La tarjeta mide lo que mide su contenido */
html body .chart-card {
    height: auto !important;
    max-height: none !important;
    overflow: hidden !important;
}

/* ==========================================================
   9. NADA DESBORDA
   Regla de cierre: ningun bloque puede empujar el ancho de la
   pagina. Es la causa numero uno de scroll horizontal.
   ========================================================== */

.tab-content,
.glass-panel,
.section-head,
.barra-filtros,
.custom-table,
.cliente-ficha,
.resumen-item {
    min-width: 0 !important;
    max-width: 100% !important;
}

.custom-table { display: table !important; table-layout: auto !important; }

.table-wrapper,
.tabla-scroll {
    width: 100% !important;
    overflow-x: auto !important;
}

/* Texto largo en celda: se corta con puntos, no rompe la fila */
.custom-table td,
.cliente-ficha,
.resumen-item {
    overflow-wrap: anywhere;
}

/* ==========================================================
   PERFIL: COMPACTADO FINAL
   La pestana de perfil repartia el aire de tres paneles
   distintos: cabecera, bitacora y horas de uso. Cada bloque
   mide ahora lo que mide su contenido.
   ========================================================== */

html body .profile-container {
    padding: var(--e-4) !important;
}

/* Cabecera: una franja, no una portada */
html body .profile-header-card {
    padding: var(--e-3) var(--e-4) !important;
    margin-bottom: var(--e-4) !important;
    gap: var(--e-3) !important;
    row-gap: var(--e-3) !important;
    align-items: center !important;
    text-align: left !important;
}

html body .profile-header-card > div:first-child {
    align-items: center !important;
    text-align: left !important;
}

/* El boton de multimedia no necesita su propia franja */
html body #tab-profile .admin-only {
    margin-bottom: var(--e-4) !important;
}

html body #tab-profile .admin-only .btn {
    padding: 0 var(--e-4) !important;
    height: var(--h-md) !important;
    font-size: 13px !important;
}

/* Bitacora y horas: paneles al ras del contenido */
html body .bitacora-grid {
    gap: var(--e-4) !important;
    margin-bottom: var(--e-4) !important;
}

html body .bitacora-panel {
    padding: var(--e-4) !important;
}

html body .bitacora-panel h3 {
    margin: 0 0 var(--e-3) !important;
    font-size: 15px !important;
}

/* El resumen es una fila de chips: no una caja de media
   pantalla. Sin altura propia y alineado arriba. */
html body .bitacora-resumen {
    display: flex !important;
    flex-wrap: wrap !important;
    align-items: flex-start !important;
    align-content: flex-start !important;
    gap: 6px !important;
    height: auto !important;
    min-height: 0 !important;
    margin: 0 0 var(--e-3) !important;
}

html body .bitacora-resumen > span,
html body .bitacora-resumen > a,
html body .bitacora-vacio {
    flex: 0 1 auto !important;
    height: auto !important;
    min-height: 0 !important;
    align-self: flex-start !important;
    padding: 5px 9px !important;
    font-size: 12px !important;
    line-height: 1.3 !important;
}

html body .bitacora-panel .form-group {
    margin-bottom: var(--e-3) !important;
}

html body .bitacora-subtitulo {
    margin: var(--e-4) 0 var(--e-2) !important;
    font-size: 14px !important;
}

html body .bitacora-ayuda {
    margin: 0 0 var(--e-3) !important;
}

html body .uso-totales {
    margin-bottom: var(--e-3) !important;
}

html body .uso-totales > div {
    padding: 8px 10px !important;
}

html body .uso-totales strong {
    font-size: 1.15rem !important;
}

/* Las barras miden 96px: se leen igual y no dejan un hueco
   verde de 130 debajo de dos numeros. */
html body .uso-barras {
    height: 96px !important;
}

html body #tab-profile .metrics-grid {
    gap: var(--e-3) !important;
    margin-bottom: var(--e-4) !important;
}

/* --- MOVIL -------------------------------------------------
   En pantalla angosta la cabecera se apilaba y el avatar se
   quedaba con una franja entera para el solo. Sigue siendo
   una fila: avatar chico a la izquierda, datos al lado. */
@media (max-width: 720px) {
    html body .profile-container {
        padding: var(--e-3) !important;
    }

    html body .profile-header-card {
        flex-direction: row !important;
        flex-wrap: wrap !important;
        align-items: center !important;
        justify-content: flex-start !important;
        text-align: left !important;
        padding: var(--e-3) !important;
    }

    html body .profile-header-card > div:first-child {
        flex: 1 1 100% !important;
        flex-direction: row !important;
        align-items: center !important;
        gap: var(--e-3) !important;
    }

    html body #profile-avatar-preview,
    html body .profile-avatar-wrapper {
        width: 48px !important;
        height: 48px !important;
        flex: 0 0 48px !important;
    }

    html body #profile-header-name {
        font-size: 16px !important;
    }

    /* El boton pasa abajo, ancho completo, sin margen fantasma */
    html body .profile-header-card > div:last-child {
        flex: 1 1 100% !important;
        margin-left: 0 !important;
        width: 100% !important;
    }

    html body .profile-header-card > div:last-child .btn {
        width: 100% !important;
        margin-left: 0 !important;
        justify-content: center !important;
    }

    html body #tab-profile .admin-only .btn {
        width: 100% !important;
    }

    html body .bitacora-panel {
        padding: var(--e-3) !important;
    }

    html body .uso-barras {
        height: 80px !important;
    }
}

/* ==========================================================
   BARRA DE PESTANAS EN MOVIL
   Eran seis botones en un carrusel horizontal: la mitad
   quedaba fuera de pantalla y no habia forma de saberlo.
   Ahora entran todas en una fila fija, icono arriba y
   etiqueta corta abajo.
   ========================================================== */

.tab-corto {
    display: none;
}

@media (max-width: 768px) {
    html body .main-tabs {
        display: grid !important;
        grid-auto-flow: column !important;
        grid-auto-columns: 1fr !important;
        align-items: stretch !important;
        gap: 2px !important;
        padding: 4px !important;
        /* `clip` y no `hidden`: una caja con overflow hidden sigue
           siendo desplazable por programa, y el navegador la corria
           sola para "traer al foco" la pestaña recien tocada. Con
           clip no hay desplazamiento posible: la barra no se mueve. */
        overflow: clip !important;
        overscroll-behavior: contain !important;
        scroll-snap-type: none !important;
    }

    /* Ninguna pestaña puede empujar el ancho: columnas iguales y
       punto. Sin esto una etiqueta larga estiraba su columna y la
       fila entera se desbordaba, que es lo que habilitaba el
       desplazamiento en primer lugar. */
    html body .main-tabs > * {
        min-width: 0 !important;
        max-width: 100% !important;
    }

    html body .main-tabs .tab-btn {
        display: flex !important;
        flex-direction: column !important;
        align-items: center !important;
        justify-content: flex-start !important;
        gap: 4px !important;
        min-width: 0 !important;
        width: 100% !important;
        min-height: 52px !important;
        /* El mismo padding para activa e inactiva: cuando la activa
           tenia el suyo propio, su icono quedaba unos pixeles mas
           abajo y la fila entera se veia torcida. */
        padding: 8px 2px 6px !important;
        font-size: 10.5px !important;
        font-weight: 600 !important;
        line-height: 1 !important;
        letter-spacing: 0 !important;
        border: none !important;
        border-radius: 12px !important;
        text-align: center !important;
        overflow: visible !important;
    }

    html body .main-tabs .tab-btn i {
        font-size: 17px !important;
        margin: 0 !important;
        line-height: 1 !important;
    }

    /* La etiqueta ocupa su renglon completo y se corta con puntos
       suspensivos solo si de verdad no entra. Antes el `overflow`
       del boton la recortaba a la mitad de una letra.

       Ojo con el selector: mencionar `.tab-largo` de entrada evita
       que esta regla le gane por especificidad a la de abajo que la
       esconde. Sin eso se veian las dos etiquetas, una sobre la
       otra ("Dashboard" arriba de "Inicio"). */
    html body .main-tabs .tab-btn > span.tab-rotulo {
        display: block !important;
        width: 100% !important;
        padding: 0 1px !important;
        overflow: hidden !important;
        text-overflow: ellipsis !important;
        white-space: nowrap !important;
    }

    /* La pestaña activa se marca con color y un punto, no con
       una caja de fondo: en 60px de ancho el relleno se comia el
       contraste del texto y por eso no se leia. */
    html body .main-tabs .tab-btn.active {
        background: transparent !important;
        color: var(--primary) !important;
        box-shadow: none !important;
    }

    html body .main-tabs .tab-btn.active::after {
        content: '';
        position: absolute;
        bottom: 1px;
        left: 50%;
        transform: translateX(-50%);
        width: 16px;
        height: 3px;
        border-radius: 3px;
        background: var(--primary);
    }

    html body .main-tabs .tab-btn:not(.active) {
        background: transparent !important;
        color: var(--text-secondary) !important;
    }

    /* El rotulo corto lo pone js/pestanas.js: aca no hay nada que
       esconder ni intercambiar. */

    /* El contador se apoya sobre el icono, no roba ancho */
    html body .main-tabs .tab-badge {
        position: absolute !important;
        top: 3px !important;
        left: 50% !important;
        right: auto !important;
        transform: translateX(4px) !important;
        margin: 0 !important;
        min-width: 15px !important;
        height: 15px !important;
        padding: 0 3px !important;
        font-size: 9px !important;
        font-weight: 700 !important;
        line-height: 15px !important;
        border: 1.5px solid var(--bg-main) !important;
        box-sizing: content-box !important;
    }

    html body .main-tabs .tab-btn {
        position: relative !important;
    }
}

/* Pantallas angostas con sesion de admin: son seis pestañas en
   360px, unos 57px cada una. Se baja el cuerpo antes de que las
   etiquetas empiecen a cortarse con puntos suspensivos. */
@media (max-width: 400px) {
    html body .main-tabs .tab-btn {
        font-size: 9.5px !important;
        padding: 7px 1px 6px !important;
    }

    html body .main-tabs .tab-btn i {
        font-size: 16px !important;
    }
}

/* Cuando el usuario no es admin son cinco botones: el grid
   automatico ya reparte el ancho, no hace falta nada mas. */

/* ==========================================================
   HORAS DE USO DENTRO DE LA CABECERA
   Antes era medio panel al lado de la bitacora: dos numeros
   y siete barras ocupando 400px de alto. Ahora es un bloque
   angosto pegado al nombre, en la misma franja.
   ========================================================== */

html body .uso-inline {
    flex: 0 0 auto !important;
    display: flex !important;
    align-items: center !important;
    gap: var(--e-3) !important;
    margin-left: auto !important;
    padding-left: var(--e-4) !important;
    border-left: 1px solid var(--border-color) !important;
}

html body .uso-inline .uso-totales {
    display: flex !important;
    gap: 6px !important;
    margin: 0 !important;
}

html body .uso-inline .uso-totales > div {
    padding: 5px 10px !important;
    border-radius: 10px !important;
    min-width: 62px !important;
}

html body .uso-inline .uso-label {
    font-size: 10px !important;
    margin-bottom: 1px !important;
}

html body .uso-inline .uso-totales strong {
    font-size: 15px !important;
}

/* Las barras quedan como referencia visual, no como grafico:
   siete trazos finos que muestran la forma de la semana. */
html body .uso-inline .uso-barras {
    height: 34px !important;
    gap: 3px !important;
    width: 108px !important;
    flex: 0 0 108px !important;
}

html body .uso-inline .uso-barra {
    gap: 0 !important;
}

html body .uso-inline .uso-barra span {
    display: none !important;
}

html body .uso-inline .uso-barra-fill {
    min-height: 3px !important;
    border-radius: 3px !important;
}

/* La bitacora se queda sola: una sola columna, ancho completo */
html body .bitacora-grid {
    grid-template-columns: 1fr !important;
}

/* Sin datos, el resumen no deja un hueco en el panel */
html body .bitacora-resumen:empty {
    display: none !important;
}

@media (max-width: 768px) {
    html body .uso-inline {
        flex: 1 1 100% !important;
        margin-left: 0 !important;
        padding: var(--e-3) 0 0 !important;
        border-left: none !important;
        border-top: 1px solid var(--border-color) !important;
    }

    html body .uso-inline .uso-totales {
        flex: 1 1 auto !important;
    }

    html body .uso-inline .uso-totales > div {
        flex: 1 1 0 !important;
    }
}

/* ==========================================================
   FONDO DE CODIGO
   El canvas vive detras de todo, fijo a la ventana y sin
   capturar clicks. La aplicacion sigue arriba, intacta.
   ========================================================== */

#fondo-codigo {
    position: fixed;
    inset: 0;
    z-index: 0;
    pointer-events: none;
    opacity: 0.5;
    /* Se apaga hacia abajo: arriba se lee la lluvia, abajo el
       contenido no compite con ella. */
    -webkit-mask-image: linear-gradient(180deg, #000 0%, rgba(0, 0, 0, 0.35) 70%, transparent 100%);
    mask-image: linear-gradient(180deg, #000 0%, rgba(0, 0, 0, 0.35) 70%, transparent 100%);
}

/* Esta regla ponia position:relative a TODO hijo directo de
   body, y el panel del chat es uno: perdia su position:fixed y
   caia al final del documento. El canvas se manda al fondo con
   z-index negativo y no hace falta tocar a nadie mas. */

/* En tema claro la lluvia verde sobre blanco no se lee:
   se baja a una insinuacion. */

/* Aca se ocultaba el canvas con prefers-reduced-motion. En
   Windows esa preferencia viene activada en muchas maquinas y
   el fondo directamente no aparecia. Se queda visible: es una
   caida lenta y pareja, no un efecto que moleste. */

/* ==========================================================
   BARRA DE PESTANAS FIJA EN MOVIL
   Estaba en el flujo del documento: quedaba a mitad de la
   pagina segun donde estuviera el scroll. En un telefono la
   navegacion va anclada abajo y no se mueve.
   ========================================================== */

@media (max-width: 720px) {
    html body .main-tabs {
        position: fixed !important;
        left: 0 !important;
        right: 0 !important;
        bottom: 0 !important;
        top: auto !important;
        z-index: 40 !important;
        margin: 0 !important;
        border-radius: 0 !important;
        border-left: none !important;
        border-right: none !important;
        border-bottom: none !important;
        border-top: 1px solid var(--border-color) !important;
        background: var(--bg-main) !important;
        backdrop-filter: blur(18px) saturate(1.1);
        -webkit-backdrop-filter: blur(18px) saturate(1.1);
        box-shadow: 0 -6px 20px rgba(0, 0, 0, 0.35) !important;
        padding: 4px 4px calc(4px + env(safe-area-inset-bottom)) !important;
    }

    /* El contenido deja libre el alto de la barra: sin esto, el
       ultimo bloque de cada pestaña queda tapado. */
    html body {
        padding-bottom: calc(62px + env(safe-area-inset-bottom)) !important;
    }

    /* El panel del chat se abre por encima de la barra */
    html body .chat-panel,
    html body .chat-fondo {
        z-index: 61 !important;
    }
}

/* --- El fondo se tiene que ver ------------------------------
   #crm-workspace pintaba var(--bg-main) opaco sobre toda la
   pagina: el canvas quedaba abajo, dibujando para nadie. El
   contenedor no necesita fondo propio, los paneles ya lo
   tienen. */
html body #crm-workspace {
    background: transparent !important;
}

/* Cabecera y barra de pestañas siguen siendo opacas (el
   contenido pasa por debajo al hacer scroll), pero dejan
   pasar algo de la lluvia. */
html body .top-navbar {
    background: color-mix(in srgb, var(--bg-main) 82%, transparent) !important;
    backdrop-filter: blur(16px) saturate(1.1);
    -webkit-backdrop-filter: blur(16px) saturate(1.1);
}

/* La lluvia se ve entera: la mascara que la desvanecia abajo
   la dejaba practicamente invisible en media pantalla. */
html body #fondo-codigo {
    /* La opacidad la maneja el slider de Apariencia: si queda un
       !important aca, el estilo inline del canvas no puede ganarle. */
    -webkit-mask-image: none !important;
    mask-image: none !important;
}


/* --- El canvas va detras de todo, por z-index negativo ------
   El fondo de la raiz (<html>) se pinta siempre por debajo,
   asi que un z-index:-1 deja el canvas entre ese fondo y la
   aplicacion, sin necesidad de reposicionar nada.
   Condicion: body no puede tener fondo opaco propio. */
html body #fondo-codigo {
    position: fixed !important;
    inset: 0 !important;
    z-index: -1 !important;
    pointer-events: none !important;
    -webkit-mask-image: none !important;
    mask-image: none !important;
}

html body {
    background: transparent !important;
}

/* El orbe y la marca de agua quedan entre el codigo y la app */
html body #ambient-background-glow {
    z-index: 0 !important;
}

/* El chat vuelve a su lugar: fijo contra el borde derecho */
html body .chat-panel {
    position: fixed !important;
    top: 0 !important;
    right: 0 !important;
    bottom: 0 !important;
    left: auto !important;
    z-index: 61 !important;
}

html body .chat-fondo {
    position: fixed !important;
    inset: 0 !important;
    z-index: 60 !important;
}

/* En tema claro el codigo se insinua, no compite con el texto */

/* --- Los paneles dejan pasar el fondo -----------------------
   Cada panel pintaba una superficie opaca encima del canvas: la
   lluvia solo se veia en los huecos. Ahora son translucidos.

   SIN backdrop-filter. Un blur de fondo obliga al navegador a
   releer y desenfocar todo lo que hay detras de CADA panel en
   cada cuadro; con el canvas animado atras eso no se cachea
   nunca. Era el origen del tironeo: veinte paneles = veinte
   desenfoques de pantalla completa por cuadro. La opacidad
   sola da el mismo efecto y no cuesta nada. */
html body .glass-panel,
html body .metric-card,
html body .resumen-item,
html body .chart-card,
html body .users-container,
html body .bitacora-panel,
html body .main-tabs {
    background: color-mix(in srgb, var(--surf-1) 86%, transparent) !important;
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
}

/* Las tarjetas anidadas ya estan sobre un panel velado: si
   vuelven a velar, el fondo desaparece en dos capas. */
html body .glass-panel .glass-panel,
html body .glass-panel .metric-card,
html body .glass-panel .resumen-item {
    background: transparent !important;
}

/* --- Nada de blur de fondo en toda la aplicacion -------------
   ui.css y legibilidad.css ponen backdrop-filter en la navbar,
   las tarjetas y los modales. Con un canvas animado detras,
   cada uno de esos desenfoques se recalcula 20 veces por
   segundo sobre pixeles que cambiaron. Se apaga en bloque. */
html body .top-navbar,
html body .main-tabs,
html body .glass-panel,
html body .pool-container,
html body .users-container,
html body .dashboard-card,
html body .metric-card,
html body .resumen-item,
html body .chart-card,
html body .bitacora-panel,
html body .chat-panel,
html body .barra-filtros {
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
}

/* El orbe pulsante era el otro gasto grande: un blur de 40px
   sobre 950x700px, re-filtrado en cada cuadro de su propia
   animacion. Queda el resplandor, quieto. */
html body #ambient-background-glow::before {
    animation: none !important;
    filter: blur(60px) !important;
    opacity: 0.5 !important;
    transform: translate(-50%, -50%) scale(1) !important;
}

/* La navbar vuelve a ser opaca: sin blur, translucida sobre el
   codigo cayendo hacia el texto ilegible. */
html body .top-navbar {
    background: var(--bg-main) !important;
}

/* ==========================================================
   BARRA SUPERIOR: LA MISMA SUPERFICIE QUE TODO LO DEMAS
   Habia quedado en negro plano (var(--bg-main)) mientras los
   paneles de abajo eran translucidos: se leia como una franja
   pegada, de otra aplicacion. Usa la misma receta que un panel.
   ========================================================== */

html body .top-navbar {
    background: color-mix(in srgb, var(--surf-1) 86%, transparent) !important;
    border-bottom: 1px solid var(--border-color) !important;
}

/* La fila de pestañas se apoya en la navbar sin dibujar otra
   caja: comparten superficie, las separa una linea. */
html body .main-tabs {
    background: color-mix(in srgb, var(--surf-1) 78%, transparent) !important;
    border-top: none !important;
}


/* ==========================================================
   BARRAS DE NAVEGACION: OPACAS
   La navbar y la fila de pestañas son lo unico que esta
   siempre encima del contenido y del fondo animado. Ahi lo
   translucido no es estilo, es texto ilegible con codigo
   moviendose atras. Superficie solida y punto.
   ========================================================== */

html body .top-navbar,
html body .main-tabs {
    background: var(--bg-main) !important;
}


/* ==========================================================
   PULSO DE LUZ EN LA BARRA SUPERIOR
   Una franja del color de acento que recorre la barra de
   izquierda a derecha. Es la unica animacion permanente de la
   interfaz aparte del fondo, asi que tiene que ser barata:
   solo transform sobre un pseudo-elemento, que corre en el
   compositor y no dispara ni layout ni pintado del resto.
   ========================================================== */

html body .top-navbar {
    position: sticky;
    overflow: hidden;
}

html body .top-navbar::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    /* Ancho fijo en vez de porcentaje: la franja mide lo mismo
       en un monitor de 27" que en un telefono. */
    width: 220px;
    height: 2px;
    pointer-events: none;
    z-index: 2;
    background: linear-gradient(
        90deg,
        transparent 0%,
        color-mix(in srgb, var(--primary) 55%, transparent) 40%,
        var(--primary) 50%,
        color-mix(in srgb, var(--primary) 55%, transparent) 60%,
        transparent 100%
    );
    box-shadow: 0 0 12px color-mix(in srgb, var(--primary) 45%, transparent);
    /* Arranca fuera del borde izquierdo y sale por el derecho */
    transform: translate3d(-220px, 0, 0);
    animation: barra-pulso 5.5s var(--c-inout, ease-in-out) infinite;
    will-change: transform;
}

@keyframes barra-pulso {
    0%   { transform: translate3d(-220px, 0, 0); opacity: 0; }
    12%  { opacity: 1; }
    88%  { opacity: 1; }
    /* 100vw + el ancho de la franja: sale entera antes de reiniciar */
    100% { transform: translate3d(calc(100vw + 220px), 0, 0); opacity: 0; }
}

/* El resplandor tenue que la acompaña por debajo de la linea */
html body .top-navbar::after {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    width: 320px;
    height: 100%;
    pointer-events: none;
    z-index: 1;
    background: linear-gradient(
        90deg,
        transparent 0%,
        color-mix(in srgb, var(--primary) 9%, transparent) 50%,
        transparent 100%
    );
    transform: translate3d(-320px, 0, 0);
    animation: barra-pulso-halo 5.5s var(--c-inout, ease-in-out) infinite;
    will-change: transform;
}

@keyframes barra-pulso-halo {
    0%   { transform: translate3d(-320px, 0, 0); }
    100% { transform: translate3d(calc(100vw + 320px), 0, 0); }
}

/* rendimiento.css y ui.css matan TODA animacion con
   prefers-reduced-motion (animation-duration: 0.01ms !important).
   En Windows esa preferencia viene activada en muchas maquinas,
   y con esa regla el pulso ni arrancaba. Se reactiva solo para
   estos dos pseudo-elementos: son 5,5 segundos de una franja
   que se desliza, no un parpadeo. */
@media (prefers-reduced-motion: reduce) {
    html body .top-navbar::before {
        animation: barra-pulso 5.5s ease-in-out infinite !important;
        animation-iteration-count: infinite !important;
    }

    html body .top-navbar::after {
        animation: barra-pulso-halo 5.5s ease-in-out infinite !important;
        animation-iteration-count: infinite !important;
    }
}

/* ==========================================================
   BARRA SUPERIOR: GRAFITO, NO NEGRO
   var(--bg-main) es #0a0a0b, practicamente negro. La barra es
   una superficie elevada: va un escalon por encima del lienzo,
   como cualquier panel.
   ========================================================== */

html body .top-navbar {
    background: #17171a !important;
    border-bottom: 1px solid #26262a !important;
}

html body .main-tabs {
    background: #131316 !important;
}

/* ==========================================================
   PANEL DE APARIENCIA
   Cuelga del engranaje de la barra. No es un modal: no tapa la
   pantalla ni bloquea el trabajo, se cierra al hacer click
   afuera o con Escape.
   ========================================================== */

#ap-panel {
    position: fixed;
    top: calc(var(--head-h, 56px) + 8px);
    left: 12px;
    width: 300px;
    max-width: calc(100vw - 24px);
    z-index: 70;
    padding: var(--e-4);
    border-radius: var(--rr-lg, 14px);
    background: #17171a;
    border: 1px solid #2b2b30;
    box-shadow: 0 18px 48px rgba(0, 0, 0, 0.55);
    display: flex;
    flex-direction: column;
    gap: var(--e-4);

    opacity: 0;
    visibility: hidden;
    transform: translateY(-6px);
    transition: opacity 160ms ease, transform 160ms ease, visibility 160ms;
}

#ap-panel.abierto {
    opacity: 1;
    visibility: visible;
    transform: none;
}

.ap-seccion h4 {
    margin: 0 0 var(--e-2) !important;
    font-size: 13px;
    font-weight: 600;
    color: var(--text-main);
    display: flex;
    align-items: center;
    gap: 7px;
}

.ap-seccion h4 i {
    color: var(--primary);
    font-size: 12px;
}

.ap-ayuda {
    margin: 0 0 var(--e-3) !important;
    font-size: 11px;
    line-height: 1.45;
    color: var(--text-dim);
}

/* --- Muestras de color --- */

.ap-colores {
    display: grid;
    grid-template-columns: repeat(8, 1fr);
    gap: 6px;
    margin-bottom: var(--e-3);
}

.ap-color {
    aspect-ratio: 1;
    width: 100%;
    padding: 0;
    border-radius: 50%;
    border: 2px solid transparent;
    background: var(--muestra);
    cursor: pointer;
    transition: transform 140ms ease, box-shadow 140ms ease;
}

.ap-color:hover {
    transform: scale(1.14);
}

/* El elegido lleva un anillo separado del color, no un borde
   encima: sobre un circulo chico el borde se come la muestra. */
.ap-color.activo {
    box-shadow: 0 0 0 2px #17171a, 0 0 0 4px var(--muestra);
}

.ap-personalizado,
.ap-velo {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--e-3);
    font-size: 12px;
    color: var(--text-muted);
}

.ap-velo {
    flex-direction: column;
    align-items: stretch;
    gap: 6px;
    margin-top: var(--e-3);
}

.ap-velo b {
    color: var(--primary);
    font-weight: 600;
}

.ap-velo input[type="range"] {
    width: 100%;
    accent-color: var(--primary);
}

.ap-personalizado input[type="color"] {
    width: 44px;
    height: 28px;
    padding: 0;
    border: 1px solid #2b2b30;
    border-radius: 8px;
    background: transparent;
    cursor: pointer;
}

/* --- Imagen de fondo --- */

.ap-fondo-acciones {
    display: flex;
    gap: 6px;
}

.ap-fondo-acciones .btn {
    flex: 1 1 auto;
    height: 32px !important;
    padding: 0 var(--e-3) !important;
    font-size: 12px !important;
    justify-content: center;
}

.ap-elegir {
    display: inline-flex !important;
    align-items: center;
    gap: 6px;
    cursor: pointer;
}

.ap-estado {
    display: block;
    margin-top: 6px;
    font-size: 11px;
    color: var(--text-dim);
}

.ap-reset {
    width: 100%;
    height: 30px;
    border: 1px solid #2b2b30;
    border-radius: 9px;
    background: transparent;
    color: var(--text-muted);
    font-size: 11px;
    cursor: pointer;
    transition: color 140ms ease, border-color 140ms ease;
}

.ap-reset:hover {
    color: var(--primary);
    border-color: var(--primary);
}

/* ==========================================================
   IMAGEN DE FONDO DEL CRM
   Va debajo del canvas de codigo: la foto abajo, los glifos
   cayendo encima. El velo es lo que mantiene legible la
   aplicacion sobre una imagen cualquiera.
   ========================================================== */

#fondo-imagen {
    position: fixed;
    inset: 0;
    z-index: -2;
    pointer-events: none;
    background-size: cover;
    background-position: center center;
    background-repeat: no-repeat;
    background-attachment: fixed;
}

#fondo-imagen::after {
    content: '';
    position: absolute;
    inset: 0;
    background: #0a0a0b;
    opacity: var(--fondo-velo, 0.72);
}

/* Con imagen propia, los paneles se cierran un poco mas: sobre
   una foto el texto necesita mas respaldo que sobre el grafito. */
html.con-fondo-propio body .glass-panel,
html.con-fondo-propio body .metric-card,
html.con-fondo-propio body .resumen-item,
html.con-fondo-propio body .chart-card,
html.con-fondo-propio body .users-container,
html.con-fondo-propio body .bitacora-panel {
    background: color-mix(in srgb, var(--surf-1) 94%, transparent) !important;
}

@media (max-width: 720px) {
    #ap-panel {
        left: 8px;
        right: 8px;
        width: auto;
    }

    /* La imagen fija se rompe en iOS al hacer scroll */
    #fondo-imagen {
        background-attachment: scroll;
    }
}

/* ==========================================================
   AJUSTE DE LA IMAGEN DE FONDO
   La capa no tenia modo declarado: se apoyaba en el cover del
   bloque original y cualquier foto vertical se veia mal
   encuadrada. Ahora el modo es explicito y elegible.
   ========================================================== */

#fondo-imagen.ajuste-cubrir {
    background-size: cover !important;
    background-position: center center !important;
    background-repeat: no-repeat !important;
}

#fondo-imagen.ajuste-contener {
    background-size: contain !important;
    background-position: center center !important;
    background-repeat: no-repeat !important;
}

#fondo-imagen.ajuste-mosaico {
    background-size: auto !important;
    background-position: top left !important;
    background-repeat: repeat !important;
}

/* El cruce ya no lo hace el contenedor sino las dos capas de
   adentro: ver "CRUCE DE FOTOS DEL FONDO" mas abajo. */

/* ==========================================================
   FONDO PROPIO DEL CHAT

   El velo estaba en un `::before` con `inset: 0` dentro de la
   caja que hace scroll: eso mide el alto VISIBLE, no el de toda
   la conversacion. Con dos pantallas de mensajes el oscurecido
   cubria la primera y se cortaba en seco a la mitad, con el
   borde marcado cruzando la imagen.

   Se saca. La imagen va limpia, como el fondo de cualquier chat,
   y de la legibilidad se ocupan las burbujas, que son opacas.
   ========================================================== */

html.con-chat-fondo body .chat-mensajes {
    background-image: var(--chat-fondo) !important;
    background-size: cover !important;
    background-position: center center !important;
    background-repeat: no-repeat !important;
    /* `scroll` —no `local`— para que la imagen se quede quieta
       mientras la conversacion se desplaza por encima. Con
       `local` se iria hacia arriba con los mensajes y dejaria
       la parte de abajo del historial sin fondo. */
    background-attachment: scroll !important;
}

/* ==========================================================
   CONTROLES NUEVOS DEL PANEL
   ========================================================== */

.ap-ajuste {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 4px;
    margin-top: var(--e-3);
}

.ap-ajuste label {
    position: relative;
    display: block;
    cursor: pointer;
}

.ap-ajuste input {
    position: absolute;
    opacity: 0;
    pointer-events: none;
}

.ap-ajuste span {
    display: block;
    padding: 6px 4px;
    border: 1px solid #2b2b30;
    border-radius: 8px;
    text-align: center;
    font-size: 11px;
    color: var(--text-muted);
    transition: border-color 140ms ease, color 140ms ease;
}

.ap-ajuste input:checked + span {
    border-color: var(--primary);
    color: var(--primary);
    background: rgba(var(--acento-rgb), 0.10);
}

.ap-ajuste label:hover span {
    border-color: var(--primary);
}

#ap-panel {
    max-height: calc(100vh - var(--head-h, 56px) - 24px);
    overflow-y: auto;
}

/* ==========================================================
   BOTONES: CONTORNO, NO RELLENO
   El boton principal era un bloque relleno con degrade y texto
   casi negro (#06231a) fijo. Con un acento claro (lima, ambar)
   el texto oscuro sobre relleno claro se volvia ilegible, y con
   uno oscuro pasaba lo contrario: cualquier acento rompia el
   contraste de alguno de los dos lados.

   La salida no es calcular contraste por color: es no depender
   del relleno. Contorno del acento y texto del acento sobre el
   fondo de la aplicacion — legible con cualquier color, porque
   el fondo siempre es el mismo grafito.
   ========================================================== */

html body .btn-primary,
html body .btn-primary-3d,
html body .section-head__acciones .btn-primary,
html body .section-head__acciones .btn-primary-3d,
html body .btn-success,
html body button[type="submit"].btn-primary,
html body .chat-enviar {
    background: transparent !important;
    background-image: none !important;
    color: var(--primary) !important;
    border: 1.5px solid var(--primary) !important;
    box-shadow: none !important;
    text-shadow: none !important;
}

/* Al pasar por encima se enciende apenas: sigue siendo contorno,
   con el relleno justo para que se note que responde. */
html body .btn-primary:hover,
html body .btn-primary-3d:hover,
html body .section-head__acciones .btn-primary:hover,
html body .section-head__acciones .btn-primary-3d:hover,
html body .btn-success:hover,
html body .chat-enviar:hover {
    background: rgba(var(--acento-rgb), 0.14) !important;
    background-image: none !important;
    color: var(--primary) !important;
    border-color: var(--primary) !important;
    box-shadow: none !important;
    transform: none !important;
}

html body .btn-primary:active,
html body .btn-primary-3d:active,
html body .chat-enviar:active {
    background: rgba(var(--acento-rgb), 0.22) !important;
}

/* Los iconos de adentro heredan el color del boton: si quedan
   con su color propio, el contorno se ve despareja. */
html body .btn-primary i,
html body .btn-primary-3d i,
html body .btn-success i,
html body .chat-enviar i {
    color: inherit !important;
}

/* El boton de enviar del chat es redondo: mantiene la forma */
html body .chat-envio .chat-enviar {
    border-radius: 50% !important;
}

/* ==========================================================
   PESTAÑAS: SIN HALO
   La pestaña activa arrastraba un box-shadow de color y un
   relleno en degrade. Sobre el fondo animado eso se leia como
   una mancha. Queda el subrayado, que es lo que informa.
   ========================================================== */

html body .main-tabs .tab-btn.active {
    background: rgba(var(--acento-rgb), 0.10) !important;
    background-image: none !important;
    box-shadow: none !important;
    border-color: transparent !important;
    color: var(--primary) !important;
}

html body .main-tabs .tab-btn.active::after {
    background: var(--primary) !important;
    box-shadow: none !important;
}

html body .main-tabs .tab-btn:hover:not(.active) {
    box-shadow: none !important;
}

/* ==========================================================
   VERDES QUE QUEDABAN FIJOS
   Cinco tonos escritos a mano que no se movian con el acento:
   los degrades del boton, la barra de horas de uso, el hover de
   "volver al fondo comun" y el icono verde de las tarjetas.
   ========================================================== */

html body .uso-barra-fill {
    background: linear-gradient(180deg,
        var(--primary-hover, var(--primary)),
        var(--primary) 60%,
        var(--primary-dim, var(--primary))) !important;
    box-shadow: none !important;
}

html body #btn-return-to-pool:hover,
html body .btn-warning:hover {
    background: rgba(var(--acento-rgb), 0.14) !important;
    background-image: none !important;
    color: var(--primary) !important;
    border-color: var(--primary) !important;
    box-shadow: none !important;
}

html body .icon-green,
html body .icon-emerald {
    background: rgba(var(--acento-rgb), 0.15) !important;
    color: var(--primary) !important;
    border: 1px solid rgba(var(--acento-rgb), 0.3) !important;
}

/* Los chips de la bitacora y cualquier pastilla de acento */
html body .bitacora-resumen > span,
html body .bitacora-resumen > a,
html body .uso-totales > div {
    background: rgba(var(--acento-rgb), 0.10) !important;
    border-color: rgba(var(--acento-rgb), 0.25) !important;
}

/* El resplandor de foco de los campos tambien sigue el acento */
html body input:focus,
html body select:focus,
html body textarea:focus {
    border-color: var(--primary) !important;
    box-shadow: 0 0 0 3px rgba(var(--acento-rgb), 0.16) !important;
}

/* --- Especificidad del boton de accion ----------------------
   moderno.css pinta todo lo que no lleva .btn-primary como
   secundario: `.btn:not(.btn-primary)` (0,2,1). El boton
   principal de los formularios lleva .btn-primary-3d, no
   .btn-primary, asi que caia en esa regla y quedaba con borde
   gris. Se iguala el peso con .btn.btn-primary-3d (0,2,2). */
html body .btn.btn-primary-3d,
html body .btn.btn-primary,
html body .btn.btn-success,
html body button.btn.btn-primary-3d,
html body form .btn.btn-primary-3d {
    background: transparent !important;
    background-image: none !important;
    color: var(--primary) !important;
    border: 1.5px solid var(--primary) !important;
    box-shadow: none !important;
}

html body .btn.btn-primary-3d:hover,
html body .btn.btn-primary:hover,
html body .btn.btn-success:hover {
    background: rgba(var(--acento-rgb), 0.14) !important;
    color: var(--primary) !important;
    border-color: var(--primary) !important;
}

html body .btn.btn-primary-3d i,
html body .btn.btn-primary i {
    color: inherit !important;
}

/* ==========================================================
   INTENSIDAD DEL CODIGO
   El canvas ya no tiene una opacidad fija: la maneja el panel
   de Apariencia. En 0 ademas se frena el dibujo.
   ========================================================== */

/* La opacidad la escribe js/apariencia.js en el propio canvas.
   Aca solo queda el valor de arranque, sin !important, para que
   ese estilo inline pueda ganarle. */
html body #fondo-codigo {
    opacity: 0.55;
}

/* ==========================================================
   TEXTO SOBRE LA IMAGEN DE FONDO
   Los titulos de seccion, las barras de filtros y los estados
   vacios no viven dentro de un panel: se apoyan directo sobre
   el lienzo. Sin imagen eso esta bien (el grafito es plano),
   pero sobre una foto el texto compite con lo que hay detras y
   se vuelve ilegible.

   No se resuelve con text-shadow: eso ensucia la tipografia y
   sigue sin funcionar sobre zonas claras. Se les da respaldo,
   que es lo que un panel ya hace.
   ========================================================== */

html.con-fondo-propio body .section-head,
html.con-fondo-propio body .barra-filtros,
html.con-fondo-propio body .barra-etapas,
html.con-fondo-propio body .historial-head,
html.con-fondo-propio body .users-header {
    background: color-mix(in srgb, var(--surf-1) 92%, transparent) !important;
    border: 1px solid var(--borde-luz) !important;
    border-radius: var(--rr-lg, 14px) !important;
    padding: var(--e-4) !important;
}

/* La bajada gris claro sobre foto no se lee: sube de tono */
html.con-fondo-propio body .section-head__texto p,
html.con-fondo-propio body .section-head p {
    color: var(--text-muted) !important;
}

/* Estados vacios y cualquier texto suelto del area de trabajo */
html.con-fondo-propio body .estado-vacio,
html.con-fondo-propio body .empty-state {
    background: color-mix(in srgb, var(--surf-1) 92%, transparent) !important;
    border-radius: var(--rr-lg, 14px) !important;
}

/* Las pastillas de etapa tienen fondo propio para no quedar
   flotando sobre la foto */
html.con-fondo-propio body .etapa-pill {
    background: color-mix(in srgb, var(--surf-2) 94%, transparent) !important;
}

/* Con imagen, el velo minimo sube: por debajo de 45% no hay
   combinacion de colores que salve la lectura. */
html.con-fondo-propio body #fondo-imagen::after {
    opacity: max(var(--fondo-velo, 0.72), 0.45);
}

/* Los vacios de Clientes y las pastillas de etapa sueltas eran
   los ultimos textos que quedaban apoyados directo sobre la
   foto. Mismo respaldo que el resto. */
html.con-fondo-propio body .clientes-vacio,
html.con-fondo-propio body .clientes-lista .estado-vacio,
html.con-fondo-propio body .tabla-vacia,
html.con-fondo-propio body .etapa-chip,
html.con-fondo-propio body .badge-etapa {
    background: color-mix(in srgb, var(--surf-1) 92%, transparent) !important;
    border-radius: var(--rr-md, 10px) !important;
    padding: var(--e-3) !important;
}

/* ==========================================================
   CRUCE DE FOTOS DEL FONDO
   Dos capas apiladas dentro de #fondo-imagen. La que entra
   llega desplazada desde un lado al azar y se acomoda mientras
   la anterior se va hacia el lado contrario.

   Se animan solo transform y opacity: las dos propiedades que
   el compositor resuelve sin volver a pintar. Un cruce de dos
   fotos de 15 MB no le cuesta nada al hilo principal.
   ========================================================== */

#fondo-imagen {
    /* El contenedor deja de pintar: ahora dibujan las capas */
    background-image: none !important;
    overflow: hidden;
}

.fondo-capa {
    position: absolute;
    inset: 0;
    opacity: 0;
    background-repeat: no-repeat;
    background-position: center center;
    background-size: cover;
    will-change: transform, opacity;
}

.fondo-capa.activa {
    opacity: 1;
    transform: none;
}

/* La curva importa: un ease-out largo se siente caro, un linear
   se siente barato. 1.1s es el punto donde se nota el movimiento
   sin que llegue a molestar cada vez que rota. */
.fondo-capa.cruzando {
    transition:
        transform 1100ms cubic-bezier(0.22, 1, 0.36, 1),
        opacity 900ms cubic-bezier(0.4, 0, 0.2, 1);
}

/* Posiciones de partida: la capa se coloca corrida y sin
   transicion, y recien en el cuadro siguiente se anima. */
.fondo-capa.preparada {
    transition: none !important;
    opacity: 0;
}

.fondo-capa.desde-arriba     { transform: translate3d(0, -8%, 0) scale(1.06); }
.fondo-capa.desde-abajo      { transform: translate3d(0, 8%, 0) scale(1.06); }
.fondo-capa.desde-izquierda  { transform: translate3d(-8%, 0, 0) scale(1.06); }
.fondo-capa.desde-derecha    { transform: translate3d(8%, 0, 0) scale(1.06); }

/* Y la que sale se va para el lado contrario */
.fondo-capa.hacia-arriba     { transform: translate3d(0, -8%, 0) scale(1.06); opacity: 0; }
.fondo-capa.hacia-abajo      { transform: translate3d(0, 8%, 0) scale(1.06); opacity: 0; }
.fondo-capa.hacia-izquierda  { transform: translate3d(-8%, 0, 0) scale(1.06); opacity: 0; }
.fondo-capa.hacia-derecha    { transform: translate3d(8%, 0, 0) scale(1.06); opacity: 0; }

/* Los modos de ajuste ahora viven en las capas */
.fondo-capa.ajuste-cubrir {
    background-size: cover;
    background-position: center center;
    background-repeat: no-repeat;
}

.fondo-capa.ajuste-contener {
    background-size: contain;
    background-position: center center;
    background-repeat: no-repeat;
}

.fondo-capa.ajuste-mosaico {
    background-size: auto;
    background-position: center center;
    background-repeat: repeat;
}

/* En mosaico el desplazamiento del cruce dejaria ver el borde:
   se agranda apenas la capa para que siempre sobre imagen. */
.fondo-capa.ajuste-mosaico.preparada,
.fondo-capa.ajuste-mosaico.cruzando {
    inset: -10%;
}

/* El velo va por encima de las dos capas */
#fondo-imagen::after {
    z-index: 2;
}

/* Mientras se guarda una foto grande, el boton avisa */
.ap-elegir.ocupado {
    opacity: 0.55;
    pointer-events: none;
}

/* rendimiento.css y ui.css anulan toda transicion con
   prefers-reduced-motion (transition-duration: 0.01ms). Esa
   preferencia viene activada de fabrica en muchas maquinas con
   Windows, y sin esto el cruce de fotos era un corte seco.
   Se reactiva solo para estas capas: es un desplazamiento lento
   de fondo, no un elemento que salte bajo el cursor. */
@media (prefers-reduced-motion: reduce) {
    html body .fondo-capa.cruzando {
        transition:
            transform 1100ms cubic-bezier(0.22, 1, 0.36, 1) !important,
            opacity 900ms cubic-bezier(0.4, 0, 0.2, 1) !important;
    }
}

/* ==========================================================
   GALERIA DE FONDOS
   Antes el panel decia "3 imagenes" y nada mas: no habia forma
   de saber cuales eran ni de sacar una sola. Ahora se ven las
   miniaturas, se hace click para mostrar esa, y cada una tiene
   su cruz para quitarla.
   ========================================================== */

.ap-galeria {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 6px;
    margin-top: var(--e-3);
}

.ap-galeria:empty {
    display: none;
}

.ap-foto {
    position: relative;
    aspect-ratio: 16 / 10;
    border-radius: 8px;
    overflow: hidden;
    border: 2px solid transparent;
    cursor: pointer;
    transition: border-color 140ms ease, transform 140ms ease;
}

.ap-foto img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.ap-foto:hover {
    transform: translateY(-1px);
    border-color: rgba(var(--acento-rgb), 0.5);
}

/* La que se esta viendo lleva el anillo del acento */
.ap-foto.activa {
    border-color: var(--primary);
}

.ap-foto-quitar {
    position: absolute;
    top: 3px;
    right: 3px;
    width: 20px;
    height: 20px;
    padding: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    border: none;
    border-radius: 50%;
    background: rgba(0, 0, 0, 0.65);
    color: #fff;
    font-size: 10px;
    cursor: pointer;
    opacity: 0;
    transition: opacity 140ms ease, background 140ms ease;
}

.ap-foto:hover .ap-foto-quitar {
    opacity: 1;
}

.ap-foto-quitar:hover {
    background: var(--danger);
}

/* En pantalla chica no hay hover: la cruz esta siempre */
@media (hover: none) {
    .ap-foto-quitar { opacity: 1; }
}

/* ==========================================================
   BARRA INFERIOR EN MOVIL
   Los iconos entraban aplastados: 50px de alto para icono +
   etiqueta + padding no alcanza, y el icono terminaba recortado
   contra el texto. Se le da el alto que necesita y se separan.
   ========================================================== */

@media (max-width: 720px) {
    html body .main-tabs {
        padding: 6px 2px calc(6px + env(safe-area-inset-bottom)) !important;
        gap: 0 !important;
    }

    html body .main-tabs .tab-btn {
        min-height: 54px !important;
        padding: 7px 1px 5px !important;
        gap: 5px !important;
        font-size: 9.5px !important;
        letter-spacing: -0.02em !important;
        border-radius: 12px !important;
    }

    html body .main-tabs .tab-btn i {
        font-size: 17px !important;
        line-height: 1 !important;
        height: 17px !important;
        display: flex !important;
        align-items: center !important;
        justify-content: center !important;
    }

    /* La etiqueta no se corta a mitad de palabra: si no entra,
       se achica el texto, no se recorta. */
    html body .main-tabs .tab-btn > span {
        display: block !important;
        width: 100% !important;
        overflow: hidden !important;
        text-overflow: ellipsis !important;
        white-space: nowrap !important;
        line-height: 1.1 !important;
    }

    /* El subrayado de la activa iria abajo de todo, fuera de la
       vista: en la barra inferior se marca con el fondo. */
    html body .main-tabs .tab-btn.active::after {
        display: none !important;
    }

    html body .main-tabs .tab-btn.active {
        background: rgba(var(--acento-rgb), 0.16) !important;
    }

    html body {
        padding-bottom: calc(66px + env(safe-area-inset-bottom)) !important;
    }
}

/* ==========================================================
   CABECERA DEL PERFIL: OTRO DISEÑO
   El problema no era el tamaño de las piezas sino el reparto:
   avatar y nombre a la izquierda, un hueco enorme al medio, y
   las horas de uso con el boton amontonados a la derecha y
   desalineados entre si.

   Ahora es una fila de tres bloques con separadores verticales,
   todos alineados al centro: identidad | uso | accion. El hueco
   desaparece porque el bloque de identidad se estira.
   ========================================================== */

html body .profile-header-card {
    display: flex !important;
    align-items: center !important;
    gap: var(--e-4) !important;
    padding: var(--e-4) !important;
    min-height: 0 !important;
}

html body .profile-header-card > div:first-child {
    flex: 1 1 auto !important;
    gap: var(--e-4) !important;
}

/* El avatar: cuadrado redondeado con el anillo del acento, no
   un circulo suelto en el medio de la nada. */
html body #profile-avatar-preview {
    width: 60px !important;
    height: 60px !important;
    flex: 0 0 60px !important;
    border-radius: 16px !important;
    border: 1px solid rgba(var(--acento-rgb), 0.35) !important;
    box-shadow: 0 0 0 4px rgba(var(--acento-rgb), 0.07) !important;
    object-fit: cover !important;
    background: var(--surf-2) !important;
    padding: 6px !important;
}

html body .profile-avatar-wrapper {
    width: 60px !important;
    height: 60px !important;
    flex: 0 0 60px !important;
}

html body #profile-header-name {
    font-size: 19px !important;
    font-weight: 600 !important;
    letter-spacing: -0.02em !important;
    line-height: 1.15 !important;
}

/* El badge y el mail en la misma linea: son dos datos cortos,
   no merecen un renglon cada uno. */
html body .profile-header-card > div:first-child > div:not(.profile-avatar-wrapper) {
    gap: 5px !important;
}

html body #profile-header-email {
    font-size: 12px !important;
    color: var(--text-dim) !important;
}

/* Las horas de uso: bloque propio, separado por una linea */
html body .uso-inline {
    align-self: center !important;
    padding-left: var(--e-4) !important;
    border-left: 1px solid var(--borde-luz) !important;
}

html body .uso-inline .uso-totales > div {
    min-width: 66px !important;
    padding: 6px 10px !important;
    border-radius: 12px !important;
}

/* El boton de chat cierra la fila, alineado con lo demas */
html body .profile-header-card > div:last-child {
    align-self: center !important;
    margin-left: 0 !important;
    padding-left: var(--e-4) !important;
    border-left: 1px solid var(--borde-luz) !important;
}

@media (max-width: 900px) {
    /* Al angostarse, cada bloque pasa a su propia fila y los
       separadores verticales se vuelven horizontales. */
    html body .profile-header-card {
        flex-wrap: wrap !important;
    }

    html body .uso-inline,
    html body .profile-header-card > div:last-child {
        flex: 1 1 100% !important;
        padding: var(--e-3) 0 0 !important;
        border-left: none !important;
        border-top: 1px solid var(--borde-luz) !important;
    }

    html body .profile-header-card > div:last-child .btn {
        width: 100% !important;
        justify-content: center !important;
    }
}

/* El bloque del boton centra su contenido: sin esto el boton
   quedaba 6px mas abajo que el nombre y las horas de uso. */
html body .profile-header-card > div:last-child {
    display: flex !important;
    align-items: center !important;
}
