/* Indicador global de espera (Fase 17, Bloque A).

   Un solo overlay para toda la aplicación: aparece cuando el navegador está esperando al
   servidor y difumina lo que hay detrás, para que se vea que hay algo en curso y que todavía
   no se puede tocar. Los colores salen de los tokens reales de `tokens/colors.css` -- ningún
   token inventado, que es el error que costó T14.22. */

#app-busy {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: none;
  align-items: center;
  justify-content: center;
  /* El difuminado es del FONDO, no del contenido del overlay. */
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  background: var(--surface-overlay);
}

#app-busy[data-visible="true"] { display: flex; }

.busy-panel {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-7) var(--space-8);
  background: var(--surface-card);
  border: var(--border-width-thin) solid var(--border-default);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg, 0 12px 32px rgba(13, 15, 46, 0.18));
}

.busy-spinner {
  width: 42px;
  height: 42px;
  border-radius: 50%;
  border: 3px solid var(--color-navy-100);
  border-top-color: var(--color-navy-500);
  animation: busy-spin 0.8s linear infinite;
}

.busy-text {
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--text-secondary);
  letter-spacing: var(--tracking-tight);
}

.busy-note {
  font-family: var(--font-sans);
  font-size: var(--text-xs);
  color: var(--text-tertiary);
  max-width: 34ch;
  text-align: center;
}

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

/* Respeto por la preferencia del sistema: sin animación, el texto sigue diciendo lo mismo.
   Un indicador de espera no puede depender de que algo gire. */
@media (prefers-reduced-motion: reduce) {
  .busy-spinner { animation: none; border-top-color: var(--color-navy-300); }
}

/* ── Avisos emergentes de trabajos terminados (T17.18) ─────────────────────── */

#job-toasts {
  position: fixed;
  right: var(--space-5);
  bottom: var(--space-5);
  z-index: 1010;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  max-width: min(380px, calc(100vw - 2 * var(--space-5)));
}

.job-toast {
  background: var(--surface-card);
  border: var(--border-width-thin) solid var(--border-default);
  border-left: 4px solid var(--color-navy-500);
  border-radius: var(--radius-md);
  padding: var(--space-4) var(--space-5);
  box-shadow: var(--shadow-lg, 0 12px 32px rgba(13, 15, 46, 0.18));
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.job-toast.done { border-left-color: var(--color-success); }
.job-toast.failed { border-left-color: var(--color-danger); }
.job-toast.cancelled,
.job-toast.interrupted { border-left-color: var(--color-warning); }

.job-toast-title { font-size: var(--text-sm); font-weight: 700; color: var(--text-primary); }
.job-toast-body { font-size: var(--text-xs); color: var(--text-secondary); }
.job-toast-actions { display: flex; gap: var(--space-3); align-items: center; }
.job-toast-actions a { font-size: var(--text-xs); font-weight: 600; }
.job-toast-close {
  margin-left: auto;
  background: none;
  border: none;
  cursor: pointer;
  color: var(--text-tertiary);
  font-size: var(--text-sm);
}

/* Contador de trabajos activos en la barra superior (T17.17). Cuando no hay nada corriendo
   no se pinta: un "0" permanente es ruido, no información. */
.topnav-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  margin-left: 6px;
  border-radius: 9px;
  background: var(--color-sky-500);
  color: var(--color-navy-900);
  font-size: 11px;
  font-weight: 700;
}

.topnav-link.active .topnav-badge {
  background: var(--color-navy-500);
  color: var(--color-white);
}
