/* Skeletons: the shape of what is coming, while it is coming.
 *
 * A region filled after a fetch has three honest states and most of this
 * platform only had two. Empty, then suddenly full, reads as a jump - the page
 * looks finished, then rearranges itself under the reader's eyes, and on a
 * slow connection the gap is long enough to decide nothing is there.
 *
 * A skeleton is not a spinner. A spinner says "something is happening"; a
 * skeleton says "something is happening AND it will be shaped like this", so
 * the layout stops moving before the content lands rather than after.
 *
 * ONE PLACE because every module wants it. The commerce gallery grew its own
 * first (a product photograph painting in line by line), and a second copy in
 * insights would have drifted from it by a week.
 */

.sk {
  /* A skeleton replaces content, so it must not be read out as content. The
     markup carries aria-hidden; this keeps it out of the way of a text
     selection too. */
  user-select: none;
  pointer-events: none;
}

.sk-line,
.sk-block {
  background:
    linear-gradient(90deg,
      transparent 0%,
      rgba(var(--bs-emphasis-color-rgb, 0, 0, 0), .06) 50%,
      transparent 100%)
    var(--bs-secondary-bg, #eceef1);
  background-size: 200% 100%;
  animation: sk-sweep 1.4s ease-in-out infinite;
  border-radius: .3rem;
}

.sk-line {
  height: .8rem;
  margin-bottom: .55rem;
}
.sk-line:last-child { margin-bottom: 0; }

/* The widths are uneven on purpose. Three identical bars read as a loading
   graphic; bars of different lengths read as a paragraph that has not arrived,
   which is what is actually coming. */
.sk-line.sk-w-90 { width: 90%; }
.sk-line.sk-w-75 { width: 75%; }
.sk-line.sk-w-60 { width: 60%; }
.sk-line.sk-w-40 { width: 40%; }

.sk-block { height: 100%; min-height: 4rem; }

/* For a region that is tall rather than text-shaped - a chart, a map, a
   preview pane. Not used yet: both charts measured turned out to draw from
   data already in the page rather than waiting on a fetch, so a skeleton
   there would be code that can never run. Kept because the next one may not
   be, and the shape is the part worth agreeing on in advance. */
.sk-chart .sk-line { height: 11rem; margin-bottom: 0; width: 100%; }

/* A skeleton standing in for a card keeps the card's frame, so the column does
   not change width when the real one arrives. */
.sk-card {
  border: 1px solid var(--bs-border-color);
  border-radius: var(--bs-border-radius, .5rem);
  padding: .85rem 1rem;
  margin-bottom: .75rem;
  background: var(--bs-paper-bg, var(--bs-card-bg, #fff));
}

@keyframes sk-sweep {
  from { background-position: 200% 0; }
  to   { background-position: -200% 0; }
}

/* Somebody who has asked for less motion gets the shape without the sweep.
   The shape is the useful half; the movement is decoration. */
@media (prefers-reduced-motion: reduce) {
  .sk-line, .sk-block { animation: none; }
}
