/* ══════════════════════════════════════════════════════════════════
   HOUSE LOADING SYSTEM (Eli, 2026-08-17: "loading states looked buggy
   on a client call — this site needs to be cutting edge").

   One shimmer, one spinner, one quiet-retry voice, everywhere. Built on
   the proven drill-down shimmer; generalized here in a LINKED file —
   the old pulse/spin keyframes lived in unlinked briefing.css, so the
   deep-report spinner and three "Analyzing…" states shipped FROZEN.

   Three states, always: loading (skeleton) / empty (hide or say so) /
   data. "Loading" must never look like "empty" or "broken".
   ══════════════════════════════════════════════════════════════════ */

/* ── Rescued keyframes: inline consumers across tracker.js, board.js,
      briefing.js reference these by name ── */
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.45; } }
@keyframes spin { to { transform: rotate(360deg); } }
@keyframes ldShimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }

/* ── Skeleton bars: the shimmer primitive ── */
.ld-skel {
  background: linear-gradient(90deg,
    color-mix(in srgb, var(--text-3) 8%, var(--surface)) 0%,
    color-mix(in srgb, var(--text-3) 16%, var(--surface)) 50%,
    color-mix(in srgb, var(--text-3) 8%, var(--surface)) 100%);
  background-size: 200% 100%;
  animation: ldShimmer 1.4s ease-in-out infinite;
  height: 12px; border-radius: 6px; margin-bottom: 8px;
}
.ld-skel.lg { height: 18px; width: 60%; }
.ld-skel.sm { height: 10px; width: 40%; }
.ld-skel.xl { height: 26px; width: 45%; }
.ld-skel.pill { height: 22px; width: 90px; border-radius: 999px; display: inline-block; margin-right: 6px; }
.ld-skel.disc { width: 40px; height: 40px; border-radius: 50%; flex: 0 0 auto; }
.ld-skel.block { height: 120px; width: 100%; border-radius: 10px; }

/* A skeleton CARD in the house card dress — drop inside any grid and it
   holds the real card's space (no pop-in shove) */
.ld-skel-card {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 12px; padding: 14px 16px;
}
.ld-skel-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; }
/* When injected INTO a grid container, span the full row — otherwise the
   retry line / ghost grid squeezes into the first track (audit, 2026-08-17) */
.ld-skel-grid, .ld-retry { grid-column: 1 / -1; }
.ld-retry a { color: var(--green); font-weight: 700; text-decoration: none; }

/* Shimmer WITHOUT the skeleton's fixed height — for ghosting elements that
   carry their own shape (aspect-ratio papers etc.); .ld-skel's height:12px
   defeats aspect-ratio and collapsed the contracts ghost (audit, 2026-08-17) */
.ld-ghost {
  background: linear-gradient(90deg,
    color-mix(in srgb, var(--text-3) 8%, var(--surface)) 0%,
    color-mix(in srgb, var(--text-3) 16%, var(--surface)) 50%,
    color-mix(in srgb, var(--text-3) 8%, var(--surface)) 100%);
  background-size: 200% 100%;
  animation: ldShimmer 1.4s ease-in-out infinite;
}

/* ── Spinner: quiet ring, brand green ── */
.ld-spin {
  width: 22px; height: 22px; border-radius: 50%;
  border: 2px solid color-mix(in srgb, var(--green) 20%, transparent);
  border-top-color: var(--green);
  animation: spin 0.8s linear infinite;
  display: inline-block; vertical-align: middle;
}

/* ── Content entrance: data replacing a skeleton FADES in — never pops ── */
.ld-enter { animation: ldEnter 240ms var(--ease, ease-out) both; }
@keyframes ldEnter { from { opacity: 0; transform: translateY(3px); } to { opacity: 1; transform: none; } }

/* ── Quiet retry voice: calm, never red, never a dead end ── */
.ld-retry {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  padding: 18px 0; font-family: var(--font-body); font-size: 12px;
  color: var(--text-3); text-align: center;
}
.ld-retry .ld-spin { width: 14px; height: 14px; border-width: 1.5px; }

/* ── X Pulse loading copy: was completely unstyled (class only existed
      in unlinked briefing.css) ── */
.xpulse-loading {
  padding: 28px 0; text-align: center;
  font-family: var(--font-body); font-size: 12.5px; color: var(--text-3);
  animation: pulse 1.5s ease-in-out infinite;
}

/* (.mgw-logo needs NO rule here — briefing.css already reserves a 40px
   padded icon tile; a duplicate rule regressed it. Audit, 2026-08-17.) */

/* ── Calendar scaffold cells shimmer softly while events load; height
      comes from the grid's own auto-rows so the real month lands in the
      same footprint ── */
.cal-cell.ld-cal-ghost .ld-skel { width: 55%; height: 8px; margin: 4px 0 0; }

/* ── Legacy skeleton systems, superseded by .ld-skel (2026-08-17):
      redefined here (this file loads last) on the shared gradient so all
      shimmers match — drill-down.css's copy mixed the broken --divider
      token and shipped invisible. .at-skel-* (artist.css) and
      .kb-skel-card (overrides-board.css) still work and stay put; new
      code uses .ld-skel. ── */
.drill-panel-skeleton {
  background: linear-gradient(90deg,
    color-mix(in srgb, var(--text-3) 8%, var(--surface)) 0%,
    color-mix(in srgb, var(--text-3) 16%, var(--surface)) 50%,
    color-mix(in srgb, var(--text-3) 8%, var(--surface)) 100%);
  background-size: 200% 100%;
  animation: ldShimmer 1.4s ease-in-out infinite;
}

/* ── Reduced motion: shimmer and spin settle to steady states ── */
@media (prefers-reduced-motion: reduce) {
  .ld-skel, .xpulse-loading { animation: none; }
  .ld-spin { animation-duration: 1.6s; }
  .ld-enter { animation: none; }
}
