/**
 * Skeleton Loader for Elementor & WooCommerce
 *
 * Toda a customização passa por custom properties definidas no wrapper
 * pelos controles do Elementor. Nenhuma medida fixa em px no CSS base.
 */

.esl-skeleton {
	--esl-bg: #EEF1EF;
	--esl-radius: 8px;
	--esl-speed: 1.35s;
	--esl-ratio: 1;
	--esl-cols: 4;
	--esl-cols-tablet: 3;
	--esl-cols-mobile: 2;
	--esl-gap: 0px;
	/* Sem limite por padrão — o usuário define via painel do Elementor */
	--esl-max-w: 9999px;
	--esl-max-h: 9999px;

	box-sizing: border-box;
	max-width: 100%;
}

.esl-skeleton *,
.esl-skeleton *::before,
.esl-skeleton *::after {
	box-sizing: border-box;
}

/* --------------------------------------------------------
   1. Estado de carregamento
   -------------------------------------------------------- */

.esl-skeleton.is-loading {
	pointer-events: none;
	overflow: hidden;
}

.esl-skeleton.is-loading > .swiper,
.esl-skeleton.is-loading > .elementor-loop-container {
	overflow: hidden;
	margin: 0;
	max-width: 100%;
}

.esl-skeleton.is-loading .swiper-wrapper {
	display: flex;
	/*
	 * flex-start: cada slide define sua própria altura via aspect-ratio
	 * da imagem. "stretch" causava blocos gigantes porque todos os slides
	 * esticavam para igualar o mais alto.
	 */
	align-items: flex-start;
	gap: var(--esl-gap);
	height: auto;
	transform: translate3d(0, 0, 0);
	transition: none;
}

/* --------------------------------------------------------
   2. Reserva de espaço dos slides (Carrossel — Swiper)
   A largura vem do próprio "slides per view" do widget,
   então o skeleton casa com o layout final do Swiper.
   -------------------------------------------------------- */

.esl-skeleton.is-loading .swiper-slide {
	--esl-slide-w: calc(
		(100% - (var(--esl-cols) - 1) * var(--esl-gap)) / var(--esl-cols)
	);

	display: block;
	/* min() garante que o card nunca ultrapasse --esl-max-w */
	flex: 0 0 min(var(--esl-slide-w), var(--esl-max-w));
	width: min(var(--esl-slide-w), var(--esl-max-w));
	max-width: min(var(--esl-slide-w), var(--esl-max-w));
	height: auto;
	margin: 0;
	transform: none;
	opacity: 1;
	visibility: visible;
}

.esl-skeleton.is-loading .swiper-slide > .e-con,
.esl-skeleton.is-loading .swiper-slide > .e-con-boxed,
.esl-skeleton.is-loading .swiper-slide > .e-con-boxed > .e-con-inner {
	width: 100%;
	max-width: 100%;
	margin: 0;
	padding: 0;
}

/* --------------------------------------------------------
   2b. Reserva de espaço para Loop Grid (sem Swiper)
   O grid usa CSS Grid nativo, com a mesma variável --esl-cols.
   -------------------------------------------------------- */

.esl-skeleton.is-loading .elementor-loop-container:not(.swiper) {
	display: grid;
	grid-template-columns: repeat(var(--esl-cols), 1fr);
	gap: var(--esl-gap);
}

.esl-skeleton.is-loading .elementor-loop-container:not(.swiper) > .e-loop-item {
	min-width: 0;
	/* Aplica largura máxima também nos itens de grid */
	max-width: var(--esl-max-w);
}

.esl-skeleton.is-loading .elementor-loop-container:not(.swiper) > .e-loop-item > .e-con,
.esl-skeleton.is-loading .elementor-loop-container:not(.swiper) > .e-loop-item > .e-con-boxed,
.esl-skeleton.is-loading .elementor-loop-container:not(.swiper) > .e-loop-item > .e-con-boxed > .e-con-inner {
	width: 100%;
	max-width: 100%;
	margin: 0;
	padding: 0;
}

/* --------------------------------------------------------
   3. Blocos base (position + overflow + cor)
   Cada bloco só aparece se a classe correspondente foi
   adicionada pelo PHP (esl-has-image, esl-has-title, ...).
   Nota: .elementor-widget-button NÃO entra aqui — ele usa
   estratégia de overlay própria (seção Botão abaixo).
   -------------------------------------------------------- */

.esl-skeleton.is-loading .esl-block,
.esl-skeleton.is-loading.esl-has-image .elementor-widget-image,
.esl-skeleton.is-loading.esl-has-rating .elementor-widget-rating,
.esl-skeleton.is-loading.esl-has-title .elementor-widget-heading .elementor-heading-title,
.esl-skeleton.is-loading.esl-has-price .price {
	position: relative;
	overflow: hidden;
	background-color: var(--esl-bg);
	border-radius: var(--esl-radius);
	color: transparent;
}

/* Imagem ---------------------------------------------- */

/*
 * NAO forcamos width nem aspect-ratio aqui.
 *
 * O browser reserva a altura correta usando os atributos width/height
 * do <img> gerados automaticamente pelo WordPress (desde v5.5).
 * Forcar aspect-ratio causava blocos maiores que o card real porque
 * ignorava qualquer height/max-height que o Elementor ou tema aplica.
 *
 * --esl-max-h funciona como cap de emergencia (configuravel no painel).
 * min-height: 80px evita colapso total em lazy loading com placeholder 1x1.
 */
.esl-skeleton.is-loading.esl-has-image .elementor-widget-image {
	display: block;
	min-height: 80px;
	max-height: var(--esl-max-h);
}

.esl-skeleton.is-loading.esl-has-image .elementor-widget-image > a {
	display: block;
	width: 100%;
	height: 100%;
}

/* Esconde a imagem real; o espaco fica pelo intrinsic size do <img> */
.esl-skeleton.is-loading.esl-has-image .elementor-widget-image img {
	opacity: 0;
}

/* Avaliação -------------------------------------------- */

.esl-skeleton.is-loading.esl-has-rating .elementor-widget-rating {
	width: 90px;
	height: 1.125rem;
	margin-top: 0.625rem;
	border-radius: calc(var(--esl-radius) * 0.625);
}

.esl-skeleton.is-loading.esl-has-rating .e-rating {
	opacity: 0;
}

/* Título ----------------------------------------------- */

.esl-skeleton.is-loading.esl-has-title .elementor-widget-heading .elementor-heading-title {
	display: block;
	width: 82%;
	min-height: 1.25rem;
	margin: 0.75rem 0 0.375rem;
	border-radius: calc(var(--esl-radius) * 0.625);
}

.esl-skeleton.is-loading.esl-has-title .elementor-widget-heading .elementor-heading-title a {
	color: transparent;
}

/* Segunda linha do título */
.esl-skeleton.is-loading.esl-has-title .elementor-widget-heading::after {
	content: "";
	display: block;
	width: 60%;
	height: 1.125rem;
	margin-top: 0.375rem;
	background-color: var(--esl-bg);
	border-radius: calc(var(--esl-radius) * 0.625);
}

/* Preço ------------------------------------------------ */

.esl-skeleton.is-loading.esl-has-price .price {
	display: block;
	width: 45%;
	min-height: 1.25rem;
	margin-top: 0.5rem;
	border-radius: calc(var(--esl-radius) * 0.625);
}

.esl-skeleton.is-loading.esl-has-price .price * {
	color: transparent;
}

/* --------------------------------------------------------
   Botao

   Estrategia dupla para esconder a borda do tema de forma
   garantida, independente de especificidade, z-index ou
   stacking context criado pelo Elementor:

   1) visibility:hidden no elemento do botao real
      → unica propriedade CSS que oculta o elemento (incluindo
        borda) sem depender de z-index. Preserva o espaco de
        layout para nao quebrar o card.

   2) Overlay ::before/::after no widget wrapper
      → mostra o bloco cinza + shimmer no lugar do botao.
      Cobre Elementor Button (.elementor-widget-button) e
      WooCommerce Add to Cart (.elementor-widget-woocommerce-
      product-add-to-cart).
   -------------------------------------------------------- */

/*
 * Torna o botao real completamente invisivel (borda inclusa).
 * visibility:hidden nao depende de z-index — sempre funciona.
 * O espaco do botao e preservado pelo layout.
 */
.esl-skeleton.is-loading.esl-has-button .elementor-button,
.esl-skeleton.is-loading.esl-has-button a.button,
.esl-skeleton.is-loading.esl-has-button button.button {
	visibility: hidden;
}

/* Widget wrappers suportados */
.esl-skeleton.is-loading.esl-has-button .elementor-widget-button,
.esl-skeleton.is-loading.esl-has-button .elementor-widget-woocommerce-product-add-to-cart {
	position: relative;
	width: 100%;
	margin-top: 1rem;
	min-height: 2.625rem;
	overflow: hidden;
}

/* Bloco cinza sobre o botao invisivel */
.esl-skeleton.is-loading.esl-has-button .elementor-widget-button::before,
.esl-skeleton.is-loading.esl-has-button .elementor-widget-woocommerce-product-add-to-cart::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 5;
	background-color: var(--esl-bg);
	border-radius: var(--esl-radius);
	pointer-events: none;
}

/* Shimmer */
.esl-skeleton.is-loading.esl-has-button .elementor-widget-button::after,
.esl-skeleton.is-loading.esl-has-button .elementor-widget-woocommerce-product-add-to-cart::after {
	content: "";
	position: absolute;
	inset: 0 auto 0 0;
	z-index: 6;
	width: 55%;
	pointer-events: none;
	background-image: linear-gradient(
		90deg,
		rgba(255, 255, 255, 0) 0%,
		rgba(255, 255, 255, 0.30) 30%,
		rgba(255, 255, 255, 0.85) 50%,
		rgba(255, 255, 255, 0.30) 70%,
		rgba(255, 255, 255, 0) 100%
	);
	transform: translateX(-150%);
	will-change: transform;
	animation: esl-shimmer var(--esl-speed) linear infinite;
}

/* --------------------------------------------------------
   4. Brilho (shimmer) — todos os blocos exceto botão
   (o botão usa ::after próprio no widget-wrapper acima)
   -------------------------------------------------------- */

.esl-skeleton.is-loading .esl-block::after,
.esl-skeleton.is-loading.esl-has-image .elementor-widget-image::after,
.esl-skeleton.is-loading.esl-has-rating .elementor-widget-rating::after,
.esl-skeleton.is-loading.esl-has-title .elementor-heading-title::after,
.esl-skeleton.is-loading.esl-has-price .price::after {
	content: "";
	position: absolute;
	inset: 0 auto 0 0;
	z-index: 2;
	width: 55%;
	pointer-events: none;
	background-image: linear-gradient(
		90deg,
		rgba(255, 255, 255, 0) 0%,
		rgba(255, 255, 255, 0.30) 30%,
		rgba(255, 255, 255, 0.85) 50%,
		rgba(255, 255, 255, 0.30) 70%,
		rgba(255, 255, 255, 0) 100%
	);
	transform: translateX(-150%);
	will-change: transform;
	animation: esl-shimmer var(--esl-speed) linear infinite;
}

@keyframes esl-shimmer {
	from { transform: translateX(-150%); }
	to   { transform: translateX(250%); }
}

/* --------------------------------------------------------
   5. Navegação
   -------------------------------------------------------- */

.esl-skeleton.is-loading .elementor-swiper-button {
	pointer-events: none;
	opacity: 1;
}

.esl-skeleton.is-loading .swiper-pagination {
	opacity: 0;
}

/* --------------------------------------------------------
   6. Pós-carregamento
   -------------------------------------------------------- */

.esl-skeleton:not(.is-loading) .elementor-widget-image img {
	opacity: 1;
}

/* --------------------------------------------------------
   7. Acessibilidade
   -------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
	.esl-skeleton.is-loading .esl-block::after,
	.esl-skeleton.is-loading .elementor-widget-image::after,
	.esl-skeleton.is-loading .elementor-widget-rating::after,
	.esl-skeleton.is-loading .elementor-heading-title::after,
	.esl-skeleton.is-loading .price::after,
	.esl-skeleton.is-loading .elementor-widget-button::after,
	.esl-skeleton.is-loading .elementor-widget-woocommerce-product-add-to-cart::after {
		animation: none;
		opacity: 0.35;
		transform: none;
	}
}
