/*
 * loaders.css
 * OWNS: every loading state. Boot screen, skeleton placeholders, spinner.
 * Skeletons are decorative (aria-hidden in markup); spinners carry state via
 * aria-busy plus sr-only text on the control.
 */

/* ------------------------------------------------------------ boot screen */

.boot {
  position: fixed;
  inset: 0;
  z-index: var(--z-overlay);
  display: grid;
  place-items: center;
  background: var(--bg);
  transition: opacity 300ms var(--ease-out);
}

.boot.is-done {
  opacity: 0;
  pointer-events: none;
}

.boot__inner {
  width: min(26rem, 84vw);
  display: flex;
  flex-direction: column;
  gap: var(--s-5);
}

.boot__log {
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
  min-height: 6.5rem;
  font-size: var(--text-xs);
  color: var(--text-muted);
}

.boot__line::before {
  content: "$ ";
  color: var(--gray-8);
}

.boot__line:last-child {
  color: var(--text-emphasis);
}

.boot__track {
  height: 1px;
  background: var(--line-hairline);
  overflow: hidden;
}

.boot__bar {
  display: block;
  height: 100%;
  background: var(--text-emphasis);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 220ms var(--ease-out);
}

.is-booting body {
  overflow: hidden;
}

/* -------------------------------------------------------------- skeletons */

.sk-card {
  display: none;
}

[data-skeleton-group].is-loading .sk-card {
  display: flex;
  flex-direction: column;
  gap: var(--s-4);
  padding: var(--card-pad);
  border: var(--hairline) solid var(--line);
  border-radius: var(--r-xl);
  background: var(--bg);
}

[data-skeleton-group].is-loading > .tier,
[data-skeleton-group].is-loading > .report__body {
  display: none;
}

.sk {
  position: relative;
  display: block;
  overflow: hidden;
  border-radius: var(--r-md);
  background: var(--slate-3);
}

.sk::after {
  content: "";
  position: absolute;
  inset: 0;
  transform: translateX(-100%);
  background: linear-gradient(90deg, transparent, rgb(255 255 255 / 0.05), transparent);
  animation: sk-sweep 1.5s ease-in-out infinite;
}

@keyframes sk-sweep {
  to {
    transform: translateX(100%);
  }
}

.sk--label { width: 5rem; height: 1.5rem; }
.sk--title { width: 60%; height: 2rem; }
.sk--seg { width: 100%; height: 3rem; border-radius: var(--r-lg); }
.sk--price { width: 8rem; height: 3.25rem; }
.sk--line { width: 100%; height: 0.875rem; }
.sk--short { width: 70%; }
.sk--rows { width: 100%; height: 8rem; border-radius: var(--r-lg); }
.sk--btn { margin-top: auto; width: 100%; height: 3rem; border-radius: var(--r-lg); }
.sk-card--report { min-height: 18rem; }

/* ---------------------------------------------------------------- spinner */

.spinner {
  display: inline-block;
  width: 1.125rem;
  height: 1.125rem;
  border: 1.5px solid var(--slate-6);
  border-top-color: currentColor;
  border-radius: 50%;
  animation: spin 720ms linear infinite;
  vertical-align: -0.2em;
}

.spinner--sm {
  width: 0.875rem;
  height: 0.875rem;
}

.spinner--lg {
  width: 2.25rem;
  height: 2.25rem;
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

/* --------------------------------------------------------------- blur-up */

img[data-blur] {
  opacity: 0;
  transition: opacity 700ms var(--ease-out);
}

img[data-blur].is-loaded {
  opacity: 1;
}

/* -------------------------------------------------------- reduced motion */

@media (prefers-reduced-motion: reduce) {
  .sk::after {
    animation: none;
  }

  .sk {
    animation: sk-pulse 2s ease-in-out infinite;
  }

  @keyframes sk-pulse {
    0%,
    100% {
      opacity: 1;
    }
    50% {
      opacity: 0.55;
    }
  }

  .spinner {
    animation-duration: 1.6s;
  }

  .boot,
  .boot__bar,
  img[data-blur] {
    transition: none;
  }
}
