/* Loading skeletons (dev-spec-skeletons.md) */

/* Shimmer */
.shimmer { background:linear-gradient(90deg,var(--surface) 25%,var(--surface2) 50%,var(--surface) 75%); background-size:200% 100%; animation:shimmer 1.4s infinite; }
@keyframes shimmer { 0%{background-position:200% 0} 100%{background-position:-200% 0} }

/* Boot skeleton: shown from first paint until app.js bootDone().
   The inline script in <head> sets html.booting + html.boot-{pulse|dive|aso};
   without JS neither class is set, so the skeleton stays hidden. */
#boot-skeleton, .boot-pulse-sk, .boot-dive-sk, .boot-aso-sk { display:none; }
html.booting #boot-skeleton { display:block; }
html.boot-pulse .boot-pulse-sk, html.boot-dive .boot-dive-sk, html.boot-aso .boot-aso-sk { display:block; }
/* Tab bodies stay hidden while booting: before /api/meta, Alpine shows Pulse whatever the tab */
html.booting [data-tab-body] { display:none !important; }
/* The footer would sit under the short boot skeleton and get pushed down by the real content (CLS) */
html.booting [data-site-footer] { display:none; }
/* The tab body replaces the boot skeleton in place — no fade on that first show */
html.boot-nofade [data-tab-body] { animation:none; }

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