
/* ============================================================
   PIONEER VISION — MOTION & LOADING LAYER (appended)
   Brand #6c5ce7 · respects prefers-reduced-motion
   ============================================================ */

/* ---- Entrance animations ---- */
@keyframes pvFadeUp { from { opacity:0; transform:translateY(10px); } to { opacity:1; transform:translateY(0); } }
@keyframes pvFadeIn { from { opacity:0; } to { opacity:1; } }
@keyframes pvScaleIn { from { opacity:0; transform:scale(.97); } to { opacity:1; transform:scale(1); } }
@keyframes pvSlideInRight { from { opacity:0; transform:translateX(24px); } to { opacity:1; transform:translateX(0); } }
@keyframes pvSpin { to { transform:rotate(360deg); } }
@keyframes pvShimmer { 0% { background-position:-468px 0; } 100% { background-position:468px 0; } }
@keyframes pvPulse { 0%,100% { opacity:1; } 50% { opacity:.5; } }

/* ---- Page content fades up on load ---- */
.pv-content { animation: pvFadeIn .35s ease both; }
.pv-content .pv-card { animation: pvFadeUp .45s cubic-bezier(.22,.61,.36,1) both; }
.pv-content .pv-card:nth-child(2){ animation-delay:.05s; }
.pv-content .pv-card:nth-child(3){ animation-delay:.10s; }
.pv-content .pv-card:nth-child(4){ animation-delay:.15s; }
.pv-content .pv-card:nth-child(5){ animation-delay:.20s; }

/* ---- Smooth interactions ---- */
.pv-btn, .pv-card, .pv-badge, .pv-input, .pv-table tbody tr, .pv-sidebar a, .pv-nav-item, a.pv-btn {
  transition: background-color .18s ease, color .18s ease, border-color .18s ease,
              box-shadow .22s ease, transform .12s ease, opacity .18s ease;
}
.pv-btn:hover { transform: translateY(-1px); box-shadow: 0 6px 18px rgba(108,92,231,.18); }
.pv-btn:active { transform: translateY(0) scale(.98); }
.pv-card { will-change: transform; }
/* A dark shadow on a dark surface reads as nothing, so hover stops registering
   as hover. Lift the border instead. */
.pv-card:hover { box-shadow: 0 12px 34px rgba(30,33,64,.10); }
html[data-theme="dark"] .pv-card:hover { box-shadow: 0 12px 34px rgba(0,0,0,.45); border-color: rgba(255,255,255,.10); }
/* THIS is the rule that was painting rows white in dark mode.
   The same line exists in components.css, but motion.css loads after it and
   therefore wins — patching the other copy changed nothing. The token already
   resolves correctly in both themes. */
.pv-table tbody tr:hover { background: var(--pv-surface-2); }

/* ---- Button loading state ---- */
.pv-btn.is-loading { position:relative; color:transparent !important; pointer-events:none; }
.pv-btn.is-loading::after {
  content:''; position:absolute; top:50%; left:50%; width:16px; height:16px; margin:-8px 0 0 -8px;
  border:2px solid rgba(255,255,255,.5); border-top-color:#fff; border-radius:50%;
  animation: pvSpin .6s linear infinite;
}
.pv-btn.pv-btn-subtle.is-loading::after, .pv-btn.pv-btn-ghost.is-loading::after {
  border-color: color-mix(in srgb, var(--pv-accent) 35%, transparent); border-top-color: var(--pv-accent);
}

/* ---- Standalone spinner ---- */
.pv-spinner {
  display:inline-block; width:20px; height:20px;
  border:2.5px solid color-mix(in srgb, var(--pv-accent) 25%, transparent);
  border-top-color: var(--pv-accent); border-radius:50%; animation: pvSpin .6s linear infinite; vertical-align:middle;
}
.pv-spinner.lg { width:34px; height:34px; border-width:3px; }

/* ---- Skeleton loaders ---- */
.pv-skeleton {
  background:#eef0f6; background-image:linear-gradient(90deg,#eef0f6 0px,#f6f7fb 40px,#eef0f6 80px);
  background-size:600px; border-radius:8px; animation: pvShimmer 1.3s linear infinite;
}
.pv-skeleton.text { height:12px; margin:6px 0; }
.pv-skeleton.title { height:20px; width:45%; margin:8px 0 14px; }
.pv-skeleton.line { height:12px; width:100%; }
.pv-skeleton.line.short { width:60%; }
.pv-skeleton.avatar { width:44px; height:44px; border-radius:50%; }
.pv-skeleton.btn { height:36px; width:120px; border-radius:10px; }
.pv-skeleton-row { display:flex; gap:12px; align-items:center; padding:12px 0; }

/* ---- Toast / flash slide-in ---- */
.pv-alert, .pv-toast { animation: pvSlideInRight .4s cubic-bezier(.22,.61,.36,1) both; }

/* ---- Sidebar item hover accent ---- */
.pv-sidebar a:hover, .pv-nav-item:hover { transform: translateX(2px); }

/* ---- Modal / dialog pop ---- */
.pv-modal, .pv-dialog, [role="dialog"] { animation: pvScaleIn .22s ease both; }

/* ---- KPI tiles gentle rise ---- */
.pv-kpi, .pv-stat-tile { animation: pvFadeUp .5s cubic-bezier(.22,.61,.36,1) both; }

/* ---- Respect reduced motion ---- */
@media (prefers-reduced-motion: reduce) {
  *, .pv-content, .pv-content .pv-card, .pv-kpi, .pv-alert, .pv-modal {
    animation: none !important; transition: none !important;
  }
}

/* ---- Branded page loader overlay ---- */
#pvLoader {
  position:fixed; inset:0; z-index:9999; display:flex; align-items:center; justify-content:center;
  /* Near-white wash. On a dark page the loading overlay flashed white over
     every navigation, which is the most visible thing in the app. */
  background:rgba(247,248,252,.45); backdrop-filter:blur(8px); -webkit-backdrop-filter:blur(8px);
  transition:opacity .4s ease, visibility .4s ease;
}
#pvLoader.hide { opacity:0; visibility:hidden; }
.pv-loader-mark {
  width:64px; height:64px; border-radius:18px;
  background:linear-gradient(135deg, var(--pv-accent), color-mix(in srgb, var(--pv-accent) 55%, #a25ddc)); color:#fff;
  display:flex; align-items:center; justify-content:center; font-size:26px;
  box-shadow:0 12px 34px rgba(108,92,231,.35);
  animation:pvLoaderPulse 1.4s ease-in-out infinite;
}
.pv-loader-ring {
  position:absolute; width:96px; height:96px; border-radius:50%;
  border:3px solid color-mix(in srgb, var(--pv-accent) 18%, transparent); border-top-color: var(--pv-accent);
  animation:pvSpin .9s linear infinite;
}
@keyframes pvLoaderPulse {
  0%,100% { transform:scale(1); box-shadow:0 12px 34px rgba(108,92,231,.35); }
  50% { transform:scale(1.08); box-shadow:0 16px 44px rgba(108,92,231,.5); }
}

/* ==========================================================================
   Dark mode
   --------------------------------------------------------------------------
   This file was written as a light-mode pass and had no dark handling at all.
   Because it loads after app.css and components.css, its hardcoded values beat
   anything those files set — which is why fixing them there had no effect.
   ========================================================================== */

/* Loading skeletons were fixed light greys, so a loading page flashed white
   blocks on a dark background. */
html[data-theme="dark"] .pv-skeleton {
  background:#182233;
  background-image:linear-gradient(90deg,#182233 0px,#22304a 40px,#182233 80px);
}

/* The page-transition overlay covers the whole viewport on every navigation.
   A near-white wash there is the most visible dark-mode failure in the app. */
html[data-theme="dark"] #pvLoader { background: rgba(11,17,32,.55); }
