/* CeibeRRHH - Custom Styles */

/* Variables CSS para consistencia */
:root {
    --ceibe-primary: #2563eb;
    --ceibe-secondary: #64748b;
    --ceibe-accent: #f59e0b;
    --ceibe-success: #10b981;
    --ceibe-error: #ef4444;
    --ceibe-warning: #f59e0b;
    --ceibe-dark: #1e293b;
    --ceibe-light: #f8fafc;
    --ceibe-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
    --ceibe-shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
    --ceibe-transition: all 0.3s ease;
}

/* Victor Mono - Fuente monoespaciada global */
@font-face {
    font-family: 'Victor Mono';
    src: url('../webfonts/VictorMono-Regular.ttf') format('truetype');
    font-weight: normal;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: 'Victor Mono';
    src: url('../webfonts/VictorMono-Bold.ttf') format('truetype');
    font-weight: bold;
    font-style: normal;
    font-display: swap;
}

/* Mobile navigation container - hide on desktop (768px+) */
#mobileNavContainer {
    display: flex;
}
@media (min-width: 768px) {
    #mobileNavContainer {
        display: none !important;
    }
}

/* Paginación de DataTables - Solo visible cuando hay más de 500 registros */
.pagination-wrapper {
    display: flex;
    justify-content: center;
    margin-top: 1rem;
}

.dataTables_paginate {
    display: flex;
    gap: 0.5rem;
    align-items: center;
}

.dataTables_paginate .paginate_button {
    padding: 0.5rem 0.75rem;
    border: 1px solid #e2e8f0;
    border-radius: 0.375rem;
    background: white;
    color: #475569;
    font-size: 0.875rem;
    cursor: pointer;
    transition: all 0.2s;
}

.dataTables_paginate .paginate_button:hover:not(.disabled) {
    background: #f1f5f9;
    border-color: var(--ceibe-primary);
    color: var(--ceibe-primary);
}

.dataTables_paginate .paginate_button.current {
    background: var(--ceibe-primary);
    border-color: var(--ceibe-primary);
    color: white;
}

.dataTables_paginate .paginate_button.disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

/* Estilos base */
body {
    font-family: 'Inter', system-ui, sans-serif;
    background-color: var(--ceibe-light);
    color: var(--ceibe-dark);
}

/* Compensación para header fijo */
.main-content {
    padding-top: 80px; /* Desktop header height + margin */
}

@media (max-width: 768px) {
    .main-content {
        padding-top: 70px; /* Mobile header height + margin */
    }
}

/* Navigation Links
   Transiciones EXPLÍCITAS y cortas, nunca `all`: con `all` el navegador vigila
   todas las propiedades animables del item y cualquier cambio (incluido el
   box-shadow del hover) entra en la interpolación. Y la curva es ease-OUT, no
   ease-in-out: esta última arranca plana, así que los primeros milisegundos no
   se ve nada y el realce parece llegar tarde. */
.nav-link {
    position: relative;
    transition: color 0.12s ease-out, background-color 0.12s ease-out;
}

.nav-link:hover {
    /* Sin movimiento, solo el efecto de gradiente del fondo */
}

.nav-link.active {
    color: var(--ceibe-primary) !important;
}

.nav-link.active::after {
    content: '';
    position: absolute;
    bottom: -8px;
    left: 50%;
    transform: translateX(-50%);
    width: 20px;
    height: 2px;
    background-color: var(--ceibe-primary);
    border-radius: 1px;
}

/* Desktop Navigation with vertical icons */
@media (min-width: 768px) {
    .nav-link-vertical {
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 4px;
        padding: 8px 12px !important;
        min-width: 80px;
        position: relative;
        border-radius: 8px;
        transition: border-color 0.12s ease-out, box-shadow 0.12s ease-out, color 0.12s ease-out;
        border: 1px solid transparent;
    }

    /* El degradado y el color del realce los fija app.css (capa de marca). */
    .nav-link-vertical::before {
        content: '';
        position: absolute;
        bottom: 0;
        left: 0;
        right: 0;
        height: 100%;
        border-radius: 8px;
        opacity: 0;
        transition: opacity 0.12s ease-out;
        pointer-events: none;
    }


    .nav-link-vertical:hover::before {
        opacity: 1;
    }
    
    .nav-link-vertical i {
        font-size: 16px;
        margin: 0 !important;
        position: relative;
        z-index: 1;
    }
    
    .nav-link-vertical .nav-text {
        font-size: 12px;
        font-weight: 500;
        text-align: center;
        white-space: nowrap;
        position: relative;
        z-index: 1;
    }
    
    .nav-button-vertical {
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 4px;
        padding: 8px 12px !important;
        min-width: 80px;
        border: 1px solid transparent;
        background: none;
        cursor: pointer;
        position: relative;
        border-radius: 8px;
        transition: border-color 0.12s ease-out, box-shadow 0.12s ease-out, color 0.12s ease-out;
    }

    .nav-button-vertical::before {
        content: '';
        position: absolute;
        bottom: 0;
        left: 0;
        right: 0;
        height: 100%;
        border-radius: 8px;
        opacity: 0;
        transition: opacity 0.12s ease-out;
        pointer-events: none;
    }


    .nav-button-vertical:hover::before {
        opacity: 1;
    }
    
    .nav-button-vertical i {
        font-size: 16px;
        margin: 0 !important;
        position: relative;
        z-index: 1;
    }
    
    .nav-button-vertical .nav-text {
        font-size: 12px;
        font-weight: 500;
        text-align: center;
        white-space: nowrap;
        position: relative;
        z-index: 1;
    }
    
    .nav-button-vertical .chevron {
        display: none;
    }
}

/* Dropdown Links */
.dropdown-link {
    display: block;
    padding: 8px 16px;
    text-decoration: none;
    color: var(--ceibe-dark);
    font-size: 14px;
    transition: all 0.2s ease-in-out;
    border-left: 2.5px solid transparent;
}

.dropdown-link:hover {
    background-color: #dbeafe;
    color: var(--ceibe-dark);
    border-left: 2.5px solid #3b82f6;
}

.dropdown-link i {
    width: 16px;
    text-align: center;
}

/*
 * Flyout submenus (desktop header)
 * Evita el “hueco” entre el item padre y su submenú lateral.
 * El solape ligero mantiene el hover al mover el ratón.
 */
.flyout-menu {
    margin-left: -0.25rem !important; /* solapa sobre el menú padre cuando abre a la derecha */
}

.flyout-menu.flyout-left {
    left: auto !important;
    right: 100% !important;
    margin-left: 0 !important;
    margin-right: -0.25rem !important; /* solapa sobre el menú padre cuando abre a la izquierda */
}

/* Mobile Navigation */
.mobile-nav-link {
    transition: all 0.2s ease-in-out;
}

.mobile-nav-link:hover {
    transform: translateX(4px);
}

.mobile-nav-section {
    margin-bottom: 16px;
}

/* Botones personalizados */
.btn-ceibe {
    padding: 8px 16px;
    border-radius: 8px;
    font-weight: 500;
    transition: all 0.3s ease;
    outline: none;
    border: none;
    cursor: pointer;
}

.btn-ceibe:focus {
    box-shadow: 0 0 0 2px rgba(37, 99, 235, 0.5);
}

.btn-primary {
    background-color: var(--ceibe-primary);
    color: white;
}

.btn-primary:hover {
    background-color: #1d4ed8;
    transform: translateY(-1px);
    box-shadow: var(--ceibe-shadow-lg);
}

.btn-primary:focus {
    box-shadow: 0 0 0 2px rgba(37, 99, 235, 0.5);
}

.btn-secondary {
    background-color: var(--ceibe-secondary);
    color: white;
}

.btn-secondary:hover {
    background-color: #475569;
}

.btn-success {
    background-color: var(--ceibe-success);
    color: white;
}

.btn-success:hover {
    background-color: #059669;
}

.btn-warning {
    background-color: var(--ceibe-warning);
    color: white;
}

.btn-warning:hover {
    background-color: #d97706;
}

.btn-error {
    background-color: var(--ceibe-error);
    color: white;
}

.btn-error:hover {
    background-color: #dc2626;
}

/* Cards personalizadas */
.card-ceibe {
    background: white;
    border-radius: 12px;
    box-shadow: var(--ceibe-shadow-lg);
    padding: 24px;
    transition: all 0.3s ease;
}

.card-ceibe:hover {
    box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1);
    transform: translateY(-2px);
}

/* Inputs personalizados */
.input-ceibe {
    width: 100%;
    padding: 12px 16px;
    border: 1px solid #d1d5db;
    border-radius: 8px;
    outline: none;
    transition: all 0.3s ease;
}

.input-ceibe:focus {
    border-color: var(--ceibe-primary);
    box-shadow: 0 0 0 2px rgba(37, 99, 235, 0.5);
}

/* Efectos hover para elementos interactivos */
.hover-lift {
    transition: transform 0.3s ease;
}

.hover-lift:hover {
    transform: translateY(-2px);
}

/* Loader personalizado */
.loader {
    display: inline-block;
    width: 24px;
    height: 24px;
    border: 2px solid white;
    border-top-color: transparent;
    border-radius: 50%;
    animation: spin 1s linear infinite;
}

@keyframes spin {
    to { transform: rotate(360deg); }
}

/* Dashboard tab loader */
.dash-spinner {
    animation: dashSpin 0.9s cubic-bezier(0.4, 0, 0.2, 1) infinite;
}

@keyframes dashSpin {
    0% { transform: rotate(0deg); }
    100% { transform: rotate(360deg); }
}

/* Animaciones personalizadas */
@keyframes fadeInUp {
    from {
        opacity: 0;
        transform: translateY(30px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

.fade-in-up {
    animation: fadeInUp 0.6s ease-out;
}

@keyframes pulse {
    0%, 100% {
        opacity: 1;
    }
    50% {
        opacity: 0.5;
    }
}

.pulse {
    animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}

/* Heartbeat animation for discrepancy alerts */
@keyframes heartbeat {
    0%, 100% { transform: scale(1); }
    14% { transform: scale(1.08); }
    28% { transform: scale(1); }
    42% { transform: scale(1.08); }
    56% { transform: scale(1); }
}
.animate-heartbeat {
    animation: heartbeat 1.5s ease-in-out infinite;
}

/* Snake border animation for nomina discrepancy */
@property --nomina-snake-angle {
    syntax: '<angle>';
    inherits: false;
    initial-value: 0deg;
}
.nomina-snake-border {
    position: relative;
    border-radius: 0.5rem;
    overflow: hidden;
}
.nomina-snake-border::before {
    content: '';
    position: absolute;
    inset: 0;
    padding: 2px;
    border-radius: 0.5rem;
    background: conic-gradient(from var(--nomina-snake-angle), #f87171 0deg, #ef4444 70deg, #dc2626 110deg, #fca5a5 160deg, transparent 220deg, transparent 360deg);
    mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
    -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
    -webkit-mask-composite: xor;
    mask-composite: exclude;
    pointer-events: none;
    animation: nominaSnakeSpin 2.4s linear infinite;
    z-index: 0;
}
@keyframes nominaSnakeSpin {
    to { --nomina-snake-angle: 360deg; }
}

/* Badge bounce animation for notifications */
@keyframes badge-bounce {
    0%, 100% { 
        transform: scale(1); 
    }
    25% { 
        transform: scale(1.3); 
    }
    50% { 
        transform: scale(1); 
    }
    75% { 
        transform: scale(1.2); 
    }
}

.badge-bounce {
    animation: badge-bounce 0.6s ease-in-out 3;
}

/* New petition row highlight */
.new-petition-row {
    background-color: rgba(147, 51, 234, 0.1) !important;
    animation: pulse 1s ease-in-out infinite;
}

/* Responsive utilities */
@media (max-width: 640px) {
    .desktop-only {
        display: none !important;
    }
}

@media (min-width: 641px) {
    .mobile-only {
        display: none !important;
    }
}

/* Estilos de formularios específicos */
.form-group {
    margin-bottom: 16px;
}

.form-label {
    display: block;
    margin-bottom: 4px;
    font-weight: 500;
    color: var(--ceibe-dark);
}

.form-input {
    width: 100%;
    padding: 12px 16px;
    border: 1px solid #d1d5db;
    border-radius: 8px;
    font-size: 14px;
    transition: all 0.3s ease;
}

.form-input:focus {
    outline: none;
    border-color: var(--ceibe-primary);
    box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1);
}

.form-select {
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e");
    background-position: right 12px center;
    background-repeat: no-repeat;
    background-size: 16px 12px;
    padding-right: 40px;
}

/* Utilidades para charts */
.chart-container {
    position: relative;
    height: 256px;
    width: 100%;
}

@media (min-width: 768px) {
    .chart-container {
        height: 320px;
    }
}

/* Overlay de loading */
.loading-overlay {
    background: rgba(255, 255, 255, 0.8);
    backdrop-filter: blur(4px);
    border: 1px solid rgba(255, 255, 255, 0.2);
}

/* ============================================
   DataTable Selector de Empleados
   ============================================ */
#selectorEmpleadosTable_wrapper .dataTables_filter {
    padding: 8px;
    background: #f9fafb;
    border-bottom: 1px solid #e5e7eb;
}

#selectorEmpleadosTable_wrapper .dataTables_filter input {
    border: 1px solid #d1d5db;
    border-radius: 0.375rem;
    padding: 6px 12px;
    font-size: 0.875rem;
    width: 100%;
    margin-left: 0;
}

#selectorEmpleadosTable_wrapper .dataTables_filter input:focus {
    outline: none;
    border-color: #10b981;
    box-shadow: 0 0 0 3px rgba(16, 185, 129, 0.1);
}

#selectorEmpleadosTable tbody tr {
    cursor: pointer;
    transition: background-color 0.15s ease;
}

#selectorEmpleadosTable tbody tr:hover {
    background-color: #f3f4f6 !important;
}

#selectorEmpleadosTable tbody td {
    padding: 8px 12px;
    font-size: 0.875rem;
}

#selectorEmpleadosTable thead th {
    padding: 8px 12px;
    font-size: 0.75rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.025em;
    color: #6b7280;
}

/* ============================================
   Dev Mode Toast - Advertencia de desarrollo
   ============================================ */
.dev-mode-toast {
    border: 2px solid #FF6B00 !important;
    box-shadow: 0 4px 12px rgba(255, 107, 0, 0.3) !important;
}

.dev-mode-title {
    font-weight: 700 !important;
    color: #FF6B00 !important;
    font-size: 0.95rem !important;
}

.dev-mode-toast .swal2-html-container {
    margin-top: 0.25rem !important;
    font-size: 0.85rem !important;
}

/* ============================================
   Toast horizontal (.ceibe-toast-vertical)
   → Definido EN swal-core.css (única fuente del tema SweetAlert2).
   Aquí había un duplicado que, por orden de carga (custom.css tras
   swal-core.css), ganaba y dejaba los iconos ✓/✗ deformes
   (scale + width/height fijos sobre un icono medido en em). NO re-añadir.
   ============================================ */

/* Lista compacta de notificaciones en línea */
.ceibe-toast-compact-list {
    display: flex !important;
    align-items: center !important;
    gap: 0.875rem !important;
    flex-wrap: nowrap !important;
    overflow: hidden !important;
}

.ceibe-toast-compact-item {
    display: flex !important;
    align-items: center !important;
    gap: 0.35rem !important;
    font-size: 0.8125rem !important;
    font-weight: 400 !important;
    color: #334155 !important;
    white-space: nowrap !important;
}

.ceibe-toast-compact-item i {
    font-size: 0.75rem !important;
}

/* ============================================
   Toast Flip Animations
   ============================================ */
@keyframes toastFlipIn {
    0% {
        transform: perspective(400px) rotateX(90deg);
        opacity: 0;
    }
    40% {
        transform: perspective(400px) rotateX(-10deg);
    }
    70% {
        transform: perspective(400px) rotateX(10deg);
    }
    100% {
        transform: perspective(400px) rotateX(0deg);
        opacity: 1;
    }
}

@keyframes toastFlipOut {
    0% {
        transform: perspective(400px) rotateX(0deg);
        opacity: 1;
    }
    30% {
        transform: perspective(400px) rotateX(-10deg);
        opacity: 1;
    }
    100% {
        transform: perspective(400px) rotateX(90deg);
        opacity: 0;
    }
}

.toast-flip-in {
    animation: toastFlipIn 0.5s ease-out forwards;
}

.toast-flip-out {
    animation: toastFlipOut 0.4s ease-in forwards;
}

/* ============================================
   SweetAlert2 Alerts - Estilo unificado con Toasts
   ============================================ */

/* Animaciones flip para alertas normales */
@keyframes alertFlipIn {
    from { opacity: 0; }
    to   { opacity: 1; }
}

@keyframes alertFlipOut {
    from { opacity: 1; }
    to   { opacity: 0; }
}

.alert-flip-in {
    animation: alertFlipIn 0.5s ease-out forwards !important;
}

.alert-flip-out {
    animation: alertFlipOut 0.2s ease-in forwards !important;
}

/* Icono SweetAlert "Acceso Inhabilitado" — círculo naranja con icono FA */
.swal2-icon.ceibe-icon-acceso-inhabilitado {
    border-color: #f97316;
    color: #f97316;
}
.swal2-icon.ceibe-icon-acceso-inhabilitado .swal2-icon-content {
    font-size: 2.5em;
    line-height: 1;
}

/* Backdrop — sincronizar velocidad con popup */
.swal2-backdrop-show {
    animation-duration: 0.5s !important;
}
.swal2-backdrop-hide {
    animation-duration: 0.2s !important;
}

/* Badge animado en títulos SweetAlert del dashboard */
@keyframes badgeFadeScale {
    from { opacity: 0; transform: scale(0.92); }
    to   { opacity: 1; transform: scale(1); }
}
.swal-badge-title {
    animation: badgeFadeScale 0.4s ease-out both;
    animation-delay: 0.15s;
    opacity: 0;
}

/* SweetAlert sobre modales - z-index muy alto */
.swal-over-modal {
    z-index: 99999 !important;
}

/* Estilos visuales para alertas normales (igual que toasts) */
.swal2-popup.ceibe-alert {
    border-radius: 16px !important;
    border: 2px solid transparent !important;
    background-image: linear-gradient(white, white), linear-gradient(135deg, #4f46e5, #7c3aed) !important;
    background-origin: padding-box, border-box !important;
    background-clip: padding-box, border-box !important;
    box-shadow:
        0 4px 6px -1px rgba(0, 0, 0, 0.1),
        0 10px 15px -3px rgba(0, 0, 0, 0.15),
        0 20px 25px -5px rgba(0, 0, 0, 0.1) !important;
}

/* Loader Modal - Estilo limpio tipo Portal */
.swal2-popup.ceibe-loader {
    border: 2px solid #000 !important;
    border-radius: 16px !important;
    padding: 2rem 1.5rem !important;
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15) !important;
    background: white !important;
}

.swal2-popup.ceibe-loader .swal2-title {
    color: #1f2937 !important;
    font-size: 1.1rem !important;
    font-weight: 600 !important;
    margin-bottom: 1rem !important;
}

/* Ocultar icono en loader */
.swal2-popup.ceibe-loader .swal2-icon {
    display: none !important;
}

/* Animación de entrada/salida suave para loader */
.swal2-popup.ceibe-loader.swal2-show {
    animation: loaderFadeIn 0.2s ease-out !important;
}

.swal2-popup.ceibe-loader.swal2-hide {
    animation: loaderFadeOut 0.15s ease-in !important;
}

@keyframes loaderFadeIn {
    0% {
        opacity: 0;
        transform: scale(0.95);
    }
    100% {
        opacity: 1;
        transform: scale(1);
    }
}

@keyframes loaderFadeOut {
    0% {
        opacity: 1;
        transform: scale(1);
    }
    100% {
        opacity: 0;
        transform: scale(0.95);
    }
}

/* Desactivar animaciones por defecto de SweetAlert2 para alertas con clase ceibe-alert */
.swal2-popup.ceibe-alert.swal2-show {
    animation: none !important;
}

.swal2-popup.ceibe-alert.swal2-hide {
    animation: none !important;
}

/* ============================================
   Animaciones Fade In/Out para alertas
   ============================================ */
@keyframes alertFadeIn {
    from { opacity: 0; }
    to   { opacity: 1; }
}

@keyframes alertFadeOut {
    from { opacity: 1; }
    to   { opacity: 0; }
}

.alert-fade-in {
    animation: alertFadeIn 0.5s ease-out forwards !important;
}

.alert-fade-out {
    animation: alertFadeOut 0.2s ease-in forwards !important;
}

/* Animación para modales HTML */
@keyframes modalFadeIn {
    from { opacity: 0; }
    to   { opacity: 1; }
}

.animate-modal-fade-in {
    animation: modalFadeIn 0.5s ease-out forwards;
}

/* ============================================ */
/* DATATABLES - ESTILOS GLOBALES PERSONALIZADOS */
/* ============================================ */

/* Botones de DataTables (Copiar, Excel, PDF, Print, Recargar) - Solo iconos */
.dt-button,
.dt-buttons .dt-button {
    background: #dbeafe !important; /* bg-blue-50 */
    border: 1.5px solid #3b82f6 !important; /* border-blue-500 */
    border-radius: 8px !important;
    color: #1e40af !important; /* text-blue-800 */
    padding: 0 !important;
    font-size: 0 !important; /* Oculta el texto */
    width: 32px !important;
    height: 32px !important;
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
    transition: all 0.2s ease !important;
    margin-right: 4px !important;
    margin-bottom: 0 !important;
}

.dt-button:hover,
.dt-buttons .dt-button:hover {
    background: #bfdbfe !important; /* bg-blue-100 */
    border-color: #2563eb !important; /* border-blue-600 */
    color: #1e3a8a !important; /* text-blue-900 */
    transform: translateY(-1px) !important;
    box-shadow: 0 2px 4px rgba(59, 130, 246, 0.2) !important;
}

.dt-button:active,
.dt-buttons .dt-button:active {
    transform: translateY(0) !important;
    box-shadow: none !important;
}

.dt-button i,
.dt-buttons .dt-button i {
    margin-right: 0 !important;
    font-size: 14px !important;
}

/* Campo de búsqueda de DataTables */
.dataTables_filter input,
.dataTables_filter input[type="search"] {
    border: 1.5px solid #3b82f6 !important; /* border-blue-500 - mismo que botones */
    border-radius: 8px !important; /* mismo que botones */
    padding: 0 12px !important;
    height: 32px !important; /* mismo alto que botones */
    font-size: 0.875rem !important;
    transition: all 0.2s ease !important;
    margin-left: 0.5rem !important;
    box-sizing: border-box !important;
}

.dataTables_filter input:focus,
.dataTables_filter input[type="search"]:focus {
    outline: none !important;
    border-color: #2563eb !important; /* border-blue-600 */
    box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1) !important;
}

.dataTables_filter input::placeholder,
.dataTables_filter input[type="search"]::placeholder {
    color: #9ca3af !important; /* text-gray-400 */
}

/* Contenedor de controles de DataTables */
.dataTables_wrapper .dataTables_filter {
    display: flex;
    align-items: center;
}

.dataTables_wrapper .dataTables_filter label {
    display: flex;
    align-items: center;
    margin: 0;
}

/* Responsive para botones en móviles */
@media (max-width: 640px) {
    .dt-buttons {
        display: flex;
        flex-wrap: wrap;
        gap: 4px;
    }

    .dt-button,
    .dt-buttons .dt-button {
        flex: 0 0 auto;
        min-width: auto;
        width: 32px !important;
        height: 32px !important;
        margin-right: 0 !important;
    }
}

/* ============================================================
   PANEL LATERAL
   ============================================================ */

/* Resize handle visual feedback */
#panelResizeHandle {
    background: transparent;
    transition: background-color 150ms;
}
#panelResizeHandle:hover {
    background: linear-gradient(180deg, transparent 20%, rgba(139, 92, 246, 0.3) 50%, transparent 80%);
}
#panelResizeHandle:active {
    background: rgba(139, 92, 246, 0.5);
}

/* Nota adhesiva font */
#panelNota {
    font-family: 'Victor Mono', 'Courier New', monospace;
    box-shadow: inset 0 1px 3px rgba(0,0,0,0.06);
}
#panelNota:focus {
    box-shadow: inset 0 1px 3px rgba(0,0,0,0.06), 0 0 0 2px rgba(168, 85, 247, 0.15);
}

/* Todo item transitions */
#todoList .group,
#todoCompletedList .group {
    transition: background-color 150ms, opacity 150ms;
}

/* Checks pills - needed because Tailwind dynamic classes don't compile */
#checksPills .bg-red-100    { background-color: #fee2e2; }
#checksPills .text-red-700  { color: #b91c1c; }
#checksPills .border-red-300 { border-color: #fca5a5; }
#checksPills .bg-amber-100  { background-color: #fef3c7; }
#checksPills .text-amber-700 { color: #b45309; }
#checksPills .border-amber-300 { border-color: #fcd34d; }
#checksPills .bg-blue-100   { background-color: #dbeafe; }
#checksPills .text-blue-700 { color: #1d4ed8; }
#checksPills .border-blue-300 { border-color: #93c5fd; }

/* Notification tree */
.notif-chevron {
    transition: transform 150ms ease;
}
.notif-group button:hover .notif-chevron {
    color: #6b7280;
}

/* Scrollbar slim for panel */
#panelTabPrincipal::-webkit-scrollbar,
#panelTabNotificaciones::-webkit-scrollbar,
#todoList::-webkit-scrollbar,
#todoCompletedList::-webkit-scrollbar,
#checksContent::-webkit-scrollbar {
    width: 4px;
}
#panelTabPrincipal::-webkit-scrollbar-thumb,
#panelTabNotificaciones::-webkit-scrollbar-thumb,
#todoList::-webkit-scrollbar-thumb,
#todoCompletedList::-webkit-scrollbar-thumb,
#checksContent::-webkit-scrollbar-thumb {
    background: #9ca3af;
    border-radius: 4px;
}
#panelTabPrincipal::-webkit-scrollbar-track,
#panelTabNotificaciones::-webkit-scrollbar-track,
#todoList::-webkit-scrollbar-track,
#todoCompletedList::-webkit-scrollbar-track,
#checksContent::-webkit-scrollbar-track {
    background: #e5e7eb;
}

/* Pin button rotation base */
#panelPinBtn i {
    transition: transform 200ms ease, color 150ms;
}

/* iOS Toggle Switch */
.ios-toggle {
    position: relative;
    width: 36px;
    height: 20px;
    -webkit-appearance: none;
    appearance: none;
    background: #d1d5db;
    border-radius: 10px;
    cursor: pointer;
    transition: background 0.3s ease;
    flex-shrink: 0;
}
.ios-toggle:checked {
    background: #10b981;
}
.ios-toggle::before {
    content: '';
    position: absolute;
    top: 2px;
    left: 2px;
    width: 16px;
    height: 16px;
    background: white;
    border-radius: 50%;
    transition: transform 0.3s ease;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
}
.ios-toggle:checked::before {
    transform: translateX(16px);
}
.ios-toggle:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

/* ── Firmas: pulso stat-card Sin validar ── */
.firmas-pulse-low {
    animation: firmasPulseLow 2s ease-in-out infinite;
    border-color: #eab308 !important;
}
.firmas-pulse-mid {
    animation: firmasPulseMid 1.5s ease-in-out infinite;
    border-color: #f97316 !important;
}
.firmas-pulse-high {
    animation: firmasPulseHigh 1.2s ease-in-out infinite;
    border-color: #ea580c !important;
}
.firmas-pulse-crit {
    animation: firmasPulseCrit 0.8s ease-in-out infinite;
    border-color: #dc2626 !important;
}

@keyframes firmasPulseLow {
    0%, 100% { box-shadow: 0 0 0 0 rgba(234, 179, 8, 0.4); }
    50% { box-shadow: 0 0 0 4px rgba(234, 179, 8, 0); }
}
@keyframes firmasPulseMid {
    0%, 100% { box-shadow: 0 0 0 0 rgba(249, 115, 22, 0.5); }
    50% { box-shadow: 0 0 0 6px rgba(249, 115, 22, 0); }
}
@keyframes firmasPulseHigh {
    0%, 100% { box-shadow: 0 0 0 0 rgba(234, 88, 12, 0.6); background-color: rgba(234, 88, 12, 0.05); }
    50% { box-shadow: 0 0 0 8px rgba(234, 88, 12, 0); background-color: rgba(234, 88, 12, 0.12); }
}
@keyframes firmasPulseCrit {
    0%, 100% { box-shadow: 0 0 0 0 rgba(220, 38, 38, 0.7); background-color: rgba(220, 38, 38, 0.05); }
    50% { box-shadow: 0 0 0 10px rgba(220, 38, 38, 0); background-color: rgba(220, 38, 38, 0.15); }
}

/* ── Ventas: pulso del statcard de Diferencia según la gravedad del descuadre ──
   sobra → verde fuerte · leve (1,5–10 €) → naranja suave ·
   medio (10–39 €) → naranja intenso · grave (>39 €) → rojo intenso.
   Anclado a #cardDiferencia para GANAR a `.cf-zoom-in > *` (app.css), que mete
   un `animation` de entrada en cada hijo del #cuadreDia y, con menos
   especificidad, pisaría este pulso dejándolo inexistente.
   El glow es `inset` (hacia DENTRO): el .cf-card que envuelve la página tiene
   overflow:hidden y recortaría un resplandor exterior; el latido (scale) y el
   tinte de fondo también van dentro del propio card, así que siempre se ven. */
#cardDiferencia.cf-dif-pulse-sobra  { animation: cfDifPulseSobra  1.2s  ease-in-out infinite; }
#cardDiferencia.cf-dif-pulse-soft   { animation: cfDifPulseSoft   2s    ease-in-out infinite; }
#cardDiferencia.cf-dif-pulse-mid    { animation: cfDifPulseMid    1.4s  ease-in-out infinite; }
#cardDiferencia.cf-dif-pulse-strong { animation: cfDifPulseStrong 0.85s ease-in-out infinite; }

@keyframes cfDifPulseSobra {
    0%, 100% { transform: scale(1);     background-color: rgba(16, 185, 129, 0.08); border-color: rgba(16, 185, 129, 0.5);  box-shadow: inset 0 0 0 0 rgba(16, 185, 129, 0); }
    50%      { transform: scale(1.045); background-color: rgba(16, 185, 129, 0.24); border-color: rgba(16, 185, 129, 0.95); box-shadow: inset 0 0 16px 2px rgba(16, 185, 129, 0.55); }
}
@keyframes cfDifPulseSoft {
    0%, 100% { transform: scale(1);     background-color: rgba(245, 158, 11, 0.08); border-color: rgba(245, 158, 11, 0.5);  box-shadow: inset 0 0 0 0 rgba(245, 158, 11, 0); }
    50%      { transform: scale(1.02);  background-color: rgba(245, 158, 11, 0.20); border-color: rgba(245, 158, 11, 0.9);  box-shadow: inset 0 0 11px 1px rgba(245, 158, 11, 0.45); }
}
@keyframes cfDifPulseMid {
    0%, 100% { transform: scale(1);     background-color: rgba(234, 88, 12, 0.09);  border-color: rgba(234, 88, 12, 0.55); box-shadow: inset 0 0 0 0 rgba(234, 88, 12, 0); }
    50%      { transform: scale(1.035); background-color: rgba(234, 88, 12, 0.24);  border-color: rgba(234, 88, 12, 0.95); box-shadow: inset 0 0 14px 2px rgba(234, 88, 12, 0.55); }
}
@keyframes cfDifPulseStrong {
    0%, 100% { transform: scale(1);     background-color: rgba(220, 38, 38, 0.10);  border-color: rgba(220, 38, 38, 0.6);  box-shadow: inset 0 0 0 0 rgba(220, 38, 38, 0); }
    50%      { transform: scale(1.05);  background-color: rgba(220, 38, 38, 0.28);  border-color: rgba(220, 38, 38, 1);    box-shadow: inset 0 0 18px 3px rgba(220, 38, 38, 0.65); }
}

.badge-baja-voluntaria {
    animation: bajaVoluntariaPulse 1.5s ease-in-out infinite;
}
@keyframes bajaVoluntariaPulse {
    0%, 100% { box-shadow: 0 0 0 0 rgba(234, 88, 12, 0.5); }
    50% { box-shadow: 0 0 0 6px rgba(234, 88, 12, 0); }
}

/* Badge "No es válido" — para datos del empleado que no cumplen normativa */
@keyframes badgeNoValidoPulse {
    0%, 100% {
        box-shadow: 0 0 0 0 rgba(220, 38, 38, 0.55);
        transform: scale(1);
    }
    50% {
        box-shadow: 0 0 0 6px rgba(220, 38, 38, 0);
        transform: scale(1.05);
    }
}
.badge-no-valido {
    display: inline-flex;
    align-items: center;
    padding: 1px 7px;
    margin-left: 0.4rem;
    border: 1px solid #DC2626;
    background: #FEE2E2;
    color: #DC2626;
    border-radius: 9999px;
    font-size: 0.6rem;
    font-weight: 700;
    line-height: 1.4;
    letter-spacing: 0.02em;
    white-space: nowrap;
    vertical-align: middle;
    animation: badgeNoValidoPulse 1.6s ease-in-out infinite;
}

/* ──────────────────────────────────────────────────────────────
   Alertas de alta sensibilidad: borde grueso pulsante + backdrop coloreado
   ─ swal-danger-* : ROJO  (acciones críticas: ascender a Root, CeibeCONTA)
   ─ swal-warn-*   : NARANJA (acciones importantes: ascender a Admin)
   ──────────────────────────────────────────────────────────────*/
@keyframes ceibeDangerPulseRing {
    0%, 100% { box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.75), 0 25px 50px -12px rgba(0,0,0,.45); }
    50%      { box-shadow: 0 0 0 18px rgba(239, 68, 68, 0),  0 25px 50px -12px rgba(0,0,0,.45); }
}
.swal-danger-pulse {
    border: 4px solid #ef4444 !important;
    animation: ceibeDangerPulseRing 1.4s ease-in-out infinite;
}
.swal-danger-backdrop.swal2-container {
    background: rgba(127, 29, 29, 0.62) !important;
    backdrop-filter: blur(3px);
    -webkit-backdrop-filter: blur(3px);
}

@keyframes ceibeWarnPulseRing {
    0%, 100% { box-shadow: 0 0 0 0 rgba(249, 115, 22, 0.75), 0 25px 50px -12px rgba(0,0,0,.4); }
    50%      { box-shadow: 0 0 0 18px rgba(249, 115, 22, 0),  0 25px 50px -12px rgba(0,0,0,.4); }
}
.swal-warn-pulse {
    border: 4px solid #f97316 !important;
    animation: ceibeWarnPulseRing 1.4s ease-in-out infinite;
}
.swal-warn-backdrop.swal2-container {
    background: rgba(154, 52, 18, 0.58) !important;
    backdrop-filter: blur(3px);
    -webkit-backdrop-filter: blur(3px);
}

/* ============================================================
   Chat IA (panel lateral + ventana flotante) — assets/js/ia_chat.js
   ============================================================ */
.ia-iconbtn {
    width: 1.5rem;
    height: 1.5rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 0.375rem;
    color: #9ca3af;
    transition: background-color .15s ease, color .15s ease;
}
.ia-iconbtn:hover { background: #f3f4f6; color: #4b5563; }

.ia-iconbtn-lg {
    width: 2.25rem;
    height: 2.25rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 0.5rem;
    color: #6b7280;
    background: #f9fafb;
    border: 1px solid #e5e7eb;
    transition: background-color .15s ease, color .15s ease;
}
.ia-iconbtn-lg:hover { background: #f3e8ff; color: #a21caf; border-color: #e9d5ff; }

/* Resalte al arrastrar archivos sobre el chat */
.ia-drop-active { outline: 2px dashed #d946ef; outline-offset: -6px; background: #fdf4ff; }

/* Cursor parpadeante mientras la IA escribe en streaming */
.ia-caret {
    display: inline-block; width: 7px; height: 1em; margin-left: 1px;
    background: #a21caf; border-radius: 1px; vertical-align: text-bottom;
    animation: iaCaretBlink 1s steps(1) infinite;
}
@keyframes iaCaretBlink { 50% { opacity: 0; } }

/* Ítems del menú "⋮" / selector de proveedor del chat */
.ia-menuitem {
    display: flex; align-items: center; gap: .55rem; width: 100%;
    padding: .5rem .75rem; font-size: 12px; color: #4b5563; text-align: left;
    transition: background-color .12s ease;
}
.ia-menuitem:hover { background: #faf5ff; }

/* Botón activo (modo imagen, desplegable abierto) */
.ia-iconbtn.ia-active { background: #f3e8ff; color: #a21caf; }
/* Botón activo en modo datos (azul) */
.ia-iconbtn.ia-active-sky { background: #e0f2fe; color: #0369a1; }

/* Selector de proveedor icon-only (esquina superior izquierda) */
.ia-prov-trigger {
    display: inline-flex; align-items: center; height: 1.75rem; padding: 0 .5rem;
    border-radius: 0.5rem; border: 1px solid #e9d5ff; background: #faf5ff;
    transition: background-color .15s ease, border-color .15s ease;
}
.ia-prov-trigger:hover { background: #f3e8ff; border-color: #d8b4fe; }
.ia-prov-trigger.ia-active { background: #f3e8ff; border-color: #c084fc; }
.ia-prov-trigger:disabled { opacity: .5; cursor: default; }

/* Ventana flotante: el tirador de resize nativo (esquina) */
#iaChatModal { box-shadow: 0 20px 50px -12px rgba(0,0,0,.35), 0 8px 16px -8px rgba(0,0,0,.2); }

/* ---- Markdown renderizado (.ia-md) ---- */
.ia-md .ia-p { margin: 0 0 .5rem; line-height: 1.5; }
.ia-md .ia-p:last-child { margin-bottom: 0; }
.ia-md .ia-h { font-weight: 700; line-height: 1.3; margin: .6rem 0 .35rem; color: #374151; }
.ia-md .ia-h:first-child { margin-top: 0; }
.ia-md .ia-h1 { font-size: 1.05rem; }
.ia-md .ia-h2 { font-size: 1rem; }
.ia-md .ia-h3 { font-size: .92rem; }
.ia-md .ia-h4, .ia-md .ia-h5, .ia-md .ia-h6 { font-size: .85rem; }
.ia-md .ia-ul, .ia-md .ia-ol { margin: 0 0 .5rem; padding-left: 1.25rem; }
.ia-md .ia-ul { list-style: disc; }
.ia-md .ia-ol { list-style: decimal; }
.ia-md .ia-ul li, .ia-md .ia-ol li { margin: .12rem 0; line-height: 1.45; }
.ia-md strong { font-weight: 700; }
.ia-md em { font-style: italic; }
.ia-md del { text-decoration: line-through; opacity: .7; }
.ia-md .ia-link { color: #7c3aed; text-decoration: underline; word-break: break-word; }
.ia-md .ia-link:hover { color: #6d28d9; }
.ia-md .ia-inline-code {
    background: #ede9fe; color: #6d28d9; padding: .05rem .3rem; border-radius: .25rem;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: .82em;
}
.ia-md .ia-code {
    background: #1e1b2e; color: #e9e3ff; padding: .6rem .75rem; border-radius: .5rem;
    overflow-x: auto; margin: 0 0 .55rem; font-size: .78rem; line-height: 1.45;
}
.ia-md .ia-code code { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; white-space: pre; }
.ia-md .ia-quote {
    border-left: 3px solid #d8b4fe; padding: .15rem .6rem; margin: 0 0 .5rem;
    color: #6b7280; background: #faf5ff; border-radius: 0 .35rem .35rem 0;
}
.ia-md .ia-hr { border: 0; border-top: 1px solid #e5e7eb; margin: .6rem 0; }
.ia-md .ia-table {
    border-collapse: collapse; width: 100%; margin: 0 0 .55rem; font-size: .78rem; display: block; overflow-x: auto;
}
.ia-md .ia-table th, .ia-md .ia-table td { border: 1px solid #e5e7eb; padding: .3rem .5rem; text-align: left; }
.ia-md .ia-table th { background: #f5f3ff; font-weight: 600; color: #4b5563; }
.ia-md .ia-table tr:nth-child(even) td { background: #fafafa; }

/* ── Badge "nueva versión" del Service Worker ────────────────────────
   Sin icono de fuente: un SVG propio (includes/header.php) donde la flecha
   sube en bucle sobre una barra que se rellena, todo en `currentColor`, así
   que hereda el vaivén de color del botón. El botón entero respira entre dos
   verdes de la marca (emerald ↔ teal) en el mismo ciclo de 2,4 s. */
@keyframes swUpdateBorder {
    0%, 100% { border-color: #10b981; }      /* emerald-500 */
    50%      { border-color: #14b8a6; }      /* teal-500    */
}
@keyframes swUpdateIcon {
    0%, 100% { color: #059669; }             /* emerald-600 */
    50%      { color: #0d9488; }             /* teal-600    */
}
@keyframes swUpdateBg {
    0%, 100% { background-color: #ecfdf5; }  /* emerald-50 */
    50%      { background-color: #f0fdfa; }  /* teal-50    */
}
.sw-update-btn {
    border-color: #10b981;
    animation: swUpdateBorder 2.4s ease-in-out infinite,
               swUpdateBg     2.4s ease-in-out infinite;
}
.sw-update-btn .sw-update-icon {
    display: inline-block;
    animation: swUpdateIcon 2.4s ease-in-out infinite;
}

/* Dentro del SVG: la flecha sube y reaparece por abajo; la barra se rellena
   de izquierda a derecha. Mismo ciclo de 2,4 s que el color. */
@keyframes swUpdateArrow {
    0%   { transform: translateY(4px);  opacity: 0; }
    18%  { transform: translateY(0);    opacity: 1; }
    62%  { transform: translateY(0);    opacity: 1; }
    82%  { transform: translateY(-4px); opacity: 0; }
    100% { transform: translateY(4px);  opacity: 0; }
}
@keyframes swUpdateFill {
    0%   { transform: scaleX(0); opacity: 1; }
    70%  { transform: scaleX(1); opacity: 1; }
    90%  { transform: scaleX(1); opacity: 0; }
    100% { transform: scaleX(0); opacity: 0; }
}
.sw-update-btn .sw-up-arrow {
    animation: swUpdateArrow 2.4s ease-in-out infinite;
}
.sw-update-btn .sw-up-fill {
    transform-box: fill-box;      /* origen = caja del rect, no del viewBox */
    transform-origin: left center;
    animation: swUpdateFill 2.4s ease-in-out infinite;
}
/* El fondo está animado: un hover que lo repinte no se vería.
   Feedback por brillo, que sí compone sobre la animación. */
.sw-update-btn:hover { filter: brightness(.95); }
@media (prefers-reduced-motion: reduce) {
    .sw-update-btn,
    .sw-update-btn .sw-update-icon,
    .sw-update-btn .sw-up-arrow,
    .sw-update-btn .sw-up-fill { animation: none; }
}

/* ====================================================================
   Actualización del Service Worker — animación "copia de archivos"
   (homenaje a la copia de Windows 7: papelitos volando en arco del
   archivo nuevo al viejo + barra de progreso verde con brillo Aero).
   Markup en includes/footer.php (modal "Actualizando…").
   ==================================================================== */
.sw-update-anim { padding-top: 0.25rem; }

.sw-update-scene {
    position: relative;
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    width: 240px;
    margin: 0.75rem auto 1.1rem;
}

.sw-update-doc {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    width: 72px;
}
.sw-update-doc i { font-size: 2.6rem; }
.sw-update-doc span {
    font-family: ui-monospace, monospace;
    font-size: 0.68rem;
    line-height: 1;
}
.sw-update-doc-new i {
    color: #10b981;
    filter: drop-shadow(0 4px 10px rgba(16, 185, 129, 0.35));
}
.sw-update-doc-new span { color: #059669; font-weight: 700; }
.sw-update-doc-old i {
    color: #cbd5e1;
    animation: swDocOldPulse 1.8s ease-in-out infinite;
}
.sw-update-doc-old span { color: #94a3b8; text-decoration: line-through; }

/* El archivo viejo "late" cada vez que recibe un papelito */
@keyframes swDocOldPulse {
    0%, 72% { transform: scale(1); }
    86%     { transform: scale(1.12); }
    100%    { transform: scale(1); }
}

/* Papelitos volando en arco (3 desfasados → flujo continuo) */
.sw-update-flight {
    position: absolute;
    left: 58px;
    top: 12px;
    width: 124px;
    height: 44px;
    pointer-events: none;
}
.sw-update-paper {
    position: absolute;
    left: 0;
    top: 12px;
    width: 14px;
    height: 18px;
    background: #fff;
    border: 1.5px solid #10b981;
    border-radius: 3px;
    box-shadow: 0 2px 5px rgba(16, 185, 129, 0.30);
    opacity: 0;
    animation: swPaperFly 1.8s cubic-bezier(0.45, 0.05, 0.55, 0.95) infinite;
}
/* Rayitas de "texto" del papelito */
.sw-update-paper::before,
.sw-update-paper::after {
    content: '';
    position: absolute;
    left: 2.5px;
    right: 2.5px;
    height: 1.5px;
    background: rgba(16, 185, 129, 0.55);
    border-radius: 1px;
}
.sw-update-paper::before { top: 4px; }
.sw-update-paper::after  { top: 8px; right: 5px; }

.sw-update-paper:nth-child(2) { animation-delay: 0.6s; }
.sw-update-paper:nth-child(3) { animation-delay: 1.2s; }

@keyframes swPaperFly {
    0%   { transform: translate(0, 0) rotate(0deg) scale(0.55); opacity: 0; }
    12%  { opacity: 1; }
    35%  { transform: translate(40px, -16px) rotate(10deg) scale(1); }
    65%  { transform: translate(80px, -14px) rotate(14deg) scale(1); opacity: 1; }
    100% { transform: translate(112px, 8px) rotate(6deg) scale(0.5); opacity: 0; }
}

/* Barra de progreso indeterminada estilo Win7 (verde + brillo que cruza) */
.sw-update-bar {
    position: relative;
    width: 240px;
    height: 14px;
    margin: 0 auto;
    border: 1px solid #d1d5db;
    border-radius: 4px;
    background: linear-gradient(to bottom, #f3f4f6, #e5e7eb);
    overflow: hidden;
}
.sw-update-bar-fill {
    position: absolute;
    inset: 1px;
    border-radius: 3px;
    background: linear-gradient(to bottom, #6ee7b7 0%, #34d399 45%, #10b981 50%, #34d399 100%);
    overflow: hidden;
}
.sw-update-bar-fill::after {
    content: '';
    position: absolute;
    top: 0;
    bottom: 0;
    left: -45%;
    width: 45%;
    background: linear-gradient(to right, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.85) 50%, rgba(255, 255, 255, 0) 100%);
    animation: swBarShine 1.6s linear infinite;
}
@keyframes swBarShine {
    from { left: -45%; }
    to   { left: 100%; }
}

.sw-update-hint {
    margin-top: 0.8rem;
    font-size: 0.8rem;
    color: #6b7280;
}

/* ─────────────────────────────────────────────────────────────
   Gestoría — edición manual antes de compartir (solo backoffice).
   El sello (.gestoria-edited / .gestoria-edit-flag) NO se exporta al
   enlace compartido: vive únicamente en esta vista.
   ───────────────────────────────────────────────────────────── */
.gestoria-editable { cursor: context-menu; transition: background-color .12s, outline-color .12s; }
.gestoria-editable:hover { background-color: #fffbeb; outline: 1px dashed #fcd34d; outline-offset: -1px; }
.gestoria-edited { background-color: #fef3c7 !important; }
.gestoria-edit-flag {
    display: inline-block;
    margin-left: 4px;
    font-size: 9px;
    font-weight: 700;
    color: #b45309;
    text-transform: uppercase;
    letter-spacing: .02em;
    vertical-align: middle;
}
#gestoria-ctxmenu .gestoria-ctx-item {
    display: flex; align-items: center; gap: 9px;
    width: 100%; text-align: left; padding: 8px 12px;
    background: transparent; border: 1px solid transparent; border-radius: 6px;
    cursor: pointer; white-space: nowrap; font: inherit; line-height: 1.3;
    transition: background-color .1s, border-color .1s;
}
#gestoria-ctxmenu .gestoria-ctx-item:hover { background-color: #eff6ff; border-color: #bfdbfe; }

/* Números del informe de gestoría en monoespaciado (con cifras tabulares) */
.gnum { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace; font-variant-numeric: tabular-nums; }

/* Registros borrables (fila completa, clic derecho → eliminar/restaurar) */
tr.gestoria-record { cursor: context-menu; }
tr.gestoria-record-deleted > td { text-decoration: line-through; color: #9ca3af !important; background: #fafafa; }
tr.gestoria-del-note > td { background: #fafafa; }

/* ── Panel lateral de estados (Facturas emitidas; patrón firmas de CeibeRRHH,
   en verde de marca). El aside lista los estados con su contador y filtra la
   tabla principal al hacer clic. ── */
.cf-estado-item {
    display: flex; align-items: center; gap: .6rem;
    padding: .5rem .7rem; border-radius: 10px;
    border: 1px solid transparent; background: transparent;
    cursor: pointer; text-align: left; white-space: nowrap;
    flex: 0 0 auto; transition: background .15s, border-color .15s;
}
@media (min-width: 1024px) { .cf-estado-item { width: 100%; } }
.cf-estado-item:hover { background: #f0fdf4; }                 /* emerald-50 */
.cf-estado-item.active { background: #d1fae5; border-color: #6ee7b7; }  /* emerald-100/300 */
.cf-estado-ico { width: 18px; text-align: center; font-size: 14px; flex-shrink: 0; }
.cf-estado-label {
    font-size: 13px; font-weight: 500; color: #374151;
    flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis;
}
.cf-estado-item.active .cf-estado-label { color: #047857; font-weight: 600; }  /* emerald-700 */
.cf-estado-count {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 13px; font-weight: 700; flex-shrink: 0;
}

/* Botón "liquid glass": superficie translúcida con desenfoque, para barras
   sobre fondos de cristal (p. ej. la barra del visor de PDF). */
.cf-glass-btn {
    display: inline-flex; align-items: center; gap: .5rem;
    padding: .5rem .95rem; border-radius: 12px;
    font-size: 13px; font-weight: 600; color: #134e4a;            /* teal-900 */
    background: rgba(255, 255, 255, .45);
    border: 1px solid rgba(255, 255, 255, .65);
    box-shadow: 0 1px 2px rgba(0, 0, 0, .06), inset 0 1px 0 rgba(255, 255, 255, .6);
    -webkit-backdrop-filter: blur(8px) saturate(1.3);
    backdrop-filter: blur(8px) saturate(1.3);
    cursor: pointer; text-decoration: none; white-space: nowrap;
    transition: background .15s, box-shadow .15s, transform .1s;
}
.cf-glass-btn:hover { background: rgba(255, 255, 255, .74); box-shadow: 0 2px 7px rgba(0, 0, 0, .1), inset 0 1px 0 rgba(255, 255, 255, .7); }
.cf-glass-btn:active { transform: translateY(1px); }
.cf-glass-btn i { font-size: 14px; }
.cf-glass-btn.is-close { color: #9f1239; }                        /* rose-800 */
.cf-glass-btn.is-close:hover { background: rgba(255, 241, 242, .85); }
@media (max-width: 520px) { .cf-glass-btn span { display: none; } }  /* solo icono en móvil */

/* ════════════════════════════════════════════════════════════════════
   Modal de Factura emitida — tamaño fijo + 2 tarjetas + scroll en conceptos
   El selector compuesto .cf-modal-glass.fe-modal-fixed gana en especificidad
   al .cf-modal-glass de app.css (que se carga después), anulando su scroll
   global para que solo scrollee la lista de conceptos.
   ════════════════════════════════════════════════════════════════════ */
.cf-modal-glass.fe-modal-fixed {
    width: min(960px, 96vw);
    height: min(88vh, 800px);
    max-height: 92vh;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}
.fe-body {
    flex: 1; min-height: 0;
    display: flex; flex-direction: column; gap: .55rem;
    padding: .6rem .7rem .7rem;
    overflow: hidden;
}
.fe-card {
    background: rgba(255, 255, 255, .55);
    border: 1.5px solid rgba(17, 94, 89, .12);
    border-radius: .8rem;
    overflow: hidden;
    flex-shrink: 0;
}
.fe-card-head {
    font-size: .76rem; font-weight: 600; letter-spacing: .015em;
    color: #0f766e;                                  /* teal-700 */
    padding: .4rem .7rem;
    background: rgba(16, 185, 129, .07);
    border-bottom: 1px solid rgba(17, 94, 89, .1);
}
.fe-card-body { padding: .6rem .7rem; }
.fe-label { display: block; font-size: .74rem; font-weight: 500; color: rgba(4, 47, 46, .72); margin-bottom: .2rem; }

/* Tarjeta de conceptos: cabecera fija + lista scrollable + totales fijos */
.fe-conceptos { flex: 1 1 auto; min-height: 150px; display: flex; flex-direction: column; }
.fe-lineas-scroll { flex: 1; min-height: 0; overflow-y: auto; padding: 0; }   /* sin padding: header pegado y a ras */
.fe-lineas-table { border-collapse: separate; border-spacing: 0; }

/* Cabecera de la lista: pegada al header del card, sticky, sombra hacia abajo */
.fe-th {
    position: sticky; top: 0; z-index: 2;
    background: #fff; color: #334155;                /* slate-700 (gris oscuro) */
    font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: .02em;
    white-space: nowrap; padding: .45rem .35rem;
    border-bottom: 1px solid #e5e7eb;
    box-shadow: 0 3px 5px -2px rgba(15, 23, 42, .16);
}
.fe-th:first-child { padding-left: .55rem; }
.fe-th:last-child  { padding-right: .55rem; }

/* Filas compactas */
.fe-cell { padding: 2px 3px; vertical-align: middle; }
.fe-cell:first-child { padding-left: .45rem; }
.fe-cell:last-child  { padding-right: .45rem; }
.fe-linea + .fe-linea .fe-cell { border-top: 1px solid #f1f5f9; }
.fe-numcell { text-align: center; font-size: 11px; color: #94a3b8; font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace; }

.fe-lineas-foot {
    display: flex; justify-content: flex-end; gap: 1.25rem;
    padding: .4rem .7rem; font-size: .8rem;
    border-top: 1px solid rgba(17, 94, 89, .1);
    background: rgba(255, 255, 255, .5);
}

/* Pie de acciones */
.fe-foot { display: flex; align-items: center; gap: .6rem; flex-shrink: 0; padding-top: .1rem; }

/* Toggle VeriFactu / Ordinaria */
.fe-mode-toggle {
    display: inline-flex; gap: 2px; padding: 3px;
    background: rgba(255, 255, 255, .6);
    border: 1.5px solid rgba(17, 94, 89, .14);
    border-radius: .7rem;
}
.fe-mode-toggle button {
    display: inline-flex; align-items: center; gap: .4rem;
    padding: .32rem .7rem; border-radius: .5rem;
    font-size: .76rem; font-weight: 600; color: rgba(4, 47, 46, .55);
    transition: all .15s ease; white-space: nowrap;
}
.fe-mode-toggle button i { font-size: .8rem; }
.fe-mode-toggle button.active { background: #059669; color: #fff; box-shadow: 0 2px 6px rgba(5, 150, 105, .3); }
.fe-mode-toggle button:not(.active):hover { color: #0f766e; background: rgba(16, 185, 129, .1); }
.fe-mode-toggle.is-locked { opacity: .55; pointer-events: none; }   /* factura ya emitida: modo fijo */
@media (max-width: 560px) { .fe-mode-toggle button span { display: none; } }

/* Botón "+" de creación rápida: mismo alto que el input contiguo y cuadrado.
   align-self:stretch lo iguala a la altura de la fila (= el input); aspect-ratio
   lo mantiene cuadrado sea cual sea ese alto. */
.fe-add-btn {
    flex: 0 0 auto; align-self: center;
    width: 2.25rem; height: 2.25rem;     /* cuadrado exacto = altura de los inputs */
    box-sizing: border-box; padding: 0;
    border-radius: .6rem;
    display: inline-flex; align-items: center; justify-content: center;
    color: #059669; background: rgba(16, 185, 129, .1);
    border: 1.5px solid rgba(16, 185, 129, .25);
    transition: all .15s ease;
}
.fe-add-btn:hover { background: #059669; color: #fff; }

/* Enlace fantasma (cabecera de conceptos) */
.fe-ghost-link { font-size: .76rem; font-weight: 600; color: #059669; }
.fe-ghost-link:hover { color: #047857; text-decoration: underline; }

/* Opción especial "+ Nuevo impuesto…" dentro del select de impuesto */
.fe-opt-new { color: #059669; font-weight: 600; background: #f0fdf4; }

/* ════ Modal de Factura recibida (mismo lenguaje, altura según contenido) ════ */
.cf-modal-glass.fr-modal {
    width: min(720px, 96vw);
    max-height: 92vh;
    display: flex; flex-direction: column;
    overflow: hidden;
}
.fr-form {
    flex: 1; min-height: 0;
    display: flex; flex-direction: column; gap: .6rem;
    padding: .7rem .85rem .8rem;
    overflow: hidden;
}
.fr-scroll { flex: 1; min-height: 0; overflow-y: auto; display: flex; flex-direction: column; gap: .6rem; }
/* El desglose de recibida no necesita cabecera pegajosa (pocas filas) */
.fr-desglose .fe-th { position: static; }
.fr-resto-btn {
    width: 26px; height: 26px; border-radius: .4rem;
    color: #059669; border: 1.5px solid rgba(16, 185, 129, .25); background: rgba(16, 185, 129, .08);
    display: inline-flex; align-items: center; justify-content: center; transition: all .15s ease;
}
.fr-resto-btn:hover { background: #059669; color: #fff; }

/* Logo de la empresa emisora (solo si lo tiene; sin placeholder) */
.fe-logo-wrap { flex-shrink: 0; }
.fe-logo-chip { width: 34px; height: 34px; border-radius: .5rem; object-fit: contain; background: #fff; border: 1px solid #e5e7eb; padding: 2px; }

/* ════ Apariencia unificada de TODOS los modales glass (config + facturas) ════
   Mismo lenguaje que los modales de factura emitida/recibida: botones planos
   (borde fino, hover marcado, SIN elevación) e inputs compactos. Se aplica a
   `.cf-modal-glass` para que TODOS los modales de configuración compartan el
   mismo aspecto sin tocar el markup de cada uno. (.cf-modal-flat-btns queda
   como alias histórico; ya no es necesaria pero no estorba.) */
.cf-modal-glass .material-btn-primary,
.cf-modal-flat-btns .material-btn-primary {
    border: 1.5px solid #047857 !important;
    box-shadow: none !important;
    transition: background .15s ease, border-color .15s ease, filter .15s ease;
}
.cf-modal-glass .material-btn-primary:hover,
.cf-modal-flat-btns .material-btn-primary:hover {
    transform: none !important; box-shadow: none !important;
    filter: brightness(.93);
}
.cf-modal-glass .material-btn-secondary,
.cf-modal-flat-btns .material-btn-secondary {
    border: 1.5px solid #cbd5e1 !important;
    box-shadow: none !important;
    transition: background .15s ease, border-color .15s ease;
}
.cf-modal-glass .material-btn-secondary:hover,
.cf-modal-flat-btns .material-btn-secondary:hover {
    transform: none !important; box-shadow: none !important;
    background: #e2e8f0 !important; border-color: #94a3b8 !important; color: #334155 !important;
}
/* Inputs compactos y de altura uniforme (2.25rem) en todos los modales glass.
   El selector compuesto (0,2,0) gana a las utilidades Tailwind inline (0,1,0)
   `px-4 py-2.5`, así que compacta sin editar el markup. La altura fija deja que
   los botones «+» cuadren exactos con los inputs. */
.cf-modal-glass .material-input {
    padding: .375rem .75rem;
    font-size: 13px;
    min-height: 2.25rem;
}
.cf-modal-glass textarea.material-input { min-height: 4.5rem; }
.cf-modal-glass .material-input:focus,
.cf-modal-flat-btns .material-input:focus { transform: none; }
/* Toggle de modo: estado activo plano (sin sombra) */
.fe-mode-toggle button.active { box-shadow: none; }


/* El modal de Factura recibida puede abrirse SOBRE el modal de Registro de
   venta (botón "Facturas efec." del cuadre en vivo). Ambos son cf-modal-overlay
   (z-index:50) y el de registro va después en el DOM, así que el de factura
   necesita un z-index mayor para quedar por encima (y de sus popovers z-[60]). */
#facturaModal { z-index: 70; }

/* Modal apilado SOBRE otro modal (p.ej. crear proveedor desde el modal de
   factura recibida, que está a z-70): debe quedar por encima de todo. */
.cf-modal-overlay.cf-modal-stacked { z-index: 90; }

/* ── Validación NO bloqueante de campos (window.fields) ──────────────── */
.cf-input-invalid {
    border-color: #f59e0b !important;
    background-color: #fffbeb;
}
.cf-field-hint {
    margin-top: .3rem;
    font-size: 11px; line-height: 1.2;
    color: #b45309;
    display: flex; align-items: center; gap: .35rem;
}
.cf-field-hint i { font-size: 10px; }

/* ── Selector de familia con color + icono (modal factura recibida) ──── */
.cf-fam-select { position: relative; }
.cf-fam-select > button { width: 100%; }
.cf-fam-chip {
    width: 22px; height: 22px; border-radius: 6px; flex-shrink: 0;
    display: inline-flex; align-items: center; justify-content: center;
    color: #fff; font-size: 11px;
}
.cf-fam-chip.cf-fam-chip-none { background: #e5e7eb; color: #9ca3af; }
.cf-fam-panel {
    position: absolute; left: 0; right: 0; top: calc(100% + 4px); z-index: 30;
    max-height: 240px; overflow-y: auto;
    background: #fff; border: 1px solid #e5e7eb; border-radius: .75rem;
    box-shadow: 0 14px 36px -12px rgba(15, 23, 42, .35);
    padding: .35rem;
}
.cf-fam-opt {
    width: 100%; display: flex; align-items: center; gap: .55rem;
    padding: .4rem .55rem; border-radius: .55rem; text-align: left;
    font-size: 13px; color: #1f2937; transition: background .12s ease;
}
.cf-fam-opt:hover { background: #ecfdf5; }
.cf-fam-opt.is-active { background: #d1fae5; }

/* ── Indicador de entorno DEV (header, junto al user menu) ──────────────
   Píldora discreta en púrpura oscuro con pulso suave. Solo se renderiza en
   beta/local (IS_DEV en config.php); en producción no aparece. */
.env-dev-badge {
    padding: .25rem .55rem;
    border-radius: 9999px;
    background: #3b0764;                          /* purple-950 — púrpura oscuro */
    border: 1px solid rgba(167, 139, 250, .45);   /* violet-400 tenue */
    color: #ede9fe;                               /* violet-100 */
    box-shadow: 0 2px 6px rgba(59, 7, 100, .45);
    animation: envDevGlow 2.4s ease-in-out infinite;
}
.env-dev-text {
    font-size: .625rem;          /* 10px */
    font-weight: 700;
    letter-spacing: .1em;
    line-height: 1;
}
.env-dev-dot {
    width: 6px; height: 6px;
    border-radius: 9999px;
    background: #c4b5fd;          /* violet-300 */
    animation: envDevDot 2.4s ease-in-out infinite;
}
@keyframes envDevGlow {
    0%, 100% { box-shadow: 0 2px 6px rgba(59, 7, 100, .45); }
    50%      { box-shadow: 0 0 12px 1px rgba(124, 58, 237, .55); }  /* violet-600 glow */
}
@keyframes envDevDot {
    0%, 100% { opacity: 1;   box-shadow: 0 0 0 0 rgba(196, 181, 253, .6); }
    50%      { opacity: .55; box-shadow: 0 0 0 4px rgba(196, 181, 253, 0); }
}
@media (prefers-reduced-motion: reduce) {
    .env-dev-badge, .env-dev-dot { animation: none; }
}

/* ─────────── Matriz de cuentas de venta (config/asientos.php · local × familia) ─────────── */
.vm-grid { width: 100%; border-collapse: separate; border-spacing: 0; }
.vm-grid th, .vm-grid td { border-bottom: 1px solid #eef2f7; border-right: 1px solid #eef2f7; }
.vm-corner { position: sticky; left: 0; background: #f1f5f9; z-index: 3; font-weight: 600; padding: 8px 10px; white-space: nowrap; color: #64748b; font-size: 11px; }
.vm-th { background: #f8fafc; vertical-align: bottom; padding: 8px 6px; min-width: 132px; }
.vm-th-in { display: flex; flex-direction: column; align-items: center; gap: 4px; }
.vm-th-name { font-size: 11px; font-weight: 600; color: #475569; text-align: center; line-height: 1.1; }
.vm-fam-chip { width: 26px; height: 26px; border-radius: 8px; display: flex; align-items: center; justify-content: center; color: #fff; font-size: 12px; }
.vm-rowhead { position: sticky; left: 0; background: #fff; z-index: 2; text-align: left; padding: 6px 10px; min-width: 152px; }
.vm-rowhead-in { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.vm-local-name { display: block; font-size: 13px; font-weight: 600; color: #334155; line-height: 1.1; }
.vm-local-code { display: block; font-size: 10px; color: #94a3b8; font-family: ui-monospace, SFMono-Regular, monospace; }
.vm-td { padding: 5px 6px; background: #fff; transition: background .35s ease; }
.vm-td.vm-ok { background: #ecfdf5; }
.vm-sub { width: 100%; border: 1px solid #e2e8f0; border-radius: 7px; padding: 4px 7px; font-family: ui-monospace, SFMono-Regular, monospace; font-size: 12px; text-align: center; color: #0f172a; }
.vm-sub::placeholder { color: #cbd5e1; }
.vm-sub:focus { outline: none; border-color: #10b981; box-shadow: 0 0 0 2px rgba(16,185,129,.15); }
.vm-imp { width: 100%; margin-top: 4px; border: 1px solid #e2e8f0; border-radius: 7px; padding: 3px 5px; font-size: 11px; color: #475569; background: #fff; }
.vm-imp:focus { outline: none; border-color: #10b981; }
.vm-fillbtn { color: #10b981; font-size: 11px; padding: 3px 5px; border-radius: 6px; border: 1px solid transparent; flex-shrink: 0; }
.vm-fillbtn:hover { background: #ecfdf5; border-color: #a7f3d0; }
.vm-grid input:disabled, .vm-grid select:disabled { background: #f8fafc; color: #94a3b8; cursor: not-allowed; }

/* ─────────── Layout con sidebar de Asientos contables (config/asientos.php) ─────────── */
.conta-side { width: 232px; padding: 14px 10px; }
.conta-side-group + .conta-side-group { margin-top: 14px; }
.conta-side-label { font-size: 10px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: #94a3b8; padding: 0 8px; margin-bottom: 6px; }
.conta-side-item { display: flex; align-items: center; gap: 9px; width: 100%; text-align: left; padding: 8px 10px; border-radius: 9px; font-size: 13px; font-weight: 500; line-height: 1.2; transition: background .12s; margin-bottom: 2px; }
.conta-side-item:hover { background: #eef2f7; }
.conta-side-item.bg-emerald-100 { box-shadow: inset 3px 0 0 #10b981; font-weight: 600; }
@media (max-width: 768px) {
    .conta-layout { flex-direction: column; }
    .conta-side { width: 100%; border-right: 0; border-bottom: 1px solid #e5e7eb; }
}
