/**
 * Widget Related Posts.
 *
 * Só carrega nas páginas que usam o widget, via get_style_depends().
 * Nada aqui assume grid, container ou variável do tema — tudo é escopado
 * em .brz-related, e toda custom property nasce na raiz do próprio widget.
 *
 * O cartão é CSS puro, inclusive o hover: o zoom da imagem e a seta que
 * gira não dependem de script nenhum. O JS do widget cuida só do modo
 * carrossel, que vem na fase seguinte.
 */

.brz-related {
	--brz-related-columns: 3;
	--brz-related-gap: 2.5rem;
	--brz-related-pad-block: 0;

	--brz-related-ratio: 4 / 3;
	--brz-related-fit: cover;
	--brz-related-position: center;
	--brz-related-radius: 0;
	--brz-related-zoom: 1.1;
	--brz-related-duration: 0.5s;
	--brz-related-ease: cubic-bezier( 0.22, 1, 0.36, 1 );

	--brz-related-header-gap: 0.75rem;
	--brz-related-header-space: 3.5rem;
	--brz-related-subtitle-color: rgba( 0, 0, 0, 0.6 );
	--brz-related-subtitle-color: color-mix( in srgb, currentColor 65%, transparent );
	--brz-related-title-size: clamp( 1.75rem, 1.1rem + 2.2vw, 3rem );
	--brz-related-title-color: inherit;

	--brz-related-card-title-size: clamp( 1.25rem, 0.9rem + 1.1vw, 2.25rem );
	--brz-related-card-title-color: inherit;
	--brz-related-card-gap: 1.5rem;

	--brz-related-meta-color: rgba( 0, 0, 0, 0.6 );
	--brz-related-meta-color: color-mix( in srgb, currentColor 65%, transparent );
	--brz-related-meta-size: 0.9375rem;

	--brz-related-arrow-size: 1.5625rem;
	--brz-related-arrow-color: currentColor;
	--brz-related-arrow-border: 2px;
	--brz-related-arrow-rotate: 60deg;
	--brz-related-arrow-hover-bg: currentColor;
	--brz-related-arrow-hover-color: #fff;

	--brz-related-nav-size: 3rem;
	--brz-related-nav-color: currentColor;
	--brz-related-nav-border: 1px;
	--brz-related-dot-size: 0.5rem;
	--brz-related-controls-space: 2.5rem;

	display: block;
	width: 100%;
}

.brz-related__inner {
	padding-block: var( --brz-related-pad-block );
}

/* Cabeçalho
   --------- */

.brz-related__header {
	display: flex;
	flex-direction: column;
	gap: var( --brz-related-header-gap );
	margin-block-end: var( --brz-related-header-space );
}

.brz-related__subtitle {
	color: var( --brz-related-subtitle-color );
	font-size: 0.9375rem;
	letter-spacing: 0.08em;
	text-transform: uppercase;
}

.brz-related__title {
	color: var( --brz-related-title-color );
	font-size: var( --brz-related-title-size );
	font-weight: 400;
	line-height: 1.1;
	margin: 0;
}

/* Grade
   ----- */

.brz-related__list {
	display: grid;
	gap: var( --brz-related-gap );
	grid-template-columns: repeat( var( --brz-related-columns ), minmax( 0, 1fr ) );
	list-style: none;
	margin: 0;
	padding: 0;
}

.brz-related__item {
	min-width: 0;
}

/* Cartão
   ------ */

.brz-related__card {
	display: flex;
	flex-direction: column;
	gap: var( --brz-related-card-gap );
	height: 100%;
}

/* A raiz no seletor é defesa, não estilo: o CSS de carrossel do Elementor
   tem uma regra sem escopo, .swiper-slide a { display: inline }, que com
   um elemento a mais passava à frente de .brz-related__thumb sozinho. No
   modo Swiper o item é .swiper-slide, e a moldura inline perdia o
   aspect-ratio, o raio e o corte do zoom. */

.brz-related .brz-related__thumb {
	/* Em 'auto' a moldura não impõe altura, e a imagem entra no tamanho
	   dela — é o que "The image ratio" quer dizer no controle. */
	aspect-ratio: var( --brz-related-ratio );
	border-radius: var( --brz-related-radius );
	display: block;
	overflow: hidden;
}

.brz-related__thumb img {
	display: block;
	height: 100%;
	object-fit: var( --brz-related-fit );
	object-position: var( --brz-related-position );
	transition: transform var( --brz-related-duration ) var( --brz-related-ease );
	width: 100%;
}

.brz-related__card:hover .brz-related__thumb img {
	transform: scale( var( --brz-related-zoom ) );
}

.brz-related__card-title {
	font-size: var( --brz-related-card-title-size );
	font-weight: 310;
	line-height: 1.1;
	margin: 0;
}

/* O :hover repete a cor porque a:hover do tema empata em especificidade
   com esta regra, e aí vence quem carrega por último. */

.brz-related__card-title a,
.brz-related__card-title a:hover {
	color: var( --brz-related-card-title-color );
	text-decoration: none;
}

/* Seta
   ----

   Fica dentro do título, no fluxo do texto: assim ela acompanha a última
   palavra em vez de cair sozinha numa linha quando o título quebra. */

.brz-related__arrow {
	align-items: center;
	border: var( --brz-related-arrow-border ) solid var( --brz-related-arrow-color );
	border-radius: 50%;
	display: inline-flex;
	height: var( --brz-related-arrow-size );
	justify-content: center;
	margin-inline-start: 0.3em;
	transform: translateY( -0.05em );
	transition:
		background-color var( --brz-related-duration ) var( --brz-related-ease ),
		border-color var( --brz-related-duration ) var( --brz-related-ease );
	width: var( --brz-related-arrow-size );
}

.brz-related__arrow svg {
	height: 45%;
	transition: transform var( --brz-related-duration ) var( --brz-related-ease );
	width: 45%;
}

.brz-related__arrow svg path {
	fill: var( --brz-related-arrow-color );
	transition: fill var( --brz-related-duration ) var( --brz-related-ease );
}

.brz-related__card:hover .brz-related__arrow,
.brz-related__card:focus-within .brz-related__arrow {
	background-color: var( --brz-related-arrow-hover-bg );
}

.brz-related__card:hover .brz-related__arrow svg,
.brz-related__card:focus-within .brz-related__arrow svg {
	transform: rotate( var( --brz-related-arrow-rotate ) );
}

.brz-related__card:hover .brz-related__arrow svg path,
.brz-related__card:focus-within .brz-related__arrow svg path {
	fill: var( --brz-related-arrow-hover-color );
}

/* Meta
   ----

   O separador é pseudo-elemento e não caractere no markup: assim ele some
   sozinho no primeiro item, seja qual for a combinação de autor, termo e
   data que o cliente deixou ligada. */

.brz-related__meta {
	color: var( --brz-related-meta-color );
	display: flex;
	flex-wrap: wrap;
	font-size: var( --brz-related-meta-size );
	gap: 0.75rem;
	line-height: 1.4;
}

.brz-related__meta > * + *::before {
	content: "";
	display: inline-block;
	height: 1em;
	margin-inline-end: 0.75rem;
	transform: translateY( 0.15em );
	vertical-align: baseline;
	width: 1px;
	background-color: currentColor;
	opacity: 0.4;
}

/* Carrossel
   ---------

   O trilho é scroll-snap puro: rola por arrasto, por roda e por teclado
   sem uma linha de script, porque é o que um elemento com overflow faz
   nativamente. O JS entra só para acrescentar botões e pontos — ou para
   ceder o lugar ao Swiper, quando a página já tem um.

   As colunas viram largura de item: é a mesma conta do grid, só que agora
   o item precisa saber o próprio tamanho para poder encostar na borda. */

.brz-related--carousel .brz-related__list {
	grid-auto-columns: calc(
		( 100% - ( var( --brz-related-columns ) - 1 ) * var( --brz-related-gap ) ) / var( --brz-related-columns )
	);
	grid-auto-flow: column;
	grid-template-columns: none;
	overflow-x: auto;
	overscroll-behavior-x: contain;
	padding-bottom: 1px;
	scroll-snap-type: x mandatory;
	scrollbar-width: none;
}

.brz-related--carousel .brz-related__list::-webkit-scrollbar {
	display: none;
}

.brz-related--carousel .brz-related__item {
	scroll-snap-align: start;
}

/* Com o Swiper no comando, quem posiciona é ele: o trilho volta a ser um
   bloco comum e o item recebe a largura de coluna direto, porque a
   biblioteca troca o grid por flex.

   O espaço entre cartões sai do gap e vai para o spaceBetween do Swiper,
   que o JS lê da mesma variável. Com os dois ao mesmo tempo o Swiper, que
   calcula o deslocamento só pela largura dos slides e pelo spaceBetween,
   ficaria um gap atrasado a cada avanço.

   O overflow do viewport também é nosso, e não do CSS da biblioteca: o
   corte do trilho não pode depender de a folha do Swiper estar na página.

   O seletor do trilho leva o viewport como pai de propósito. O CSS do
   Nested Carousel do Elementor Pro tem regras sem escopo que põem
   overflow hidden e um gap próprio em .swiper > .swiper-wrapper antes da
   inicialização — com três classes, a mesma especificidade que este
   seletor teria sem o pai. Empatado, vence quem carrega por último, e no
   editor, que carrega a folha de todos os widgets, a do Elementor vinha
   depois: o trilho deslocado pelo translate ficava cortado e o widget, em
   branco. Com o pai a especificidade sobe e a ordem deixa de importar. */

.brz-related.is-brz-swiper .brz-related__viewport {
	overflow: hidden;
	position: relative;
}

.brz-related.is-brz-swiper .brz-related__viewport > .brz-related__list {
	display: flex;
	gap: 0;
	overflow: visible;
	scroll-snap-type: none;
}

/* O overflow, o transition e o will-change desfazem a regra sem escopo
   .swiper-slide do CSS de carrossel do Elementor, que cortaria o contorno
   de foco do cartão e animaria o item por conta própria. A entrada do
   item é animation, não transition, então zerar aqui não a afeta. */

.brz-related.is-brz-swiper .brz-related__item {
	flex: 0 0 auto;
	overflow: visible;
	transition: none;
	will-change: auto;
	width: calc(
		( 100% - ( var( --brz-related-columns ) - 1 ) * var( --brz-related-gap ) ) / var( --brz-related-columns )
	);
}

/* Controles
   ---------

   Nascem com o atributo hidden no PHP; é o JS que os revela. Botão que não
   faz nada é pior que botão nenhum. */

.brz-related__controls {
	align-items: center;
	display: flex;
	gap: 1rem;
	margin-block-start: var( --brz-related-controls-space );
}

/* O display: flex acima é regra de autor e passa à frente do [hidden] do
   navegador; sem isto as setas apareceriam mortas quando o JS não roda ou
   desiste (um post só). */

.brz-related__controls[hidden] {
	display: none;
}

.brz-related__arrow-btn {
	align-items: center;
	background: none;
	border: var( --brz-related-nav-border ) solid var( --brz-related-nav-color );
	border-radius: 50%;
	color: var( --brz-related-nav-color );
	cursor: pointer;
	display: inline-flex;
	height: var( --brz-related-nav-size );
	justify-content: center;
	padding: 0;
	transition: opacity var( --brz-related-duration ) var( --brz-related-ease );
	width: var( --brz-related-nav-size );
}

.brz-related__arrow-btn:hover {
	opacity: 0.6;
}

/* A ponta da seta é feita de borda: dois lados de um quadrado girado. Sem
   SVG, sem fonte de ícone, e acompanha a cor do botão sozinha. */
.brz-related__arrow-btn::before {
	border-right: 2px solid currentColor;
	border-top: 2px solid currentColor;
	content: "";
	height: 0.5rem;
	width: 0.5rem;
}

.brz-related__arrow-btn--prev::before {
	transform: rotate( -135deg ) translate( -0.1rem, -0.1rem );
}

.brz-related__arrow-btn--next::before {
	transform: rotate( 45deg ) translate( -0.1rem, -0.1rem );
}

.brz-related__dots {
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem;
	margin-inline-start: auto;
}

.brz-related__dot {
	background-color: currentColor;
	border: 0;
	border-radius: 50%;
	cursor: pointer;
	height: var( --brz-related-dot-size );
	opacity: 0.3;
	padding: 0;
	transition: opacity var( --brz-related-duration ) var( --brz-related-ease );
	width: var( --brz-related-dot-size );
}

.brz-related__dot.is-brz-active {
	opacity: 1;
}

/* Rótulo que só o leitor de tela lê. O recorte de 1px, e não display:none,
   é o que mantém o texto anunciável. */

.brz-related__sr {
	border: 0;
	clip-path: inset( 50% );
	height: 1px;
	margin: -1px;
	overflow: hidden;
	padding: 0;
	position: absolute;
	white-space: nowrap;
	width: 1px;
}

/* Estado vazio, só no editor
   ------------------------- */

.brz-related__empty {
	border: 1px dashed currentColor;
	border-radius: 0.5rem;
	margin: 0;
	opacity: 0.6;
	padding: 2rem;
	text-align: center;
}

/* Animação de entrada
   ------------------

   As classes is-brz-animated e is-brz-visible são adicionadas pelo
   brz-reveal.js, nunca pelo PHP: sem JS o conteúdo simplesmente nasce
   visível, e nenhuma falha de script consegue deixar a faixa em branco. */

.brz-related.is-brz-animated .brz-related__reveal {
	opacity: 0;
	transform: translate3d( 0, 1rem, 0 );
}

.brz-related.is-brz-animated.is-brz-visible .brz-related__reveal {
	animation: brz-related-reveal 0.5s var( --brz-related-ease ) forwards;

	/* O índice vem inline do PHP e escalona a entrada cartão a cartão. O
	   teto impede que uma faixa longa deixe os últimos esperando depois de
	   já estarem na tela. */
	animation-delay: min( calc( var( --brz-related-index, 0 ) * 0.08s ), 0.6s );
}

@keyframes brz-related-reveal {

	to {
		opacity: 1;
		transform: translate3d( 0, 0, 0 );
	}
}

/* Movimento reduzido
   ----------------- */

@media ( prefers-reduced-motion: reduce ) {

	.brz-related__thumb img,
	.brz-related__arrow,
	.brz-related__arrow svg,
	.brz-related__arrow svg path {
		transition: none;
	}

	.brz-related__card:hover .brz-related__thumb img {
		transform: none;
	}

	.brz-related__card:hover .brz-related__arrow svg,
	.brz-related__card:focus-within .brz-related__arrow svg {
		transform: none;
	}

	.brz-related.is-brz-animated .brz-related__reveal,
	.brz-related.is-brz-animated.is-brz-visible .brz-related__reveal {
		animation: none;
		opacity: 1;
		transform: none;
	}

	/* O trilho continua rolando; o que sai é o deslize suave. O JS já pede
	   scroll instantâneo, e isto cobre o arrasto do próprio navegador. */
	.brz-related--carousel .brz-related__list {
		scroll-behavior: auto;
	}
}
