/*
 * Blocco "SYN – Blog" — Swiper.js, ma molto più semplice di Case Studies/
 * Testimonial: qui tutte le card hanno la STESSA larghezza (nessuna
 * "attiva" più grande), quindi nessuno dei trucchi di timing su
 * slideTo() serve — vedi blog.js. Su desktop le 4 card riempiono la riga
 * (slidesPerView:4, touch disattivato): le frecce non servono e spariscono.
 */

.syn-blog__header {
	padding-inline: var(--syn-gutter);
	margin-bottom: var(--wp--preset--spacing--xl);
}

.syn-blog__row {
	/* Il gutter vive QUI, non su .syn-blog__swiper: Swiper misura la
	 * larghezza del proprio elemento (clientWidth, che include il
	 * padding) per calcolare slidesPerView — con il padding sullo stesso
	 * elemento, le 4 card su desktop finivano calcolate su una larghezza
	 * più ampia di quella realmente visibile e la quarta restava tagliata
	 * fuori. Un wrapper esterno col padding, e lo swiper via senza, dà a
	 * Swiper la larghezza vera dell'area visibile. */
	padding-inline: var(--syn-gutter);
}

.syn-blog__swiper {
	overflow: hidden;
}

.syn-blog__card {
	box-sizing: border-box;
}

/* Swiper ora parte in lazy (blog.js, all'ingresso nel viewport): finché
 * non è inizializzato, le card devono avere GIÀ la larghezza e lo spazio
 * che Swiper darà loro, altrimenti all'init si spostano (CLS). Formula di
 * Swiper: (larghezza − (slidesPerView − 1) × spaceBetween) / slidesPerView,
 * con spaceBetween come margine destro — stessi valori dei breakpoint di
 * blog.js, da tenere allineati. */
.syn-blog__swiper:not(.swiper-initialized) .syn-blog__card {
	width: calc((100% - 0.15 * 16px) / 1.15);
	margin-right: 16px;
}

@media (min-width: 768px) { /* bp: tablet — vedi _breakpoints.scss del tema */
	.syn-blog__swiper:not(.swiper-initialized) .syn-blog__card {
		width: calc((100% - 1.2 * 20px) / 2.2);
		margin-right: 20px;
	}
}

@media (min-width: 1024px) { /* bp: desktop */
	.syn-blog__swiper:not(.swiper-initialized) .syn-blog__card {
		width: calc((100% - 3 * 24px) / 4);
		margin-right: 24px;
	}
}

/* Unico link della card: avvolge immagine, titolo, divisore e data. */
.syn-blog__link {
	display: flex;
	flex-direction: column;
	color: inherit;
	text-decoration: none;
}

/* Il colore :hover globale dei link (theme.json → grigio taupe) ha la
 * stessa specificità di .syn-blog__link e arriva dopo: senza questa
 * regola titolo e data diventerebbero grigi al passaggio del mouse. */
.syn-blog__link:hover {
	color: inherit;
}

.syn-blog__link:focus-visible {
	/* Il contorno nativo verrebbe tagliato dall'overflow:hidden dello
	 * swiper: il focus è segnalato dall'overlay (che compare anche col
	 * focus, vedi :focus-within e blog.js) + titolo sottolineato. */
	outline: none;
}

.syn-blog__link:focus-visible .syn-blog__title {
	text-decoration: underline;
	text-underline-offset: 0.15em;
}

.syn-blog__media {
	position: relative;
	display: block;
	border-radius: var(--syn-radius-sm);
	overflow: hidden;
	/* Nuovo contesto di stacking per questo box: l'immagine, il tag e
	 * l'overlay si impilano SOLO fra loro (per ordine nel DOM, l'overlay
	 * è l'ultimo quindi sopra a entrambi), senza dipendere da come
	 * .syn-blog__card (uno swiper-slide, che Swiper posiziona con un suo
	 * transform inline) si impila rispetto al resto della pagina. */
	isolation: isolate;
}

.syn-blog__image {
	display: block;
	width: 100%;
	aspect-ratio: 3 / 4;
	object-fit: cover;
}

.syn-blog__image--placeholder {
	display: flex;
	align-items: center;
	justify-content: center;
	background-color: var(--wp--preset--color--grey-light);
	color: var(--wp--preset--color--grey-taupe);
	font-size: 32px;
}

/* Tag categoria — valori esatti da design (fallback #DCEAFF perché
 * --color-bg-subtle non è ancora un token definito in theme.json; se/
 * quando lo diventa, questo lo eredita automaticamente). Stesso discorso
 * per il colore testo #2D8BFF: è il blu di Figma scartato altrove nel
 * progetto per contrasto insufficiente su sfondo bianco (vedi
 * Testimonial, __name usa accent-blue invece) — qui lo sfondo è
 * #DCEAFF, non bianco, quindi la soglia AA potrebbe essere diversa; da
 * verificare con uno strumento di contrasto reale prima di considerarlo
 * a norma. Nessun token "xs" nella scala font-size del tema (la più
 * piccola è "small", 13px): usato quello come approssimazione più
 * vicina alla richiesta. */
.syn-blog__tag {
	position: absolute;
	top: var(--wp--preset--spacing--xs);
	right: var(--wp--preset--spacing--xs);
	display: inline-flex;
	align-items: center;
	height: 26px;
	padding-inline: var(--wp--preset--spacing--xs);
	border-radius: var(--syn-radius-pill);
	background-color: var(--color-bg-subtle, #DCEAFF);
	border: 1px solid #FFFFFF1A;
	color: #2D8BFF;
	font-size: var(--wp--preset--font-size--small);
	line-height: 1;
	white-space: nowrap;
}

/* Overlay scuro al passaggio del mouse/focus, solo sopra l'immagine (il
 * titolo/data sotto restano sempre visibili, invariati).
 *
 * Fallback (touch, prefers-reduced-motion, JS non ancora partito):
 * l'overlay appare di colpo via :hover/:focus-within (regole qui sotto).
 * Su device con mouse blog.js aggiunge .is-flair-ready al blocco e lo
 * sfondo scuro lo disegna invece .syn-blog__flair — stesso effetto di
 * .syn-button__flair del tema (cerchio che nasce dal punto d'ingresso del
 * cursore, lo segue e si ritira verso il punto d'uscita), ma senza GSAP:
 * vedi perf-fix-spec.md §3, i blocchi del plugin non importano GSAP. */
.syn-blog__overlay {
	position: absolute;
	inset: 0;
	z-index: 1; /* esplicito, non lasciato al solo ordine nel DOM — sopra a immagine e tag */
	display: flex;
	align-items: center; /* testo verticalmente centrato nel box, non ancorato in basso — vedi screenshot */
	padding: var(--wp--preset--spacing--lg);
	background-color: #292929;
	opacity: 0;
}

.syn-blog__card:hover .syn-blog__overlay,
.syn-blog__card:focus-within .syn-blog__overlay {
	opacity: 1;
}

.syn-blog.is-flair-ready .syn-blog__overlay {
	background-color: transparent;
	opacity: 1;
}

/* Stessa meccanica di .syn-button__flair (_button.scss del tema): il
 * box copre l'immagine, viene spostato (translate in % della sua stessa
 * dimensione, come xPercent/yPercent di GSAP) in modo che il suo angolo in
 * alto a sinistra (= centro del cerchio, vedi ::before) cada sotto al
 * cursore, e scala da 0 a 1 attorno a quel punto.
 *
 * translate e scale come proprietà SEPARATE (non dentro `transform`): così
 * hanno transizioni indipendenti — il cerchio segue il cursore in 0.4s
 * mentre cresce in 0.8s, come nella versione GSAP. La posizione arriva da
 * blog.js tramite --flair-x/--flair-y (0–100). */
.syn-blog__flair {
	position: absolute;
	inset: 0;
	pointer-events: none;
	translate: calc(var(--flair-x, 50) * 1%) calc(var(--flair-y, 50) * 1%);
	scale: 0;
	transform-origin: 0 0;
	will-change: translate, scale;
	/* uscita: il cerchio si ritira (scale) mentre viene spinto oltre il bordo */
	transition:
		translate 0.5s cubic-bezier(0.215, 0.61, 0.355, 1),
		scale 0.5s cubic-bezier(0.215, 0.61, 0.355, 1); /* ≈ power2.out */
}

.is-flair-on .syn-blog__flair {
	scale: 1;
	transition:
		translate 0.4s cubic-bezier(0.215, 0.61, 0.355, 1),
		scale 0.8s cubic-bezier(0.215, 0.61, 0.355, 1);
}

/* All'ingresso il cerchio deve nascere ESATTAMENTE sotto al cursore, non
 * scivolare dalla posizione d'uscita precedente: blog.js mette questa
 * classe per un frame mentre aggiorna la posizione. */
.is-flair-jump .syn-blog__flair {
	transition: none;
}

/* Excerpt nascosto finché il flair non è attivo (solo device con mouse). */
.is-flair-ready .syn-blog__excerpt {
	opacity: 0;
	transition: opacity 0.2s ease-out;
}

.is-flair-ready .is-flair-on .syn-blog__excerpt {
	opacity: 1;
	transition: opacity 0.4s ease-out 0.15s;
}

.syn-blog__flair::before {
	content: '';
	position: absolute;
	top: 0;
	left: 0;
	/* Il cerchio deve coprire tutta l'immagine anche se il cursore entra da
	 * un angolo: raggio ≥ diagonale. Con proporzione 3:4 la diagonale vale
	 * ~1,67× la larghezza → diametro ~3,34× — da qui il 340% (il bottone
	 * usa 170% perché è una pillola molto più bassa che larga). */
	width: 340%;
	aspect-ratio: 1 / 1;
	border-radius: 50%;
	background-color: #292929;
	transform: translate(-50%, -50%);
}

.syn-blog__excerpt {
	position: relative; /* sopra al cerchio, che è il primo figlio dell'overlay */
	color: var(--wp--preset--color--white);
	font-size: var(--wp--preset--font-size--medium);
	display: -webkit-box;
	-webkit-line-clamp: 7;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

.syn-blog__title {
	margin: var(--wp--preset--spacing--md) 0 0 0;
}

/* span, non <hr>: dentro al link un <hr> verrebbe annunciato come
 * "separatore" dagli screen reader. */
.syn-blog__divider {
	display: block;
	border-top: 1px solid rgba(0, 0, 0, .1);
	margin: var(--wp--preset--spacing--sm) 0;
}

.syn-blog__date {
	display: block;
	color: var(--wp--preset--color--grey-taupe);
	font-size: var(--wp--preset--font-size--small);
}

.syn-blog__empty-notice {
	opacity: .6;
	font-style: italic;
	padding-inline: var(--syn-gutter);
}

/* Stesso componente/posizione di .syn-testimonial__controls — frecce
 * sotto la riga, allineate a destra. Nascoste su desktop: con le 4 card
 * già tutte visibili (slidesPerView:4 in blog.js) non c'è nulla da
 * scorrere. */
.syn-blog__controls {
	display: flex;
	gap: var(--wp--preset--spacing--xs);
	justify-content: flex-end;
	padding-inline: var(--syn-gutter);
	margin-top: var(--wp--preset--spacing--lg);
}

@media (min-width: 1024px) { /* bp: desktop — vedi _breakpoints.scss del tema */
	.syn-blog__controls {
		display: none;
	}
}
