/**
 * ╔══════════════════════════════════════════════════════════════════════╗
 * ║  iga-theme.css — Sistema visual IGA · piloto en Empleados            ║
 * ║  Nexus · Inversiones Galindo Aros                                     ║
 * ╠══════════════════════════════════════════════════════════════════════╣
 * ║  Spec: BRIEF_DISENO_IGA_PILOTO.md                                     ║
 * ║                                                                       ║
 * ║  POR QUÉ ESTE ARCHIVO ES CSS A MANO Y NO CLASES DE TAILWIND           ║
 * ║  El brief (§1.1) asume Tailwind por CDN. Este proyecto lo usa         ║
 * ║  COMPILADO (assets/css/nexus.css) y hoy `node_modules/` no está       ║
 * ║  instalado, así que `npm run build:css` no corre. Una clase de        ║
 * ║  Tailwind nueva no aparecería en el CSS — y el purge no falla con     ║
 * ║  error: el estilo simplemente no se ve. Escribir los componentes      ║
 * ║  nuevos como CSS propio los hace inmunes a eso.                      ║
 * ║                                                                       ║
 * ║  Además es el patrón que el proyecto ya usa para estilos de vista     ║
 * ║  (.inp en empleados.php, .iga-tab en turnos): no se introduce una     ║
 * ║  forma nueva de hacer las cosas.                                      ║
 * ║                                                                       ║
 * ║  Se carga DESPUÉS de nexus.css para poder pisarlo cuando hace falta.  ║
 * ╚══════════════════════════════════════════════════════════════════════╝
 */

/* ══════════════════════════════════════════════════════════════════════
   1 · TOKENS DE MARCA                                        (brief §2)
   ──────────────────────────────────────────────────────────────────────
   AZUL — El brief propone la escala `blue` de Tailwind (#2563eb). NO se
   usa, y la razón importa: el sistema ya tiene una paleta azul derivada
   del LOGO de IGA (--brand-*, en tailwind-entrada.css, sacada del brief
   de color de Juan Manuel: #79B4D9). Meter un segundo azul, más saturado,
   dejaría el sidebar de un tono y los elementos nuevos de otro — se vería
   como un error, no como una decisión.

   El propio brief lo prevé: "usar lo que genere menos duplicación" (§2.1).
   Así que --iga-blue-* apunta a la escala de marca que ya existe.

   PLATEADO — `slate`, como pide el brief: temperatura fría, no el gris
   cálido de `gray`.
   ══════════════════════════════════════════════════════════════════════ */
:root {
    /* Azul de marca — los mismos valores que --brand-*, expresados aquí
       en hex para poder usarlos en gradientes y rgba() sin ceremonia. */
    --iga-blue-50:  #f4f9fc;
    --iga-blue-100: #e7f2f8;
    --iga-blue-400: #96c5e1;
    --iga-blue-500: #79b4d9;
    --iga-blue-600: #6a9ebf;
    --iga-blue-700: #557e98;
    --iga-blue-900: #273a45;
    --iga-blue-950: #0f1c2e;   /* el mismo del manifest y del favicon */

    /* Plateado — escala slate de Tailwind */
    --iga-silver-50:  #f8fafc;
    --iga-silver-100: #f1f5f9;
    --iga-silver-200: #e2e8f0;
    --iga-silver-400: #94a3b8;
    --iga-silver-600: #475569;

    --iga-black: #0f172a;
    --iga-white: #ffffff;
}


/* ══════════════════════════════════════════════════════════════════════
   1b · MODO OSCURO                                        (14-ago-2026)
   ──────────────────────────────────────────────────────────────────────
   Se INVIERTEN LOS TOKENS, no se reescribe cada componente.

   Los 42 componentes .iga-* de este archivo ya pintan con var(--iga-*)
   en vez de colores fijos, así que redefinir esas variables bajo .dark
   los oscurece TODOS de una vez: tarjetas, KPIs, badges, breadcrumb,
   grid… sin tocar ni una línea del HTML de las vistas.

   La alternativa era ir vista por vista agregando `dark:` a cada
   `bg-white` — unos 160 repartidos en 11 módulos. Además de ser mucho
   más trabajo, dejaría el modo oscuro dependiendo de que nadie olvide
   la variante `dark:` al escribir una tarjeta nueva. Así, un componente
   nuevo que use los tokens ya nace con modo oscuro.

   Los valores NO son la escala clara al revés: en oscuro los fondos van
   a slate-900/800 (no negro puro, que produce halo en pantallas OLED y
   cansa) y el texto a slate-200 (no blanco puro, mismo motivo). El azul
   de marca se ACLARA un paso: el tono medio del logo (#79b4d9) tiene
   poco contraste sobre fondo oscuro.
   ══════════════════════════════════════════════════════════════════════ */
.dark {
    /* Azul de marca: un paso más claro para que contraste sobre oscuro.

       OJO con --iga-blue-900 y --iga-blue-950: NO se invierten. No son
       "el azul más oscuro de la escala" sin más — son el fondo del header
       (.iga-franja-superior/.iga-franja-titulo) y del sidebar, que YA
       eran oscuros en modo claro por decisión de diseño (brief §2.2: el
       negro es del header). Invertirlos dejaba una banda blanca cruzando
       la parte de arriba de todas las pantallas en modo oscuro — se veía
       exactamente como un error de render. Se dejan tal cual. */
    --iga-blue-50:  #172554;
    --iga-blue-100: #1e3a5f;
    --iga-blue-400: #96c5e1;
    --iga-blue-500: #a8d0e6;
    --iga-blue-600: #96c5e1;
    --iga-blue-700: #79b4d9;
    --iga-blue-900: #1e293b;   /* header/sidebar: oscuro en los DOS temas */
    --iga-blue-950: #0b1220;   /* un punto más hondo que en claro, no claro */

    /* Plateado invertido: lo que era casi blanco pasa a casi negro. */
    --iga-silver-50:  #0f172a;
    --iga-silver-100: #1e293b;
    --iga-silver-200: #334155;   /* bordes: visibles pero sin gritar */
    --iga-silver-400: #94a3b8;   /* texto secundario: igual, ya contrastaba */
    --iga-silver-600: #cbd5e1;

    --iga-black: #e2e8f0;        /* el "texto negro" pasa a claro */
    --iga-white: #1e293b;        /* el "fondo blanco" pasa a oscuro */
}


/* ══════════════════════════════════════════════════════════════════════
   2 · HEADER EN DOS FRANJAS                       (refinamiento brief §1)
   ──────────────────────────────────────────────────────────────────────
   Antes el título de la vista y el saludo peleaban en la misma línea, sin
   jerarquía. Ahora son dos franjas: arriba el saludo y el usuario, debajo
   el título con su propio sitio.

   Las dos van oscuras porque el brief asigna el negro al header (§2.2).
   El markup del header estaba escrito para fondo blanco, así que aquí se
   reasignan los colores en bloque en vez de reescribir el HTML: menos
   superficie de cambio, menos regresión.

   Lo pinta includes/header_vista.php, un solo archivo para todo el
   sistema.
   ══════════════════════════════════════════════════════════════════════ */

/* ── Franja superior: saludo, usuario, avatar ───────────────────────── */
.iga-franja-superior {
    background: var(--iga-blue-950);
    border-bottom: 1px solid rgba(255, 255, 255, 0.06);
    color: var(--iga-silver-200);
}
.iga-franja-superior .iga-h-nombre { color: var(--iga-silver-200); }
.iga-franja-superior .iga-h-correo { color: var(--iga-silver-400); }

.iga-pill-saludo {
    background: rgba(255, 255, 255, 0.07);
    border: 1px solid rgba(255, 255, 255, 0.12);
    color: var(--iga-blue-400);
}
.iga-pill-saludo span { color: inherit; }

/* ── Franja de título: aquí sí va el glass ──────────────────────────────
   El blur solo EXISTE si hay algo que difuminar detrás, y eso exige que
   el contenido pase por debajo: de ahí el `sticky`. Sin él la franja se
   vería simplemente translúcida, que no es lo mismo.

   El degradado va de azul-950 a azul-900 —no al azul del brief (#1e3a8a),
   que es de otra escala— para no meter un segundo azul que se leería como
   error de color junto al sidebar. */
.iga-franja-titulo {
    position: sticky;
    top: 0;
    z-index: 30;
    padding: 1.15rem 2rem;
    text-align: center;
    background: linear-gradient(135deg,
                rgba(15, 28, 46, 0.88),
                rgba(39, 58, 69, 0.80));
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}

/* Sin soporte de backdrop-filter, un fondo translúcido deja leer el
   contenido a través de la franja. Se vuelve opaca: menos bonita, legible. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    .iga-franja-titulo { background: var(--iga-blue-950); }
}

.iga-titulo-vista {
    margin: 0;
    color: var(--iga-white);
    font-size: 1.35rem;
    font-weight: 700;
    letter-spacing: 0.02em;
    line-height: 1.2;
    /* Un título largo en pantalla angosta debe partir, no desbordar
       lateralmente y romper el layout. */
    overflow-wrap: anywhere;
}

.iga-subtitulo-vista {
    margin: .2rem 0 0;
    color: var(--iga-silver-400);
    font-size: .78rem;
    font-weight: 500;
    letter-spacing: .01em;
}

@media (max-width: 640px) {
    .iga-franja-titulo { padding: .85rem 1rem; }
    .iga-titulo-vista  { font-size: 1.1rem; }
}


/* ══════════════════════════════════════════════════════════════════════
   3 · ACENTO TORNASOL — UN SOLO PUNTO                        (brief §4)
   ──────────────────────────────────────────────────────────────────────
   Va en el botón "Agregar Empleado": la acción primaria más importante de
   la pantalla (candidato 2 del brief).

   REGLA: si esto aparece en un segundo elemento de la misma pantalla,
   deja de ser acento. Es condimento, no salsa base. Antes de reutilizar
   esta clase en otro lado, quitarla de aquí.

   El gradiente recorre azul de marca → plateado → cian, y se DESPLAZA al
   pasar el mouse (por eso el background-size de 200%): el tornasol se
   nota en el movimiento, no en el color quieto.
   ══════════════════════════════════════════════════════════════════════ */
.iga-acento-tornasol {
    background-image: linear-gradient(
        110deg,
        var(--iga-blue-700) 0%,
        var(--iga-blue-500) 30%,
        #a8c8dd            50%,
        #5eead4            70%,
        var(--iga-blue-600) 100%
    );
    background-size: 200% 100%;
    background-position: 0% 50%;
    transition: background-position .55s ease, box-shadow .25s ease, transform .12s ease;
    box-shadow: 0 2px 10px rgba(106, 158, 191, 0.35);
}
.iga-acento-tornasol:hover { background-position: 100% 50%; box-shadow: 0 4px 16px rgba(106, 158, 191, .45); }
.iga-acento-tornasol:active { transform: translateY(1px); }

/* Quien pidió menos animación no debería recibir un degradado en marcha. */
@media (prefers-reduced-motion: reduce) {
    .iga-acento-tornasol { transition: none; }
    .iga-acento-tornasol:hover { background-position: 0% 50%; }
}


/* ══════════════════════════════════════════════════════════════════════
   4 · TOGGLE LISTA / TARJETAS                                (brief §5.1)
   ══════════════════════════════════════════════════════════════════════ */
.iga-toggle-vista {
    display: inline-flex;
    padding: 3px;
    gap: 2px;
    background: var(--iga-silver-100);
    border: 1px solid var(--iga-silver-200);
    border-radius: .75rem;
}
.iga-toggle-vista button {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    padding: .3rem .6rem;
    border-radius: .55rem;
    font-size: 11px;
    font-weight: 700;
    color: var(--iga-silver-600);
    background: transparent;
    border: 0;
    cursor: pointer;
    transition: background .15s, color .15s, box-shadow .15s;
}
.iga-toggle-vista button:hover { color: var(--iga-blue-700); }

/* `aria-pressed` no es decorativo: es lo que le dice a un lector de
   pantalla cuál vista está activa. Se usa TAMBIÉN como selector para que
   el estado visual y el accesible no puedan separarse por descuido. */
.iga-toggle-vista button[aria-pressed="true"] {
    background: var(--iga-white);
    color: var(--iga-blue-700);
    box-shadow: 0 1px 3px rgba(15, 23, 42, .10);
}
.iga-toggle-vista button:focus-visible {
    outline: 2px solid var(--iga-blue-500);
    outline-offset: 1px;
}


/* ══════════════════════════════════════════════════════════════════════
   5 · VISTA TARJETAS                                         (brief §5.2)
   ──────────────────────────────────────────────────────────────────────
   SIN glassmorphism, a propósito: son superficie de datos repetida y el
   brief lo prohíbe explícitamente (§3.2). Blur sobre 15 tarjetas —o sobre
   200 cuando crezca la nómina— cansa la vista y cuesta de renderizar.
   ══════════════════════════════════════════════════════════════════════ */
.iga-cards-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
    gap: 1rem;
    padding: 1.25rem 1.5rem 1.5rem;
}

/* En pantallas angostas se fuerza UNA columna en vez de confiar en el
   auto-fill. Con minmax(250px, …) y los 3rem de padding lateral, un
   teléfono de 320 px (iPhone SE) deja 240 px útiles: menos que el mínimo,
   así que la columna se sale y aparece scroll horizontal en toda la
   página. Una sola columna no puede desbordar. */
@media (max-width: 480px) {
    .iga-cards-grid {
        grid-template-columns: 1fr;
        padding: 1rem;
        gap: .75rem;
    }
}

.iga-card {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: .75rem;
    padding: 1rem;
    background: var(--iga-white);
    border: 1px solid var(--iga-silver-200);
    border-radius: 1rem;
    text-align: left;
    cursor: pointer;
    transition: border-color .15s, box-shadow .15s, transform .12s;
}
.iga-card:hover {
    border-color: var(--iga-blue-400);
    box-shadow: 0 6px 20px rgba(15, 23, 42, .07);
    transform: translateY(-2px);
}
.iga-card:focus-visible {
    outline: 2px solid var(--iga-blue-500);
    outline-offset: 2px;
}

.iga-card-top { display: flex; align-items: center; gap: .65rem; }

.iga-card-avatar {
    width: 2.5rem;
    height: 2.5rem;
    flex-shrink: 0;
    border-radius: 999px;
    background: var(--iga-blue-100);
    color: var(--iga-blue-700);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 14px;
    font-weight: 700;
}

.iga-card-nombre {
    font-size: 13px;
    font-weight: 700;
    color: var(--iga-black);
    line-height: 1.25;
}
.iga-card-cargo {
    font-size: 11px;
    color: var(--iga-silver-600);
    line-height: 1.3;
}

.iga-card-datos {
    display: flex;
    flex-direction: column;
    gap: .25rem;
    font-size: 11px;
    color: var(--iga-silver-600);
}
.iga-card-dato { display: flex; align-items: center; gap: .35rem; }
.iga-card-dato svg { width: .8rem; height: .8rem; flex-shrink: 0; color: var(--iga-silver-400); }

/* Nació en la card de Flota: "Sin conductor" no es un dato neutro como
   el resto de .iga-card-dato, es una alerta — mismo rojo que
   .iga-badge--mal, para no inventar un tercer tono de "esto está mal". */
.iga-card-dato--alerta,
.iga-card-dato--alerta svg { color: #be123c; }

.iga-card-pie {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .5rem;
    margin-top: auto;
    padding-top: .65rem;
    border-top: 1px solid var(--iga-silver-100);
}
.iga-card-ver {
    display: inline-flex;
    align-items: center;
    gap: .25rem;
    font-size: 11px;
    font-weight: 700;
    color: var(--iga-blue-700);
}
.iga-card:hover .iga-card-ver { color: var(--iga-blue-600); }

/* Estado vacío de la vista tarjetas — ocupa toda la rejilla. */
.iga-cards-vacio {
    grid-column: 1 / -1;
    padding: 3rem 1rem;
    text-align: center;
    font-size: 12px;
    color: var(--iga-silver-400);
}


/* ══════════════════════════════════════════════════════════════════════
   6 · ALTERNANCIA DE VISTAS
   ──────────────────────────────────────────────────────────────────────
   Las dos vistas se renderizan en el servidor y se muestran/ocultan en el
   cliente. Se hace así —y no cargando por AJAX— porque los filtros, la
   búsqueda y la paginación ya resuelven en PHP: reconstruirlos en JS sería
   duplicar lógica y arriesgar que las dos vistas dejen de coincidir.

   El costo es marcar el HTML dos veces por página (hoy 15 filas), que a
   esta escala no se nota.
   ══════════════════════════════════════════════════════════════════════ */
/* Genérico desde el 01-ago-2026: antes era [data-vista-empleados], solo
   para Empleados. Al llegar Flota como segundo módulo con el mismo
   toggle, mantener un atributo por módulo habría repetido la misma
   duplicación que ya se resolvió con el header (9 copias de un mismo
   bloque). Un atributo en <html> alcanza porque solo hay un toggle
   activo por página. Ver JS/iga-vista-toggle.js. */
[data-vista="lista"]    .iga-solo-tarjetas { display: none; }
[data-vista="tarjetas"] .iga-solo-lista    { display: none; }


/* ══════════════════════════════════════════════════════════════════════
   7 · TEXTURA DE FONDO DEL ÁREA DE CONTENIDO   (refinamiento brief §2)
   ──────────────────────────────────────────────────────────────────────
   De las dos opciones del brief se toma el degradado radial, no el patrón
   de puntos: la regla es que "nadie pueda señalar qué cambió" (§2), y una
   retícula de puntos SÍ se reconoce como retícula en cuanto el ojo se
   detiene. Un halo tenue bajo el header no se percibe como patrón.

   Va a 0.025 en vez del 0.02 del brief porque el azul de marca es más
   claro y desaturado que el #3b82f6 que el brief asumía: al 0.02 no se
   distinguía del blanco ni midiendo.
   ══════════════════════════════════════════════════════════════════════ */
.iga-area-contenido {
    background-color: var(--iga-silver-50);
    background-image: radial-gradient(
        circle at top center,
        rgba(121, 180, 217, 0.10),
        transparent 55%
    );
    background-repeat: no-repeat;
    background-attachment: local;
}


/* ══════════════════════════════════════════════════════════════════════
   8 · PROFUNDIDAD EN LAS CARDS                 (refinamiento brief §3)
   ══════════════════════════════════════════════════════════════════════ */

/* Avatar con gradiente (§3.1). El texto pasa a blanco: la inicial en
   azul-700 sobre el gradiente quedaba en 2.1:1 de contraste, por debajo
   del mínimo legible. */
.iga-card-avatar {
    background: linear-gradient(135deg, var(--iga-blue-500), var(--iga-silver-400));
    color: var(--iga-white);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25);
}

/* Elevación en hover (§3.2). La sombra lleva tinte azul en vez de negro:
   una sombra neutra sobre fondo frío se ve sucia. */
.iga-card:hover {
    transform: translateY(-2px);
    box-shadow: 0 8px 24px rgba(39, 58, 69, 0.14);
    border-color: var(--iga-blue-500);
}

/* Quien pidió menos animación no debería recibir cards que saltan. */
@media (prefers-reduced-motion: reduce) {
    .iga-card, .iga-card:hover { transform: none; transition: none; }
}


/* ══════════════════════════════════════════════════════════════════════
   9 · FRANJA DE KPIs                           (refinamiento brief §4)
   ══════════════════════════════════════════════════════════════════════ */
/* auto-fit y no `repeat(4, ...)` fijo: Empleados usa 4 tarjetas, Flota
   usa 4 o 5 (una quinta condicional, "Sin Conductor", solo en IGA). Con
   un número fijo, la quinta se habría desbordado a una fila propia de
   una sola columna. Con 180px de mínimo, en escritorio caben 4-5 en una
   fila y en móvil cae solo a 1-2 sin necesitar breakpoint aparte. */
.iga-kpis {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: .75rem;
    margin-bottom: 1rem;
    /* Tope de ancho (09-ago-2026). Con pocas tarjetas en una pantalla grande,
       `1fr` las estiraba a ~500px de ancho por 90 de alto: quedaban como barras
       medio vacías (Juan: "está como muy grande y hay espacio de sobra").

       Se topa el CONTENEDOR y no la tarjeta a propósito. Topar la tarjeta
       (`minmax(180px, 340px)`) habría cambiado cuántas columnas caben, y eso
       tiene dos efectos feos: en pantallas medianas 3 tarjetas pasarían a 2+1,
       y en Control de Parqueo rompería algo PEDIDO por Juan el 02-ago ("4
       arriba y 3 estirado a lo largo abajo") — la fila de 3 es más ancha
       justamente porque reparte el mismo ancho entre menos tarjetas.

       Con un tope de contenedor eso se conserva: la fila de 3 sigue siendo más
       ancha que la de 4, solo que ambas dentro de un límite sano. Y como los
       tracks siguen siendo `1fr`, el número de columnas no cambia nunca. */
    max-width: 82rem;
}

.iga-kpi {
    background: var(--iga-white);
    border: 1px solid var(--iga-silver-200);
    border-radius: 12px;
    padding: .8rem 1rem;
}

.iga-kpi-valor {
    font-size: 1.5rem;
    font-weight: 800;
    line-height: 1.1;
    color: var(--iga-black);
    font-variant-numeric: tabular-nums;
}
.iga-kpi-etiqueta {
    margin-top: .15rem;
    font-size: .68rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: var(--iga-silver-400);
    line-height: 1.3;
}
.iga-kpi-valor.vacio { color: var(--iga-silver-200); }



/* El avatar del header sobre fondo oscuro: un aro tenue lo despega del
   azul-950 sin encender un borde duro. */
.iga-franja-superior .iga-h-avatar {
    background: rgba(255, 255, 255, 0.10);
    box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.14);
}


/* ══════════════════════════════════════════════════════════════════════
   10 · STATCARD              (referencia Magic Patterns · brief §1 y §5.2)
   ──────────────────────────────────────────────────────────────────────
   Evolución de .iga-kpi: mismo bloque, ahora con elevación al pasar el
   mouse, franja superior de acento y espacio para tendencia e icono.

   La tendencia solo se pinta cuando HAY con qué compararla. El brief lo
   pide explícito (§8): nunca un porcentaje inventado para que se vea
   bien. De los cuatro KPIs de Empleados solo "Ingresos este mes" tiene
   periodo anterior real; los otros tres no llevan flecha porque el
   sistema no guarda fotos de la plantilla en el tiempo.
   ══════════════════════════════════════════════════════════════════════ */
.iga-kpi {
    position: relative;
    overflow: hidden;
    transition: border-color .15s ease, box-shadow .15s ease, transform .12s ease;
}
/* Hover "intenso" — pedido explícito de Juan (02-ago-2026), ver la nota
   larga más abajo: borde y sombra con tinte de marca, no solo elevación
   neutra, para que se note de un vistazo cuál tarjeta tiene el mouse
   encima. */
.iga-kpi:hover {
    transform: translateY(-3px);
    border-color: rgb(var(--brand-500));
    box-shadow: 0 14px 32px rgb(var(--brand-700) / .22),
                0 0 0 1px rgb(var(--brand-300) / .6);
}

/* Franja superior: invisible en reposo, tornasol al pasar el mouse — en
   CUALQUIER StatCard, ya no solo en la de acento (ver nota más abajo). */
.iga-kpi::before {
    content: '';
    position: absolute;
    inset: 0 0 auto 0;
    height: 3px;
    background: linear-gradient(90deg, var(--iga-blue-500), #8b5cf6, #06b6d4);
    opacity: 0;
    transition: opacity .15s ease;
}
.iga-kpi:hover::before { opacity: 1; }

/* El acento tornasol de .iga-kpi--acento (§4) ERA fijo — opacity:1 sin
 * necesitar :hover — para marcar UNA sola StatCard por pantalla como "la
 * métrica principal". Juan lo vio en producción (captura de Empleados) y
 * pidió lo contrario: "que todos estén en blanco, yo nomás me paro en uno,
 * pum, se ponga con esa sombra intensa" — quería la MISMA franja + sombra
 * fuerte que ya se veía en "Activos", pero como algo que le pasa a
 * CUALQUIER tarjeta al pasar el mouse, no como marca permanente de una
 * sola. Por eso ya no hay un override de `.iga-kpi--acento::before` aquí:
 * la franja tornasol y la sombra intensa (arriba) ahora viven en
 * `.iga-kpi:hover`/`.iga-kpi:hover::before`, iguales para todas.
 *
 * La clase `.iga-kpi--acento` se queda en el HTML de los ~9 módulos que la
 * traían (Empleados, Flota, Dotación...) aunque ya no pinte nada por sí
 * sola — no vale la pena tocar 9 archivos para borrar una clase que ya no
 * hace daño estar ahí, y documenta cuál KPI se pensó como el "principal"
 * si se retoma la idea más adelante.
 *
 * (Antes de esto: la franja se pintaba con `border-image` sobre un
 * `border-top` transparente, y eso pintaba el gradiente en los CUATRO
 * lados de la tarjeta — bug ya corregido, ver commit de esa fecha.) */

/* Estado de alerta — nació en el KPI "Sin Conductor" de Flota, que antes
   se pintaba de rojo a mano con clases condicionales inline
   (border-red-200, bg-red-50...) solo cuando el conteo era mayor a
   cero. Mismos rojos que .iga-badge--mal, para no inventar un tercer
   tono de "esto está mal" en el sistema. Es un MODIFICADOR: se agrega o
   quita según el dato, nunca decorativo por defecto. */
.iga-kpi--alerta {
    border-color: #fecdd3;
}
.iga-kpi--alerta .iga-kpi-icono {
    background: #fff1f2;
    color: #be123c;
}
.iga-kpi--alerta .iga-kpi-valor {
    color: #be123c;
}

/* Los otros tres niveles del semáforo de Documentación (Control de Licencias
   y Documento de Vehículo): mismos tonos que .iga-badge--aviso/--ok/--neutro,
   para no inventar un cuarto set de colores de estado en el sistema. A
   diferencia de --alerta (arriba), estos no tocan el borde — el rojo es la
   única condición que necesita "saltar" desde la franja de KPIs; verde/
   ámbar/gris solo tiñen el ícono y el número. */
.iga-kpi--aviso .iga-kpi-icono {
    background: #fffbeb;
    color: #b45309;
}
.iga-kpi--aviso .iga-kpi-valor {
    color: #b45309;
}
.iga-kpi--ok .iga-kpi-icono {
    background: #ecfdf5;
    color: #047857;
}
.iga-kpi--ok .iga-kpi-valor {
    color: #047857;
}
.iga-kpi--neutro .iga-kpi-icono {
    background: var(--iga-silver-100);
    color: var(--iga-silver-400);
}
.iga-kpi--neutro .iga-kpi-valor {
    color: var(--iga-silver-400);
}

/* "Info" (azul) — nació en Vacaciones para "De vacaciones ahora mismo": un
   estado que no es alerta ni aviso ni ok, es informativo ("esto está
   pasando", no "esto está bien o mal"). Azul de Tailwind (blue-50/200/700),
   NO el azul de marca (--brand-*): un badge de estado que se recoloree con
   el tema perdería su significado si la marca cambia. */
.iga-kpi--info .iga-kpi-icono {
    background: #eff6ff;
    color: #1d4ed8;
}
.iga-kpi--info .iga-kpi-valor {
    color: #1d4ed8;
}

.iga-kpi-cabecera {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: .75rem;
}

/* El icono, en un cuadro suave. Se apoya en --brand-* para que siga la
   marca aunque cambie la rampa. */
.iga-kpi-icono {
    width: 2.25rem;
    height: 2.25rem;
    flex-shrink: 0;
    border-radius: .6rem;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgb(var(--brand-100));
    color: rgb(var(--brand-700));
}

.iga-kpi-pie {
    margin-top: .6rem;
    display: flex;
    align-items: center;
    gap: .5rem;
    min-height: 1.1rem;
}
.iga-kpi-tendencia {
    display: inline-flex;
    align-items: center;
    gap: .2rem;
    font-size: .72rem;
    font-weight: 700;
}
.iga-kpi-tendencia.sube  { color: #059669; }
.iga-kpi-tendencia.baja  { color: #e11d48; }
.iga-kpi-nota {
    font-size: .7rem;
    color: var(--iga-silver-400);
}

@media (prefers-reduced-motion: reduce) {
    .iga-kpi, .iga-kpi:hover { transform: none; transition: none; }
}


/* ══════════════════════════════════════════════════════════════════════
   11 · BADGE con punto y aro                          (brief §1 y §5.3)
   ──────────────────────────────────────────────────────────────────────
   Pastilla con un punto de color y un aro del mismo tono. Refina los
   "Activo" / "Sí" / "No" que ya existen, sin cambiar su semántica: el
   verde sigue siendo verde y el rojo, rojo. Los estados NO se recolorean
   con la marca — un badge de estado que cambia de significado con el
   tema es una trampa.
   ══════════════════════════════════════════════════════════════════════ */
.iga-badge {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    padding: .15rem .55rem;
    border-radius: 999px;
    font-size: .69rem;
    font-weight: 700;
    line-height: 1.5;
    white-space: nowrap;
}
.iga-badge::before {
    content: '';
    width: .4rem;
    height: .4rem;
    border-radius: 999px;
    background: currentColor;
    flex-shrink: 0;
}
.iga-badge--ok    { color: #047857; background: #ecfdf5; box-shadow: inset 0 0 0 1px #a7f3d0; }
.iga-badge--mal   { color: #be123c; background: #fff1f2; box-shadow: inset 0 0 0 1px #fecdd3; }
.iga-badge--aviso { color: #b45309; background: #fffbeb; box-shadow: inset 0 0 0 1px #fde68a; }
.iga-badge--neutro{ color: var(--iga-silver-600); background: var(--iga-silver-100);
                    box-shadow: inset 0 0 0 1px var(--iga-silver-200); }
.iga-badge--info  { color: #1d4ed8; background: #eff6ff; box-shadow: inset 0 0 0 1px #bfdbfe; }


/* ══════════════════════════════════════════════════════════════════════
   12 · BREADCRUMB en la franja de título                (brief §5.5)
   ══════════════════════════════════════════════════════════════════════ */
.iga-breadcrumb {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    gap: .4rem;
    margin-bottom: .3rem;
    font-size: .68rem;
    font-weight: 600;
    letter-spacing: .04em;
    color: rgba(255, 255, 255, .45);
}
.iga-breadcrumb .sep { opacity: .5; }
.iga-breadcrumb .actual { color: rgba(255, 255, 255, .8); }


/* ══════════════════════════════════════════════════════════════════════
   13 · FADE-IN DE PÁGINA                                (brief §4 y §5.6)
   ──────────────────────────────────────────────────────────────────────
   No elimina la recarga —eso seria htmx o una SPA, y el brief lo deja
   fuera a proposito— pero suaviza el salto entre vistas.

   150ms y solo opacidad: nada de desplazamientos, que a esta duracion se
   perciben como tirón. Y `backwards` para que el elemento arranque ya
   transparente en vez de parpadear opaco un fotograma antes.
   ══════════════════════════════════════════════════════════════════════ */
@keyframes iga-aparecer { from { opacity: 0; } to { opacity: 1; } }

.iga-area-contenido {
    animation: iga-aparecer .15s ease-out backwards;
}

/* Quien pidió menos animación entra directo, sin transición. */
@media (prefers-reduced-motion: reduce) {
    .iga-area-contenido { animation: none; }
}


/* ══════════════════════════════════════════════════════════════════════
   14 · BARRA DE ACENTO EN EL ÍTEM ACTIVO DEL SIDEBAR    (brief §5.4)
   ──────────────────────────────────────────────────────────────────────
   .nav-activo está definido en NUEVE archivos distintos (index.php,
   empleados, licencias, vacaciones, dotación, usuarios, archivador ×2 y
   mtto_head). La barra se agrega AQUÍ y no allá: iga-theme.css se carga
   después que todos y llega a las mismas vistas, así que es un sitio en
   vez de nueve. Unificar esas nueve copias es otra tarea — la misma que
   ya se hizo con el header.

   Va con ::after y no con border-left para no alterar el ancho ni el
   padding del ítem: el texto no se mueve al activarse.
   ══════════════════════════════════════════════════════════════════════ */
.nav-activo { position: relative; }

.nav-activo::after {
    content: '';
    position: absolute;
    left: 0;
    top: 50%;
    transform: translateY(-50%);
    width: 3px;
    height: 60%;
    border-radius: 0 3px 3px 0;
    background: rgb(var(--brand-300));
}

/* ══════════════════════════════════════════════════════════════════════
   13 · COMPONENTE DE FORMULARIO Y DIGITACIÓN (.inp, .lbl)
   ──────────────────────────────────────────────────────────────────────
   Rediseño visual 2026: elimina las "cajas grises pesadas de formulario"
   (#f8fafc + #e2e8f0). Fondo blanco puro (#ffffff), borde nítido en slate-300,
   sombra de elevación sutil y halo de enfoque azul marca (ring-4).
   ══════════════════════════════════════════════════════════════════════ */
.inp,
.parq-inp,
.inp-rod {
    width: 100%;
    /* Padding por LADOS, no con el shorthand. Iba como
       `padding: .625rem .875rem !important` y ese `!important` sobre el
       shorthand anulaba CUALQUIER `!pl-*` de Tailwind en todo el sistema:
       los campos con lupa (Dotación, Empleados, Licencias, Vacaciones…)
       reservaban 14px en vez de los 36px que pide `!pl-9`, y el ícono
       quedaba montado encima del placeholder. Se veía en claro y en
       oscuro; lo reportó Juan el 14-ago-2026 revisando el modo oscuro.
       Con los lados sueltos, `!pl-9` gana en su propiedad (padding-left)
       y el resto del bloque sigue mandando igual que antes. */
    padding-top: .625rem !important;
    padding-bottom: .625rem !important;
    padding-left: .875rem;
    padding-right: .875rem !important;
    border-radius: .75rem !important;
    border: 1px solid #cbd5e1 !important;
    background: #ffffff !important;
    font-size: .875rem !important;
    color: #0f172a !important;
    box-shadow: 0 1px 2px 0 rgba(15, 23, 42, 0.04) !important;
    transition: border-color .15s ease, box-shadow .15s ease, background .15s ease !important;
    outline: none !important;
}
.inp::placeholder,
.parq-inp::placeholder,
.inp-rod::placeholder {
    color: #94a3b8 !important;
}
.inp:focus,
.parq-inp:focus,
.inp-rod:focus {
    border-color: #0284c7 !important;
    box-shadow: 0 0 0 4px rgba(2, 132, 199, 0.14) !important;
    background: #ffffff !important;
}
select.inp,
select.parq-inp,
select.inp-rod {
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%6b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e") !important;
    background-position: right .75rem center !important;
    background-repeat: no-repeat !important;
    background-size: 1.25em 1.25em !important;
    padding-right: 2.5rem !important;
    -webkit-appearance: none !important;
    -moz-appearance: none !important;
    appearance: none !important;
}
.lbl {
    display: block;
    font-size: .6875rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .06em;
    color: #475569;
    margin-bottom: .35rem;
}

/* ╔══════════════════════════════════════════════════════════════════╗
   ║  Guarda contra el "icono gigante"                                ║
   ╠══════════════════════════════════════════════════════════════════╣
   ║  Ni iconoContenido() ni lucide.icono() ni createIcons() escriben  ║
   ║  width/height en el <svg>: solo viewBox. El tamano lo pone SIEMPRE ║
   ║  una clase de Tailwind (w-4 h-4, w-5 h-5...).                     ║
   ║                                                                    ║
   ║  Si esa clase no existe, el <svg> no se pinta chiquito ni          ║
   ║  invisible: se pinta al tamano por defecto de un elemento          ║
   ║  reemplazado, 300x150 px, y revienta el layout. Paso de verdad     ║
   ║  con `w-4.5 h-4.5`, que parece valida pero NO lo es: la escala de  ║
   ║  Tailwind salta 3.5 -> 4 -> 5, el paso 4.5 no existe. Como la      ║
   ║  clase nunca se genera, `npm run build:css` tampoco lo arregla —   ║
   ║  no es el bug del purge, es una clase inventada.                   ║
   ║                                                                    ║
   ║  :where() NO suma especificidad, asi que cualquier w-4 / h-4 real  ║
   ║  la pisa sin pelear. Esto es solo el piso al que se cae.          ║
   ╚══════════════════════════════════════════════════════════════════╝ */
:where(svg[data-lucide]) {
    width: 1rem;
    height: 1rem;
    flex-shrink: 0;
}


/* ══════════════════════════════════════════════════════════════════════
   14 · MODO OSCURO · ESTADOS SEMAFÓRICOS               (14-ago-2026)
   ──────────────────────────────────────────────────────────────────────
   La inversión de tokens del bloque 1b resuelve fondos, bordes y texto,
   pero NO los estados de color (rojo/ámbar/verde/azul): esos están en hex
   fijo a propósito, porque su significado no puede depender del tema —
   "vencido" tiene que ser rojo siempre.

   El problema en oscuro no es el tono sino el FONDO: #fff1f2, #fffbeb y
   compañía son casi blancos, pensados para tarjeta clara. Sobre un panel
   oscuro se ven como parches encendidos. Aquí se cambian por el mismo
   color a baja opacidad (color-mix con transparent), que se funde con el
   fondo y conserva la lectura, y el texto se aclara al tono 300/400 de la
   escala para que contraste.

   Se toca SOLO fondo y texto, nunca el significado: rojo sigue siendo
   rojo. Los umbrales del semáforo viven en PHP y no se tocan desde aquí.
   ══════════════════════════════════════════════════════════════════════ */

/* ── KPI: modificadores de estado ───────────────────────────────────── */
.dark .iga-kpi--alerta            { border-color: rgb(190 18 60 / .45); }
.dark .iga-kpi--alerta .iga-kpi-icono { background: rgb(190 18 60 / .18); color: #fda4af; }
.dark .iga-kpi--alerta .iga-kpi-valor { color: #fda4af; }

.dark .iga-kpi--aviso .iga-kpi-icono  { background: rgb(180 83 9 / .20);  color: #fcd34d; }
.dark .iga-kpi--aviso .iga-kpi-valor  { color: #fcd34d; }

.dark .iga-kpi--ok .iga-kpi-icono     { background: rgb(4 120 87 / .20);  color: #6ee7b7; }
.dark .iga-kpi--ok .iga-kpi-valor     { color: #6ee7b7; }

.dark .iga-kpi--info .iga-kpi-icono   { background: rgb(29 78 216 / .22); color: #93c5fd; }
.dark .iga-kpi--info .iga-kpi-valor   { color: #93c5fd; }

.dark .iga-kpi-tendencia.sube { color: #34d399; }
.dark .iga-kpi-tendencia.baja { color: #fb7185; }

/* ── Badges ─────────────────────────────────────────────────────────── */
.dark .iga-badge--ok {
    color: #6ee7b7; background: rgb(4 120 87 / .18);
    box-shadow: inset 0 0 0 1px rgb(110 231 183 / .30);
}
.dark .iga-badge--mal {
    color: #fda4af; background: rgb(190 18 60 / .18);
    box-shadow: inset 0 0 0 1px rgb(253 164 175 / .30);
}
.dark .iga-badge--aviso {
    color: #fcd34d; background: rgb(180 83 9 / .20);
    box-shadow: inset 0 0 0 1px rgb(252 211 77 / .30);
}
.dark .iga-badge--info {
    color: #93c5fd; background: rgb(29 78 216 / .22);
    box-shadow: inset 0 0 0 1px rgb(147 197 253 / .30);
}
.dark .iga-badge--neutro {
    color: var(--iga-silver-400); background: rgb(148 163 184 / .15);
    box-shadow: inset 0 0 0 1px rgb(148 163 184 / .25);
}

/* Ícono de alerta dentro de una tarjeta (dato en rojo). */
.dark .iga-card-dato--alerta svg { color: #fda4af; }

/* ── Switch de modo oscuro: estado inicial en CSS puro (19-ago-2026) ──
   El HTML de header_vista.php nace SIEMPRE en posición "claro" (gajo a
   la izquierda, sol visible) porque el servidor no sabe la preferencia
   del navegador. Antes solo JS/dark-mode.js corregía esto -- pero corre
   con `defer`, después del primer pintado, así que con el modo oscuro
   ya activado se veía el switch nacer en claro y "saltar" a oscuro un
   instante después (se sentía como un clic fantasma al cambiar de
   pestaña). dark-mode-init.js SÍ pone la clase `dark` en <html> antes
   de pintar (sin defer) — estas reglas usan esa clase para que el CSS,
   no el JS, decida la posición correcta desde el primer frame. Los
   valores (translateX(20px), opacidades) son EXACTAMENTE los mismos que
   aplicarEstado(true) en dark-mode.js — si esa función cambia, esto
   también. */
.dark #dark-mode-gajo    { transform: translateX(20px); }
.dark #dark-mode-sol     { opacity: 0; }
.dark #dark-mode-luna    { opacity: 1; }
.dark #btn-dark-mode     { background-color: rgb(255 255 255 / .25); }

/* ── Utilidades de Tailwind con fondo claro fijo ─────────────────────
   Las vistas usan `bg-white` directo en tarjetas, tablas y paneles (unos
   160 en 11 módulos). Reescribirlas una por una con `dark:` sería mucho
   trabajo y quedaría dependiendo de que nadie olvide la variante al
   crear una tarjeta nueva. Se resuelven en bloque aquí.

   `:is(.dark *)` — misma forma que genera Tailwind para sus variantes
   dark, así la especificidad queda pareja y no hay peleas raras entre
   esta regla y una utilidad `dark:` escrita a mano en una vista.
   ──────────────────────────────────────────────────────────────────── */
.dark :is(.bg-white)      { background-color: var(--iga-white); }
.dark :is(.bg-slate-50)   { background-color: #0f172a; }
.dark :is(.bg-slate-100)  { background-color: #1e293b; }
.dark :is(.bg-gray-50)    { background-color: #0f172a; }
.dark :is(.bg-gray-100)   { background-color: #1e293b; }

.dark :is(.border-slate-100) { border-color: #1e293b; }
.dark :is(.border-slate-200) { border-color: #334155; }
.dark :is(.border-gray-100)  { border-color: #1e293b; }
.dark :is(.border-gray-200)  { border-color: #334155; }

.dark :is(.text-slate-900, .text-gray-900, .text-slate-800, .text-gray-800) { color: #e2e8f0; }
.dark :is(.text-slate-700, .text-gray-700) { color: #cbd5e1; }
.dark :is(.text-slate-600, .text-gray-600) { color: #94a3b8; }
.dark :is(.text-slate-500, .text-gray-500) { color: #94a3b8; }

/* Campos de digitación: el .inp lo define cada vista en su propio <style>
   (fondo blanco, borde slate-200), así que se ataja igual que lo anterior. */
/* !important porque varias vistas redefinen su propio `.inp`/`.parq-inp`
   con `background:#fff` dentro de un <style> que se carga DESPUÉS de este
   archivo — sin la marca, los campos se quedaban blancos en modo oscuro
   (se vio en Control de Parqueo: la tabla oscura con las casillas de
   digitación encendidas). Solo se marcan las tres propiedades del tema;
   el tamaño y el padding siguen siendo de quien corresponda. */
.dark .inp, .dark .parq-inp, .dark .inp-rod, .dark .inp-login,
.dark input[type="text"], .dark input[type="password"],
.dark input[type="email"], .dark input[type="number"], .dark input[type="date"],
.dark select, .dark textarea {
    background-color: #0f172a !important;
    border-color: #334155 !important;
    color: #e2e8f0 !important;
}
.dark .inp::placeholder, .dark input::placeholder, .dark textarea::placeholder {
    color: #64748b;
}

/* Filas de tabla al pasar el mouse: los hover:bg-slate-50/gray-50 de las
   vistas aclaran sobre claro; en oscuro tienen que oscurecer, no encender. */
.dark tbody tr:hover { background-color: rgb(148 163 184 / .06); }

/* ── Texto de color "medio" sobre fondo oscuro ───────────────────────
   Las vistas usan tonos 600/700 para texto de estado (text-amber-600 en
   "Falta por archivar", text-red-600, etc.). Están calculados para leerse
   sobre blanco; sobre un panel oscuro quedan apagados, casi ilegibles.
   Se suben a los tonos 300/400 de la misma familia — mismo significado,
   contraste recuperado. Solo TEXTO: los fondos ya se resolvieron arriba. */
.dark :is(.text-amber-600, .text-amber-700, .text-yellow-600, .text-yellow-700) { color: #fcd34d; }
.dark :is(.text-red-600,   .text-red-700)     { color: #fda4af; }
.dark :is(.text-green-600, .text-green-700,
          .text-emerald-600, .text-emerald-700) { color: #6ee7b7; }
.dark :is(.text-blue-600,  .text-blue-700)    { color: #93c5fd; }
.dark :is(.text-brand-600, .text-brand-700, .text-brand-800) { color: var(--iga-blue-500); }

/* Fondos tenues de estado (bg-amber-50/40, bg-red-50…) usados para teñir
   filas: en claro son un velo suave; en oscuro, un parche encendido. */
.dark :is(.bg-amber-50, .bg-yellow-50)   { background-color: rgb(180 83 9 / .14); }
.dark :is(.bg-red-50)                    { background-color: rgb(190 18 60 / .14); }
.dark :is(.bg-green-50, .bg-emerald-50)  { background-color: rgb(4 120 87 / .14); }
.dark :is(.bg-blue-50)                   { background-color: rgb(29 78 216 / .16); }
.dark :is(.bg-brand-50)                  { background-color: rgb(121 180 217 / .12); }

/* Fondos de marca con opacidad (bg-brand-50/70 en la fila del móvil
   seleccionado del Archivador, por ejemplo): la utilidad de Tailwind ya
   trae su propia alfa, así que la regla de arriba (que fija un rgb con
   opacidad) no la alcanza — hay que atajar la variante con barra aparte.
   Sin esto la fila activa quedaba casi del mismo tono que las demás y se
   perdía cuál está seleccionada. */
.dark :is([class*="bg-brand-50/"]) { background-color: rgb(121 180 217 / .16) !important; }
.dark :is(.text-brand-800, .text-brand-900) { color: #cfe4f2; }

/* ══════════════════════════════════════════════════════════════════════
   15 · MODO OSCURO · CORRECCIONES DE CONTRASTE      (14-ago-2026, tarde)
   ──────────────────────────────────────────────────────────────────────
   Salieron de que Juan recorriera el sistema pantalla por pantalla, no de
   leer el código: título del Dashboard invisible, pies de tabla ("Total:
   8 licencia(s) · Mostrando 1–8") ilegibles, la lupa del buscador
   amontonada sobre un campo que seguía blanco, cabeceras de tabla gris
   sobre gris, y la grilla de Turnos casi entera sin contraste.

   Todos son el mismo error de fondo: el bloque 14 cubrió la familia
   `slate-*`, pero media aplicación usa `gray-*` (Licencias, Flota, Turnos,
   Dotación nacieron con esa escala). Aquí se completa la otra familia y
   se atajan tres casos que ninguna utilidad genérica alcanza.
   ══════════════════════════════════════════════════════════════════════ */

/* ── 1. Título de la vista sobre la franja oscura ────────────────────
   .iga-titulo-vista pinta con var(--iga-white) — que en oscuro pasa a ser
   #1e293b, o sea casi el mismo color que la franja donde se apoya. La
   franja SIEMPRE es oscura (ver bloque 1b), así que su texto siempre debe
   ser claro, en los dos temas. */
.dark .iga-titulo-vista    { color: #e2e8f0; }
.dark .iga-subtitulo-vista { color: #94a3b8; }
.dark .iga-breadcrumb,
.dark .iga-breadcrumb a    { color: #94a3b8; }
.dark .iga-breadcrumb .iga-bc-actual { color: #e2e8f0; }

/* ── 2. Familia gray-* (la que faltaba) ──────────────────────────────
   Mismos valores que sus equivalentes slate-* del bloque 14, para que dos
   pantallas hermanas no queden de tonos distintos según con qué escala
   las escribió quien las hizo. */
.dark :is(.bg-gray-50\/50, .bg-gray-50\/60, .bg-gray-50\/70, .bg-gray-50\/80) { background-color: rgb(148 163 184 / .05); }
.dark :is(.bg-slate-50\/50, .bg-slate-50\/60, .bg-slate-50\/70, .bg-slate-50\/80) { background-color: rgb(148 163 184 / .05); }
.dark :is(.bg-gray-200, .bg-slate-200)   { background-color: #334155; }
.dark :is(.border-gray-50, .border-slate-50) { border-color: #1e293b; }

/* Texto gris: el 500/400 es el que más duele — son los pies de tabla,
   las etiquetas de columna y las notas al pie. */
.dark :is(.text-gray-400, .text-slate-400) { color: #94a3b8; }
.dark :is(.text-gray-300, .text-slate-300) { color: #cbd5e1; }

/* ── 3. Cabeceras de tabla ───────────────────────────────────────────
   `<thead class="bg-gray-50">` + `text-gray-400`: en claro es una franja
   apenas más oscura que la tarjeta; en oscuro quedaba gris sobre gris y
   los nombres de columna (CÓDIGO GPS, GRUPO, VEHÍCULO…) desaparecían. */
.dark thead :is(th) { color: #cbd5e1; }
.dark thead:is(.bg-gray-50, .bg-slate-50, .bg-gray-100, .bg-slate-100) { background-color: rgb(148 163 184 / .08); }

/* ── 4. Campos que fuerzan blanco con !important ─────────────────────
   `class="inp !pl-9 !bg-white"` (buscador de Dotación): el `!` gana sobre
   la regla del bloque 14, así que el campo seguía blanco — y la lupa gris
   encima parecía amontonada porque el ícono claro caía sobre fondo claro.
   Se ataja con la misma arma: !important sobre la variante forzada. */
.dark :is(.\!bg-white) { background-color: #0f172a !important; }

/* ── 5. Grilla de Turnos y Descansos ─────────────────────────────────
   Es una tabla-calendario: cabecera de días, columna fija de móvil y
   trabajador, y las celdas AM/PM/NOCHE. Usa bordes gray-100/200 y fondos
   blancos por celda; sin esto quedaba una malla casi invisible sobre
   fondo oscuro. Los colores D/R/F (amarillo/verde/rojo) NO se tocan: son
   el dato, y ya se resolvieron en el bloque 14. */
.dark :is(.tabla-turnos, .grid-turnos) :is(td, th) { border-color: #334155; }
.dark :is(td, th):is(.bg-white) { background-color: var(--iga-white); }
.dark :is(.divide-gray-100, .divide-slate-100) > :not([hidden]) ~ :not([hidden]) { border-color: #1e293b; }
.dark :is(.divide-gray-200, .divide-slate-200) > :not([hidden]) ~ :not([hidden]) { border-color: #334155; }

/* ── 6. Matriz de Turnos y Descansos ─────────────────────────────────
   Esa vista define su calendario en un <style> propio con hex FIJOS
   (#fff en las columnas fijas, #f9fafb en la cabecera de días, #fafafa
   en las celdas vacías) — ninguna utilidad de Tailwind de por medio, así
   que nada de lo anterior la alcanzaba y la grilla se quedaba blanca
   sobre la página oscura.

   Los tres colores del DATO (amarillo D, verde R, rojo F) NO se tocan:
   son los mismos del Excel del que nació la matriz y cambiarlos rompería
   la lectura que el equipo ya tiene aprendida. Sí se ajusta su texto,
   que en oscuro necesita más peso para leerse sobre esos mismos fondos. */
.dark .iga-matriz thead th        { background: #16202e; color: #cbd5e1; }
.dark .iga-matriz th,
.dark .iga-matriz td              { border-color: #2a3648; }
.dark .iga-col-fija               { background: var(--iga-white); }
.dark .iga-celda                  { background: #131c2b; }
.dark .iga-matriz                 { background: var(--iga-white); }

/* Pestañas de la vista (Matriz / Historial / Trabajadores) */
.dark .iga-tab:hover              { color: #e2e8f0; background: rgb(148 163 184 / .10); }
.dark .iga-tab.activa             { background: #334155; color: #f1f5f9; }

/* Chips de tipo y campos propios de la vista */
.dark .iga-chip                   { background: var(--iga-white); border-color: #334155; color: #cbd5e1; }
.dark .iga-inp                    { background: #0f172a; border-color: #334155; color: #e2e8f0; }
.dark .iga-inp:focus              { background: #0f172a; }
.dark .iga-mes-btn                { background: var(--iga-white); border-color: #334155; color: #cbd5e1; }

/* ── 7. Control de Parqueo ───────────────────────────────────────────
   Mismo caso que la matriz de Turnos: la vista define sus estilos en un
   <style> propio con hex fijos, así que nada de lo genérico la alcanza.

   Lo particular acá son las FILAS coloreadas por semáforo de pago
   (.fila-alto/.fila-medio/.fila-bajo): en claro son tintes muy suaves
   (#fef2f2, #fffbeb, #f0fdf4) sobre tabla blanca. Sobre fondo oscuro esos
   mismos tintes son casi blancos — la tabla entera se veía encendida. Se
   cambian por el color a baja opacidad, que tiñe sin iluminar y conserva
   la lectura de "esta fila necesita atención". */
.dark .fila-alto      { background: rgb(190 18 60 / .16); }
.dark .fila-medio     { background: rgb(180 83 9 / .16); }
.dark .fila-bajo      { background: rgb(4 120 87 / .14); }
.dark .fila-sin_datos { background: transparent; }

/* Campos propios de la vista. Ojo: .parq-inp también está en el bloque 13
   (el componente compartido), así que aquí solo se ajusta lo que esa vista
   redefine por su cuenta — el disabled, que es el que se perdía. */
.dark .parq-inp:disabled { background: #16202e; color: #64748b; }

/* Cabecera y celdas de la tabla de parqueo */
.dark .parq-th { color: #94a3b8; }
.dark .parq-td { color: #cbd5e1; }

/* ── 8. Login ─────────────────────────────────────────────────────────
   Hasta el 14-ago-2026 el login quedaba fuera del modo oscuro (su propio
   <head>, sin dark-mode-init.js). Juan pidió que respetara la preferencia
   guardada: si alguien lo activó una vez, debe verse oscuro también ANTES
   de entrar. El panel HERO (izquierda) ya es oscuro por diseño con overlay
   sobre foto — no se toca. Lo que faltaba era el panel BLANCO del
   formulario (derecha): la mayoría de sus clases (bg-white, text-slate-*,
   bg-slate-50, bg-amber-50, bg-red-50) ya las cubren los bloques 14/15
   genéricos; acá solo lo que es propio de esta vista. */
.dark .inp-login::placeholder { color: #64748b; }
.dark .inp-login:focus { border-color: #557e98 !important; }

/* El bloque "Acceso suspendido" anida un bg-white DENTRO de un
   bg-amber-50 ya oscurecido — necesita un tono intermedio, ni el fondo
   general ni el de tarjeta, para seguir leyéndose como "una caja aparte". */
.dark #msg-bloqueado .bg-white { background-color: rgb(180 83 9 / .12) !important; }

/* "Acceso Seguro" (pill) y el pie "Nexus v1.0": bg-slate-100 y
   border-slate-100 no estaban en la lista genérica con ESE tono exacto. */
.dark .bg-slate-100 { background-color: #1e293b; }

/* ── 9. Modales "Ver detalle" de Empleados y Licencias ────────────────
   Los dos definen .val-ver/.lbl-ver en un <style> propio con hex fijos
   (empleados.php: #1e293b/#94a3b8; licencias.php: #0f172a/#94a3b8) —
   mismo caso que la matriz de Turnos y la tabla de Parqueo (bloques 6/7):
   nada genérico los alcanza. Un solo selector cubre ambos porque los dos
   quieren lo mismo en oscuro (texto claro), aunque el hex de partida no
   sea idéntico. Encontrado el 14-ago-2026: "Conductor cali" y el nombre
   del hero de Empleados casi invisibles al pasar el mouse / abrir Ver.

   Especificidad, no solo color: el <style> de cada vista define
   `.campo-ver-lic .val-ver` / `.campo-ver .val-ver` (0,2,0) y se declara
   DESPUÉS de este archivo en el <head> — a especificidad empatada gana
   el último en el documento, así que `.dark .val-ver` (también 0,2,0)
   perdía en silencio. Se iguala repitiendo el selector compuesto en vez
   de subir a !important (mismo criterio que el resto del archivo: usar
   !important solo donde la propia vista ya lo usa, bloque 4). */
.dark :is(.val-ver, .campo-ver-lic .val-ver, .campo-ver .val-ver, .titulo-seccion-ver) { color: #e2e8f0; }
.dark :is(.lbl-ver, .campo-ver-lic .lbl-ver, .campo-ver .lbl-ver) { color: #94a3b8; }
.dark .val-ver.vacio { color: #64748b; }
.dark .campo-ver-lic { border-color: #1e293b; }
.dark .campo-ver     { border-color: #1e293b; }

/* ── 10. Tarjeta "Cumpleaños del mes" del dashboard — fila de HOY ─────
   `bg-gradient-to-r from-pink-50 to-pink-50/40` (index.php): un degradado
   compuesto de dos utilidades de color, no un `bg-*` plano — ninguna
   regla genérica de este archivo lo alcanza (todas apuntan a
   background-color, no a los stops de un gradiente). El texto encima
   (text-gray-900/text-gray-500) sí se invertía por las reglas genéricas,
   así que quedaba claro sobre un fondo que seguía claro: casi invisible.
   Solo la fila de HOY tiene este gradiente — las demás filas del mismo
   componente ("Próximos") son fondo plano y ya las cubre el bloque 2. */
.dark .bg-gradient-to-r.from-pink-50 {
    background-image: linear-gradient(to right, rgb(190 24 93 / .16), rgb(190 24 93 / .06));
}
.dark .border-pink-100 { border-color: rgb(190 24 93 / .3); }

/* ── 11. Calendario de Vencimientos (21-ago-2026) ─────────────────────
   Mismo caso que la Matriz de Turnos y Parqueo (bloques 7-8): la vista
   define su cuadrícula en un <style> propio con hex fijos, así que nada
   de lo genérico de arriba la alcanza. Los puntos de semáforo
   (.cal-punto--critico/alerta/vigente) NO se tocan: son el mismo rojo/
   amarillo/verde en los dos temas, misma razón que los 3 colores del
   Excel de Turnos no se invierten — son el dato, no decoración. */
/* Líneas azules (21-ago, pedido de Juan: "como el KPI lista de
   empleados") también en oscuro — sin este override, el `.dark
   .cal-cuadricula` opaco (mayor especificidad que el `.cal-cuadricula`
   base del <style> de la vista) tapaba el azul por completo. Menos
   opacidad que en claro porque un tinte translúcido se ve más intenso
   sobre fondo oscuro. */
.dark .cal-cuadricula      { background: rgb(var(--brand-500) / .28); border-color: rgb(var(--brand-500) / .28); }
.dark .cal-celda-cabecera  { background: #131c2b; color: #94a3b8; }
.dark .cal-celda-dia       { background: var(--iga-white); }
/* Hover general (21-ago, todos los días, no solo los con eventos) — el
   glow por urgencia (data-nivel) no necesita variante dark aparte: son
   sombras translúcidas (rgb(.../ .28)), se ven bien sobre cualquier
   fondo sin redefinir nada. */
.dark .cal-celda-dia:hover { background: #131c2b; }
/* Hover de "Próximos vencimientos" — más opacidad que en claro (.10)
   porque el mismo tinte translúcido se lee más tenue sobre fondo
   oscuro; mismo criterio que el resto de ajustes de contraste de este
   archivo. */
.dark .cal-proximo-item:hover { background: rgb(var(--brand-500) / .16); }
.dark .cal-celda-dia.cal-fuera-mes { background: #0f172a; }
.dark .cal-celda-dia.cal-fuera-mes .cal-num-dia { color: #475569; }
.dark .cal-num-dia         { color: #cbd5e1; }
.dark .cal-contador        { color: #94a3b8; }
.dark .cal-evento          { border-color: #334155; }
.dark .cal-evento:hover    { background: #131c2b; border-color: #475569; }

/* ── 12. Dashboard — Resumen General, index.php (21-ago-2026) ─────────
   Las 6 tarjetas KPI del Dashboard son un componente MÁS ANTIGUO que
   `.iga-kpi` — armadas con utilities de Tailwind directas
   (`bg-white`, `border-l-4 border-l-{color}`...), nunca se migraron al
   sistema visual compartido del 01-ago (context/decisiones/2026-08-01-
   sistema-visual-compartido.md). Juan pidió el mismo "efecto KPI" que
   ya tienen Empleados/Flota/Documentación al pasar el mouse: elevación
   + sombra con tinte de marca + franja tornasol arriba.

   NO se les puede agregar directamente la clase `.iga-kpi`: esa clase
   también fija `border-color` en :hover (mismo shorthand, los 4 lados),
   y pisaría el borde IZQUIERDO de color propio de cada tarjeta — el
   acento POR MÉTRICA (azul Personal, verde Flota, rojo Lic. Vencidas,
   amarillo Por Vencer...) se volvería el mismo azul de marca en las 6
   al pasar el mouse, perdiendo la identidad de color que sí es
   deliberada aquí. Por eso es una clase nueva, mismo lenguaje visual
   (mismos valores de sombra/gradiente que `.iga-kpi:hover`/`::before`),
   pero sin tocar `border-color` — el borde de color de cada tarjeta se
   queda intacto en cualquier estado. */
.iga-kpi-dash {
    position: relative;
    overflow: hidden;
    transition: box-shadow .15s ease, transform .12s ease, background-color .15s ease, border-color .15s ease;
}
.iga-kpi-dash:hover {
    transform: translateY(-3px);
    box-shadow: 0 14px 32px rgb(var(--brand-700) / .22), 0 0 0 1px rgb(var(--brand-300) / .6);
}
.iga-kpi-dash::before {
    content: '';
    position: absolute;
    inset: 0 0 auto 0;
    height: 3px;
    background: linear-gradient(90deg, var(--iga-blue-500), #8b5cf6, #06b6d4);
    opacity: 0;
    transition: opacity .15s ease;
}
.iga-kpi-dash:hover::before { opacity: 1; }
