/* Loading skeletons.
 *
 * These live in the markup rather than being injected by script, because the
 * moment they are needed is the one before any script has run: every page is an
 * ES module that awaits an auth check before it renders anything. A skeleton that
 * only appears once JS is alive would miss exactly the pause it exists to cover.
 *
 * They need no teardown either — every render path replaces the innerHTML or
 * textContent of the element holding them, so a skeleton clears itself the moment
 * real content lands. The two exceptions are canvases, which are drawn into
 * rather than written over, and KPIs that may never receive a figure; both are
 * handled by clearSkeletons() in js/skeleton.js.
 *
 * Built only from theme variables, so light and dark both work with no extra rules.
 */

@keyframes sk-shimmer {
  from { background-position: 180% 0; }
  to   { background-position: -80% 0; }
}

.sk,
.sk-table i,
.sk-chart i,
.sk-donut {
  border-radius: 3px;
  /* --border-strong is the highest-contrast neutral every theme defines, so the
     shimmer is visible without a hard-coded colour. */
  background-image: linear-gradient(
    90deg,
    var(--surface-alt) 20%,
    var(--border-strong) 38%,
    var(--surface-alt) 56%
  );
  background-size: 220% 100%;
  animation: sk-shimmer 1.6s linear infinite;
}

/* Where color-mix is available, mix the highlight from the theme's own text
   colour: it lightens on a dark ground and darkens on a light one, so the
   shimmer keeps the same weight in both without a second palette. */
@supports (background: color-mix(in srgb, red 10%, blue)) {
  .sk,
  .sk-table i,
  .sk-chart i,
  .sk-donut {
    background-image: linear-gradient(
      90deg,
      var(--surface-alt) 20%,
      color-mix(in srgb, var(--text) 13%, var(--surface-alt)) 38%,
      var(--surface-alt) 56%
    );
  }
}

/* Rows standing in for a table body. Widths vary so it reads as content rather
   than as a progress bar. */
.sk-table {
  display: flex;
  flex-direction: column;
  gap: .62rem;
  padding: .5rem 0;
}

.sk-table i {
  display: block;
  height: .78rem;
  width: 100%;
}

.sk-table i:nth-child(2) { width: 82%; }
.sk-table i:nth-child(3) { width: 91%; }
.sk-table i:nth-child(4) { width: 74%; }
.sk-table i:nth-child(5) { width: 86%; }

/* A table cell holding skeleton rows should not inherit the centred, padded
   styling of the "no data" cell it replaces. */
td.sk-cell {
  padding: .35rem .6rem !important;
  text-align: left !important;
}

/* Charts are drawn into a canvas, so their skeleton sits over the wrap and is
   removed once something has been drawn. Bars rather than one filled slab: a
   grey rectangle the size of a panel reads as something broken, where a row of
   columns reads as a chart that has not arrived. */
.sk-chart {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: flex-end;
  gap: 2.2%;
  /* Fixed, not percentage: percentage padding resolves against the container's
     width, which on a wide card exceeds its height and collapses the bars to
     nothing. */
  padding: 2.25rem .5rem 0;
  box-sizing: border-box;
  /* The baseline the bars stand on — the axis the real chart will draw. */
  border-bottom: 1px solid var(--border);
}

.sk-chart i {
  flex: 1;
  display: block;
  border-radius: 2px 2px 0 0;
  opacity: .8;
}

/* A climbing, uneven profile — the shape of a portfolio, not a bar chart of
   nothing in particular. */
.sk-chart i:nth-child(1)  { height: 22%; }
.sk-chart i:nth-child(2)  { height: 31%; }
.sk-chart i:nth-child(3)  { height: 27%; }
.sk-chart i:nth-child(4)  { height: 40%; }
.sk-chart i:nth-child(5)  { height: 36%; }
.sk-chart i:nth-child(6)  { height: 49%; }
.sk-chart i:nth-child(7)  { height: 58%; }
.sk-chart i:nth-child(8)  { height: 52%; }
.sk-chart i:nth-child(9)  { height: 66%; }
.sk-chart i:nth-child(10) { height: 74%; }
.sk-chart i:nth-child(11) { height: 69%; }
.sk-chart i:nth-child(12) { height: 84%; }

/* A ring, because the charts it stands in for are doughnuts. */
.sk-donut {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 148px;
  height: 148px;
  margin: -74px 0 0 -74px;
  border-radius: 50%;
  -webkit-mask: radial-gradient(circle, transparent 0 54%, #000 55%);
  mask: radial-gradient(circle, transparent 0 54%, #000 55%);
}

/* A single figure — a KPI value, an inline total. */
.sk-value {
  display: inline-block;
  height: 1.05em;
  width: 4.5em;
  vertical-align: -.12em;
}

.sk-value.narrow { width: 3em; }

/* Motion is decoration here: the shape alone says "not yet". */
@media (prefers-reduced-motion: reduce) {
  .sk,
  .sk-table i,
  .sk-chart i,
  .sk-donut {
    animation: none;
  }
}
