/* =========================================================
   mbrd - status surfaces: drop overlay, busy strip, toast

   Non-blocking feedback (import/drop.ts, ui/overlays.ts). The global
   prefers-reduced-motion stop lives at the foot of this file.
   ========================================================= */

#drop-overlay {
  position: fixed;
  inset: 0;
  z-index: var(--z-drop);
  display: grid;
  place-items: center;
  background: color-mix(in srgb, var(--accent-warm) 14%, transparent);
  pointer-events: none;
}
/* Explicit display beats the UA [hidden] rule. */
#drop-overlay[hidden] { display: none; }
/* Same: sidebar wrappers need explicit display:none when [hidden]. */
.field[hidden], .check[hidden], .btn-row[hidden] { display: none; }
#drop-overlay div {
  padding: 16px 30px;
  border: 2px dashed var(--accent-text);
  border-radius: var(--radius);
  background: var(--paper-card);
  box-shadow: var(--shadow-2);
  /* Off the type scale on purpose: a banner read at a glance during a drag. */
  font-size: 19px;
  font-style: var(--display-italic);
  color: var(--accent-deep);
  animation: bloom var(--dur-base) var(--ease-back);
}
@keyframes bloom { from { opacity: 0; transform: scale(0.94) rotate(-1deg); } }

/* ---------------------------------------------------------
   The waiting strip (busy() in ui/overlays.ts)
   --------------------------------------------------------- */
#busy {
  position: fixed;
  /* Below the sidebar, the panels and the menus on purpose. An import runs for
     as long as it runs and the user carries on working over it; a card parked
     on top of whatever they opened next is in the way of the thing they meant
     to look at. It reappears the moment that closes. */
  z-index: var(--z-busy);
  /* Below the toolbar. mobile.css resets this when the bar moves to the foot. */
  top: calc(max(14px, env(safe-area-inset-top)) + var(--toolbar-h) + 10px);
  left: 50%;
  width: min(330px, calc(100vw - 28px));
  padding: 10px 14px 11px;
  border: var(--hairline) solid var(--rule-2);
  border-radius: var(--leaf);
  background: var(--paper-card);
  box-shadow: var(--shadow-2);
  /* .is-up moves to rest; removing the class slides it back offscreen. */
  translate: -50% -14px;
  opacity: 0;
  transition: translate var(--dur-base) var(--ease-back),
              opacity var(--dur-base) var(--ease);
}
#busy.is-up { translate: -50% 0; opacity: 1; }
#busy[hidden] { display: none; }

.busy-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 8px;
}
#busy-label {
  min-width: 0;
  /* Grows to push count and cancel to the right. */
  flex: 1 1 auto;
  /* One line, truncated: wrapping would change the strip's height mid-job. */
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  font-size: var(--t-small);
  font-style: var(--display-italic);
  color: var(--ink);
}
#busy-count {
  flex: none;
  font-family: var(--font-mono);
  font-size: var(--t-tiny);
  font-variant-numeric: tabular-nums;
  color: var(--ink-3);
}
/* Only shown for cancellable jobs (large imports). */
#busy-cancel {
  flex: none;
  margin: -2px -2px -2px 0;
  padding: 2px 6px;
  border: 0;
  border-radius: var(--leaf);
  background: none;
  font: inherit;
  font-size: var(--t-tiny);
  color: var(--ink-3);
  cursor: pointer;
  transition: color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}
#busy-cancel:hover { color: var(--accent-text); background: var(--paper-2); }
#busy-cancel[hidden] { display: none; }

#busy-track {
  position: relative;
  overflow: hidden;
  height: 3px;
  border-radius: var(--radius-xs);
  background: var(--rule);
}
#busy-fill {
  height: 100%;
  border-radius: inherit;
  background: var(--accent);
}

/* Indeterminate mode: CSS transform animation so it runs on the compositor
   and keeps moving during synchronous main-thread work. Using width or left
   instead of translate would put it back on the main thread. */
#busy:not(.is-counting) #busy-fill {
  width: 38%;
  animation: busy-slide 1.15s var(--ease) infinite;
}
@keyframes busy-slide {
  0%   { translate: -100% 0; }
  50%  { translate: 163% 0; }
  100% { translate: -100% 0; }
}

/* Determinate mode: JS-driven width, eased so batch jumps fill smoothly. */
#busy.is-counting #busy-fill {
  width: 0%;
  transition: width var(--dur-base) var(--ease);
}

/* Toast host: bottom-anchored column, click-through; only the lines are solid. */
#toast {
  position: fixed;
  z-index: var(--z-status);
  left: 50%;
  bottom: calc(max(24px, env(safe-area-inset-bottom)) + var(--dock));
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  max-width: min(520px, 90vw);
  pointer-events: none;
}
.toast-line {
  max-width: 100%;
  padding: 10px 20px;
  border: var(--hairline) solid var(--rule-2);
  border-radius: var(--leaf);
  background: var(--paper-card);
  box-shadow: var(--shadow-2);
  font-size: var(--t-small);
  font-style: var(--display-italic);
  text-align: center;
  transform: rotate(-0.5deg);
  pointer-events: auto;
  animation: rise var(--dur-base) var(--ease-back);
  /* Literal 300ms, paired with TOAST_FADE_MS in ui/overlays.ts. Not a token:
     the JS timer and the CSS duration must agree exactly. */
  transition: opacity 300ms var(--ease);
}
.toast-line.is-going { opacity: 0; }
/* The one action a toast can carry - Undo on a removal. */
.toast-act {
  margin-left: 14px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--accent-text);
  font: inherit;
  font-style: normal;
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
}
.toast-line.is-error { border-color: var(--danger); color: var(--danger); }
@keyframes rise { from { opacity: 0; transform: translateY(10px) rotate(-3deg); } }

@media (prefers-reduced-motion: reduce) {
  /* One lap too - an `infinite` loop cut in duration alone strobes. See the
     quality block in quality.css. */
  * {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }

  /* The canvas at 0s, not 0.01ms, and the argument is written out beside the
     same pair of rules in quality.css: under #viewport a duration is not a
     shortening but a transition where there was none, on every property the
     pan and zoom frames rewrite. */
  #viewport, #viewport * { transition-duration: 0s !important; }

  /* Exception: a stopped indeterminate bar reads as false progress at 38%.
     Draw it as a full dim track instead; the counting bar can stand still. */
  #busy:not(.is-counting) #busy-fill {
    width: 100%;
    opacity: 0.4;
    animation: none;
  }
}

/* Fallback for WebKit below 16.2, which lacks color-mix(). */
@supports not (color: color-mix(in srgb, red, blue)) {
  #drop-overlay { background: rgb(var(--accent-warm-c) / 14%); }
}
