/* ═══════════════════════════════════════════════════════════════════════
   MOTION & FLUIDITY — 2026
   ───────────────────────────────────────────────────────────────────────
   Additive, token-driven polish layered on top of design-system.css.
   Loaded LAST so it can refine (never replace) existing rules.

   Design rules honoured here:
     • All motion is wrapped in @media (prefers-reduced-motion: no-preference)
       so reduced-motion users get an instant, still UI.
     • Entrance choreography is keyed off `.view-container.active`. A view is
       display:none until active, so switching to it re-enters the render tree
       and REPLAYS these animations — the cascade plays on every navigation,
       and it never fights the ~10s live-metrics refresh (which only rewrites
       textContent / bar widths, not the .active class).
     • Tokens only — no hard-coded hex. Colours come from --accent, --border-*,
       --shadow-*, easings from --ease-out / --ease-spring.
   ═══════════════════════════════════════════════════════════════════════ */

/* ── Shared entrance keyframes ───────────────────────────────────────── */
@keyframes dashRise {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes kpiReveal {
  from { opacity: 0; transform: translateY(7px); filter: blur(6px); }
  to   { opacity: 1; transform: translateY(0);   filter: blur(0); }
}
@keyframes shimmer {
  100% { transform: translateX(100%); }
}

@media (prefers-reduced-motion: no-preference) {

  /* ── Dashboard entrance choreography ───────────────────────────────── */
  /* Replace the container's own translate-fade with a plain fade so the
     children own the vertical motion (avoids a double-transform judder). */
  #view-dashboard.active {
    animation: fadeIn var(--t-base) var(--ease-out);
  }

  /* Top-level rows rise + fade in sequence. */
  #view-dashboard.active > .dash-title,
  #view-dashboard.active > .dash-hero,
  #view-dashboard.active > #dashboard-clusters-card,
  #view-dashboard.active > .card,
  #view-dashboard.active > .dash-bottom-row {
    animation: dashRise 520ms var(--ease-out) both;
  }
  #view-dashboard.active > .dash-title              { animation-delay: 40ms; }
  #view-dashboard.active > .dash-hero               { animation-delay: 80ms; }
  #view-dashboard.active > #dashboard-clusters-card { animation-delay: 150ms; }
  #view-dashboard.active > .card                    { animation-delay: 200ms; }
  #view-dashboard.active > .dash-bottom-row         { animation-delay: 260ms; }

  /* Inside the hero, stagger the health card and the three KPI cards so the
     row assembles left-to-right instead of appearing as one block. */
  #view-dashboard.active .dash-health-card {
    animation: dashRise 560ms var(--ease-out) both;
    animation-delay: 120ms;
  }
  #view-dashboard.active .dash-top-cards .dash-top-card {
    animation: dashRise 500ms var(--ease-out) both;
  }
  #view-dashboard.active .dash-top-cards .dash-top-card:nth-child(1) { animation-delay: 170ms; }
  #view-dashboard.active .dash-top-cards .dash-top-card:nth-child(2) { animation-delay: 230ms; }
  #view-dashboard.active .dash-top-cards .dash-top-card:nth-child(3) { animation-delay: 290ms; }

  /* KPI headline numbers de-blur into place, echoing the ECharts gauge which
     already value-animates its score. Fires after the cards have landed. */
  #view-dashboard.active .dash-top-card-value {
    animation: kpiReveal 640ms var(--ease-out) both;
    animation-delay: 340ms;
  }

  /* ── Card hover micro-interactions (bento-style lift) ──────────────── */
  /* Scoped to the KPI + insight cards; the tall real-time chart card is left
     flat on purpose (a 300px chart lifting under the cursor reads as noise). */
  #view-dashboard .dash-top-card:hover,
  #view-dashboard .dash-health-card:hover,
  #view-dashboard .dash-bottom-row .card:hover {
    transform: translateY(-3px);
    border-color: var(--border-accent);
    box-shadow: var(--shadow-lg), inset 0 1px 0 rgba(255, 255, 255, 0.04);
  }
}

/* Hover transition is defined OUTSIDE the reduced-motion guard so the colour/
   shadow change is still smooth (not the transform, which the guard drops via
   the :hover rule simply not applying). */
#view-dashboard .dash-top-card,
#view-dashboard .dash-health-card,
#view-dashboard .dash-bottom-row .card {
  transition: transform var(--t-base) var(--ease-out),
              border-color var(--t-base) var(--ease-out),
              box-shadow var(--t-base) var(--ease-out);
  will-change: transform;
}

/* ── Progress / health bars: give them a springier, more visible sweep ─── */
/* The bar widths are set inline by the metrics refresh; these only tune the
   easing of the width transition the design system already declares. */
@media (prefers-reduced-motion: no-preference) {
  .health-stat-fill,
  .metric-card-progress-bar,
  #view-dashboard .progress-bar {
    transition: width 700ms var(--ease-out), background 300ms var(--ease-out);
  }
}

/* ── Skeleton shimmer utility ──────────────────────────────────────────── */
/* Apply `.skeleton` (optionally with a fixed height/width) to any placeholder
   block to show an animated loading shimmer instead of bare "Loading…" text. */
.skeleton {
  position: relative;
  overflow: hidden;
  background: var(--bg-elevated);
  border-radius: var(--r-sm);
  color: transparent !important;
}
.skeleton::after {
  content: '';
  position: absolute;
  inset: 0;
  transform: translateX(-100%);
  background: linear-gradient(
    90deg,
    transparent 0%,
    rgba(255, 255, 255, 0.07) 50%,
    transparent 100%
  );
}
@media (prefers-reduced-motion: no-preference) {
  .skeleton::after { animation: shimmer 1.4s var(--ease-out) infinite; }
}

/* ── Sidebar nav: subtle slide on hover for a more tactile feel ─────────── */
@media (prefers-reduced-motion: no-preference) {
  .nav-item { transition: all var(--t-fast) var(--ease-out), transform var(--t-fast) var(--ease-spring); }
  .nav-item:not(.active):hover { transform: translateX(2px); }
  .nav-item:hover .nav-icon { transform: scale(1.08); }
}
