/* ---------------------------------------------------------------------------
   Action buttons: an icon, and motion that means something.

   The rail already sets the tone - the bell pulses because something is waiting,
   the settings gear turns because it is the one control that opens a panel. This
   extends the same vocabulary to the buttons on the pages, with one rule:

       MOTION REPORTS STATE. It never just decorates.

   So nothing here animates on its own. An icon reacts when you point at it, and
   it spins ONLY while its request is actually in flight. A row of permanently
   spinning icons would be noise, and worse, it would make the one button that IS
   working indistinguishable from the twelve that are not.

   Loaded after main.css and color_skins.css, so the skin's colours win wherever
   they overlap - nothing in here sets a brand colour.
--------------------------------------------------------------------------- */

/* The gap between an icon and its label. Buttons that are icon-only opt out. */
.btn > i.zmdi + span,
.btn > i.zmdi {
  margin-right: 6px;
}
.btn.btn-icon > i.zmdi,
.btn-icon-mini > i.zmdi {
  margin-right: 0;
}

/* Point at a button and its icon leans into the action: forward for something
   that proceeds, a small lift for everything else. 140ms - fast enough to feel
   like a response rather than an animation. */
.btn > i.zmdi {
  display: inline-block;
  transition: transform 140ms ease;
}
.btn:hover > i.zmdi {
  transform: translateY(-1px);
}
.btn-primary:hover > i.zmdi,
.btn-success:hover > i.zmdi {
  transform: translateX(2px);
}
.btn-danger:hover > i.zmdi {
  /* A delete gets a shake rather than a nudge - a half-second of hesitation is
     the right feeling for the button that cannot be undone. */
  animation: fx-shake 420ms ease;
}

/* In flight. Add `is-busy` while the request is running and the icon turns,
   which is the same idiom as the settings gear - and take the pointer away, so
   nobody fires the same request twice. */
.btn.is-busy {
  pointer-events: none;
  opacity: 0.72;
}
.btn.is-busy > i.zmdi {
  animation: fx-spin 900ms linear infinite;
  transform: none;
}

/* An icon-only action inside a table row. Round, quiet until pointed at. */
.btn-icon-mini {
  width: 30px;
  height: 30px;
  padding: 0;
  line-height: 30px;
  text-align: center;
  border-radius: 50%;
  transition: background-color 140ms ease, transform 140ms ease;
}
.btn-icon-mini:hover {
  transform: translateY(-1px);
}

/* A count that has just changed, or an action that needs attention, borrows the
   bell's pulse. Deliberately NOT applied by default - a page where everything
   pulses says nothing. */
.fx-attention {
  position: relative;
}
.fx-attention::after {
  content: '';
  position: absolute;
  top: -2px;
  right: -2px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: currentColor;
  opacity: 0.85;
  animation: fx-heartbit 1.6s ease-out infinite;
}

@keyframes fx-spin {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}

@keyframes fx-shake {
  0%, 100% { transform: translateX(0); }
  25% { transform: translateX(-2px); }
  75% { transform: translateX(2px); }
}

/* The bell's ring, rebuilt here so it can sit on anything rather than only on
   the rail's markup. */
@keyframes fx-heartbit {
  0% { transform: scale(0.6); opacity: 0.9; }
  70% { transform: scale(2.2); opacity: 0; }
  100% { transform: scale(2.2); opacity: 0; }
}

/* Somebody who has asked their system for less movement gets none of it. This
   is not decoration worth overriding an accessibility preference for. */
@media (prefers-reduced-motion: reduce) {
  .btn > i.zmdi,
  .btn.is-busy > i.zmdi,
  .btn-danger:hover > i.zmdi,
  .fx-attention::after,
  .btn-icon-mini {
    animation: none !important;
    transition: none !important;
    transform: none !important;
  }
}
