/* ==========================================================================
   Movimento compartilhado: progresso, skeletons, imagens e transições.
   Durações e curvas vêm de base.css (--dur-fast 160ms, --dur-base 280ms,
   --ease-out). Entradas usam --dur-base; saídas são mais curtas e sutis.
   ========================================================================== */
:root {
  --skeleton-base: rgb(var(--ink-rgb) / .07);
  --skeleton-shine: rgb(255 255 255 / .55);
}

:root[data-theme="dark"] {
  --skeleton-base: rgb(var(--ink-rgb) / .08);
  --skeleton-shine: rgb(255 255 255 / .06);
}

/* ---------- Barra de progresso (navegação e chamadas à API) ---------- */
.pl-progress {
  position: fixed;
  inset: 0 0 auto;
  z-index: 1000;
  height: 3px;
  pointer-events: none;
  opacity: 0;
  transition: opacity var(--dur-fast) var(--ease-out) 120ms;
}

.pl-progress.is-active {
  opacity: 1;
  transition-delay: 0ms;
}

.pl-progress span {
  display: block;
  height: 100%;
  background: var(--gradient-brand);
  box-shadow: 0 0 8px var(--color-hover-shadow);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 400ms var(--ease-out);
}

.pl-progress.is-resetting span {
  transition: none;
}

/* ---------- Skeleton ---------- */
.pl-skeleton {
  position: relative;
  display: block;
  overflow: hidden;
  background: var(--skeleton-base);
  border-radius: 8px;
}

.pl-skeleton::after {
  content: "";
  position: absolute;
  inset: 0;
  transform: translateX(-100%);
  background: linear-gradient(90deg, transparent, var(--skeleton-shine), transparent);
}

@media (prefers-reduced-motion: no-preference) {
  .pl-skeleton::after {
    animation: pl-skeleton-shine 1.4s linear infinite;
  }
}

@keyframes pl-skeleton-shine {
  to {
    transform: translateX(100%);
  }
}

/* Card de produto provisório (mesmas medidas do card vertical). */
.pcard-skeleton {
  pointer-events: none;
  box-shadow: none;
}

.pcard-skeleton .pcard-img.pl-skeleton {
  background: var(--skeleton-base);
  border-radius: 0;
}

.pcard-skeleton .pcard-img::before {
  display: none;
}

.pcard-skeleton .pcard-info {
  gap: 10px;
}

.pcard-skeleton-code {
  width: 62%;
  height: 24px;
}

.pcard-skeleton-badge {
  width: 100%;
  height: 30px;
  border-radius: 0;
}

.pcard-skeleton-spec {
  width: 80%;
  height: 34px;
}

/* Lateral: informações ao lado da foto. */
.pcard--lateral.pcard-skeleton .pcard-info {
  justify-content: space-evenly;
  align-items: center;
  padding: 0 var(--lateral-pad, 16px);
}

.pcard--lateral.pcard-skeleton .pcard-skeleton-spec {
  width: 100%;
  height: 28px;
}

/* Lista: mesma grade do card real; tarja na base, logo acima dos dados elétricos. */
.pcard--list.pcard-skeleton .pcard-list-main .pcard-skeleton-code {
  width: 70%;
  height: 34px;
  margin: 0;
}

.pcard--list.pcard-skeleton .pcard-list-main .pcard-skeleton-badge {
  width: auto;
  margin: auto calc(-1 * var(--list-pad-x, 24px)) calc(var(--list-pad-y, 22px) - var(--list-gap, 14px));
}

.pcard--list.pcard-skeleton .pcard-list-main .pcard-skeleton-spec {
  width: 100%;
  height: 30px;
}

.pcard-skeleton-title {
  flex: none;
  width: 130px;
  height: 14px;
  margin-bottom: var(--list-gap, 14px);
}

.pcard-skeleton-groups {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: var(--list-gap, 14px) 28px;
  flex: 1 1 auto;
  min-height: 0;
}

.pcard-skeleton-groups .pl-skeleton {
  height: 100%;
  min-height: 80px;
}

/* Skeleton só aparece se a espera passar de 250ms: respostas rápidas (cache)
   vão direto ao conteúdo, sem o skeleton piscar na tela. */
.pl-delayed-reveal {
  animation: pl-fade var(--dur-base) var(--ease-out) 250ms backwards;
}

/* Imagem que já estava em cache aparece na hora, sem esmaecer. */
.motion-ready img.is-instant {
  transition: none !important;
}

/* ---------- Imagens: esmaecem ao terminar de carregar ----------
   Só com o script ativo (.motion-ready): sem ele, as imagens aparecem normalmente. */
.motion-ready :is(.pcard-img,.product-main-image-wrap,.product-thumbnail,.hero-banner-slot) img:not(.is-loaded) {
  opacity: 0;
}

.motion-ready .pcard .pcard-img img {
  transition: transform var(--dur-base) var(--ease-out), opacity var(--dur-base) var(--ease-out);
}

.motion-ready :is(.product-thumbnail,.hero-banner-slot) img {
  transition: opacity var(--dur-base) var(--ease-out);
}

.motion-ready :is(.pcard-img,.product-thumbnail,.hero-banner-slot):has(> img:not(.is-loaded)),
.motion-ready main.product-stage .product-main-image-wrap:has(> img:not(.is-loaded)) {
  background-color: var(--skeleton-base);
  background-image: linear-gradient(90deg, transparent 30%, var(--skeleton-shine) 50%, transparent 70%);
  background-size: 200% 100%;
  background-repeat: no-repeat;
}

@media (prefers-reduced-motion: no-preference) {
  .motion-ready :is(.pcard-img,.product-thumbnail,.hero-banner-slot):has(> img:not(.is-loaded)),
  .motion-ready main.product-stage .product-main-image-wrap:has(> img:not(.is-loaded)) {
    animation: pl-image-loading 1.4s linear infinite;
  }
}

@keyframes pl-image-loading {
  from {
    background-position: 150% 0;
  }

  to {
    background-position: -50% 0;
  }
}

/* ---------- Entradas de conteúdo (variam conforme o papel do elemento) ---------- */
@media (prefers-reduced-motion: no-preference) {
  /* Conteúdo principal que chega da API: sobe 8px e aparece. */
  .pl-reveal:not([hidden]) {
    animation: pl-enter var(--dur-base) var(--ease-out) backwards;
  }
}

@keyframes pl-enter {
  from {
    opacity: 0;
    transform: translateY(8px);
  }
}

@keyframes pl-fade {
  from {
    opacity: 0;
  }
}

/* ---------- Menu do cabeçalho no celular: entra do botão e sai mais rápido ---------- */
@media (max-width: 767px) and (prefers-reduced-motion: no-preference) {
  .pl-nav {
    opacity: 0;
    transform: translateY(-6px);
    transform-origin: top right;
    transition: opacity 120ms var(--ease-out), transform 120ms var(--ease-out), display 120ms allow-discrete;
  }

  .is-open .pl-nav {
    opacity: 1;
    transform: none;
    transition-duration: 220ms;
  }

  @starting-style {
    .is-open .pl-nav {
      opacity: 0;
      transform: translateY(-6px);
    }
  }
}

/* ---------- Transição suave entre páginas do site ----------
   O navegador continua mostrando a página atual até a próxima estar pronta (com a barra
   de progresso) e então faz um esmaecimento cruzado curto entre as duas. É o esmaecimento
   padrão do navegador (as duas imagens somam sempre 100%, sem clarear nem escurecer no
   meio), sem movimento, para não somar com as animações de entrada de cada página.
   Vale também para voltar/avançar. Navegadores sem suporte trocam de página como antes. */
@media (prefers-reduced-motion: no-preference) {
  @view-transition {
    navigation: auto;
    types: pl-page;
  }
}

:root:active-view-transition-type(pl-page)::view-transition-old(root),
:root:active-view-transition-type(pl-page)::view-transition-new(root) {
  animation-duration: 180ms;
  animation-timing-function: ease-out;
}
