/* =========================================
   CRM Construcción - Sistema de Temas Inteligente
   ========================================= */

:root {
    /* --- PALETA MODO CLARO (Por Defecto) --- */
    --bg-body: #f4f6f9;
    --bg-card: #ffffff;
    --bg-header: #f8f9fa;

    /* El texto principal siempre debe contrastar con el fondo */
    --text-main: #212529;       /* Casi negro */
    --text-secondary: #6c757d;  /* Gris */
    --text-inverse: #ffffff;    /* Para botones sólidos */

    --border-color: #dee2e6;
    --accent-color: #1D5B8F;    /* Azul de marca ("blueprint"). Antes era rojo (#d32f2f):
                                   competía con el rojo de peligro de Bootstrap (eliminar,
                                   errores, vencidos), que se deja intacto en su sitio. */
    --accent-rgb: 29, 91, 143;
    --accent-hover: #164A75;

    /* Remapea las utilidades "primary" de Bootstrap (text-primary, border-primary,
       bg-primary, link-primary) al azul de marca en vez del azul por defecto de
       Bootstrap, para que "acción principal" tenga un único color en toda la app. */
    --bs-primary: var(--accent-color);
    --bs-primary-rgb: var(--accent-rgb);

    /* PALETA DE GRÁFICOS Y MAPAS
       Existe porque hasta ahora cada gráfico (analiticas.html, proyecto_detalle.html) y el mapa
       de activos llevaban sus colores a pelo en el JS, empezando por el azul POR DEFECTO de
       Bootstrap (#0d6efd) en vez del azul de marca: el mismo dato salía de un color en el panel
       y de otro en la analítica. La serie 1 es siempre la marca; el resto son los colores
       semánticos que ya usa la app (verde=ingreso, rojo=gasto, ámbar=aviso) más dos neutros de
       apoyo para series adicionales.
       Se leen desde JS con getComputedStyle(document.documentElement).getPropertyValue(...) */
    --chart-1: var(--accent-color);
    --chart-2: #198754;
    --chart-3: #fd7e14;
    --chart-4: #6f42c1;
    --chart-5: #20c997;
    --chart-6: #dc3545;

    /* SOMBRAS */
    --shadow-sm: 0 2px 4px rgba(0,0,0,0.05);
    --shadow-hover: 0 5px 15px rgba(29, 91, 143, 0.15);

    /* TIPOGRAFÍA */
    --font-display: 'IBM Plex Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    --font-condensed: 'IBM Plex Sans Condensed', var(--font-display);
    --font-mono: 'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

    /* LAYOUT */
    --sidebar-width: 264px;
}

/* --- PALETA MODO OSCURO (Activada por JS) --- */
[data-bs-theme="dark"] {
    --bg-body: #121212;
    --bg-card: #1e1e1e;
    --bg-header: #2c2c2c;

    --text-main: #e0e0e0;       /* Blanco suave */
    --text-secondary: #adb5bd;
    --text-inverse: #ffffff;

    --border-color: #495057;
    --accent-color: #5CA3DB;    /* Azul más claro para fondo oscuro */
    --accent-rgb: 92, 163, 219;
    --accent-hover: #7FB8E6;

    --bs-primary: var(--accent-color);
    --bs-primary-rgb: var(--accent-rgb);

    --shadow-sm: 0 2px 4px rgba(0,0,0,0.5);
    --shadow-hover: 0 5px 15px rgba(92, 163, 219, 0.2);
}

/* =========================================
   ESTILOS GLOBALES
   ========================================= */

body {
    background-color: var(--bg-body);
    color: var(--text-main);
    font-family: var(--font-display);
    transition: background-color 0.3s, color 0.3s;
}

h1, h2, h3, h4, h5, h6 {
    letter-spacing: -0.01em;
}

/* Cifras de gasto/coste/saldo negativo: convención financiera (rojo = sale dinero
   o saldo negativo), a propósito distinta de --bs-danger (acción destructiva/error).
   Mismo rojo visualmente, pero con su propio nombre para que un futuro barrido de
   "quitar rojo decorativo" no la confunda ni con marca vieja ni con peligro real. */
.text-expense {
    color: var(--bs-danger) !important;
}
.border-expense {
    border-color: var(--bs-danger) !important;
}
.bg-expense {
    background-color: rgba(var(--bs-danger-rgb), var(--bs-bg-opacity, 1)) !important;
}

/* Cifras que van en columna (importes, contadores): números tabulares para que alineen.
   Opt-in explícito, con la mono de marca: para el dato protagonista de una tarjeta o KPI. */
.text-tabular {
    font-family: var(--font-mono);
    font-variant-numeric: tabular-nums;
}

/* Números tabulares POR DEFECTO donde las cifras se leen en columna, sin tener que acordarse
   de poner una clase. Antes .text-tabular era la única vía y solo se usaba en 2 de las 34
   plantillas que muestran importes: el resto renderizaba con cifras proporcionales, así que
   una misma columna de euros "bailaba" al cambiar de pantalla.

   Aquí NO se cambia la familia tipográfica (eso sigue siendo cosa de .text-tabular): solo se
   fija el ancho de cifra, que es lo que hace que una columna de importes quede alineada.
   Cambiar además la familia de golpe en toda la app habría alterado el aspecto de cada tabla
   sin pedirlo. */
table,
.card .display-1, .card .display-2, .card .display-3,
.card .display-4, .card .display-5, .card .display-6 {
    font-variant-numeric: tabular-nums;
}

/* Enlaces */
a {
    color: var(--accent-color);
    text-decoration: none;
}
a:hover {
    color: var(--text-main);
}

/* =========================================
   COMPONENTES PRINCIPALES
   ========================================= */

/* 1. Tarjetas */
.card {
    background-color: var(--bg-card);
    border: 1px solid var(--border-color);
    color: var(--text-main); /* Forzar color de texto base */
    box-shadow: var(--shadow-sm);
}

.card:hover {
    transform: translateY(-2px);
    box-shadow: var(--shadow-hover);
    border-color: var(--accent-color);
    transition: all 0.2s ease;
}

.card-header {
    background-color: var(--bg-header);
    border-bottom: 1px solid var(--border-color);
    color: var(--text-main);
    font-weight: 600;
}

.card-footer {
    background-color: var(--bg-header);
    border-top: 1px solid var(--border-color);
}

/* Jerarquía entre tarjetas de estadística: la destacada lleva sombra y color;
   las de solo-recuento van sin chrome, para que no compitan por atención. */
.kpi-quiet.card {
    background: transparent;
    border: none !important;
    box-shadow: none !important;
}

/* 2. Tablas */
.table {
    color: var(--text-main);
    --bs-table-color: var(--text-main);
    --bs-table-bg: var(--bg-card);
    --bs-table-border-color: var(--border-color);
    --bs-table-striped-bg: rgba(0, 0, 0, 0.03); /* Gris suave en claro */
}

[data-bs-theme="dark"] .table {
    --bs-table-striped-bg: rgba(255, 255, 255, 0.05); /* Blanco suave en oscuro */
}

.table thead th {
    background-color: var(--bg-header);
    color: var(--text-main);
    border-bottom: 2px solid var(--accent-color);
}

/* 3. Formularios */
.form-control, .form-select {
    background-color: var(--bg-card);
    color: var(--text-main);
    border: 1px solid var(--border-color);
}

.form-control:focus, .form-select:focus {
    background-color: var(--bg-card);
    color: var(--text-main);
    border-color: var(--accent-color);
    box-shadow: 0 0 0 0.25rem rgba(var(--accent-rgb), 0.25);
}

/* 3b. Botones: btn-primary/btn-outline-primary de Bootstrap traen sus colores ya
   compilados dentro de la propia clase (no heredan de una variable raíz), así que
   hay que redefinirlos aquí para que usen el azul de marca. text-primary/
   border-primary/bg-primary sí heredan de --bs-primary-rgb (arriba) y no hace
   falta tocarlos aparte. */
.btn-primary {
    --bs-btn-bg: var(--accent-color);
    --bs-btn-border-color: var(--accent-color);
    --bs-btn-hover-bg: var(--accent-hover);
    --bs-btn-hover-border-color: var(--accent-hover);
    --bs-btn-active-bg: var(--accent-hover);
    --bs-btn-active-border-color: var(--accent-hover);
    --bs-btn-focus-shadow-rgb: var(--accent-rgb);
    --bs-btn-disabled-bg: var(--accent-color);
    --bs-btn-disabled-border-color: var(--accent-color);
}

.btn-outline-primary {
    --bs-btn-color: var(--accent-color);
    --bs-btn-border-color: var(--accent-color);
    --bs-btn-hover-bg: var(--accent-color);
    --bs-btn-hover-border-color: var(--accent-color);
    --bs-btn-active-bg: var(--accent-color);
    --bs-btn-active-border-color: var(--accent-color);
    --bs-btn-focus-shadow-rgb: var(--accent-rgb);
    --bs-btn-disabled-color: var(--accent-color);
    --bs-btn-disabled-border-color: var(--accent-color);
}

/* 4. Navegación */
.navbar {
    background-color: var(--bg-card) !important;
}

.navbar-brand {
    color: var(--accent-color) !important;
    font-weight: bold;
}

.nav-link {
    color: var(--text-main) !important;
}

.nav-link:hover {
    color: var(--accent-color) !important;
}

/* --- Barra lateral (sidebar) --- */
/* Material translúcido compartido por el sidebar y la barra móvil: capa de cristal
   flotando sobre el contenido, no un cartel opaco. prefers-reduced-transparency
   vuelve a un fondo sólido sin blur. */
.glass-chrome {
    background-color: rgba(255, 255, 255, 0.72);
    backdrop-filter: blur(18px) saturate(180%);
    -webkit-backdrop-filter: blur(18px) saturate(180%);
}
[data-bs-theme="dark"] .glass-chrome {
    background-color: rgba(30, 30, 30, 0.72);
}
@media (prefers-reduced-transparency: reduce) {
    .glass-chrome {
        background-color: var(--bg-card) !important;
        backdrop-filter: none;
        -webkit-backdrop-filter: none;
    }
}

/* Barra superior solo en móvil/tablet (<lg): hamburguesa + marca + Portal. */
.topbar-mobile {
    position: sticky;
    top: 0;
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: 0.65rem 1rem;
    border-bottom: 1px solid var(--border-color);
}
.topbar-mobile .navbar-brand { margin-bottom: 0; }

/* El propio sidebar: oculto fuera de pantalla por defecto (móvil/tablet), se
   convierte en fijo y siempre visible a partir de "lg" (ver media query abajo). */
.app-sidebar {
    position: fixed;
    top: 0;
    left: 0;
    bottom: 0;
    width: var(--sidebar-width);
    display: flex;
    flex-direction: column;
    border-right: 1px solid var(--border-color);
    transform: translateX(-100%);
    transition: transform 0.25s ease;
}
.app-sidebar.show { transform: translateX(0); }
@media (prefers-reduced-motion: reduce) {
    .app-sidebar { transition: none; }
}

.sidebar-brand {
    padding: 1.1rem 1.25rem 0.75rem;
}
.sidebar-brand .navbar-brand { margin-bottom: 0; }

.sidebar-portal-link {
    display: flex;
    align-items: center;
    gap: 0.6em;
    margin: 0 0.75rem 0.75rem;
    padding: 0.5rem 0.75rem;
    border-radius: 8px;
    background: rgba(var(--accent-rgb), 0.1);
    color: var(--accent-color) !important;
    font-weight: 600;
    font-size: 0.9rem;
    text-decoration: none;
}

.sidebar-nav {
    flex: 1 1 auto;
    overflow-y: auto;
    padding: 0 0.75rem 0.75rem;
}

.sidebar-group-title {
    display: flex;
    align-items: center;
    gap: 0.5em;
    margin: 1.1rem 0.75rem 0.3rem;
    font-family: var(--font-condensed);
    font-size: 0.72rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-secondary);
}
.sidebar-group-title:first-child { margin-top: 0.25rem; }

.sidebar-subgroup-title {
    margin: 0.6rem 0.75rem 0.15rem;
    padding-left: 0.75rem;
    font-size: 0.68rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--text-secondary);
    opacity: 0.8;
}

.sidebar-link {
    display: flex;
    align-items: center;
    gap: 0.65em;
    padding: 0.4rem 0.75rem 0.4rem 1.5rem;
    margin: 0.05rem 0;
    border-radius: 6px;
    color: var(--text-main);
    font-size: 0.87rem;
    text-decoration: none;
    border: none;
    background: none;
    width: 100%;
    text-align: left;
    font-family: inherit;
    cursor: pointer;
}
.sidebar-link:hover {
    background: rgba(var(--accent-rgb), 0.08);
    color: var(--accent-color);
}
.sidebar-link i { width: 1.1em; text-align: center; flex: none; }

.sidebar-footer {
    border-top: 1px solid var(--border-color);
    padding: 0.75rem;
}
.sidebar-user {
    display: flex;
    align-items: center;
    gap: 0.6em;
    padding: 0.3rem 0.5rem;
    border-radius: 6px;
    color: var(--text-main) !important;
    text-decoration: none;
    overflow: hidden;
}
.sidebar-user:hover { background: rgba(var(--accent-rgb), 0.08); }

/* Fondo oscuro del sidebar en móvil/tablet; clic fuera = cerrar. Invisible y
   fuera de la jugada en escritorio (ver media query abajo). */
.sidebar-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.5);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.2s ease;
}
.sidebar-backdrop.show { opacity: 1; pointer-events: auto; }

@media (max-width: 991.98px) {
    body.sidebar-open { overflow: hidden; }
}

@media (min-width: 992px) {
    .topbar-mobile, .sidebar-backdrop { display: none !important; }
    .app-sidebar { transform: none; }
    /* Solo se aparta el contenido si la página TIENE sidebar. Antes era `body { margin-left }`
       a secas, lo que obligaba a que las pantallas sin sidebar (login, cambiar contraseña,
       suscripción requerida, portal, escáner, páginas legales) no pudieran enlazar esta hoja:
       habrían quedado con 264px de hueco a la izquierda y nada dentro. Por eso cada una se
       traía su propia copia de tipografías y colores, y de ahí venía la deriva visual.
       Con :has() la regla se autocorrige sola: quien monta el sidebar lo recibe, quien no, no. */
    body:has(.app-sidebar) { margin-left: var(--sidebar-width); }
}

/* 5. Footer */
footer {
    background-color: var(--bg-card) !important;
    border-top: 1px solid var(--border-color);
    color: var(--text-secondary) !important;
}

/* =========================================
   🚨 SEGURIDAD DE CONTRASTE (CORRECCIONES)
   ========================================= */

/* Antes había aquí un "html:not([data-bs-theme=dark]) .text-white { color: #212529 !important }"
   para arreglar títulos que usaban por error text-white sobre fondo claro (clientes.html,
   facturas.html, empleados.html). Al ser una regla global, también rompía el contraste de
   .text-white legítimo sobre fondos de color (cabeceras bg-primary/bg-danger de
   certificacion_form.html, navbar del Portal del Empleado). Los títulos con el error se
   corrigieron en su propia plantilla en vez de secuestrar la utilidad de Bootstrap aquí. */

html:not([data-bs-theme="dark"]) .text-light {
    color: #6c757d !important;
}

/* CORRECCIÓN MODO OSCURO:
   Si el HTML tiene 'text-dark' pero estamos en modo oscuro sobre fondo negro,
   lo forzamos a blanco.
*/
[data-bs-theme="dark"] .text-dark {
    color: #e0e0e0 !important;
}

[data-bs-theme="dark"] .text-muted {
    color: #adb5bd !important;
}

[data-bs-theme="dark"] .bg-light {
    background-color: #2c2c2c !important; /* Fondo gris oscuro en vez de blanco */
}

[data-bs-theme="dark"] .bg-white {
    background-color: #1e1e1e !important; /* Fondo negro suave en vez de blanco puro */
}

/* Botones Outline en modo oscuro */
[data-bs-theme="dark"] .btn-outline-dark {
    color: #e0e0e0;
    border-color: #e0e0e0;
}
[data-bs-theme="dark"] .btn-outline-dark:hover {
    background-color: #e0e0e0;
    color: #000;
}

/* =========================================
   🚑 PARCHE DE SEGURIDAD DE INTERFAZ (CORREGIDO)
   ========================================= */

/* La regla que apagaba .modal-backdrop/.offcanvas-backdrop en toda la app (y que forzaba
   overflow-y/padding-right del body) se retiró al añadir el modal de confirmación real
   (ver fragments.html :: footer y crm.js). Tapaba un bug histórico de un backdrop que se
   quedaba bloqueando la página, pero de paso impedía que CUALQUIER modal real tuviera fondo
   oscuro y bloqueaba el scroll-lock del body mientras un modal está abierto. El offcanvas
   propio del Portal del Empleado (portal_nav.html) usa sus propias clases .portal-drawer*,
   no .offcanvas, así que no le afecta este cambio. Si vuelve a aparecer un backdrop
   atascado, acotar la solución a ese caso concreto en vez de apagarlo globalmente otra vez. */

/* ASEGURAR QUE EL CUERPO SEA CLICABLE */
body {
    pointer-events: auto !important;
}

/* Modal de confirmación de marca (fragments.html :: footer) */
.confirm-modal-icon {
    width: 3.25rem;
    height: 3.25rem;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 0 auto;
    font-size: 1.25rem;
    background: rgba(var(--bs-danger-rgb), 0.12);
    color: var(--bs-danger);
}
.confirm-modal-icon.is-primary {
    background: rgba(var(--accent-rgb), 0.12);
    color: var(--accent-color);
}
#confirmActionModal .modal-content {
    border: none;
    border-radius: 12px;
}

/* --- JERARQUÍA DE CAPAS (Z-INDEX) --- */

/* NIVEL 3 (MÁXIMO): la barra lateral y su versión móvil siempre encima de todo. */
.app-sidebar, .topbar-mobile {
    z-index: 2000 !important;
}

.sidebar-backdrop {
    z-index: 1990 !important; /* justo debajo del sidebar, por encima del contenido */
}

.dropdown-menu {
    z-index: 2050 !important; /* Aún más alto que la barra, para los dropdowns que queden fuera de la navegación principal */
}

/* NIVEL 2: Botones flotantes o alertas (si los hubiera) */
.alert {
    position: relative;
    z-index: 1500 !important;
}

/* NIVEL 1 (BASE): El contenido de la página */
.container, footer, .card, .btn {
    position: relative;
    z-index: 1 !important; /* Muy bajo para que el menú pase por encima */
}

/* 4. ELIMINAR CONFLICTOS DE LOGIN */
body.login-page {
    display: block !important;
}