/* ===========================================================================
 * FB04 EmptyState · FB05 Skeleton · FB06 Spinner.
 *
 * The loading rule, which is easy to get backwards: skeletons for CONTENT,
 * spinners for ACTIONS. A spinner where a list is about to appear tells the
 * reader nothing about what is coming; a skeleton in a button is nonsense.
 * ======================================================================== */

.ui-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-8) var(--space-5);
  border: var(--border-width) dashed var(--border-empty);
  border-radius: var(--radius-md);
  text-align: center;
}

/* The glyph sits at 70% gold — present, but not competing with the action
   below it, which is the thing the reader is meant to reach for. */
.ui-empty__icon { color: var(--gold-rest); opacity: 0.7; }

.ui-empty__title {
  font-size: var(--type-body-lg-size);
  line-height: var(--type-body-lg-leading);
  font-weight: var(--font-weight-semibold);
  color: var(--text-primary);
}

.ui-empty__description {
  font-size: var(--type-caption-size);
  line-height: var(--type-caption-leading);
  color: var(--text-tertiary);
}

.ui-empty__action { margin-top: var(--space-2); }

/* --- FB05 Skeleton ------------------------------------------------------
 * Pulsing wash bars. Each successive bar is a fainter wash AND starts later,
 * so the block reads as one object settling rather than three bars flashing
 * in unison. Under prefers-reduced-motion the animation stops and the bars
 * stay visible — the placeholder still does its job stationary.
 * --------------------------------------------------------------------- */
.ui-skeleton {
  display: block;
  height: var(--skeleton-bar);
  border-radius: var(--radius-pill);
  background: var(--surface-1);
}

.ui-skeleton--sm { height: var(--space-3); }
.ui-skeleton--block { height: var(--space-16); border-radius: var(--radius-md); }

.ui-skeleton-group { display: flex; flex-direction: column; gap: var(--space-3); }
.ui-skeleton-group .ui-skeleton:nth-child(2) { background: var(--surface-skeleton-2); }
.ui-skeleton-group .ui-skeleton:nth-child(3) { background: var(--surface-skeleton-3); }

@media (prefers-reduced-motion: no-preference) {
  .ui-skeleton { animation: ui-shimmer var(--duration-shimmer) ease-in-out infinite; }
  .ui-skeleton-group .ui-skeleton:nth-child(2) { animation-delay: var(--duration-shimmer-step); }
  .ui-skeleton-group .ui-skeleton:nth-child(3) { animation-delay: calc(var(--duration-shimmer-step) * 2); }
}

@keyframes ui-shimmer {
  0%, 100% { opacity: 0.5; }
  50% { opacity: 1; }
}

/* --- FB06 Spinner — the standalone form. The in-button one lives in
       button.css because it inherits the button's own colour. ------------ */
.ui-spinner {
  display: inline-block;
  width: var(--icon-lg);
  height: var(--icon-lg);
  border: var(--border-width-stepper) solid var(--gold-rest);
  border-top-color: transparent;
  border-radius: var(--radius-pill);
}

.ui-spinner--sm { width: var(--spinner-size); height: var(--spinner-size); border-width: var(--spinner-stroke); }

@media (prefers-reduced-motion: no-preference) {
  .ui-spinner { animation: ui-spin var(--duration-spin) linear infinite; }
}
