/* no-blink.css — global stillness switch.
 *
 * Owner directive 2026-08-21: "remove the entire blinking effect from the
 * whole entire website immediately." Staff read this dashboard all day; a
 * screen full of independently-pulsing dots, breathing panels and scanning
 * gradients is fatiguing and makes genuinely-urgent state impossible to spot.
 *
 * WHY A KILL-SWITCH RATHER THAN EDITING ~40 RULES: the animations are spread
 * across 12 stylesheets plus inline <style> blocks in horizon.html and
 * controlmate.html, which load NO external CSS at all. Editing each rule would
 * have missed some — and a missed shell is exactly how Recording Search stayed
 * invisible earlier today. One rule with !important beats every non-important
 * declaration regardless of source order, including inline <style>.
 *
 * LOAD LAST in every shell.
 */

/* Kill every decorative animation. animation-name:none leaves the other
 * animation-* properties intact, so nothing depends on a shorthand reset. */
*,
*::before,
*::after {
  animation-name: none !important;
}

/* Rotation spinners are progress FEEDBACK, not decoration — a frozen spinner
 * reads as a hung page. Re-enable just those, with a local keyframe so this
 * file does not depend on `spin` existing in whichever stylesheet loaded. */
@keyframes nb-spin { to { transform: rotate(360deg); } }

.spin,
.spinner,
[class*="spinner"],
.login-btn.is-loading::after,
.refresh-btn.loading .spin {
  animation-name: nb-spin !important;
  animation-duration: .8s !important;
  animation-timing-function: linear !important;
  animation-iteration-count: infinite !important;
}

/* Skeleton loaders: keep the element visible and still rather than mid-fade,
 * so a loading placeholder does not sit frozen at 35% opacity. */
.skeleton,
.skeleton::after {
  opacity: 1 !important;
}
