/* Skeleton loading placeholders (js/skeleton.js) and the distinct
   "filters produced zero rows" empty state (render.js's
   upgradeEmptyStates()). Neither is the other: a skeleton means "not
   loaded yet", an empty state means "loaded, and there is genuinely
   nothing here" - conflating them would tell a reader who just cleared
   every filter that the page is still loading. */

/* ---------- un-hide cards for the "loading" state only ----------
   states.css blanks #kpiGrid, .sec, .foot, .side-filters and .side-foot
   until body[data-state="ready"]. The footer and the sidebar filters
   still have nothing truthful to show before the first snapshot (facet
   option lists and the generated-at date both come FROM that snapshot),
   so they stay hidden exactly as states.css left them. The KPI row and
   the section cards get their skeleton shape instead of being blanked.

   Selector weight matches states.css's rule exactly (type + attribute +
   class), and this stylesheet loads after states.css in dashboard.html,
   so the cascade favours this override without needing !important. */
/* #kpiGrid needs display:grid, not merely "not none": an ID selector
   always outranks a class one, so a separate `.kpi-grid{display:grid}`
   follow-up rule (lower specificity than this #kpiGrid one) would lose
   the cascade for the `display` property specifically and leave the KPI
   row's six cards stacked as plain blocks instead of a 3/6-column grid -
   which was exactly the first bug this file's CDP verification caught. */
body[data-state="loading"] #kpiGrid{ display:grid; }
body[data-state="loading"] .sec{ display:block; }

/* ---------- the one shared primitive: a solid var(--skeleton) block ---- */
.sk-block{
  display:inline-block; vertical-align:middle;
  background-color:var(--skeleton);
  background-image:linear-gradient(90deg, transparent, var(--track), transparent);
  background-size:120px 100%;
  background-repeat:no-repeat;
  background-position:-120px 0;
  animation:sk-shimmer 1.7s ease-in-out infinite;
}
.sk-text{ display:inline-flex; flex-direction:column; gap:6px; width:100%; }
@keyframes sk-shimmer{
  0%{ background-position:-120px 0; }
  100%{ background-position:calc(100% + 120px) 0; }
}
/* Off by default under reduced motion: a sweeping gradient is exactly the
   kind of motion that preference exists to suppress. The block itself
   still reads as a placeholder without it - just flat, not shimmering. */
@media (prefers-reduced-motion:reduce){
  .sk-block{ animation:none; background-image:none; }
}

/* ---------- bar list (impact, usage type, venue, employees, industry,
   membership, districts, consent fields) ----------
   .bl-row/.bl-label/.bl-track/.bl-value are the REAL classes from
   charts.css; reusing them here means --bar-height/--bar-label-col/
   --bar-value-col/--bar-gap size the skeleton row exactly as they size a
   loaded one, with nothing restated. Only .bl-fill needs a colour
   override, since the real rule paints it var(--series-primary). */
.bl-fill.is-skeleton{ background:var(--skeleton); animation:none; }
.bl-row.is-skeleton{ pointer-events:none; }

/* ---------- donut (topic mix, consent standing) ----------
   .donut-svg/.legend-rows/.lrow/.sw/.ltxt/.lnum are the real classes from
   viz.css/cards.css; the ring geometry itself comes from DONUT in
   js/tokens.js via skeleton.js, not from anything restated here. */
.legend-rows .sw.is-skeleton{ background:var(--skeleton); }
.donut-row.is-skeleton .lrow{ pointer-events:none; }

/* ---------- trend / advocacy line charts ----------
   No real class to reuse for the plot area itself (the real one is an
   <svg>), so this is sized by skeleton.js's trendSkeletonHeight(), which
   mirrors TrendChart's own W-dependent height rule from primitives.js
   rather than picking an independent number. */
.sk-trend{
  position:relative; border-radius:var(--radius-sm); overflow:hidden;
  background-color:var(--skeleton);
  background-image:linear-gradient(90deg, transparent, var(--track), transparent);
  background-size:220px 100%; background-repeat:no-repeat; background-position:-220px 0;
  animation:sk-shimmer 1.9s ease-in-out infinite;
}
.sk-trend-ticks{
  position:absolute; left:0; right:0; bottom:8px; display:flex; justify-content:space-between; padding:0 10px;
}
@media (prefers-reduced-motion:reduce){
  .sk-trend{ animation:none; background-image:none; }
}

/* ---------- story feed table ----------
   .t-story/.t-company/.t-loc/.t-num/.t-topics/.status-pill/.tag-chip are
   all real classes from table.css; the skeleton row's cell padding, font
   metrics and column proportions are therefore identical to a loaded
   row's, and only the cell content (a solid block instead of text)
   differs. */
tr.is-skeleton td{ pointer-events:none; }
.status-pill.is-skeleton{ background:var(--skeleton); border-color:transparent; color:transparent; }
.tag-chip.is-skeleton{ background:var(--skeleton); border-color:transparent; color:transparent; }

/* ---------- KPI grid ----------
   .kpi/.kpi-row/.kpi-value/.kpi-sub/.kpi-spark are the real classes from
   layout.css/cards.css. .sk-kpi-value is sized in `em` so it always
   reads as a fraction of .kpi-value's own line box (font-size is a
   clamp(), so no px number here could track it safely) and can never be
   taller than the text it stands in for. */
.sk-kpi-value{ width:64px; height:0.72em; }
.kpi.is-skeleton .kpi-spark.sk-block{ border-radius:4px; }

/* ---------- lifecycle funnel segmented bar ---------- */
.segbar .seg.is-skeleton{ height:100%; background-color:var(--skeleton); }

/* ---------- empty state ----------
   Set by render.js's upgradeEmptyStates() once real data has rendered
   and a filter produced zero rows - never by anything in skeleton.js.
   Same fixed-height frame a populated card would occupy, so the bento
   grid around it does not collapse or reflow when a filter empties one
   card but not its neighbour. */
.viz-empty.is-empty-state{
  display:flex; flex-direction:column; align-items:center; justify-content:center;
  gap:10px; text-align:center; min-height:140px; padding:20px 12px;
}
.viz-empty .empty-clear{
  font-family:var(--sans); font-weight:300; font-size:12px; line-height:1;
  padding:8px 16px; border:1px solid var(--border-strong); border-radius:var(--radius-pill);
  background:var(--surface); color:var(--text-primary); cursor:pointer;
}
.viz-empty .empty-clear:hover{ border-color:var(--tag); color:var(--tag); }
