/* skeleton-module (MIX-85): the one shared skeleton/loading kit.
   Load in <head> BEFORE the page's own <style> so a page can override, and
   before nav.js (which uses these classes for its own loading state).
   Never redefine these rules or the shimmer keyframes per page — the Module
   registry in public/CLAUDE.md + tests/public-modules.test.js enforce it.

   Radius: set --skeleton-radius on the page (e.g. `:root { --skeleton-radius:
   var(--radius-m); }`) or on a container, instead of redeclaring the rule. */

@keyframes shimmer {
  0% {
    background-position: 200% 0;
  }
  100% {
    background-position: -200% 0;
  }
}

.skeleton-shimmer {
  background: linear-gradient(90deg, var(--line) 25%, var(--surface) 50%, var(--line) 75%);
  background-size: 200% 100%;
  animation: shimmer 1.4s infinite;
  overflow: hidden;
  border-radius: var(--skeleton-radius, 0);
}

/* Placeholders sometimes wrap real layout (e.g. .featured-layout) purely to
   reserve its height — the children must not show through the shimmer. */
.skeleton-shimmer * {
  visibility: hidden;
}

/* skeletonError(id) sets className to exactly this, so an errored section
   renders as a bare message. Dark surfaces scope their own colour (see
   nav.js's .nav-switch .skeleton-error). */
.skeleton-error {
  color: var(--muted);
  font-size: 13px;
  text-align: center;
  padding: 20px 0;
}

/* Card-shaped skeleton pieces (skeleton-reserved-height). The thumb mirrors
   the real 16:9 thumbnail so it self-corrects across breakpoints; per-card
   min-heights stay on the page, next to the content they were measured
   against. */
.skeleton-thumb {
  aspect-ratio: 16 / 9;
  border-radius: var(--radius-l);
}
.skeleton-details {
  border-radius: var(--radius-s);
}

/* ── Empty states (empty-state-contract, MIX-92) ──────────────────────────
   What a section shows when it loaded fine and has nothing in it — the
   third state beside the shimmer (loading) and .skeleton-error (failed).
   One class for every page; a size that genuinely differs is a modifier
   here, never a per-page alias (.foo-empty). Contract, copy rules and the
   variant-picking table: docs/design-system.md "Empty states".

   Base: a whole section or page has nothing to show. Centred; may carry
   one icon, one title and one action. */
.empty-state {
  padding: 40px 20px;
  text-align: center;
  font-size: 14px;
  line-height: 1.5;
  color: var(--muted-2);
}
.empty-state-icon {
  font-size: 32px;
  line-height: 1;
  margin-bottom: 12px;
}
.empty-state-title {
  font-size: 15px;
  font-weight: 600;
  color: var(--ink);
  margin-bottom: 4px;
}
.empty-state p {
  max-width: 420px;
  margin-left: auto;
  margin-right: auto;
}
.empty-state p + p {
  margin-top: 8px;
}
.empty-state a {
  color: var(--ink);
}
.empty-state-action {
  margin-top: 16px;
}

/* A list inside a section has no rows: reads as the list's first row —
   left-aligned, same vertical rhythm as a row. One line of text on the
   element itself; no icon, title or child <p>. */
.empty-state--inline {
  padding: 12px 0;
  text-align: left;
}

/* Inside a dropdown, picker, typeahead or search-results pane. */
.empty-state--compact {
  padding: 12px;
  font-size: 13px;
}
