/* ============================================================
   MARSUPIA · assets/css/style.css
   Identidad de marca aplicada al panel — tokens tomados del Manual
   de Identidad v1 (pino/menta/arena/papel/tinta/salvia/bruma/miel),
   no de la web pública actual (que usa una tinta y una tipografía
   de texto distintas — ver README, "Rediseño con identidad de
   marca"). Tipografía: Fraunces (títulos) + Hanken Grotesk (texto),
   cargadas en includes/header.php y en las páginas de auth sueltas.

   SIN MODO OSCURO A PROPÓSITO (2026-07-13): el panel no sigue
   prefers-color-scheme. En modo oscuro, sidebar + contenido + tarjetas
   terminaban siendo variaciones del mismo verde — monocromático, sin
   la variedad cálida (arena/blanco/verde/miel) que sí tienen el editor
   de Bitácora/Brújula y la web pública real de Marsupia, ninguno de
   los cuales cambia con el tema del sistema tampoco. Se sigue el mismo
   criterio acá: una sola paleta cálida siempre, para que el panel se
   sienta como el mismo producto en todas sus pantallas.
   ============================================================ */
:root {
    /* Marca */
    --pino: #035159;
    --pino-2: #739CA6;
    --menta: #42B8C4;
    --menta-dark: #35939D;
    --arena: #E2DFD4;
    --papel: #F7F2EA;
    --tinta: #0C2427;
    --salvia: #6F827E;
    --bruma: #DCEAEA;
    --miel: #E6B45C;
    --clay: #B5533C;

    /* Semántico */
    --bg: var(--papel);
    --card-bg: #ffffff;
    --text: var(--tinta);
    --text-muted: var(--salvia);
    --border: rgba(3, 81, 89, .14);
    --link: var(--pino);
    --accent: var(--menta);
    --accent-ink: var(--pino);
    --danger: var(--clay);
    --success-bg: rgba(66, 184, 196, .18);
    --success-text: var(--pino);
    --error-bg: rgba(181, 83, 60, .14);
    --error-text: #7A3625;
    --warn-bg: rgba(230, 180, 92, .2);
    --warn-text: #7A5416;
    --chrome: var(--pino);
    --chrome-2: var(--pino-2);
    --chrome-ink: var(--papel);
    --chrome-muted: var(--bruma);
    --radius: 20px;
    --radius-sm: 12px;
}

* { box-sizing: border-box; }

body {
    margin: 0;
    font-family: 'Hanken Grotesk', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    background: var(--bg);
    color: var(--text);
}

h1, h2, h3 { font-family: 'Fraunces', Georgia, serif; font-weight: 600; letter-spacing: -.01em; margin: 0; }

a { color: var(--link); text-decoration: none; }
a:hover { text-decoration: underline; }
::selection { background: var(--menta); color: var(--pino); }
:focus-visible { outline: 2.5px solid var(--menta); outline-offset: 2px; border-radius: 4px; }

/* ---------- Auth pages (login / forgot / reset) ---------- */
.auth-body {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 100vh;
    padding: 20px;
    background: var(--pino);
}

.auth-card {
    width: 100%;
    max-width: 380px;
    background: var(--card-bg);
    border-radius: var(--radius);
    padding: 36px 32px;
    box-shadow: 0 1px 3px rgba(0, 0, 0, .08), 0 24px 60px -20px rgba(0, 0, 0, .45);
}

.auth-brand {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 22px;
}
.auth-brand span {
    font-family: 'Fraunces', Georgia, serif;
    font-weight: 600;
    font-size: 19px;
    color: var(--link);
    letter-spacing: -.01em;
}

.auth-card h1 {
    margin: 0 0 4px;
    font-size: 24px;
    color: var(--link);
}

.subtitle {
    color: var(--text-muted);
    margin: 0 0 20px;
    font-size: 14px;
}

.link-muted {
    display: inline-block;
    margin-top: 16px;
    font-size: 14px;
    color: var(--text-muted);
}
.link-muted:hover { color: var(--link); }

/* ---------- Forms ---------- */
form label {
    display: block;
    font-size: 13px;
    font-weight: 600;
    color: var(--text);
    margin: 14px 0 6px;
}

form input[type="text"],
form input[type="email"],
form input[type="password"],
form input[type="date"],
form input[type="number"],
form textarea,
form select {
    width: 100%;
    padding: 10px 13px;
    border: 1.5px solid var(--border);
    border-radius: 10px;
    font-size: 14px;
    /* Fondo siempre blanco (no sigue el tema oscuro) — el texto tiene que
       quedar siempre oscuro para que se pueda leer, nunca var(--text)
       (que en modo oscuro es claro, casi ilegible sobre blanco). */
    background: #fff;
    color: #0C2427;
    font-family: inherit;
}

form textarea {
    resize: vertical;
    line-height: 1.5;
}

/* ---------- Código de verificación (2FA) — 6 casillas ----------
   Usado en login.php (paso de verificación al iniciar sesión) y en
   2fa-setup.php (activación). El valor final viaja al servidor
   igual que antes, concatenado a mano por assets/js/otp-input.js en
   un input hidden — el backend no cambió. */
.otp-input {
    display: flex;
    gap: 8px;
    margin: 6px 0 4px;
}
.otp-input .otp-box {
    flex: 1 1 0;
    min-width: 0;
    max-width: 48px;
    aspect-ratio: 1 / 1;
    text-align: center;
    font-size: 22px;
    font-weight: 600;
    padding: 0;
    letter-spacing: 0;
}
.otp-input .otp-box:focus {
    outline: none;
    border-color: var(--menta);
    box-shadow: 0 0 0 3px rgba(66, 184, 196, .3);
}
@media (max-width: 400px) {
    .otp-input { gap: 6px; }
    .otp-input .otp-box { font-size: 18px; max-width: 42px; }
}

.password-field {
    position: relative;
}
.password-field input[type="password"],
.password-field input[type="text"] {
    padding-right: 42px;
}
.password-toggle {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    width: 40px;
    background: none;
    border: none;
    cursor: pointer;
    opacity: .55;
    padding: 0;
    display: flex;
    align-items: center;
    justify-content: center;
}
.password-toggle svg { width: 18px; height: 18px; }
.password-toggle:hover { opacity: .85; }
.password-toggle.is-visible { opacity: 1; }

form input:focus,
form textarea:focus,
form select:focus {
    outline: none;
    border-color: var(--menta);
    box-shadow: 0 0 0 3px rgba(66, 184, 196, .3);
}

button, .btn {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    background: var(--menta);
    color: var(--pino);
    border: none;
    padding: 11px 22px;
    border-radius: 999px;
    font-size: 14px;
    font-weight: 600;
    cursor: pointer;
    font-family: inherit;
    transition: transform .15s ease, background .15s ease;
}

button:hover, .btn:hover { background: var(--menta-dark); text-decoration: none; transform: translateY(-1px); }
button:disabled, .btn:disabled { opacity: .55; cursor: default; transform: none; }

.auth-card button[type="submit"] { width: 100%; margin-top: 20px; justify-content: center; }

.btn-link {
    display: inline-flex;
    background: none;
    border: none;
    color: var(--pino);
    padding: 0;
    font: inherit;
    font-weight: 600;
    font-size: 13.5px;
    cursor: pointer;
}
.btn-link:hover { text-decoration: underline; }

.btn-link.btn-danger { color: var(--danger); }

/* ---------- Alerts ---------- */
.alert {
    padding: 11px 15px;
    border-radius: var(--radius-sm);
    font-size: 14px;
    margin-bottom: 16px;
}

.alert-success { background: var(--success-bg); color: var(--success-text); }
.alert-error { background: var(--error-bg); color: var(--error-text); }

/* ---------- Admin layout ---------- */
.app {
    display: flex;
    min-height: 100vh;
}

/* Fijo siempre (no solo en mobile) — es la navegación principal de una
   herramienta de uso diario, no debe perderse de vista al bajar en
   páginas largas (ej. La Bitácora). .main lleva el margin-left
   equivalente para no quedar debajo. overflow-y:auto por si el menú
   llega a crecer más que la altura de la pantalla más adelante. */
.sidebar {
    width: 260px;
    background: var(--chrome);
    color: var(--chrome-muted);
    padding: 24px 14px;
    flex-shrink: 0;
    position: fixed;
    top: 0;
    left: 0;
    height: 100vh;
    overflow-y: auto;
    z-index: 100;
}

.sidebar .brand {
    display: flex;
    align-items: center;
    gap: 12px;
    font-family: 'Fraunces', Georgia, serif;
    font-weight: 600;
    font-size: 24px;
    letter-spacing: -.01em;
    margin: 4px 10px 28px;
    color: var(--chrome-ink);
}
.sidebar .brand svg { flex: none; }

.sidebar nav { display: flex; flex-direction: column; gap: 3px; }

.sidebar nav a {
    display: flex;
    align-items: center;
    color: var(--chrome-muted);
    padding: 11px 16px;
    border-radius: 999px;
    font-size: 15.5px;
}

.sidebar nav a:hover { background: rgba(255, 255, 255, .07); color: var(--chrome-ink); text-decoration: none; }
.sidebar nav a.active { background: var(--menta); color: var(--pino); font-weight: 600; }

/* Etiqueta de sección — separa Operación/Gestión/Configuración en el menú
   sin ser un link (no lleva a ningún lado, solo agrupa visualmente). */
.sidebar .nav-section-label {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: rgba(247, 242, 234, .35);
    padding: 16px 16px 5px;
}
/* Acotado a "hijo directo de <nav>" a propósito: sin el "nav >", esta
   regla (2 clases + pseudo-clase) le gana en especificidad a
   .nav-group-title de abajo (2 clases) y le recorta el padding-top a 2px
   al botón "Gestión" — que también es :first-child, pero de su propio
   .nav-group, no de <nav> — achicando su área de toque a 32px en vez de
   los ~42px pensados (bug real, encontrado midiendo el alto renderizado
   del botón, no solo mirando el CSS). */
.sidebar nav > .nav-section-label:first-child { padding-top: 2px; }

/* Línea divisoria fina antes de "Gestión": marca a propósito el quiebre
   entre el patrón "siempre visible" de Operación (uso diario) y el
   patrón "acordeón" de Gestión/Configuración (uso ocasional), para que
   el cambio de tratamiento visual se lea como intencional y no como una
   inconsistencia. Solo antes de Gestión — Configuración ya queda
   separada por su propio acordeón inmediatamente arriba. */
.sidebar .nav-group[data-grupo="gestion"] {
    margin-top: 8px;
    padding-top: 12px;
    border-top: 1px solid rgba(247, 242, 234, .1);
}

/* Acordeón de "Gestión"/"Configuración" (ver header.php) — mismo rótulo
   visual que .nav-section-label (reusa la clase), convertido en <button>
   para poder expandir/colapsar. Operación queda fuera de este patrón a
   propósito: es la sección de uso diario, así que se deja siempre
   visible sin flecha ni clic extra. */
.sidebar .nav-group-title {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    background: none;
    border: none;
    cursor: pointer;
    font-family: inherit;
    text-align: left;
    /* Un poco más de aire vertical que el label estático (16px/16px/5px)
       para que el botón entero tenga un área de toque más cómoda en
       celular — sigue siendo compacto, pero se acerca más al mínimo de
       ~44px recomendado para objetivos táctiles. */
    padding: 14px 16px;
}
.sidebar .nav-group-title:hover { color: rgba(247, 242, 234, .6); }
.sidebar .nav-group-title:hover .nav-group-arrow { opacity: 1; }
.sidebar .nav-group-title:focus-visible { border-radius: 10px; }
.sidebar .nav-group-arrow {
    /* viewBox 24 + stroke-width 2, igual lenguaje que los íconos de línea
       del panel (ver dashboard.php/pagos.php: viewBox 24, stroke-width
       1.75-2). A 16px de lado, el grosor de trazo renderizado queda en
       ~1.3px — el mismo peso óptico que esos íconos a 18px, así el
       chevron no se ve ni más grueso ni más fino que el resto. */
    width: 16px;
    height: 16px;
    flex: none;
    opacity: .75;
    transition: transform .2s ease, opacity .2s ease;
}
.sidebar .nav-group.open .nav-group-arrow { transform: rotate(180deg); }

/* Apertura/cierre animados con el truco de "grid-template-rows: 0fr → 1fr"
   (anima una altura intrínseca sin conocer el alto real de antemano, algo
   que max-height con un valor fijo no logra limpiamente). El contenido
   real vive en .nav-submenu-inner porque la fila de grid necesita un solo
   hijo con overflow:hidden para recortarse a 0 mientras se anima. */
.sidebar .nav-submenu {
    display: grid;
    grid-template-rows: 0fr;
    transition: grid-template-rows .2s ease;
}
.sidebar .nav-group.open .nav-submenu { grid-template-rows: 1fr; }

/* Indentado + riel vertical fino: distingue a simple vista un link "de
   adentro" de un acordeón abierto de los links sueltos de Operación,
   que no llevan ningún indentado. La visibilidad se retrasa hasta que
   termina la animación de cierre (transition-delay) para que los links
   colapsados no queden alcanzables con Tab mientras están invisibles;
   al abrir, se hacen visibles de inmediato (transition-delay: 0). */
.sidebar .nav-submenu-inner {
    overflow: hidden;
    display: flex;
    flex-direction: column;
    gap: 3px;
    /* Solo espaciado horizontal (indentado + riel) acá. Cualquier margin
       o padding VERTICAL en este elemento reserva su propia altura de
       caja pase lo que pase con overflow:hidden (el recorte solo afecta
       al contenido, no a la caja misma) y dejaría un residuo visible sin
       colapsar del todo cuando la fila de grid llega a 0fr. El respiro
       vertical antes/después de los links de acá lo da el padding
       vertical de los propios <a> (10px, ver regla siguiente) más el
       padding del botón del acordeón arriba/abajo — sin necesidad de
       sumar nada acá. */
    margin-left: 18px;
    padding-left: 12px;
    border-left: 1px solid rgba(247, 242, 234, .16);
    visibility: hidden;
    transition: visibility 0s linear .2s;
}
.sidebar .nav-group.open .nav-submenu-inner {
    visibility: visible;
    transition-delay: 0s;
}
.sidebar .nav-submenu-inner a { padding: 10px 14px; }


.main { flex: 1; display: flex; flex-direction: column; min-width: 0; margin-left: 260px; }

.topbar {
    display: flex;
    justify-content: flex-end;
    align-items: center;
    gap: 16px;
    padding: 16px 30px;
    background: var(--arena);
    border-bottom: 1px solid var(--border);
    font-size: 14px;
    color: var(--text-muted);
}

.content { padding: 30px; background: var(--arena); flex: 1; }

.page-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 22px;
}

.page-header h1 { margin: 0; font-size: 24px; color: var(--text); }

/* Enlace "volver" — en toda pantalla que se llega desde una lista (editar,
   nuevo, curaduría, reabrir un reporte guardado) para que siempre quede
   claro cómo salir sin usar el botón "atrás" del navegador. */
.back-link {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-size: 13px;
    color: var(--text-muted);
    margin-bottom: 10px;
}
.back-link:hover { color: var(--pino); text-decoration: none; }

.form-card {
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 26px 28px;
    max-width: 420px;
}

.form-actions {
    display: flex;
    align-items: center;
    gap: 18px;
    margin-top: 22px;
}

/* Fila de 2 campos lado a lado dentro de un formulario (ej. Edad + Género). */
.row2 { display: flex; gap: 12px; }
.row2 > * { flex: 1; }

/* Tarjeta repetible dentro de un form-card (ej. un hijo, un perfil) —
   mismo dispositivo visual que ya usa el editor de Bitácora/Brújula para
   sus bloques por hijo, adaptado a los tokens de marca del panel. */
.block {
    border: 1.5px solid var(--border);
    border-radius: var(--radius-sm);
    padding: 18px;
    margin-bottom: 16px;
    background: var(--bg);
}
.block .bh {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 6px;
}
.block .bh .t {
    font-family: 'Fraunces', Georgia, serif;
    font-weight: 600;
    color: var(--pino);
    font-size: 15px;
}
.btn-x {
    background: none;
    border: none;
    color: var(--text-muted);
    font-size: 20px;
    line-height: 1;
    cursor: pointer;
    padding: 2px 6px;
    border-radius: 6px;
}
.btn-x:hover { color: var(--danger); background: var(--error-bg); }

/* Grilla de tarjetas KPI del Dashboard (Familias vinculadas/Servicios
   activos/Reportes pendientes) — clase propia (no inline) para poder
   pasarla a una columna en el bloque responsive de abajo. */
.kpi-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; margin-bottom: 26px; max-width: 760px; }
/* Variante de 4 tarjetas (dashboard.php, con el KPI de Cobros pendientes) —
   clase aparte en vez de style="" inline: un inline style gana siempre en
   especificidad sobre la regla mobile de abajo (@media max-width:880px),
   así que forzarlo inline dejaba la 4ta tarjeta cortada e invisible en
   celular (bug real encontrado por revisión UI, 2026-07-27). */
.kpi-grid-4 { grid-template-columns: repeat(4, 1fr); max-width: 960px; }

/* Tarjetas KPI clicables — a pedido explícito del usuario ("un dashboard
   debe ser indicadores de número y una breve descripción, que al hacer
   clic... dirijan a donde corresponda"): el <a> envuelve la tarjeta
   entera en vez de agregar un link aparte adentro, así toda la tarjeta
   es el área de clic, no solo un texto pequeño. */
a.form-card.kpi-card-link {
    display: block;
    text-decoration: none;
    color: inherit;
    transition: border-color .15s, box-shadow .15s;
}
a.form-card.kpi-card-link:hover {
    border-color: var(--pino);
    box-shadow: var(--sombra-sm, 0 2px 10px rgba(0,0,0,.06));
}

/* ---------- Table ---------- */
.table {
    width: 100%;
    border-collapse: collapse;
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    overflow: hidden;
}

.table th, .table td {
    text-align: left;
    padding: 13px 16px;
    border-bottom: 1px solid var(--border);
    font-size: 14px;
    vertical-align: middle;
}

.table th {
    background: var(--pino);
    font-weight: 600;
    font-size: 11.5px;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--papel);
    border-bottom: none;
}
.table tbody tr:last-child td { border-bottom: none; }

/* Ojo: NUNCA display:flex directo en un <td> — deja de comportarse como
   celda de tabla (el navegador lo envuelve en una celda anónima) y pierde
   el centrado vertical automático de la fila. En filas altas (ej. texto
   largo en una columna vecina) los links de acción quedaban pegados
   arriba, "flotando" separados del resto de la fila. En vez de eso, los
   hijos de .actions son inline-block con separación por margen — así el
   <td> sigue siendo una celda de tabla normal y se centra solo. */
.table .actions {
    /* Nunca partir Editar/Eliminar en dos líneas por falta de espacio —
       si la columna queda angosta (ej. Fuentes confiables, con "Fuente"
       y "Tipo" largos compitiendo por ancho), que la columna crezca lo
       necesario en vez de apilar las acciones una debajo de la otra. */
    white-space: nowrap;
}
.table .actions > a,
.table .actions > form {
    display: inline-block;
    vertical-align: middle;
    margin-right: 14px;
}
.table .actions > a:last-child,
.table .actions > form:last-child { margin-right: 0; }

/* Que un link real (no una acción/botón) se note como tal a simple
   vista, no solo al pasar el mouse — ej. la columna "Enlace" de Fuentes
   confiables. */
.table td a { text-decoration: underline; text-underline-offset: 2px; text-decoration-color: rgba(3, 81, 89, .35); }
.table td a:hover { text-decoration-color: currentColor; }

/* Envuelve cada <table class="table"> para que en pantallas angostas
   haga scroll horizontal propio, en vez de forzar que toda la página
   se desplace de lado (ver bloque responsive al final del archivo). */
.table-scroll { width: 100%; overflow-x: auto; -webkit-overflow-scrolling: touch; }

/* ---------- Tabla interactiva: ordenar por columna + buscar ----------
   Inyectado por panel/assets/js/tabla-interactiva.js sobre cualquier
   <table class="table"> que tenga filas reales — reusa los mismos tokens
   de marca que el resto del panel (inputs de settings.php, .btn-link) en
   vez de inventar un estilo aislado. */
.table th.is-ordenable {
    cursor: pointer;
    user-select: none;
}
.table th.is-ordenable:hover { color: var(--menta); }
.table th.is-ordenable:focus-visible {
    outline: 2.5px solid var(--menta);
    outline-offset: -3px;
    border-radius: 4px;
}
.table th .th-inner {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    white-space: nowrap;
}
.table th .th-sort-icon {
    display: inline-flex;
    width: 13px;
    height: 13px;
    flex: none;
    opacity: .35;
    transition: opacity .15s ease, transform .15s ease;
}
.table th.is-ordenable:hover .th-sort-icon { opacity: .75; }
.table th.is-ordenado .th-sort-icon { opacity: 1; color: var(--menta); }
.table th.is-ordenado.dir-desc .th-sort-icon { transform: rotate(180deg); }

/* Barra de herramientas (buscador + contador) arriba de cada tabla —
   misma altura/forma que los botones pill del panel (border-radius 999px)
   para que se sienta parte del mismo sistema, no un input de navegador
   suelto. */
.tabla-toolbar {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-bottom: 12px;
    flex-wrap: wrap;
}
.tabla-buscar {
    position: relative;
    flex: 1 1 260px;
    max-width: 360px;
}
.tabla-buscar-icono {
    position: absolute;
    left: 13px;
    top: 50%;
    transform: translateY(-50%);
    width: 16px;
    height: 16px;
    display: flex;
    color: var(--text-muted);
    pointer-events: none;
}
.tabla-buscar input {
    width: 100%;
    padding: 9px 14px 9px 37px;
    border: 1.5px solid var(--border);
    border-radius: 999px;
    font-size: 13.5px;
    background: #fff;
    color: #0C2427;
    font-family: inherit;
}
.tabla-buscar input:focus {
    outline: none;
    border-color: var(--menta);
    box-shadow: 0 0 0 3px rgba(66, 184, 196, .3);
}
/* Cromo nativo del botón "borrar" de type="search" en Chrome/Edge trae su
   propio look — se deja, es útil y no compite visualmente con nada más. */
.tabla-buscar input::-webkit-search-cancel-button { cursor: pointer; }
.tabla-contador {
    font-size: 12px;
    color: var(--text-muted);
    white-space: nowrap;
}
.tr-sin-resultados td {
    text-align: center;
    color: var(--text-muted);
    padding: 22px 16px;
}

.badge {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 3px 11px 3px 8px;
    border-radius: 999px;
    font-size: 11.5px;
    font-weight: 600;
    background: rgba(111, 130, 126, .14);
    color: var(--text-muted);
}
.badge::before {
    content: "";
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: currentColor;
    flex: none;
}

.badge-ok { background: var(--success-bg); color: var(--success-text); }
.badge-off { background: var(--error-bg); color: var(--error-text); }
.badge-warn { background: rgba(230, 180, 92, .18); color: #8a5f16; }

/* Chip discreto para marcar el origen de una familia (autoregistro vía
   activar.php vs. cargada a mano por el operador) — no es un estado, así
   que no usa .badge para no competir visualmente con la columna Estado. */
.chip-origen {
    display: inline-block;
    font-size: 10.5px;
    font-weight: 600;
    color: var(--pino);
    background: rgba(66, 184, 196, .18);
    border-radius: 999px;
    padding: 2px 8px;
    margin-left: 6px;
    vertical-align: middle;
}

/* ---------- Descripción de página + subsecciones con contador (ej. Solicitudes: PQR / Cancelaciones) ---------- */
.page-desc {
    font-size: 13.5px;
    color: var(--text-muted);
    max-width: 680px;
    line-height: 1.6;
    margin: -10px 0 26px;
}
.section-title {
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 18px;
    color: var(--pino);
    margin: 34px 0 14px;
}
.section-title:first-of-type { margin-top: 6px; }
.badge-count {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 22px;
    height: 22px;
    padding: 0 7px;
    border-radius: 999px;
    background: var(--arena);
    color: var(--pino);
    font-size: 12px;
    font-weight: 700;
}
/* ---------- Pestañas de estado (ej. Familias: Pendientes/Activas/Todas) ----------
   Mismo criterio visual que el toggle Mensual/Anual de la landing
   (.ptab-btn en index.html): grupo segmentado, pestaña activa en sólido
   pino, resto transparente. Navegación real por ?estado=X (no hay SPA en
   el panel), así que cada pestaña es un <a> normal — el estado activo lo
   decide PHP en el render, no JS. */
.tabs-familias {
    display: inline-flex; gap: 4px; padding: 4px;
    background: var(--arena); border-radius: 12px;
    margin-bottom: 18px;
}
.tab-item {
    display: inline-flex; align-items: center; gap: 7px;
    padding: 8px 14px; border-radius: 9px;
    font-size: 13.5px; font-weight: 600; color: var(--text-muted);
    text-decoration: none; transition: background .15s, color .15s;
}
.tab-item:hover { color: var(--pino); }
.tab-item.active { background: var(--pino); color: #fff; }
.tab-item .tab-count {
    display: inline-flex; align-items: center; justify-content: center;
    min-width: 19px; height: 19px; padding: 0 5px;
    border-radius: 999px; font-size: 11px; font-weight: 700;
    background: rgba(3, 81, 89, .1); color: var(--pino);
}
.tab-item.active .tab-count { background: rgba(255, 255, 255, .22); color: #fff; }

.empty-note {
    font-size: 14px;
    color: var(--text-muted);
    background: var(--card-bg);
    border: 1px dashed var(--border);
    border-radius: var(--radius-sm);
    padding: 16px 18px;
}

/* ---------- Grilla de contenido de audio (saludos/despedidas/taglines) ---------- */
.ac-grid { margin: 10px 0 8px; }
.ac-row {
    display: flex;
    gap: 8px;
    align-items: flex-start;
    padding: 8px 0;
    border-bottom: 1px solid var(--border);
}
.ac-row:first-child { border-top: 1px solid var(--border); }
.ac-tono {
    flex: 0 0 110px;
    padding: 7px 8px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--card-bg);
    color: var(--text);
    font-size: 13px;
}
.ac-texto {
    flex: 1 1 auto;
    min-height: 40px;
    padding: 7px 8px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--card-bg);
    color: var(--text);
    font-size: 13px;
    font-family: inherit;
    resize: vertical;
}
.ac-del {
    flex: 0 0 auto;
    background: transparent;
    border: 1px solid var(--border);
    color: var(--danger);
    border-radius: 8px;
    width: 32px;
    height: 32px;
    font-size: 16px;
    line-height: 1;
    cursor: pointer;
    padding: 0;
}
.ac-del:hover { background: var(--error-bg); text-decoration: none; transform: none; }
.ac-add {
    margin-top: 6px;
    background: transparent;
    border: 1.5px dashed var(--border);
    color: var(--pino);
    border-radius: 999px;
    padding: 8px 16px;
    font-size: 13px;
    cursor: pointer;
}
.ac-add:hover { background: rgba(3, 81, 89, .06); text-decoration: none; transform: none; }
.ac-empty { font-size: 13px; color: var(--text-muted); padding: 8px 0; }

/* ---------- Panel admin responsive (celular / tablet) ----------
   El resto del panel (Bitácora, Brújula, activar.php) ya tenía su
   propio diseño mobile-first; esto es solo para el layout compartido
   (sidebar + tablas) del panel admin — Dashboard, Familias, Reportes,
   Biblioteca, Fuentes, Usuarios, Configuración. Nada de esto se activa
   arriba de 880px, así que la vista de escritorio queda idéntica. */
.menu-toggle {
    display: none;
    background: none;
    border: none;
    font-size: 22px;
    line-height: 1;
    color: var(--text);
    cursor: pointer;
    padding: 4px 8px;
    margin-right: auto;
}
.sidebar-backdrop {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(22, 33, 29, .45);
    z-index: 99;
}
.sidebar-backdrop.open { display: block; }

@media (max-width: 880px) {
    /* Seguro general: nada debería forzar scroll horizontal de toda la
       página (las tablas ya hacen su propio scroll vía .table-scroll) —
       si algo se escapa, que se recorte ahí en vez de correr todo el
       body de lado. `clip` en vez de `hidden`: mismo recorte visual,
       pero `hidden` en html/body convierte a body en "scroll container"
       y eso rompe silenciosamente position:sticky de cualquier
       descendiente (confirmado con la barra de pasos de Bitácora, ver
       #bitacora-app .topbar-sticky) — `clip` no crea ese scroll
       container y no tiene ese efecto secundario. */
    html, body { overflow-x: clip; }

    .menu-toggle { display: inline-block; }

    .app { display: block; }

    .kpi-grid { grid-template-columns: 1fr; max-width: none; }

    .sidebar {
        transform: translateX(-100%);
        transition: transform .25s ease;
        box-shadow: 4px 0 24px rgba(0, 0, 0, .2);
    }
    .sidebar.open { transform: translateX(0); }

    .main { width: 100%; margin-left: 0; }

    .topbar { padding: 14px 16px; justify-content: flex-start; }
    .topbar span { margin-right: auto; }

    .content { padding: 18px; }

    .page-header { flex-wrap: wrap; gap: 10px; }

    .row2 { flex-direction: column; }

    .form-card { padding: 20px; }

    /* Buscador de tabla: apilado y a todo el ancho en vez de compartir
       fila con el contador (que en 260px de ancho quedaba apretado).
       ¡Ojo! flex-direction pasa de row a column acá — el "260px" de
       ".tabla-buscar { flex: 1 1 260px }" (pensado como ancho preferido
       en fila) se vuelve ALTO preferido en columna si no se resetea, y
       estira la caja a 260px de alto (bug real, encontrado con captura
       de pantalla en 375px: la lupa quedaba flotando lejos del input
       porque su "top:50%" se calculaba sobre esa caja inflada). */
    .tabla-toolbar { flex-direction: column; align-items: stretch; gap: 6px; }
    .tabla-buscar { flex: 0 0 auto; max-width: none; }
    .tabla-contador { text-align: right; }
}

@media (max-width: 480px) {
    .table th, .table td { padding: 10px 12px; font-size: 13px; }
    /* "Hola, Nombre" no es información crítica — en pantallas muy
       angostas se esconde para garantizar que "Cerrar sesión" siempre
       quede visible y alcanzable, en vez de competir por espacio. */
    .topbar span { display: none; }
}
