/* =========================================================================
   REA - Red Educativa Arquidiocesana
   Sistema de Apoyo a la Gestión de Protección de Datos
   Hoja de estilos única (rediseño visual profesional 2026)
   ========================================================================= */

@import url('https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@500;600;700;800&family=Inter:wght@400;500;600;700&display=swap');

:root {
    /* Paleta corporativa REA */
    --rea-rojo:        #c8102e;
    --rea-rojo-vivo:   #e2263f;
    --rea-rojo-oscuro: #8f0a1f;
    --rea-rojo-claro:  #fdeaee;
    --rea-vino:        #5d0715;

    --rea-tinta:       #14161c;
    --rea-gris-900:    #1c1f27;
    --rea-gris-800:    #313743;
    --rea-gris-700:    #4c5462;
    --rea-gris-600:    #667085;
    --rea-gris-500:    #8a93a5;
    --rea-gris-300:    #d6dae3;
    --rea-gris-200:    #e6e9f0;
    --rea-gris-100:    #eef1f6;
    --rea-gris-50:     #f6f8fb;
    --rea-blanco:      #ffffff;

    --color-exito:     #12734a;
    --color-exito-bg:  #e4f7ec;
    --color-advertencia: #9a5b00;
    --color-advertencia-bg: #fdf2dd;
    --color-peligro:   #c8102e;
    --color-peligro-bg:#fdeaee;
    --color-info:      #0a5f9e;
    --color-info-bg:   #e5f1fb;

    --fuente-titulos: 'Plus Jakarta Sans', 'Segoe UI', system-ui, sans-serif;
    --fuente-base:    'Inter', 'Segoe UI', system-ui, sans-serif;

    --radio-sm: 8px;
    --radio-md: 14px;
    --radio-lg: 20px;

    --sombra-xs: 0 1px 2px rgba(20, 22, 28, .06);
    --sombra-sm: 0 1px 2px rgba(20, 22, 28, .05), 0 4px 12px -6px rgba(20, 22, 28, .10);
    --sombra-md: 0 10px 30px -12px rgba(20, 22, 28, .22);
    --sombra-lg: 0 28px 60px -24px rgba(20, 22, 28, .34);

    --anillo: 0 0 0 4px rgba(200, 16, 46, .14);
    --transicion: all .18s cubic-bezier(.4, 0, .2, 1);

    --gradiente-rojo: linear-gradient(135deg, var(--rea-rojo-vivo), var(--rea-rojo-oscuro));
    --gradiente-oscuro: linear-gradient(168deg, #23262f 0%, #16181e 48%, #0f1014 100%);

    --sidebar-ancho: 274px;
    --topbar-alto: 68px;
}

* { box-sizing: border-box; }

html, body {
    margin: 0;
    padding: 0;
    font-family: var(--fuente-base);
    background-color: var(--rea-gris-50);
    color: var(--rea-gris-900);
    font-size: 15px;
    line-height: 1.55;
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
}

h1, h2, h3, h4, h5 {
    font-family: var(--fuente-titulos);
    color: var(--rea-tinta);
    font-weight: 700;
    letter-spacing: -.015em;
    margin: 0 0 .5rem 0;
}
h1 { font-size: 1.6rem; }
h2 { font-size: 1.18rem; }

a { color: var(--rea-rojo); text-decoration: none; transition: var(--transicion); }
a:hover { color: var(--rea-rojo-oscuro); text-decoration: none; }

p { line-height: 1.6; }

hr { border: none; border-top: 1px solid var(--rea-gris-200); margin: 1.5rem 0; }

::selection { background: var(--rea-rojo-claro); color: var(--rea-rojo-oscuro); }

/* Scrollbar discreto */
* { scrollbar-width: thin; scrollbar-color: var(--rea-gris-300) transparent; }
*::-webkit-scrollbar { width: 9px; height: 9px; }
*::-webkit-scrollbar-thumb { background: var(--rea-gris-300); border-radius: 999px; }
*::-webkit-scrollbar-track { background: transparent; }

/* ---------- Utilidades ---------- */
.texto-mutado { color: var(--rea-gris-600); font-size: .875rem; }
.texto-centrado { text-align: center; }
.mt-0 { margin-top: 0 !important; }
.mb-0 { margin-bottom: 0 !important; }
.flex { display: flex; }
.flex-entre { display: flex; justify-content: space-between; align-items: center; gap: 12px; flex-wrap: wrap; }
.flex-gap { display: flex; gap: .6rem; flex-wrap: wrap; align-items: center; }
.w-100 { width: 100%; }

/* =========================================================================
   PANTALLA DE LOGIN
   ========================================================================= */
.login-body {
    font-family: var(--fuente-base);
    background: var(--gradiente-oscuro);
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 100vh;
    margin: 0;
    padding: 20px 16px;
    position: relative;
    overflow-x: hidden;
}
/* Los dos halos del fondo van FIJOS a la ventana, no al documento.
   Colocados en absolute con desplazamientos negativos —como estaban— el de
   abajo sobresalía 220 px por debajo del cuerpo y estiraba la página: aparecía
   barra de desplazamiento y el botón de Ingresar quedaba fuera de la vista,
   aunque la tarjeta cabía de sobra. Fijos adornan igual y no ocupan sitio. */
.login-body::before,
.login-body::after {
    content: '';
    position: fixed;
    border-radius: 50%;
    filter: blur(10px);
    pointer-events: none;
    z-index: 0;
}
.login-body::before {
    width: 620px; height: 620px;
    top: -260px; right: -180px;
    background: radial-gradient(circle at center, rgba(226, 38, 63, .38), transparent 68%);
}
.login-body::after {
    width: 520px; height: 520px;
    bottom: -220px; left: -160px;
    background: radial-gradient(circle at center, rgba(200, 16, 46, .22), transparent 70%);
}

.login-shell {
    width: 100%;
    max-width: 410px;
    position: relative;
    z-index: 1;
    animation: subir .5s cubic-bezier(.2, .8, .2, 1) both;
}

@keyframes subir {
    from { opacity: 0; transform: translateY(14px); }
    to   { opacity: 1; transform: none; }
}

/* Igual que en la barra lateral: el logotipo vive dentro de la tarjeta clara,
   no flotando como un recuadro blanco sobre el fondo oscuro. */
.login-logo-wrap {
    text-align: center;
    margin: 0 0 14px;
    padding-bottom: 12px;
    border-bottom: 1px solid var(--rea-gris-200);
}
.login-logo-wrap img {
    display: block;
    width: 60%;
    max-width: 190px;
    height: auto;
    margin: 0 auto;
}
.login-logo-wrap .lema {
    color: rgba(255, 255, 255, .78);
    font-family: var(--fuente-titulos);
    font-style: italic;
    font-weight: 500;
    font-size: .92rem;
    letter-spacing: .01em;
    margin-top: 10px;
}

.login-container {
    background: rgba(255, 255, 255, .98);
    padding: 24px 28px 26px;
    border-radius: var(--radio-lg);
    box-shadow: var(--sombra-lg);
    border: 1px solid rgba(255, 255, 255, .5);
    width: 100%;
    position: relative;
    overflow: hidden;
}
.login-container::before {
    content: '';
    position: absolute;
    inset: 0 0 auto 0;
    height: 4px;
    background: var(--gradiente-rojo);
}

.login-container h2 { text-align: center; margin: 0 0 4px; }
.login-titulo {
    font-family: var(--fuente-titulos);
    font-size: 1.22rem;
    font-weight: 800;
    text-align: center;
    color: var(--rea-tinta);
    margin: 0;
}
.login-subtitulo {
    text-align: center;
    color: var(--rea-gris-600);
    font-size: .86rem;
    margin: 6px 0 26px;
    line-height: 1.5;
}

.login-footer-nota {
    text-align: center;
    color: rgba(255, 255, 255, .62);
    font-size: .76rem;
    margin-top: 12px;
    letter-spacing: .01em;
}

/* ---------- El formulario de ingreso, apretado ----------
   Solo aquí: los formularios del sistema conviven con tablas y avisos y
   agradecen el aire; esta pantalla tiene que entrar entera de una vez, porque
   tener que desplazarse para encontrar el botón de Ingresar es lo primero que
   ve quien llega. */
.login-container .form-group { margin-bottom: 12px; }
.login-container .form-group:last-of-type { margin-bottom: 16px; }
.login-container label { margin-bottom: 4px; }

.login-container input[type=text],
.login-container input[type=password],
.login-container select {
    padding: 9px 12px;
}

.login-container .form-ayuda { margin-top: 4px; font-size: .74rem; }

/* El buscador vive DENTRO del grupo de la institución, sobre el desplegable al
   que filtra: como campo aparte se llevaba una etiqueta y un margen enteros
   para algo que no es un dato del formulario, sino una ayuda para elegirlo. */
.login-buscador { margin-bottom: 7px; }
.login-buscador[hidden] { display: none !important; }

.login-container .btn-submit { padding: 11px 16px; }

/* Ventanas bajas —un portátil con la barra de marcadores abierta— o teléfonos
   apaisados: se recorta lo prescindible antes que dejar el botón fuera. */
@media (max-height: 700px) {
    .login-body { padding: 12px 16px; }
    .login-container { padding: 18px 24px 20px; }
    .login-logo-wrap { margin-bottom: 10px; padding-bottom: 9px; }
    .login-logo-wrap img { max-width: 150px; }
    .login-container .form-group { margin-bottom: 9px; }
    .login-footer-nota { margin-top: 9px; font-size: .72rem; }
}

/* Teléfono en horizontal: quedan poco más de 400 px de alto. Se retira lo que
   solo acompaña —la nota del pie— para no dejar el botón debajo del borde. */
@media (max-height: 520px) {
    .login-body { padding: 8px 12px; align-items: flex-start; }
    .login-container { padding: 12px 20px 14px; }
    .login-logo-wrap { margin-bottom: 8px; padding-bottom: 7px; }
    .login-logo-wrap img { max-width: 120px; }
    .login-container .form-group { margin-bottom: 7px; }
    .login-container .form-group:last-of-type { margin-bottom: 11px; }
    .login-container label { margin-bottom: 3px; font-size: .78rem; }
    .login-container input[type=text],
    .login-container input[type=password],
    .login-container select { padding: 7px 11px; }
    .login-container .btn-submit { padding: 9px 16px; }
    .login-footer-nota { display: none; }
}

/* =========================================================================
   FORMULARIOS
   ========================================================================= */
.form-group { margin-bottom: 18px; }
.form-group label {
    display: block;
    margin-bottom: 6px;
    color: var(--rea-gris-800);
    font-weight: 600;
    font-size: .82rem;
    letter-spacing: .005em;
}
.form-row { display: flex; gap: 18px; flex-wrap: wrap; }
.form-row .form-group { flex: 1 1 220px; }

input[type=text], input[type=password], input[type=email], input[type=date],
input[type=datetime-local], input[type=number], input[type=search], input[type=tel],
select, textarea {
    width: 100%;
    padding: 11px 13px;
    border: 1px solid var(--rea-gris-300);
    border-radius: var(--radio-sm);
    font-size: .92rem;
    font-family: var(--fuente-base);
    background: var(--rea-blanco);
    color: var(--rea-gris-900);
    transition: var(--transicion);
    box-shadow: var(--sombra-xs);
}
input::placeholder, textarea::placeholder { color: var(--rea-gris-500); }
textarea { min-height: 96px; resize: vertical; }

select {
    appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%238a93a5' stroke-width='2.4' stroke-linecap='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 12px center;
    padding-right: 36px;
}

input:hover, select:hover, textarea:hover { border-color: var(--rea-gris-500); }
input:focus, select:focus, textarea:focus {
    outline: none;
    border-color: var(--rea-rojo);
    box-shadow: var(--anillo);
}

.form-ayuda { font-size: .78rem; color: var(--rea-gris-600); margin-top: 5px; }

/* Aviso de un campo mal escrito: lo ponen js/documento.js y js/correo.js justo
   debajo del campo, para que el motivo se lea sin buscarlo arriba. */
.form-error-campo {
    font-size: .78rem;
    font-weight: 600;
    color: var(--color-peligro);
    margin-top: 5px;
    line-height: 1.35;
}
.form-error-campo[hidden] { display: none !important; }

.campo-invalido,
input.campo-invalido:focus {
    border-color: var(--color-peligro) !important;
    box-shadow: 0 0 0 4px rgba(200, 16, 46, .12) !important;
}
.campo-requerido::after { content: " *"; color: var(--rea-rojo); }

fieldset {
    border: 1px solid var(--rea-gris-200);
    border-radius: var(--radio-md);
    padding: 18px 18px 6px;
    margin: 0 0 20px 0;
    background: var(--rea-gris-50);
}
fieldset legend {
    font-family: var(--fuente-titulos);
    font-weight: 700;
    color: var(--rea-rojo-oscuro);
    padding: 2px 10px;
    font-size: .78rem;
    text-transform: uppercase;
    letter-spacing: .06em;
    background: var(--rea-blanco);
    border: 1px solid var(--rea-gris-200);
    border-radius: 999px;
}

.check-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
    gap: 10px 16px;
}
.check-item {
    display: flex; align-items: center; gap: 9px;
    font-size: .88rem;
    padding: 8px 10px;
    background: var(--rea-blanco);
    border: 1px solid var(--rea-gris-200);
    border-radius: var(--radio-sm);
    transition: var(--transicion);
}
.check-item:hover { border-color: var(--rea-gris-300); box-shadow: var(--sombra-xs); }
.check-item input { width: auto; box-shadow: none; }

/* ---------- Instituciones de una cuenta de usuario ----------
   Veintiún bloques abiertos a la vez no se leen. Cada institución es un
   <details> que se abre solo si la cuenta entra en ella, así se ve de un
   vistazo dónde alcanza y los roles quedan a un clic. Sin JavaScript: el
   desplegable es del propio navegador. */
.instituciones-lista {
    display: flex;
    flex-direction: column;
    gap: 8px;
    max-height: 420px;
    overflow-y: auto;
    padding-right: 4px;
}
.institucion-bloque {
    border: 1px solid var(--rea-gris-200);
    border-radius: var(--radio-sm);
    background: var(--rea-blanco);
}
.institucion-bloque > summary {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 10px;
    padding: 8px 12px;
    cursor: pointer;
    font-size: .88rem;
}
.institucion-bloque > summary::-webkit-details-marker { display: none; }
.institucion-bloque > summary::before {
    content: '▸';
    color: var(--rea-gris-400, #9aa0a6);
    font-size: .8rem;
}
.institucion-bloque[open] > summary::before { content: '▾'; }
/* La casilla vive dentro del resumen: se marca sin desplegar el bloque. */
.institucion-bloque > summary .check-item {
    border: 0;
    background: transparent;
    padding: 0;
}
.institucion-bloque > summary .check-item:hover { box-shadow: none; }
.institucion-bloque[open] > summary { border-bottom: 1px solid var(--rea-gris-200); }
.institucion-bloque > .check-grid,
.institucion-bloque > p { padding: 12px; margin: 0; }
/* Las instituciones a las que la cuenta entra se distinguen de un vistazo, sin
   tener que leer casilla por casilla cuál está marcada. */
.institucion-bloque:has(input[name="instituciones[]"]:checked) {
    border-color: var(--rea-rojo);
    background: var(--rea-gris-50, #fafafa);
}
#filtro_instituciones { margin-bottom: 10px; }
input[type=checkbox], input[type=radio] { accent-color: var(--rea-rojo); width: 16px; height: 16px; }

/* ---------- Botones ---------- */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    padding: 10px 18px;
    border: 1px solid transparent;
    border-radius: var(--radio-sm);
    font-size: .86rem;
    font-weight: 600;
    font-family: var(--fuente-base);
    cursor: pointer;
    text-decoration: none !important;
    transition: var(--transicion);
    line-height: 1.2;
    white-space: nowrap;
}
.btn:active { transform: translateY(1px); }

.btn-submit, .btn-primario {
    background: var(--gradiente-rojo);
    color: var(--rea-blanco);
    box-shadow: 0 8px 18px -10px rgba(200, 16, 46, .8);
}
.btn-submit:hover, .btn-primario:hover {
    color: #fff;
    filter: brightness(1.06);
    box-shadow: 0 12px 24px -10px rgba(200, 16, 46, .85);
}
.login-container .btn-submit { width: 100%; padding: 13px; font-size: .95rem; letter-spacing: .01em; }

.btn-secundario {
    background: var(--rea-blanco);
    color: var(--rea-gris-800);
    border-color: var(--rea-gris-300);
    box-shadow: var(--sombra-xs);
}
.btn-secundario:hover { background: var(--rea-gris-50); color: var(--rea-gris-900); border-color: var(--rea-gris-500); }

.btn-peligro { background: var(--color-peligro); color: #fff; }
.btn-peligro:hover { background: var(--rea-rojo-oscuro); color: #fff; }

.btn-exito { background: var(--color-exito); color: #fff; }
.btn-exito:hover { background: #0d5b3a; color: #fff; }

.btn-sm { padding: 6px 11px; font-size: .78rem; border-radius: 7px; }
.btn-icono { padding: 7px 9px; }
.btn:disabled { opacity: .5; cursor: not-allowed; box-shadow: none; }

.logout-btn {
    display: inline-flex;
    align-items: center;
    /* Separa el icono del texto. Cuando en el teléfono el texto se oculta, el
       hueco desaparece solo: `gap` no deja aire donde no hay dos cosas. */
    gap: 6px;
    padding: 8px 15px;
    background: var(--rea-blanco);
    border: 1px solid var(--rea-gris-300);
    color: var(--rea-gris-800);
    border-radius: var(--radio-sm);
    font-size: .82rem;
    font-weight: 600;
    box-shadow: var(--sombra-xs);
}
.logout-btn:hover { background: var(--rea-rojo); border-color: var(--rea-rojo); color: #fff; text-decoration: none; }

/* ---------- Alertas / mensajes ---------- */
.alerta, .error-msg {
    padding: 13px 16px;
    border-radius: var(--radio-sm);
    margin-bottom: 18px;
    font-size: .87rem;
    border: 1px solid transparent;
    border-left-width: 4px;
    box-shadow: var(--sombra-xs);
}
.error-msg, .alerta-error {
    background: var(--color-peligro-bg); color: var(--rea-rojo-oscuro);
    border-color: #f6ccd4; border-left-color: var(--rea-rojo);
}
.alerta-exito { background: var(--color-exito-bg); color: var(--color-exito); border-color: #c3ead4; border-left-color: var(--color-exito); }
.alerta-info { background: var(--color-info-bg); color: var(--color-info); border-color: #c7e2f6; border-left-color: var(--color-info); }
.alerta-advertencia { background: var(--color-advertencia-bg); color: var(--color-advertencia); border-color: #f2dcb0; border-left-color: var(--color-advertencia); }

/* =========================================================================
   LAYOUT INTERNO (sidebar + topbar + contenido)
   ========================================================================= */
.app-shell { display: flex; min-height: 100vh; }

.sidebar {
    width: var(--sidebar-ancho);
    flex-shrink: 0;
    background: var(--gradiente-oscuro);
    color: var(--rea-gris-100);
    padding: 20px 14px 28px;
    position: sticky;
    top: 0;
    height: 100vh;
    overflow-y: auto;
    border-right: 1px solid rgba(255, 255, 255, .06);
}
/* El logotipo institucional es de tinta oscura sobre fondo claro. En lugar de
   recortarlo como un recuadro blanco sobre la barra oscura, la cabecera de la
   barra es una banda clara a sangre: el logotipo descansa sobre ella sin marco
   ni sombra y no se percibe ningún contraste. */
.sidebar-logo {
    margin: -20px -14px 16px;              /* a sangre: anula el padding de .sidebar */
    padding: 10px 16px;
    min-height: var(--topbar-alto);        /* misma altura que la barra superior */
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 4px;
    background: var(--rea-blanco);
    border-bottom: 1px solid var(--rea-gris-200);
    text-align: center;
}
.sidebar-logo img {
    display: block;
    width: 78%;
    max-width: 172px;
    height: auto;
}
.sidebar-lema {
    color: var(--rea-gris-500);
    font-family: var(--fuente-titulos);
    font-size: .62rem;
    font-style: italic;
    font-weight: 500;
    letter-spacing: .01em;
    line-height: 1.2;
}

.nav-seccion { margin-bottom: 4px; }
.nav-titulo {
    text-transform: uppercase;
    font-size: .66rem;
    letter-spacing: .11em;
    color: rgba(255, 255, 255, .38);
    padding: 16px 12px 7px;
    font-weight: 700;
}
.nav-link {
    display: flex;
    align-items: center;
    gap: 11px;
    padding: 10px 12px;
    border-radius: 10px;
    color: rgba(255, 255, 255, .76);
    font-size: .86rem;
    font-weight: 500;
    margin-bottom: 2px;
    position: relative;
    transition: var(--transicion);
}
.nav-link:hover { background: rgba(255, 255, 255, .07); color: #fff; text-decoration: none; }
.nav-link.activo {
    background: linear-gradient(100deg, rgba(226, 38, 63, .95), rgba(143, 10, 31, .95));
    color: #fff;
    font-weight: 600;
    box-shadow: 0 10px 22px -14px rgba(226, 38, 63, .95);
}
.nav-link.activo::before {
    content: '';
    position: absolute;
    left: -14px; top: 50%;
    transform: translateY(-50%);
    width: 3px; height: 22px;
    border-radius: 0 3px 3px 0;
    background: #fff;
}
.nav-link .icono { width: 20px; text-align: center; font-size: .98rem; opacity: .95; }

.nav-grupo > summary { cursor: pointer; list-style: none; }
.nav-grupo > summary::-webkit-details-marker { display: none; }
.nav-grupo > summary .flecha { margin-left: auto; transition: var(--transicion); font-size: .62rem; opacity: .6; }
.nav-grupo[open] > summary .flecha { transform: rotate(90deg); }
.nav-grupo .nav-sub {
    padding-left: 14px;
    margin: 2px 0 6px 12px;
    border-left: 1px solid rgba(255, 255, 255, .1);
}
.nav-grupo .nav-sub .nav-link { font-size: .83rem; padding: 8px 10px; }

.main-area { flex: 1; min-width: 0; display: flex; flex-direction: column; }

/* `min-height`, no `height`: con una altura fija el nombre de una institución
   larga se partía en dos líneas y se salía de la barra, encima de la miga de
   pan. Ahora la barra crece lo que haga falta y el nombre se recorta con
   puntos suspensivos cuando no cabe. */
.topbar {
    min-height: var(--topbar-alto);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 14px;
    padding: 0 24px;
    background: rgba(255, 255, 255, .88);
    backdrop-filter: blur(10px);
    border-bottom: 1px solid var(--rea-gris-200);
    position: sticky;
    top: 0;
    z-index: 30;
}
.topbar > .flex-gap { min-width: 0; flex: 1 1 auto; }
.topbar > .flex-gap > div { min-width: 0; overflow: hidden; }

.topbar-titulo {
    font-family: var(--fuente-titulos);
    font-weight: 700;
    color: var(--rea-tinta);
    font-size: 1.02rem;
    letter-spacing: -.01em;
    /* Bloque, no flex: `text-overflow: ellipsis` no funciona sobre un contenedor
       flexible, y aquí lo que hace falta es justamente que el nombre de una
       institución larga termine en puntos suspensivos en vez de cortarse a
       mitad de letra. La pastilla de «otra institución» va en línea. */
    display: block;
    min-width: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    padding-right: 6px;
}
.topbar-eyebrow {
    display: block;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    font-family: var(--fuente-base);
    font-size: .66rem;
    font-weight: 700;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--rea-rojo);
    margin-bottom: 1px;
}
.topbar-usuario { display: flex; align-items: center; gap: 14px; flex-shrink: 0; }
.avatar-usuario {
    width: 38px; height: 38px; border-radius: 50%;
    background: var(--gradiente-rojo); color: #fff;
    display: flex; align-items: center; justify-content: center;
    font-weight: 700; font-size: .84rem;
    box-shadow: 0 8px 18px -10px rgba(200, 16, 46, .9);
    flex-shrink: 0;
}
.usuario-meta { font-size: .74rem; color: var(--rea-gris-600); line-height: 1.35; }
.usuario-meta strong { color: var(--rea-gris-900); font-size: .85rem; font-weight: 600; }

.content-wrap { padding: 28px 24px 8px; max-width: 1320px; width: 100%; margin: 0 auto; }

.breadcrumb { font-size: .78rem; color: var(--rea-gris-500); margin-bottom: 16px; }
.breadcrumb a { color: var(--rea-gris-600); }
.breadcrumb a:hover { color: var(--rea-rojo); }
.breadcrumb .actual { color: var(--rea-gris-900); font-weight: 600; }

.page-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    flex-wrap: wrap;
    gap: 14px;
    margin-bottom: 24px;
    padding-bottom: 18px;
    border-bottom: 1px solid var(--rea-gris-200);
}
.page-header h1 { font-size: 1.55rem; }
.page-header p { color: var(--rea-gris-600); margin: 6px 0 0; font-size: .88rem; }

/* En los reportes esta franja solo lleva las acciones: el título y la
   descripción los da la cabecera del reporte. Sin texto a la izquierda, los
   botones se van al borde derecho y la línea divisoria sobra. */
.page-header-acciones {
    justify-content: flex-end;
    border-bottom: 0;
    padding-bottom: 0;
    margin-top: -6px;
    margin-bottom: 18px;
}

/* ---------- Tarjetas ---------- */
.card {
    background: var(--rea-blanco);
    border: 1px solid var(--rea-gris-200);
    border-radius: var(--radio-md);
    box-shadow: var(--sombra-sm);
    padding: 22px;
    margin-bottom: 22px;
}
.card h3 {
    margin-top: 0;
    color: var(--rea-tinta);
    font-size: 1rem;
    padding-bottom: 12px;
    margin-bottom: 14px;
    border-bottom: 1px solid var(--rea-gris-100);
}
.card-titulo-icono { display: flex; align-items: center; gap: 9px; }

.menu-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(262px, 1fr)); gap: 20px; }
.card-modulo {
    position: relative;
    border: 1px solid var(--rea-gris-200);
    border-radius: var(--radio-md);
    padding: 22px;
    background: var(--rea-blanco);
    box-shadow: var(--sombra-sm);
    transition: var(--transicion);
    overflow: hidden;
}
.card-modulo::after {
    content: '';
    position: absolute;
    inset: auto 0 0 0;
    height: 3px;
    background: var(--gradiente-rojo);
    transform: scaleX(0);
    transform-origin: left;
    transition: var(--transicion);
}
.card-modulo:hover {
    box-shadow: var(--sombra-md);
    transform: translateY(-3px);
    border-color: var(--rea-gris-300);
}
.card-modulo:hover::after { transform: scaleX(1); }
.card-modulo .icono-modulo {
    width: 46px; height: 46px; border-radius: 13px;
    background: var(--rea-rojo-claro); color: var(--rea-rojo);
    display: flex; align-items: center; justify-content: center;
    font-size: 1.25rem; margin-bottom: 14px;
    border: 1px solid #f7d3da;
}
.card-modulo h3 { margin: 0 0 6px; font-size: 1.02rem; color: var(--rea-tinta); border: none; padding: 0; }
.card-modulo p { font-size: .84rem; color: var(--rea-gris-600); margin: 0 0 14px; }
.card-modulo ul { list-style: none; margin: 0; padding: 0; }
.card-modulo ul li { margin-bottom: 6px; }
.card-modulo ul li a {
    font-size: .85rem; font-weight: 600;
    display: inline-flex; align-items: center; gap: 6px;
}
.card-modulo ul li a::before { content: '›'; color: var(--rea-gris-500); font-weight: 700; }
.card-modulo ul li a:hover::before { color: var(--rea-rojo); }

/* ---------- KPIs / estadísticas ---------- */
.kpi-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(206px, 1fr)); gap: 18px; margin-bottom: 26px; }
.kpi-card {
    position: relative;
    background: var(--rea-blanco);
    border: 1px solid var(--rea-gris-200);
    border-radius: var(--radio-md);
    padding: 20px;
    box-shadow: var(--sombra-sm);
    overflow: hidden;
    transition: var(--transicion);
}
.kpi-card::before {
    content: '';
    position: absolute;
    inset: 0 auto 0 0;
    width: 4px;
    background: var(--gradiente-rojo);
}
.kpi-card:hover { transform: translateY(-2px); box-shadow: var(--sombra-md); }
.kpi-card .kpi-valor {
    font-family: var(--fuente-titulos);
    font-size: 2.1rem;
    font-weight: 800;
    letter-spacing: -.03em;
    color: var(--rea-tinta);
    line-height: 1.1;
}
.kpi-card .kpi-label {
    font-size: .72rem;
    color: var(--rea-gris-600);
    text-transform: uppercase;
    letter-spacing: .09em;
    font-weight: 700;
    margin-top: 6px;
}
.kpi-card.kpi-alt-1::before { background: linear-gradient(180deg, #2b8ed6, var(--color-info)); }
.kpi-card.kpi-alt-2::before { background: linear-gradient(180deg, #23a06a, var(--color-exito)); }
.kpi-card.kpi-alt-3::before { background: linear-gradient(180deg, #d99420, var(--color-advertencia)); }

/* ---------- Tablas ---------- */
/* Las tablas de datos tienen más columnas de las que caben en un teléfono. Se
   desplazan de lado, y para que se note —una tabla cortada sin aviso parece una
   tabla incompleta— llevan una sombra en el borde por el que continúan, que
   desaparece sola al llegar al extremo. Es puro CSS: las dos primeras capas van
   ancladas al contenido (`local`) y las dos sombras al marco (`scroll`), de modo
   que una tapa a la otra según cuánto se haya desplazado. */
.tabla-wrap {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    background-color: var(--rea-blanco);
    background-image:
        linear-gradient(to right, var(--rea-blanco) 30%, rgba(255, 255, 255, 0)),
        linear-gradient(to left,  var(--rea-blanco) 30%, rgba(255, 255, 255, 0)),
        radial-gradient(farthest-side at 0 50%,   rgba(20, 22, 28, .16), rgba(20, 22, 28, 0)),
        radial-gradient(farthest-side at 100% 50%, rgba(20, 22, 28, .16), rgba(20, 22, 28, 0));
    background-repeat: no-repeat;
    background-size: 38px 100%, 38px 100%, 13px 100%, 13px 100%;
    background-position: left center, right center, left center, right center;
    background-attachment: local, local, scroll, scroll;
    border-radius: var(--radio-md);
    border: 1px solid var(--rea-gris-200);
    box-shadow: var(--sombra-sm);
}
table.tabla-datos { width: 100%; border-collapse: collapse; font-size: .84rem; }
table.tabla-datos th {
    background: var(--rea-gris-50);
    color: var(--rea-gris-700);
    text-align: left;
    padding: 9px 8px;
    font-weight: 700;
    font-size: .70rem;
    text-transform: uppercase;
    letter-spacing: .03em;
    border-bottom: 1px solid var(--rea-gris-200);
    position: sticky;
    top: 0;
}
table.tabla-datos td {
    padding: 9px 8px;
    border-bottom: 1px solid var(--rea-gris-100);
    color: var(--rea-gris-800);
    vertical-align: middle;
}
table.tabla-datos th:first-child, table.tabla-datos td:first-child { padding-left: 14px; }
table.tabla-datos th:last-child, table.tabla-datos td:last-child { padding-right: 14px; }
table.tabla-datos tbody tr { transition: var(--transicion); }
table.tabla-datos tbody tr:hover { background: var(--rea-gris-50); }
table.tabla-datos tbody tr:last-child td { border-bottom: none; }
.tabla-acciones { display: flex; gap: 6px; flex-wrap: nowrap; }
.tabla-vacia { text-align: center; padding: 54px 20px; color: var(--rea-gris-500); font-size: .9rem; }

/* ---------- Badges / estado ---------- */
.badge {
    display: inline-flex; align-items: center; gap: 5px;
    padding: 4px 11px;
    border-radius: 999px;
    font-size: .72rem;
    font-weight: 700;
    letter-spacing: .02em;
    border: 1px solid transparent;
    text-transform: uppercase;
}
.badge-activo { background: var(--color-exito-bg); color: var(--color-exito); border-color: #c3ead4; }
.badge-inactivo { background: var(--color-peligro-bg); color: var(--rea-rojo-oscuro); border-color: #f6ccd4; }
.badge-neutro { background: var(--rea-gris-100); color: var(--rea-gris-700); border-color: var(--rea-gris-200); }
.badge-info { background: var(--color-info-bg); color: var(--color-info); border-color: #c7e2f6; }
.badge-sensible { background: #fde3e6; color: #a3122c; border-color: #f3b7bd; }
/* Una cuenta de otra institución que viene de visita: no es un error ni un
   estado malo, es un dato que conviene ver antes de abrirla. */
.badge-advertencia { background: var(--color-advertencia-bg, #fdf3d8); color: #8a6100; border-color: #f0dcae; }

/* ---------- Filtros de búsqueda ---------- */
.filtros-bar {
    display: flex;
    gap: 14px;
    flex-wrap: wrap;
    align-items: flex-end;
    background: var(--rea-blanco);
    border: 1px solid var(--rea-gris-200);
    border-radius: var(--radio-md);
    padding: 18px;
    margin-bottom: 20px;
    box-shadow: var(--sombra-sm);
}
.filtros-bar .form-group { margin-bottom: 0; min-width: 190px; }

/* ---------- Paginación ---------- */
/* Una sola línea: la ventana de números cabe siempre, y si la lista continúa se
   dice con los puntos suspensivos, el número del final y el resumen. */
.paginacion { display: flex; gap: 6px; justify-content: center; align-items: center; margin: 22px 0; flex-wrap: nowrap; }
.paginacion a, .paginacion span {
    padding: 7px 13px; border-radius: 8px; font-size: .82rem; font-weight: 600;
    border: 1px solid var(--rea-gris-200); color: var(--rea-gris-700);
    background: var(--rea-blanco);
    white-space: nowrap;
}
.paginacion a:hover { background: var(--rea-gris-50); border-color: var(--rea-gris-300); text-decoration: none; }
.paginacion .pagina-actual { background: var(--gradiente-rojo); color: #fff; border-color: transparent; }
/* Corte de la serie: no es un botón, solo el aviso de que faltan páginas. */
.paginacion .pagina-corte {
    border-color: transparent; background: none; color: var(--rea-gris-500);
    padding-left: 2px; padding-right: 2px; letter-spacing: 1px;
}
/* Flecha del extremo: se ve, pero no lleva a ninguna parte. */
.paginacion .pagina-inerte { color: var(--rea-gris-300); background: var(--rea-gris-50); }
.paginacion .pagina-resumen {
    border-color: transparent; background: none; color: var(--rea-gris-600);
    font-weight: 500; margin-left: 4px;
}
@media (max-width: 640px) {
    /* En pantalla estrecha manda el resumen: los números se recortan solos. */
    .paginacion { overflow-x: auto; justify-content: flex-start; }
    .paginacion .pagina-resumen { position: sticky; right: 0; background: var(--rea-blanco); }
}

/* ---------- Encabezado de formulario ----------
   Título a la izquierda, botón de volver a la derecha, siempre a la vista. */
.form-encabezado {
    display: flex; align-items: center; justify-content: space-between;
    gap: 12px; flex-wrap: wrap; margin-bottom: 14px;
}
.form-encabezado h3 { margin: 0; }

/* ---------- Campos que no se editan ----------
   Se usan en los mantenimientos cuyas altas vienen de la Carga de Información y
   en el identificador de la institución, que asigna la base. Van deshabilitados,
   así que no viajan en el envío: lo que se ve es solo para leer. */
.campo-bloqueado,
input.campo-bloqueado:disabled,
select.campo-bloqueado:disabled {
    background: #f1f3f6;
    color: #55606f;
    border-style: dashed;
    cursor: not-allowed;
    opacity: 1;                 /* Safari los apaga demasiado */
    -webkit-text-fill-color: #55606f;
}
.bloque-persona-bloqueado > legend::after { content: ' 🔒'; font-size: .85em; }

/* ---------- Pestañas ---------- */
.tabs { display: flex; gap: 6px; border-bottom: 1px solid var(--rea-gris-200); margin-bottom: 20px; flex-wrap: wrap; }
.tab-link {
    padding: 10px 16px; font-size: .85rem; color: var(--rea-gris-600);
    border-bottom: 2px solid transparent; margin-bottom: -1px; font-weight: 600;
}
.tab-link.activo, .tab-link:hover { color: var(--rea-rojo); border-bottom-color: var(--rea-rojo); text-decoration: none; }

/* ---------- Timeline (historial) ---------- */
.timeline { list-style: none; margin: 0; padding: 0; }
.timeline li { position: relative; padding: 0 0 22px 28px; border-left: 2px solid var(--rea-gris-200); margin-left: 6px; }
.timeline li:last-child { border-color: transparent; padding-bottom: 0; }
.timeline li::before {
    content: ''; position: absolute; left: -7px; top: 4px;
    width: 12px; height: 12px; border-radius: 50%;
    background: var(--rea-rojo); border: 2px solid #fff; box-shadow: 0 0 0 3px var(--rea-rojo-claro);
}
.timeline .t-fecha { font-size: .74rem; color: var(--rea-gris-500); font-weight: 500; }
.timeline .t-titulo { font-weight: 700; color: var(--rea-gris-900); font-size: .88rem; }
.timeline .t-detalle { font-size: .82rem; color: var(--rea-gris-700); }

/* ---------- Pie ---------- */
.footer-app {
    text-align: center;
    color: var(--rea-gris-500);
    font-size: .75rem;
    padding: 26px 0 20px;
    margin-top: 10px;
    border-top: 1px solid var(--rea-gris-200);
}

/* =========================================================================
   RESPONSIVE
   =========================================================================
   El sistema se usa en el escritorio de la secretaría, pero también desde el
   teléfono de quien está de pie en el patio comprobando un dato. Lo que sigue
   es lo que cambia cuando la pantalla se estrecha.
   ========================================================================= */

/* ---------- Tableta y teléfono: el menú pasa a ser un cajón ---------- */
@media (max-width: 900px) {
    .sidebar {
        position: fixed;
        top: 0;
        left: -100%;
        height: 100dvh;              /* dvh: descuenta la barra del navegador móvil */
        max-width: 86vw;
        z-index: 60;
        box-shadow: var(--sombra-lg);
        transition: left .22s ease;
    }
    .sidebar.abierto { left: 0; }
    .app-shell { display: block; }
    .content-wrap { padding: 20px 16px 4px; }
    .topbar { padding: 8px 14px; }
    .menu-toggle { display: inline-flex !important; }
    .usuario-meta { display: none; }
    .page-header h1 { font-size: 1.3rem; }
    .kpi-card .kpi-valor { font-size: 1.8rem; }

    /* Fondo oscurecido bajo el cajón: lo crea js/menu_movil.js y es lo que se
       toca para cerrarlo. Sin él el menú tapaba la pantalla sin salida visible. */
    .menu-fondo {
        position: fixed;
        inset: 0;
        z-index: 55;
        background: rgba(20, 22, 28, .5);
        backdrop-filter: blur(2px);
        border: 0;
        padding: 0;
        cursor: pointer;
        animation: aparecer .18s ease-out;
    }
    .menu-fondo[hidden] { display: none !important; }
    body.menu-abierto { overflow: hidden; }
}
@keyframes aparecer { from { opacity: 0; } to { opacity: 1; } }

/* ---------- Teléfono ---------- */
@media (max-width: 640px) {
    .topbar { gap: 10px; }
    /* El botón del menú y el nombre de la institución, en la misma línea: con el
       ajuste automático el título caía debajo y la barra ocupaba el doble.
       El antetítulo «PROTECCIÓN DE DATOS» se retira: en un teléfono se lleva una
       línea entera para decir algo que ya dice la pantalla en la que se está. */
    .topbar > .flex-gap { flex-wrap: nowrap; }
    .topbar-eyebrow { display: none; }
    .topbar-eyebrow { font-size: .6rem; letter-spacing: .09em; }
    .topbar-titulo { font-size: .92rem; }
    .topbar-usuario { gap: 8px; }
    .avatar-usuario { width: 32px; height: 32px; font-size: .78rem; }
    /* El texto de los botones de la barra sobra: quedan el icono y el título */
    .logout-btn { padding: 7px 10px; font-size: .76rem; }
    /* Lo que solo cabe cuando hay ancho. El botón conserva su title y su
       aria-label, así que sigue diciendo lo que hace. */
    .solo-ancho { display: none; }

    .content-wrap { padding: 16px 12px 4px; }
    .page-header { flex-direction: column; align-items: stretch; gap: 10px; }
    .page-header h1 { font-size: 1.18rem; }
    .page-header .flex-gap > .btn { flex: 1 1 auto; justify-content: center; }

    /* Los filtros dejan de competir por el ancho y se apilan */
    .filtros-bar { padding: 14px; gap: 10px; }
    .filtros-bar .form-group { min-width: 100%; }
    .filtros-bar .btn { width: 100%; justify-content: center; }
    .filtros-bar form.flex-gap { width: 100%; }

    .card { padding: 16px 14px; }

    /* Una columna. Se nombra a TODOS los hijos, no solo a los .form-group: en la
       ficha 360° las parejas etiqueta/valor son divs sueltos, y al compartir
       línea el correo y el teléfono aparecían pegados uno detrás de otro.

       `.form-row .form-group` se repite aparte a propósito: la regla base le da
       `flex: 1 1 220px` con dos clases de especificidad, y un `.form-row > *`
       —que solo lleva una— perdería. Sin esto, los filtros de los informes se
       quedaban en 47 px de ancho y desbordaban la página. */
    .form-row { gap: 10px 16px; }
    .form-row > * { flex: 1 1 100%; min-width: 0; }
    .form-row .form-group { flex: 1 1 100%; min-width: 0; margin-bottom: 6px; }
    /* Un correo largo parte donde haga falta antes que desbordar la tarjeta. */
    .ficha-identidad .form-row strong { overflow-wrap: anywhere; }

    table.tabla-datos { font-size: .8rem; }
    table.tabla-datos th, table.tabla-datos td { padding: 9px 10px; }

    /* La columna de acciones se queda pegada al borde derecho mientras el resto
       de la tabla se desplaza por debajo. En un teléfono, «Editar» quedaba fuera
       de la pantalla y había que arrastrar la tabla a ciegas para encontrarlo;
       así está siempre donde el pulgar la espera.

       Solo en las tablas que tienen acciones: en las que terminan en «Estado»
       fijar la última columna no aportaría nada. */
    table.tabla-datos:has(.tabla-acciones) th:last-child,
    table.tabla-datos:has(.tabla-acciones) td:last-child {
        position: sticky;
        right: 0;
        z-index: 1;
        background: var(--rea-blanco);
        box-shadow: -9px 0 12px -9px rgba(20, 22, 28, .28);
    }
    table.tabla-datos:has(.tabla-acciones) th:last-child { background: var(--rea-gris-50); }
    table.tabla-datos tr.fila-activa td:last-child { background: var(--rea-rojo-claro); }

    .sp-modal__cabecera h3 { font-size: .9rem; }
    .ficha-modal .sp-modal__cuerpo { padding: 12px; }
    .footer-app { padding: 18px 0 14px; font-size: .7rem; }
}

/* ---------- Dedos, no ratón ----------
   28 px de alto se aciertan con el cursor y se fallan con el pulgar.

   Se pregunta por el TIPO DE PUNTERO —una tableta de 1024 px se toca igual que
   un teléfono— y TAMBIÉN por el ancho, porque no todos los navegadores informan
   bien del puntero y quedarse sin la regla es peor que aplicarla de más: en una
   ventana estrecha de escritorio, unos botones algo mayores no estorban. */
@media (pointer: coarse), (max-width: 900px) {
    .btn-sm { padding: 9px 13px; font-size: .8rem; }
    .btn-icono { padding: 10px 12px; }
    .paginacion a, .paginacion span { padding: 10px 14px; }
    .tab-link { padding: 12px 16px; }
    .nav-link { padding: 11px 12px; }

    /* En los listados, las acciones de cada fila se reparten en dos líneas
       antes que encogerse: es preferible una fila más alta a un botón que se
       falla. */
    .tabla-acciones { flex-wrap: wrap; gap: 6px; }

    /* La barra de formato del disclaimer: son los botones más pequeños del
       sistema y los que peor se aciertan con el pulgar. Se nombra también al
       contenedor `.editor` porque la regla base se declara más abajo en este
       mismo archivo y, a igual especificidad, ganaría la última. */
    .editor .editor-barra button { padding: 9px 12px; }
    .editor .editor-barra { gap: 6px; }
}

.menu-toggle {
    display: none;
    align-items: center; justify-content: center;
    width: 40px; height: 40px;
    border-radius: 10px; border: 1px solid var(--rea-gris-200);
    background: var(--rea-blanco); cursor: pointer; font-size: 1.1rem;
    color: var(--rea-gris-800);
    box-shadow: var(--sombra-xs);
    transition: var(--transicion);
}
.menu-toggle:hover { background: var(--rea-gris-50); }

/* ---------- Impresión (reportes) ---------- */
@media print {
    .sidebar, .topbar, .no-imprimir, .footer-app { display: none !important; }
    .app-shell, .main-area, .content-wrap { display: block; width: 100%; padding: 0; margin: 0; max-width: none; }
    body { background: #fff; }
    .card, .tabla-wrap, .kpi-card { box-shadow: none; break-inside: avoid; }
}

/* =========================================================================
   CABECERA DE REPORTE (logotipo e institución)
   =========================================================================
   La misma que lleva el PDF. En pantalla acompaña sin robar protagonismo al
   título de la página; al imprimir es lo primero de la hoja. */
.reporte-cabecera {
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 14px 18px;
    margin-bottom: 18px;
    background: var(--rea-blanco);
    border: 1px solid var(--rea-gris-200);
    border-left: 5px solid var(--rea-rojo);
    border-radius: var(--radio-sm);
}
/* En PANTALLA el escudo y el nombre de la institución no se dibujan: la barra
   superior ya los muestra en todas las páginas, y repetirlos aquí hacía que el
   mismo nombre se leyera dos veces en la misma pantalla. En PAPEL sí hacen
   falta —ahí no hay barra superior— y vuelven a aparecer en el @media print de
   más abajo. El PDF descargado no depende de esta hoja: arma su propia
   cabecera en includes/pdf_reporte.php. */
/* Los archivos miden 150x150: la medida se fija por los dos lados para que el
   escudo no crezca por su cuenta y desbarate la cabecera. */
.reporte-logo {
    display: none;
    width: 58px !important;
    height: 58px !important;
    max-width: 58px;
    object-fit: contain;
    flex: 0 0 auto;
}
.reporte-identidad { flex: 1; min-width: 0; }
.reporte-institucion {
    display: none;
    font-size: .95rem;
    font-weight: 700;
    color: var(--rea-rojo);
    line-height: 1.25;
}
.reporte-titulo {
    font-size: 1.05rem;
    margin: 2px 0 0;
    color: var(--rea-gris-700);
}
.reporte-subtitulo {
    margin: 2px 0 0;
    font-size: .85rem;
    color: var(--rea-gris-500);
}
.reporte-emision {
    flex: 0 0 auto;
    text-align: right;
    font-size: .78rem;
    color: var(--rea-gris-500);
    line-height: 1.4;
}

/* En pantallas estrechas la cabecera se apila y la fecha de emisión pasa a
   ocupar el ancho, alineada a la izquierda como el resto. */
@media (max-width: 640px) {
    .reporte-cabecera { flex-wrap: wrap; gap: 12px; padding: 12px 14px; }
    .reporte-logo { width: 44px; height: 44px; }
    .reporte-identidad { flex: 1 1 60%; }
    .reporte-emision { flex: 1 1 100%; text-align: left; }
}

/* En papel, la cabecera encabeza la hoja sin caja ni fondo, que solo gastan
   tinta, y se queda pegada a lo que sigue.
   Va DESPUÉS de las reglas de arriba a propósito: con la misma especificidad
   gana la última, y puesta antes no anulaba nada. */
@media print {
    /* El rastro de navegación es para moverse por el sitio; en una hoja de papel
       no lleva a ninguna parte y además repite el nombre del reporte, que ya da
       la cabecera. */
    .breadcrumb { display: none !important; }

    /* Sin barra superior en la hoja, la identificación del documento tiene que
       estar aquí: quién lo emite y con qué escudo. */
    .reporte-logo { display: block; }
    .reporte-institucion { display: block; }

    .reporte-cabecera {
        border: 0;
        border-bottom: 2px solid #000;
        border-radius: 0;
        background: none;
        padding: 0 0 10px;
        margin: 0 0 14px;
        break-after: avoid;
    }
    .reporte-emision { color: #000; }
}

/* =========================================================================
   SELECTOR DE PERSONA (campo con búsqueda en subpantalla)
   ========================================================================= */
.selector-persona {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 10px 8px 14px;
    border: 1px solid var(--rea-gris-300);
    border-radius: var(--radio-sm);
    background: var(--rea-gris-50);
    box-shadow: var(--sombra-xs);
    transition: var(--transicion);
}
.selector-persona.tiene-valor { background: var(--rea-blanco); border-color: var(--rea-gris-300); }
.selector-persona:focus-within { border-color: var(--rea-rojo); box-shadow: 0 0 0 3px var(--rea-rojo-claro); }

.selector-persona__valor { flex: 1; min-width: 0; line-height: 1.3; }
.selector-persona__nombre {
    display: block;
    font-size: .92rem;
    font-weight: 600;
    color: var(--rea-gris-500);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.selector-persona.tiene-valor .selector-persona__nombre { color: var(--rea-gris-900); }
.selector-persona__detalle { display: block; font-size: .76rem; color: var(--rea-gris-600); }
.selector-persona__detalle:empty { display: none; }

.selector-persona__acciones { display: flex; gap: 6px; flex-shrink: 0; }
.selector-persona__limpiar[hidden] { display: none; }

/* Aviso cuando se intenta guardar sin haber elegido persona */
.selector-persona.sp-invalido {
    border-color: var(--color-peligro);
    background: var(--color-peligro-bg);
    animation: sp-latido .4s ease-in-out 2;
}
@keyframes sp-latido {
    0%, 100% { transform: translateX(0); }
    25%      { transform: translateX(-4px); }
    75%      { transform: translateX(4px); }
}

/* ---------- Subpantalla (modal) ---------- */
.sp-sin-scroll { overflow: hidden; }

.sp-modal {
    position: fixed;
    inset: 0;
    z-index: 1000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px;
}
.sp-modal[hidden] { display: none; }

.sp-modal__fondo {
    position: absolute;
    inset: 0;
    background: rgba(20, 22, 28, .55);
    backdrop-filter: blur(2px);
}

.sp-modal__caja {
    position: relative;
    width: min(860px, 100%);
    max-height: min(90vh, 720px);
    display: flex;
    flex-direction: column;
    background: var(--rea-blanco);
    border-radius: var(--radio-md, 12px);
    box-shadow: 0 20px 55px rgba(20, 22, 28, .32);
    overflow: hidden;
    animation: sp-entrada .16s ease-out;
}
@keyframes sp-entrada {
    from { opacity: 0; transform: translateY(-10px) scale(.99); }
    to   { opacity: 1; transform: none; }
}

.sp-modal__cabecera {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 15px 20px;
    background: var(--rea-rojo);
    color: #fff;
}
.sp-modal__cabecera h3 { margin: 0; font-size: 1rem; font-weight: 600; color: #fff; }
.sp-modal__cerrar {
    background: transparent;
    border: 1px solid rgba(255, 255, 255, .55);
    color: #fff;
    border-radius: 6px;
    width: 30px;
    height: 30px;
    cursor: pointer;
    font-size: .85rem;
    line-height: 1;
}
.sp-modal__cerrar:hover { background: var(--rea-rojo-oscuro); }

.sp-modal__buscador {
    display: flex;
    gap: 10px;
    padding: 15px 20px;
    border-bottom: 1px solid var(--rea-gris-200);
    background: var(--rea-gris-50);
}
.sp-modal__buscador input { flex: 1; margin: 0; }

.sp-modal__cuerpo { overflow-y: auto; padding: 4px 20px 12px; }
.sp-modal__cuerpo .sp-tabla { margin-top: 8px; }
.sp-modal__cuerpo .sp-tabla th { position: sticky; top: 0; z-index: 1; }

.sp-fila { cursor: pointer; }
.sp-fila:hover, .sp-fila:focus { background: var(--rea-rojo-claro); outline: none; }
.sp-col-accion { text-align: right; white-space: nowrap; }
.sp-error { color: var(--color-peligro); font-weight: 600; }

.sp-modal__pie {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 13px 20px;
    border-top: 1px solid var(--rea-gris-200);
    background: var(--rea-gris-50);
}
.sp-modal__conteo { font-size: .8rem; color: var(--rea-gris-600); }

@media (max-width: 620px) {
    .sp-modal { padding: 10px; }
    .sp-modal__caja { max-height: 95vh; }
    .sp-modal__cuerpo { padding: 4px 12px 12px; }
    .selector-persona { flex-wrap: wrap; }
}

/* ---------- Ficha 360° como subpantalla (consultas/buscar_persona.php) -------
   Reutiliza el modal de arriba. Lo que cambia: la caja es más ancha porque la
   ficha lleva cuatro tarjetas y una tabla, y tanto el cerrar como el fondo son
   ENLACES —no botones—, para que la pantalla siga funcionando sin JavaScript. */
.sp-modal__caja--ancha { width: min(1040px, 100%); max-height: min(92vh, 860px); }

a.sp-modal__cerrar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    text-decoration: none;
}
a.sp-modal__cerrar:hover { color: #fff; }

.ficha-modal .sp-modal__cuerpo { padding: 18px 20px 20px; background: var(--rea-gris-50); }
.ficha-modal .sp-modal__cuerpo > .card,
.ficha-modal .sp-modal__cuerpo > .menu-grid { margin-bottom: 16px; }

/* Las cuatro tarjetas de rol en dos filas de dos: con el ancho de la caja,
   auto-fit dejaba tres arriba y una sola abajo. */
.ficha-modal .menu-grid { grid-template-columns: repeat(2, 1fr); gap: 14px; }
.ficha-modal .menu-grid .card { margin: 0; padding: 14px 16px; }
.ficha-modal .menu-grid .card h3 { font-size: .95rem; }
.ficha-modal .menu-grid .card p { margin: 6px 0; }

@media (max-width: 720px) {
    .ficha-modal .menu-grid { grid-template-columns: 1fr; }
}
.ficha-modal .sp-modal__cuerpo > :last-child { margin-bottom: 0; }

.ficha-identidad {
    background: var(--rea-blanco);
    border: 1px solid var(--rea-gris-200);
    border-left: 4px solid var(--rea-rojo);
    border-radius: var(--radio-md, 12px);
    padding: 16px 18px;
    margin-bottom: 16px;
}

/* La fila del listado que está abierta en la ficha, para no perder el sitio
   al cerrar la subpantalla. */
.fila-activa > td { background: var(--rea-rojo-claro); }

/* =========================================================================
   Carga Inicial (modules/carga_inicial.php)
   ========================================================================= */

/* Tarjeta de advertencia del paso destructivo */
.card-peligro {
    border: 1px solid #f0b7c1;
    border-left: 5px solid var(--color-peligro);
    background: linear-gradient(180deg, var(--color-peligro-bg) 0%, #fff 90px);
}
.card-peligro h3 { color: var(--rea-rojo-oscuro); }

/* Listas de apoyo dentro de las tarjetas */
.lista-simple {
    margin: 8px 0 14px;
    padding-left: 20px;
    color: #34495e;
    font-size: .9rem;
    line-height: 1.65;
}
.lista-simple li { margin-bottom: 4px; }

.lista-errores {
    margin: 8px 0 12px;
    padding-left: 20px;
    max-height: 320px;
    overflow-y: auto;
    color: var(--rea-rojo-oscuro);
    font-size: .87rem;
    line-height: 1.6;
}
.lista-errores li { margin-bottom: 5px; }

/* Casilla de confirmación */
.form-check label {
    display: flex;
    align-items: flex-start;
    gap: 9px;
    font-weight: 500;
    color: #2c3e50;
    cursor: pointer;
}
.form-check input[type="checkbox"] {
    width: 17px;
    height: 17px;
    margin-top: 1px;
    accent-color: var(--color-peligro);
    cursor: pointer;
}

/* Campo de archivo */
input[type="file"] {
    width: 100%;
    padding: 9px 11px;
    border: 1px dashed #c9ced6;
    border-radius: 9px;
    background: #fbfcfd;
    font-size: .88rem;
    cursor: pointer;
}
input[type="file"]:hover { border-color: var(--rea-rojo); background: #fff; }

.btn:disabled,
.btn[disabled] { opacity: .5; cursor: not-allowed; }

/* Logotipo de la institución activa en la barra superior. Sustituyó a la
   pastilla de «otra institución»: el escudo se reconoce antes que un nombre
   largo, y no gasta el ancho que en un teléfono hace falta para el nombre.

   Los archivos miden 150×150, así que la medida se fija por los dos lados y
   además se acota contra la altura de la barra: pase lo que pase, el escudo no
   puede salirse de ella. El `!important` no es capricho —es la única forma de
   que una regla posterior de `img` no vuelva a estirarlo—. */
.topbar-logo {
    width: 38px !important;
    height: 38px !important;
    max-width: 38px;
    max-height: calc(var(--topbar-alto) - 20px);
    object-fit: contain;
    flex: 0 0 auto;
}

/* En el teléfono se encoge, pero se queda: es lo que identifica la institución
   de un vistazo, justo cuando el nombre tiene que recortarse.
   Va DESPUÉS de la regla de arriba a propósito: con la misma especificidad gana
   la última, y puesta antes —que es donde estaba— no llegaba a aplicarse. */
@media (max-width: 640px) {
    .topbar-logo { width: 30px !important; height: 30px !important; max-width: 30px; }
}
/* El bloque del nombre se queda con el ancho que sobra, y `min-width: 0` es lo
   que permite que un nombre largo se recorte con puntos suspensivos en vez de
   empujar la barra entera. */
.topbar > .flex-gap:first-child { flex: 1 1 auto; min-width: 0; }
.topbar-identidad { flex: 1 1 auto; min-width: 0; }


/* =========================================================================
   Editor de texto enriquecido (modules/disclaimers.php)
   ========================================================================= */

.editor {
    border: 1px solid var(--rea-gris-300);
    border-radius: var(--radio-md);
    overflow: hidden;
    background: #fff;
}
.editor:focus-within { border-color: var(--rea-rojo); box-shadow: 0 0 0 3px var(--rea-rojo-claro); }

.editor-barra {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 4px;
    padding: 8px 10px;
    background: var(--rea-gris-50);
    border-bottom: 1px solid var(--rea-gris-200);
}
.editor-barra button {
    padding: 6px 10px;
    border: 1px solid transparent;
    border-radius: var(--radio-sm);
    background: transparent;
    color: var(--rea-gris-800);
    font-family: var(--fuente-base);
    font-size: .82rem;
    cursor: pointer;
    transition: var(--transicion);
}
.editor-barra button:hover {
    background: #fff;
    border-color: var(--rea-gris-300);
    color: var(--rea-rojo-oscuro);
}
.editor-separador {
    width: 1px;
    height: 20px;
    margin: 0 4px;
    background: var(--rea-gris-300);
}

.editor-area {
    min-height: 320px;
    max-height: 560px;
    overflow-y: auto;
    padding: 18px 20px;
    font-size: .95rem;
    line-height: 1.7;
    color: var(--rea-gris-800);
}
.editor-area:focus { outline: none; }
.editor-area p  { margin: 0 0 12px; }
.editor-area h2 { font-size: 1.15rem; margin: 18px 0 10px; color: var(--rea-tinta); }
.editor-area h3 { font-size: 1rem;    margin: 16px 0 8px;  color: var(--rea-tinta); }
.editor-area ul,
.editor-area ol { margin: 0 0 12px; padding-left: 24px; }
.editor-area li { margin-bottom: 4px; }
.editor-area a  { color: var(--rea-rojo); }
.editor-area:empty::before {
    content: 'Escriba aquí el texto de la política…';
    color: var(--rea-gris-500);
}

/* Vista previa del disclaimer */
.vista-previa {
    padding: 20px 24px;
    border: 1px dashed var(--rea-gris-300);
    border-radius: var(--radio-md);
    background: var(--rea-gris-50);
    color: var(--rea-gris-800);
    line-height: 1.7;
}
.vista-previa h2 { font-size: 1.15rem; margin: 16px 0 10px; }
.vista-previa h2:first-child { margin-top: 0; }
.vista-previa ul, .vista-previa ol { padding-left: 24px; }

/* =========================================================================
   Enlaces públicos con verificación (modules/enlaces_verificados.php)
   ========================================================================= */

.caja-enlace {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin: 12px 0 6px;
}
.caja-enlace input {
    flex: 1 1 320px;
    padding: 10px 13px;
    border: 1px solid var(--rea-gris-300);
    border-radius: var(--radio-sm);
    background: var(--rea-gris-50);
    font-family: ui-monospace, 'Cascadia Code', Consolas, monospace;
    font-size: .84rem;
    color: var(--rea-gris-800);
}
.caja-enlace input:focus {
    outline: none;
    border-color: var(--rea-rojo);
    background: #fff;
}

/* --- Bloque de datos personales (includes/campos_persona.php) --------------
   Lo usan Empleados, Estudiantes —titular y representante— y Proveedores, que
   capturan los datos de la persona en su propio formulario. */
.bloque-persona {
    border: 1px solid var(--color-borde, #e6e9f0);
    border-radius: 10px;
    padding: 14px 18px 4px;
    margin: 0 0 18px;
    background: #fcfdff;
}
.bloque-persona > legend {
    font-size: .82rem;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--rea-azul, #1f4e79);
    padding: 0 8px;
}
.bloque-persona-ayuda { margin: 0 0 12px; }


/* ===========================================================================
   Validación de campos y política de contraseñas
   ---------------------------------------------------------------------------
   Se usan en el formulario de usuarios (modules/usuarios.php) y en cualquier
   campo que la API haya rechazado.
   =========================================================================== */

/* Campo que la API rechazó. El color no es la única señal: el mensaje concreto
   aparece siempre arriba del formulario, para quien no distingue los colores. */
.campo-error,
.campo-error-vivo,
input.campo-error,
input.campo-error-vivo,
select.campo-error {
    border-color: var(--color-peligro);
    background: var(--color-peligro-bg);
}
.campo-error:focus,
.campo-error-vivo:focus {
    outline: 2px solid var(--color-peligro);
    outline-offset: 1px;
}

.campo-aviso {
    color: var(--color-peligro);
    font-weight: 600;
}

/* --- Bloque de contraseña --- */
.bloque-clave {
    border: 1px solid var(--rea-gris-200);
    border-radius: 10px;
    padding: 14px 16px 16px;
    margin: 0 0 18px;
    background: var(--rea-gris-50);
}
.bloque-clave > legend {
    font-weight: 700;
    color: var(--rea-gris-800);
    font-size: .9rem;
    padding: 0 8px;
}

/* --- Lista de condiciones --- */
.lista-reglas {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: 4px 18px;
}
.regla-clave {
    font-size: .8rem;
    color: var(--rea-gris-600);
    display: flex;
    align-items: center;
    gap: 6px;
}
.regla-clave .regla-marca {
    font-weight: 700;
    width: 1em;
    text-align: center;
}
.regla-clave.cumple { color: var(--color-exito); }
.regla-clave.falta  { color: var(--color-peligro); }

/* --- Contraseña recién generada --- */
.clave-generada {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    margin: 0 0 14px;
    padding: 12px 14px;
    border: 1px solid #cfe0f2;
    border-radius: 8px;
    background: var(--color-info-bg);
}
.clave-generada-etiqueta { font-size: .82rem; color: var(--rea-gris-700); font-weight: 600; }
.clave-generada-valor {
    font-family: ui-monospace, 'Cascadia Code', Consolas, monospace;
    font-size: 1.02rem;
    font-weight: 700;
    letter-spacing: .06em;
    color: var(--rea-tinta);
    background: var(--rea-blanco);
    border: 1px solid var(--rea-gris-300);
    border-radius: 6px;
    padding: 4px 10px;
    user-select: all;
}
.clave-generada .form-ayuda { flex-basis: 100%; margin: 0; }

/* `display:flex` de arriba gana al display:none que el navegador aplica por el
   atributo hidden; sin esto el recuadro se vería vacío desde el primer momento. */
.clave-generada[hidden] { display: none; }
.campo-aviso[hidden]    { display: none; }

.lista-errores { margin: 6px 0 0; padding-left: 20px; }
.lista-errores li { margin: 2px 0; }
