/* ===== ESTILOS PARA ESTADOS DE ERROR ===== */
.error-state {
    margin-bottom: 1rem;
}

.error-state .alert {
    border-left: 4px solid #dc3545;
    background-color: #f8d7da;
    border-color: #f5c6cb;
    color: #721c24;
}

.error-state .btn-outline-danger {
    border-color: #dc3545;
    color: #dc3545;
}

.error-state .btn-outline-danger:hover {
    background-color: #dc3545;
    color: white;
}

.error-state .btn-outline-danger:focus {
    box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25);
}

/* --- General App Layout & Feel --- */
/* Aplicar el fondo solo cuando la vista de login está activa */
body.login-active {
    background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
}


/* Si no es la vista de login, usar el fondo que ya teníamos */
body:not(.login-active) {
    background-color: #eef2f7; /* A softer, modern light gray/blue */
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
}

/* --- Modern Login View --- */
#login-view {
    min-height: 100vh;
    padding: 1rem;
}

.login-card {
    margin-bottom: 20vh;
    width: 100%;
    max-width: 500px;
    padding: 2rem;
    background-color: #ffffff;
    border-radius: 12px;
    box-shadow: 0 8px 32px rgba(0, 30, 80, 0.1);
    border: 1px solid #dee2e6;
}

.login-icon {
    font-size: 3rem;
    color: #0d6efd;
}

.form-floating > .form-control:focus,
.form-floating > .form-control:not(:placeholder-shown) {
    padding-top: 1.625rem;
    padding-bottom: 0.625rem;
}


/* --- Main App View --- */
#main-app-view {
    background-color: #ffffff;
    border-radius: 12px;
    padding: 2rem;
    box-shadow: 0 8px 32px rgba(0, 30, 80, 0.08);
    margin-top: 1.5rem !important;
    margin-bottom: 1.5rem !important;
    border: 1px solid #dee2e6;
}

/* --- Header & User Actions --- */
.app-header {
    padding-bottom: 1.5rem;
    border-bottom: 1px solid #e9ecef;
}

.user-actions .btn {
    transition: all 0.2s ease-in-out;
}

/* --- Tabs --- */
.nav-tabs {
    border-bottom-color: #dee2e6;
}

.nav-tabs .nav-link {
    color: #6c757d;
    font-weight: 500;
    border: none;
    border-bottom: 2px solid transparent;
    transition: color 0.2s, border-color 0.2s;
}

.nav-tabs .nav-link:hover {
    color: #0d6efd;
}

.nav-tabs .nav-link.active {
    color: #0d6efd;
    background-color: transparent;
    border-color: #0d6efd;
}

/* --- Cards (Filters) --- */
.card {
    border: 1px solid #e9ecef;
    box-shadow: 0 4px 12px rgba(0, 30, 80, 0.05);
    transition: box-shadow 0.3s ease-in-out;
}

/* Table Enhancements */
.table-hover tbody tr {
    transition: background-color 0.15s ease-in-out;
}

.table-hover tbody tr:hover {
    background-color: #e9ecef;
}

/* Make folder links more obvious */
.folder-link {
    font-weight: 500;
    cursor: pointer;
}

/* Sortable Table Headers */
.sortable-header, .file-sortable-header {
    position: relative;
    padding-right: 20px !important; /* Space for the arrow */
    cursor: pointer;
}

/*
  Sobrescribimos las reglas de style.css siendo más específicos (añadiendo 'th')
  y asegurando que la fuente de iconos se aplique a todos los estados para evitar conflictos.
*/
th.sortable-header::after, th.file-sortable-header::after {
    content: '\F575'; /* Bootstrap Icons sort icon */
    font-family: 'bootstrap-icons';
    position: absolute;
    right: 5px;
    top: 50%;
    transform: translateY(-50%);
    color: #adb5bd;
    opacity: 0.5;
}

th.sortable-header:hover::after, th.file-sortable-header:hover::after {
    opacity: 1;
}

th.sortable-header.sort-asc::after, th.file-sortable-header.sort-asc::after {
    font-family: 'bootstrap-icons'; /* Asegurar la fuente en este estado también */
    content: '\F57B'; /* Arrow up */
}

th.sortable-header.sort-desc::after, th.file-sortable-header.sort-desc::after {
    font-family: 'bootstrap-icons'; /* Asegurar la fuente en este estado también */
    content: '\F575'; /* Arrow down */
}

/* Dropzone Customization */
#upload-dropzone {
    border: 2px dashed #0d6efd;
    border-radius: 0.375rem;
    background-color: #f8f9fa;
    transition: background-color 0.2s ease-in-out;
}

#upload-dropzone.dz-drag-hover {
    background-color: #e9f2ff;
    border-style: solid;
}

.dz-preview {
    border: none !important; /* Sin borde para diseño limpio */
    border-radius: 0.5rem !important; /* Bordes más redondeados */
    padding: 0 !important; /* Sin padding general */
    background-color: transparent !important; /* Fondo transparente */
    box-shadow: 0 2px 8px rgba(0,0,0,0.1) !important; /* Sombra más suave */
    position: relative !important;
    max-width: 240px !important; /* Ancho máximo - 20% más chico (300px * 0.8) */
    width: 100% !important;
    min-width: 160px !important; /* Ancho mínimo - 20% más chico (200px * 0.8) */
    overflow: hidden !important; /* Contener el contenido */
    aspect-ratio: 4/3 !important; /* Proporción fija para consistencia */
}


/* Placeholder que ocupa todo el espacio */
.dz-preview .dz-image {
    position: absolute !important;
    top: 0 !important;
    left: 0 !important;
    width: 100% !important;
    height: 100% !important;
    background-color: #e9ecef !important; /* Fondo gris para placeholder */
    display: flex !important;
    align-items: center !important;
    justify-content: center !important;
    border-radius: 0.5rem !important;
    overflow: hidden !important;
}

.dz-preview .dz-image img {
    width: 100% !important;
    height: 100% !important;
    object-fit: cover !important; /* Mantener proporciones */
    border-radius: 0.375rem !important;
}

/* Placeholder para archivos que no son imagen */
.dz-preview .dz-image {
    position: relative !important;
}

.dz-preview .dz-image::before {
    content: "📄" !important; /* Icono genérico de archivo por defecto */
    font-size: 3rem !important; /* Icono más grande */
    position: absolute !important;
    top: 23% !important;
    left: 50% !important;
    transform: translate(-50%, -50%) !important;
    z-index: 1 !important;
    color: #6c757d !important;
}

.dz-preview .dz-image img {
    position: relative !important;
    z-index: 2 !important;
}

/* Barra de progreso justo sobre el borde superior de la info bar */
.dz-preview .dz-progress {
    position: absolute !important;
    top: 49% !important; /* Ajustado para previews más pequeños */
    bottom: 0 !important; /* Justo sobre el borde superior de la info bar */
    left: 0 !important;
    right: 0 !important;
    height: 3px !important; /* Más delgada */
    background-color: rgba(255, 255, 255, 0.4) !important; /* Más visible */
    border-radius: 0 !important;
    overflow: hidden !important;
    z-index: 15 !important;
    margin-bottom: 0 !important; /* Sin margen */
}

.dz-preview .dz-upload {
    background-color: white !important;
    height: 100% !important;
    border-radius: 0 !important;
    transition: width 0.3s ease !important;
}

/* Barra de información flotante sobre el placeholder */
.dz-preview .info-bar {
    position: absolute !important;
    bottom: 3px !important; /* Más cerca de la barra de progreso */
    left: 0 !important;
    right: 0 !important;
    background: linear-gradient(135deg, #007bff, #0056b3) !important; /* Azul degradado */
    color: white !important;
    padding: 0.75rem 1rem !important;
    display: flex !important;
    align-items: center !important;
    gap: 0.75rem !important;
    border-radius: 0 0 0.5rem 0.5rem !important;
    box-shadow: 0 -2px 8px rgba(0,0,0,0.2) !important; /* Sombra hacia arriba */
    z-index: 10 !important;
}

/* Información del archivo en la barra */
.dz-preview .info-bar .file-info {
    flex: 1 !important;
    min-width: 0 !important; /* Permitir que se contraiga */
}

.dz-preview .info-bar .dz-filename {
    font-size: 0.9rem !important;
    font-weight: 600 !important;
    color: white !important;
    white-space: nowrap !important;
    overflow: hidden !important;
    text-overflow: ellipsis !important;
    margin-bottom: 0.25rem !important;
}

.dz-preview .info-bar .dz-size {
    font-size: 0.75rem !important;
    color: rgba(255, 255, 255, 0.8) !important;
    font-weight: 400 !important;
}


/* Controles integrados en la barra */
.dz-preview .info-bar .file-controls {
    display: flex !important;
    gap: 0.5rem !important;
    flex-shrink: 0 !important;
}

.dz-preview .info-bar .file-controls .btn {
    width: 28px !important;
    height: 28px !important;
    padding: 0 !important;
    border-radius: 50% !important;
    display: flex !important;
    align-items: center !important;
    justify-content: center !important;
    font-size: 0.75rem !important;
    border: 1px solid rgba(255, 255, 255, 0.3) !important;
}

.dz-preview .info-bar .custom-clear-btn {
    background-color: #ffc107 !important;
    color: #000 !important;
    border-color: #ffc107 !important;
}

.dz-preview .info-bar .custom-cancel-btn {
    background-color: #dc3545 !important;
    color: white !important;
    border-color: #dc3545 !important;
}

/* Reglas para mostrar solo un botón a la vez */
/* Por defecto, Cancel está oculto (ya está en HTML con style="display: none;") */
.dz-preview .info-bar .file-controls .custom-cancel-btn {
    display: none !important;
}

/* Durante subidas activas, mostrar Cancel y ocultar Clear */
.dz-preview.dz-processing .info-bar .file-controls .custom-clear-btn {
    display: none !important;
}

.dz-preview.dz-processing .info-bar .file-controls .custom-cancel-btn {
    display: flex !important;
}

/* Sección inferior - Solo controles */
.dz-preview .file-controls-section {
    background-color: #f8f9fa !important; /* Gris claro, no verde */
    padding: 0.75rem 1rem !important;
    border-radius: 0 0 0.5rem 0.5rem !important; /* Redondeado solo abajo */
    border-top: 1px solid #dee2e6 !important; /* Separador sutil */
    text-align: center !important; /* Centrar controles */
}

/* Controles en la sección inferior */
.dz-preview .file-controls-section .custom-controls {
    display: flex !important;
    gap: 0.5rem !important;
    justify-content: center !important;
    margin: 0 !important;
}

.dz-preview .file-controls-section .btn {
    font-size: 0.8rem !important;
    padding: 0.375rem 0.75rem !important;
    min-width: 80px !important;
    border-radius: 0.375rem !important;
}



.dz-preview .dz-size {
    font-size: 0.8rem !important;
    color: #6c757d !important;
    margin-bottom: 0.5rem !important;
}

/* Estilos para el popover del nombre de archivo */
.popover {
    max-width: 300px !important;
    z-index: 1070 !important; /* Por encima del modal (z-index: 1055) y loading overlay (z-index: 1060) */
}

/* Asegurar que el popover esté por encima de la barra de progreso de Dropzone */
.dropzone .dz-preview .dz-filename + .popover,
.dropzone .dz-preview .dz-filename[data-bs-toggle="popover"] + .popover {
    z-index: 1070 !important; /* Por encima del modal y loading overlay */
}

.popover .popover-body {
    word-wrap: break-word !important;
    white-space: normal !important;
    line-height: 1.4 !important;
    font-size: 0.9rem !important;
}

.dz-preview .dz-progress {
    width: 100% !important;
    max-width: 100% !important; /* Asegurar que no se salga del contenedor */
    height: 6px !important; /* Grosor moderado */
    margin: 0.75rem 0 0 0 !important; /* Espaciado superior */
    overflow: hidden !important; /* Contener el contenido */
    border-radius: 3px !important; /* Bordes redondeados */
    background-color: #e9ecef !important; /* Fondo gris claro */
}

.dz-preview .dz-upload {
    background-color: #007bff !important; /* Azul para progreso */
    height: 100% !important;
    border-radius: 3px !important;
    transition: width 0.3s ease !important;
}

/* Controles personalizados compactos */
.dz-preview .custom-controls {
    display: flex !important;
    gap: 0.5rem !important;
    justify-content: center !important;
    margin-top: 0.5rem !important;
}

.dz-preview .custom-controls .btn {
    font-size: 0.75rem !important;
    padding: 0.25rem 0.5rem !important;
    min-width: 60px !important;
    flex-shrink: 0 !important; /* Evitar que los botones se compriman */
}

/* Colores correctos para botones */
.dz-preview .custom-clear-btn {
    background-color: #ffc107 !important; /* Amarillo para Clear */
    color: #000 !important;
    border-color: #ffc107 !important;
}

.dz-preview .custom-clear-btn:hover {
    background-color: #e0a800 !important;
    border-color: #d39e00 !important;
    color: #000 !important;
}

.dz-preview .custom-cancel-btn {
    background-color: #dc3545 !important; /* Rojo para Cancel */
    color: white !important;
    border-color: #dc3545 !important;
}

.dz-preview .custom-cancel-btn:hover {
    background-color: #c82333 !important;
    border-color: #bd2130 !important;
    color: white !important;
}

/* Por defecto, ocultar mensajes de error */
.dz-error-message {
    display: none !important;
}

/* MEJORADO: Mostrar errores de forma integrada sin interferir con controles */
.dz-error-message {
    background: #f8d7da !important;
    color: #842029 !important;
    border: 1px solid #f5c6cb !important;
    border-radius: 0.25rem !important;
    padding: 0.375rem 0.5rem !important;
    font-size: 0.75rem !important;
    font-weight: 500 !important;
    position: absolute !important;
    top: 5px !important; /* Posicionar en la esquina superior derecha */
    right: 5px !important;
    max-width: 200px !important; /* Limitar ancho para no interferir */
    max-height: 100px !important;
    white-space: break-word !important; /* Multi linea */
    text-overflow: clip !important; 
    overflow: hidden !important;
    z-index: 15 !important; /* Asegurar que esté por encima */
    box-shadow: 0 2px 4px rgba(0,0,0,0.15) !important; /* Sombra más visible */
    border-left: 3px solid #dc3545 !important; /* Borde izquierdo rojo para destacar */
    line-height: 1.2 !important;
    overflow-y: auto;
}

/* Ajustar el contenedor del archivo para el mensaje de error compacto */
.dz-preview.dz-error {
    margin-bottom: 10px !important; /* Espacio mínimo ya que el error está en la esquina */
    position: relative !important; /* Necesario para posicionamiento absoluto del mensaje de error */
}

/* Asegurar que dz-file-preview tenga position relative para el posicionamiento absoluto */
.dz-file-preview {
    position: relative !important;
}

/* Mostrar mensaje de error permanentemente cuando el archivo tiene error */
.dz-preview.dz-error .dz-error-message {
    display: block !important;
    opacity: 1 !important;
    visibility: visible !important;
    position: absolute !important;
    top: 5px !important;
    left: 5px !important;
    z-index: 10 !important;
}

/* Regla más específica para asegurar visibilidad en archivos con error */
.dropzone .dz-preview.dz-error .dz-error-message {
    display: block !important;
    opacity: 1 !important;
    visibility: visible !important;
    position: absolute !important;
    top: 5px !important;
    left: 5px !important;
    z-index: 10 !important;
}

/* Regla ultra específica para el selector completo que mencionaste */
#upload-dropzone > div.dz-preview.dz-file-preview.dz-error.dz-complete > div.dz-error-message {
    display: block !important;
    opacity: 1 !important;
    visibility: visible !important;
    position: absolute !important;
    top: 5px !important;
    left: 5px !important;
    z-index: 10 !important;
}

/* Regla para cubrir todas las variaciones de dz-file-preview con error */
.dz-file-preview.dz-error .dz-error-message,
#upload-dropzone .dz-file-preview.dz-error .dz-error-message {
    display: block !important;
    opacity: 1 !important;
    visibility: visible !important;
    position: absolute !important;
    top: 5px !important;
    left: 5px !important;
    z-index: 10 !important;
}

/* Mostrar mensaje de error también para archivos cancelados */
.dz-preview.dz-canceled .dz-error-message,
.dropzone .dz-preview.dz-canceled .dz-error-message {
    display: block !important;
    opacity: 1 !important;
    visibility: visible !important;
}

/* Añadir un indicador visual adicional en el archivo con error */
.dz-preview.dz-error .dz-details {
    background-color: #f8d7da !important; /* Fondo rojizo para errores */
    border-left: 3px solid #dc3545 !important; /* Borde izquierdo rojo */
}

.dz-preview.dz-error .file-controls-section {
    background-color: #f8d7da !important; /* Fondo rojizo para errores */
    border-top-color: #f5c6cb !important; /* Borde rojizo */
}

.dz-preview.dz-success .file-controls-section {
    background-color: #d1edff !important; /* Fondo azul claro para éxito */
    border-top-color: #b8daff !important; /* Borde azul claro */
}

/* Hacer que el botón Clear sea más visible en archivos con error */
.dz-preview.dz-error .custom-clear-btn {
    background-color: #ffc107 !important; /* Amarillo para Clear */
    color: #000 !important;
    border-color: #ffc107 !important;
    font-weight: 600 !important;
}


/* Alternativa: Mostrar error de forma más integrada en el archivo */
.dz-preview.dz-error .dz-details {
    border-bottom: 2px solid #dc3545 !important; /* Línea roja debajo del nombre */
}

/* Añadir icono de error más visible */
.dz-preview.dz-error .dz-details::after {
    content: "⚠️" !important;
    position: absolute !important;
    top: 5px !important;
    right: 5px !important;
    font-size: 1.2rem !important;
}

/* ALTERNATIVA: Mostrar error de forma compacta dentro del archivo */
.dz-preview.dz-error .dz-details {
    position: relative !important;
}

/* Estilo para mensaje de error compacto (opcional) */
.dz-preview.dz-error .dz-error-message-compact {
    background: #f8d7da !important;
    color: #842029 !important;
    border: 1px solid #f5c6cb !important;
    border-radius: 0.25rem !important;
    padding: 0.25rem 0.5rem !important;
    font-size: 0.75rem !important;
    font-weight: 500 !important;
    position: absolute !important;
    bottom: 5px !important;
    left: 5px !important;
    right: 5px !important;
    z-index: 100 !important;
    text-align: center !important;
    white-space: nowrap !important;
    overflow: hidden !important;
    text-overflow: ellipsis !important;
    box-shadow: 0 1px 3px rgba(0,0,0,0.1) !important;
}

/* --- Upload Telemetry Display --- */

.upload-stat {
    padding: 0.25rem 0.5rem;
    text-align: center;
    min-width: 60px;
}

.upload-stat .stat-label {
    font-size: 0.75rem;
    color: #6c757d;
    font-weight: 500;
    margin-bottom: 0.125rem;
    text-transform: uppercase;
    letter-spacing: 0.5px;
}

.upload-stat .stat-value {
    font-size: 0.9rem;
    font-weight: 600;
    color: #495057;
    font-family: 'Courier New', monospace;
    line-height: 1.2;
}

/* --- Dropzone Custom Button Visibility States --- */
/* Estados de error, éxito y completado: mostrar solo "Clear" */
.dropzone .dz-preview .dz-error .custom-controls .custom-clear-btn{
    display: inline-block !important; /* Mostrar "Clear" en caso de error */
}

.dropzone .dz-preview .dz-error .custom-controls .custom-cancel-btn{
    display: none !important; /* Ocultar "Cancel" en caso de error */
}

/* Reglas adicionales más específicas para archivos con error */
.dz-preview.dz-error .custom-controls .custom-clear-btn{
    display: inline-block !important; /* Mostrar "Clear" en caso de error */
}

.dz-preview.dz-error .custom-controls .custom-cancel-btn{
    display: none !important; /* Ocultar "Cancel" en caso de error */
}

/* Reglas de máxima especificidad para forzar el comportamiento correcto */
.dropzone .dz-preview.dz-error .custom-controls .custom-clear-btn{
    display: inline-block !important; /* Mostrar "Clear" en caso de error */
}

.dropzone .dz-preview.dz-error .custom-controls .custom-cancel-btn{
    display: none !important; /* Ocultar "Cancel" en caso de error */
}

/* Asegurar que no haya conflictos con otros estilos */
.dz-preview.dz-error .custom-cancel-btn {
    display: none !important; /* Forzar ocultación del botón Cancel */
}

.dz-preview.dz-error .custom-clear-btn {
    display: inline-block !important; /* Forzar visualización del botón Clear */
}

.dropzone .dz-preview .dz-success .custom-controls .custom-clear-btn{
    display: inline-block !important; /* Mostrar "Clear" en caso de éxito */
}

.dropzone .dz-preview .dz-success .custom-controls .custom-cancel-btn{
    display: none !important; /* Ocultar "Cancel" en caso de éxito */
}

.dropzone .dz-preview .dz-complete .custom-controls .custom-clear-btn{
    display: inline-block !important; /* Mostrar "Clear" cuando está completo */
}

.dropzone .dz-preview .dz-complete .custom-controls .custom-cancel-btn{
    display: none !important; /* Ocultar "Cancel" cuando está completo */
}

/* CORREGIDO: Manejar archivos cancelados que tienen tanto dz-error como dz-complete */
.dropzone .dz-preview.dz-error.dz-complete .custom-controls .custom-clear-btn{
    display: inline-block !important; /* Mostrar "Clear" en archivos cancelados */
}

.dropzone .dz-preview.dz-error.dz-complete .custom-controls .custom-cancel-btn{
    display: none !important; /* Ocultar "Cancel" en archivos cancelados */
}

/* Estado por defecto (archivo en cola): mostrar solo "Clear" */
.dropzone .dz-preview:not(.dz-processing):not(.dz-error):not(.dz-success):not(.dz-complete) .custom-controls .custom-clear-btn{
    display: inline-block !important; /* Mostrar "Clear" por defecto */
}

.dropzone .dz-preview:not(.dz-processing):not(.dz-error):not(.dz-success):not(.dz-complete) .custom-controls .custom-cancel-btn{
    display: none !important; /* Ocultar "Cancel" por defecto */
}

/* Estado de procesamiento (subiendo): mostrar solo "Cancel" */
.dropzone .dz-preview.dz-processing .custom-controls .custom-clear-btn{
    display: none !important; /* Ocultar "Clear" durante subida */
}

.dropzone .dz-preview.dz-processing .custom-controls .custom-cancel-btn{
    display: inline-block !important; /* Mostrar "Cancel" durante subida */
}

/* Estilos para la tabla de telemetría horizontal estable */
.telemetry-table {
    display: flex;
    flex-direction: row;
    gap: 2rem;
    align-items: center;
    min-width: 400px;
}

.telemetry-cell {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    min-width: 90px;
    flex: 0 0 auto; /* No crecer, no encoger */
}

/* Ancho específico para la columna de velocidad */
.telemetry-cell:first-child {
    min-width: 100px; /* Un poco más ancha para velocidad */
}

.telemetry-table .stat-label {
    font-size: 0.75rem;
    font-weight: 600;
    color: #6c757d;
    margin: 0 0 0.25rem 0;
    white-space: nowrap;
    text-align: right;
}

.telemetry-table .stat-value {
    font-size: 0.9rem;
    font-weight: 500;
    color: #212529;
    margin: 0;
    text-align: right;
    min-width: 70px;
    white-space: nowrap;
}

/* --- File Actions Column Alignment --- */
/* Alinear los botones de la columna de acciones a la derecha solo en la tabla de archivos */
#files-tab-pane .table td:last-child {
    text-align: right;
}

/* Asegurar que el grupo de botones esté alineado a la derecha solo en la tabla de archivos */
#files-tab-pane .table td:last-child .btn-group {
    justify-content: flex-end;
    display: flex;
}

/* --- Spinner en botones durante procesamiento --- */
.btn-processing {
    position: relative;
    pointer-events: none;
    opacity: 0.7;
}

.btn-processing .btn-text {
    opacity: 0;
}

.btn-processing .spinner-border {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 1rem;
    height: 1rem;
    border-width: 0.15em;
    border: 0.15em solid currentColor;
    border-right-color: transparent;
    border-radius: 50%;
    animation: spinner-border 0.75s linear infinite;
    display: inline-block;
}

/* Spinner más pequeño para botones pequeños */
.btn-sm.btn-processing .spinner-border {
    width: 0.8rem;
    height: 0.8rem;
    border-width: 0.1em;
}

/* Animación del spinner para botones */
@keyframes spinner-border {
    to {
        transform: translate(-50%, -50%) rotate(360deg);
    }
}

/* Spinner del loading overlay */
#loading-overlay .spinner-border {
    width: 3rem;
    height: 3rem;
    border-width: 0.3em;
    border: 0.3em solid currentColor;
    border-right-color: transparent;
    border-radius: 50%;
    animation: spinner-border-overlay 0.75s linear infinite;
    display: inline-block;
}

/* Animación específica para el spinner del loading overlay */
@keyframes spinner-border-overlay {
    to {
        transform: rotate(360deg);
    }
}

/* Botón desactivado durante procesamiento */
.btn-disabled-processing {
    opacity: 0.6 !important;
    pointer-events: none !important;
    cursor: not-allowed !important;
}