/* ═══════════════════════════════════════════════════════════════════
   SKELETON LOADING SCREENS — css/skeletons.css
   Driven by js/features/skeletons.js. Replaces the previous blank
   white gap between "page opened" and "data rendered".

   TOKENS: everything here is built from --bg / --surface / --border /
   --muted, which body.dark-mode DOES flip. Do NOT switch these to the
   --color-* Clinical Clarity palette: those are NOT overridden in dark
   mode, so a skeleton built from them would stay bone-white on a near
   black page. The two skeleton-specific tokens below carry their own
   dark-mode values because a white shimmer needs a very different
   alpha on light grey than on near black.

   MOTION: the shimmer is a transform-only sweep (GPU-friendly, never
   touches layout) and is REMOVED ENTIRELY under
   prefers-reduced-motion — the grey shapes still communicate
   "loading", so nothing is lost for users who disable animation.
   ═══════════════════════════════════════════════════════════════════ */

:root {
  --skel-base:  #E8E4DF;
  --skel-shine: rgba(255, 255, 255, .62);
}

body.dark-mode {
  --skel-base:  #262623;
  --skel-shine: rgba(255, 255, 255, .055);
}

/* The host page becomes the positioning context. Additive only — a
   class is added and removed; no existing element is ever mutated, so
   a failure in the skeleton layer cannot corrupt real page content. */
.pg.skel-host { position: relative; }

/* Opaque cover so a page switch does not show stale content behind the
   placeholders. Sits above page content but far below modals (9999)
   and the toast. */
.skel-overlay {
  position: absolute;
  inset: 0;
  z-index: 5;
  background: var(--bg);
  padding: 2px 0 24px;
  min-height: 62vh;
  overflow: hidden;
  /* Non-interactive: taps during load must not hit placeholders, and
     must not reach the real controls underneath either. */
  pointer-events: all;
  cursor: progress;
}

/* ── primitives ───────────────────────────────────────────────────── */
.skel-block {
  background: var(--skel-base);
  border-radius: 6px;
  position: relative;
  overflow: hidden;
}

.skel-block::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg,
    transparent 0%, var(--skel-shine) 50%, transparent 100%);
  transform: translateX(-100%);
  animation: skel-sweep 1.45s ease-in-out infinite;
}

@keyframes skel-sweep {
  100% { transform: translateX(100%); }
}

/* ── page furniture ───────────────────────────────────────────────── */
.skel-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 22px;
  flex-wrap: wrap;
}

.skel-title   { height: 26px; width: 240px; border-radius: 7px; }
.skel-sub     { height: 13px; width: 330px; margin-top: 10px; }
.skel-btn     { height: 34px; width: 112px; border-radius: 9px; }
.skel-btn-sm  { height: 30px; width: 84px;  border-radius: 8px; }
.skel-line    { height: 12px; width: 100%; }
.skel-line.w90 { width: 90%; } .skel-line.w75 { width: 75%; }
.skel-line.w60 { width: 60%; } .skel-line.w45 { width: 45%; }
.skel-line.w30 { width: 30%; }
.skel-pill    { height: 24px; width: 92px; border-radius: 999px; }
.skel-avatar  { height: 38px; width: 38px; border-radius: 50%; flex-shrink: 0; }

/* Real cards use --surface + --border, so the skeleton card frame is
   the real frame — only its contents are placeholders. That is what
   makes the shape read as "this page", not "some loading screen". */
.skel-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius, 14px);
  padding: 16px;
  margin-bottom: 14px;
}

.skel-metrics {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 14px;
  margin-bottom: 20px;
}

.skel-metric {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius, 14px);
  padding: 16px;
}

.skel-metric .skel-line:first-child { width: 58%; height: 11px; }
.skel-metric .skel-num {
  height: 27px; width: 76px; margin-top: 12px; border-radius: 7px;
}

.skel-tabs { display: flex; gap: 10px; margin-bottom: 18px; }

.skel-toolbar {
  display: flex; gap: 10px; margin-bottom: 18px; flex-wrap: wrap;
}

.skel-field { height: 34px; width: 210px; border-radius: 9px; }

/* Table: a header strip plus evenly spaced rows. Row cells are not
   individually modelled — at skeleton fidelity a single bar per row
   reads as a table without implying a column count that may be wrong. */
.skel-table {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius, 14px);
  overflow: hidden;
}

.skel-trow {
  display: flex; align-items: center; gap: 14px;
  padding: 13px 16px;
  border-bottom: 1px solid var(--border);
}

.skel-trow:last-child { border-bottom: 0; }
.skel-trow.head { background: var(--bg); }
.skel-trow .skel-line { height: 11px; }
.skel-trow .c1 { flex: 2.4; } .skel-trow .c2 { flex: 1.5; }
.skel-trow .c3 { flex: 1.1; } .skel-trow .c4 { flex: .8; }

/* MAR: med card + its day-grid strip. */
.skel-grid-strip { display: flex; gap: 4px; margin-top: 12px; }
.skel-grid-strip .skel-cell {
  height: 26px; flex: 1; min-width: 0; border-radius: 4px;
}

.skel-roster { display: flex; align-items: center; gap: 13px; }
.skel-roster .skel-lines { flex: 1; }
.skel-roster .skel-lines .skel-line + .skel-line { margin-top: 8px; }

/* Screen-only. A skeleton must never reach a print window or a
   print-to-PDF clone of a legal form. */
@media print { .skel-overlay { display: none !important; } }

@media (prefers-reduced-motion: reduce) {
  .skel-block::after { animation: none; display: none; }
}

@media (max-width: 768px) {
  .skel-title { width: 60%; }
  .skel-sub   { width: 80%; }
  .skel-field { width: 100%; }
  .skel-overlay { min-height: 70vh; }
}
