/* Shared loading skeleton (linked from base.html). Async panels show these
   shimmer bars while their FIRST fetch is in flight; background polls keep the
   last render instead of flashing back to skeleton. Markup:
     <div class="skeleton-group"><div class="skeleton-row">
       <span class="skeleton-bar is-wide"></span></div></div>
   JS helpers that build it: ADV.renderSkeleton (advertising), copy_opt/loading.js.
   Page-specific layouts (e.g. .skeleton-pills) live with the page. */
@keyframes skeleton-shimmer {
    0% { background-position: 200% 0; }
    100% { background-position: -200% 0; }
}
.skeleton-group { width: 100%; display: grid; gap: 12px; }
.skeleton-row { display: flex; align-items: center; gap: 10px; width: 100%; }
.skeleton-bar {
    display: block;
    width: 60%;
    height: 12px;
    flex: 0 1 60%;
    border-radius: 4px;
    background: linear-gradient(90deg,
        var(--tint-1) 25%, var(--tint-3) 50%, var(--tint-1) 75%);
    background-size: 200% 100%;
    animation: skeleton-shimmer 1.5s linear infinite;
}
.skeleton-bar.is-tiny { width: 18%; flex-basis: 18%; height: 9px; }
.skeleton-bar.is-narrow { width: 42%; flex-basis: 42%; }
.skeleton-bar.is-wide { width: 82%; flex-basis: 82%; }
.skeleton-bar.is-kpi { width: 52%; flex-basis: 52%; height: 24px; border-radius: 6px; }
.skeleton-bar.is-circle { width: 40px; height: 40px; flex: 0 0 40px; border-radius: 50%; }
.skeleton-bar.is-block { width: 100%; height: 76px; flex-basis: 100%; border-radius: 8px; }
.skeleton-bar.is-document { width: 100%; height: 150px; flex-basis: 100%; border-radius: 8px; }
.skeleton-bar.is-chart { width: 100%; height: 210px; flex-basis: 100%; border-radius: 8px; }
.skeleton-stats,
.skeleton-cards { grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); }
.skeleton-table { padding: 14px; }
.skeleton-table .skeleton-row { justify-content: space-between; }
@media (prefers-reduced-motion: reduce) {
    .skeleton-bar { animation: none; background-position: 0 0; }
}
