/* ==========================================================================
   Media skeleton loading state
   ==========================================================================
   Applies to any image-bearing media box that hasn't finished loading yet:
   the product iPhone's screen (.iphone-screen .device-shot) and gallery tiles
   (.gallery-item img). js/global.js's initMediaSkeleton() tags a box with
   data-loading while its image is still fetching/decoding, and removes it
   on load or error.

   Self-contained on purpose, same pattern as atmosphere.css and
   splash-cube.css: drop this <link> and these boxes just render as their
   flat --am-900/near-black fallback with no skeleton motion at all.

   Respects prefers-reduced-motion: the sweep stops moving, the surface
   just sits at a static mid-tone instead of animating.
   ========================================================================== */

@keyframes skeleton-sweep {
  0%   { transform: translateX(-140%); }
  100% { transform: translateX(140%); }
}

@keyframes skeleton-pulse {
  0%, 100% { opacity: 0.55; }
  50%      { opacity: 0.85; }
}

/* Shared skeleton surface: a near-black base (matches the flat #050409
   media boxes already used for product logos) with a faint amethyst
   underlight so it reads as "loading" rather than "empty" or "broken". */
[data-loading] {
  position: relative;
  background:
    radial-gradient(120% 140% at 50% 20%, var(--am-900) 0%, #050409 62%);
  overflow: hidden;
}

/* Hide the real image while loading rather than letting a half-decoded
   frame or broken-icon flash through underneath the skeleton. */
[data-loading] img,
[data-loading] .device-shot {
  opacity: 0;
}

/* The diagonal sweep. A single soft amethyst band, not a hard shine line:
   hard highlights read as cheap; this stays close to the atmosphere.css
   aesthetic of soft, blurred, drifting light rather than a crisp gloss. */
[data-loading]::before {
  content: "";
  position: absolute;
  inset: -20% -60%;
  background: linear-gradient(
    100deg,
    transparent 30%,
    rgba(173, 79, 255, 0.10) 45%,
    rgba(173, 79, 255, 0.22) 50%,
    rgba(173, 79, 255, 0.10) 55%,
    transparent 70%
  );
  animation: skeleton-sweep 2.1s var(--ease) infinite;
  will-change: transform;
  pointer-events: none;
}

/* A faint centered glyph placeholder (a soft square, echoing the studio's
   cube motif at low opacity) so the box doesn't read as fully blank on
   very slow connections, before the sweep alone would carry it. */
[data-loading]::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 22%;
  aspect-ratio: 1;
  max-width: 64px;
  transform: translate(-50%, -50%) rotate(45deg);
  border: 1.5px solid var(--line-strong);
  border-radius: 6px;
  animation: skeleton-pulse 2.1s var(--ease) infinite;
  pointer-events: none;
}

/* Gallery tiles and the device mock both already set overflow/position,
   but reassert here in case a future container doesn't. */
.gallery-item[data-loading] {
  position: relative;
  overflow: hidden;
}

/* Fade the real image in once loading is done. Applies whether or not
   [data-loading] was ever present, so it's safe to leave on permanently. */
.gallery-item img,
.device-shot {
  transition: opacity var(--dur-m) var(--ease);
}

@media (prefers-reduced-motion: reduce) {
  [data-loading]::before,
  [data-loading]::after {
    animation: none;
  }
  [data-loading]::before {
    opacity: 0.6;
  }
  [data-loading]::after {
    opacity: 0.5;
  }
}
