/* ============================================================
   Flow Signals — Skeleton Loading System (fs-skeleton.css)
   Calm, restrained, premium dark shimmer. Matches the app's
   --bg-secondary cards + gold accent. No bright-white flash,
   no big pulse. Dimensions match real components to prevent
   cumulative layout shift (CLS = 0).
   Namespaced: all classes prefixed .skeleton* / .fs-sk* / .sr-only.
   ============================================================ */

:root{
  --fs-sk-base:   rgba(255,255,255,.055);   /* resting fill on a card    */
  --fs-sk-base-2: rgba(255,255,255,.08);    /* slightly stronger fill    */
  --fs-sk-sheen:  rgba(255,255,255,.12);    /* travelling highlight       */
  --fs-sk-radius: 8px;
  --fs-sk-speed:  1.45s;
}

/* ---- base shimmer primitive ---------------------------------- */
.skeleton{
  position:relative;
  overflow:hidden;
  display:block;
  background:var(--fs-sk-base);
  border-radius:var(--fs-sk-radius);
  /* keep skeletons out of the a11y tree by default */
}
.skeleton::after{
  content:"";
  position:absolute;
  inset:0;
  transform:translateX(-100%);
  background:linear-gradient(90deg,
      transparent 0,
      var(--fs-sk-sheen) 50%,
      transparent 100%);
  animation:fsSkShimmer var(--fs-sk-speed) ease-in-out infinite;
  will-change:transform;
}
@keyframes fsSkShimmer{ 100%{ transform:translateX(100%); } }

/* Reduced motion: no travelling sheen, calm static fill only */
@media (prefers-reduced-motion:reduce){
  .skeleton::after{ animation:none; opacity:0; }
  .skeleton{ background:var(--fs-sk-base-2); }
}

/* ---- text primitives ---------------------------------------- */
.skeleton-line{ height:12px; width:100%; border-radius:6px; }
.skeleton-line + .skeleton-line{ margin-top:9px; }
.skeleton-title{ height:20px; width:58%; border-radius:7px; }
.skeleton-subtitle{ height:13px; width:38%; border-radius:6px; margin-top:9px; }

/* ---- shape primitives --------------------------------------- */
.skeleton-avatar{ width:48px; height:48px; border-radius:50%; flex:none; }
.skeleton-icon{ width:22px; height:22px; border-radius:7px; flex:none; }
.skeleton-button{ height:44px; width:140px; border-radius:12px; }
.skeleton-card{ border-radius:16px; width:100%; height:120px; }
.skeleton-metric{ height:28px; width:72%; border-radius:8px; }
.skeleton-form-field{ height:44px; width:100%; border-radius:10px; }
.skeleton-sidebar-item{ height:44px; width:100%; border-radius:10px; }

/* ---- chart placeholder (reserves final height, no collapse) -- */
.skeleton-chart{
  width:100%;
  min-height:220px;
  border-radius:12px;
  background:
    linear-gradient(180deg, rgba(255,255,255,.02), rgba(255,255,255,.045));
}
/* faint baseline + rising area hint so it reads as a chart, calmly */
.skeleton-chart::before{
  content:"";
  position:absolute;
  left:0; right:0; bottom:0;
  height:46%;
  background:linear-gradient(180deg, rgba(209,158,0,.05), rgba(209,158,0,.11));
  -webkit-mask:linear-gradient(180deg,transparent,#000);
          mask:linear-gradient(180deg,transparent,#000);
  clip-path:polygon(0 78%, 12% 60%, 26% 70%, 40% 40%, 55% 52%, 70% 24%, 84% 38%, 100% 14%, 100% 100%, 0 100%);
}

/* ---- table skeleton ----------------------------------------- */
.skeleton-table{ width:100%; }
.skeleton-row{ display:flex; align-items:center; gap:14px; padding:12px 2px; border-top:1px solid rgba(255,255,255,.05); }
.skeleton-row:first-child{ border-top:none; }
.skeleton-row .skeleton-line{ height:11px; }

/* ---- state helpers on real regions -------------------------- */
/* Refresh-in-place: keep old content, drop opacity + block clicks */
.is-loading{ position:relative; }
.is-loading[data-fs-dim]{ opacity:.55; transition:opacity .2s ease; pointer-events:none; }
.is-loaded{}

/* ---- button loading (disable + inline spinner, no double submit) */
.fs-btn-loading{ position:relative; pointer-events:none; }
.fs-btn-spinner{
  display:inline-block; width:15px; height:15px; vertical-align:-2px;
  margin-right:8px; border-radius:50%;
  border:2px solid rgba(0,0,0,.28); border-top-color:currentColor;
  animation:fsSkSpin .7s linear infinite;
}
/* on dark/gold buttons the spinner track is dark; on ghost buttons override */
.fs-btn-spinner.on-dark{ border-color:rgba(255,255,255,.25); border-top-color:#fff; }
@keyframes fsSkSpin{ to{ transform:rotate(360deg); } }
@media (prefers-reduced-motion:reduce){ .fs-btn-spinner{ animation-duration:1.4s; } }

/* ---- image lazy fade-in ------------------------------------- */
.fs-img-fade{ opacity:0; transition:opacity .45s ease; }
.fs-img-fade.fs-img-loaded{ opacity:1; }
@media (prefers-reduced-motion:reduce){ .fs-img-fade{ transition:none; opacity:1; } }

/* ---- screen-reader only ------------------------------------- */
.sr-only{
  position:absolute !important;
  width:1px; height:1px;
  padding:0; margin:-1px;
  overflow:hidden; clip:rect(0,0,0,0);
  white-space:nowrap; border:0;
}

/* ============================================================
   Unify the dashboard's legacy signals-table shimmer (.sk-bar /
   .signal-skeleton-row) onto this system so both animate as one.
   ============================================================ */
.sk-bar{
  position:relative; overflow:hidden;
  background:var(--fs-sk-base) !important;
  animation:none !important;               /* replace old bg-position keyframe */
}
.sk-bar::after{
  content:""; position:absolute; inset:0; transform:translateX(-100%);
  background:linear-gradient(90deg,transparent 0,var(--fs-sk-sheen) 50%,transparent 100%);
  animation:fsSkShimmer var(--fs-sk-speed) ease-in-out infinite;
}
@media (prefers-reduced-motion:reduce){
  .sk-bar::after{ animation:none; opacity:0; }
  .sk-bar{ background:var(--fs-sk-base-2) !important; }
}
