/* Estilos propios de SLRP sobre Pico: layout, formularios, avisos y el gestor
   de archivos. Se cargan después de pico.min.css para poder sobrescribirlo. */

.app-layout {
    display: grid;
    grid-template-columns: 260px minmax(0, 1fr);
    min-height: 100vh;
}
.app-sidebar {
    background: var(--pico-background-color);
    border-right: 1px solid var(--pico-muted-border-color);
    padding: var(--pico-spacing);
    display: flex;
    flex-direction: column;
    position: sticky;
    top: 0;
    height: 100vh;
    overflow-y: auto;
}
.app-sidebar nav ul {
    margin: 0;
}
.app-sidebar .app-nav-group > a {
    font-weight: 600;
}
.app-sidebar .app-nav-sub {
    display: block;
    list-style: none;
    margin: 0 0 0 var(--pico-spacing);
    padding-left: var(--pico-spacing);
    border-left: 2px solid var(--pico-muted-border-color);
}
.app-sidebar .app-nav-sub li {
    margin: 0;
}
.app-sidebar .app-brand {
    margin-bottom: var(--pico-spacing);
}
.app-logo {
    display: block;
    max-width: 100%;
    max-height: 58px;
    height: auto;
    background: #ffffff;
    border-radius: 0.375rem;
    padding: 0.25rem 0.5rem;
}
.app-main {
    padding: var(--pico-spacing);
    min-width: 0;
    overflow-x: auto;
}
.table-container {
    overflow-x: auto;
}
/* Espacio al final de la tabla para que el menú de acciones, que se
   posiciona absoluto bajo su fila, no quede recortado por el scroll
   del contenedor al abrirse en las últimas filas. */
.table-container table:has(details.dropdown) {
    margin-bottom: 8rem;
}
.table-container details.dropdown {
    margin-bottom: 0;
}
.table-container details.dropdown > summary[role="button"] {
    width: auto;
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    white-space: nowrap;
}
.table-container details.dropdown > summary[role="button"]::after {
    float: none;
    flex: 0 0 auto;
    margin-inline-start: 0;
}
.table-container details.dropdown > summary + ul {
    min-width: max-content;
}
.task-detail th,
.task-detail td {
    overflow-wrap: anywhere;
}
.table-container pre {
    white-space: pre-wrap;
    overflow-wrap: anywhere;
    margin-bottom: 0;
}
/* Celda del payload JSON (solo con show_debug_data): ancho mínimo para que
   la columna no se comprima en pantallas pequeñas (la tabla se desplaza
   dentro de .table-container) y alto acotado con scroll interno para no
   disparar el tamaño de la fila. */
.payload-cell {
    min-width: 18rem;
    max-width: 32rem;
}
.table-container .payload-cell pre {
    max-height: 10rem;
    overflow: auto;
    font-size: 0.85rem;
    margin: 0;
}
/* Fila centinela del scroll infinito: carga la página siguiente al
   entrar en pantalla. */
.list-sentinel td {
    text-align: center;
    color: var(--pico-muted-color);
}
.app-footer {
    margin-top: auto;
    padding-top: var(--pico-spacing);
    color: var(--pico-muted-color);
}
/* Barra superior del sidebar (logo + botón hamburguesa) y cuerpo colapsable. */
.app-sidebar-bar {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: var(--pico-spacing);
}
.app-sidebar-bar .app-brand {
    margin-bottom: var(--pico-spacing);
}
.app-menu-toggle,
.app-menu-backdrop {
    display: none;
}
.app-sidebar-body {
    display: flex;
    flex-direction: column;
    flex: 1;
}
@media (max-width: 768px) {
    /* Una columna sin ensanchar por contenido ancho; la barra mide lo suyo y
       el main ocupa el resto, pegado bajo la barra aunque la página sea corta
       (sin filas explícitas, el sobrante de min-height se reparte entre las
       filas auto y empuja el contenido hacia abajo). */
    .app-layout {
        grid-template-columns: minmax(0, 1fr);
        grid-template-rows: auto minmax(0, 1fr);
        align-content: start;
    }
    .app-layout--auth { grid-template-rows: none; }
    .app-sidebar {
        border-right: 0;
        border-bottom: 1px solid var(--pico-muted-border-color);
        position: sticky;
        top: 0;
        z-index: 30;
        height: auto;
        overflow: visible;
    }
    /* La barra queda por encima del panel para que el botón siga visible. */
    .app-sidebar-bar {
        position: relative;
        z-index: 2;
        background: var(--pico-background-color);
    }
    .app-sidebar-bar .app-brand {
        margin-bottom: 0;
    }
    /* Con el menú abierto la barra deja de ser una franja blanca y pasa a ser
       la cabecera del panel: logo y botón de cerrar quedan dentro del ancho
       del panel y el resto (incluida la franja superior) lo oscurece el fondo. */
    .app-sidebar {
        transition: background-color 0.25s ease, border-color 0.25s ease;
    }
    .app-sidebar.is-open {
        background: transparent;
        border-bottom-color: transparent;
    }
    .app-sidebar.is-open .app-sidebar-bar {
        background: transparent;
        width: calc(min(80vw, 280px) - 2 * var(--pico-spacing));
    }
    .app-menu-toggle {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        width: 2.75rem;
        height: 2.75rem;
        margin: 0;
        padding: 0;
        /* Pico pinta los botones con texto "inverso" (blanco); aquí se fijan
           colores propios que contrastan en tema claro y oscuro, también en
           hover/foco/activo. */
        --pico-background-color: transparent;
        --pico-border-color: var(--pico-muted-border-color);
        --pico-color: var(--pico-contrast);
        background: transparent;
        color: var(--pico-contrast);
        border: 1px solid var(--pico-muted-border-color);
    }
    .app-menu-toggle:hover,
    .app-menu-toggle:active,
    .app-menu-toggle:focus {
        background: transparent;
        color: var(--pico-contrast);
        border-color: var(--pico-contrast);
    }
    .app-menu-toggle:focus-visible {
        box-shadow: 0 0 0 var(--pico-outline-width) var(--pico-primary-focus);
    }
    /* Icono hamburguesa dibujado con CSS: barra central + ::before/::after. */
    .app-menu-icon,
    .app-menu-icon::before,
    .app-menu-icon::after {
        display: block;
        width: 1.25rem;
        height: 2px;
        background: currentColor;
        border-radius: 1px;
        transition: transform 0.2s, background-color 0.2s;
    }
    .app-menu-icon {
        position: relative;
    }
    .app-menu-icon::before,
    .app-menu-icon::after {
        content: "";
        position: absolute;
        left: 0;
    }
    .app-menu-icon::before { top: -6px; }
    .app-menu-icon::after { top: 6px; }
    .app-menu-toggle[aria-expanded="true"] .app-menu-icon { background: transparent; }
    .app-menu-toggle[aria-expanded="true"] .app-menu-icon::before { transform: translateY(6px) rotate(45deg); }
    .app-menu-toggle[aria-expanded="true"] .app-menu-icon::after { transform: translateY(-6px) rotate(-45deg); }
    /* Panel lateral (drawer): superpuesto a la página, se desliza desde la
       izquierda. visibility evita el foco por Tab mientras está cerrado. */
    .app-sidebar-body {
        position: fixed;
        top: 0;
        bottom: 0;
        left: 0;
        z-index: 1;
        width: min(80vw, 280px);
        padding: var(--pico-spacing);
        padding-top: 6.5rem;
        background: var(--pico-background-color);
        border-right: 1px solid var(--pico-muted-border-color);
        box-shadow: 0 0 1rem rgba(0, 0, 0, 0.2);
        overflow-y: auto;
        transform: translateX(-100%);
        visibility: hidden;
        transition: transform 0.25s ease, visibility 0.25s;
    }
    .app-sidebar.is-open .app-sidebar-body {
        transform: none;
        visibility: visible;
    }
    /* Fondo oscuro tras el panel; un clic en él cierra el menú. */
    .app-menu-backdrop {
        display: block;
        position: fixed;
        inset: 0;
        z-index: 20;
        background: rgba(0, 0, 0, 0.45);
        opacity: 0;
        visibility: hidden;
        transition: opacity 0.25s ease, visibility 0.25s;
    }
    .app-sidebar.is-open ~ .app-menu-backdrop {
        opacity: 1;
        visibility: visible;
    }
    body:has(.app-sidebar.is-open) {
        overflow: hidden;
    }
}
.form-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0 var(--pico-spacing);
}
.form-grid .full { grid-column: 1 / -1; }
.form-actions {
    display: flex;
    justify-content: flex-end;
    align-items: center;
    gap: var(--pico-spacing);
    margin-top: var(--pico-spacing);
}
.form-actions button,
.form-actions a[role="button"] {
    width: auto;
    height: 2rem;
    padding: 0 1rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    box-sizing: border-box;
    margin-bottom: 0;
}
.list-actions {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: var(--pico-spacing);
}
.list-actions button,
.list-actions a[role="button"] {
    margin-bottom: 0;
}
/* Tarjeta de tareas completadas del panel: en escritorio ocupa un
   cuarto del ancho disponible y en móvil la mitad, con margen superior
   e inferior iguales. */
.dashboard-completed-card {
    flex: 0 0 25%;
    max-width: 25%;
    text-align: center;
    margin: var(--pico-spacing) 0;
}
.field-help {
    color: var(--pico-muted-color);
    margin-top: 0.25rem;
}
/* Sistema de avisos: un único par de componentes (inline por campo y
   aviso destacado) para que el resultado de una acción salte a la vista
   en todo el sitio. El color sale de la paleta de Pico (rojo para
   errores, verde para éxitos) y se adapta al tema claro/oscuro; los
   íconos son SVG dibujados como máscara y teñidos con currentColor
   (compatible con la CSP, que solo permite imágenes data:). */
:root {
    --slrp-error: var(--pico-del-color, #c62828);
    --slrp-error-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23000' fill-rule='evenodd' d='M12 2 23 21 1 21z M12 7.5 18.2 18.5 5.8 18.5z M11.1 10.5h1.8v3.9h-1.8z M11.1 15.9h1.8v1.8h-1.8z'/%3E%3C/svg%3E");
    --slrp-success: var(--pico-ins-color, #398712);
    --slrp-success-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23000' d='M9 16.17 4.83 12 3.41 13.41 9 19 21 7 19.59 5.59z'/%3E%3C/svg%3E");
}
/* Error inline junto al campo: una línea compacta, en negrita y con
   ícono, alineada bajo el input. */
.field-error,
.file-error {
    position: relative;
    display: block;
    padding-left: 1.3rem;
    margin-top: 0.25rem;
    color: var(--slrp-error);
    font-weight: 600;
}
.field-error::before,
.file-error::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0.1rem;
    width: 1rem;
    height: 1rem;
    background-color: currentColor;
    -webkit-mask: var(--slrp-error-icon) center / contain no-repeat;
    mask: var(--slrp-error-icon) center / contain no-repeat;
}
.field-error[hidden],
.file-error[hidden] { display: none; }
/* El campo culpable se marca en rojo (Pico no lo hace porque los
   formularios son novalidate): basta con que el label contenga un
   error visible. El error de confirmación solo tiñe cuando está
   visible (sin [hidden]). */
label:has(> .field-error:not([data-confirm-error])) > input,
label:has(> .field-error:not([data-confirm-error])) > select,
label:has(> .field-error:not([data-confirm-error])) > textarea,
label:has(> .field-error[data-confirm-error]:not([hidden])) > input {
    border-color: var(--slrp-error);
    background-color: color-mix(in srgb, var(--slrp-error) 6%, var(--pico-background-color));
}
form:has(.file-error:not([hidden])) input[type="file"] {
    border-color: var(--slrp-error);
}
/* Aviso destacado (formulario o página): borde izquierdo grueso, fondo
   teñido e ícono, para que se perciba incluso sobre el fondo del modal.
   Errores y éxitos comparten la forma; cada variante solo cambia el
   color y el ícono por el par de variables --slrp-alert*. */
.alert-error,
.alert-success {
    position: relative;
    display: block;
    padding: 0.75rem var(--pico-spacing) 0.75rem 2.7rem;
    border: 1px solid color-mix(in srgb, var(--slrp-alert) 40%, transparent);
    border-left: 0.375rem solid var(--slrp-alert);
    background: color-mix(in srgb, var(--slrp-alert) 10%, transparent);
    color: var(--slrp-alert);
    border-radius: var(--pico-border-radius);
    margin: var(--pico-spacing) 0;
    font-weight: 500;
}
.alert-error {
    --slrp-alert: var(--slrp-error);
    --slrp-alert-icon: var(--slrp-error-icon);
}
.alert-success {
    --slrp-alert: var(--slrp-success);
    --slrp-alert-icon: var(--slrp-success-icon);
}
.alert-error::before,
.alert-success::before {
    content: "";
    position: absolute;
    left: 1rem;
    top: 0.95rem;
    width: 1.25rem;
    height: 1.25rem;
    background-color: currentColor;
    -webkit-mask: var(--slrp-alert-icon) center / contain no-repeat;
    mask: var(--slrp-alert-icon) center / contain no-repeat;
}
.alert-error strong,
.alert-success strong { color: inherit; }
.alert-error[hidden],
.alert-success[hidden] { display: none; }
/* Los mensajes de la bitácora se guardan en minúscula; se muestra
   capitalizada solo la primera letra. */
.event-message span { display: inline-block; }
.event-message span::first-letter { text-transform: uppercase; }
/* Zona de arrastre del gestor de archivos: el input de archivo marca el
   área y se resalta mientras se arrastra un archivo encima. */
input[data-dropzone] { cursor: pointer; }
input[data-dropzone].dropzone--active {
    outline: 2px dashed var(--pico-primary);
    outline-offset: 2px;
}
/* Modal de carga del gestor: ancho acotado para que no crezca con los
   nombres de archivo, y lista de selección con scroll vertical. */
#archive-upload-dialog {
    width: min(40rem, calc(100vw - 2rem));
    max-width: calc(100vw - 2rem);
    max-height: calc(100vh - 2rem);
}
#archive-upload-dialog article { margin-bottom: 0; }
#archive-upload-dialog input[type="file"] { max-width: 100%; }
.file-list {
    max-height: 12rem;
    overflow-y: auto;
    overflow-wrap: anywhere;
    margin-top: 0.5rem;
    padding: 0.5rem;
    border: 1px solid var(--pico-muted-border-color);
    border-radius: var(--pico-border-radius);
}
.file-list:empty { display: none; }
.file-list-summary {
    margin: 0 0 0.25rem;
    color: var(--pico-muted-color);
}
.file-list-items {
    margin: 0;
    padding-left: 1.25rem;
}
.file-list-items li { overflow-wrap: anywhere; }
/* Gestor de archivos: listado principal a la izquierda y panel de cargas
   activas de ancho fijo a la derecha. En pantallas estrechas se apilan. */
.archive-layout {
    display: flex;
    align-items: flex-start;
    gap: var(--pico-spacing);
}
.archive-main { flex: 1 1 auto; min-width: 0; }
.archive-side { flex: 0 0 34rem; max-width: 34rem; }
@media (max-width: 1280px) {
    .archive-layout { flex-direction: column; }
    .archive-side { flex: 1 1 auto; max-width: none; width: 100%; }
}
/* Navegación e íconos del gestor de archivos: migas de pan, entradas del
   listado y SVG inline que heredan el color por tipo. */
.breadcrumbs {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    flex-wrap: wrap;
    gap: 0.375rem;
    margin-bottom: var(--pico-spacing);
    color: var(--pico-muted-color);
}
.breadcrumbs a { color: var(--pico-primary); }
.breadcrumb-up {
    font-weight: 700;
    text-decoration: none;
    padding: 0 0.375rem;
}
.file-icon {
    width: 1.25rem;
    height: 1.25rem;
    flex: 0 0 auto;
    vertical-align: -0.25em;
}
.file-icon--pdf { color: #d32f2f; }
.file-icon--word { color: #1565c0; }
.file-icon--spreadsheet { color: #2e7d32; }
.file-icon--text { color: #607d8b; }
.file-icon--archive { color: #ef6c00; }
.file-icon--image { color: #6a1b9a; }
.folder-icon { color: #f9a825; }
.entry {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    text-decoration: none;
    color: inherit;
}
.entry--dir { font-weight: 600; }
.entry-name { overflow-wrap: anywhere; }
.app-layout--auth { grid-template-columns: 1fr; }
.auth-card {
    max-width: 24rem;
    margin: 3rem auto;
}
@media (max-width: 768px) {
    .form-grid { grid-template-columns: 1fr; }
    .form-actions {
        flex-direction: column;
        align-items: stretch;
    }
    .form-actions button,
    .form-actions a[role="button"] {
        width: 100%;
    }
    .dashboard-completed-card {
        flex: 0 0 50%;
        max-width: 50%;
    }
}
/* Tipografía uniforme: todo el texto al mismo tamaño. */
:root { --pico-font-size: 100%; }
body,
h1, h2, h3, h4, h5, h6,
small, sub, sup, code, kbd, pre, samp,
.app-sidebar nav, .app-sidebar .app-nav-sub,
.app-footer, .field-help {
    font-size: 1rem;
}
/* Botones compactos: se redefinen las variables de espaciado solo en los
   controles de botón para reducir altura y fuente sin afectar los inputs. */
button,
[type="submit"],
[type="button"],
[type="reset"],
[role="button"],
[type="file"]::file-selector-button {
    --pico-form-element-spacing-vertical: 0.4rem;
    --pico-form-element-spacing-horizontal: 0.75rem;
    font-size: 0.875rem;
    line-height: 1.3;
}

/* Spinner del botón "Prueba de conexión" del formulario de reconectadores:
   se muestra mientras la petición htmx está en curso. */
.btn-spinner {
    display: none;
    width: 1rem;
    height: 1rem;
    margin-right: .5rem;
    border: 2px solid currentColor;
    border-right-color: transparent;
    border-radius: 50%;
    vertical-align: middle;
    animation: slrp-spin .6s linear infinite;
}
#btn-test-connection.htmx-request .btn-spinner { display: inline-block; }
#btn-test-connection .btn-label-loading { display: none; }
#btn-test-connection.htmx-request .btn-label-normal { display: none; }
#btn-test-connection.htmx-request .btn-label-loading { display: inline; }
@keyframes slrp-spin { to { transform: rotate(360deg); } }

/* Lista de archivos COMTRADE del modal de prueba de conexión. */
.test-files {
    max-height: 12rem;
    overflow-y: auto;
    scrollbar-gutter: stable;
    margin-bottom: var(--pico-spacing);
}
