/* Loading, empty and error states, plus snapshot freshness cues. */

/* Until a snapshot is applied there is nothing truthful to draw, so the
   cards stay hidden rather than rendering as a grid of empty boxes. */
body:not([data-state="ready"]) #kpiGrid,
body:not([data-state="ready"]) .sec,
body:not([data-state="ready"]) .foot,
body:not([data-state="ready"]) .side-filters,
body:not([data-state="ready"]) .side-foot{ display:none; }

/* An author display rule outranks the UA's [hidden] rule, so hiding the
   banner has to be spelled out or it stays on screen after loading. */
.page-state[hidden]{ display:none; }
.page-state{
  display:flex; align-items:center; gap:12px; flex-wrap:wrap;
  padding:18px 20px; margin:24px 0;
  border:1px solid var(--border); border-radius:var(--radius-md);
  background:var(--surface); color:var(--text-secondary); font-size:13.5px;
}
.page-state.error{ border-color:var(--critical); color:var(--critical); background:var(--critical-wash); }
.page-state.empty{ border-color:var(--amber-border); background:var(--amber-wash); color:var(--amber-text); }
.page-state button{
  margin-left:auto; min-height:36px; padding:0 16px;
  border:1px solid currentColor; border-radius:var(--radius-sm);
  background:transparent; color:inherit; font-family:var(--sans); font-size:13px; cursor:pointer;
}
.ps-spin{
  width:15px; height:15px; flex:none; border-radius:50%;
  border:2px solid var(--border-strong); border-top-color:var(--text-primary);
  animation:ps-rot .8s linear infinite;
}
@keyframes ps-rot{ to{ transform:rotate(360deg); } }

/* A snapshot older than the refresh interval means the scheduled pull is
   probably failing, which should look different from a healthy one. */
.appbar-status .dot.stale{ background:var(--critical); }
#genDateTag.just-updated{ color:var(--good); transition:color .3s ease; }

@media (prefers-reduced-motion:reduce){
  .ps-spin{ animation-duration:2.4s; }
  #genDateTag.just-updated{ transition:none; }
}
