/* =========================================================================
   MARCA INSTITUCIONAL — Preventiva Salud IPS
   Variables CSS del manual de marca (pedido por Tomás, 12/09/2026), para que
   cualquier plantilla que quiera usar los colores/tipografía oficiales lo
   haga referenciando estas variables (ej. clases Tailwind con valor
   arbitrario: bg-[var(--marca-azul-primario)]) en vez de repetir códigos hex
   sueltos por el código.

   Los colores se usan en /login y en el selector de color del Muro de
   Comunicados (ver templates/comunicados.html). La tipografía (ver la regla
   'body' más abajo) es global: esta hoja de estilos está enlazada al final
   del <head> de TODAS las plantillas (pedido por Tomás, 12/09/2026: "Haz
   global la fuente Montserrat"), así que Montserrat aplica en toda la
   plataforma sin tocar plantilla por plantilla.
   ========================================================================= */
:root {
    --marca-azul-primario: #1654a5;   /* Azul institucional principal */
    --marca-azul-secundario: #145299; /* Azul de apoyo (degradados, hover) */
    --marca-cian: #0ca3c5;            /* Cian de "Salud" en el isotipo */
    --marca-naranja: #ee7128;         /* Naranja acento (check del isotipo) */
    --marca-gris: #a09f9e;            /* Gris neutro de apoyo */
    --marca-azul-oscuro: #2d5461;     /* Azul-petróleo oscuro */
    --marca-morado: #7b4c9e;          /* Morado (variación Odontología) */
    --marca-fuente: 'Montserrat', sans-serif;

    /* 🎨 Colores de los modales, personalizables desde /admin/diseno (pedido por Tomás,
       12/09/2026: "un modal de diseño para poder modificar a gusto los colores de los
       modales"). Los valores de aquí abajo son el respaldo (fallback de cada var() donde se
       usan, unas líneas más abajo) por si esta hoja se sirviera sin pasar por
       partials/colores_modal_personalizados.html — en el uso normal, ese partial (inyectado al
       final del <head> de cada plantilla con los valores guardados en la BD, ver
       _colores_modal_actuales en app.py) redefine estas mismas variables con lo que el admin
       haya guardado, y como se enlaza DESPUÉS de este archivo, gana por orden de cascada. Los
       valores de abajo son EXACTAMENTE los que los modales ya tenían antes de este feature, así
       que mientras nadie personalice nada desde /admin/diseno, no cambia nada visualmente. */
    --modal-oscuro-fondo: #0f172a;
    --modal-oscuro-borde: #1e293b;
    --modal-oscuro-texto: #ffffff;
    --modal-oscuro-texto-secundario: #94a3b8;
    --modal-claro-fondo: #ffffff;
    --modal-claro-borde: #e2e8f0;
    --modal-claro-texto: #1e293b;
    --modal-claro-texto-secundario: #64748b;
    --modal-descanso-fondo: #e8e2d5;
    --modal-descanso-borde: #ded9c9;
    --modal-descanso-texto: #3a322e;
    --modal-descanso-texto-secundario: #605b5a;
}

/* 🌐 Tipografía global: se aplica sobre 'body' (se hereda a todo el texto
   normal) y a propósito SIN '* { ... !important }' — forzar el font-family a
   TODOS los elementos con !important rompería los iconos de Font Awesome
   (fa-solid/fa-regular dibujan su glifo con su propio font-family, que
   quedaría pisado) y los textos que varias plantillas ya ponen a propósito
   en fuente monoespaciada (.font-mono: IPs, cédulas, fechas, JSON, MACs).
   Con 'body' sin !important, esas clases más específicas siguen ganando
   como deben, y como este archivo se enlaza al final de cada <head>, gana
   por orden de cascada sobre cualquier font-family que ya tuviera esa
   plantilla en un <style> propio (misma especificidad, pero se carga
   después). */
body {
    font-family: var(--marca-fuente);
}

/* 🪟 Modales institucionales — rediseño por tema (pedido de Tomás, 12/09/2026: "quiero que el
   estilo del login sea así mismo de limpio para todos los modales en sus diferentes temas,
   oscuro, claro y en reposo"). Todos los modales de Arkiv comparten el mismo wrapper
   "fixed inset-0" (con distintos tonos/opacidades de velo detrás según la plantilla:
   bg-slate-950/80, bg-slate-950/90, bg-black/80, bg-black/70 — por eso el selector usa
   "fixed inset-0", no un color puntual, para llegar a los 4 casos con un único selector). Ese
   velo se DEJA tal cual: solo oscurece la página detrás, no es el modal en sí.

   🔧 Origen del rediseño: la primera versión (homologar modales al estilo claro de /login,
   commit 89bfca5) forzaba SIEMPRE fondo blanco y texto oscuro en el panel del modal, sin mirar
   el tema activo (html[data-theme]) — así que en 'oscuro' los modales salían blancos de golpe
   en medio de una interfaz oscura, y en 'descanso' salían blanco-frío en vez del sepia cálido
   de ese tema, rompiendo la consistencia que Arkiv ya cuidaba en el resto de cada página (ver
   static/css/tema-claro.css / tema-descanso.css, que sí recolorean bg-slate-800/900 etc. según
   el tema). Ahora:
     · Estructura (radio de esquina + sombra + acentos de marca en azul/cian/naranja): igual en
       los 3 temas, para que "cada modal sea igual" y se sienta de la misma familia que /login.
     · Colores de fondo/texto: en 'claro' se fuerza el blanco puro de /login (más "limpio" que el
       #f8fafc genérico de tema-claro.css, a propósito: el modal es la pieza que más se
       parece a la tarjeta de login, y el pedido de Tomás fue explícito en que el claro se
       viera "muy parecido a como está implementada la paleta de colores en login").
     · ACTUALIZACIÓN 12/09/2026 (/admin/diseno): 'oscuro' y 'descanso' antes se dejaban heredar
       de las clases Tailwind nativas / tema-descanso.css sin bloque propio aquí. Ahora los tres
       temas fuerzan explícitamente fondo/borde/texto del modal, pero a través de variables CSS
       (--modal-oscuro-*, --modal-claro-*, --modal-descanso-*, definidas en :root con el mismo
       valor que cada tema ya tenía) para que /admin/diseno pueda personalizarlas sin tocar esta
       hoja — ver los tres bloques de abajo y _colores_modal_actuales en app.py.

       🐛 BUG CRÍTICO hallado y corregido en la verificación visual del rediseño (12/09/2026): la
       versión anterior de este comentario escribía la lista de variables como
       "--modal-oscuro-*{/}--modal-claro-*{/}--modal-descanso-*" (con '/' pegado al '*' de en
       medio, sin espacio) — eso son DOS apariciones literales de la secuencia de caracteres
       '*' + '/', que en CSS SIEMPRE cierra el comentario ahí mismo, sin importar que "la
       intención" fuera seguir comentando. Efecto real (confirmado con el CSSOM del navegador,
       comparando cssRules antes/después de este fix): el comentario se cerraba de golpe a la
       mitad, y el texto suelto que quedaba ("-modal-claro-*, --modal-descanso-*, ... *\/") pasaba
       a interpretarse como CSS de verdad — basura sintáctica que el parser no podía digerir, y
       que arrastraba consigo la ruptura silenciosa de varias reglas siguientes (el radio/sombra
       del panel del modal, y la regla de fondo/borde del panel en tema 'oscuro' — es decir, la
       personalización de colores en oscuro desde /admin/diseno llevaba rota desde que se
       desplegó ese comentario, sin que ningún test unitario pudiera detectarlo porque pytest no
       ejecuta un motor CSS). Lección: nunca escribir '*' inmediatamente seguido de '/' dentro de
       un comentario CSS, ni siquiera para notación abreviada de nombres de variables. */
/* ⚠️ Ojo con el combinador '>': a propósito es hijo DIRECTO del wrapper "fixed inset-0", no
   descendiente genérico. Confirmado (12/09/2026) que en TODOS los modales de Arkiv el panel
   visible es siempre el <div> hijo directo del wrapper — pero varios modales (ej.
   mi_boveda.html) también tienen <input>/<textarea>/<label> internos con bg-slate-900/60, que
   con un selector de descendiente genérico (el usado hasta ahora para todo lo demás en este
   bloque) también harían match y se llevarían el radio/sombra/barra de acento pensados solo
   para el panel. */
div[class*="fixed inset-0"] > [class*="bg-slate-800"],
div[class*="fixed inset-0"] > [class*="bg-slate-900"] {
    border-radius: 1.25rem !important;
    box-shadow: 0 25px 50px -12px rgb(0 0 0 / 0.45), 0 10px 15px -3px rgb(0 0 0 / 0.3), 0 0 0 1px rgb(255 255 255 / 0.04) !important;
    /* 'relative' para que la barra de acento superior (::before, ver más abajo, sección "✨
       Rediseño profesional de modales") pueda anclarse con position:absolute sin depender de
       que la plantilla ya trajera la clase 'relative' (algunas sí, ej. usuarios.html; otras no,
       ej. comunicados.html) — forzarlo aquí cubre ambas familias de marcado por igual. */
    position: relative !important;
}

/* 🎨 Acentos de marca (divisores/iconos de cabecera y botón primario): iguales en los 3 temas,
   para que el CTA azul institucional y los acentos cian/naranja no cambien de tono al cambiar
   de tema — es la parte de "colores corporativos" que sí debe ser idéntica siempre. */
div[class*="fixed inset-0"] [class*="border-slate-700/60"] {
    border-color: var(--marca-azul-primario) !important;
}
div[class*="fixed inset-0"] [class*="text-cyan-400"] {
    color: var(--marca-cian) !important;
}
div[class*="fixed inset-0"] [class*="text-amber-400"],
div[class*="fixed inset-0"] [class*="text-amber-500"] {
    color: var(--marca-naranja) !important;
}
div[class*="fixed inset-0"] button[class*="bg-cyan-600"],
div[class*="fixed inset-0"] button[class*="bg-blue-600"] {
    background-color: var(--marca-azul-primario) !important;
}
div[class*="fixed inset-0"] button[class*="bg-cyan-600"]:hover,
div[class*="fixed inset-0"] button[class*="bg-blue-500"]:hover,
div[class*="fixed inset-0"] button[class*="bg-blue-600"]:hover {
    background-color: var(--marca-azul-secundario) !important;
}

/* 🤍 Tema CLARO: paleta idéntica a /login (blanco puro, bordes #e2e8f0, texto en slate oscuro).
   Solo dentro de modales — el resto de la app en tema claro sigue usando el #f8fafc algo más
   gris de tema-claro.css; el modal es, a propósito, el elemento más "blanco y limpio" de la
   página, igual que la tarjeta de /login. */
html[data-theme="claro"] div[class*="fixed inset-0"] [class*="bg-slate-800"],
html[data-theme="claro"] div[class*="fixed inset-0"] [class*="bg-slate-900"] {
    background-color: var(--modal-claro-fondo, #ffffff) !important;
    border-color: var(--modal-claro-borde, #e2e8f0) !important;
}
html[data-theme="claro"] div[class*="fixed inset-0"] [class*="border-slate-600"],
html[data-theme="claro"] div[class*="fixed inset-0"] [class*="border-slate-700"],
html[data-theme="claro"] div[class*="fixed inset-0"] [class*="border-slate-800"],
html[data-theme="claro"] div[class*="fixed inset-0"] [class*="divide-slate-700"],
html[data-theme="claro"] div[class*="fixed inset-0"] [class*="divide-slate-800"] {
    border-color: var(--modal-claro-borde, #e2e8f0) !important;
}
/* 🔤 Texto: de tonos claros (pensados para fondo oscuro) a tonos oscuros (para fondo blanco).
   Los botones se excluyen y se restauran aparte: un botón primario azul/cian con texto blanco
   debe seguir teniendo texto blanco, no oscuro. Nota sobre /admin/diseno: antes de este feature
   text-white usaba un tono más oscuro (#1e293b) que text-slate-100/200/300 (#475569) — para que
   el admin personalice UN solo "texto principal" en vez de dos tonos casi iguales, aquí se
   consolidan ambos en --modal-claro-texto (con el valor más oscuro/legible de los dos, #1e293b,
   como valor por defecto: un cambio cosmético mínimo, más contraste, no menos). */
html[data-theme="claro"] div[class*="fixed inset-0"] [class*="text-white"],
html[data-theme="claro"] div[class*="fixed inset-0"] [class*="text-slate-100"],
html[data-theme="claro"] div[class*="fixed inset-0"] [class*="text-slate-200"],
html[data-theme="claro"] div[class*="fixed inset-0"] [class*="text-slate-300"] { color: var(--modal-claro-texto, #1e293b) !important; }
html[data-theme="claro"] div[class*="fixed inset-0"] [class*="text-slate-400"],
html[data-theme="claro"] div[class*="fixed inset-0"] [class*="text-slate-500"] { color: var(--modal-claro-texto-secundario, #64748b) !important; }
html[data-theme="claro"] div[class*="fixed inset-0"] button[class*="text-white"] { color: #ffffff !important; }
/* 📝 Inputs/selects/textareas de fondo oscuro -> mismo fondo del panel, con su texto ya
   oscurecido arriba. El placeholder se consolida con --modal-claro-texto-secundario (antes tenía
   su propio tono #94a3b8, ligeramente más claro que el texto secundario #64748b — otro cambio
   cosmético mínimo por la misma razón de arriba: un solo campo de "texto secundario" que
   personalizar, no dos casi iguales). */
html[data-theme="claro"] div[class*="fixed inset-0"] input[class*="bg-slate-900"],
html[data-theme="claro"] div[class*="fixed inset-0"] input[class*="bg-slate-950"],
html[data-theme="claro"] div[class*="fixed inset-0"] select[class*="bg-slate-900"],
html[data-theme="claro"] div[class*="fixed inset-0"] select[class*="bg-slate-950"],
html[data-theme="claro"] div[class*="fixed inset-0"] textarea[class*="bg-slate-900"],
html[data-theme="claro"] div[class*="fixed inset-0"] textarea[class*="bg-slate-950"] {
    background-color: var(--modal-claro-fondo, #ffffff) !important;
}
html[data-theme="claro"] div[class*="fixed inset-0"] input::placeholder,
html[data-theme="claro"] div[class*="fixed inset-0"] textarea::placeholder {
    color: var(--modal-claro-texto-secundario, #64748b) !important;
}
/* 🌑 Tema OSCURO y 🟤 Tema DESCANSO: antes de /admin/diseno estos dos temas NO tenían un bloque
   propio aquí — se dejaban heredar tal cual de las clases Tailwind nativas (oscuro) o de
   tema-descanso.css (descanso), a propósito, para no duplicar cientos de reglas. Para que el
   admin pueda personalizarlos igual que el claro de arriba, ahora sí se fuerzan explícitamente,
   pero con las variables --modal-oscuro-*, --modal-descanso-* cuyo valor por defecto (ver :root
   al principio de este archivo) es EXACTAMENTE el color que ya tenían de forma nativa/heredada
   — así que, igual que con claro, nada cambia visualmente mientras no se use /admin/diseno.

   🐛 Igual al bug de más arriba: esta misma nota tenía los dos nombres de variable separados por
   una barra pegada al asterisco (sin espacio de por medio) — esa secuencia de caracteres '*'
   seguido de '/' cierra el comentario CSS ahí mismo, sin importar la intención. Rompía la regla
   de fondo/borde de OSCURO que viene justo abajo (la personalización de /admin/diseno en tema
   oscuro llevaba rota desde que se desplegó este comentario). Corregido igual: coma en vez de
   '/' entre nombres de variable. */
html[data-theme="oscuro"] div[class*="fixed inset-0"] [class*="bg-slate-800"],
html[data-theme="oscuro"] div[class*="fixed inset-0"] [class*="bg-slate-900"] {
    background-color: var(--modal-oscuro-fondo, #0f172a) !important;
    border-color: var(--modal-oscuro-borde, #1e293b) !important;
}
html[data-theme="oscuro"] div[class*="fixed inset-0"] [class*="border-slate-600"],
html[data-theme="oscuro"] div[class*="fixed inset-0"] [class*="border-slate-700"],
html[data-theme="oscuro"] div[class*="fixed inset-0"] [class*="border-slate-800"],
html[data-theme="oscuro"] div[class*="fixed inset-0"] [class*="divide-slate-700"],
html[data-theme="oscuro"] div[class*="fixed inset-0"] [class*="divide-slate-800"] {
    border-color: var(--modal-oscuro-borde, #1e293b) !important;
}
html[data-theme="oscuro"] div[class*="fixed inset-0"] [class*="text-white"],
html[data-theme="oscuro"] div[class*="fixed inset-0"] [class*="text-slate-100"],
html[data-theme="oscuro"] div[class*="fixed inset-0"] [class*="text-slate-200"],
html[data-theme="oscuro"] div[class*="fixed inset-0"] [class*="text-slate-300"] { color: var(--modal-oscuro-texto, #ffffff) !important; }
html[data-theme="oscuro"] div[class*="fixed inset-0"] [class*="text-slate-400"],
html[data-theme="oscuro"] div[class*="fixed inset-0"] [class*="text-slate-500"] { color: var(--modal-oscuro-texto-secundario, #94a3b8) !important; }
html[data-theme="oscuro"] div[class*="fixed inset-0"] button[class*="text-white"] { color: #ffffff !important; }
html[data-theme="oscuro"] div[class*="fixed inset-0"] input[class*="bg-slate-900"],
html[data-theme="oscuro"] div[class*="fixed inset-0"] input[class*="bg-slate-950"],
html[data-theme="oscuro"] div[class*="fixed inset-0"] select[class*="bg-slate-900"],
html[data-theme="oscuro"] div[class*="fixed inset-0"] select[class*="bg-slate-950"],
html[data-theme="oscuro"] div[class*="fixed inset-0"] textarea[class*="bg-slate-900"],
html[data-theme="oscuro"] div[class*="fixed inset-0"] textarea[class*="bg-slate-950"] {
    background-color: var(--modal-oscuro-fondo, #0f172a) !important;
}
html[data-theme="oscuro"] div[class*="fixed inset-0"] input::placeholder,
html[data-theme="oscuro"] div[class*="fixed inset-0"] textarea::placeholder {
    color: var(--modal-oscuro-texto-secundario, #94a3b8) !important;
}

html[data-theme="descanso"] div[class*="fixed inset-0"] [class*="bg-slate-800"],
html[data-theme="descanso"] div[class*="fixed inset-0"] [class*="bg-slate-900"] {
    background-color: var(--modal-descanso-fondo, #e8e2d5) !important;
    border-color: var(--modal-descanso-borde, #ded9c9) !important;
}
html[data-theme="descanso"] div[class*="fixed inset-0"] [class*="border-slate-600"],
html[data-theme="descanso"] div[class*="fixed inset-0"] [class*="border-slate-700"],
html[data-theme="descanso"] div[class*="fixed inset-0"] [class*="border-slate-800"],
html[data-theme="descanso"] div[class*="fixed inset-0"] [class*="divide-slate-700"],
html[data-theme="descanso"] div[class*="fixed inset-0"] [class*="divide-slate-800"] {
    border-color: var(--modal-descanso-borde, #ded9c9) !important;
}
html[data-theme="descanso"] div[class*="fixed inset-0"] [class*="text-white"],
html[data-theme="descanso"] div[class*="fixed inset-0"] [class*="text-slate-100"],
html[data-theme="descanso"] div[class*="fixed inset-0"] [class*="text-slate-200"],
html[data-theme="descanso"] div[class*="fixed inset-0"] [class*="text-slate-300"] { color: var(--modal-descanso-texto, #3a322e) !important; }
html[data-theme="descanso"] div[class*="fixed inset-0"] [class*="text-slate-400"],
html[data-theme="descanso"] div[class*="fixed inset-0"] [class*="text-slate-500"] { color: var(--modal-descanso-texto-secundario, #605b5a) !important; }
html[data-theme="descanso"] div[class*="fixed inset-0"] button[class*="text-white"] { color: #ffffff !important; }
html[data-theme="descanso"] div[class*="fixed inset-0"] input[class*="bg-slate-900"],
html[data-theme="descanso"] div[class*="fixed inset-0"] input[class*="bg-slate-950"],
html[data-theme="descanso"] div[class*="fixed inset-0"] select[class*="bg-slate-900"],
html[data-theme="descanso"] div[class*="fixed inset-0"] select[class*="bg-slate-950"],
html[data-theme="descanso"] div[class*="fixed inset-0"] textarea[class*="bg-slate-900"],
html[data-theme="descanso"] div[class*="fixed inset-0"] textarea[class*="bg-slate-950"] {
    background-color: var(--modal-descanso-fondo, #e8e2d5) !important;
}
html[data-theme="descanso"] div[class*="fixed inset-0"] input::placeholder,
html[data-theme="descanso"] div[class*="fixed inset-0"] textarea::placeholder {
    color: var(--modal-descanso-texto-secundario, #605b5a) !important;
}

/* 🔘 Botones secundarios (Cancelar, etc. — bg-slate-700/800 sin ser el primario azul/cian) a
   gris claro, sin quedar en un fondo oscuro perdido dentro de una tarjeta blanca.
   🐛 Bug de contraste hallado en la verificación visual del rediseño (12/09/2026): varias
   plantillas ponen 'text-white' en el mismo botón (ej. "bg-slate-700 hover:bg-slate-600
   text-white", patrón típico de Cancelar/Cerrar en tickets_inventario.html y otras) — la regla
   de más arriba "button[class*='text-white'] { color: #ffffff !important; }" (pensada para los
   botones PRIMARIOS azul/cian, donde texto blanco sí tiene contraste) también le gana a este
   botón secundario, dejando texto blanco sobre el gris casi blanco de acá abajo: prácticamente
   ilegible. Se agrega 'color' aquí explícitamente — misma especificidad que esa regla, pero
   ésta va después en la hoja, así que gana por orden de cascada. */
html[data-theme="claro"] div[class*="fixed inset-0"] button[class*="bg-slate-700"],
html[data-theme="claro"] div[class*="fixed inset-0"] button[class*="bg-slate-800"] {
    background-color: #f1f5f9 !important;
    color: var(--modal-claro-texto, #1e293b) !important;
}
html[data-theme="claro"] div[class*="fixed inset-0"] button[class*="bg-slate-700"]:hover,
html[data-theme="claro"] div[class*="fixed inset-0"] button[class*="bg-slate-800"]:hover {
    background-color: #e2e8f0 !important;
}

/* 🐛 Mismo bug de contraste que arriba, pero en 'descanso': tema-descanso.css (que carga antes
   que esta hoja) ya aclara .bg-slate-700/800 a un sepia claro en TODA la app, así que un botón
   secundario con 'text-white' dentro de un modal en este tema hereda ese mismo problema —
   ver 'button[class*="text-white"] { color: #ffffff !important; }' en el bloque de descanso más
   arriba, pensado para los botones primarios, no para estos. */
html[data-theme="descanso"] div[class*="fixed inset-0"] button[class*="bg-slate-700"],
html[data-theme="descanso"] div[class*="fixed inset-0"] button[class*="bg-slate-800"] {
    color: var(--modal-descanso-texto, #3a322e) !important;
}

/* 🌑 Velo oscuro del modal (bg-slate-950/80, /90 en el wrapper "fixed inset-0" mismo, no en un
   descendiente): debe quedarse oscuro en LOS 3 TEMAS, a propósito (un fondo semitransparente
   oscuro detrás de una tarjeta clara se ve bien tanto en oscuro/descanso, donde ya es su color
   nativo, como en claro). El problema (hallado 12/09/2026, ver captura de Tomás del <thead> de
   Usuarios) es que tema-claro.css/tema-descanso.css ahora SÍ convierten bg-slate-950/80 y /90 de
   forma genérica, porque esas mismas clases de Tailwind también las usan elementos que nada
   tienen que ver con el velo del modal (esa tabla). La solución no es dejar de convertirlas
   ahí (eso volvería a romper el <thead>), sino restaurar el oscuro puntualmente aquí, con un
   selector que solo hace match sobre el DIV que es a la vez "fixed inset-0" Y trae esa clase de
   fondo — nunca sobre un <thead>, tarjeta u otro elemento que solo tenga la clase de fondo sin
   ser el wrapper del modal. Como este archivo se enlaza al final de cada <head> (después de
   tema-claro.css y tema-descanso.css), gana la cascada con la misma especificidad. */
html[data-theme="claro"] div[class*="fixed inset-0"][class*="bg-slate-950/80"],
html[data-theme="descanso"] div[class*="fixed inset-0"][class*="bg-slate-950/80"] {
    background-color: rgba(2, 6, 23, 0.8) !important;
}
html[data-theme="claro"] div[class*="fixed inset-0"][class*="bg-slate-950/90"],
html[data-theme="descanso"] div[class*="fixed inset-0"][class*="bg-slate-950/90"] {
    background-color: rgba(2, 6, 23, 0.9) !important;
}

/* 🪟 Por si en el futuro se agrega algún modal/diálogo con clases genéricas en vez del wrapper
   de Arkiv (Tailwind puro no las usa hoy, pero quedan cubiertas si aparecen). Fallback en la
   paleta clara de /login, igual que el resto de este bloque. */
.modal-content, .modal-box, dialog {
    background-color: #ffffff;
    border: 1px solid #e2e8f0;
    border-radius: 1.25rem;
    box-shadow: 0 25px 50px -12px rgb(0 0 0 / 0.15), 0 10px 15px -3px rgb(0 0 0 / 0.1);
    color: #1e293b;
}

/* =========================================================================
   ✨ Rediseño "más profesional" de los modales (pedido por Tomás, 12/09/2026:
   "aplica un diseño mas profesional a todos los modales ya"). Todo lo de acá
   abajo es CSS puro sobre el mismo wrapper "fixed inset-0" / panel
   bg-slate-800|900 que ya usa el bloque de arriba — ningún archivo HTML de
   ningún modal se tocó, así que esto aplica automáticamente a los ~40+
   modales de toda la app, en sus 2 variantes de marcado (con encabezado
   separado por un borde inferior, ej. comunicados.html, y sin ese borde,
   ej. usuarios.html) y en los 3 temas por igual, reutilizando currentColor
   para no tener que repetir reglas por tema.
   ========================================================================= */

/* 🌈 Barra de acento superior: una franja de degradado con los 3 colores de marca, pegada al
   borde superior del panel (mismo radio que el panel, así que se ve como una costura integrada,
   no como una barra flotante). Es puramente decorativa (aria-hidden vía ::before, no toma foco
   ni espacio en el documento) y no depende de que la plantilla traiga 'overflow-hidden': al
   tener su propio border-radius en las 2 esquinas superiores, queda a ras del borde del panel
   aunque el panel no recorte su contenido (varios modales usan overflow-y-auto para poder hacer
   scroll del formulario, y forzar overflow:hidden ahí rompería ese scroll). */
div[class*="fixed inset-0"] > [class*="bg-slate-800"]::before,
div[class*="fixed inset-0"] > [class*="bg-slate-900"]::before {
    content: '';
    position: absolute;
    /* Sobre el borde del panel (1px), para que la franja quede a ras del canto exterior. */
    top: -1px;
    left: -1px;
    right: -1px;
    /* La caja mide 2rem (más que cualquier radio de panel: rounded-2xl/3xl) y hereda el radio del
       panel, así la curva de las esquinas es la misma del panel. Con una caja de solo 4px el
       navegador encogía el radio para que cupiera y la franja se salía por las esquinas
       redondeadas (se veía como una barra recta encima del modal). La máscara deja visibles
       solo los 4px de arriba. */
    height: 2rem;
    border-radius: inherit;
    border-bottom-left-radius: 0;
    border-bottom-right-radius: 0;
    background: linear-gradient(90deg, var(--marca-azul-primario), var(--marca-cian) 55%, var(--marca-naranja));
    -webkit-mask: linear-gradient(#000 0 4px, transparent 4px);
    mask: linear-gradient(#000 0 4px, transparent 4px);
    pointer-events: none;
}

/* 🏷️ Insignia para el ícono del título del modal: el primer <i> dentro del <h2>/<h3> de la
   cabecera (en las 2 familias de marcado: con 'flex items-center gap-2' en el propio <h3>, ej.
   usuarios.html, o suelto con 'mr-2' antes del texto, ej. comunicados.html — en ambas ese <i> es
   el primer hijo elemento del encabezado) pasa de ser un simple glifo suelto a una insignia con
   fondo suave. Usa 'color-mix(in srgb, currentColor ...)' para teñir el fondo con el MISMO color
   que ya tiene el ícono (cian, naranja, o el color de texto del tema si no trae acento propio —
   ver bloque "🎨 Acentos de marca" y los bloques por tema más arriba, que ya fijan ese color vía
   currentColor antes de que esta regla se aplique), así que no hace falta repetir la paleta por
   tema ni por color de acento aquí. */
div[class*="fixed inset-0"] h2 > i:first-child,
div[class*="fixed inset-0"] h3 > i:first-child {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.75em;
    height: 1.75em;
    margin-right: 0.5rem;
    border-radius: 0.625rem;
    background: color-mix(in srgb, currentColor 14%, transparent);
    vertical-align: middle;
}

/* 🔘 Botón de cerrar (la 'x'): en las 43 apariciones de fa-xmark de toda la app, el ícono es
   siempre hijo directo de un <button> — :has() permite darle una zona de click circular con
   hover sin tener que tocar el HTML de ningún modal. El hover usa currentColor igual que la
   insignia de arriba, así que se ve correcto en los 3 temas sin reglas adicionales por tema
   (el color de texto del botón ya lo fija el bloque de arriba según el tema activo). */
div[class*="fixed inset-0"] button:has(> i.fa-xmark) {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2rem;
    height: 2rem;
    border-radius: 9999px;
    transition: background-color 0.15s ease, color 0.15s ease;
}
div[class*="fixed inset-0"] button:has(> i.fa-xmark):hover {
    background-color: color-mix(in srgb, currentColor 12%, transparent);
}

/* 🔲 Botones primarios/secundarios del modal: transición suave de color en vez del cambio
   brusco que ya tenían (los colores de hover en sí — azul-secundario, #f1f5f9/#e2e8f0 — no
   cambian, ver los bloques de arriba; esto solo agrega la transición). */
div[class*="fixed inset-0"] button[class*="bg-cyan-600"],
div[class*="fixed inset-0"] button[class*="bg-blue-600"],
div[class*="fixed inset-0"] button[class*="bg-blue-500"],
div[class*="fixed inset-0"] button[class*="bg-slate-700"],
div[class*="fixed inset-0"] button[class*="bg-slate-800"] {
    transition: background-color 0.15s ease, transform 0.1s ease !important;
}

/* 🌫️ Velo con desenfoque consistente: unifica el backdrop-blur del velo detrás del modal en
   TODA la app — algunas plantillas ya traían 'backdrop-blur-sm' en el HTML y otras no (ej.
   admin_boveda_personal.html, mi_boveda.html), lo que hacía que unos modales se sintieran más
   "flotando sobre un vidrio esmerilado" que otros. Como esta hoja se enlaza al final del <head>,
   este valor gana la cascada parejo en todos, sin tocar el HTML de ninguna plantilla. */
div[class*="fixed inset-0"] {
    backdrop-filter: blur(6px) !important;
    -webkit-backdrop-filter: blur(6px) !important;
}

/* 🎬 Animación de entrada: el velo aparece con un fade y el panel con un fade+escala suave. Los
   modales de Arkiv se muestran/ocultan alternando la clase 'hidden' de Tailwind
   (display:none ⇄ flex) vía classList.add/remove en JS — los navegadores reinician una
   animación CSS cada vez que un elemento pasa de display:none a visible, así que no hace falta
   ningún cambio de JS para que esto se dispare en cada apertura. Se respeta
   prefers-reduced-motion para quienes lo tengan activado en su sistema. */
@keyframes arkiv-modal-velo-in {
    from { opacity: 0; }
    to { opacity: 1; }
}
@keyframes arkiv-modal-panel-in {
    from { opacity: 0; transform: scale(0.96) translateY(4px); }
    to { opacity: 1; transform: scale(1) translateY(0); }
}
@media (prefers-reduced-motion: no-preference) {
    div[class*="fixed inset-0"] {
        animation: arkiv-modal-velo-in 0.18s ease-out;
    }
    div[class*="fixed inset-0"] > [class*="bg-slate-800"],
    div[class*="fixed inset-0"] > [class*="bg-slate-900"] {
        animation: arkiv-modal-panel-in 0.22s cubic-bezier(0.16, 1, 0.3, 1);
    }
}

/* =========================================================================
   ✨ SISTEMA DE DISEÑO MODERNO (pedido de Jesús, 20/10/2026: "modernizar la UI/UX con
   cuidado, respetando los colores que ya hay, solo diseño").

   Capa global y conservadora: NO cambia la paleta ni la estructura de ninguna plantilla.
   Solo pule lo que se comparte en toda la app y funciona igual en los 3 temas (oscuro, claro y
   descanso), porque usa currentColor y los colores de marca de arriba en vez de colores fijos:
     1. Transiciones suaves de 0.3s en todo lo interactivo (y ninguna si la persona pidió
        reducir el movimiento en su sistema operativo).
     2. Indicador de foco visible y accesible (teclado) en enlaces, botones y campos.
     3. Estados hover claros: filas de tabla, tarjetas-enlace, botones deshabilitados.
     4. Tipografía más legible: interlineado, suavizado, placeholders con contraste.
     5. Detalles modernos: selección de texto con el cian de marca, barras de desplazamiento
        finas, sombras más suaves en las tarjetas.
   Para desactivarla basta con borrar esta sección; nada más depende de ella.
   ========================================================================= */

/* 4 · Tipografía legible */
body {
    line-height: 1.5;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    /* ⚡ Sin text-rendering: optimizeLegibility (20/10/2026): en tablas de cientos de filas hacía
       el cálculo de estilos ~35% más lento y la app se sentía pesada. */
}
h1, h2, h3 {
    letter-spacing: -0.01em;
}
/* Firefox atenúa el placeholder al 54% por defecto: queda con el color que define la plantilla,
   sin esa atenuación extra que lo volvía casi ilegible sobre fondos oscuros. */
::placeholder {
    opacity: 1;
}

/* 1 · Transiciones: se dejan las de Tailwind (150ms). ⚡ (20/10/2026) Alargarlas a 0.3s/0.2s hacía que
   cada animación —también las que el navegador dispara al cargar la página— durara más cuadros de
   recálculo de estilos, y la app se sentía lenta al cargar y al hacer clic. */

/* 2 · Foco accesible: solo con teclado (:focus-visible), no al hacer clic con el mouse. Los
   campos que ya traen su anillo de Tailwind (focus:ring + focus:outline-none) lo conservan,
   porque esas clases son más específicas que estas reglas. */
a:focus-visible,
button:focus-visible,
[role="button"]:focus-visible,
[tabindex]:not([tabindex="-1"]):focus-visible,
summary:focus-visible {
    outline: 2px solid var(--marca-cian);
    outline-offset: 2px;
    border-radius: 0.5rem;
}
input:focus-visible,
select:focus-visible,
textarea:focus-visible {
    outline: 2px solid var(--marca-cian);
    outline-offset: 1px;
}

/* 3 · Hover y estados */
button:disabled,
button[disabled],
input:disabled,
select:disabled,
textarea:disabled {
    cursor: not-allowed;
    opacity: 0.6;
}
/* ⚡ Filas de tabla: se quitó el resaltado/transición global de todas las filas (20/10/2026); las
   tablas que lo necesitan ya traen su propio hover (clases hover:bg-*), sin costo extra. */
/* Tarjetas-enlace (ej. los módulos de la pantalla de inicio): se elevan levemente. Se usa la
   propiedad 'translate' (no 'transform') para sumarse a cualquier transform de Tailwind que ya
   tenga el elemento (centrados con -translate-x, active:scale) en vez de reemplazarlo. */
a[class*="rounded-2xl"]:hover,
a[class*="rounded-3xl"]:hover {
    translate: 0 -2px;
}
a[class*="rounded-2xl"],
a[class*="rounded-3xl"] {
    transition: translate 0.2s ease, background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, color 0.2s ease;
}

/* 5 · Detalles modernos */
/* ⚡ Sin ::selection personalizada (20/10/2026): obligaba al navegador a calcular un estilo extra
   por CADA elemento de la página; en Inventario (200+ filas) era la regla más costosa. */
/* ⚡ Sin scrollbar-color/scrollbar-width globales: se heredaban a todos los elementos y encarecían
   el cálculo de estilos en páginas grandes. */
/* ⚡ Sin estilos ::-webkit-scrollbar (se aplicaban a cada elemento desplazable y encarecían el
   dibujado); scrollbar-width/scrollbar-color de arriba bastan en los navegadores actuales. */
/* Sombras de tarjeta más suaves y difusas (las de Tailwind se ven duras sobre fondos claros). */
.shadow-xl {
    box-shadow: 0 10px 30px -12px rgb(2 6 23 / 0.25), 0 4px 10px -6px rgb(2 6 23 / 0.15);
}

/* Respeta "reducir movimiento" del sistema operativo: sin animaciones ni desplazamientos. */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        transition-duration: 0.01ms !important;
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        scroll-behavior: auto !important;
    }
    a[class*="rounded-2xl"]:hover,
    a[class*="rounded-3xl"]:hover {
        translate: none;
    }
}

/* =========================================================================
   🧩 REDISEÑO DE MÓDULOS Y MODALES MÁS USADOS (pedido de Jesús, 20/10/2026)
   Inicio (buscador + tarjetas), modal Nuevo/Editar Activo y modal Nueva Solicitud.
   Solo estilo y distribución: los colores salen de la marca y del tema activo; no cambia ningún
   id, campo de formulario ni atributo de la Guía (data-guia-*).
   ========================================================================= */

/* Títulos de sección dentro de un modal largo (ej. "Identificación del equipo"). */
.seccion-modal {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin: 0 0 0.25rem;
    padding-bottom: 0.5rem;
    border-bottom: 1px solid color-mix(in srgb, currentColor 12%, transparent);
    font-size: 11px;
    font-weight: 800;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--marca-cian);
}

/* Barra de acciones fija al pie del modal: Guardar/Enviar siempre a la vista en formularios largos.
   Va pegada al borde inferior del panel (que tiene 1.5rem de relleno, clase p-6) y toma el color de
   fondo del modal según el tema, para que el contenido pase por debajo sin verse a través. */
.modal-acciones-fijas {
    position: sticky;
    bottom: 0;
    z-index: 5;
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    align-items: center;
    gap: 0.5rem;
    margin: 0.75rem -1.5rem -1.5rem;
    /* A la derecha deja libre la esquina de las burbujas flotantes (chat y tema), que quedan por
       encima del modal y tapaban el botón principal en los modales anchos. */
    padding: 0.875rem 5.5rem 0.875rem 1.5rem;
    border-top: 1px solid color-mix(in srgb, currentColor 12%, transparent);
    border-radius: 0 0 1.25rem 1.25rem;
    background: var(--modal-oscuro-fondo, #0f172a);
    box-shadow: 0 -10px 24px -18px rgb(2 6 23 / 0.6);
}
html[data-theme="claro"] .modal-acciones-fijas { background: var(--modal-claro-fondo, #ffffff); }
html[data-theme="descanso"] .modal-acciones-fijas { background: var(--modal-descanso-fondo, #e8e2d5); }
@media (max-width: 639px) { .modal-acciones-fijas { padding-right: 4.75rem; justify-content: stretch; } .modal-acciones-fijas > * { flex: 1; } }

/* =========================================================================
   🧭 ESTILO MODERNO · ETAPA 2 — Inicio (22/10/2026, propuesta "D · Mezcla")
   Buscador grande, accesos frecuentes y módulos agrupados por área. Solo distribución y estilo:
   las tarjetas conservan sus clases (card-acento-*, colores de cada tema) y su marcado (la Guía
   lee su h3/p/i). Funciona en los 3 temas porque usa currentColor y los colores de marca.
   ========================================================================= */
.inicio-hero {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    margin-bottom: 1.75rem;
}
.inicio-buscador {
    position: relative;
    display: flex;
    align-items: center;
    gap: 0.75rem;
    min-height: 3.5rem;
    padding: 0 0.6rem 0 1.1rem;
    border-radius: 1rem;
    border: 1px solid color-mix(in srgb, currentColor 18%, transparent);
    background: color-mix(in srgb, currentColor 5%, transparent);
}
.inicio-buscador:focus-within {
    border-color: var(--marca-cian);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--marca-cian) 25%, transparent);
}
.inicio-buscador > i { color: var(--marca-cian); font-size: 1rem; }
.inicio-buscador > input {
    flex: 1;
    min-width: 0;
    padding: 0.9rem 0;
    border: 0;
    background: transparent;
    color: inherit;
    font: inherit;
    font-size: 1rem;
}
.inicio-buscador > input:focus { outline: none; }
.inicio-buscador > input::placeholder { color: color-mix(in srgb, currentColor 55%, transparent); }
.inicio-buscador-global {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    min-height: 2.5rem;
    padding: 0 0.75rem;
    border-radius: 0.7rem;
    border: 1px solid color-mix(in srgb, currentColor 14%, transparent);
    background: transparent;
    color: inherit;
    font: inherit;
    font-size: 0.78rem;
    font-weight: 600;
    opacity: 0.85;
    cursor: pointer;
    white-space: nowrap;
}
.inicio-buscador-global:hover { opacity: 1; border-color: var(--marca-cian); }
.inicio-buscador-global kbd {
    font-family: inherit;
    font-size: 0.7rem;
    padding: 0.05rem 0.4rem;
    border-radius: 0.35rem;
    border: 1px solid color-mix(in srgb, currentColor 22%, transparent);
}
@media (max-width: 639px) { .inicio-buscador-global-texto { display: none; } }

/* ⭐ Accesos frecuentes */
.accesos-frecuentes { margin-bottom: 2.25rem; }
.accesos-frecuentes > h2,
.grupo-modulos-cuenta {
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    opacity: 0.7;
}
.accesos-frecuentes > h2 { margin: 0 0 0.75rem; }
.accesos-frecuentes-lista { display: flex; flex-wrap: wrap; gap: 0.625rem; }
.acceso-frecuente {
    --acento: var(--marca-cian);
    display: inline-flex;
    align-items: center;
    gap: 0.625rem;
    min-height: 2.875rem;
    padding: 0 1rem 0 0.5rem;
    border-radius: 0.8rem;
    border: 1px solid color-mix(in srgb, currentColor 14%, transparent);
    background: color-mix(in srgb, currentColor 4%, transparent);
    font-size: 0.85rem;
    font-weight: 600;
    transition: border-color 0.15s ease;
}
.acceso-frecuente:hover { border-color: var(--acento); }
.acceso-frecuente-icono {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.9rem;
    height: 1.9rem;
    border-radius: 0.55rem;
    color: var(--acento);
    background: color-mix(in srgb, var(--acento) 15%, transparent);
    font-size: 0.85rem;
}
.acceso-frecuente-orange { --acento: var(--marca-naranja); }
.acceso-frecuente-blue { --acento: #3d7fd6; }
.acceso-frecuente-sky { --acento: #38bdf8; }
.acceso-frecuente-indigo { --acento: #818cf8; }
/* En el celular los accesos frecuentes van en una sola fila desplazable, para no ocupar media pantalla. */
@media (max-width: 639px) {
    .accesos-frecuentes-lista { flex-wrap: nowrap; overflow-x: auto; padding-bottom: 0.25rem; scrollbar-width: none; }
    .acceso-frecuente { flex: none; }
}

/* 🗂️ Áreas de módulos */
.modulos-por-area { display: flex; flex-direction: column; gap: 2.25rem; }
.grupo-modulos { --area: var(--marca-cian); }
.grupo-modulos[data-area="comunicacion"] { --area: #3d7fd6; }
.grupo-modulos[data-area="seguridad"] { --area: #9b6fc6; }
.grupo-modulos[data-area="analisis"] { --area: var(--marca-naranja); }
.grupo-modulos[data-area="administracion"] { --area: var(--marca-gris); }
/* Un área sin ninguna tarjeta para este rol no se muestra (el filtro del buscador hace lo mismo en JS). */
.grupo-modulos:not(:has(.grupo-modulos-rejilla > *)) { display: none; }
.grupo-modulos-cabecera { display: flex; align-items: center; gap: 0.625rem; margin-bottom: 0.875rem; }
.grupo-modulos-cabecera > h2 { margin: 0; font-size: 1.05rem; font-weight: 700; }
.grupo-modulos-punto { width: 0.625rem; height: 0.625rem; border-radius: 0.2rem; background: var(--area); }
.grupo-modulos-rejilla {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(15.5rem, 1fr));
    gap: 0.875rem;
}
/* Tarjeta compacta: ícono a la izquierda, título y descripción a la derecha. El marcado de cada
   tarjeta no cambia (div con ícono + h3 + p, y un pie "Ingresar →" que aquí se oculta porque
   toda la tarjeta ya es el enlace). first-of-type: la tarjeta de Chat puede llevar antes un
   <span> con el punto de "no leídos". */
.grupo-modulos-rejilla > a,
.grupo-modulos-rejilla > button {
    position: relative;
    padding: 1rem 1.1rem;
    border-radius: 0.9rem;
    justify-content: flex-start;
    text-align: left;
}
.grupo-modulos-rejilla > * > div:first-of-type {
    display: grid;
    grid-template-columns: 2.5rem minmax(0, 1fr);
    column-gap: 0.875rem;
    align-items: start;
}
.grupo-modulos-rejilla > * > div:first-of-type > div:first-child {
    grid-row: span 2;
    margin: 0;
    width: 2.5rem;
    height: 2.5rem;
    border-radius: 0.7rem;
}
.grupo-modulos-rejilla > * > div:first-of-type > h3 { font-size: 0.875rem; margin: 0.1rem 0 0; }
.grupo-modulos-rejilla > * > div:first-of-type > p { font-size: 12.5px; margin-top: 0.25rem; }
.grupo-modulos-rejilla > * > div:last-of-type:not(:first-of-type) { display: none; }

/* 👤 Menú de usuario (partials/perfil_boton.html) */
.menu-usuario-avatar {
    color: #fff;
    background: linear-gradient(135deg, var(--marca-azul-primario), var(--marca-cian));
}
.menu-usuario-flecha { transition: transform 0.3s ease; }
.menu-usuario-boton[aria-expanded="true"] .menu-usuario-flecha { transform: rotate(180deg); }
.menu-usuario-panel:not(.hidden) { animation: menu-usuario-entra 0.18s ease-out; }
@keyframes menu-usuario-entra { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }
/* En las barras de los módulos (muy llenas) el saludo solo aparece en pantallas grandes; en el
   encabezado de Inicio, desde tablet. */
nav .menu-usuario-hola { display: none; }
@media (min-width: 1536px) { nav .menu-usuario-hola { display: inline; } }
@media (max-width: 639px) { header .menu-usuario-hola { display: none; } }
@media (max-width: 480px) { .menu-usuario-panel { position: fixed; left: 12px; right: 12px; top: 64px; width: auto; } }
/* El tema claro oscurece .text-white; sobre el rojo del botón Salir el texto debe seguir blanco. */
html[data-theme] a.menu-usuario-salir, html[data-theme] a.menu-usuario-salir i { color: #fff !important; }

/* 🔢 Números clicables de "Distribución por sede" (Inventario): se ven como enlaces discretos. */
.celda-distribucion {
    display: inline-block;
    min-width: 2rem;
    padding: 0.15rem 0.5rem;
    border-radius: 0.5rem;
    text-decoration: underline dotted;
    text-underline-offset: 3px;
    text-decoration-color: color-mix(in srgb, currentColor 40%, transparent);
}
.celda-distribucion:hover { color: var(--marca-naranja); text-decoration-color: currentColor; }
.celda-distribucion-activa { color: var(--marca-naranja); font-weight: 800; outline: 1px solid color-mix(in srgb, var(--marca-naranja) 45%, transparent); }

/* =========================================================================
   🧭 ESTILO MODERNO · ETAPA 1 (pedido de Jesús, 22/10/2026: propuesta "D · Mezcla")
   Paleta azul-noche más profunda y botón principal con mejor contraste, SOLO en el tema
   oscuro (html[data-theme="oscuro"]); claro y descanso no cambian (tienen sus propias hojas).
   Es una capa de color: no mueve ni oculta nada, no toca ids, formularios ni atributos de la
   Guía (data-guia-*). Los modales tampoco cambian: sus colores salen de /admin/diseno
   (--modal-oscuro-*), con más especificidad que estas reglas.
   Para revertir la etapa completa basta con borrar esta sección.
   ========================================================================= */
:root {
    --arkiv-fondo: #0a101c;          /* fondo de página */
    --arkiv-base: #0b1220;           /* superficie base (antes slate-900) */
    --arkiv-superficie: #131d33;     /* tarjetas y paneles (antes slate-800) */
    --arkiv-elevada: #1f2b47;        /* botones secundarios (antes slate-700) */
    --arkiv-elevada-hover: #2a3a5c;
    --arkiv-borde: #24314f;          /* antes slate-700 */
    --arkiv-borde-suave: #1a2540;    /* antes slate-800 */
    --arkiv-texto-2: #9fb0c8;        /* texto secundario (antes slate-400) */
    --arkiv-texto-3: #8396b3;        /* texto terciario (antes slate-500, ahora con contraste AA) */
    --arkiv-naranja-hover: #f08a4b;
    --arkiv-texto-sobre-naranja: #1b0e04;
}

/* Fondos */
html[data-theme="oscuro"] .bg-slate-950 { background-color: var(--arkiv-fondo); }
html[data-theme="oscuro"] .bg-slate-950\/80 { background-color: rgb(10 16 28 / 0.8); }
html[data-theme="oscuro"] .bg-slate-950\/60 { background-color: rgb(10 16 28 / 0.6); }
html[data-theme="oscuro"] .bg-slate-900 { background-color: var(--arkiv-base); }
html[data-theme="oscuro"] .bg-slate-900\/80 { background-color: rgb(11 18 32 / 0.8); }
html[data-theme="oscuro"] .bg-slate-900\/60 { background-color: rgb(11 18 32 / 0.6); }
html[data-theme="oscuro"] .bg-slate-900\/50 { background-color: rgb(11 18 32 / 0.5); }
html[data-theme="oscuro"] .bg-slate-900\/40 { background-color: rgb(11 18 32 / 0.4); }
html[data-theme="oscuro"] .bg-slate-800 { background-color: var(--arkiv-superficie); }
html[data-theme="oscuro"] .bg-slate-800\/90 { background-color: rgb(19 29 51 / 0.9); }
html[data-theme="oscuro"] .bg-slate-800\/80 { background-color: rgb(19 29 51 / 0.8); }
html[data-theme="oscuro"] .bg-slate-800\/60 { background-color: rgb(19 29 51 / 0.6); }
html[data-theme="oscuro"] .bg-slate-800\/40 { background-color: rgb(19 29 51 / 0.4); }
html[data-theme="oscuro"] .bg-slate-700 { background-color: var(--arkiv-elevada); }
html[data-theme="oscuro"] .bg-slate-700\/60 { background-color: rgb(31 43 71 / 0.6); }
html[data-theme="oscuro"] .bg-slate-700\/50 { background-color: rgb(31 43 71 / 0.5); }
html[data-theme="oscuro"] .hover\:bg-slate-600:hover { background-color: var(--arkiv-elevada-hover); }
html[data-theme="oscuro"] .hover\:bg-slate-700:hover { background-color: var(--arkiv-elevada); }
html[data-theme="oscuro"] .hover\:bg-slate-800:hover { background-color: var(--arkiv-superficie); }
html[data-theme="oscuro"] .hover\:bg-slate-800\/40:hover { background-color: rgb(19 29 51 / 0.4); }

/* Bordes y divisores */
html[data-theme="oscuro"] .border-slate-700 { border-color: var(--arkiv-borde); }
html[data-theme="oscuro"] .border-slate-700\/60 { border-color: rgb(36 49 79 / 0.85); }
html[data-theme="oscuro"] .border-slate-700\/50 { border-color: rgb(36 49 79 / 0.75); }
html[data-theme="oscuro"] .border-slate-700\/40 { border-color: rgb(36 49 79 / 0.65); }
html[data-theme="oscuro"] .border-slate-800 { border-color: var(--arkiv-borde-suave); }
html[data-theme="oscuro"] .border-slate-800\/80 { border-color: rgb(26 37 64 / 0.8); }
html[data-theme="oscuro"] .divide-slate-800 > :not([hidden]) ~ :not([hidden]) { border-color: var(--arkiv-borde-suave); }
html[data-theme="oscuro"] .divide-slate-700\/50 > :not([hidden]) ~ :not([hidden]) { border-color: rgb(36 49 79 / 0.75); }
html[data-theme="oscuro"] .divide-slate-700\/40 > :not([hidden]) ~ :not([hidden]) { border-color: rgb(36 49 79 / 0.65); }

/* Texto secundario con mejor contraste sobre el azul-noche */
html[data-theme="oscuro"] .text-slate-400 { color: var(--arkiv-texto-2); }
html[data-theme="oscuro"] .text-slate-500 { color: var(--arkiv-texto-3); }

/* Botón principal naranja: naranja de marca con texto oscuro (el blanco sobre naranja no llega
   al contraste mínimo de lectura). Solo botones/enlaces con fondo naranja y texto blanco. */
html[data-theme="oscuro"] .bg-orange-600,
html[data-theme="oscuro"] .bg-orange-500 { background-color: var(--marca-naranja); }
html[data-theme="oscuro"] .hover\:bg-orange-500:hover,
html[data-theme="oscuro"] .hover\:bg-orange-600:hover { background-color: var(--arkiv-naranja-hover); }
html[data-theme="oscuro"] .bg-orange-600.text-white,
html[data-theme="oscuro"] .bg-orange-500.text-white { color: var(--arkiv-texto-sobre-naranja); }

/* =========================================================================
   🧭 ESTILO MODERNO · ETAPA 3 — Barra lateral (22/10/2026, propuesta "D · Mezcla")
   partials/barra_lateral.html (incluida desde utilidades_globales.html). Solo en pantallas
   anchas (≥1280 px): ahí la página se corre a la derecha el ancho de la barra. En tablet y celular
   no aparece y cada pantalla queda exactamente como antes. Los modales (z-50) y la Guía quedan por
   encima de la barra (z-30). Para revertir: quitar el include y borrar esta sección.
   ========================================================================= */
:root { --barra-lateral-ancho: 15.5rem; }
.barra-lateral { display: none; }
@media (min-width: 1280px) {
    /* 🧭 24/10/2026 (Jesús: las gráficas de Inventario "aún cargan de golpe"): la barra se incluye al
       FINAL de cada página, así que body:has(#barra-lateral) solo aplicaba cuando el navegador
       llegaba ahí. Hasta entonces pintaba la página sin barra, y luego todo se corría (y las
       gráficas se redimensionaban a mitad de su animación). html.con-barra-lateral la pone un
       script del <head> (partials/favicon.html) desde el primer instante, y el espacio y el
       fondo de la barra quedan reservados antes de que exista. */
    body:has(> #barra-lateral), body:has(#barra-lateral), html.con-barra-lateral body { padding-left: var(--barra-lateral-ancho); }
    html.con-barra-lateral body::before {
        content: "";
        position: fixed;
        top: 0;
        bottom: 0;
        left: 0;
        width: var(--barra-lateral-ancho);
        background: #0d1526;
        border-right: 1px solid #1a2540;
        z-index: 29;                       /* debajo de la barra real (z-30) cuando aparece */
        pointer-events: none;
    }
    .barra-lateral {
        position: fixed;
        top: 0;
        bottom: 0;
        left: 0;
        z-index: 30;
        width: var(--barra-lateral-ancho);
        display: flex;
        flex-direction: column;
        gap: 0.75rem;
        padding: 1rem 0.75rem 1.25rem;
        box-sizing: border-box;
        overflow-y: auto;
        /* La barra de desplazamiento se dibuja más abajo ("Barra de desplazamiento del menú
           lateral"): ojo, scrollbar-width aquí anularía ese estilo en Chrome/Edge. */
        font-family: var(--marca-fuente);
        background: #0d1526;
        border-right: 1px solid #1a2540;
        color: #b9c6da;
    }
    /* Los botones y chips fijos de la esquina inferior izquierda se corren para no quedar encima. */
    :is(html.con-barra-lateral body, body:has(#barra-lateral)) .guia-lanzador,
    :is(html.con-barra-lateral body, body:has(#barra-lateral)) #chip-empresa-superadmin,
    :is(html.con-barra-lateral body, body:has(#barra-lateral)) #chip-sedes-visibles { left: calc(var(--barra-lateral-ancho) + 1rem) !important; }
    /* Contenedores "a todo el ancho" (w-screen + left-1/2 -translate-x-1/2, ej. Inventario, Soporte TI, Usuarios):
       con la barra, el ancho útil es la ventana menos la barra, no toda la ventana. */
    :is(html.con-barra-lateral body, body:has(#barra-lateral)) .w-screen { width: calc(100vw - var(--barra-lateral-ancho) - var(--ancho-scroll, 0px)); }
}
/* ↔️ 26/10/2026 (Jesús: barra de scroll horizontal en Inventario): 100vw incluye la barra de scroll
   vertical de Windows (~17 px), así que los contenedores w-screen quedaban ese ancho más anchos que
   la página y aparecía un scroll lateral. --ancho-scroll lo mide partials/favicon.html. */
.w-screen { width: calc(100vw - var(--ancho-scroll, 0px)); }
/* Cabecera: título de la sección actual + botón para plegar/desplegar (sin logo: ya está en el encabezado). */
.barra-lateral-cabecera {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    padding: 0.15rem 0.1rem 0.4rem 0.625rem;
}
.barra-lateral-encabezado {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: 0.95rem;
    font-weight: 700;
    color: #e8eef8;
}
.barra-lateral-plegar {
    flex: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.5rem;
    height: 2.5rem;
    border-radius: 0.7rem;
    border: 1px solid #24314f;
    background: transparent;
    color: inherit;
    cursor: pointer;
    transition: border-color 0.15s ease, color 0.15s ease, background-color 0.15s ease;
}
.barra-lateral-plegar:hover { border-color: var(--marca-cian); color: #ffffff; }
.barra-lateral-flecha { transition: transform 0.2s ease; transform-origin: 15px 12px; }
html.barra-plegada .barra-lateral-flecha { transform: rotate(180deg); }
.barra-lateral-nav { display: flex; flex-direction: column; gap: 1px; }
.barra-lateral-titulo {
    margin: 0.9rem 0.625rem 0.3rem;
    font-size: 0.66rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: #8396b3;
}
.barra-lateral-enlace {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    min-height: 2.25rem;
    padding: 0.35rem 0.625rem;
    border-radius: 0.55rem;
    color: inherit;
    font-size: 0.8rem;
    font-weight: 500;
    line-height: 1.25;
    text-decoration: none;
    transition: background-color 0.15s ease, color 0.15s ease;
}
.barra-lateral-enlace > i { width: 1rem; text-align: center; font-size: 0.85rem; color: var(--area-bl, #8fa2bf); }
.barra-lateral-enlace > span { flex: 1; min-width: 0; }
.barra-lateral-enlace > small { font-size: 0.7rem; opacity: 0.7; }
.barra-lateral-enlace:hover { background: #121c31; color: #ffffff; }
.barra-lateral-enlace.activo { background: rgb(12 163 197 / 0.14); color: #ffffff; font-weight: 600; }
.barra-lateral-enlace.activo > i { color: var(--marca-cian); }
.barra-lateral [data-area="operacion"] { --area-bl: #3cc4e2; }
.barra-lateral [data-area="comunicacion"] { --area-bl: #7fb0f2; }
.barra-lateral [data-area="seguridad"] { --area-bl: #c19be6; }
.barra-lateral [data-area="analisis"] { --area-bl: #f39a5f; }
.barra-lateral [data-area="administracion"] { --area-bl: #a9b8cf; }
.barra-lateral .barra-lateral-titulo[data-area] { color: #8396b3; }
/* 🖱️ Barra de desplazamiento del menú lateral (29/10/2026, pedido de Jesús: la barra gris del
   sistema "no iba con la estética de Arkiv"). Delgada, redondeada, sin flechas y casi invisible
   hasta pasar el mouse por el menú; al tomarla se pinta con el cian de la marca.
   ⚡ Solo aplica a .barra-lateral (un único elemento), no a toda la página: ver la nota de
   rendimiento de "5 · Detalles modernos". */
.barra-lateral {
    --bl-scroll-pulgar: rgb(148 163 184 / 0.18);
    --bl-scroll-pulgar-visible: rgb(148 163 184 / 0.42);
    --bl-scroll-pulgar-activo: #22b8d8;
}
html[data-theme="claro"] .barra-lateral {
    --bl-scroll-pulgar: rgb(100 116 139 / 0.16);
    --bl-scroll-pulgar-visible: rgb(100 116 139 / 0.38);
    --bl-scroll-pulgar-activo: #0e7490;
}
html[data-theme="descanso"] .barra-lateral {
    --bl-scroll-pulgar: rgb(107 98 92 / 0.16);
    --bl-scroll-pulgar-visible: rgb(107 98 92 / 0.38);
    --bl-scroll-pulgar-activo: #8a6d4f;
}
/* Chrome, Edge y Safari: control fino del dibujo (sin flechas, pulgar redondeado y con aire). */
.barra-lateral::-webkit-scrollbar { width: 10px; }
.barra-lateral::-webkit-scrollbar-button { display: none; height: 0; }
.barra-lateral::-webkit-scrollbar-track { background: transparent; margin: 10px 0; }
.barra-lateral::-webkit-scrollbar-thumb {
    background-color: var(--bl-scroll-pulgar);
    border-radius: 999px;
    border: 3px solid transparent;           /* pulgar de 4 px "flotando" dentro de 10 px */
    background-clip: padding-box;
    min-height: 40px;
}
.barra-lateral:hover::-webkit-scrollbar-thumb { background-color: var(--bl-scroll-pulgar-visible); }
.barra-lateral::-webkit-scrollbar-thumb:hover,
.barra-lateral::-webkit-scrollbar-thumb:active { background-color: var(--bl-scroll-pulgar-activo); border-width: 2px; }
/* Firefox (no entiende ::-webkit-scrollbar): versión estándar equivalente. */
@supports not selector(::-webkit-scrollbar) {
    .barra-lateral { scrollbar-width: thin; scrollbar-color: var(--bl-scroll-pulgar) transparent; }
    .barra-lateral:hover { scrollbar-color: var(--bl-scroll-pulgar-visible) transparent; }
}
/* 🖱️ Barras de desplazamiento de TODO Arkiv (29/10/2026, pedido de Jesús: «que se adapte a todos los
   módulos» con el mismo diseño del menú lateral). Delgadas, redondeadas, sin flechas, con el color de
   cada tema; más visibles al pasar el mouse sobre el contenedor y con el color de la marca al tomarlas.
   ⚡ Rendimiento (ver "5 · Detalles modernos"): NO se usa `*` ni reglas sueltas `::-webkit-scrollbar`.
   Solo la página y los elementos que pueden desplazarse (clases overflow-* de Tailwind, áreas de texto,
   bloques de código, diálogos, listas desplegables y estilos en línea con overflow). :where() deja la
   especificidad en 0, así cualquier regla propia (p. ej. la barra lateral, o las que ocultan la barra
   con scrollbar-width: none) sigue mandando. */
:root {
    --arkiv-scroll-pulgar: rgb(148 163 184 / 0.28);
    --arkiv-scroll-pulgar-visible: rgb(148 163 184 / 0.5);
    --arkiv-scroll-pulgar-activo: #22b8d8;
}
html[data-theme="claro"] {
    --arkiv-scroll-pulgar: rgb(100 116 139 / 0.3);
    --arkiv-scroll-pulgar-visible: rgb(100 116 139 / 0.5);
    --arkiv-scroll-pulgar-activo: #0e7490;
}
html[data-theme="descanso"] {
    --arkiv-scroll-pulgar: rgb(107 98 92 / 0.3);
    --arkiv-scroll-pulgar-visible: rgb(107 98 92 / 0.5);
    --arkiv-scroll-pulgar-activo: #8a6d4f;
}
:where(html, [class*="overflow-"], textarea, pre, [role="dialog"], [role="listbox"], [style*="overflow"], .guia-popover p)::-webkit-scrollbar { width: 10px; height: 10px; }
:where(html, [class*="overflow-"], textarea, pre, [role="dialog"], [role="listbox"], [style*="overflow"], .guia-popover p)::-webkit-scrollbar-button { display: none; width: 0; height: 0; }
:where(html, [class*="overflow-"], textarea, pre, [role="dialog"], [role="listbox"], [style*="overflow"], .guia-popover p)::-webkit-scrollbar-track { background: transparent; }
:where(html, [class*="overflow-"], textarea, pre, [role="dialog"], [role="listbox"], [style*="overflow"], .guia-popover p)::-webkit-scrollbar-corner { background: transparent; }
:where(html, [class*="overflow-"], textarea, pre, [role="dialog"], [role="listbox"], [style*="overflow"], .guia-popover p)::-webkit-scrollbar-thumb {
    background-color: var(--arkiv-scroll-pulgar);
    border-radius: 999px;
    border: 3px solid transparent;           /* pulgar de 4 px "flotando" dentro de 10 px, como el menú */
    background-clip: padding-box;
    min-height: 40px;
    min-width: 40px;
}
:where(html, [class*="overflow-"], textarea, pre, [role="dialog"], [role="listbox"], [style*="overflow"], .guia-popover p):hover::-webkit-scrollbar-thumb { background-color: var(--arkiv-scroll-pulgar-visible); }
:where(html, [class*="overflow-"], textarea, pre, [role="dialog"], [role="listbox"], [style*="overflow"], .guia-popover p)::-webkit-scrollbar-thumb:hover,
:where(html, [class*="overflow-"], textarea, pre, [role="dialog"], [role="listbox"], [style*="overflow"], .guia-popover p)::-webkit-scrollbar-thumb:active { background-color: var(--arkiv-scroll-pulgar-activo); border-width: 2px; }
/* Firefox (no entiende ::-webkit-scrollbar). Va dentro de @supports a propósito: en Chrome/Edge 121+,
   scrollbar-color anula los estilos ::-webkit-scrollbar de arriba. */
@supports not selector(::-webkit-scrollbar) {
    :root { scrollbar-color: var(--arkiv-scroll-pulgar) transparent; }
    :where(html, [class*="overflow-"], textarea, pre, [role="dialog"], [role="listbox"], [style*="overflow"]) { scrollbar-width: thin; }
}
/* Tema claro y descanso */
@media (min-width: 1280px) {
    html[data-theme="claro"] .barra-lateral { background: #ffffff; border-right-color: #e2e8f0; color: #334155; }
    html[data-theme="descanso"] .barra-lateral { background: #e8e2d5; border-right-color: #d6cfbf; color: #3a322e; }
}
html[data-theme="claro"] .barra-lateral-titulo, html[data-theme="claro"] .barra-lateral .barra-lateral-titulo[data-area] { color: #64748b; }
html[data-theme="descanso"] .barra-lateral-titulo, html[data-theme="descanso"] .barra-lateral .barra-lateral-titulo[data-area] { color: #6b625c; }
html[data-theme="claro"] .barra-lateral-enlace:hover { background: #f1f5f9; color: #0f172a; }
html[data-theme="descanso"] .barra-lateral-enlace:hover { background: #ded7c7; color: #2a231f; }
html[data-theme="claro"] .barra-lateral-enlace.activo { background: rgb(12 163 197 / 0.12); color: #0f172a; }
html[data-theme="descanso"] .barra-lateral-enlace.activo { background: rgb(12 163 197 / 0.14); color: #2a231f; }
html[data-theme="claro"] .barra-lateral [data-area="operacion"] { --area-bl: #0e7490; }
html[data-theme="claro"] .barra-lateral [data-area="comunicacion"] { --area-bl: #1d4ed8; }
html[data-theme="claro"] .barra-lateral [data-area="seguridad"] { --area-bl: #7e22ce; }
html[data-theme="claro"] .barra-lateral [data-area="analisis"] { --area-bl: #c2410c; }
html[data-theme="claro"] .barra-lateral [data-area="administracion"] { --area-bl: #475569; }
html[data-theme="descanso"] .barra-lateral [data-area="operacion"] { --area-bl: #0e7490; }
html[data-theme="descanso"] .barra-lateral [data-area="comunicacion"] { --area-bl: #1d4ed8; }
html[data-theme="descanso"] .barra-lateral [data-area="seguridad"] { --area-bl: #7e22ce; }
html[data-theme="descanso"] .barra-lateral [data-area="analisis"] { --area-bl: #c2410c; }
html[data-theme="descanso"] .barra-lateral [data-area="administracion"] { --area-bl: #57534e; }
html[data-theme="claro"] .barra-lateral-encabezado { color: #0f172a; }
html[data-theme="descanso"] .barra-lateral-encabezado { color: #2a231f; }
html[data-theme="claro"] .barra-lateral-plegar { border-color: #cbd5e1; }
html[data-theme="descanso"] .barra-lateral-plegar { border-color: #cfc6b4; }
html[data-theme="claro"] .barra-lateral-plegar:hover, html[data-theme="descanso"] .barra-lateral-plegar:hover { border-color: #0e7490; color: #0e7490; }

/* 🗜️ Barra plegada (botón de la cabecera): solo íconos, el nombre aparece al pasar el mouse (title) y los
   títulos de área quedan como líneas separadoras. Todo lo que depende del ancho (relleno de la página,
   contenedores w-screen, botones fijos de la esquina) usa --barra-lateral-ancho, así que se ajusta solo. */
html.barra-plegada { --barra-lateral-ancho: 4.25rem; }
@media (min-width: 1280px) {
    .barra-lateral { transition: width 0.2s ease; }
    html.barra-plegada .barra-lateral { padding-left: 0.5rem; padding-right: 0.5rem; }
}
html.barra-plegada .barra-lateral-cabecera { justify-content: center; padding: 0.15rem 0 0.4rem; }
html.barra-plegada .barra-lateral-encabezado,
html.barra-plegada .barra-lateral-enlace > span,
html.barra-plegada .barra-lateral-enlace > small { display: none; }
html.barra-plegada .barra-lateral-enlace {
    justify-content: center;
    width: 2.75rem;
    min-height: 2.6rem;
    margin: 0 auto;
    padding: 0;
}
html.barra-plegada .barra-lateral-enlace > i { width: auto; font-size: 1rem; }
html.barra-plegada .barra-lateral-titulo {
    height: 1px;
    margin: 0.55rem 0.4rem;
    overflow: hidden;
    font-size: 0;
    background: #1f2b47;
}
html[data-theme="claro"].barra-plegada .barra-lateral-titulo { background: #e2e8f0; }
html[data-theme="descanso"].barra-plegada .barra-lateral-titulo { background: #d6cfbf; }

/* =========================================================================
   🧭 ENCABEZADO DE MÓDULO (23/10/2026, pedido de Jesús: "está sobrecargado a la izquierda")
   Tres zonas, para usar módulo por módulo agregando las clases al <nav> y a sus bloques:
     .encabezado-modulo            → el <nav> (o el contenedor flex del <header>, como en Usuarios)
     .encabezado-modulo-titulo     → logo + Volver + título (izquierda)
     .encabezado-modulo-utilidades → buscador, ayuda, sesión, chat, avisos (derecha, misma fila)
     .encabezado-modulo-acciones   → botones del módulo (fila propia debajo, separada por una línea)
   Si título y herramientas no caben juntos, las herramientas bajan a su propia fila alineadas a la
   derecha. Solo distribución: no cambia ids, onclick ni atributos de la Guía de ningún botón.
   ========================================================================= */
.encabezado-modulo {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    column-gap: 1rem;
    row-gap: 0.75rem;
}
.encabezado-modulo-titulo { order: 0; min-width: 0; }
.encabezado-modulo-utilidades {
    order: 0;
    margin-left: auto;
    flex-wrap: wrap;
    justify-content: flex-end;
}
.encabezado-modulo-acciones {
    order: 1;
    flex-basis: 100%;
    padding-top: 0.75rem;
    border-top: 1px solid color-mix(in srgb, currentColor 10%, transparent);
}
/* Variante "en línea" (Soporte TI): con pocas acciones (1–3 botones) no vale la pena una fila
   propia; van a la derecha, en la misma fila, justo antes de las herramientas. */
.encabezado-modulo-acciones.en-linea {
    order: 1;
    flex-basis: auto;
    margin-left: auto;
    padding-top: 0;
    border-top: 0;
}
.encabezado-modulo:has(> .encabezado-modulo-acciones.en-linea) > .encabezado-modulo-utilidades {
    order: 2;
    margin-left: 0;
}
@media (max-width: 639px) {
    .encabezado-modulo-utilidades { margin-left: 0; justify-content: flex-start; }
    .encabezado-modulo-acciones.en-linea { margin-left: 0; }
}

/* =========================================================================
   🎫 DETALLE DEL TICKET (Soporte TI, 23/10/2026): dos columnas en pantallas anchas.
   Antes era una sola columna angosta y la conversación quedaba de última, después de la gestión,
   la baja y las tareas. Ahora (≥1280 px): izquierda el caso, calificación, tareas y seguimiento;
   derecha la gestión, el SLA y el solicitante. Por debajo de 1280 px las columnas desaparecen
   (display: contents) y cada bloque vuelve a su orden de siempre con .detalle-orden-N.
   Solo distribución: ningún bloque cambió por dentro (formularios, ids, pasos de la Guía).
   ========================================================================= */
.detalle-ticket { display: flex; flex-direction: column; gap: 1.5rem; }
.detalle-col { display: contents; }
.detalle-orden-2 { order: 2; }
.detalle-orden-3 { order: 3; }
.detalle-orden-4 { order: 4; }
.detalle-orden-5 { order: 5; }
.detalle-orden-6 { order: 6; }
.detalle-orden-7 { order: 7; }
.detalle-orden-8 { order: 8; }
@media (min-width: 1280px) {
    .detalle-ticket-ancho { max-width: 84rem; }
    .detalle-ticket {
        display: grid;
        grid-template-columns: minmax(0, 1fr) 23rem;
        align-items: start;
    }
    .detalle-col { display: flex; flex-direction: column; gap: 1.5rem; min-width: 0; }
    .detalle-col > [class*="detalle-orden-"] { order: 0; }
    /* Bloques pensados para todo el ancho, acomodados a la columna derecha */
    .detalle-col-lateral [data-bloque="gestion"] .grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .detalle-col-lateral [data-bloque="gestion"] .grid > [class*="col-span"] { grid-column: 1 / -1; }
    .detalle-col-lateral [data-bloque="solicitante"] .grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .detalle-col-lateral [data-bloque="solicitante"] .grid > * { overflow-wrap: anywhere; }
}

/* =========================================================================
   ✅ MIS TAREAS (Soporte TI, 23/10/2026): el contenido ya usa el mismo ancho que la barra de pestañas
   (antes max-w-4xl, angosto y descentrado respecto a ella) y desde 1280 px las tarjetas de tarea van
   en dos columnas. Solo distribución: cada tarjeta queda igual por dentro.
   ========================================================================= */
@media (min-width: 1280px) {
    .mis-tareas-lista {
        display: grid;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 0.75rem;
        align-items: start;
    }
    .mis-tareas-lista > * { margin-top: 0 !important; }
}

/* =========================================================================
   📭 ESTADO VACÍO (23/10/2026): un solo aspecto para "todavía no hay nada aquí" en todos los
   módulos (antes unos eran texto suelto y otros una tarjeta, cada uno distinto). Marco punteado,
   centrado, ícono arriba (el que ya tenía la plantilla o, si no tenía, una bandeja dibujada aquí
   mismo, sin depender de Font Awesome). Usa el color de texto de cada tema (currentColor), así
   que se ve bien en oscuro, claro y descanso. .compacto = versión pequeña, dentro de tarjetas.
   Respeta .hidden: varios se muestran desde JS solo cuando un filtro no encuentra nada.
   ========================================================================= */
.estado-vacio {
    display: block;
    text-align: center;
    padding: 2.5rem 1.5rem;
    margin: 0;
    max-width: none;
    border: 1px dashed color-mix(in srgb, currentColor 28%, transparent);
    border-radius: 1.25rem;
    background: color-mix(in srgb, currentColor 4%, transparent);
    font-size: 0.8125rem;
    font-weight: 500;
    font-style: normal;
    line-height: 1.55;
}
.estado-vacio.hidden, .estado-vacio[hidden] { display: none; }
.estado-vacio > i:first-child {
    display: block;
    margin: 0 auto 0.6rem;
    font-size: 1.75rem;
    opacity: 0.6;
}
.estado-vacio:not(:has(> i:first-child))::before {
    content: "";
    display: block;
    width: 2rem;
    height: 2rem;
    margin: 0 auto 0.6rem;
    background: currentColor;
    opacity: 0.55;
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 13h5l1.5 2.5h5L16 13h5'/%3E%3Cpath d='M5.5 5h13L21 13v5a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-5z'/%3E%3C/svg%3E") center / contain no-repeat;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 13h5l1.5 2.5h5L16 13h5'/%3E%3Cpath d='M5.5 5h13L21 13v5a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-5z'/%3E%3C/svg%3E") center / contain no-repeat;
}
.estado-vacio > h3 { font-size: 0.875rem; font-weight: 700; margin: 0; }
.estado-vacio > p { margin: 0.25rem 0 0; font-size: 0.75rem; }
.estado-vacio.compacto {
    padding: 1.1rem 1rem;
    border-radius: 0.9rem;
    font-size: 0.75rem;
}
.estado-vacio.compacto::before { display: none; }

/* =========================================================================
   📣 AVISOS (23/10/2026): un solo componente para los avisos de todos los módulos (antes había ~15
   combinaciones: info en azul, celeste o cian; bordes /20 o /30; esquinas xl o 2xl; texto xs o sm).
   .aviso + un tono: .aviso-info · .aviso-exito · .aviso-alerta · .aviso-error.
   Mismo marco para todos (barra de color a la izquierda, fondo suave) y colores pensados por tema.
   No cambia el display del aviso (algunos son bloques con texto y negrillas, otros flex con ícono)
   ni su visibilidad (.hidden), solo color, borde, esquinas, relleno y tamaño de letra.
   Los avisos dentro de modales no llevan la clase: sus colores salen de /admin/diseno.
   ========================================================================= */
:root .aviso.aviso-info   { --aviso-rgb: 56 189 248;  --aviso-texto: #bae6fd; }
:root .aviso.aviso-exito  { --aviso-rgb: 52 211 153;  --aviso-texto: #a7f3d0; }
:root .aviso.aviso-alerta { --aviso-rgb: 251 191 36;  --aviso-texto: #fde68a; }
:root .aviso.aviso-error  { --aviso-rgb: 251 113 133; --aviso-texto: #fecdd3; }
:root .aviso[class*="aviso-"] {
    background-color: rgb(var(--aviso-rgb) / 0.08);
    border: 1px solid rgb(var(--aviso-rgb) / 0.28);
    border-left: 3px solid rgb(var(--aviso-rgb) / 0.9);
    border-radius: 1rem;
    padding: 0.85rem 1rem;
    color: var(--aviso-texto);
    font-size: 0.75rem;
    line-height: 1.55;
}
:root .aviso[class*="aviso-"] > i:first-child { color: rgb(var(--aviso-rgb)); }
/* Temas claros: texto oscuro del mismo tono (los temas fuerzan colores con !important) */
:root[data-theme="claro"] .aviso.aviso-info,   :root[data-theme="descanso"] .aviso.aviso-info   { --aviso-rgb: 2 132 199;  color: #075985 !important; }
:root[data-theme="claro"] .aviso.aviso-exito,  :root[data-theme="descanso"] .aviso.aviso-exito  { --aviso-rgb: 5 150 105;  color: #065f46 !important; }
:root[data-theme="claro"] .aviso.aviso-alerta, :root[data-theme="descanso"] .aviso.aviso-alerta { --aviso-rgb: 217 119 6;  color: #92400e !important; }
:root[data-theme="claro"] .aviso.aviso-error,  :root[data-theme="descanso"] .aviso.aviso-error  { --aviso-rgb: 225 29 72;  color: #9f1239 !important; }

/* 📱 Encabezado en celular (23/10/2026): los títulos largos ("Certificación de Devolución de
   Activos", "Soporte TI — Todas las Solicitudes") tenían whitespace-nowrap y empujaban la página a
   lo ancho. En pantallas angostas el título puede partirse en dos líneas. */
@media (max-width: 639px) {
    .encabezado-modulo-titulo { min-width: 0; max-width: 100%; }
    .encabezado-modulo-titulo > * { min-width: 0; }
    .encabezado-modulo-titulo h1 { white-space: normal; min-width: 0; line-height: 1.25; }
}

/* =========================================================================
   ✨ VIVA · SISTEMA DE MOVIMIENTO — Fase 1 (23/10/2026, dirección "Viva" elegida por Jesús)
   Movimiento productivo y corto (Carbon/IBM: 70–240 ms en micro-interacciones, 400 ms en entradas
   grandes). Reglas para no romper nada:
     · Solo CSS: si algo no carga, todo se ve igual que antes (las animaciones terminan visibles).
     · Solo opacity/transform (nunca tamaño ni posición en el flujo): no mueve el layout ni cambia
       medidas que lean otros scripts (la firma digital mide su lienzo al abrir el modal: por eso
       los modales entran con translateY, nunca con scale).
     · Los botones a los que apunta la Guía (encabezados) no se animan.
     · prefers-reduced-motion: todo queda quieto (bloque final).
   ========================================================================= */
:root {
    --mov-rapido: 120ms;
    --mov-medio: 240ms;
    --mov-lento: 400ms;
    --mov-curva: cubic-bezier(0.2, 0, 0.38, 0.9);      /* productiva: estados, hover */
    --mov-entrada: cubic-bezier(0, 0, 0.3, 1);         /* expresiva: algo que aparece */
}
@keyframes viva-entrar { from { opacity: 0; transform: translateY(10px); } }
@keyframes viva-aparecer { from { opacity: 0; } }
@keyframes viva-deriva-1 { to { transform: translate(18%, 12%); } }
@keyframes viva-deriva-2 { to { transform: translate(-16%, 10%); } }

/* 1 · Entrada escalonada: hijos de [data-viva-escalonar] entran uno tras otro (máx. 12 pasos de 30 ms). */
[data-viva-escalonar] > * { animation: viva-entrar var(--mov-lento) var(--mov-entrada) backwards; }
[data-viva-escalonar] > :nth-child(2) { animation-delay: 30ms; }
[data-viva-escalonar] > :nth-child(3) { animation-delay: 60ms; }
[data-viva-escalonar] > :nth-child(4) { animation-delay: 90ms; }
[data-viva-escalonar] > :nth-child(5) { animation-delay: 120ms; }
[data-viva-escalonar] > :nth-child(6) { animation-delay: 150ms; }
[data-viva-escalonar] > :nth-child(7) { animation-delay: 180ms; }
[data-viva-escalonar] > :nth-child(8) { animation-delay: 210ms; }
[data-viva-escalonar] > :nth-child(9) { animation-delay: 240ms; }
[data-viva-escalonar] > :nth-child(10) { animation-delay: 270ms; }
[data-viva-escalonar] > :nth-child(11) { animation-delay: 300ms; }
[data-viva-escalonar] > :nth-child(n+12) { animation-delay: 330ms; }

/* 2 · Tarjetas que responden: se elevan un poco con una sombra del color de su área. */
.grupo-modulos-rejilla > a,
.grupo-modulos-rejilla > button,
.acceso-frecuente {
    transition: transform var(--mov-medio) var(--mov-curva), box-shadow var(--mov-medio) var(--mov-curva),
                border-color var(--mov-rapido) var(--mov-curva), background-color var(--mov-rapido) var(--mov-curva);
}
.grupo-modulos-rejilla > a:hover,
.grupo-modulos-rejilla > button:hover,
.grupo-modulos-rejilla > a:focus-visible,
.grupo-modulos-rejilla > button:focus-visible {
    transform: translateY(-3px);
    box-shadow: 0 12px 28px -12px color-mix(in srgb, var(--area) 55%, transparent);
}
.acceso-frecuente:hover, .acceso-frecuente:focus-visible {
    transform: translateY(-2px);
    box-shadow: 0 10px 22px -12px color-mix(in srgb, var(--acento) 60%, transparent);
}
.grupo-modulos-rejilla > a:active, .grupo-modulos-rejilla > button:active, .acceso-frecuente:active {
    transform: translateY(0);
    transition-duration: var(--mov-rapido);
}

/* 2b · Tarjetas de resumen (Soporte TI y siguientes módulos): mismo gesto, con el color de marca. */
.viva-tarjeta { transition: transform var(--mov-medio) var(--mov-curva), box-shadow var(--mov-medio) var(--mov-curva), border-color var(--mov-rapido) var(--mov-curva); }
.viva-tarjeta:hover, .viva-tarjeta:focus-visible {
    transform: translateY(-3px);
    box-shadow: 0 14px 30px -14px color-mix(in srgb, var(--marca-naranja) 55%, transparent);
}
.viva-tarjeta:active { transform: translateY(0); transition-duration: var(--mov-rapido); }

/* 3 · Luz ambiental en el saludo de Inicio: dos focos suaves que se desplazan lento detrás del
   texto (pseudo-elementos: no hay marcado nuevo ni capas encima del buscador). */
.inicio-hero { position: relative; isolation: isolate; }
.inicio-hero::before,
.inicio-hero::after {
    content: "";
    position: absolute;
    z-index: -1;
    border-radius: 50%;
    filter: blur(60px);
    pointer-events: none;
    opacity: 0.22;
}
.inicio-hero::before {
    width: 22rem; height: 22rem; left: -6rem; top: -11rem;
    background: var(--marca-cian);
    animation: viva-deriva-1 16s ease-in-out infinite alternate;
}
.inicio-hero::after {
    width: 18rem; height: 18rem; right: 4rem; top: -10rem;
    background: var(--marca-naranja);
    opacity: 0.12;
    animation: viva-deriva-2 20s ease-in-out infinite alternate;
}
html[data-theme="claro"] .inicio-hero::before, html[data-theme="descanso"] .inicio-hero::before { opacity: 0.14; }
html[data-theme="claro"] .inicio-hero::after, html[data-theme="descanso"] .inicio-hero::after { opacity: 0.08; }
.inicio-hero > * { animation: viva-entrar var(--mov-lento) var(--mov-entrada) backwards; }
.inicio-hero > :nth-child(2) { animation-delay: 60ms; }

/* 4 · Modales: el panel entra desde abajo (solo translateY + opacidad, ver nota de arriba). */
div[class*="fixed inset-0"]:not(.hidden) > div:first-of-type {
    animation: viva-entrar var(--mov-medio) var(--mov-entrada) backwards;
}

/* 5 · Avisos y estados vacíos aparecen suaves en vez de "saltar". */
.aviso[class*="aviso-"] { animation: viva-entrar var(--mov-medio) var(--mov-entrada) backwards; }
.estado-vacio { animation: viva-aparecer var(--mov-lento) var(--mov-entrada) backwards; }

/* 6 · Barra lateral: el enlace se desliza apenas al pasar el mouse. */
.barra-lateral-enlace { transition: background-color var(--mov-rapido) var(--mov-curva), color var(--mov-rapido) var(--mov-curva), transform var(--mov-medio) var(--mov-curva); }
.barra-lateral-enlace:hover { transform: translateX(2px); }
html.barra-plegada .barra-lateral-enlace:hover { transform: none; }

/* 7 · Movimiento reducido (ajuste del sistema operativo): nada se mueve; todo se ve igual. */
@media (prefers-reduced-motion: reduce) {
    [data-viva-escalonar] > *,
    .inicio-hero > *,
    .inicio-hero::before, .inicio-hero::after,
    div[class*="fixed inset-0"]:not(.hidden) > div:first-of-type,
    .aviso[class*="aviso-"],
    .estado-vacio { animation: none !important; }
    .grupo-modulos-rejilla > a, .grupo-modulos-rejilla > button, .acceso-frecuente,
    .barra-lateral-enlace, .viva-tarjeta { transition: none !important; }
    .viva-tarjeta:hover, .viva-tarjeta:focus-visible,
    .grupo-modulos-rejilla > a:hover, .grupo-modulos-rejilla > button:hover,
    .grupo-modulos-rejilla > a:focus-visible, .grupo-modulos-rejilla > button:focus-visible,
    .acceso-frecuente:hover, .acceso-frecuente:focus-visible,
    .barra-lateral-enlace:hover { transform: none !important; }
}

/* =========================================================================
   🧼 ENCABEZADO LIMPIO (23/10/2026, pedido de Jesús: "está saturado"): desde 1280 px, cuando se ve la
   barra lateral, el encabezado de cada módulo queda solo con lo funcional — a la izquierda «Volver» +
   título, a la derecha buscador e íconos (justify-content: space-between). El isotipo de Arkiv y el
   logo de la empresa salen de ahí: el logo pasa a la parte superior de la barra lateral. Por debajo de
   1280 px (sin barra lateral) el encabezado queda como estaba, con sus logos.
   Solo se ocultan con CSS: el marcado de las 47 plantillas no cambia y el logo es el mismo parcial.
   ========================================================================= */
.barra-lateral-marca { display: none; }
@media (min-width: 1280px) {
    :is(html.con-barra-lateral body, body:has(#barra-lateral)) :is(nav, header):not(.barra-lateral-nav) a:has(> div img[src^="/static/img/isotipo-arkiv"]),
    :is(html.con-barra-lateral body, body:has(#barra-lateral)) :is(nav, header):not(.barra-lateral-nav) a.logo-institucional-nav { display: none !important; }
    :is(html.con-barra-lateral body, body:has(#barra-lateral)) .encabezado-modulo { justify-content: space-between; column-gap: 1.25rem; }
    .barra-lateral-marca {
        display: flex;
        justify-content: center;
        padding: 0.25rem 0.25rem 0.9rem;
        margin-bottom: 0.4rem;
        border-bottom: 1px solid var(--arkiv-borde-suave, rgba(148, 163, 184, 0.15));
    }
    .barra-lateral-marca a.logo-institucional-nav { display: flex !important; padding: 0.45rem 0.9rem; }
    .barra-lateral-marca a.logo-institucional-nav img { height: 34px !important; max-width: 11rem; }
    html.barra-plegada .barra-lateral-marca { display: none; }
}

/* =========================================================================
   ✨ ISOTIPO DE ARKIV: nítido y con una estela de luz periódica (26/10/2026, pedido de Jesús)
   partials/marca_arkiv.html pone la imagen (WebP 128/256/512 con srcset) y una elipse SVG; el
   disparador de partials/favicon.html agrega .animando cada ~13 s durante 1,6 s. Sin sonido, fondo
   transparente y nada con "reducir movimiento". Imita el video de marca: una estela cian que
   cruza el logo, un brillo breve y unos cuadritos que salen por la esquina.
   ========================================================================= */
.marca-arkiv { position: relative; display: inline-block; flex: none; vertical-align: middle; }
.marca-arkiv-img { display: block; width: 100%; height: 100%; max-height: 100%; object-fit: contain; }
.marca-arkiv-orbita { position: absolute; left: -32%; top: -36%; width: 164%; height: 172%; overflow: visible; pointer-events: none; opacity: 0; }
.marca-arkiv-estela { fill: none; stroke: #7dd3fc; stroke-width: 3; stroke-linecap: round; stroke-dasharray: 28 72; stroke-dashoffset: 100;
    filter: drop-shadow(0 0 1.5px #22d3ee) drop-shadow(0 0 4px rgba(56, 189, 248, .85)); }
.marca-arkiv-pixel { position: absolute; top: 14%; right: 2%; width: 13%; height: 13%; border-radius: 1px; background: #38bdf8; opacity: 0; pointer-events: none; }
.marca-arkiv-pixel:nth-of-type(2n) { background: #1d6fd6; width: 10%; height: 10%; }
.marca-arkiv.animando .marca-arkiv-orbita { animation: marca-arkiv-orbita 1.6s ease-out both; }
.marca-arkiv.animando .marca-arkiv-estela { animation: marca-arkiv-estela 1.6s cubic-bezier(.45, .05, .25, 1) both; }
.marca-arkiv.animando .marca-arkiv-img { animation: marca-arkiv-brillo 1.6s ease-out both; }
.marca-arkiv.animando .marca-arkiv-pixel { animation: marca-arkiv-pixel 1.1s ease-out var(--d, .6s) both; }
@keyframes marca-arkiv-estela { from { stroke-dashoffset: 100; } to { stroke-dashoffset: -100; } }
@keyframes marca-arkiv-orbita { 0% { opacity: 0; } 12% { opacity: 1; } 78% { opacity: 1; } 100% { opacity: 0; } }
@keyframes marca-arkiv-brillo {
    0%, 100% { filter: none; transform: none; }
    45% { filter: drop-shadow(0 0 5px rgba(56, 189, 248, .9)) brightness(1.12); transform: scale(1.05); }
}
@keyframes marca-arkiv-pixel {
    0% { opacity: 0; transform: translate(0, 0) scale(.6); }
    25% { opacity: 1; }
    100% { opacity: 0; transform: translate(var(--x), var(--y)) scale(.35); }
}
@media (prefers-reduced-motion: reduce) {
    .marca-arkiv-orbita, .marca-arkiv-pixel { display: none; }
    .marca-arkiv.animando .marca-arkiv-img { animation: none; }
}
