/* Shared loading shimmer/skeleton styles
   Supports dark/light via existing theme CSS variables + Tailwind dark class */
/* Defaults read well on BOTH light and dark surfaces, so the skeleton looks
   right even on pages that never toggle a `dark` class (e.g. the standalone
   landing page, which is always dark navy). The .dark block just tunes the
   tokens for explicit dark mode. */
:root {
  --skeleton-base: rgba(148, 163, 184, 0.22);
  --skeleton-highlight: rgba(255, 255, 255, 0.6);
  --skeleton-radius: 0.75rem;
  --skeleton-duration: 1.8s;
}

.dark {
  --skeleton-base: rgba(255, 255, 255, 0.1);
  --skeleton-highlight: rgba(255, 255, 255, 0.28);
}

.skeleton {
  position: relative;
  overflow: hidden;
  background: var(--skeleton-base);
  border-radius: var(--skeleton-radius);
  will-change: transform;
  isolation: isolate;
}

.skeleton::after {
  content: "";
  position: absolute;
  inset: 0;
  transform: translateX(-100%);
  background-image: linear-gradient(
    90deg,
    rgba(255, 255, 255, 0) 0%,
    var(--skeleton-highlight) 50%,
    rgba(255, 255, 255, 0) 100%
  );
  animation: shimmer var(--skeleton-duration) infinite ease-in-out;
  pointer-events: none;
}

.skeleton--rect {
  border-radius: 0.5rem;
}

.skeleton--circle {
  border-radius: 9999px;
  aspect-ratio: 1 / 1;
}

.skeleton--text {
  height: 1em;
  border-radius: 0.375rem;
}

.skeleton--line-xs {
  height: 0.625rem;
}

.skeleton--line-sm {
  height: 0.75rem;
}

.skeleton--line-md {
  height: 1rem;
}

.skeleton--line-lg {
  height: 1.25rem;
}

.skeleton--line-xl {
  height: 1.5rem;
}

.skeleton--card {
  min-height: 14rem;
}

.skeleton--img {
  width: 100%;
  height: 100%;
}

@keyframes shimmer {
  100% {
    transform: translateX(100%);
  }
}

@media (prefers-reduced-motion: reduce) {
  .skeleton::after {
    animation: none;
    background-image: none;
  }
}

/* .img-skeleton — wrapper that fades its single <img> in over a shimmer.
   Unlike .sk-watch this DOES own the image (sets its opacity), so use it on a
   dedicated wrapper you add around one image, not on a wrapper that already
   animates its own image. */
.img-skeleton {
  position: relative;
  overflow: hidden;
  background: var(--skeleton-base);
  border-radius: inherit;
}

.img-skeleton::after {
  content: "";
  position: absolute;
  inset: 0;
  transform: translateX(-100%);
  background-image: linear-gradient(
    90deg,
    rgba(255, 255, 255, 0) 0%,
    var(--skeleton-highlight) 50%,
    rgba(255, 255, 255, 0) 100%
  );
  pointer-events: none;
}

/* Shimmer runs only while in / near the viewport (see .sk-watch note). */
.img-skeleton.is-loading::after {
  animation: shimmer var(--skeleton-duration) infinite ease-in-out;
}

.img-skeleton > img {
  position: relative;
  z-index: 1;
  opacity: 0;
  transition: opacity 0.25s ease-in-out;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.img-skeleton.is-loaded > img {
  opacity: 1;
}

.img-skeleton.is-loaded::after {
  content: none;
}

.img-skeleton.is-loaded {
  background: transparent;
}

@media (prefers-reduced-motion: reduce) {
  .img-skeleton.is-loading::after {
    animation: none;
    background-image: none;
  }
}

/* .sk-watch — lightweight variant.
   Put it on any container that holds image(s); a shimmer shows until the
   image(s) finish loading.

   It paints the shimmer on the element's OWN background-image
   (two layers: a moving highlight over a flat base tint) instead of an overlay
   pseudo-element. Two reasons:
   1. The real image paints on top and fully hides the shimmer the moment it
      decodes — no z-index games, no overlay ever covers the photo.
   2. It only touches `background-image`, never `background-color`, so a class
      like `bg-navy-900` on the same element is untouched and restored for free
      once `is-loaded` clears the gradient.

   On its own the shimmer is only visible while an image is still downloading,
   which on a fast/cached connection is too brief to notice. Below-the-fold
   wrappers therefore also get the `.sk-reveal` modifier (see below). */
.sk-watch {
  background-image: linear-gradient(var(--skeleton-base), var(--skeleton-base));
  background-size: 100% 100%;
  background-repeat: no-repeat;
}

/* The moving highlight only runs while the element is actually in / near the
   viewport (`is-loading` is added by JS). A lazy image far below the fold
   therefore never keeps an animation spinning off-screen, which matters on
   mobile. */
.sk-watch.is-loading {
  background-image:
    linear-gradient(
      90deg,
      rgba(255, 255, 255, 0) 0%,
      var(--skeleton-highlight) 50%,
      rgba(255, 255, 255, 0) 100%
    ),
    linear-gradient(var(--skeleton-base), var(--skeleton-base));
  background-size: 200% 100%, 100% 100%;
  animation: shimmer-bg var(--skeleton-duration) linear infinite;
}

.sk-watch.is-loaded {
  background-image: none;
  animation: none;
}

@keyframes shimmer-bg {
  0% {
    background-position: 200% 0, 0 0;
  }
  100% {
    background-position: -200% 0, 0 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .sk-watch.is-loading {
    animation: none;
    background-image: linear-gradient(var(--skeleton-base), var(--skeleton-base));
  }
}

/* .sk-reveal — reveal treatment added by JS to BELOW-THE-FOLD `.sk-watch`
   wrappers only. Above-the-fold (LCP) wrappers never receive it.

   The photo is held at opacity 0 while the skeleton is on screen, then faded
   back in by JS after the shimmer has been visible for its minimum duration.
   Without this the photo would paint over the shimmer the instant it decoded,
   which is exactly why the effect was invisible on a fast connection.

   Opacity keeps the element's box, so there is no layout shift (CLS). */
.sk-watch.sk-reveal:not(.is-loaded) img {
  opacity: 0;
}

/* `.sk-fading` is armed by JS one frame before `is-loaded` flips, so the photo
   cross-fades instead of snapping in. It is removed again once the fade ends,
   which leaves the image under pure CSS control (product hover transforms and
   news thumbnail scaling keep working).

   The transition lives on the class, not on `img`, so it can never leak into
   unrelated images. */
img.sk-fading {
  transition: opacity 350ms ease-out;
}

@media (prefers-reduced-motion: reduce) {
  img.sk-fading {
    transition: none;
  }
}

.content-skeleton .sk-line + .sk-line {
  margin-top: 0.5rem;
}

.content-skeleton .sk-line:last-child {
  width: 70%;
}