/*=========================================================
    EVOL-IA DESIGN SYSTEM
    Componentes Globales
==========================================================*/


/*=========================================
    TARJETA GLASS
=========================================*/

.glass-card{

    background:var(--glass-bg);

    backdrop-filter:blur(var(--blur-lg));

    border:1px solid var(--glass-border);

    border-radius:var(--radius-xl);

    box-shadow:

        var(--shadow-lg);

    transition:all var(--transition-normal);

}

.glass-card:hover{

    background:var(--glass-bg-hover);

    border-color:var(--glass-border-active);

}


/*=========================================
    BOTÓN PRINCIPAL
=========================================*/

.btn-primary{

    width:100%;

    border:none;

    cursor:pointer;

    padding:18px;

    border-radius:var(--radius-md);

    background:var(--button-gradient);

    color:white;

    font-size:20px;

    font-weight:600;

    transition:all var(--transition-normal);

    box-shadow:

        var(--shadow-glow);

}

.btn-primary:hover{

    transform:translateY(-3px);

    background:var(--button-gradient-hover);

    box-shadow:

        var(--shadow-purple);

}

.btn-primary:active{

    transform:scale(.98);

}


/*=========================================
    INPUTS
=========================================*/

.input{

    width:100%;

    padding:16px;

    border-radius:var(--radius-md);

    border:1px solid var(--campo-borde, rgba(255,255,255,.08));

    background:var(--campo-bg, rgba(255,255,255,.04));

    color:var(--text-primary);

    font-size:16px;

    transition:all var(--transition-normal);

}

.input::placeholder{

    color:var(--text-disabled);

}

.input:focus{

    outline:none;

    border-color:var(--secondary-blue);

    box-shadow:var(--campo-foco-halo, 0 0 20px rgba(34,200,255,.20));

}


/*=========================================
    LABELS
=========================================*/

.label{

    display:block;

    margin-bottom:10px;

    font-size:15px;

    color:var(--text-secondary);

    text-align:left;

}


/*=========================================
    TÍTULOS
=========================================*/

.title{

    font-size:var(--font-xxl);

    color:var(--text-primary);

    font-weight:700;

}

.subtitle{

    color:var(--text-secondary);

    line-height:1.7;

    font-size:18px;

}


/*=========================================
    LÍNEA CORPORATIVA
=========================================*/

.line{

    width:120px;

    height:4px;

    margin:30px auto;

    border-radius:50px;

    background:

    linear-gradient(

        90deg,

        var(--secondary-blue),

        var(--primary-purple)

    );

}


/*=========================================
    BADGE
=========================================*/

.badge{

    display:inline-flex;

    align-items:center;

    justify-content:center;

    padding:8px 18px;

    border-radius:30px;

    background:var(--info-bg, rgba(34,200,255,.12));

    border:1px solid var(--info-borde, rgba(34,200,255,.20));

    color:var(--secondary-blue);

    font-size:13px;

    font-weight:600;

}


/*=========================================
    TEXTO
=========================================*/

/* Pais de una Parte o de una Empresa: bandera + nombre, o solo el codigo si
   no esta en el catalogo ISO. Discreto: acompana al nombre, no compite con
   el. Ver EvoliaApi.paisHtml y partials/pais.html. */
.pais-parte{
  display:inline-flex;
  align-items:center;
  gap:.35em;
  margin-left:.5em;
  font-size:.86em;
  opacity:.85;
  vertical-align:middle;
  white-space:nowrap;
}
/* Solo, sin un nombre delante (ficha de Parte o de Empresa): sin sangria. */
.pais-parte:first-child{
  margin-left:0;
}
/* Contenedores con una regla generica "X span" pensada para su etiqueta
   (gris, en bloque): sin esto convertirian el pais en otra etiqueta. En la
   stat-card (ficha de Empresa) el pais ES el valor de la tarjeta; en la
   ficha del contrato acompana al nombre de la empresa o de la Parte. */
.stat-card .pais-parte{
  display:inline-flex;
  color:inherit;
  font-size:1em;
  opacity:1;
}
.contract-detail-item .pais-parte{
  display:inline-flex;
  margin-bottom:0;
  color:inherit;
  font-size:.86em;
}
/* Contorno tenue: sin el, las banderas con blanco (Japon, Corea) se pierden
   sobre fondo claro. */
.pais-bandera{
  flex:none;
  width:20px;
  height:15px;
  border-radius:2px;
  box-shadow:0 0 0 1px rgba(0,0,0,.18);
  object-fit:cover;
}

.text-muted{

    color:var(--text-muted);

}

.text-center{

    text-align:center;

}


/*=========================================
    CONTENEDOR
=========================================*/

.container{

    width:100%;

    max-width:1300px;

    margin:auto;

    padding:40px;

}


/*=========================================
    EFECTO SCROLL
=========================================*/

/* La barra tiene que LEERSE como una barra.

   Antes: 10px, pulgar #8C42FF sobre via #071838 -- 3,63 de contraste. Se
   dibujaba, pero en paginas que desbordan poco (Expedientes desborda 3px a
   805 de alto) el pulgar ocupa el 99% del recorrido y se lee como un borde
   decorativo, no como algo que se pueda arrastrar.

   Ahora: mas ancha, pulgar mas claro y separado de la via por un borde del
   color de la via -- ese borde es lo que da la sensacion de canal. Y un
   estado :hover, que es la senal de que el elemento es agarrable.

   NO se oculta en ningun sitio: nada de scrollbar-width:none ni de
   ::-webkit-scrollbar{display:none}. */
::-webkit-scrollbar{
    width:12px;
    height:12px;
}

::-webkit-scrollbar-track{
    background:var(--scroll-via, #0A1A3C);
    border-radius:20px;
}

::-webkit-scrollbar-thumb{
    background:var(--scroll-pulgar, #A855F7);
    border-radius:20px;
    /* El borde del color de la via encoge el pulgar visualmente y deja ver
       el canal a los lados. */
    border:3px solid var(--scroll-via, #0A1A3C);
    background-clip:padding-box;
}

::-webkit-scrollbar-thumb:hover{
    background:var(--scroll-pulgar-hover, #C084FC);
    border-width:2px;
}

::-webkit-scrollbar-corner{
    background:var(--scroll-via, #0A1A3C);
}

/* Firefox no admite ::-webkit-scrollbar y necesita las propiedades
   estandar. Pero NO se pueden poner sueltas: Chrome tambien las obedece y,
   en cuanto ve scrollbar-width o scrollbar-color, IGNORA por completo los
   ::-webkit-scrollbar de arriba. Se comprobo midiendo -- la barra volvia a
   10px en vez de los 12 pedidos, y el borde de canal y el :hover
   desaparecian.

   @supports selector(::-webkit-scrollbar) es falso en Firefox y verdadero
   en Chrome, asi que cada navegador coge solo lo suyo.

   thin, nunca none: la barra sigue siendo visible. */
@supports not selector(::-webkit-scrollbar){
    html{
        scrollbar-width:thin;
        scrollbar-color:var(--scroll-pulgar, #A855F7) var(--scroll-via, #0A1A3C);
    }
}


/* ==========================================================
   Fase 1 — Sistema visual base (2026-08-11)
   Componentes compartidos nuevos, agregados para el rediseño
   visual integral (ver claude/fase0-auditoria-frontend-evolia.md
   y prompt-maestro-evolia.md seccion 31). Todo lo de abajo es
   aditivo: ninguna regla existente arriba de este bloque fue
   modificada. Ningun template todavia consume estas clases --
   se conectaran en las fases siguientes (Inicio, Empresas,
   Proyectos, Contratos, etc.), pantalla por pantalla.
   ========================================================== */

/* ---------- Botones: variantes adicionales a .btn-primary ---------- */

.btn-secondary {
    width: 100%;
    border: 1px solid var(--glass-border-active);
    cursor: pointer;
    padding: 18px;
    border-radius: var(--radius-md);
    background: transparent;
    color: var(--boton-secundario-texto, var(--text-primary));
    font-size: 16px;
    font-weight: 600;
    transition: all var(--transition-normal);
}

.btn-secondary:hover {
    background: var(--glass-bg-hover);
    border-color: var(--secondary-blue);
}

.btn-ghost {
    border: none;
    cursor: pointer;
    padding: 10px 16px;
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--text-secondary);
    font-size: 14px;
    font-weight: 600;
    transition: all var(--transition-fast);
}

.btn-ghost:hover {
    background: var(--fantasma-hover, rgba(255, 255, 255, .06));
    color: var(--text-primary);
}

/* ---------- Badge de estado (distinto de .badge, que ya existe
   arriba como etiqueta tipo "AI Powered Platform" -- este es
   para estados de datos: aceptado/pendiente/rechazado/etc.) ---------- */

.status-badge {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 6px 14px;
    border-radius: var(--radius-pill);
    font-size: 13px;
    font-weight: 600;
    white-space: nowrap;
}

.status-badge-success { background: var(--success-bg); color: var(--success); }
.status-badge-warning { background: var(--warning-bg); color: var(--warning); }
.status-badge-danger  { background: var(--danger-bg);  color: var(--danger); }
.status-badge-info    { background: var(--info-bg);    color: var(--info); }
.status-badge-neutral { background: var(--neutral-bg); color: var(--neutral); }

/* ---------- Tabla de datos compartida (con overflow-x incorporado
   de fabrica -- mismo patron ya probado en expedientes.css) ---------- */

.table-wrap {
    max-width: 100%;
    overflow-x: auto;
    border-radius: var(--radius-lg);
}

.data-table {
    width: 100%;
    min-width: 560px;
    border-collapse: collapse;
}

.data-table thead {
    background: var(--bg-secondary);
}

.data-table thead th {
    text-align: left;
    padding: 10px 14px;
    color: var(--secondary-blue);
    /* 15 y no 13: la cabecera va en azul sobre fondo oscuro, asi que a
       igualdad de tamano pesa menos que el blanco de las celdas y se leia
       mas pequena de lo que era. Ahora queda un punto POR ENCIMA del
       cuerpo (14px), que es lo que compensa esa diferencia de contraste.
       Vale para las diez pantallas con tabla: la clase se define aqui una
       sola vez. */
    font-size: 15px;
    font-weight: 600;
    white-space: nowrap;
}

.data-table tbody td {
    padding: 10px 14px;
    font-size: 14px;
    border-top: 1px solid var(--glass-border);
    color: var(--text-primary);
}

.data-table tbody tr {
    transition: background var(--transition-fast);
}

/* Celda de acciones dentro de una tabla.

   Medido: la fila de /contratos ocupaba 145px, y 124 de esos eran la celda
   de Acciones -- tres enlaces en un flex con flex-wrap:wrap que, al no
   caber a lo ancho, se apilaban en vertical y estiraban TODA la fila. Con
   16 contratos eso son 2.320px de tabla.

   Cinco modulos repiten el mismo patron con distinto nombre de clase
   (contract-, document-, treatment-, evidence-, authorization-actions).
   La correccion va aqui una sola vez, acotada a celdas de tabla para no
   alcanzar a .detail-actions-buttons ni a .page-header-actions, que estan
   fuera de la tabla y si deben poder envolverse.

   Si la fila se queda sin ancho, quien se desplaza es .table-wrap, que ya
   trae overflow-x:auto. Una tabla algo mas ancha es mejor que filas de tres
   alturas. */
.data-table tbody td [class*="-actions"] {
    flex-wrap: nowrap;
    gap: 6px;
}

.data-table tbody td [class*="-actions"] .btn-ghost {
    padding: 5px 9px;
    font-size: 12.5px;
}

.data-table tbody tr:hover {
    background: var(--fila-hover, rgba(255, 255, 255, .04));
}

/* ---------- Enlace dentro de tabla ("Ver detalle ->") ----------
   Fase 4: mismo criterio visual que .records-back de expedientes.css
   (color de acento, sin subrayado) pero como componente compartido,
   para no repetir la regla en cada hoja de estilos de cada pantalla
   nueva que tenga una tabla con un enlace de detalle. */
.table-link {
    color: var(--secondary-blue);
    font-size: 14px;
    text-decoration: none;
    white-space: nowrap;
}

.table-link:hover {
    text-decoration: underline;
}

/* ---------- Campo de formulario (envoltorio de .input/.label) ---------- */

.form-field {
    display: grid;
    gap: 8px;
    text-align: left;
}

.form-field-row {
    display: flex;
    gap: 12px;
    flex-wrap: wrap;
}

.form-field-row > .form-field {
    flex: 1;
    min-width: 220px;
}

select.input {
    appearance: none;
    cursor: pointer;
}

/* ---------- Barra de filtros / busqueda ---------- */

.filter-bar {
    display: flex;
    flex-wrap: wrap;
    gap: 15px;
    margin-bottom: 16px;
}

.filter-bar .input {
    flex: 1;
    min-width: 200px;
}

/* ---------- Mensajes / avisos (distinto de .alert-item de
   dashboard.css, que es especifico de esa pantalla) ---------- */

/* Texto corrido, NO flex.

   Era `display:flex; align-items:flex-start; gap:10px`, pensado para un
   patron icono + texto. Ese patron no existe en el proyecto: de los 38
   .notice de las plantillas, NINGUNO tiene un hijo de bloque. El unico
   aviso con icono es .access-notice de login.html, que es otra clase con
   su propio CSS en login.css.

   Lo que si hacia el flex era romper los avisos con enfasis en linea. Un
   parrafo como el de identidad.html tiene cinco hijos -- tres trozos de
   texto y dos <strong> --, y flex los convertia en cinco columnas con
   10px de hueco entre ellas:

       Una validacion pertenece a la | empresa que la hizo | , no a la...

   Los huecos aparecian antes de la coma y de los dos puntos. Afectaba a 8
   avisos (identidad, identidad_detalle, firmas, documento_cliente_detalle).
   En los otros 30 no se notaba porque tienen un unico nodo de texto.

   El marcado de las plantillas era correcto; el defecto estaba aqui. */
.notice {
    padding: 14px 16px;
    border-radius: var(--radius-sm);
    font-size: 13px;
    line-height: 1.5;
    border: 1px solid transparent;
}

.notice-info    { background: var(--info-bg);    border-color: var(--info-borde, rgba(34,200,255,.24)); color: var(--text-secondary); }
.notice-success { background: var(--success-bg); border-color: var(--success-borde, rgba(0,212,126,.24));  color: var(--text-secondary); }
.notice-warning { background: var(--warning-bg); border-color: var(--warning-borde, rgba(255,200,87,.24)); color: var(--text-secondary); }
.notice-danger  { background: var(--danger-bg);  border-color: var(--danger-borde, rgba(255,77,109,.24)); color: var(--text-secondary); }

/* ---------- Estados vacio / error ---------- */

.empty-state,
.error-state {
    display: grid;
    justify-items: center;
    gap: 10px;
    padding: 60px 30px;
    text-align: center;
    color: var(--text-muted);
}

.empty-state strong,
.error-state strong {
    color: var(--text-primary);
    font-size: 18px;
}

.error-state {
    color: var(--danger);
}

/* ---------- Tarjeta de contenido (no-glass, para bloques densos
   como tablas o listas -- .glass-card sigue siendo la tarjeta
   con blur para pantallas tipo login/hero) ---------- */

.content-card {
    background: var(--bg-card);
    border: 1px solid var(--glass-border);
    border-radius: var(--radius-lg);
    padding: 18px;
    box-shadow: var(--sombra-tarjeta, none);
}

/* ---------- Modal ---------- */

.modal-backdrop {
    position: fixed;
    inset: 0;
    background: var(--velo-modal, rgba(4, 8, 25, .65));
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 50;
}

/* ---------------------------------------------------------------------------
   CAUSA RAIZ de "los menus estan congelados" y "el modal no se cierra".

   .modal-backdrop se escribio para un <div> de overlay. Aplicada a un
   <dialog>, su `display: flex` ANULA el `display: none` que el navegador da
   por defecto a un dialog SIN [open]. Resultado: cada dialog cerrado queda
   como una capa fija a pantalla completa con z-index 50, invisible por
   estar vacia pero interceptando todos los clics.

   Se comprobo con document.elementFromPoint sobre el enlace "Inicio" del
   sidebar: devolvia DIALOG#contract-anular-dialog, un modal CERRADO que
   medía 1122x479. Eso explica a la vez los menus que no responden, el
   scroll bloqueado y el modal que parece no cerrarse.

   Antes esto se parcheaba por ID en el CSS de cada modulo (cinco copias de
   la misma regla), asi que cualquier dialogo nuevo nacia roto. La regla
   vive aqui, una sola vez, y cubre los catorce dialogos.

   Se acota con dialog.modal-backdrop para no alterar el comportamiento si
   algun dia se usa .modal-backdrop sobre un <div>.
   --------------------------------------------------------------------- */
dialog.modal-backdrop:not([open]) {
    display: none;
}

dialog.modal-backdrop[open] {
    display: flex;
}

/* El <dialog> nativo trae margenes de UA que lo descentran dentro del
   flex, y un borde propio que no queremos. */
dialog.modal-backdrop {
    margin: 0;
    padding: 0;
    border: 0;
    max-width: none;
    max-height: none;
    width: 100%;
    height: 100%;
    background: var(--velo-modal, rgba(4, 8, 25, .65));
    color: inherit;
    overflow: hidden;   /* quien hace scroll es .modal-card, no el overlay */
}

/* La capa real del navegador queda detras; se oscurece igual por si el
   modal se abre con showModal() en un contexto sin el fondo propio. */
dialog.modal-backdrop::backdrop {
    background: var(--velo-modal-nativo, rgba(4, 8, 25, .45));
}

.modal-card {
    width: min(90%, 520px);
    max-height: 85vh;
    overflow-y: auto;
    padding: 30px;
    border-radius: var(--radius-lg);
    background: var(--bg-card);
    border: 1px solid var(--glass-border-active);
    box-shadow: var(--shadow-lg);
}

/* ---------- Breadcrumbs ---------- */

.breadcrumbs {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 10px;
    font-size: 13px;
    color: var(--text-muted);
}

.breadcrumbs a {
    color: var(--text-muted);
    text-decoration: none;
}

.breadcrumbs a:hover {
    color: var(--secondary-blue);
}

.breadcrumbs .current {
    color: var(--text-secondary);
}

/* ---------- Paginacion ---------- */

.pagination {
    display: flex;
    align-items: center;
    gap: 8px;
    justify-content: flex-end;
    margin-top: 20px;
}

.pagination button {
    min-width: 36px;
    height: 36px;
    border: 1px solid var(--glass-border);
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--text-secondary);
    cursor: pointer;
    transition: all var(--transition-fast);
}

.pagination button:hover {
    border-color: var(--secondary-blue);
    color: var(--text-primary);
}

.pagination button[aria-current="true"] {
    background: var(--button-gradient);
    border-color: transparent;
    color: white;
}

/* ---------- Tarjetas de resumen (stat cards) ----------
   Fase 4 (Bloque A, 2026-08-11): primer consumidor real de este
   archivo de componentes fuera de Fase 1 (que los dejo preparados
   mencionando explicitamente "Inicio, Empresas, Proyectos, Contratos
   ... se conectaran en las fases siguientes"). Mismo concepto que
   .records-summary/article de expedientes.css (Sprint 9), pero como
   componente compartido para que Empresas y Proyectos no dupliquen
   la misma tabla de estilos cada uno en su propio archivo. */

.stat-cards {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 16px;
    margin-bottom: 24px;
}

.stat-card {
    padding: 13px 16px;
    border: 1px solid var(--glass-border);
    border-radius: var(--radius-lg);
    background: var(--bg-card);
    box-shadow: var(--sombra-tarjeta, none);
}

.stat-card span { display: block; color: var(--text-muted); font-size: 13px; }
.stat-card strong { display: block; margin: 4px 0 2px; color: var(--text-primary); font-size: 23px; }
.stat-card small { display: block; color: var(--text-muted); font-size: 12px; }

/* ==========================================================
   APP-SHELL — patron unico de scroll de toda la plataforma
   (Fase B.5.4-C, 2026-08-15)

   Causa raiz corregida aqui: style.css define, de forma global,
   "body{overflow:hidden}" (necesario para la tarjeta centrada de "/" y
   "/login") y "main{height:100vh}". Con ese par, cualquier pagina cuyo
   contenido superara la altura de la ventana quedaba SIN scroll: ni
   rueda, ni touchpad, ni PageDown/End -- el contenido inferior era
   sencillamente inalcanzable (auditoria: hasta 1752px cortados a
   375px de ancho).

   Solucion: no se toca la regla global. Cada pagina autenticada marca
   su <main> con .app-shell-page y el scroll pasa a vivir DENTRO de su
   columna de contenido (.content / .page-content), que es la unica que
   crece. El sidebar queda fijo y scrollea aparte solo si su propio
   contenido no cabe.

   Se usan selectores "main.app-shell-page" (especificidad 0,1,1) a
   proposito: components.css se carga via @import desde style.css, es
   decir ANTES que los CSS por modulo (empresas.css, expedientes.css,
   proyectos.css...), que traen su propio "min-height:100vh". Con mayor
   especificidad estas reglas ganan sin depender del orden de carga y
   sin tener que editar cada archivo de modulo.

   Las barras de scroll siguen siendo las definidas mas arriba en este
   mismo archivo (::-webkit-scrollbar, 10px, pulgar morado): no se
   ocultan -- ahora por fin tienen algo que desplazar.
   ========================================================== */

body:has(.app-shell-page) {
    /* Era display:flex + height:100vh. Ese alto fijo era la razon de que el
       scroll tuviera que vivir en un contenedor interno. Ahora el body
       crece con su contenido y quien se desplaza es la PAGINA. */
    display: block;
    height: auto;
    min-height: 100vh;
}

/* Mientras haya un modal abierto se congela el fondo, para que la rueda no
   desplace la pagina de detras en vez del modal. Los <dialog> se abren con
   showModal(), asi que viven en el TOP LAYER: quedan por encima de todo sin
   depender de z-index, y el video de fondo no puede taparlos.
   Va en html y NO en body a proposito. Medido: con la regla en body el
   ancho util saltaba de 1270 a 1280px al abrir un modal. El motivo es que
   scrollbar-gutter:stable esta declarado en html, y solo reserva el hueco
   del elemento que lo declara; si quien pierde la barra es body, la
   reserva no le sirve de nada. Con las dos cosas en html, el hueco sigue
   reservado y el contenido no se mueve. */
html:has(dialog[open]) {
    overflow: hidden;
    padding-right: var(--hueco-barra, 0px);
}

/* El <main> exterior de base.html trae height:100vh de style.css; si
   ademas hubiera algo encima (un banner), 100vh + ese alto desbordaria
   y body{overflow:hidden} recortaria el final. Aqui reparte el alto
   disponible en vez de imponerlo. */
body:has(.app-shell-page) > main {
    height: auto;
    min-height: 100vh;
}

main.app-shell-page {
    display: flex;
    width: 100%;
    height: auto;
    min-height: 100vh;
    /* flex-start y no stretch: el sidebar se fija con position:sticky y
       para eso no puede estirarse hasta el alto TOTAL del documento -- si
       se estira, no le queda margen contra el que pegarse. */
    align-items: flex-start;
    /* Era overflow:hidden. Recortaba en seco lo que sobresaliera; ahora el
       desbordamiento vertical lo asume la pagina. */
    overflow: visible;
}

main.app-shell-page > .sidebar {
    flex-shrink: 0;
    /* El desplazamiento vive en .sidebar nav (app_shell.css explica por
       que: con el sidebar entero desplazandose, los enlaces pasaban por
       DETRAS del boton Salir y no recibian el clic). */
    overflow: hidden;
}

/* Solo en escritorio, donde el shell es una fila. A partir de 900px el
   sidebar pasa a ser una franja superior y ya tiene su propio sticky. */
@media (min-width: 901px) {
    main.app-shell-page > .sidebar {
        position: sticky;
        top: 0;
        height: 100vh;
        align-self: flex-start;
    }
}

/* Unico scroller de la pagina. .content lo usan expedientes/empresas/
   proyectos/inicio; .page-content lo usan contratos/documentos/
   tratamiento/evidencias/autorizaciones. */
main.app-shell-page > .content,
main.app-shell-page > .page-content {
    flex: 1 1 auto;

    /* min-width:0 es la pieza que impide el scroll horizontal de PAGINA.
       Sin el, un hijo flex no baja de su ancho de contenido: una tabla
       ancha ensancharia la columna, la columna ensancharia el shell y la
       ventana entera acabaria desplazandose de lado. Con min-width:0 la
       columna se queda en su sitio y quien se desplaza es .table-wrap,
       que ya trae overflow-x:auto. */
    min-width: 0;

    /* Ya no recorta ni desplaza: la pagina lo hace por el. overflow debe
       quedar visible en AMBOS ejes -- si uno se pone en hidden, el
       navegador convierte el otro en auto y volveria a haber un scroller
       interno aqui. */
    min-height: 0;
    overflow: visible;
}

/* La regla `main.app-shell-page > .page-content:focus { outline:none }`
   vivia aqui. Existia porque esas columnas llevaban tabindex="0" para
   poder recibir el foco y desplazarse con el teclado, y habia que quitarles
   el anillo de foco por no ser controles. Desde 1.4.0 desplaza la pagina,
   el tabindex desaparecio de las plantillas y la regla se quedo sin
   sujeto. */

/* ---------- Estructura de pagina de modulos ---------- */

.app-page {
    display: flex;
    width: 100%;
    min-height: 100vh;
    height: auto;
    align-self: flex-start;
    align-items: stretch;
}

.page-content {
    flex: 1;
    width: 100%;
    min-width: 0;
    padding: 22px 28px;
}

/* ==========================================================================
   Densidad (1.7.0)
   --------------------------------------------------------------------------
   Se hizo porque la aplicacion se estaba usando al 80% de zoom: la interfaz
   pedia mas alto del que cabia comodamente. Medido a 1025x805, /contratos
   ocupaba 920px repartidos asi: 64 de relleno de columna, 90 de cromo de
   navegacion (miga + Volver) ANTES del titulo, 130 de cabecera, 143 de
   tarjetas de estadistica y 493 de la tarjeta de contenido.

   Los recortes van donde de verdad pesaba: titulo 36->27, cifra de
   estadistica 30->23, celdas de tabla de 16px de relleno a 10 y de 16px de
   texto a 14 -- eso ultimo es lo que mas se notara cuando haya muchos
   registros. Nada baja de 13px, que es el limite que ya usaban los
   controles del propio sistema.

   Todo vive en esta hoja compartida: ni una plantilla ni una hoja de modulo
   se tocan.
   ========================================================================== */
.page-header {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 24px;
    margin-bottom: 16px;
}

.page-header h1 {
    margin: 0 0 6px;
    color: var(--color-titulo-pagina, var(--color-titulo, var(--text-primary)));
    font-size: clamp(21px, 2.4vw, 27px);
}

.page-header p {
    margin: 0;
    color: var(--text-muted);
    font-size: 13.5px;
    line-height: 1.5;
}

.page-header-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
}

.btn-link {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: auto;
    padding: 12px 18px;
    text-decoration: none;
    white-space: nowrap;
}

/* ---------- Responsive base para el sistema de componentes ---------- */

@media (max-width: 700px) {
    .filter-bar { flex-direction: column; }
    .form-field-row { flex-direction: column; }
    .pagination { justify-content: center; }
    .stat-cards { grid-template-columns: minmax(0, 1fr); }
    .page-content { padding: 18px 16px; }
    .page-header { flex-direction: column; align-items: flex-start; }
    .page-header-actions { width: 100%; }
    .page-header-actions .btn-link { width: 100%; }
}

@media (max-width: 900px) {
    .app-page { flex-direction: column; }
}

/* ==========================================================
   Fase 11 — Acciones de escritura en Documentos/Tratamiento/
   Evidencias/Autorizaciones (2026-08-11). Las 4 pantallas del
   Bloque 8-10 eran de solo consulta; esta fase agrega botones de
   accion (aceptar/rechazar/autorizar/revocar) dentro del modal de
   detalle ya existente de cada una, contra los PUT que las 4 APIs
   ya exponian. Mismo criterio de color que .status-badge-*, en
   formato boton. Aditivo: nada de lo de arriba se modifico.
   ========================================================== */

.btn-action {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    width: auto;
    padding: 10px 18px;
    border-radius: var(--radius-sm);
    border: 1px solid transparent;
    cursor: pointer;
    font-size: 14px;
    font-weight: 600;
    transition: all var(--transition-fast);
}

.btn-action:disabled { opacity: .5; cursor: not-allowed; }

.btn-action-success { background: var(--success-bg); border-color: var(--success-borde-accion, rgba(0,212,126,.30)); color: var(--success); }
.btn-action-success:hover:not(:disabled) { background: var(--success-bg-hover, rgba(0,212,126,.20)); }

.btn-action-warning { background: var(--warning-bg); border-color: var(--warning-borde-accion, rgba(255,200,87,.30)); color: var(--warning); }
.btn-action-warning:hover:not(:disabled) { background: var(--warning-bg-hover, rgba(255,200,87,.20)); }

.btn-action-danger { background: var(--danger-bg); border-color: var(--danger-borde-accion, rgba(255,77,109,.30)); color: var(--danger); }
.btn-action-danger:hover:not(:disabled) { background: var(--danger-bg-hover, rgba(255,77,109,.20)); }

/* ---------- Bloque de acciones dentro de un modal de detalle ---------- */

.detail-actions {
    display: grid;
    gap: 14px;
    padding-top: 18px;
    margin-top: 4px;
    border-top: 1px solid var(--glass-border);
}

.detail-actions-buttons { display: flex; flex-wrap: wrap; gap: 10px; }

.detail-actions-confirm { display: grid; gap: 12px; padding: 16px; border-radius: var(--radius-sm); background: var(--bg-secondary); }
.detail-actions-confirm p { margin: 0; color: var(--text-secondary); font-size: 14px; line-height: 1.5; }
.detail-actions-confirm-buttons { display: flex; flex-wrap: wrap; gap: 10px; }

.detail-actions-feedback:empty { display: none; }
.detail-actions-feedback .notice { margin: 0; }

@media (max-width: 700px) {
    .detail-actions-buttons { flex-direction: column; }
    .detail-actions-buttons .btn-action { width: 100%; }
    .detail-actions-confirm-buttons { flex-direction: column; }
    .detail-actions-confirm-buttons .btn-action,
    .detail-actions-confirm-buttons .btn-ghost { width: 100%; }
}

/* El estado vacio deja de ser solo una constatacion: ofrece la accion.
   El boton necesita separacion propia porque .empty-state apila su texto. */
.empty-state button {
    margin-top: 14px;
}

/* Modal en movil: a pantalla casi completa, con su propio scroll interno.
   Un modal de escritorio comprimido a 375px se rompe; aqui se le da el
   espacio que necesita en vez de encogerlo. */
@media (max-width: 640px) {
    .modal-card {
        width: 100%;
        max-height: 92vh;
        padding: 20px 18px;
        border-radius: var(--radius-lg) var(--radius-lg) 0 0;
    }

    dialog.modal-backdrop {
        align-items: flex-end;   /* hoja inferior: el pulgar llega */
    }
}

/* Volver: lo inyecta app.js a partir del ultimo enlace de la miga, asi que
   su destino siempre es una ruta real y nunca hay que mantenerlo a mano. */
.btn-volver {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    margin: 0 0 18px;
    padding: 6px 12px;
    border: 1px solid var(--border, #2A3560);
    border-radius: 999px;
    background: transparent;
    color: var(--text-muted, #97A6D8);
    font-size: .88rem;
    text-decoration: none;
    transition: border-color .15s ease, color .15s ease;
}

.btn-volver:hover,
.btn-volver:focus-visible {
    border-color: var(--primary, #4F7CFF);
    color: var(--text-primary, #fff);
}

/* ===========================================================================
   CORRECCIONES TRANSVERSALES DE FORMULARIOS Y MODALES
   =========================================================================== */

/* --- 1. El atributo hidden debe ganar SIEMPRE ------------------------------
   El navegador aplica display:none a [hidden] desde su hoja de usuario, que
   pierde contra cualquier display: de autor. Cuando .notice era
   display:flex (ya no lo es, ver su regla), los 23 avisos marcados hidden
   estaban PERMANENTEMENTE visibles: son esas
   barras de color vacias que aparecian encima del boton principal en los
   tres formularios. Lo mismo le pasaba a .form-field (el campo de identidad
   se veia aunque el nivel fuese "simple") y a .detalle-grid.

   Es el mismo fallo que tenia .modal-backdrop con <dialog>, en otra forma.
   Aqui !important es correcto: hidden significa "esto no es relevante
   ahora", y ninguna regla de presentacion deberia poder contradecirlo. */
[hidden] {
    display: none !important;
}

/* --- 2. Selectores legibles ------------------------------------------------
   .input usa background:rgba(255,255,255,.04) -- blanco translucido. En un
   <input> compone sobre la tarjeta oscura y se ve bien, pero el desplegable
   de un <select> lo pinta el sistema operativo SIN esa composicion: fondo
   casi blanco con color:#FFF encima. De ahi que "NIT" y "Manual" salieran
   ilegibles.

   La cura es un color OPACO, y repetirlo en <option> porque el popup nativo
   no hereda del select en todos los navegadores. */
select.input {
    background-color: var(--campo-opaco-bg, var(--bg-secondary));
    color: var(--text-primary);
    /* appearance:none quita la flecha del sistema; sin reponerla el campo no
       se distingue de un input de texto. SVG en linea: sin peticion extra. */
    background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='%2397A6D8' d='M1 1l5 5 5-5'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 16px center;
    padding-right: 42px;
}

select.input option,
select.input optgroup {
    background-color: var(--campo-opaco-bg, var(--bg-secondary));
    color: var(--text-primary);
}

select.input:disabled,
.input:disabled {
    opacity: .55;
    cursor: not-allowed;
}

/* Foco visible tambien en los select, no solo en los input de texto. */
select.input:focus-visible {
    outline: 2px solid var(--secondary-blue);
    outline-offset: 1px;
}

/* --- 3. Cabecera de modal, disponible en TODAS las pantallas ---------------
   .document-detail-header solo estaba definida en documentos.css, que unas
   pocas paginas cargan. Los modales nuevos usan esa clase desde hojas que no
   la incluyen, asi que el boton "Cerrar" caia al flujo normal y aparecia
   como texto suelto bajo el subtitulo. Se define aqui, que carga siempre. */
.document-detail-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 16px;
    margin-bottom: 18px;
}

.document-detail-header h2 {
    margin: 0 0 6px;
    color: var(--color-titulo-pagina, var(--color-titulo, var(--text-primary)));
}

.document-detail-header p {
    margin: 0;
    color: var(--text-muted);
}

/* --- 4. Modales altos: las acciones nunca fuera de alcance -----------------
   .modal-card ya se desplaza por dentro (max-height:85vh). Pero con un
   formulario largo -- el de solicitud de firma lo es -- el usuario no ve que
   hay botones mas abajo y cree que la pantalla esta rota.
   La fila de acciones se ancla al pie del area que se desplaza: siempre a la
   vista, con fondo opaco para que el contenido no se lea por detras. */
.modal-card .detail-actions-buttons {
    position: sticky;
    bottom: -30px;              /* compensa el padding inferior de .modal-card */
    margin: 18px -30px -30px;
    padding: 18px 30px;
    background: var(--bg-card);
    border-top: 1px solid var(--border, #2A3560);
    border-radius: 0 0 var(--radius-lg) var(--radius-lg);
    z-index: 1;
}

@media (max-width: 640px) {
    .modal-card .detail-actions-buttons {
        bottom: -20px;
        margin: 16px -18px -20px;
        padding: 16px 18px;
    }
}

/* El boton principal ocupa la fila entera en movil: es el que se busca. */
@media (max-width: 640px) {
    .detail-actions-buttons > .btn-primary {
        width: 100%;
    }
}

/* Pista de diagnostico bajo un error de carga: endpoint y codigo HTTP.
   No son secretos -- el usuario ya los ve en las herramientas del
   navegador -- y sin ellos un fallo de carga es indiagnosticable. */
.error-pista {
    display: inline-block;
    margin-top: 10px;
    padding: 4px 10px;
    border-radius: 6px;
    background: var(--codigo-bg, rgba(0, 0, 0, .28));
    color: var(--text-muted, #97A6D8);
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: .76rem;
}


/* ==========================================================================
   ICONOS SVG DEL PANEL  (macro partials/iconos.html)
   ==========================================================================
   Los pictogramas del panel dejaron de ser emojis: ahora son SVG de trazo
   con stroke="currentColor", asi que toman el color del elemento que los
   contiene y no imponen ninguno propio.

   Aqui solo se fija el TAMANO. El color no se toca en ningun sitio: es
   justamente lo que permite que el mismo trazo sirva en el sidebar, en un
   KPI y en un boton sin duplicar nada.

   Un SVG inline es display:inline por defecto y se asienta sobre la linea
   base del texto, lo que descuadraba la altura de los enlaces del sidebar.
   Por eso va como inline-flex con alineacion vertical explicita.
   ========================================================================== */
.evol-ico{
    width:1em;
    height:1em;
    flex:0 0 auto;
    display:inline-flex;
    vertical-align:-.125em;
}

/* Ranuras que ya tenian un tamano propio cuando el icono era un emoji:
   se conserva el mismo tamano visual para no mover la maqueta. */
.kpi-icon .evol-ico{ width:24px; height:24px; }
.ciclo-icono .evol-ico{ width:24px; height:24px; }
.module-panel-icon .evol-ico{ width:18px; height:18px; }
.protection-list-icon .evol-ico{ width:18px; height:18px; }
.institutional-banner-icon .evol-ico{ width:24px; height:24px; }
.recent-activity-icon .evol-ico{ width:17px; height:17px; }
.notification-btn .evol-ico{ width:18px; height:18px; }
.sidebar-logout-icon .evol-ico{ width:16px; height:16px; }

/* El enlace del sidebar pasa a ser una fila icono+texto. Solo alineacion:
   el relleno, el radio y el color siguen siendo los de app_shell.css. */
.sidebar nav a{
    display:flex;
    align-items:center;
    gap:10px;
}
.sidebar nav a .evol-ico{ width:18px; height:18px; }

.sidebar-logout{
    display:flex;
    align-items:center;
    gap:10px;
}

/* Titulos de pagina: el icono acompana al texto sin alterar su tamano. */
h1 .evol-ico{
    width:.85em;
    height:.85em;
    vertical-align:-.06em;
}
