/* Loaders (js/busy.js): the full-page one each app page shows from first paint (#pageLoader) and the
   modal one over a running job (dialog.busy). Both draw the Tabler mark as a connection being made. */

.page-loader {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: grid;
  place-items: center;
  background: var(--paper);
}
.page-loader.leaving { animation: loader-out .22s ease forwards; pointer-events: none; }
@keyframes loader-out { to { opacity: 0; } }

dialog.busy {
  border: 0;
  padding: 0;
  background: transparent;
  overflow: visible;
  max-width: none;
}
dialog.busy::backdrop {
  background: color-mix(in srgb, var(--paper) 62%, transparent);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  animation: loader-in .2s ease;
}
dialog.busy[open] .loader-card { animation: card-pop .22s cubic-bezier(.2, .8, .3, 1); }
dialog.busy:focus { outline: none; }
@keyframes loader-in { from { opacity: 0; } }
@keyframes card-pop { from { opacity: 0; transform: translateY(6px) scale(.97); } }

.loader-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  width: min(320px, calc(100vw - 32px));
  padding: 26px 24px 20px;
  border-radius: 18px;
  background: var(--white);
  border: 1px solid var(--line-soft);
  box-shadow: 0 18px 50px -18px rgba(36, 36, 36, .28), 0 2px 6px rgba(36, 36, 36, .06);
  text-align: center;
}
.page-loader .loader-card { background: transparent; border-color: transparent; box-shadow: none; }

.loader-mark { width: 44px; height: 44px; overflow: visible; }
.loader-wire {
  fill: none;
  stroke: var(--navy);
  stroke-width: 2.4;
  stroke-linecap: round;
  stroke-dasharray: 26;
  animation: wire-draw 1.6s cubic-bezier(.6, 0, .4, 1) infinite;
}
.loader-node {
  fill: var(--white);
  stroke: var(--navy);
  stroke-width: 2.4;
  transform-box: fill-box;
  transform-origin: center;
  animation: node-pulse 1.6s ease-in-out infinite;
}
.loader-node.b { animation-delay: .4s; }
@keyframes wire-draw {
  0% { stroke-dashoffset: 26; }
  45%, 60% { stroke-dashoffset: 0; }
  100% { stroke-dashoffset: -26; }
}
@keyframes node-pulse {
  0%, 100% { transform: scale(1); fill: var(--white); }
  30% { transform: scale(1.14); fill: var(--blue); stroke: var(--blue); }
}

.loader-label {
  margin: 0;
  color: var(--navy);
  font: var(--weight-head) 16px/1.3 var(--font-head);
  letter-spacing: var(--tracking-display);
}
.loader-note { margin: -4px 0 0; color: var(--muted); font-size: 13px; line-height: 1.4; }

.loader-bar {
  position: relative;
  width: 140px;
  height: 3px;
  border-radius: 3px;
  background: var(--line-soft);
  overflow: hidden;
}
.loader-bar::after {
  content: '';
  position: absolute;
  inset: 0 auto 0 0;
  width: 40%;
  border-radius: inherit;
  background: var(--blue);
  animation: bar-slide 1.15s cubic-bezier(.45, 0, .25, 1) infinite;
}
@keyframes bar-slide { from { transform: translateX(-100%); } to { transform: translateX(250%); } }

@media (prefers-reduced-motion: reduce) {
  .loader-wire, .loader-node, .loader-bar::after { animation-duration: 3s; }
  .loader-wire { animation: none; }
  dialog.busy[open] .loader-card, dialog.busy::backdrop { animation: none; }
}

/* A signed-out visitor on app.html goes straight to the login view (the class is set before paint). */
.signed-out .page-loader { display: none; }
