/* ============================================================
   MZANSI FARMING HUB — loading-states.css
   UX review item #15 — "Loading states": avoid blank screens while
   database operations happen. Shared, site-wide (loaded once from
   includes/header.php, right after style.css) so every page — the
   article editor, marketplace, dashboard, messages, product pages —
   gets the same look for free, with no per-page CSS needed.
   Colours reuse the --green/--gold variables already defined in
   style.css so this never looks like a bolted-on add-on.
   ============================================================ */

/* ---- Top-of-page progress bar --------------------------------
   A slim bar that fills in while a navigation or form submit is in
   flight. Sits above everything (including the sticky header) so it
   reads as "the whole page is working", not just one widget. */
#mfh-progress {
  position: fixed;
  top: 0; left: 0;
  height: 3px;
  width: 0%;
  z-index: 99999;
  background: linear-gradient(90deg, var(--gold, #c8960c), var(--green-light, #4a8c2a));
  box-shadow: 0 0 8px rgba(200, 150, 12, .6);
  transition: width .25s ease-out, opacity .3s ease .1s;
  opacity: 0;
  pointer-events: none;
}
#mfh-progress.is-active { opacity: 1; }
#mfh-progress.is-done { transition: width .2s ease-out, opacity .35s ease; opacity: 0; }

/* ---- Button loading state --------------------------------------
   Applied to whichever <button type=submit> triggered a form submit.
   Keeps the button's own width (no layout jump) and shows a small
   spinner in place of/next to the label. */
button.is-loading,
.btn-submit.is-loading,
.btn-secondary.is-loading {
  position: relative;
  color: transparent !important;
  pointer-events: none;
  opacity: .85;
}
button.is-loading::after,
.btn-submit.is-loading::after,
.btn-secondary.is-loading::after {
  content: "";
  position: absolute;
  top: 50%; left: 50%;
  width: 16px; height: 16px;
  margin: -8px 0 0 -8px;
  border-radius: 50%;
  border: 2px solid rgba(255,255,255,.45);
  border-top-color: #fff;
  animation: mfh-spin .7s linear infinite;
}
/* Secondary/outline buttons are often dark-text-on-light — the white
   spinner above is illegible there, so give that variant a dark spinner. */
.btn-secondary.is-loading::after {
  border-color: rgba(45,90,27,.35);
  border-top-color: var(--green, #2d5a1b);
}
@keyframes mfh-spin { to { transform: rotate(360deg); } }

/* Small inline spinner for non-button contexts (e.g. a "Sending…"
   status line next to a chat box) via <span class="mfh-spinner">. */
.mfh-spinner {
  display: inline-block;
  width: 14px; height: 14px;
  border-radius: 50%;
  border: 2px solid rgba(45,90,27,.25);
  border-top-color: var(--green, #2d5a1b);
  animation: mfh-spin .7s linear infinite;
  vertical-align: -2px;
  margin-right: 6px;
}

/* ---- Skeleton placeholders --------------------------------------
   For any element that's about to be replaced with real content
   (a stat card while its count loads, a card grid while a filter
   re-query is in flight, a chat pane while a conversation loads).
   Usage: add class="mfh-skeleton" to a block with a set height, or
   wrap several with class="mfh-skeleton-group" and each child gets
   the shimmer. */
.mfh-skeleton,
.mfh-skeleton-group > * {
  position: relative;
  overflow: hidden;
  background: var(--soft, #f0ead8);
  border-radius: 8px;
  color: transparent !important;
}
.mfh-skeleton *,
.mfh-skeleton-group > * * { visibility: hidden; }
.mfh-skeleton::after,
.mfh-skeleton-group > *::after {
  content: "";
  position: absolute;
  inset: 0;
  transform: translateX(-100%);
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.55), transparent);
  animation: mfh-shimmer 1.4s infinite;
}
@keyframes mfh-shimmer { 100% { transform: translateX(100%); } }

/* Ready-made skeleton shapes for the most common loading spots. */
.mfh-skel-line { height: 14px; border-radius: 4px; margin: 6px 0; background: var(--soft, #f0ead8); position: relative; overflow: hidden; }
.mfh-skel-line::after { content:""; position:absolute; inset:0; transform:translateX(-100%); background:linear-gradient(90deg,transparent,rgba(255,255,255,.55),transparent); animation: mfh-shimmer 1.4s infinite; }
.mfh-skel-line.w-60 { width: 60%; }
.mfh-skel-line.w-40 { width: 40%; }
.mfh-skel-card { height: 150px; border-radius: 8px; background: var(--soft, #f0ead8); position: relative; overflow: hidden; }
.mfh-skel-card::after { content:""; position:absolute; inset:0; transform:translateX(-100%); background:linear-gradient(90deg,transparent,rgba(255,255,255,.55),transparent); animation: mfh-shimmer 1.4s infinite; }
.mfh-skel-avatar { width: 44px; height: 44px; border-radius: 50%; background: var(--soft, #f0ead8); position: relative; overflow: hidden; flex-shrink: 0; }
.mfh-skel-avatar::after { content:""; position:absolute; inset:0; transform:translateX(-100%); background:linear-gradient(90deg,transparent,rgba(255,255,255,.55),transparent); animation: mfh-shimmer 1.4s infinite; }

/* Respect reduced-motion visitors: keep the placeholder, drop the
   animated sheen and the spin, so nothing moves for people who asked
   for less motion. */
@media (prefers-reduced-motion: reduce) {
  .mfh-skeleton::after, .mfh-skeleton-group > *::after, .mfh-skel-line::after,
  .mfh-skel-card::after, .mfh-skel-avatar::after,
  button.is-loading::after, .btn-submit.is-loading::after, .btn-secondary.is-loading::after,
  .mfh-spinner {
    animation: none;
  }
}

/* ---- Inline "Saving…" progress line -----------------------------
   A thin determinate-looking bar some pages show under a form while
   it's mid-submit (e.g. large media uploads on the article editor),
   driven by assets/js/loading-states.js's MFHLoading.progressBar(). */
.mfh-inline-progress { height: 6px; border-radius: 3px; background: var(--soft, #f0ead8); overflow: hidden; margin-top: 8px; display: none; }
.mfh-inline-progress.is-active { display: block; }
.mfh-inline-progress > span { display: block; height: 100%; width: 0%; background: linear-gradient(90deg, var(--green-mid,#3d7a25), var(--green-light,#4a8c2a)); transition: width .3s ease; }

/* ---- Gentle content fade-in on first paint -----------------------
   Server-rendered pages appear all at once; a very small fade avoids
   the "flash of fully-formed content" feeling jarring right after the
   progress bar above finishes, especially noticeable on slower
   connections where the previous page was visible a beat longer. */
@media (prefers-reduced-motion: no-preference) {
  body { animation: mfh-page-in .25s ease-out; }
}
@keyframes mfh-page-in { from { opacity: .4; } to { opacity: 1; } }
