/* ─────────────────────────────────────────────────────────────
   CMEX.ai — preloader.css
   Pixel-perfect translation of PreloaderBody (data/_disign/preloader.jsx),
   branch size='sm' (isCompact). Desktop values are the base; ≤768px
   mobile values come from a media-query override.
   Overlay shown/hidden via .is-visible (fade 250ms). Colours only via
   var(--*) tokens (base.css) — theme (data-theme on <html>) is inherited.
   ───────────────────────────────────────────────────────────── */

/* ── Fixed overlay ───────────────────────────────────────────── */
.cmex-preloader {
  position: fixed;
  inset: 0;
  z-index: 9999;                 /* above nav-bar (50) and mobile menu (200) */
  background: var(--bg);
  color: var(--text);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 20px;
  box-sizing: border-box;
  overflow: hidden;
  font-family: 'Manrope', sans-serif;

  /* Hidden by default; fade in/out via .is-visible */
  opacity: 0;
  visibility: hidden;
  transition: opacity 250ms ease, visibility 0s linear 250ms;
}

.cmex-preloader.is-visible {
  opacity: 1;
  visibility: visible;
  transition: opacity 250ms ease;
}

/* ── Logo + spinner combo ────────────────────────────────────── */
.pl-stack {
  position: relative;
  margin-bottom: 18px;           /* isCompact desktop */
}

/* Outer rotating ring (72px desktop) */
.pl-ring {
  width: 72px;
  height: 72px;
  display: block;
  animation: plRotate 1.6s linear infinite;
  /* Promote to its own GPU compositor layer so rotation keeps running
     even when the main thread is busy parsing the next page. */
  will-change: transform;
  transform: translateZ(0);
  backface-visibility: hidden;
}

.pl-ring-track {
  fill: none;
  stroke: var(--divider);
  stroke-width: 3;
}

.pl-ring-arc {
  fill: none;
  stroke: var(--accent);
  stroke-width: 3;
  stroke-linecap: round;
  stroke-dasharray: 80 200;
}

/* Centered logo */
.pl-logo-wrap {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}

.pl-logo {
  display: inline-flex;
  align-items: baseline;
  gap: 1px;
  line-height: 1;
  font-weight: 800;
  font-size: 14px;               /* isCompact desktop */
  letter-spacing: -0.02em;
  color: var(--text);
}

.pl-logo-dot {
  width: 3px;
  height: 3px;
  border-radius: 50%;
  background: var(--accent);
  display: inline-block;
  transform: translateY(-1px) translateZ(0);
  animation: plPulse 1.4s ease-in-out infinite;
  /* GPU layer — keep the pulse smooth under main-thread load. */
  will-change: transform;
  backface-visibility: hidden;
}

.pl-logo-ai {
  color: var(--accent);
  font-weight: 700;
}

/* ── Message + sub-message ───────────────────────────────────── */
.pl-title {
  font-size: 16px;               /* titleSize, isCompact desktop */
  font-weight: 800;
  color: var(--text);
  letter-spacing: -0.02em;
  text-align: center;
  margin-bottom: 6px;
}

.pl-sub {
  font-size: 12px;               /* subSize, isCompact desktop */
  color: var(--text-muted);
  text-align: center;
  max-width: 360px;
  line-height: 1.5;
}

/* ── Bouncing dots ───────────────────────────────────────────── */
.pl-dots {
  margin-top: 16px;              /* isCompact desktop */
  display: flex;
  gap: 6px;
}

.pl-dot {
  width: 6px;                    /* dotSize, isCompact desktop */
  height: 6px;
  border-radius: 50%;
  background: var(--accent);
  animation: plBounce 1.2s ease-in-out infinite;
  /* GPU layer — bounce driven by transform/opacity only, stays smooth
     while the main thread parses the next page. */
  will-change: transform;
  transform: translateZ(0);
  backface-visibility: hidden;
}

.pl-dot:nth-child(1) { animation-delay: 0s; }
.pl-dot:nth-child(2) { animation-delay: 0.15s; }
.pl-dot:nth-child(3) { animation-delay: 0.30s; }

/* ── Keyframes (mirror preloader.jsx <style>) ────────────────── */
@keyframes plRotate {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}

@keyframes plPulse {
  0%, 100% { opacity: 0.4; transform: translateY(-1px) scale(0.8); }
  50%      { opacity: 1;   transform: translateY(-1px) scale(1.2); }
}

@keyframes plBounce {
  0%, 100% { transform: translateY(0);    opacity: 0.4; }
  50%      { transform: translateY(-8px); opacity: 1; }
}

/* ── Mobile (≤768px) — PreloaderMobile sm values ─────────────── */
@media (max-width: 768px) {
  .pl-stack { margin-bottom: 14px; }
  .pl-ring  { width: 56px; height: 56px; }
  .pl-logo  { font-size: 12px; }
  .pl-title { font-size: 14px; }
  .pl-sub   { font-size: 11px; }
  .pl-dots  { margin-top: 14px; }
  .pl-dot   { width: 5px; height: 5px; }
}

/* ── Respect reduced-motion — kill all preloader animations ──── */
@media (prefers-reduced-motion: reduce) {
  .cmex-preloader,
  .pl-ring,
  .pl-logo-dot,
  .pl-dot {
    animation: none !important;
    transition: none !important;
  }
}
