/*
 * Vik Base — theme.css
 * Stili non esprimibili tramite theme.json: layout dei pattern, componenti
 * custom (card, carosello, griglie), accessibilità e sistema animazioni.
 * Tutti i valori passano da custom property / preset di theme.json.
 */

:root {
	/* Default neutri del parent: skin-terra (e ogni altro child) li
	   sovrascrive nel proprio assets/css/theme.css con i valori di design
	   effettivi (border-radius quasi-zero, sfondo scuro caldo, overlay
	   caldo) — vedi skin-terra/assets/css/theme.css. */
	--vik-radius: 0px;
	--newsletter-bg: var(--wp--preset--color--dark);
	--vik-overlay-dark: rgba(0, 0, 0, 0.55);
	--vik-paybar-bg: var(--wp--preset--color--dark);
	/*
	 * Default = lo stesso avorio caldo hardcoded 4 volte nel resto di questo
	 * file (hero title em, room-overlay-category, packages eyebrow, footer
	 * tagline — tutti testo piccolo/corsivo su sfondo scuro): il default qui
	 * è intenzionalmente lo STESSO valore, così nessuna skin che non lo
	 * ridefinisce (skin-terra, per cui questo valore era stato pensato in
	 * origine — vedi CLAUDE.md) cambia resa. Solo skin-marea lo ridefinisce
	 * col proprio tocco (skin-marea/assets/css/theme.css).
	 */
	--vik-overlay-ivory: #e9c9ae;

	/* Sistema di spaziatura verticale sezioni: valori unici invece di preset
	   scelti caso per caso in ogni pattern. Scala "standard" per le sezioni
	   di contenuto piene, "compact" per fasce sottili come trust-bar. Vedi
	   la regola ".entry-content.wp-block-post-content > *" più sotto nel
	   file per il motivo per cui va sempre accompagnata dall'azzeramento
	   del margin-block-start automatico di WordPress tra le sezioni. */
	--vik-section-space-y: var(--wp--preset--spacing--10);
	--vik-section-space-y-tablet: var(--wp--preset--spacing--8);
	--vik-section-space-y-mobile: var(--wp--preset--spacing--7);

	--vik-section-space-y-compact: var(--wp--preset--spacing--6);
	--vik-section-space-y-compact-tablet: var(--wp--preset--spacing--5);
	--vik-section-space-y-compact-mobile: var(--wp--preset--spacing--4);

	/* Gap card griglia standard (camere, pacchetti/offerte) */
	--vik-grid-gap: var(--wp--preset--spacing--6);

	/* Animazioni in entrata: durata/easing unici in tutto il sito */
	--vik-anim-duration: 350ms;
	--vik-anim-ease: ease-out;

	/* Interlinea del testo corrente (paragrafi ed elenchi), vedi la regola
	   "Interlinea del testo" più sotto. */
	--vik-text-line-height: 1.7;
	/* Interlinea dei titoli grandi che possono andare a capo (titolo
	   dell'Header di pagina). */
	--vik-heading-line-height: 1.3;
}

/* -----------------------------------------------------------
   Root padding awareness — responsive
   theme.json imposta solo il valore desktop (spacing--8, 64px) per
   "styles.spacing.padding.left/right", perché theme.json non supporta
   media query: WordPress traduce quel valore in
   "body { --wp--style--root--padding-right: var(--wp--preset--spacing--8);
   ... }" dentro global-styles-inline-css, dichiarato direttamente
   sull'elemento "body" (non su ":root"). Per questo la ridefinizione
   responsiva va ripetuta qui anch'essa su "body", non su ":root": una
   custom property dichiarata esplicitamente su un elemento non eredita
   più da ":root" per quell'elemento, quindi un ":root { --var: ... }"
   qui non avrebbe alcun effetto sul valore che "body" (e i suoi
   discendenti) vedono. Stessa identica scala responsiva 64/32/20px
   (spacing--8/6/5) già in uso per il padding orizzontale di pagina
   altrove (".page-header--left", "location-split__content", ecc.) —
   non una scala nuova. Stessa specificità (0,0,1) di "body" nel CSS
   iniettato da WordPress: vince per ordine di sorgente, essendo
   theme.css accodato dopo global styles in functions.php.
   ----------------------------------------------------------- */
@media (max-width: 1023px) {
	body {
		--wp--style--root--padding-left: var(--wp--preset--spacing--6);
		--wp--style--root--padding-right: var(--wp--preset--spacing--6);
	}
}

@media (max-width: 767px) {
	body {
		--wp--style--root--padding-left: var(--wp--preset--spacing--5);
		--wp--style--root--padding-right: var(--wp--preset--spacing--5);
	}
}

/* -----------------------------------------------------------
   Interlinea del testo (2026-10-07)
   Nessun theme.json imposta un'interlinea: paragrafi ed elenchi restavano
   a "normal" del browser (circa 1,2 con Inter), stretta per testi lunghi.
   Non in theme.json (styles.blocks.core/paragraph): lì il selettore del
   blocco è "p", e colpirebbe anche le etichette dei componenti stampate
   come <p> (titolo del sito, eyebrow, numeri di Chi siamo, prezzi, footer).
   Qui solo il testo scritto come tale: paragrafi senza una classe di
   componente (eyebrow, o una classe "blocco__elemento" dei pattern) ed
   elenchi del blocco Lista. :where() = specificità zero, quindi qualunque
   line-height già dichiarato da un componente continua a valere.
   ----------------------------------------------------------- */
:where(.wp-block-paragraph:not(.eyebrow):not([class*="__"])),
:where(.wp-block-list) {
	line-height: var(--vik-text-line-height);
}

/* Componenti compatti con paragrafi senza classe propria (righe della
   trust bar, didascalie dei numeri di Chi siamo, header e footer):
   restano all'interlinea di prima. */
:where(.site-header, .site-footer, .trust-bar, .about-story__stat) :where(.wp-block-paragraph) {
	line-height: normal;
}

/* -----------------------------------------------------------
   Link senza sottolineatura, a livello globale
   VikBooking carica Bootstrap 3 (vikbooking/site/resources/bootstrap.min.css)
   che dichiara "a:hover, a:focus { text-decoration: underline }" e
   ".btn-link:hover, .btn-link:focus { ... underline }" su tutto il sito.
   "body a:hover" (0,1,2) e "body .btn-link:hover" (0,2,1) superano le
   regole Bootstrap (0,1,1)/(0,2,0) a prescindere dall'ordine di caricamento.
   I componenti che vogliono esplicitamente la sottolineatura la dichiarano
   con selettori di classe + :hover (specificità ≥ 0,2,0), che continuano
   a vincere. Il caso a riposo è coperto anche da theme.json
   (styles.elements.link.typography.textDecoration).
   ----------------------------------------------------------- */
body a,
body a:hover,
body a:focus,
body .btn-link:hover,
body .btn-link:focus {
	text-decoration: none;
}

/* -----------------------------------------------------------
   Accessibilità
   ----------------------------------------------------------- */
.screen-reader-text {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	white-space: nowrap;
	clip: rect(0, 0, 0, 0);
	border: 0;
}

.skip-link.screen-reader-text:focus {
	position: fixed;
	top: var(--wp--preset--spacing--3);
	left: var(--wp--preset--spacing--3);
	z-index: 100000;
	width: auto;
	height: auto;
	padding: var(--wp--preset--spacing--3) var(--wp--preset--spacing--4);
	clip: auto;
	background-color: var(--wp--preset--color--accent);
	color: var(--wp--preset--color--white);
	text-decoration: none;
	border-radius: var(--vik-radius);
}

:focus-visible {
	outline: 2px solid var(--wp--preset--color--accent);
	outline-offset: 2px;
}

/* -----------------------------------------------------------
   Breakout a tutta larghezza — esplicito e non dipendente dal solo
   CSS automatico generato da WordPress per i layout "constrained",
   che con alcuni annidamenti (es. dentro wp-block-post-content) può
   non applicarsi visivamente.
   ----------------------------------------------------------- */
.alignfull {
	width: auto;
	max-width: none;
	margin-left: calc(50% - 50vw);
	margin-right: calc(50% - 50vw);
}

/* Da quando "useRootPaddingAwareAlignments" è attivo in theme.json (vedi
   sotto per il motivo), WordPress stesso inietta ".has-global-padding >
   .alignfull { margin-left/right: calc(var(--wp--style--root--padding-*) *
   -1) }" in global-styles-inline-css — stessa identica specificità (due
   classi) della regola ".alignfull" qui sopra, quindi vincerebbe lei
   sull'ultima dichiarata, azzerando il vero breakout a piena viewport e
   restringendo ogni sezione full-bleed (hero-search, trust-bar,
   rooms-carousel, amenities-grid-section, experiences-carousel,
   cta-banner, newsletter-placeholder, location-split, packages-featured,
   ecc.) alla sola larghezza del padding di root. Ripetuta qui, DOPO
   global-styles-inline-css nel <head> (vik-base-theme è messo in coda a
   vik-base-style/global styles in functions.php), la stessa identica
   specificità vince per ordine di sorgente — nessun bisogno di
   !important, stesso schema già usato altrove in questo file. */
.has-global-padding > .alignfull {
	margin-left: calc(50% - 50vw);
	margin-right: calc(50% - 50vw);
}

/* -----------------------------------------------------------
   Sistema di spaziatura verticale sezioni
   Ogni sezione della pagina controlla il proprio spazio SOLO tramite
   padding-top/bottom (token qui sopra in ":root"): lo stile globale di
   WordPress ":root :where(.is-layout-constrained) > * { margin-block-start:
   24px }" applicato ai figli diretti di ".entry-content" si sommava a quel
   padding creando spazi doppi e incoerenti da una sezione all'altra.
   Azzerato qui con un selettore a due classi (0,2,0), più specifico del
   ":root" di WordPress, così vince senza "!important" — stesso schema già
   usato per "body:has(.hero-bg.is-height-full) #main" più sotto e per
   ".experiences-dark__track > .wp-block-vik-base-experience-card".
   ----------------------------------------------------------- */
.entry-content.wp-block-post-content > * {
	margin-block-start: 0;
}

/* WordPress core (wp-includes/blocks/group/theme.min.css) ships a default
   ":where(.wp-block-group.has-background) { padding: 1.25em 2.375em }" for
   ANY Group block that gets a background color — including via the
   Inspector's Color panel, not just the backgroundColor already baked into
   some of these patterns (rooms-carousel, amenities-grid-section,
   experiences-dark, ecc.). Because ":where()" has zero specificity, our own
   padding-top/bottom above already overrides the vertical half, but nothing
   here was overriding padding-left/right — so setting (or already having) a
   background color silently added ~38px of unwanted horizontal padding
   inside these full-bleed sections. Reset explicitly, unconditionally
   (not just ".has-background"), since horizontal spacing for these
   sections is always handled by an inner wrapper with its own max-width,
   never by the outer full-bleed section itself.

   ECCEZIONE — ".rooms-grid", ".rooms-carousel", ".rooms-list" e
   ".events-showcase-section" NON sono più in questo elenco. Il loro
   wrapper interno ("*__wrapper", vedi patterns/rooms-carousel.php ecc.)
   usa "layout":{"type":"constrained","contentSize":"1200px"} nativo,
   senza alcun CSS proprio per il padding orizzontale — a differenza
   degli altri qui sotto non hanno "un wrapper interno con max-width e
   padding propri", si appoggiano al tutto al meccanismo nativo di
   WordPress. Da quando "useRootPaddingAwareAlignments" è attivo (vedi
   in cima al file), quel meccanismo nativo è "has-global-padding" sulla
   sezione esterna stessa: azzerare qui il suo padding, come prima,
   toglieva l'unico padding che il wrapper interno riceve (il wrapper
   nested viene già azzerato da WordPress stesso per evitare il doppio
   padding, vedi ".has-global-padding :where(...)" iniettato in
   global-styles-inline-css) — risultato, testo a bordo vivo su mobile
   (dal vivo su "Ogni camera, la sua storia."). */
.hero-search,
.trust-bar,
.search-page-header,
.intro-text-image,
.offers-featured,
.packages-featured,
.packages-grid-section,
.amenities-grid-section,
.how-it-works,
.experiences-carousel,
.experiences-dark,
.location-split,
.cta-banner {
	padding-left: 0;
	padding-right: 0;
}

.trust-bar,
.intro-text-image,
.rooms-grid,
.rooms-carousel,
.rooms-list,
.offers-featured,
.packages-featured,
.packages-grid-section,
.amenities-grid-section,
.how-it-works,
.experiences-carousel,
.experiences-dark,
.events-showcase-section,
.cta-banner {
	padding-top: var(--vik-section-space-y);
	padding-bottom: var(--vik-section-space-y);
}

/* trust-bar e search-page-header sono fasce sottili, non sezioni di
   contenuto piene: usano la scala "compact" invece dello standard qui
   sopra. search-page-header (header contestuale della pagina "Cerca
   disponibilità") deve restare contenuto in altezza per non competere
   con il search form che segue subito sotto. */
.trust-bar,
.search-page-header {
	padding-top: var(--vik-section-space-y-compact);
	padding-bottom: var(--vik-section-space-y-compact);
}

/* Vedi il commento su ".trust-bar__item" più sotto nel file: rete di
   sicurezza contro il quirk flexbox del secondo item review che si
   allarga a piena riga. Non fa parte dell'elenco di reset
   "padding-left/right: 0" più sopra — qui il padding è voluto. */
.trust-bar {
	box-sizing: border-box;
	padding-left: var(--wp--preset--spacing--8);
	padding-right: var(--wp--preset--spacing--8);
}

@media (max-width: 1023px) {
	.trust-bar {
		padding-left: var(--wp--preset--spacing--6);
		padding-right: var(--wp--preset--spacing--6);
	}
}

@media (max-width: 767px) {
	.trust-bar {
		padding-left: var(--wp--preset--spacing--5);
		padding-right: var(--wp--preset--spacing--5);
	}
}

@media (max-width: 1023px) {
	.trust-bar,
	.intro-text-image,
	.rooms-grid,
	.rooms-carousel,
	.rooms-list,
	.offers-featured,
	.packages-featured,
	.packages-grid-section,
	.amenities-grid-section,
	.how-it-works,
	.experiences-carousel,
	.experiences-dark,
	.events-showcase-section,
	.cta-banner {
		padding-top: var(--vik-section-space-y-tablet);
		padding-bottom: var(--vik-section-space-y-tablet);
	}

	.trust-bar,
	.search-page-header {
		padding-top: var(--vik-section-space-y-compact-tablet);
		padding-bottom: var(--vik-section-space-y-compact-tablet);
	}
}

@media (max-width: 767px) {
	.trust-bar,
	.intro-text-image,
	.rooms-grid,
	.rooms-carousel,
	.rooms-list,
	.offers-featured,
	.packages-featured,
	.packages-grid-section,
	.amenities-grid-section,
	.how-it-works,
	.experiences-carousel,
	.experiences-dark,
	.events-showcase-section,
	.cta-banner {
		padding-top: var(--vik-section-space-y-mobile);
		padding-bottom: var(--vik-section-space-y-mobile);
	}

	.trust-bar,
	.search-page-header {
		padding-top: var(--vik-section-space-y-compact-mobile);
		padding-bottom: var(--vik-section-space-y-compact-mobile);
	}
}

/* -----------------------------------------------------------
   page-header — intestazione contestuale condivisa (eyebrow + H1 +
   sottotitolo su sfondo background-alt), unica sorgente di verità per
   Galleria, Offerte, Pacchetti, Chi siamo, Contatti e gli archivi
   Esperienze/Eventi (blocco dinamico vik-base/page-header, vedi
   blocks/page-header/render.php) — prima ognuna di queste pagine aveva
   la propria classe e il proprio blocco di regole quasi identico qui
   sotto (.gallery-page-header, .experiences-page-header,
   .promotions-page-header: tutte e tre rimosse, era la causa della
   deriva visiva vista pagina per pagina).

   ".search-page-header" resta un alias storico, selettori uniti ovunque
   sotto: markup scritto a mano (non passato al blocco condiviso in
   questo giro) nelle pagine legali (Privacy Policy, Cookie Policy,
   Termini e Condizioni, vedi .legal-page-content più sotto) e in "Cerca
   disponibilità" continua a usare la classe letterale "search-page-
   header" nel proprio post_content — cambiarla avrebbe richiesto
   toccare quelle pagine una per una senza un vero bisogno, dato che il
   risultato visivo è comunque identico a ".page-header--compact".

   Contenuto centrato entro la stessa larghezza usata dal resto del sito
   per i blocchi "constrained" nativi (contentSize 1200px, vedi
   theme.json) — qui replicata a mano su "> *" perché questo non è un
   core/group con layout "constrained" gratuito, è un div reso da PHP:
   non riceve mai la classe "has-global-padding" che WordPress applica
   automaticamente ai blocchi nativi (vedi "useRootPaddingAwareAlignments"
   in cima al file), quindi il padding orizzontale va dichiarato qui a
   mano, stessa scala responsiva 64/32/20px del resto del tema — senza
   non c'è alcun margine dal bordo reale della viewport su mobile
   (sottotitolo confermato dal vivo su "Chi siamo"). */
.page-header,
.search-page-header {
	box-sizing: border-box;
	padding-top: 48px;
	padding-right: var(--wp--preset--spacing--8);
	padding-bottom: 40px;
	margin-bottom: var(--wp--preset--spacing--6);
	padding-left: var(--wp--preset--spacing--8);
	text-align: center;
}

.page-header > *,
.search-page-header > * {
	max-width: var(--wp--style--global--content-size, 1200px);
	margin-left: auto;
	margin-right: auto;
}

.page-header .wp-block-heading,
.page-header .wp-block-query-title,
.search-page-header .wp-block-heading {
	margin: 0 auto var(--wp--preset--spacing--3);
	/* Interlinea (2026-10-07): era "normal" (circa 1,2), con un titolo
	   lungo che va a capo, soprattutto su mobile, le righe risultavano
	   attaccate. */
	line-height: var(--vik-heading-line-height);
}

/* Solo l'H1 dinamico degli archivi (titleSource "archive") pesava già
   600 prima del merge — invariato, non esteso alle altre varianti che
   non lo avevano (Galleria, Cerca disponibilità/pagine legali). */
.page-header .wp-block-query-title {
	font-weight: 600;
}

/* Più respiro tra il badge eyebrow e il titolo rispetto allo spacing--2
   di ".eyebrow" (usato invariato altrove nel sito): qui l'eyebrow è da
   solo sopra un H1, non appena sopra un paragrafo di testo come nelle
   altre sezioni, quindi la gerarchia titolo/badge ha bisogno di più aria. */
.page-header .eyebrow,
.page-header .is-style-eyebrow,
.search-page-header .eyebrow,
.search-page-header .is-style-eyebrow {
	margin-bottom: var(--wp--preset--spacing--4);
}

.page-header p:last-child,
.search-page-header p:last-child {
	max-width: 560px;
	margin-left: auto;
	margin-right: auto;
	margin-bottom: 0;
	color: var(--wp--preset--color--text-soft);
	/* Descrizione: stessa interlinea del testo corrente (vedi "Interlinea
	   del testo"), il paragrafo è stampato dal blocco senza la classe
	   wp-block-paragraph a cui si aggancia quella regola. */
	line-height: var(--vik-text-line-height);
}

@media (max-width: 1023px) {
	.page-header,
	.search-page-header {
		padding-top: var(--vik-section-space-y-compact-tablet);
		padding-right: var(--wp--preset--spacing--6);
		padding-bottom: var(--vik-section-space-y-compact-tablet);
		padding-left: var(--wp--preset--spacing--6);
	}
}

@media (max-width: 767px) {
	.page-header,
	.search-page-header {
		padding-top: var(--vik-section-space-y-compact-mobile);
		padding-right: var(--wp--preset--spacing--5);
		padding-bottom: var(--vik-section-space-y-compact-mobile);
		padding-left: var(--wp--preset--spacing--5);
	}
}

/* Sfondo scelto dall'utente (2026-10-06, blocks/page-header/render.php):
   colore dalla palette (default background-alt, invariato) e immagine
   opzionale con velatura scura regolabile (--page-header-overlay, 0–0.9)
   e punto focale (--page-header-position). Il colore resta sotto
   l'immagine come ripiego finché questa non è caricata. */
.page-header--has-image {
	background-image:
		linear-gradient(
			rgba(30, 30, 30, var(--page-header-overlay, 0.45)),
			rgba(30, 30, 30, var(--page-header-overlay, 0.45))
		),
		var(--page-header-image);
	background-position: center, var(--page-header-position, 50% 50%);
	background-size: cover;
	background-repeat: no-repeat;
}

/* Testo chiaro sopra un'immagine o un colore scuro della palette (stesso
   elenco di .intro-text-image-bleed__panel), salvo un colore testo
   scelto esplicitamente dall'utente (.has-text-color, gestito sotto).
   "ink" è lo slug del testo scuro nelle skin, "text" quello del parent. */
.page-header:not(.has-text-color):is(
		.page-header--has-image,
		.has-text-background-color,
		.has-ink-background-color,
		.has-text-soft-background-color,
		.has-accent-background-color,
		.has-accent-dark-background-color,
		.has-dark-background-color
	) {
	color: var(--wp--preset--color--white);
}

.page-header:not(.has-text-color):is(
		.page-header--has-image,
		.has-text-background-color,
		.has-ink-background-color,
		.has-text-soft-background-color,
		.has-accent-background-color,
		.has-accent-dark-background-color,
		.has-dark-background-color
	) .wp-block-heading {
	color: var(--wp--preset--color--white);
}

.page-header:not(.has-text-color):is(
		.page-header--has-image,
		.has-text-background-color,
		.has-ink-background-color,
		.has-text-soft-background-color,
		.has-accent-background-color,
		.has-accent-dark-background-color,
		.has-dark-background-color
	) p:last-child {
	color: rgba(255, 255, 255, 0.85);
}

/* Eyebrow: accent su scuro sarebbe illeggibile (accent su accent, o
   contrasto insufficiente su foto) — stesso avorio caldo del titolo hero. */
.page-header:not(.has-text-color):is(
		.page-header--has-image,
		.has-text-background-color,
		.has-ink-background-color,
		.has-text-soft-background-color,
		.has-accent-background-color,
		.has-accent-dark-background-color,
		.has-dark-background-color
	) .eyebrow {
	color: var(--vik-overlay-ivory);
}

/* Colore testo scelto dall'utente: vale per titolo, eyebrow e
   sottotitolo, che altrimenti hanno ciascuno un colore proprio. */
.page-header.has-text-color .wp-block-heading,
.page-header.has-text-color .eyebrow,
.page-header.has-text-color p:last-child {
	color: inherit;
}

.page-header.has-text-color p:last-child {
	opacity: 0.85;
}

/* Modificatore "compatto" (attributo "density":"compact" del blocco) —
   lascia spazio a un form/elenco subito sotto (Offerte, Pacchetti),
   stessa scala già usata da ".search-page-header" qui sopra. */
.page-header--compact {
	padding-top: var(--vik-section-space-y-compact);
	padding-bottom: var(--vik-section-space-y-compact);
}

@media (max-width: 1023px) {
	.page-header--compact {
		padding-top: var(--vik-section-space-y-compact-tablet);
		padding-bottom: var(--vik-section-space-y-compact-tablet);
	}
}

@media (max-width: 767px) {
	.page-header--compact {
		padding-top: var(--vik-section-space-y-compact-mobile);
		padding-bottom: var(--vik-section-space-y-compact-mobile);
	}
}

/* Modificatore "a sinistra" (attributo "contentAlign":"left", oggi solo
   Offerte/Pacchetti) — serve anche un padding orizzontale esplicito,
   dato che sotto i 1200px di content-size il layout non lo aggiunge da
   solo (stesso problema già documentato per ".vb-shortcode-wrap" in
   vikbooking-overrides.css). Stessa identica scala responsive di
   quel selettore (spacing--5/6/8 a 0/768/1024px) per restare allineato
   al resto della pagina. Heading con font-size esplicito perché qui
   niente hero fotografico sopra a "spingere" la gerarchia visiva come
   nella variante spaziosa/centrata. */
.page-header--left {
	text-align: left;
	padding-left: var(--wp--preset--spacing--5);
	padding-right: var(--wp--preset--spacing--5);
}

.page-header--left > * {
	margin-left: 0;
	margin-right: 0;
}

.page-header--left p:last-child {
	max-width: none;
	margin-left: 0;
	margin-right: 0;
}

@media (min-width: 768px) {
	.page-header--left {
		padding-left: var(--wp--preset--spacing--6);
		padding-right: var(--wp--preset--spacing--6);
	}
}

@media (min-width: 1024px) {
	.page-header--left {
		padding-left: var(--wp--preset--spacing--8);
		padding-right: var(--wp--preset--spacing--8);
	}
}

.page-header--left .wp-block-heading {
	font-family: var(--wp--preset--font-family--display);
	/* "--2-xl", non "--2xl": WordPress genera le custom property dei
	   fontSizes con un trattino prima di un token che inizia con cifra
	   (slug "2xl" in theme.json → variabile "--font-size--2-xl"). */
	font-size: var(--wp--preset--font-size--2-xl);
	font-weight: 500;
}

/* -----------------------------------------------------------
   legal-page — corpo delle pagine legali (Privacy Policy, Cookie
   Policy, Termini e Condizioni). Header contestuale sopra riusa
   invariata ".search-page-header"; qui solo il corpo testo, colonna
   singola più stretta della contentSize di pagina (1200px) per la
   leggibilità di testo denso. Padding orizzontale esplicito perché,
   a differenza delle altre sezioni del tema, questo blocco non ha un
   wrapper interno con max-width proprio: sui viewport sotto la
   contentSize (800px) i figli del layout "constrained" riempiono
   tutta la larghezza disponibile, quindi senza padding qui il testo
   toccherebbe i bordi dello schermo.
   ----------------------------------------------------------- */
.legal-page-content {
	padding-top: var(--vik-section-space-y);
	padding-bottom: var(--vik-section-space-y);
	padding-left: var(--wp--preset--spacing--8);
	padding-right: var(--wp--preset--spacing--8);
}

.legal-page-content h2,
.legal-page-content h3 {
	font-family: var(--wp--preset--font-family--body);
	font-weight: 600;
}

@media (max-width: 1023px) {
	.legal-page-content {
		padding-top: var(--vik-section-space-y-tablet);
		padding-bottom: var(--vik-section-space-y-tablet);
		padding-left: var(--wp--preset--spacing--6);
		padding-right: var(--wp--preset--spacing--6);
	}
}

@media (max-width: 767px) {
	.legal-page-content {
		padding-top: var(--vik-section-space-y-mobile);
		padding-bottom: var(--vik-section-space-y-mobile);
		padding-left: var(--wp--preset--spacing--5);
		padding-right: var(--wp--preset--spacing--5);
	}
}

/* Callout "contenuto di esempio" — stesso linguaggio visivo della nota
   informativa già usata per i disclaimer nativi di VikBooking (vedi
   ".vbo-precheckin-disclaimer" in vikbooking-overrides.css: sfondo
   background-alt, icona accent, testo text-soft), qui però costruita
   con blocchi nativi (Group + HTML + Paragraph) perché è contenuto
   editoriale della pagina, non output del plugin. */
.legal-notice {
	align-items: flex-start;
	gap: var(--wp--preset--spacing--3);
	margin-bottom: var(--wp--preset--spacing--6);
	padding: var(--wp--preset--spacing--4) var(--wp--preset--spacing--5);
	border-radius: var(--vik-radius);
}

.legal-notice__icon {
	display: flex;
	flex-shrink: 0;
	margin-top: 2px;
	color: var(--wp--preset--color--accent);
}

.legal-notice__text {
	flex: 1 1 auto;
	min-width: 0;
	margin: 0;
	color: var(--wp--preset--color--text-soft);
	font-size: var(--wp--preset--font-size--sm);
	line-height: 1.5;
}

/* -----------------------------------------------------------
   Utility condivise tra i pattern
   ----------------------------------------------------------- */
.eyebrow,
.is-style-eyebrow {
	display: block;
	margin-bottom: var(--wp--preset--spacing--2);
	color: var(--wp--preset--color--accent);
	font-size: var(--wp--preset--font-size--xs);
	letter-spacing: 0.08em;
	text-transform: uppercase;
}

.section-head {
	margin-bottom: var(--wp--preset--spacing--6);
	text-align: center;
}

.section-head--left {
	text-align: left;
}

/* -----------------------------------------------------------
   CTA — varianti riutilizzabili del bottone/link di invito
   all'azione. Usabili in qualsiasi pattern (intro-text-image,
   hero-search, offers-featured, cta-banner, ecc.) assegnando la
   classe al blocco Button/Buttons dall'editor.
   ----------------------------------------------------------- */
.wp-block-button.cta-pill .wp-block-button__link {
	display: inline-flex;
	align-items: center;
	padding: var(--wp--preset--spacing--3) var(--wp--preset--spacing--6);
	background-color: transparent;
	border: 1px solid var(--wp--preset--color--ink);
	border-radius: 100px;
	box-shadow: none;
	color: var(--wp--preset--color--ink);
	font-size: var(--wp--preset--font-size--sm);
	font-weight: 500;
	transition: background-color 0.2s ease, color 0.2s ease;
}

.wp-block-button.cta-pill .wp-block-button__link:hover {
	background-color: var(--wp--preset--color--ink);
	color: var(--wp--preset--color--white);
}

.wp-block-button.cta-link-arrow .wp-block-button__link {
	display: inline-flex;
	align-items: center;
	gap: var(--wp--preset--spacing--2);
	padding: 0 0 var(--wp--preset--spacing--1);
	background-color: transparent;
	border: none;
	border-bottom: 1px solid var(--wp--preset--color--accent);
	border-radius: 0;
	box-shadow: none;
	color: var(--wp--preset--color--accent);
	font-size: var(--wp--preset--font-size--xs);
	font-weight: 600;
	letter-spacing: 0.08em;
	text-transform: uppercase;
}

.wp-block-button.cta-link-arrow .wp-block-button__link::after {
	content: "\2192";
	transition: transform 0.2s ease;
}

.wp-block-button.cta-link-arrow .wp-block-button__link:hover::after {
	transform: translateX(4px);
}

/*
 * cta-outline — bottone secondario "outline" su sfondo scuro/foto (usato da
 * ".hero-search-compact__cta"): border/testo chiari, sfondo trasparente a
 * riposo, si riempie di bianco all'hover. Classe CSS libera sul blocco
 * Button, non i supporti nativi border/color di core/button (che serializzano
 * come stile inline sul link, non come classi preset "has-*-color" —
 * evitato qui per restare sullo stesso schema, già validato, di
 * ".cta-pill"/".cta-link-arrow" sopra).
 */
.wp-block-button.cta-outline .wp-block-button__link {
	display: inline-flex;
	align-items: center;
	gap: var(--wp--preset--spacing--2);
	background-color: transparent;
	border: 1px solid var(--wp--preset--color--white);
	border-radius: var(--vik-radius);
	color: var(--wp--preset--color--white);
	box-shadow: none;
	transition: background-color 0.2s ease, color 0.2s ease;
}

.wp-block-button.cta-outline .wp-block-button__link:hover {
	background-color: var(--wp--preset--color--white);
	color: var(--wp--preset--color--ink);
}

/* Freccia coerente con ".cta-link-arrow" sopra: stesso glifo, qui inline
   invece che in coda via ::after perché il bottone ha già "gap" flex per
   lo spazio con il testo. */
.wp-block-button.cta-outline .wp-block-button__link::after {
	content: "\2192";
	transition: transform 0.2s ease;
}

.wp-block-button.cta-outline .wp-block-button__link:hover::after {
	transform: translateX(4px);
}

/* -----------------------------------------------------------
   site-header — logo, navigazione, CTA
   ----------------------------------------------------------- */
.site-header__logo,
.site-header__logo a {
	font-family: var(--wp--preset--font-family--display);
	font-size: var(--wp--preset--font-size--lg);
	font-weight: 500;
	letter-spacing: 0.02em;
	color: var(--wp--preset--color--ink);
	text-decoration: none;
}

/*
 * Logo immagine (core/site-logo, vedi inc/site-logo.php): limitato in
 * altezza, larghezza proporzionale. "width/height: auto" annullano i 120px
 * fissi di ".wp-block-site-logo.is-default-size img" del core, che con un
 * limite d'altezza deformerebbero i loghi non orizzontali.
 */
.site-header {
	--vik-site-logo-max-height: 44px;
	--vik-site-logo-max-width: 160px;
}

@media (min-width: 1024px) {
	.site-header {
		--vik-site-logo-max-height: 56px;
		--vik-site-logo-max-width: 220px;
	}
}

.site-footer {
	--vik-site-logo-max-height: 72px;
	--vik-site-logo-max-width: 220px;
}

.site-header .site-header__brand-logo.wp-block-site-logo img,
.site-footer .site-footer__brand-logo.wp-block-site-logo img {
	display: block;
	width: auto;
	height: auto;
	max-width: var(--vik-site-logo-max-width);
	max-height: var(--vik-site-logo-max-height);
}

.site-header__nav .wp-block-navigation-item__content {
	font-family: var(--wp--preset--font-family--body);
	padding-bottom: var(--wp--preset--spacing--1);
	border-bottom: 1px solid transparent;
	transition: border-color 200ms ease;
}

.site-header__nav .wp-block-navigation-item.current-menu-item > .wp-block-navigation-item__content,
.site-header__nav .wp-block-navigation-item__content:hover {
	border-bottom-color: var(--wp--preset--color--accent);
}

/*
 * vik-base/language-switcher (giro multi-lingua, punto 6) — stesso
 * trattamento "sottolineatura bottom accent" della voce di nav attiva sopra
 * (.site-header__nav .wp-block-navigation-item__content), non un componente
 * visivamente distinto: è pensato per stare accanto alla navigazione nello
 * stesso header, non per richiamare l'attenzione come una CTA.
 */
.vik-base-language-switcher__list {
	display: flex;
	align-items: center;
	gap: var(--wp--preset--spacing--3);
	margin: 0;
	padding: 0;
	list-style: none;
}

.vik-base-language-switcher__item a {
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--xs);
	font-weight: 600;
	letter-spacing: 0.04em;
	text-transform: uppercase;
	text-decoration: none;
	color: inherit;
	padding-bottom: var(--wp--preset--spacing--1);
	border-bottom: 1px solid transparent;
	transition: border-color 200ms ease;
}

.vik-base-language-switcher__item a:hover,
.vik-base-language-switcher__item.is-current a {
	border-bottom-color: var(--wp--preset--color--accent);
}

.site-header__cta .wp-block-button__link {
	border-radius: var(--vik-radius);
	padding: var(--wp--preset--spacing--2) var(--wp--preset--spacing--5);
	font-size: var(--wp--preset--font-size--xs);
	font-weight: 600;
	letter-spacing: 0.08em;
	text-transform: uppercase;
}

/*
 * site-header — variante "Fisso in cima (sticky)" (attributo "Stile Header"
 * nell'Inspector del template part, assets/js/editor/site-header-style-
 * control.js): nessun filtro server-side qui, un solo blocco header
 * condiviso da tutto il sito, la classe modificatrice basta da sola.
 *
 * "position:sticky" va sul wrapper ".wp-block-template-part" (generato
 * automaticamente da WordPress attorno all'output di OGNI template part,
 * qui un secondo elemento <header> attorno al nostro ".site-header"), non
 * su ".site-header" stesso: verificato dal vivo con Playwright che
 * mettendolo lì l'header smette di seguire lo scroll subito dopo il primo
 * pixel. Motivo — il "containing block" di un elemento sticky è il suo
 * blocco genitore più vicino, non il documento; ".wp-block-template-part"
 * è alto esattamente quanto ".site-header" (nessun contenuto proprio, lo
 * avvolge e basta), quindi un ".site-header" sticky avrebbe margine per
 * restare fisso pari a zero, uscendo dallo schermo al primo scroll
 * insieme al proprio genitore. Il wrapper invece è figlio diretto di
 * ".wp-site-blocks" (alto quanto l'intera pagina), il "containing block"
 * corretto perché lo sticky abbia margine per restare fisso lungo tutto lo
 * scroll. ":has(> ...)" scoped al solo figlio diretto marcato: il footer,
 * altro template part con la stessa classe wrapper, non viene toccato.
 *
 * Specificità volutamente contenuta (":has()" conta come una classe, qui
 * una sola su un elemento diverso da ".site-header"): resta più debole dei
 * selettori "body:has(.hero-search--immersive-centered) .site-header" ecc.
 * più sotto (0,2,0 grazie a ":has()" su "body"), quindi quando l'hero
 * attivo è una delle varianti scure con header in overlay, quel
 * trattamento (position:absolute, sfondo trasparente) vince comunque senza
 * bisogno di "!important" — le due modalità non sono pensate per convivere
 * sulla stessa pagina, ma se capitasse l'overlay resta la scelta più
 * sicura (l'alternativa, l'header sticky con sfondo pieno, coprirebbe
 * l'hero).
 */
.wp-block-template-part:has(> .site-header--sticky) {
	position: sticky;
	top: 0;
	z-index: 40;
}

.site-header--sticky {
	background-color: var(--wp--preset--color--background);
	border-bottom: 1px solid var(--wp--preset--color--line);
}

/*
 * site-header — variante "Trasparente sopra l'hero" (MAREA.md §3):
 * trasparente sopra un hero full-size in cima alla pagina, diventa sfondo
 * pieno dopo ~40px di scroll (classe "is-scrolled", vedi assets/js/header-
 * scroll-state.js). Ha effetto SOLO quando il body porta la classe
 * "vik-has-fullsize-hero" (rilevata server-side da
 * inc/header-fullsize-hero.php in base al primo blocco della pagina) — su
 * qualunque altra pagina (interne, camera singola, legali, 404, risultati
 * ricerca) questa stessa classe modificatrice ricade SENZA alcuna
 * impostazione per-pagina sullo stesso trattamento solido di
 * ".site-header--sticky" sopra, dichiarato qui come base non condizionata.
 *
 * "position:fixed" (non "position:sticky" come ".site-header--sticky"
 * sopra) va bene direttamente sull'header stesso, senza l'indirizione sul
 * wrapper ".wp-block-template-part": il containing block di un elemento
 * fixed è il viewport (o il primo antenato con transform/filter/
 * perspective, nessuno dei due presente qui), non il genitore immediato —
 * a differenza di sticky, qui non c'è il problema "il genitore non ha
 * margine per farlo restare fisso" che aveva reso necessario il wrapper
 * per la sticky (vedi il commento su quella regola sopra). Un header fixed
 * esce inoltre del tutto dal flusso: il wrapper collassa a altezza 0 e
 * l'hero sotto può davvero partire dal bordo dello schermo ("l'header
 * sovrappone l'hero, l'hero non scende").
 */
.site-header--transparent-overlay {
	background-color: var(--wp--preset--color--background);
	border-bottom: 1px solid var(--wp--preset--color--line);
	box-shadow: none;
	transition: background-color 200ms ease, border-color 200ms ease;
}

@media (prefers-reduced-motion: reduce) {
	.site-header--transparent-overlay {
		transition: none;
	}
}

body.vik-has-fullsize-hero .site-header--transparent-overlay {
	position: fixed;
	inset: 0 0 auto 0;
	z-index: 40;
	background-color: transparent;
	border-bottom-color: transparent;
}

/* Offset per la admin bar di WordPress (32px desktop, 46px <=782px — soglia
   e valori nativi di WP, non una scelta del tema): senza questo l'header
   fixed finisce sotto o sovrapposto alla admin bar invece che appena sotto.
   ".site-header--sticky" non ne ha bisogno: "position:sticky" resta nel
   flusso normale, che l'admin bar sposta già in blocco via
   "html.wp-toolbar". */
body.vik-has-fullsize-hero.admin-bar .site-header--transparent-overlay {
	top: 32px;
}

@media screen and (max-width: 782px) {
	body.vik-has-fullsize-hero.admin-bar .site-header--transparent-overlay {
		top: 46px;
	}
}

body.vik-has-fullsize-hero .site-header--transparent-overlay.is-scrolled {
	background-color: var(--wp--preset--color--background);
	border-bottom-color: var(--wp--preset--color--line);
}

/*
 * Stato trasparente (non ancora scrollato): logo, voci di nav e selettore
 * lingua passano a un colore chiaro leggibile sulla foto sottostante — lo
 * stesso schema già usato per le varianti hero scure più sotto in questo
 * file (".site-header__logo" ecc. dentro "body:has(...)"), qui però
 * condizionato anche da ":not(.is-scrolled)" perché lo stesso elemento
 * header cambia stato in pagina, non è un trattamento fisso per tutta la
 * visita. Site-title è testo (non immagine, vedi parts/header.html): basta
 * cambiare "color", nessun filtro immagine necessario — se in futuro il
 * logo diventasse un'immagine, l'approccio più semplice e robusto è un
 * secondo file logo chiaro mostrato/nascosto con lo stesso selettore
 * ":not(.is-scrolled)" (un CSS "filter:brightness()/invert()" su una foto
 * reale del logo produce risultati incoerenti a seconda dei colori del
 * logo stesso, un secondo asset preparato ad hoc resta l'unica soluzione
 * realmente robusta per un'immagine).
 *
 * ".wp-block-navigation__responsive-container:not(.is-menu-open)" — il
 * pannello mobile a schermo intero (aperto dall'hamburger) è un discendente
 * dello stesso ".site-header__nav" ma ha uno sfondo chiaro proprio,
 * indipendente dalla foto dietro la barra header: senza questa esclusione
 * i link risultavano bianchi su sfondo bianco, illeggibili (verificato con
 * Playwright, screenshot del pannello aperto).
 */
body.vik-has-fullsize-hero .site-header--transparent-overlay:not(.is-scrolled) .site-header__logo,
body.vik-has-fullsize-hero .site-header--transparent-overlay:not(.is-scrolled) .site-header__logo a,
body.vik-has-fullsize-hero .site-header--transparent-overlay:not(.is-scrolled) .site-header__nav .wp-block-navigation__responsive-container:not(.is-menu-open) .wp-block-navigation-item__content,
body.vik-has-fullsize-hero .site-header--transparent-overlay:not(.is-scrolled) .vik-base-language-switcher__item a {
	color: var(--wp--preset--color--white);
}

/*
 * CTA "Prenota Ora": nello stato trasparente non resta il bottone pieno
 * accent/bianco di default (contrasto non garantito con qualunque foto
 * sotto, vedi CLAUDE.md) ma un trattamento a sé, sfondo pieno chiaro +
 * testo scuro (stesso principio "mai un outline chiaro su foto per un CTA
 * primario" già seguito per gli outline secondari) — poi torna al bottone
 * accent normale una volta in stato "is-scrolled".
 *
 * Non una semplice "background-color"/"color" qui: le classi core
 * ".has-accent-background-color"/".has-white-color" già sul blocco
 * (generate dal pannello colore nativo del bottone) vengono emesse da
 * WordPress con "!important" (verificato nell'HTML servito, non
 * un'assunzione) — nessuna specificità, per quanto alta, le batte senza
 * ricorrere anch'essa a "!important", vietato dalle regole del tema.
 * Ridefinendo qui le CUSTOM PROPERTY che quelle regole "!important"
 * referenziano (non le proprietà finali) si ottiene lo stesso risultato
 * senza mai scrivere "!important": la regola core resta quella che vince
 * (è sempre lei ad applicarsi), ma risolve al valore che le passiamo noi.
 */
body.vik-has-fullsize-hero .site-header--transparent-overlay:not(.is-scrolled) .site-header__cta {
	--wp--preset--color--accent: var(--wp--preset--color--background);
	--wp--preset--color--white: var(--wp--preset--color--ink);
}

/*
 * Scrim di leggibilità per la sola fascia dell'header, riusa lo stesso
 * token "--vik-overlay-dark" già usato per lo scrim dietro l'header nella
 * variante hero "Immersivo in overlay" più sotto in questo file (default
 * neutro qui, skin-terra/skin-marea lo ridefiniscono col proprio colore):
 * indipendente dallo scrim proprio dell'hero (che può o meno coprire a
 * sufficienza la fascia alta, a seconda della skin) — un header trasparente
 * porta sempre con sé la garanzia minima di leggibilità per sé stesso,
 * qualunque hero/skin lo usi. "position:fixed" sull'header stesso crea già
 * un containing block per questo pseudo-elemento (inset relativo
 * all'header), nessun "position:relative" esplicito necessario.
 */
body.vik-has-fullsize-hero .site-header--transparent-overlay:not(.is-scrolled)::before {
	content: "";
	position: absolute;
	inset: 0 0 -64px 0;
	z-index: -1;
	background: linear-gradient(to bottom, var(--vik-overlay-dark) 0%, transparent 100%);
	pointer-events: none;
}

/*
 * L'hero full-size sotto un header trasparente-overlay deve occupare
 * l'intero schermo (l'header non gli sottrae spazio, lo sovrappone) — stesso
 * principio già applicato per il toggle manuale "Header in overlay sopra
 * l'hero" del blocco hero-background più sotto in questo file
 * (".hero-bg.is-height-full.hero-bg--header-overlay"), qui esteso alla
 * nuova condizione automatica basata sulla modalità header globale.
 *
 * ":has(.site-header--transparent-overlay)" (fix 2026-10-07, bb-ledueg):
 * "vik-has-fullsize-hero" dice solo "il primo blocco è un hero full-size",
 * NON "l'header è trasparente". Senza questa condizione, con header solido
 * (default Terra) o sticky — entrambi nel flusso, sopra l'hero — l'hero
 * prendeva comunque 100svh invece di "100svh - --header-height": header +
 * hero eccedevano il viewport e il form di ricerca finiva sotto la piega.
 */
body.vik-has-fullsize-hero:has(.site-header--transparent-overlay) .hero-bg.is-height-full {
	min-height: 100svh;
}

body.vik-has-fullsize-hero #main {
	margin-block-start: 0;
}

/*
 * scroll-margin-top universale — un header sticky o trasparente-overlay
 * resta fisso sopra il contenuto anche quando si salta a un'ancora (es. il
 * CTA "Scopri le camere" della hero compatta, "href=#camere"): senza
 * questo il titolo della sezione di destinazione finirebbe nascosto sotto
 * l'header invece che appena sotto. "--header-height" è la stessa custom
 * property scritta da assets/js/header-height.js, già usata altrove in
 * questo file — un margine fisso avrebbe bisogno di essere ricontrollato a
 * mano ogni volta che l'header cambia altezza (desktop/mobile, con o senza
 * admin bar). Applicata a qualunque elemento con id, non solo a sezioni
 * note oggi: nessun costo per un elemento che non viene mai usato come
 * bersaglio di un'ancora.
 */
[id] {
	scroll-margin-top: calc(var(--header-height, 88px) + var(--wp--preset--spacing--4));
}

/*
 * site-header__nav — hamburger anche a tablet (768–1023px), non solo sotto
 * i 600px. Il blocco core "wp:navigation" (parts/header.html) non ha
 * l'attributo "overlayMenu" impostato, quindi eredita il default core
 * ("mobile"): la soglia a cui passa da elenco inline a hamburger è fissa a
 * 600px (wp-includes/blocks/navigation/style.min.css,
 * "@media (min-width: 600px) { .wp-block-navigation__responsive-container-
 * open:not(.always-shown) { display: none } }") — non configurabile
 * dall'editor, indipendente dai breakpoint del tema.
 *
 * Con le 7 voci di menu + CTA "Prenota Ora" di questo giro, l'elenco
 * inline non ci sta nei primi ~170px oltre quella soglia — verificato dal
 * vivo a 768px: "Contatti" va a capo da solo su una seconda riga, seguito
 * dal CTA ancora più sotto, header alto ~200px invece dei ~74px previsti.
 * Non è un problema che una spaziatura più stretta risolverebbe in modo
 * affidabile (il numero di voci è editabile dall'utente non tecnico nel
 * Site Editor, quindi qualunque margine calcolato oggi può bastare o non
 * bastare più domani) — l'hamburger, già presente e già funzionante sotto
 * i 600px, è la soluzione strutturale: estendere la sua soglia nativa fino
 * al limite superiore "tablet" del tema (1023px, vedi regola 5 del brief)
 * invece di lasciarla al default core, così l'header resta a una riga in
 * tutto l'intervallo < 1024px indipendentemente da quante voci contiene.
 *
 * Selettori con lo stesso identico "descendant" del core più il solo
 * ".site-header__nav" in più (specificità superiore di una classe,
 * nessun bisogno di "!important", vedi regola 3 del brief) — scoped a
 * questo nav, non a tutti i blocchi "wp:navigation" del sito (es. il nav
 * del footer resta col default core, già impilato in colonna, senza lo
 * stesso problema di spazio).
 */
@media (min-width: 600px) and (max-width: 1023px) {
	.site-header__nav .wp-block-navigation__responsive-container:not(.hidden-by-default):not(.is-menu-open) {
		display: none;
	}

	.site-header__nav .wp-block-navigation__responsive-container-open:not(.always-shown) {
		display: flex;
	}
}

/*
 * site-header — overlay su varianti hero scure (Immersivo centrato /
 * Form protagonista). L'header resta lo stesso template part in tutte le
 * pagine (parts/header.html): qui lo si sovrappone in trasparenza solo
 * quando la pagina contiene, in un punto qualsiasi, un hero-search con
 * una di queste 2 varianti attive — :has() guarda in avanti nel DOM,
 * quindi funziona anche se l'header (fuori da <main>) precede l'hero.
 * La variante "Pannello laterale" non serve qui: lascia l'header nel suo
 * trattamento solido di default, sopra il layout, non sovrapposto.
 *
 * ".hero-bg--header-overlay" (variante "Immersivo"/default, blocco
 * vik-base/hero-background) è nello stesso gruppo di selettori quando
 * l'utente attiva esplicitamente il ToggleControl "Header in overlay
 * sopra l'hero" nell'Inspector (edit.js), presente solo con altezza
 * "Schermo intero" — di default (Toggle disattivo) l'header per questa
 * variante resta invece nel trattamento solido standard, e ".hero-bg"
 * sottrae l'altezza reale dell'header dal proprio 100svh invece di
 * sovrapporcisi (vedi ".hero-bg.is-height-full" più sopra in questo
 * file): due soluzioni diverse allo stesso problema di viewport-overflow,
 * quale delle due dipende dalla scelta dell'utente per QUESTA variante,
 * non è un default imposto.
 *
 * "body.vik-has-fullsize-hero" aggiunto qui (audit 2026-09-28): questo
 * blocco è più vecchio del meccanismo dimensione full-size/compatta
 * (inc/hero-search-size-variants.php, inc/header-fullsize-hero.php) e non
 * lo consultava affatto — scattava per QUALUNQUE istanza di queste 2
 * varianti/toggle a prescindere dalla dimensione, ignorando anche la
 * scelta esplicita dell'utente nel controllo "Stile Header"
 * (site-header-style-control.js). Bug reale: un hero "Immersivo centrato"/
 * "Form protagonista" in dimensione COMPATTA riceveva comunque l'header
 * assoluto/trasparente pensato solo per il full-size. Rientra nel
 * comportamento di prima per ogni contenuto esistente: prima che la
 * dimensione compatta esistesse queste varianti erano sempre e solo
 * full-size, quindi "vik-has-fullsize-hero" era già sempre vero in quei
 * casi — zero cambio di resa per skin-terra. Cambia solo il caso nuovo
 * (compatta), che ora ricade correttamente sul trattamento header solido
 * di default invece di ereditare questo overlay.
 */
body.vik-has-fullsize-hero:has(.hero-search--immersive-centered) .site-header,
body.vik-has-fullsize-hero:has(.hero-search--form-protagonist) .site-header,
body.vik-has-fullsize-hero:has(.hero-bg--header-overlay) .site-header {
	position: absolute;
	inset: 0 0 auto 0;
	z-index: 30;
	background: none;
}

body.vik-has-fullsize-hero:has(.hero-search--immersive-centered) .site-header__logo,
body.vik-has-fullsize-hero:has(.hero-search--immersive-centered) .site-header__logo a,
body.vik-has-fullsize-hero:has(.hero-search--form-protagonist) .site-header__logo,
body.vik-has-fullsize-hero:has(.hero-search--form-protagonist) .site-header__logo a,
body.vik-has-fullsize-hero:has(.hero-bg--header-overlay) .site-header__logo,
body.vik-has-fullsize-hero:has(.hero-bg--header-overlay) .site-header__logo a,
body.vik-has-fullsize-hero:has(.hero-search--immersive-centered) .site-header__nav .wp-block-navigation-item__content,
body.vik-has-fullsize-hero:has(.hero-search--form-protagonist) .site-header__nav .wp-block-navigation-item__content,
body.vik-has-fullsize-hero:has(.hero-bg--header-overlay) .site-header__nav .wp-block-navigation-item__content,
body.vik-has-fullsize-hero:has(.hero-search--immersive-centered) .vik-base-language-switcher__item a,
body.vik-has-fullsize-hero:has(.hero-search--form-protagonist) .vik-base-language-switcher__item a,
body.vik-has-fullsize-hero:has(.hero-bg--header-overlay) .vik-base-language-switcher__item a {
	color: var(--wp--preset--color--white);
}

/*
 * "#main" (wrapper "wp:group tagName main", vedi templates/front-page.html)
 * eredita "margin-block-start" dallo stile globale WordPress
 * ":root :where(.is-layout-flow) > *" (24px in questo tema) in quanto
 * secondo figlio di ".wp-site-blocks" dopo l'header — indipendente dalla
 * presenza/posizione dell'header stesso. Azzerato per l'intero
 * ".is-height-full" (non solo per "--header-overlay"): serve in ENTRAMBE
 * le modalità, altrimenti anche col calcolo "calc(100svh -
 * var(--header-height))" del caso default questi 24px residui
 * farebbero eccedere l'hero dal viewport lo stesso, solo di meno. Stesso
 * schema già usato per
 * ".experiences-dark__track > .wp-block-vik-base-experience-card" più
 * sotto nel file.
 */
body:has(.hero-bg.is-height-full) #main {
	margin-block-start: 0;
}

/*
 * Scrim aggiuntivo dietro l'header per l'hero "Immersivo"/default in
 * modalità overlay: a differenza delle 2 varianti sopra (core/cover con
 * dimRatio 40/60, scurimento uniforme su tutta l'immagine), il gradiente
 * overlay di ".hero-bg" (0.05→0.55 alpha dall'alto al basso, vedi
 * blocks/hero-background/render.php) è quasi trasparente proprio nella
 * fascia dove l'header ora galleggia — sufficiente per il testo in basso
 * a sinistra che questo pattern è nato per servire, non per logo/nav
 * bianchi in alto. Striscia scura fissa, indipendente da
 * "overlayOpacity" (che governa il gradiente principale, configurabile
 * dall'utente per l'umore della foto): garantisce un contrasto minimo
 * per l'header senza scurire il resto dell'immagine.
 *
 * "calc(var(--header-height, 88px) + 80px)": agganciata alla stessa
 * custom property scritta da assets/js/header-height.js usata per il
 * calcolo dell'altezza qui sopra (non un valore fisso indipendente) —
 * segue quindi automaticamente l'header reale (desktop ~55px, mobile
 * ~110px misurati) più un margine di sfumatura di 80px, invece di dover
 * essere ricontrollata a mano se l'header cambia altezza in futuro.
 */
body:has(.hero-bg--header-overlay) .hero-bg::before {
	content: "";
	position: absolute;
	inset: 0 0 auto 0;
	z-index: 1;
	height: calc(var(--header-height, 88px) + 80px);
	background: linear-gradient(180deg, rgba(0, 0, 0, 0.45) 0%, rgba(0, 0, 0, 0) 100%);
	pointer-events: none;
}

/* -----------------------------------------------------------
   intro-text-image
   ----------------------------------------------------------- */
.intro-text-image__text .eyebrow,
.intro-text-image__text .is-style-eyebrow {
	margin-bottom: var(--wp--preset--spacing--3);
}

.intro-text-image__text .wp-block-heading {
	margin-bottom: var(--wp--preset--spacing--4);
}

.intro-text-image__text .wp-block-paragraph {
	margin-bottom: var(--wp--preset--spacing--5);
	color: var(--wp--preset--color--text-soft);
}

.intro-text-image__text .wp-block-buttons {
	margin-top: var(--wp--preset--spacing--2);
}

/* -----------------------------------------------------------
   intro-text-image-card
   ----------------------------------------------------------- */
.intro-text-image-card__frame {
	display: grid;
	grid-template-columns: 1fr;
	min-height: 420px;
	background-color: var(--wp--preset--color--white);
	border: 1px solid var(--wp--preset--color--line);
	border-radius: var(--vik-radius);
	overflow: hidden;
}

@media (min-width: 768px) {
	.intro-text-image-card__frame {
		grid-template-columns: 1fr 1fr;
		min-height: 520px;
	}
}

.intro-text-image-card__text {
	display: flex;
	flex-direction: column;
	justify-content: center;
	min-width: 0;
	margin: 0;
	padding: var(--wp--preset--spacing--7) var(--wp--preset--spacing--6);
}

@media (min-width: 1024px) {
	.intro-text-image-card__text {
		padding: var(--wp--preset--spacing--8);
	}
}

.intro-text-image-card__text .eyebrow,
.intro-text-image-card__text .is-style-eyebrow {
	margin-bottom: var(--wp--preset--spacing--3);
}

.intro-text-image-card__text .wp-block-heading {
	margin-bottom: var(--wp--preset--spacing--4);
}

.intro-text-image-card__divider {
	display: block;
	width: 40px;
	height: 1px;
	margin: 0 0 var(--wp--preset--spacing--5);
	background-color: var(--wp--preset--color--accent);
}

.intro-text-image-card__text .wp-block-paragraph {
	margin-bottom: var(--wp--preset--spacing--5);
	color: var(--wp--preset--color--text-soft);
}

.intro-text-image-card__text .wp-block-buttons {
	margin-top: var(--wp--preset--spacing--2);
}

.intro-text-image-card__image {
	min-width: 0;
	margin: 0;
	min-height: 260px;
}

.intro-text-image-card__image img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* -----------------------------------------------------------
   intro-text-image-bleed
   ----------------------------------------------------------- */
.intro-text-image-bleed__cover.wp-block-cover {
	min-height: 480px;
}

@media (min-width: 768px) {
	.intro-text-image-bleed__cover.wp-block-cover {
		min-height: 620px;
	}
}

/*
 * Lo sfondo del pannello (colore scelto dall'utente + sfumatura verso la
 * foto) vive su ::before, non sull'elemento stesso: mask-image applicato
 * direttamente al pannello sfumerebbe anche il testo dei figli, non solo lo
 * sfondo. ::before resta dietro il contenuto (z-index 0 vs 1) mentre il
 * colore nativo assegnato dal blocco Group ("Colore di sfondo") viene
 * neutralizzato su .has-background e ridiretto a ::before per slug.
 *
 * !important necessario qui, unica eccezione nel file: le classi
 * "has-*-background-color" generate da WordPress a partire dai colori
 * della palette (theme.json) vengono emesse nel foglio di stile globale
 * inline con !important (per garantire che il colore scelto in Inspector
 * vinca sempre sugli stili dei singoli blocchi) — per neutralizzarle qui
 * non c'è alternativa che pareggiare con !important.
 */
.intro-text-image-bleed__panel {
	position: relative;
	width: 100%;
	padding: var(--wp--preset--spacing--7) var(--wp--preset--spacing--6);
}

.intro-text-image-bleed__panel.has-background {
	background-color: transparent !important;
}

.intro-text-image-bleed__panel::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 0;
}

/*
 * Un fill per ogni colore della palette (theme.json), non solo i 2 mostrati
 * nel mockup di riferimento ("Background" e "Dark"): il pannello usa il
 * controllo nativo "Colore di sfondo" del blocco Group, che nell'Inspector
 * propone TUTTI gli swatch della palette — se uno di questi non avesse una
 * regola qui sotto, scegliendolo il pannello resterebbe trasparente (nessun
 * fill, testo senza sfondo leggibile sopra la foto).
 */
.intro-text-image-bleed__panel.has-background-background-color::before {
	background-color: var(--wp--preset--color--background);
}

.intro-text-image-bleed__panel.has-background-alt-background-color::before {
	background-color: var(--wp--preset--color--background-alt);
}

.intro-text-image-bleed__panel.has-white-background-color::before {
	background-color: var(--wp--preset--color--white);
}

.intro-text-image-bleed__panel.has-line-background-color::before {
	background-color: var(--wp--preset--color--line);
}

.intro-text-image-bleed__panel.has-text-background-color::before {
	background-color: var(--wp--preset--color--ink);
}

.intro-text-image-bleed__panel.has-text-soft-background-color::before {
	background-color: var(--wp--preset--color--text-soft);
}

.intro-text-image-bleed__panel.has-accent-background-color::before {
	background-color: var(--wp--preset--color--accent);
}

.intro-text-image-bleed__panel.has-accent-dark-background-color::before {
	background-color: var(--wp--preset--color--accent-dark);
}

.intro-text-image-bleed__panel.has-dark-background-color::before {
	background-color: var(--wp--preset--color--dark);
}

.intro-text-image-bleed__panel > * {
	position: relative;
	z-index: 1;
}

@media (min-width: 768px) {
	.intro-text-image-bleed__panel {
		max-width: 560px;
		padding: var(--wp--preset--spacing--8);
	}

	/*
	 * --intro-bleed-fade: punto (%) in cui inizia la dissolvenza, iniettato
	 * inline da inc/intro-bleed-fade.php in base al controllo "Dissolvenza"
	 * nell'Inspector del blocco (assets/js/editor/intro-bleed-fade-control.js).
	 * Il fallback 60% resta valido se il blocco non ha lo stile inline
	 * (es. markup salvato prima dell'introduzione del controllo).
	 */
	.intro-text-image-bleed__panel::before {
		-webkit-mask-image: linear-gradient(90deg, black 0%, black var(--intro-bleed-fade, 60%), transparent 100%);
		mask-image: linear-gradient(90deg, black 0%, black var(--intro-bleed-fade, 60%), transparent 100%);
	}
}

@media (min-width: 1024px) {
	.intro-text-image-bleed__panel {
		max-width: 620px;
		padding: var(--wp--preset--spacing--9) var(--wp--preset--spacing--8);
	}
}

/*
 * color esplicito necessario: il blocco Cover, senza "has-text-color",
 * applica di default color:#fff a tutto il contenuto (style.css core del
 * blocco), pensato per foto scure con testo chiaro sovrapposto. Il nostro
 * pannello chiaro di default necessita del colore di testo scuro standard.
 */
.intro-text-image-bleed__panel .wp-block-heading {
	margin: 0 0 var(--wp--preset--spacing--4);
	color: var(--wp--preset--color--ink);
}

.intro-text-image-bleed__divider {
	display: block;
	width: 40px;
	height: 1px;
	margin: 0 0 var(--wp--preset--spacing--5);
	background-color: var(--wp--preset--color--accent);
}

.intro-text-image-bleed__panel .wp-block-paragraph {
	margin: 0 0 var(--wp--preset--spacing--5);
	color: var(--wp--preset--color--text-soft);
}

.intro-text-image-bleed__panel .wp-block-buttons {
	margin-top: var(--wp--preset--spacing--2);
}

/*
 * L'eyebrow resta color accent su qualunque sfondo (coerente con i mockup,
 * dove compare in terracotta sia sul pannello chiaro che su quello scuro) —
 * eccetto quando il pannello stesso è impostato su "Accent" o "Accent Dark":
 * lì l'eyebrow diventerebbe accent-su-accent, illeggibile.
 */
.intro-text-image-bleed__panel:is(.has-accent-background-color, .has-accent-dark-background-color) .eyebrow,
.intro-text-image-bleed__panel:is(.has-accent-background-color, .has-accent-dark-background-color) .is-style-eyebrow {
	color: var(--wp--preset--color--white);
}

/*
 * Sfondo scuro/medio-scuro selezionato dall'utente (Text, Text Soft, Accent,
 * Accent Dark, Dark): il testo passa a chiaro perché il colore di default
 * (var(--text) / var(--text-soft), pensato per sfondi chiari) non sarebbe
 * leggibile. "Background", "Background Alt", "White" e "Line" restano con
 * il testo scuro di default, definito sopra.
 */
.intro-text-image-bleed__panel:is(
		.has-text-background-color,
		.has-text-soft-background-color,
		.has-accent-background-color,
		.has-accent-dark-background-color,
		.has-dark-background-color
	) .wp-block-heading {
	color: var(--wp--preset--color--white);
}

.intro-text-image-bleed__panel:is(
		.has-text-background-color,
		.has-text-soft-background-color,
		.has-accent-background-color,
		.has-accent-dark-background-color,
		.has-dark-background-color
	) .wp-block-paragraph {
	color: rgba(255, 255, 255, 0.78);
}

.intro-text-image-bleed__panel:is(
		.has-text-background-color,
		.has-text-soft-background-color,
		.has-accent-background-color,
		.has-accent-dark-background-color,
		.has-dark-background-color
	) .cta-link-arrow .wp-block-button__link {
	color: var(--wp--preset--color--white);
	border-bottom-color: var(--wp--preset--color--white);
}

/* -----------------------------------------------------------
   hero-search
   ----------------------------------------------------------- */
/*
 * Nasconde le varianti non attive nel Site Editor: inc/hero-search-variants.php
 * scarta le altre 3 lato server (render_block_data), ma quel filtro non gira
 * nel canvas dell'editor (i blocchi statici come Group vengono lì montati
 * client-side dai propri attributi, senza passare da PHP) — senza queste
 * regole tutte e 4 le varianti, coi rispettivi widget, sarebbero visibili
 * impilate mentre si modifica la pagina. I due selettori bastano perché,
 * a differenza dell'overlay dell'header più sopra, "hero-search" e la
 * classe modificatrice stanno sullo stesso elemento: non serve :has().
 */
.hero-search:not([class*="hero-search--"]) .hero-search__variant:not(.hero-search__variant--default),
.hero-search.hero-search--split-panel .hero-search__variant:not(.hero-search__variant--split-panel),
.hero-search.hero-search--immersive-centered .hero-search__variant:not(.hero-search__variant--immersive-centered),
.hero-search.hero-search--form-protagonist .hero-search__variant:not(.hero-search__variant--form-protagonist) {
	display: none;
}

/*
 * Stesso trattamento, per lo switch indipendente "Dimensione Hero"
 * (inc/hero-search-size-variants.php) annidato dentro
 * ".hero-search__variant--default": nasconde nel canvas dell'editor il
 * sotto-albero di dimensione non selezionato.
 */
.hero-search__size-switch:not(.hero-search__size-switch--compact) .hero-search__size:not(.hero-search__size--full),
.hero-search__size-switch.hero-search__size-switch--compact .hero-search__size:not(.hero-search__size--compact) {
	display: none;
}

.hero-search__content {
	max-width: 780px;
}

.hero-search__eyebrow {
	color: var(--wp--preset--color--white);
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--sm);
	letter-spacing: 0.2em;
	text-transform: uppercase;
	opacity: 0.85;
}

.hero-search__title {
	max-width: 780px;
	color: var(--wp--preset--color--white);
	font-family: var(--wp--preset--font-family--display);
	font-size: clamp(3rem, 2rem + 4vw, 5.5rem);
	font-weight: 500;
	line-height: 1.3;
}

.hero-search__title em {
	font-style: italic;
	color: var(--vik-overlay-ivory);
}

.hero-search__widget {
	max-width: 920px;
	margin-top: var(--wp--preset--spacing--6);
	background-color: var(--wp--preset--color--white);
	border-radius: var(--vik-radius);
	box-shadow: 0 24px 48px rgba(0, 0, 0, 0.18);
}

.hero-search__widget {
	padding: var(--wp--preset--spacing--5);
}

.hero-search__widget:empty::before {
	content: "Configura qui il widget VikBooking \"Search Form\" dall'editor.";
	display: block;
	color: var(--wp--preset--color--text-soft);
	font-size: var(--wp--preset--font-size--sm);
	text-align: center;
}

/*
 * hero-search — dimensione "Compatta" (hero-search__size--compact)
 *
 * Controparte incorniciata della variante full-size di sopra: stesso Group
 * "hero-search__content" (eyebrow/titolo, più un sottotitolo e una CTA
 * secondaria in più, esclusivi di questa dimensione) dentro lo stesso
 * blocco vik-base/hero-background, ma senza "align:full" — resta contenuto
 * dentro ".hero-search-compact", che aggiunge il margine di sfondo pagina
 * visibile sopra e ai lati. Il widget di ricerca è invece un FRATELLO del
 * blocco hero-background (non un suo InnerBlock): ".hero-bg" ha
 * "overflow:hidden" per il crop di slider/video, quindi l'unico modo per
 * farlo sporgere a cavallo del bordo inferiore della foto è tenerlo fuori
 * da quel box e tirarlo su con un margine negativo sul proprio wrapper.
 */
.hero-search-compact {
	position: relative;
	max-width: 1320px;
	margin-inline: auto;
	padding: var(--wp--preset--spacing--8) var(--wp--preset--spacing--8) 0;
}

/*
 * ".hero-search-compact__frame" è condivisa dalle 3 varianti di stile che
 * supportano la dimensione "Compatta" (Immersivo/default, Immersivo
 * centrato, Form protagonista — non "Pannello laterale", vedi il commento
 * nell'header di hero-search.php sul perché). Su ".hero-bg"
 * (vik-base/hero-background, variante default) "overflow:hidden" è già
 * suo di base; su ".wp-block-cover" (le altre 2) core non lo garantisce
 * per il solo scopo di arrotondare gli angoli dell'immagine, va dichiarato
 * qui esplicitamente — ripeterlo non fa danno dove è già presente.
 */
.hero-search-compact__frame {
	border-radius: var(--vik-radius);
	overflow: hidden;
}

.hero-search-compact__subtitle {
	max-width: 620px;
	margin-top: var(--wp--preset--spacing--3);
	color: var(--wp--preset--color--white);
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--base);
	opacity: 0.9;
}

.hero-search-compact__cta {
	margin-top: var(--wp--preset--spacing--5);
}

/*
 * Il wrapper resta nel normal flow SUBITO dopo ".hero-search-compact"
 * (che contiene la sola immagine incorniciata): il margine negativo lo
 * tira su a cavallo del bordo inferiore della foto, metà dentro/metà
 * fuori. Stessa larghezza massima/padding orizzontale di
 * ".hero-search-compact" così il bordo della card si allinea a quello
 * della foto invece di seguire la larghezza piena di ".hero-search__widget"
 * (920px, pensata per la variante full-size).
 */
.hero-search-compact__widget-wrap {
	position: relative;
	z-index: 2;
	max-width: 1320px;
	margin-inline: auto;
	margin-top: calc(-1 * var(--wp--preset--spacing--7));
	padding: 0 var(--wp--preset--spacing--8) var(--vik-section-space-y-compact);
}

.hero-search-compact__widget-wrap .hero-search__widget {
	margin-top: 0;
}

@media (max-width: 1023px) {
	.hero-search-compact {
		padding-left: var(--wp--preset--spacing--6);
		padding-right: var(--wp--preset--spacing--6);
	}

	.hero-search-compact__widget-wrap {
		padding-left: var(--wp--preset--spacing--6);
		padding-right: var(--wp--preset--spacing--6);
		padding-bottom: var(--vik-section-space-y-compact-tablet);
	}
}

@media (max-width: 767px) {
	.hero-search-compact {
		padding-left: var(--wp--preset--spacing--5);
		padding-right: var(--wp--preset--spacing--5);
	}

	.hero-search-compact__widget-wrap {
		padding-left: var(--wp--preset--spacing--5);
		padding-right: var(--wp--preset--spacing--5);
		padding-bottom: var(--vik-section-space-y-compact-mobile);
		margin-top: calc(-1 * var(--wp--preset--spacing--6));
	}
}

/* -----------------------------------------------------------
   hero-background (vik-base/hero-background)
   ----------------------------------------------------------- */
/*
 * Livello di sfondo del blocco vik-base/hero-background, che sostituisce
 * core/cover nella sola variante "Immersivo" (default) di hero-search.php:
 * tipo di sfondo (immagine/slider/video), altezza sezione e overlay
 * scurente sono tutti configurabili dall'Inspector. Le altre 3 varianti
 * (hero-search--split-panel, --immersive-centered, --form-protagonist)
 * restano su core/cover/core/image e non sono toccate da queste regole.
 */
.hero-bg {
	position: relative;
	overflow: hidden;
}

/*
 * Default (nessun overlay header, ToggleControl "Header in overlay sopra
 * l'hero" disattivo): l'header resta nel flusso normale sopra l'hero come
 * barra solida, quindi l'hero deve occupare solo lo spazio VERAMENTE
 * restante dello schermo, non l'intero 100svh — altrimenti header + hero
 * eccedono insieme il viewport (il fondo dell'hero, incluso il search
 * form, finisce tagliato fuori dallo schermo).
 *
 * "--header-height" è scritta dinamicamente da assets/js/header-height.js
 * (header.offsetHeight, misura reale — l'altezza dell'header cambia tra
 * desktop/mobile perché la nav va a capo sotto il logo sotto una certa
 * larghezza). Il fallback qui sotto (var(--header-height, 88px)) copre
 * solo il primissimo istante prima che il JS giri: valore desktop reale
 * misurato via Playwright per il caso comune, non un placeholder a caso.
 * Su mobile per quell'istante il fallback risulta un po' corto (header
 * reale ~110px vs 88px), causando una minima invisibile eccedenza solo
 * nel primo frame, corretta non appena il JS imposta il valore vero.
 */
.hero-bg.is-height-full {
	min-height: calc(100svh - var(--header-height, 88px));
}

/*
 * Con l'overlay attivo l'header non occupa spazio nel flusso (vedi
 * "body:has(.hero-bg--header-overlay) .site-header" più sotto), quindi
 * l'hero torna a coprire l'intero schermo. Specificità a 3 classi (0,3,0),
 * vince senza bisogno di !important sulla regola sopra (0,2,0).
 */
.hero-bg.is-height-full.hero-bg--header-overlay {
	min-height: 100svh;
}

.hero-bg.is-height-large {
	min-height: 85svh;
}

.hero-bg.is-height-medium {
	min-height: 60svh;
}

.hero-bg.is-height-compact {
	min-height: 40svh;
}

.hero-bg.is-height-custom {
	min-height: var(--hero-custom-height, 100svh);
}

.hero-bg__media {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.hero-bg__slider {
	position: absolute;
	inset: 0;
}

/*
 * Base (= transizione "fade", il default): crossfade puro via opacity.
 * "hero-bg-slider--slide" e "hero-bg-slider--zoom" più sotto sovrascrivono
 * mirror selettivamente quello che serve, quindi questa resta anche la loro
 * base condivisa (es. il crossfade opacity di "zoom" è letteralmente questa
 * stessa regola, invariata). will-change forza il compositing GPU della sola
 * proprietà che anima; translateZ(0) + backface-visibility:hidden sono
 * un'ulteriore spinta alla promozione a layer indipendente — will-change da
 * solo non è sempre sufficiente cross-browser per garantire che il
 * compositor tratti la slide come layer stabile, e senza layer dedicato il
 * crossfade può risultare a scatti anche con la sola transition su opacity.
 */
.hero-bg__slide {
	position: absolute;
	inset: 0;
	opacity: 0;
	transition: opacity 0.8s ease-in-out;
	will-change: opacity;
	transform: translateZ(0);
	backface-visibility: hidden;
}

.hero-bg__slide.is-active {
	opacity: 1;
}

/*
 * Variante "slide": nessun crossfade, la posizione orizzontale è l'unico
 * segnale di cambio. Tre stati (non solo is-active/assente) perché la slide
 * appena uscita deve fermarsi a sinistra invece di tornare subito a destra
 * col resto delle slide non ancora mostrate:
 * - default (nessuna classe): parcheggiata a destra, fuori vista
 * - is-active: al centro
 * - is-prev: appena uscita, parcheggiata a sinistra
 * Entrambi i parcheggi sono fuori dall'area visibile (".hero-bg" ha
 * overflow:hidden), quindi il "reset" di una ex is-prev tornata default
 * (gestito da hero-slider.js ad ogni nuovo giro) è invisibile.
 *
 * translateZ(0) va combinato nella STESSA funzione transform di translateX
 * (non una dichiarazione transform separata, che sovrascriverebbe l'altra):
 * ogni stato porta quindi anche la propria promozione a layer.
 */
.hero-bg-slider--slide .hero-bg__slide {
	opacity: 1;
	transform: translateX(100%) translateZ(0);
	transition: transform 0.8s ease-in-out;
	will-change: transform;
	backface-visibility: hidden;
}

.hero-bg-slider--slide .hero-bg__slide.is-active {
	transform: translateX(0) translateZ(0);
}

.hero-bg-slider--slide .hero-bg__slide.is-prev {
	transform: translateX(-100%) translateZ(0);
}

/*
 * Variante "zoom" (Ken Burns leggero): stesso crossfade opacity della base
 * (nessuna regola aggiuntiva per opacity/is-active, eredita quella sopra),
 * più uno scale(1)→scale(1.08) sulla sola immagine attiva, per tutta la sua
 * durata di visualizzazione — durata presa da --hero-slider-interval
 * (custom property impostata inline da render.php sullo stesso valore in
 * secondi di data-interval, che governa l'autoplay in hero-slider.js).
 * Stessa combinazione scale()+translateZ(0) nella stessa funzione transform
 * per la promozione a layer indipendente.
 */
.hero-bg-slider--zoom .hero-bg__media {
	transform: scale(1) translateZ(0);
	transition: transform var(--hero-slider-interval, 6s) linear;
	will-change: transform;
	backface-visibility: hidden;
}

.hero-bg-slider--zoom .hero-bg__slide.is-active .hero-bg__media {
	transform: scale(1.08) translateZ(0);
}

/*
 * Ken Burns leggero per l'immagine di sfondo SINGOLA (backgroundType
 * "image", il caso più comune, es. hero-search.php di default): scale +
 * pan minimi, ease-in-out, "alternate" così il loop non ha mai un salto
 * secco a fine ciclo (torna indietro con la stessa easing con cui è
 * andato avanti, invece di un reset istantaneo come farebbe un
 * @keyframes "normal infinite"). Durata lenta (28s) per restare "in
 * sottofondo" e non competere con testo/CTA dell'hero — coerente col mood
 * "warm minimal" di skin-terra, dove il movimento deve suggerire
 * "vista che scorre nel paesaggio", non un effetto vistoso. Scoperto solo
 * a ".is-type-image" apposta: slider e video hanno già un proprio
 * movimento (".hero-bg-slider--zoom", <video autoplay>) e sommare questo
 * loop anche lì darebbe un doppio movimento scoordinato.
 */
.hero-bg.is-type-image .hero-bg__media {
	animation: hero-ken-burns 28s ease-in-out infinite alternate;
	will-change: transform;
	backface-visibility: hidden;
}

@keyframes hero-ken-burns {
	from {
		transform: scale(1) translate(0, 0) translateZ(0);
	}
	to {
		transform: scale(1.07) translate(-1.5%, -1%) translateZ(0);
	}
}

/*
 * Fallback video: nascosto di default, mostrato al posto di ".hero-bg__video"
 * quando è attiva "riduci animazioni" — non rilevabile lato server, quindi
 * gestito qui via media query (vedi anche render.php, che su mobile non
 * emette mai il tag <video>, solo questo stesso poster).
 */
.hero-bg__video-fallback {
	display: none;
}

/*
 * I selettori qui ripetono quelli delle varianti "slide"/"zoom" sopra (stessa
 * specificità, in un blocco che nel foglio viene dopo) apposta: senza questo
 * abbinamento la regola generica ".hero-bg__slide { transition:none }" non
 * vincerebbe su quelle più specifiche e le transizioni resterebbero attive
 * con "riduci animazioni". Nessun !important: solo ordine + specificità.
 */
@media (prefers-reduced-motion: reduce) {
	.hero-bg__slide,
	.hero-bg-slider--slide .hero-bg__slide {
		transition: none;
	}

	.hero-bg-slider--zoom .hero-bg__media {
		transition: none;
		transform: none;
	}

	.hero-bg.is-type-image .hero-bg__media {
		animation: none;
	}

	.hero-bg__video {
		display: none;
	}

	.hero-bg__video-fallback {
		display: block;
	}
}

.hero-bg__overlay {
	position: absolute;
	inset: 0;
	z-index: 1;
}

/*
 * position:absolute + inset:0 (non più width/min-height percentuali dentro
 * un genitore flex): il box di questo layer deve essere identico e
 * deterministico indipendentemente da backgroundType/heightVariant, cosa che
 * "width:100%"/"min-height:100%" dentro un ".hero-bg" flex con solo
 * min-height (mai height) non garantivano in modo affidabile. Il proprio
 * layout interno (eyebrow/titolo/widget in basso a sinistra) resta gestito
 * dal flex qui sotto, che riguarda solo i SUOI figli.
 *
 * pointer-events:none: questo layer copre l'intera area (anche dove
 * trasparente) e sta sopra i dot dello slider nello stacking — senza
 * disattivare qui i click, intercetterebbe quelli diretti ai dot prima che
 * arrivino ai loro <button>. Riattivato subito sotto solo sul widget di
 * ricerca, l'unico contenuto realmente interattivo.
 */
.hero-bg__inner {
	position: absolute;
	inset: 0;
	z-index: 2;
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	justify-content: flex-end;
	padding: var(--wp--preset--spacing--8);
	pointer-events: none;
}

.hero-bg__inner .hero-search__widget {
	pointer-events: auto;
}

@media (max-width: 1023px) {
	.hero-bg__inner {
		padding: var(--wp--preset--spacing--6);
	}
}

@media (max-width: 767px) {
	.hero-bg__inner {
		padding: var(--wp--preset--spacing--5);
	}
}

/*
 * Dot di navigazione dello slider, generati da assets/js/hero-slider.js come
 * figli diretti di ".hero-bg" (non di ".hero-bg__slider"): appesi in coda,
 * dopo ".hero-bg__inner" nel DOM, e con uno z-index esplicitamente più alto
 * — doppia garanzia (ordine + specificità) che restino sempre sopra al layer
 * di contenuto invece di finirci sotto per un pareggio di stacking.
 * (Assenti finché il JS non gira, quindi assenti anche con "riduci
 * animazioni" attivo — coerente con l'autoplay disattivato in quel caso.)
 */
.hero-bg__slider-dots {
	position: absolute;
	z-index: 3;
	bottom: 24px;
	left: 50%;
	transform: translateX(-50%);
	display: flex;
	gap: var(--wp--preset--spacing--2);
}

.hero-bg__slider-dot {
	width: 8px;
	height: 8px;
	border-radius: 100px;
	border: 1px solid var(--wp--preset--color--white);
	background: transparent;
	padding: 0;
	cursor: pointer;
}

.hero-bg__slider-dot.is-active {
	background: var(--wp--preset--color--white);
}

/*
 * Editor: anteprima dei controlli Inspector aggiuntivi del blocco
 * (elenco immagini slider), stesso schema minimale di
 * editor-experience-card.css.
 */
.hero-bg-edit__slider-list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-wrap: wrap;
	gap: var(--wp--preset--spacing--2);
}

.hero-bg-edit__slider-item {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 4px;
}

.hero-bg-edit__slider-item img {
	width: 64px;
	height: 64px;
	object-fit: cover;
	border-radius: var(--vik-radius);
}

/* -----------------------------------------------------------
   hero-search — variante "Pannello laterale" (hero-search--split-panel)
   ----------------------------------------------------------- */
.hero-split-panel {
	display: grid;
	grid-template-columns: 1fr;
	min-height: 100svh;
}

@media (min-width: 1024px) {
	.hero-split-panel {
		grid-template-columns: 58% 1fr;
	}
}

.hero-split-panel__image {
	margin: 0;
	min-height: 320px;
}

.hero-split-panel__image img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/*
 * .hero-split-panel__form riempie l'intera colonna 1fr della griglia (altezza
 * e larghezza), portando con sé lo sfondo bianco fino ai bordi della colonna.
 * Il max-width per la leggibilità del contenuto vive invece su
 * .hero-split-panel__form-inner: prima erano sulla stessa regola, quindi lo
 * sfondo bianco si fermava a 440px lasciando visibile lo sfondo pagina ai
 * lati del form, disallineato rispetto all'immagine.
 *
 * margin:0 — .hero-split-panel ha la classe core "is-layout-flow" (layout
 * di default del blocco Group), che applica margin-block-start agli
 * elementi figli successivi al primo (qui il form, secondo figlio dopo
 * l'immagine) indipendentemente dal fatto che qui il contenitore sia in
 * realtà display:grid. Senza l'azzeramento esplicito il form parte 24px
 * più in basso dell'immagine, creando uno scalino visibile in alto.
 */
.hero-split-panel__form {
	display: flex;
	flex-direction: column;
	justify-content: center;
	margin: 0;
	background-color: var(--wp--preset--color--white);
}

.hero-split-panel__form-inner {
	width: 100%;
	max-width: 440px;
	margin-inline: auto;
	padding: var(--wp--preset--spacing--8) var(--wp--preset--spacing--6);
}

.hero-split-panel__eyebrow {
	margin-bottom: var(--wp--preset--spacing--3);
}

.hero-split-panel__title {
	margin: 0 0 var(--wp--preset--spacing--6);
	color: var(--wp--preset--color--ink);
	font-family: var(--wp--preset--font-family--display);
	font-size: var(--wp--preset--font-size--xl);
	font-weight: 400;
}

.hero-split-panel__widget:empty::before {
	content: "Configura qui il widget VikBooking \"Search Form\" dall'editor.";
	display: block;
	color: var(--wp--preset--color--text-soft);
	font-size: var(--wp--preset--font-size--sm);
	text-align: center;
}

.hero-split-panel__note {
	margin: var(--wp--preset--spacing--4) 0 0;
	color: var(--wp--preset--color--text-soft);
	font-size: var(--wp--preset--font-size--xs);
	text-align: center;
}

/* -----------------------------------------------------------
   hero-search — variante "Immersivo centrato"
   (hero-search--immersive-centered)
   ----------------------------------------------------------- */
/*
 * align-items:stretch — WP imposta di default align-items:flex-start su
 * .wp-block-cover per contentPosition "top" (qui "top center"): l'inner-
 * container resta alto quanto il proprio contenuto invece di riempire il
 * Cover. Senza questo override ".hero-immersive__bar { bottom: 0 }" si
 * ancora al fondo di quel contenitore corto, sovrapponendosi alla headline
 * invece che restare in fondo all'immagine. Con stretch l'inner-container
 * riempie tutta l'altezza del Cover; il contenuto resta comunque in alto
 * perché ".hero-immersive__content" è il suo primo figlio in normal flow.
 */
.wp-block-cover.hero-immersive {
	/* Specificità a 2 classi: deve pareggiare (e vincere per ordine di
	   caricamento, essendo dopo) la regola core ".wp-block-cover.is-
	   position-top-center { align-items: flex-start; }", altrimenti un
	   singolo ".hero-immersive" da solo perde il confronto. */
	align-items: stretch;
}

.hero-immersive .wp-block-cover__inner-container {
	padding-top: var(--wp--preset--spacing--8);
}

.hero-immersive__content {
	max-width: 900px;
	text-align: center;
}

.hero-immersive__eyebrow {
	color: var(--wp--preset--color--white);
	opacity: 0.85;
}

.hero-immersive__title {
	margin: 0;
	color: var(--wp--preset--color--white);
	font-family: var(--wp--preset--font-family--display);
	font-size: clamp(2.5rem, 1.8rem + 3vw, 4rem);
	font-weight: 400;
	line-height: 1.25;
}

.hero-immersive__title em {
	font-style: italic;
}

/*
 * position:relative + isolation:isolate + ::before invece di background-
 * color/backdrop-filter diretti sull'elemento: il popover "Ospiti" dentro
 * al widget (.vbo-horizsearch-guests-panel, position:fixed con coordinate
 * calcolate via JS in vikbooking-dom.js) deve posizionarsi rispetto al
 * viewport. Un backdrop-filter (o transform/filter/will-change) su un
 * qualunque antenato crea invece un nuovo containing block per i
 * discendenti fixed: le coordinate calcolate da getBoundingClientRect()
 * (sempre relative al viewport) finiscono applicate rispetto al box di
 * quell'antenato, e il pannello compare centinaia di pixel fuori posto
 * (verificato in browser: pannello renderizzato a top:1305px invece di
 * ~700px). Spostando il blur su uno pseudo-elemento decorativo, ".hero-
 * immersive__bar" stessa non ha più backdrop-filter e il popover torna a
 * posizionarsi correttamente. isolation:isolate confina lo z-index
 * negativo dello pseudo-elemento dentro il proprio stacking context,
 * cosi non interferisce con fratelli/antenati.
 */
.hero-immersive__bar {
	position: relative;
	isolation: isolate;
	margin-top: var(--wp--preset--spacing--6);
	padding: var(--wp--preset--spacing--5) var(--wp--preset--spacing--6);
	max-width: 1200px;
	margin: 0 auto;
}

.hero-immersive__bar::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	background-color: var(--vik-overlay-dark);
	backdrop-filter: blur(10px);
	-webkit-backdrop-filter: blur(10px);
	pointer-events: none;
}

/* Reset esplicito: il testo placeholder resta in flusso normale, non deve
   ereditare position/z-index/sfondo dallo pseudo-elemento sopra. */
.hero-immersive__bar:empty::before {
	content: "Configura qui il widget VikBooking \"Search Form\" dall'editor.";
	position: static;
	z-index: auto;
	display: block;
	background: none;
	backdrop-filter: none;
	-webkit-backdrop-filter: none;
	color: var(--wp--preset--color--white);
	font-size: var(--wp--preset--font-size--sm);
	text-align: center;
	opacity: 0.8;
}

@media (min-width: 768px) {
	/* Sotto i 768px il widget impila i campi in colonna (vedi
	   vikbooking-overrides.css) e diventa più alto della barra: lasciata
	   in flusso normale sotto la headline invece che ancorata in basso,
	   altrimenti si sovrapporrebbe al testo sopra. Da tablet in su i campi
	   stanno su una riga sola e la barra può ancorarsi al bordo dell'immagine. */
	.hero-immersive__bar {
		position: absolute;
		left: 0;
		right: 0;
		bottom: 0;
		margin-top: 0;
	}
}

.hero-trust-row {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: var(--wp--preset--spacing--2) var(--wp--preset--spacing--6);
	padding: var(--wp--preset--spacing--4) var(--wp--preset--spacing--6);
	background-color: var(--wp--preset--color--background);
	border-bottom: 1px solid var(--wp--preset--color--line);
}

.hero-trust-row__item {
	margin: 0;
	color: var(--wp--preset--color--text-soft);
	font-size: var(--wp--preset--font-size--xs);
	letter-spacing: 0.02em;
}

.hero-trust-row__stars {
	color: var(--wp--preset--color--accent);
	letter-spacing: 0.1em;
}

/* -----------------------------------------------------------
   hero-search — variante "Form protagonista"
   (hero-search--form-protagonist)
   ----------------------------------------------------------- */
.hero-form-protagonist .wp-block-cover__inner-container {
	padding-top: var(--wp--preset--spacing--9);
}

.hero-form-protagonist__content {
	max-width: 760px;
	text-align: center;
}

.hero-form-protagonist__eyebrow {
	color: var(--wp--preset--color--white);
	opacity: 0.85;
}

.hero-form-protagonist__title {
	margin: 0;
	color: var(--wp--preset--color--white);
	font-family: var(--wp--preset--font-family--display);
	font-size: clamp(2rem, 1.6rem + 2vw, 3rem);
	font-weight: 400;
	line-height: 1.3;
}

.hero-form-protagonist__title em {
	font-style: italic;
}

.hero-form-protagonist__deco {
	display: block;
	width: 40px;
	height: 1px;
	margin: var(--wp--preset--spacing--5) auto 0;
	background-color: var(--wp--preset--color--accent);
}

/* Stesso motivo di ".hero-immersive__bar" sopra: backdrop-filter spostato
   su uno pseudo-elemento cosi il popover "Ospiti" (position:fixed) non
   erediti un containing block da questo antenato. */
.hero-form-protagonist__card {
	position: relative;
	isolation: isolate;
	width: 100%;
	max-width: 600px;
	margin: var(--wp--preset--spacing--7) auto 0;
	padding: var(--wp--preset--spacing--6);
	border-radius: var(--vik-radius);
}

.hero-form-protagonist__card::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	border-radius: inherit;
	background-color: var(--vik-overlay-dark);
	backdrop-filter: blur(10px);
	-webkit-backdrop-filter: blur(10px);
	pointer-events: none;
}

.hero-form-protagonist__card:empty::before {
	content: "Configura qui il widget VikBooking \"Search Form\" dall'editor.";
	position: static;
	z-index: auto;
	display: block;
	background: none;
	backdrop-filter: none;
	-webkit-backdrop-filter: none;
	color: var(--wp--preset--color--white);
	font-size: var(--wp--preset--font-size--sm);
	text-align: center;
	opacity: 0.8;
}

/* -----------------------------------------------------------
   trust-bar
   ----------------------------------------------------------- */
/* Ogni ".trust-bar__item" è a sua volta un blocco Group con
   "layout":{"type":"flex"} (default core "flexWrap":"wrap"): senza
   "nowrap" qui, quando il testo più lungo ("9.4 su Booking.com — 187
   recensioni") non ci stava più sulla stessa riga delle stelle,
   l'item andava a capo internamente, stelle ed testo separati su due
   righe diverse. "nowrap" da solo però non basta a evitare che quel
   secondo item, da solo sulla propria riga dentro ".trust-bar"
   (flex-wrap:wrap, justify-content:center), si allarghi fino a
   riempire l'intera riga anziché restare stretto attorno al proprio
   contenuto (comportamento flexbox non risolto da "min-width:0" né da
   "flex:0 1 auto", verificato dal vivo) — il testo finiva così a
   toccare il bordo sinistro reale dello schermo su mobile. Il padding
   orizzontale su ".trust-bar" poco sotto è la rete di sicurezza che
   risolve il sintomo indipendentemente dalla causa esatta dentro al
   motore flex del browser. */
/* "display: flex" e "line-height: normal" esplicitamente per la voce
   dinamica vik-base/trust-item (inc/trust-bar.php), che non è un Group
   e quindi non riceve né la classe "is-layout-flex" né la regola
   sull'interlinea dei paragrafi della trust bar più in alto nel file. */
.trust-bar__item {
	display: flex;
	line-height: normal;
	align-items: center;
	flex-wrap: nowrap;
	gap: var(--wp--preset--spacing--2);
}

.trust-bar__stars {
	display: inline-flex;
	align-items: center;
	color: var(--wp--preset--color--accent);
	font-size: var(--wp--preset--font-size--md);
	line-height: 1;
	letter-spacing: 0.1em;
}

.trust-bar__item strong {
	font-size: var(--wp--preset--font-size--md);
	font-weight: 600;
	color: var(--wp--preset--color--ink);
}

.trust-bar__badge {
	padding: var(--wp--preset--spacing--1) var(--wp--preset--spacing--3);
	background-color: var(--wp--preset--color--background-alt);
	border-radius: 100px;
	font-size: var(--wp--preset--font-size--xs);
	line-height: normal;
}

/* -----------------------------------------------------------
   rooms-grid / rooms-carousel / rooms-list — comune
   ----------------------------------------------------------- */
.rooms-grid__widget:not(:empty),
.rooms-carousel__widget:not(:empty),
.rooms-list__widget:not(:empty) {
	margin-bottom: var(--wp--preset--spacing--6);
	max-width: 1200px;
}

/*
 * Demo statica camere (rooms-grid__demo / rooms-carousel__demo) e relativo
 * avviso: inc/vikbooking-rooms-reorg.php nasconde la demo lato front-end
 * solo quando il widget "Rooms List" che la precede ha già restituito
 * camere reali nella STESSA request — vero per il rendering di pagina
 * pubblico, mai per il canvas del Site Editor, dove quel widget viene
 * renderizzato in isolamento tramite ServerSideRender (nessuna richiesta
 * condivisa in cui il flag possa propagarsi). Lì la demo va quindi nascosta
 * sempre — non è verificabile se esistano camere reali — a favore di un
 * avviso testuale (".rooms-grid__editor-notice" / "...__editor-notice"),
 * stesso meccanismo già usato per ".vikbooking-packages__editor-notice":
 * markup sempre presente nel pattern, invertito in visibilità qui.
 */
.editor-styles-wrapper .rooms-grid__demo,
.editor-styles-wrapper .rooms-carousel__demo,
.editor-styles-wrapper .rooms-list__demo {
	display: none;
}

.rooms-grid__editor-notice,
.rooms-carousel__editor-notice,
.rooms-list__editor-notice {
	display: none;
	margin: 0;
	padding: var(--wp--preset--spacing--3) var(--wp--preset--spacing--4);
	background-color: #fdf2d0;
	border: 1px solid #e3c766;
	border-radius: var(--vik-radius);
	color: var(--wp--preset--color--text);
	font-size: var(--wp--preset--font-size--sm);
}

.editor-styles-wrapper .rooms-grid__editor-notice,
.editor-styles-wrapper .rooms-carousel__editor-notice,
.editor-styles-wrapper .rooms-list__editor-notice {
	display: block;
}

.room-card__tag {
	display: block;
	margin: var(--wp--preset--spacing--4) var(--wp--preset--spacing--4) var(--wp--preset--spacing--2);
	color: var(--wp--preset--color--text-soft);
	font-size: var(--wp--preset--font-size--xs);
	letter-spacing: 0.05em;
	text-transform: uppercase;
}

/* -----------------------------------------------------------
   Titoli sezione camere — H2 a due righe, seconda in corsivo soft
   ----------------------------------------------------------- */
.rooms-grid .section-head h2,
.rooms-carousel .section-head h2 {
	font-family: var(--wp--preset--font-family--display);
	font-size: 52px;
	font-weight: 400;
	line-height: 1.1;
}

.rooms-grid .section-head h2 em,
.rooms-carousel .section-head h2 em {
	display: block;
	font-style: italic;
	color: var(--wp--preset--color--text-soft);
}

/* -----------------------------------------------------------
   rooms-grid — variante Overlay (griglia 3 colonne)
   ----------------------------------------------------------- */
.room-overlay-grid {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--vik-grid-gap);
}

@media (min-width: 768px) {
	.room-overlay-grid {
		grid-template-columns: repeat(2, 1fr);
	}
}

@media (min-width: 1024px) {
	.room-overlay-grid {
		/* --room-overlay-cols è impostata inline da vik_base_render_rooms_overlay()
		   in base al campo "Rooms per row" del widget VikBooking; 3 è il fallback
		   per la demo statica, dove non esiste alcun widget da leggere. */
		grid-template-columns: repeat(var(--room-overlay-cols, 3), 1fr);
	}
}

.room-overlay-card {
	position: relative;
	aspect-ratio: 3 / 4;
	overflow: hidden;
	border-radius: var(--vik-radius);
}

.room-overlay-card__image {
	position: absolute;
	inset: 0;
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.room-overlay-card::after {
	content: "";
	position: absolute;
	inset: 0;
	background: linear-gradient(180deg, rgba(20, 16, 12, 0) 45%, rgba(20, 16, 12, 0.75) 100%);
	pointer-events: none;
}

.room-badge-price {
	position: absolute;
	top: 0;
	right: 0;
	z-index: 2;
	padding: var(--wp--preset--spacing--3) var(--wp--preset--spacing--4);
	background-color: rgba(20, 16, 12, 0.55);
	backdrop-filter: blur(10px);
	-webkit-backdrop-filter: blur(10px);
	border-radius: 0 0 0 var(--vik-radius);
	text-align: right;
}

.room-badge-price.hidden {
	display: none;
}

.room-badge-price .from,
.room-badge-price .price-night {
	color: var(--wp--preset--color--white);
	font-size: 9px;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	opacity: 0.7;
}

.room-badge-price .price-main {
	margin: 2px 0;
	color: var(--wp--preset--color--white);
	font-family: var(--wp--preset--font-family--display);
	font-size: 28px;
}

.room-overlay-content {
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	z-index: 2;
	padding: var(--wp--preset--spacing--5);
}

.room-overlay-category {
	margin: 0 0 var(--wp--preset--spacing--1);
	color: var(--vik-overlay-ivory);
	font-style: italic;
	font-size: var(--wp--preset--font-size--sm);
}

.room-overlay-name {
	margin: 0 0 var(--wp--preset--spacing--2);
	color: var(--wp--preset--color--white);
	font-family: var(--wp--preset--font-family--display);
	font-size: 28px;
	font-weight: 500;
}

.room-overlay-sleeps {
	margin: 0;
	color: var(--wp--preset--color--white);
	font-size: 10px;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	opacity: 0.85;
}

.room-overlay-deco {
	display: block;
	width: 32px;
	height: 1px;
	margin: var(--wp--preset--spacing--3) 0;
	background-color: rgba(255, 255, 255, 0.4);
}

.room-overlay-cta {
	position: absolute;
	right: var(--wp--preset--spacing--5);
	bottom: var(--wp--preset--spacing--5);
	z-index: 2;
	padding: var(--wp--preset--spacing--2) var(--wp--preset--spacing--4);
	background-color: var(--wp--preset--color--accent);
	border-radius: var(--vik-radius);
	color: var(--wp--preset--color--white);
	font-size: var(--wp--preset--font-size--sm);
	text-decoration: none;
	opacity: 0;
	transform: translateY(6px);
	transition: opacity 0.2s ease, transform 0.2s ease, background-color 0.2s ease;
}

.room-overlay-card:hover .room-overlay-cta,
.room-overlay-card:focus-within .room-overlay-cta {
	opacity: 1;
	transform: translateY(0);
}

.room-overlay-cta:hover {
	background-color: var(--wp--preset--color--accent-dark);
}

/* -----------------------------------------------------------
   amenities con etichetta — condivise tra variante Overlay e
   variante Carosello split (colori diversi per contesto chiaro/scuro)
   ----------------------------------------------------------- */
.room-overlay-amenities,
.room-split-amenities {
	display: flex;
	gap: var(--wp--preset--spacing--4);
}

.room-overlay-amenities:empty,
.room-split-amenities:empty {
	display: none;
}

.room-overlay-amenities .amen,
.room-split-amenities .amen {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--wp--preset--spacing--1);
}

.room-overlay-amenities .ico svg {
	width: 18px;
	height: 18px;
	color: var(--wp--preset--color--white);
}

.room-overlay-amenities .lbl {
	color: var(--wp--preset--color--white);
	font-size: 9px;
	letter-spacing: 0.05em;
	text-transform: uppercase;
	opacity: 0.85;
}

.room-split-amenities .ico svg {
	width: 18px;
	height: 18px;
	color: var(--wp--preset--color--accent);
}

.room-split-amenities .lbl {
	color: var(--wp--preset--color--text-soft);
	font-size: 9px;
	letter-spacing: 0.05em;
	text-transform: uppercase;
}

/* -----------------------------------------------------------
   rooms-carousel — variante Carosello split
   ----------------------------------------------------------- */
.room-carousel-track {
	display: flex;
	overflow-x: auto;
	scroll-snap-type: x mandatory;
	scroll-behavior: smooth;
	-webkit-overflow-scrolling: touch;
}

.room-card-split {
	flex: 0 0 100%;
	display: grid;
	grid-template-columns: 1fr;
	min-height: 400px;
	scroll-snap-align: start;
	background-color: var(--wp--preset--color--white);
	border: 1px solid var(--wp--preset--color--line);
	border-radius: var(--vik-radius);
	overflow: hidden;
}

@media (min-width: 768px) {
	.room-card-split {
		grid-template-columns: 54% 1fr;
		max-height: 460px;
	}
}

.room-split-image-col {
	position: relative;
}

.room-split-image-col img {
	display: block;
	width: 100%;
	height: 100%;
	min-height: 260px;
	object-fit: cover;
}

.room-split-sleeps-badge {
	position: absolute;
	left: var(--wp--preset--spacing--3);
	bottom: var(--wp--preset--spacing--3);
	display: inline-flex;
	align-items: center;
	gap: var(--wp--preset--spacing--1);
	padding: var(--wp--preset--spacing--2) var(--wp--preset--spacing--3);
	background-color: rgba(20, 16, 12, 0.55);
	backdrop-filter: blur(10px);
	-webkit-backdrop-filter: blur(10px);
	border-radius: 100px;
	color: var(--wp--preset--color--white);
	font-size: var(--wp--preset--font-size--xs);
}

.room-split-sleeps-badge::before {
	content: "\2191";
}

.room-split-info {
	position: relative;
	display: flex;
	flex-direction: column;
	padding: var(--wp--preset--spacing--7);
}

.room-split-deco {
	position: absolute;
	top: var(--wp--preset--spacing--6);
	right: var(--wp--preset--spacing--6);
	width: 40px;
	height: 1px;
	background-color: var(--wp--preset--color--accent);
}

.room-split-category {
	margin: 0 0 var(--wp--preset--spacing--2);
	color: var(--wp--preset--color--accent);
	font-style: italic;
	font-size: var(--wp--preset--font-size--sm);
}

.room-split-name {
	margin: 0;
	font-family: var(--wp--preset--font-family--display);
	font-size: 30px;
	font-weight: 500;
}

.room-split-name-divider {
	display: block;
	width: 28px;
	height: 1px;
	margin: var(--wp--preset--spacing--3) 0 var(--wp--preset--spacing--4);
	background-color: var(--wp--preset--color--accent);
}

.room-split-description {
	margin: 0 0 var(--wp--preset--spacing--4);
	color: var(--wp--preset--color--text-soft);
	font-size: var(--wp--preset--font-size--sm);
	line-height: 1.4em;
}

.room-split-amenities {
	margin-bottom: var(--wp--preset--spacing--4);
}

.room-split-footer {
	display: flex;
	align-items: flex-end;
	justify-content: space-between;
	margin-top: auto;
	padding-top: var(--wp--preset--spacing--4);
	border-top: 1px solid var(--wp--preset--color--line);
}

.room-split-price {
	display: flex;
	align-items: baseline;
	gap: var(--wp--preset--spacing--1);
	margin: 0;
	/*
	 * Fallback per il prezzo del widget VikBooking reale (inc/vikbooking-rooms-reorg.php),
	 * ridotto a solo testo — non ha la struttura <span class="cur/amount/unit">
	 * della demo statica sotto, che comunque continua ad applicarsi quando presente
	 * (regole più specifiche subito sotto).
	 */
	font-family: var(--wp--preset--font-family--display);
	font-variant-numeric: lining-nums;
	font-size: 28px;
	color: var(--wp--preset--color--accent);
}

.room-split-price .cur {
	color: var(--wp--preset--color--text-soft);
	font-size: 13px;
}

.room-split-price .amount {
	color: var(--wp--preset--color--accent);
	font-family: var(--wp--preset--font-family--display);
	font-variant-numeric: lining-nums;
	font-size: 42px;
}

.room-split-price .unit {
	color: var(--wp--preset--color--text-soft);
	font-size: 10px;
}

.room-split-cta {
	padding: var(--wp--preset--spacing--3) var(--wp--preset--spacing--5);
	background-color: var(--wp--preset--color--accent);
	border-radius: var(--vik-radius);
	color: var(--wp--preset--color--white);
	font-size: var(--wp--preset--font-size--sm);
	text-decoration: none;
	transition: background-color 0.2s ease;
}

.room-split-cta:hover {
	background-color: var(--wp--preset--color--accent-dark);
}

.room-carousel-footer {
	display: flex;
	align-items: center;
	justify-content: space-between;
	margin-top: var(--wp--preset--spacing--5);
}

.room-carousel-counter {
	font-family: var(--wp--preset--font-family--display);
	font-variant-numeric: lining-nums;
	font-size: var(--wp--preset--font-size--lg);
	color: var(--wp--preset--color--text-soft);
}

.room-carousel-nav {
	display: flex;
	gap: var(--wp--preset--spacing--2);
}

.room-carousel-arrow {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 42px;
	height: 42px;
	border: 1px solid var(--wp--preset--color--line);
	border-radius: 100px;
	background: none;
	color: var(--wp--preset--color--ink);
	font-size: var(--wp--preset--font-size--lg);
	cursor: pointer;
	transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease;
}

.room-carousel-arrow:hover,
.room-carousel-arrow.is-active {
	background-color: var(--wp--preset--color--accent);
	border-color: var(--wp--preset--color--accent);
	color: var(--wp--preset--color--white);
}

/* -----------------------------------------------------------
   rooms-list — variante Righe alternate: una card ".room-card-split"
   (stessa card/stile della variante Carosello split più sopra, vedi
   ".room-card-split"/".room-split-*") per riga, immagine a sinistra/destra
   alternata riga per riga. Su mobile nessun "order" viene impostato, quindi
   l'immagine resta sempre il primo figlio DOM di ".room-card-split" — stack
   verticale immagine-sopra-contenuto-sotto automatico, senza media query
   dedicata.
   ----------------------------------------------------------- */
.room-list-rows {
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--6);
}

@media (min-width: 768px) {
	.room-list-row.is-reverse .room-card-split {
		grid-template-columns: 1fr 54%;
	}

	.room-list-row.is-reverse .room-split-image-col {
		order: 2;
	}

	.room-list-row.is-reverse .room-split-info {
		order: 1;
	}
}

/* -----------------------------------------------------------
   experiences-carousel — track scorrevole. Contenuto dentro un wrapper
   allineato (non più a bordo pieno): le card sono blocchi
   vik-base/experience-card, non più markup grezzo — vedi
   patterns/experiences-carousel.php per la struttura e
   ".wp-block-vik-base-experience-card"/".experience-card--style-light"
   più sotto per l'aspetto della card in sé.
   ----------------------------------------------------------- */
.experiences-carousel__track {
	display: flex;
	gap: var(--wp--preset--spacing--4);
	overflow-x: auto;
	scroll-snap-type: x mandatory;
	scroll-behavior: smooth;
	-webkit-overflow-scrolling: touch;
}

/*
 * Dimensione da carosello: solo quando la card è dentro questo track
 * (selettore scoped al genitore diretto, stesso principio di
 * ".experiences-dark__track" più sotto — vedi lì per i commenti estesi
 * su "--vik-carousel-visible" e "margin-block-start"). "2 visibili" di
 * default per questo pattern (attributo "vikVisibleCards" sul Group in
 * patterns/experiences-carousel.php), modificabile dal pannello
 * "Carosello" dell'Inspector — stesso motore di experiences-dark.php,
 * un'unica implementazione condivisa in inc/carousel-track.php.
 */
.experiences-carousel__track > .wp-block-vik-base-experience-card {
	flex: 0 0 84%;
	margin-block-start: 0;
	scroll-snap-align: start;
}

@media (min-width: 768px) {
	.experiences-carousel__track > .wp-block-vik-base-experience-card {
		flex: 0 0 calc( ( 100% - ( var( --vik-carousel-visible, 2 ) - 1 ) * var( --wp--preset--spacing--4 ) ) / var( --vik-carousel-visible, 2 ) );
	}

	.experiences-carousel__track > .wp-block-vik-base-experience-card.is-featured {
		flex-basis: calc( ( ( 100% - ( var( --vik-carousel-visible, 2 ) - 1 ) * var( --wp--preset--spacing--4 ) ) / var( --vik-carousel-visible, 2 ) ) * 1.08 );
	}
}

.experiences-carousel__nav {
	display: flex;
	justify-content: flex-end;
	gap: var(--wp--preset--spacing--2);
	margin-top: var(--wp--preset--spacing--4);
	margin-right: var(--wp--preset--spacing--4);
}

.experiences-carousel__arrow {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	border: 1px solid var(--wp--preset--color--text-soft);
	border-radius: 100px;
	background-color: var(--wp--preset--color--background-alt);
	color: var(--wp--preset--color--ink);
	font-size: var(--wp--preset--font-size--lg);
	cursor: pointer;
	transition: background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease;
}

.experiences-carousel__arrow:hover {
	background-color: var(--wp--preset--color--accent);
	color: var(--wp--preset--color--white);
}

/* -----------------------------------------------------------
   experiences-dark — variante scura, 3 slide interamente
   visibili (nessuna "sbirciata" parziale come in
   experiences-carousel). Sfondo e terracotta riusano i token
   "dark" e "accent" già in theme.json: nessun nuovo colore.
   ----------------------------------------------------------- */
.experiences-dark__head {
	display: flex;
	flex-wrap: wrap;
	align-items: flex-end;
	justify-content: space-between;
	gap: var(--wp--preset--spacing--4);
	margin-bottom: var(--wp--preset--spacing--6);
}

.experiences-dark__link a {
	color: inherit;
	font-size: var(--wp--preset--font-size--xs);
	letter-spacing: 0.08em;
	text-transform: uppercase;
	text-decoration: none;
	opacity: 0.75;
	transition: opacity 0.2s ease, color 0.2s ease;
}

.experiences-dark__link a:hover {
	color: var(--wp--preset--color--accent);
	opacity: 1;
}

.experiences-dark__track {
	display: flex;
	gap: var(--wp--preset--spacing--4);
	overflow-x: auto;
	scroll-snap-type: x mandatory;
	scroll-behavior: smooth;
	-webkit-overflow-scrolling: touch;
}

/*
 * Dimensione/comportamento da carosello: solo quando la card è dentro il
 * track di experiences-dark.php (selettore scoped al genitore diretto).
 * L'aspetto della card in sé (foto, badge, overlay…) vive invece nelle
 * regole ".wp-block-vik-base-experience-card" più sotto, così il blocco
 * resta presentabile anche fuori da questo contesto.
 *
 * "margin-block-start: 0" annulla qui lo stile globale di WordPress
 * ":root :where(.is-layout-flow) > * { margin-block-start: ... }"
 * (spaziatura verticale di default tra blocchi impilati, non definito in
 * questo tema): il Group usato come track eredita la classe
 * "is-layout-flow" di default e quello stile spostava in basso tutte le
 * card tranne la prima, disallineandole in altezza in un contenitore flex
 * orizzontale. Selettore a due classi apposta (più specifico del ":root"
 * di WordPress, 0,1,0) così vince senza bisogno di "!important" e senza
 * toccare lo stile globale, che resta intatto per il resto del tema.
 */
.experiences-dark__track > .wp-block-vik-base-experience-card {
	flex: 0 0 84%;
	height: 480px;
	margin-block-start: 0;
	scroll-snap-align: start;
}

@media (min-width: 768px) {
	.experiences-dark__track > .wp-block-vik-base-experience-card {
		flex-basis: calc(50% - var(--wp--preset--spacing--4) / 2);
		height: 520px;
	}
}

@media (min-width: 1024px) {
	/*
	 * Numero di card interamente visibili: sceglibile dal pannello
	 * "Carosello" del blocco Group/track (RangeControl 2–5, vedi
	 * assets/js/editor/carousel-visible-control.js), iniettato qui come
	 * custom property "--vik-carousel-visible" da inc/carousel-track.php
	 * — stesso meccanismo condiviso con ".experiences-carousel__track"
	 * più sopra, un solo motore per entrambi i pattern (ognuno imposta il
	 * proprio "vikVisibleCards" nel Group: 3 qui, 2 in
	 * experiences-carousel.php). Il fallback "3" copre il caso in cui il
	 * blocco non sia passato dal filtro server-side (es. anteprima dentro
	 * l'iframe dell'editor prima del primo salvataggio: lì il valore live
	 * arriva comunque via wrapperProps, stesso file JS).
	 * flex-basis fisso (non flex-grow) apposta: con più card totali di
	 * quelle visibili, le eccedenti devono restare fuori schermo e
	 * raggiungibili scorrendo, non restringersi tutte per stare a bordo.
	 */
	.experiences-dark__track > .wp-block-vik-base-experience-card {
		flex: 0 0 calc( ( 100% - ( var( --vik-carousel-visible, 3 ) - 1 ) * var( --wp--preset--spacing--4 ) ) / var( --vik-carousel-visible, 3 ) );
		height: 620px;
	}

	/*
	 * La card "in evidenza" (attributo "featured" del blocco, pannello
	 * Aspetto) è leggermente più larga delle altre — proporzione presa
	 * dallo screenshot di riferimento (~629px contro ~582px, un +8%
	 * circa). Non riduce le altre per compensare: il track scorre in
	 * orizzontale apposta, qualche pixel di scroll in più non è un problema.
	 */
	.experiences-dark__track > .wp-block-vik-base-experience-card.is-featured {
		flex-basis: calc( ( ( 100% - ( var( --vik-carousel-visible, 3 ) - 1 ) * var( --wp--preset--spacing--4 ) ) / var( --vik-carousel-visible, 3 ) ) * 1.08 );
	}
}

/* -----------------------------------------------------------
   vik-base/experience-card (blocks/experience-card/) — aspetto
   intrinseco della card: foto piena, badge categoria, overlay a
   gradiente (stile default "dark"; vedi ".experience-card--style-light"
   più sotto per la variante chiara). Riusabile in qualunque contesto, non
   solo dentro experiences-dark__track/experiences-carousel__track (da cui
   riceve solo dimensioni/scroll-snap, vedi sopra).
   ----------------------------------------------------------- */
.wp-block-vik-base-experience-card {
	position: relative;
	display: block;
	aspect-ratio: 3 / 4;
	overflow: hidden;
	border-radius: var(--vik-radius);
	color: var(--wp--preset--color--white);
}

.experience-card__image {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.experience-card__placeholder {
	position: absolute;
	inset: 0;
	height: auto;
	background-color: var(--wp--preset--color--background-alt);
}

.experience-card__badge {
	position: absolute;
	top: 0;
	left: 0;
	z-index: 2;
	padding: var(--wp--preset--spacing--2) var(--wp--preset--spacing--3);
	background-color: var(--wp--preset--color--accent);
	border-radius: 0 0 var(--vik-radius) 0;
	color: var(--wp--preset--color--white);
	font-size: var(--wp--preset--font-size--xs);
	letter-spacing: 0.05em;
	text-transform: uppercase;
}

.experience-card__badge:empty {
	display: none;
}

.experience-card__content {
	position: absolute;
	inset: 0;
	z-index: 2;
	display: flex;
	flex-direction: column;
	justify-content: flex-end;
	align-items: flex-start;
	padding: var(--wp--preset--spacing--5) var(--wp--preset--spacing--4) var(--wp--preset--spacing--4);
	background: linear-gradient(180deg, rgba(20, 16, 12, 0) 40%, rgba(20, 16, 12, 0.85) 100%);
	pointer-events: none;
}

.experience-card__content > * {
	pointer-events: auto;
}

.experience-card__title {
	margin: 0 0 var(--wp--preset--spacing--2);
	color: var(--wp--preset--color--white);
	font-family: var(--wp--preset--font-family--display);
	font-size: var(--wp--preset--font-size--lg);
	line-height: 1.15;
}

.experience-card__text {
	margin: 0 0 var(--wp--preset--spacing--3);
	color: rgba(255, 255, 255, 0.75);
	font-size: var(--wp--preset--font-size--sm);
	line-height: 1.5;
}

.experience-card__cta {
	color: var(--wp--preset--color--white);
	font-size: var(--wp--preset--font-size--xs);
	letter-spacing: 0.06em;
	text-transform: uppercase;
	text-decoration: none;
	transition: color 0.2s ease;
}

.experience-card__cta:hover {
	color: var(--wp--preset--color--accent);
}

.experience-card__cta--button {
	padding: var(--wp--preset--spacing--3) var(--wp--preset--spacing--5);
	background-color: var(--wp--preset--color--accent);
	border-radius: var(--vik-radius);
	transition: background-color 0.2s ease, color 0.2s ease;
}

.experience-card__cta--button:hover {
	background-color: var(--wp--preset--color--accent-dark);
	color: var(--wp--preset--color--white);
}

/*
 * Le card dell'archivio Esperienze (".experience-card", più sotto in
 * questo file) usano le stesse classi __title/__cta, con regole a una
 * sola classe che, venendo dopo, vincevano anche qui: titolo color ink
 * (illeggibile sull'overlay scuro) e "margin-top: auto" sulla CTA, che
 * nel flex a colonna di .experience-card__content spingeva titolo/
 * descrizione in cima alla card invece che in basso sopra la CTA.
 * Selettori a più classi, scoped al blocco: l'archivio resta invariato,
 * e la variante chiara (".experience-card--style-light", content in
 * display:block dove margin-top:auto non ha effetto) pure.
 */
.wp-block-vik-base-experience-card:not(.experience-card--style-light) .experience-card__title {
	color: var(--wp--preset--color--white);
}

.wp-block-vik-base-experience-card .experience-card__cta {
	margin-top: 0;
}

/*
 * vik-base/experience-card — variante "Overlay chiaro con badge testo"
 * (attributo "cardStyle": "light", pannello Aspetto — usata di default in
 * experiences-carousel.php). La foto riempie l'intera card, esattamente
 * come nello stile scuro (nessuna regola propria su ".experience-card__image":
 * eredita width/height/object-fit dalla regola base); il box chiaro
 * FLUTTUA sopra la foto invece di scriverci sopra col gradiente — badge
 * testo (terracotta, senza sfondo pieno) + titolo + descrizione dentro un
 * riquadro con angoli arrotondati e ombra, staccato dai bordi su ogni lato.
 *
 * Geometria del box (posizione, larghezza, centratura verticale) recuperata
 * da ".experiences-carousel__card" così com'era prima della conversione del
 * pattern a blocchi (git HEAD di questa sessione, prima di qualunque
 * modifica): "top:50%; left:64%; width:300px; transform:translateY(-50%)".
 * Unico valore convertito in proporzione: la larghezza, tarata sui 300px
 * di una slide da 920px (~33%) — un clamp() la mantiene fedele a quel
 * rapporto qualunque sia la larghezza reale della card, con un margine
 * minimo/massimo di sicurezza. "left:64%" resta invariato: era già una
 * percentuale, non un valore assoluto da convertire.
 */
.wp-block-vik-base-experience-card.experience-card--style-light {
	aspect-ratio: 8 / 5;
	overflow: visible;
	color: var(--wp--preset--color--ink);
}

.experience-card--style-light .experience-card__content {
	position: absolute;
	top: auto;
	right: var(--wp--preset--spacing--4);
	bottom: var(--wp--preset--spacing--4);
	left: var(--wp--preset--spacing--4);
	z-index: 3;
	box-sizing: border-box;
	display: block;
	padding: var(--wp--preset--spacing--5) var(--wp--preset--spacing--4);
	background: var(--wp--preset--color--background);
	border-radius: var(--vik-radius);
	box-shadow: 0 20px 44px rgba(0, 0, 0, 0.12);
}

@media (min-width: 768px) {
	.experience-card--style-light .experience-card__content {
		top: 50%;
		right: auto;
		bottom: auto;
		left: 64%;
		width: clamp(200px, 33%, 320px);
		transform: translateY(-50%);
	}
}

.experience-card--style-light .experience-card__badge {
	position: static;
	display: block;
	margin: 0 0 var(--wp--preset--spacing--2);
	padding: 0;
	background: none;
	border-radius: 0;
	color: var(--wp--preset--color--accent);
}

.experience-card--style-light .experience-card__title {
	color: var(--wp--preset--color--ink);
}

.experience-card--style-light .experience-card__text {
	color: var(--wp--preset--color--text-soft);
}

.experience-card--style-light .experience-card__cta {
	color: var(--wp--preset--color--ink);
}

.experience-card--style-light .experience-card__cta:hover {
	color: var(--wp--preset--color--accent);
}

.experiences-dark__foot {
	display: flex;
	align-items: center;
	justify-content: space-between;
	margin-top: var(--wp--preset--spacing--5);
}

.experiences-dark__counter {
	font-family: var(--wp--preset--font-family--display);
	font-size: var(--wp--preset--font-size--lg);
	color: rgba(255, 255, 255, 0.6);
}

.experiences-dark__nav {
	display: flex;
	gap: var(--wp--preset--spacing--2);
}

.experiences-dark__arrow {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	border: 1px solid rgba(255, 255, 255, 0.3);
	border-radius: 100px;
	background: none;
	color: var(--wp--preset--color--white);
	font-size: var(--wp--preset--font-size--lg);
	cursor: pointer;
	transition: background-color 0.2s ease, border-color 0.2s ease, opacity 0.2s ease;
}

/*
 * A differenza di .room-carousel-arrow (dove il riempimento segue lo stato
 * "is-active" JS, cioè non-al-limite), qui il riempimento pieno è uno stile
 * permanente della sola freccia "successiva" — invito visivo a continuare,
 * fedele allo screenshot di riferimento. ".is-active" resta usato solo per
 * disabilitare visivamente la freccia quando il carosello è a un estremo.
 */
.experiences-dark__arrow--next {
	background-color: var(--wp--preset--color--accent);
	border-color: var(--wp--preset--color--accent);
}

.experiences-dark__arrow:hover {
	background-color: var(--wp--preset--color--accent);
	border-color: var(--wp--preset--color--accent);
}

.experiences-dark__arrow:not(.is-active) {
	opacity: 0.35;
	pointer-events: none;
}

/* -----------------------------------------------------------
   offers-featured
   ----------------------------------------------------------- */
.offers-featured > .wp-block-columns {
	gap: var(--vik-grid-gap);
}

.offer-card__image {
	margin: 0 0 var(--wp--preset--spacing--3);
}

.offer-card__image img {
	border-radius: var(--vik-radius);
}

.offer-card__tag {
	color: var(--wp--preset--color--accent);
	font-size: var(--wp--preset--font-size--xs);
	letter-spacing: 0.05em;
	text-transform: uppercase;
}

/* -----------------------------------------------------------
   amenities-grid — griglia uniforme (pattern amenities-grid.php),
   ogni scheda è un blocco vik-base/amenity-card (blocks/amenity-card/).
   ----------------------------------------------------------- */
.amenities-grid {
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	border-top: 1px solid var(--wp--preset--color--line);
	border-left: 1px solid var(--wp--preset--color--line);
}

@media (min-width: 768px) {
	.amenities-grid {
		grid-template-columns: repeat(3, 1fr);
	}
}

@media (min-width: 1024px) {
	.amenities-grid {
		grid-template-columns: repeat(6, 1fr);
	}
}

.amenities-grid .amenity-card {
	border-right: 1px solid var(--wp--preset--color--line);
	border-bottom: 1px solid var(--wp--preset--color--line);
}

/* -----------------------------------------------------------
   amenities-grid-photos — pattern amenities-grid-photos.php, due varianti
   di layout selezionabili dall'Inspector (assets/js/editor/
   amenities-grid-photos-layout-control.js, PanelBody "Layout griglia" sul
   blocco Group con className "amenities-grid-photos"): la classe
   modificatrice "amenities-grid-photos--mosaic" viene aggiunta/rimossa
   dal controllo. Nessun filtro server-side necessario: è puro CSS, le
   stesse schede vik-base/amenity-card restano invariate in entrambi i
   casi, cambia solo come il contenitore le dispone.

   - Regolare (default, nessuna classe modificatrice): griglia uniforme,
     tutte le celle della stessa dimensione — vedi screenshot di
     riferimento del pattern.
   - Mosaico (.amenities-grid-photos--mosaic): 5 colonne di base, ogni
     scheda con foto occupa 2 colonne, ogni scheda di fallback (nessuna
     foto) ne occupa 1. L'auto-placement di CSS Grid genera da solo il
     mosaico asimmetrico, nessuna posizione scritta a mano riga per riga.
   ----------------------------------------------------------- */
.amenities-grid-photos {
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	gap: var(--wp--preset--spacing--4);
	max-width: var(--wp--style--global--wide-size);
	margin: 0 auto;
}

@media (min-width: 768px) {
	.amenities-grid-photos:not(.amenities-grid-photos--mosaic) {
		grid-template-columns: repeat(3, 1fr);
	}

	.amenities-grid-photos:not(.amenities-grid-photos--mosaic) .amenity-card {
		aspect-ratio: 3 / 2;
		min-height: 0;
	}

	.amenities-grid-photos--mosaic {
		grid-template-columns: repeat(5, 1fr);
	}

	/* Classi dedicate solo alla dimensione della cella nel grid (non allo
	   stile visivo, quello resta su .amenity-card--photo/--fallback): sul
	   frontend il blocco produce un unico div che porta entrambe le classi,
	   ma nell'editor il wrapper del blocco (l'elemento che il canvas tratta
	   davvero come grid item) è un div diverso e più esterno rispetto a
	   quello renderizzato da render.php dentro ServerSideRender — vedi
	   blocks/amenity-card/edit.js. Tenerle separate evita che il wrapper
	   esterno erediti anche il gradiente/overlay visivo (pensato solo per
	   il div interno) e lo mostri "in eccesso" nello spazio che l'editor
	   riserva sotto ogni blocco. Si applicano solo in mosaico: in layout
	   regolare tutte le celle restano a 1 colonna, con o senza foto. */
	.amenities-grid-photos--mosaic .amenity-card-grid-item--wide {
		grid-column: span 2;
	}

	.amenities-grid-photos--mosaic .amenity-card-grid-item--narrow {
		grid-column: span 1;
	}
}

/* -----------------------------------------------------------
   amenity-card (blocks/amenity-card/render.php) — due varianti:
   --fallback (icona + badge, sfondo pieno) e --photo (foto piena cella
   con overlay basso-sinistra). Card comune ad entrambi i pattern.
   ----------------------------------------------------------- */
.amenity-card {
	position: relative;
	display: flex;
	min-height: 220px;
	overflow: hidden;
	border-radius: var(--vik-radius);
}

.amenity-card--fallback {
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: var(--wp--preset--spacing--2);
	/* padding: var(--wp--preset--spacing--5) var(--wp--preset--spacing--3); 
	   Disabilitato perchè modificava altezza rispetto agli item con immagine.
	 */ 
	text-align: center;
	/* Il colore di sfondo (default #EFE7D8 / background-alt) arriva dal
	   supporto colore nativo del blocco vik-base/amenity-card
	   (blocks/amenity-card/block.json → supports.color.background),
	   applicato da WordPress come classe "has-*-background-color" o stile
	   inline — modificabile dall'utente nell'Inspector nativo, nessuna
	   regola hardcoded qui. */
	transition: filter 0.2s ease;
}

.amenity-card--fallback:hover {
	filter: brightness(0.96);
}

.amenity-card--fallback .vik-icon {
	display: inline-flex;
	line-height: 1;
}

/* Promemoria "manca la foto", visibile solo dentro l'editor: nascosto di
   default (frontend), mostrato solo dentro ".editor-styles-wrapper" — la
   classe che WordPress aggiunge automaticamente al contenuto del canvas
   nell'iframe dell'editor (add_editor_style() in functions.php), mai
   presente sul sito pubblicato. */
.amenity-card__badge {
	display: none;
	position: absolute;
	top: var(--wp--preset--spacing--2);
	right: var(--wp--preset--spacing--2);
	padding: 4px 10px;
	border-radius: 100px;
	background: rgba(30, 30, 30, 0.08);
	color: var(--wp--preset--color--text-soft);
	font-size: 10px;
	font-weight: 600;
	letter-spacing: 0.04em;
	text-transform: uppercase;
	white-space: nowrap;
}

.editor-styles-wrapper .amenity-card__badge {
	display: inline-flex;
}

.amenity-card--photo {
	flex-direction: column;
	justify-content: flex-end;
	align-items: flex-start;
	text-align: left;
}

.amenity-card__image {
	position: absolute;
	inset: 0;
	z-index: 0;
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.amenity-card--photo::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 1;
	background: linear-gradient(180deg, rgba(20, 16, 12, 0) 45%, rgba(20, 16, 12, 0.75) 100%);
	pointer-events: none;
}

.amenity-card__title,
.amenity-card__subtitle {
	margin: 0;
	position: relative;
	z-index: 2;
}

.amenity-card__title {
	font-size: var(--wp--preset--font-size--sm);
	font-weight: 600;
	color: var(--wp--preset--color--ink);
}

.amenity-card__subtitle {
	font-size: var(--wp--preset--font-size--xs);
	color: var(--wp--preset--color--text-soft);
}

.amenity-card--photo .amenity-card__title,
.amenity-card--photo .amenity-card__subtitle {
	padding: 0 var(--wp--preset--spacing--3);
	color: var(--wp--preset--color--white);
}

.amenity-card--photo .amenity-card__subtitle {
	padding-bottom: var(--wp--preset--spacing--3);
	color: rgba(255, 255, 255, 0.8);
}

/* -----------------------------------------------------------
   how-it-works
   ----------------------------------------------------------- */
.how-it-works__step {
	text-align: center;
}

.how-it-works__number {
	margin: 0 0 var(--wp--preset--spacing--2);
	color: var(--wp--preset--color--line);
	font-family: var(--wp--preset--font-family--display);
	font-size: var(--wp--preset--font-size--xl);
	font-weight: 600;
}

/* -----------------------------------------------------------
   location-split / contact-split
   ----------------------------------------------------------- */
.location-split__map iframe,
.contact-split__map iframe {
	display: block;
	width: 100%;
	border-radius: var(--vik-radius);
}

/*
 * Fallback quando vik_base_maps_embed_url() ritorna false (indirizzo non
 * ancora compilato nel wizard di setup, vedi patterns/contact-split.php):
 * stessa altezza/larghezza dell'iframe che sostituisce, per non far
 * saltare il layout a colonne quando l'indirizzo viene poi compilato.
 */
.contact-split__map-placeholder {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: var(--wp--preset--spacing--3);
	width: 100%;
	height: 480px;
	background-color: var(--wp--preset--color--background-alt);
	border: 1px solid var(--wp--preset--color--line);
	border-radius: var(--vik-radius);
	text-align: center;
	padding: var(--wp--preset--spacing--5);
}

.contact-split__map-placeholder svg {
	width: 40px;
	height: 40px;
	color: var(--wp--preset--color--text-soft);
}

.contact-split__map-placeholder p {
	max-width: 280px;
	margin: 0;
	color: var(--wp--preset--color--text-soft);
	font-size: var(--wp--preset--font-size--sm);
}

/*
 * location-split diventa align full di default (vedi patterns/location-split.php):
 * la colonna testo ha bisogno del padding orizzontale "di pagina" che il resto
 * del layout riceve normalmente da contentSize/wideSize, dato che qui la riga
 * arriva a bordo viewport. Stessa scala responsive 64/32/20px già usata da
 * ".hero-bg__inner" per lo stesso motivo. La colonna mappa non riceve invece
 * alcun padding, cosi arriva fino al vero bordo destro della viewport.
 */
.location-split__content {
	padding-inline-start: var(--wp--preset--spacing--8);
	padding-inline-end: var(--wp--preset--spacing--6);
	padding-block: var(--wp--preset--spacing--7);
}

/*
 * Righe icona + vik-base/business-field (indirizzo/telefono/email dinamici,
 * vedi patterns/location-split.php) — stesse regole di
 * .site-footer__contact-row in questo file, adattate al testo scuro su
 * sfondo chiaro di questa sezione invece che al footer.
 */
.location-split__contact-row {
	align-items: center;
	margin-bottom: var(--wp--preset--spacing--3);
}

.location-split__contact-row--address {
	align-items: flex-start;
}

.location-split__contact-row p {
	margin: 0;
	color: var(--wp--preset--color--text-soft);
	font-size: var(--wp--preset--font-size--sm);
	line-height: 1.5;
}

@media (max-width: 1023px) {
	.location-split__content {
		padding-inline-start: var(--wp--preset--spacing--6);
		padding-inline-end: var(--wp--preset--spacing--6);
	}
}

@media (max-width: 767px) {
	.location-split__content {
		padding-inline-start: var(--wp--preset--spacing--5);
		padding-inline-end: var(--wp--preset--spacing--5);
	}
}

/*
 * La mappa può estendersi oltre l'altezza naturale della colonna testo:
 * "align-self:stretch" la riporta all'altezza della riga (quella del
 * fratello più alto tra i due), sovrascrivendo solo per questa colonna
 * l'"align-items:center" impostato da ".location-split__columns" (attributo
 * "verticalAlignment":"center" del blocco Columns nel pattern) — la colonna
 * testo resta invece centrata verticalmente come previsto. "min-height"
 * garantisce inoltre che la mappa sia sempre percepibilmente più alta della
 * colonna testo anche quando quest'ultima è breve.
 */
.location-split__map {
	align-self: stretch;
	min-height: 480px;
}

.location-split__map iframe {
	height: 100%;
}

@media (max-width: 1023px) {
	.location-split__map {
		min-height: 360px;
	}
}

@media (max-width: 767px) {
	.location-split__map {
		min-height: 280px;
	}
}

.contact-split__details h3 {
	margin-top: var(--wp--preset--spacing--5);
	margin-bottom: var(--wp--preset--spacing--2);
	font-size: var(--wp--preset--font-size--md);
}

.contact-split__details h3:first-child {
	margin-top: 0;
}

/* Telefono ed email: due blocchi vik-base/business-field (2026-10-07),
   prima un unico paragrafo "Tel: …<br/>Email: …" — stesse righe attaccate. */
.contact-split__details .contact-split__line + .contact-split__line {
	margin-block-start: 0;
}

/* Spazio prima del footer (2026-10-06): la sezione non ne aveva, e con
   un testo lungo nella colonna dettagli (es. "Come raggiungerci", aggiunto
   dal cliente) l'ultima riga toccava il footer. Stessa scala responsive
   delle altre sezioni del tema. */
.contact-split {
	padding-bottom: var(--vik-section-space-y);
}

@media (max-width: 1023px) {
	.contact-split {
		padding-bottom: var(--vik-section-space-y-tablet);
	}
}

@media (max-width: 767px) {
	.contact-split {
		padding-bottom: var(--vik-section-space-y-mobile);
	}
}

/* Desktop, colonne affiancate: la mappa (altezza fissa) accompagna lo
   scorrimento di un testo più lungo di lei invece di lasciare un vuoto
   sotto. Sotto i 1024px le colonne vanno una sotto l'altra, niente sticky.
   Con header fisso ("Fisso in cima") si ferma sotto di esso: altezza
   reale da assets/js/header-height.js. */
@media (min-width: 1024px) {
	.contact-split__map {
		position: sticky;
		top: var(--wp--preset--spacing--6);
		align-self: flex-start;
	}

	body:has(.site-header--sticky) .contact-split__map {
		top: calc(var(--header-height, 88px) + var(--wp--preset--spacing--6));
	}
}

/* -----------------------------------------------------------
   cta-banner
   ----------------------------------------------------------- */
.cta-banner .wp-block-cover__inner-container {
	max-width: 640px;
	margin-inline: auto;
	text-align: center;
}

/* -----------------------------------------------------------
   newsletter-placeholder
   ----------------------------------------------------------- */
/* A differenza delle altre sezioni "alignfull" del tema, qui non c'è
   nessun wrapper interno (titolo, testo e form sono figli diretti del
   gruppo full-bleed, vedi patterns/newsletter-placeholder.php) e il
   gruppo stesso è "layout":{"type":"flow"} (default del blocco Group
   con background scuro fisso), quindi non è mai idoneo a
   "has-global-padding" di WordPress: senza un padding orizzontale
   proprio qui, titolo/testo/form toccano il vero bordo della viewport
   su mobile, a prescindere dal centering del testo (una riga
   abbastanza lunga riempie comunque tutta la larghezza disponibile).
   Stessa scala responsiva 64/32/20px già in uso altrove nel tema. */
.newsletter-placeholder {
	background-color: var(--newsletter-bg);
	padding-left: var(--wp--preset--spacing--8);
	padding-right: var(--wp--preset--spacing--8);
	text-align: center;
}

@media (max-width: 1023px) {
	.newsletter-placeholder {
		padding-left: var(--wp--preset--spacing--6);
		padding-right: var(--wp--preset--spacing--6);
	}
}

@media (max-width: 767px) {
	.newsletter-placeholder {
		padding-left: var(--wp--preset--spacing--5);
		padding-right: var(--wp--preset--spacing--5);
	}
}

.newsletter-placeholder h2 {
	font-size: var(--wp--preset--font-size--xl);
}

.newsletter-placeholder p {
	color: rgba(255, 255, 255, 0.7);
}

.newsletter-placeholder__form {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: var(--wp--preset--spacing--1);
	max-width: 480px;
	margin: var(--wp--preset--spacing--5) auto 0;
}

.newsletter-placeholder__form input[type="email"] {
	flex: 1 1 240px;
	padding: var(--wp--preset--spacing--2) var(--wp--preset--spacing--3);
	background-color: transparent;
	color: var(--wp--preset--color--white);
	border: 1px solid rgba(255, 255, 255, 0.3);
	border-radius: var(--vik-radius);
	font-family: var(--wp--preset--font-family--body);
}

.newsletter-placeholder__form input[type="email"]::placeholder {
	color: rgba(255, 255, 255, 0.6);
}

.newsletter-placeholder__form button {
	padding: var(--wp--preset--spacing--2) var(--wp--preset--spacing--5);
	background-color: var(--wp--preset--color--accent);
	color: var(--wp--preset--color--white);
	border: none;
	border-radius: var(--vik-radius);
	font-weight: 700;
	letter-spacing: 0.05em;
	text-transform: uppercase;
	cursor: pointer;
	transition: background-color 0.2s ease;
}

.newsletter-placeholder__form button:hover {
	background-color: var(--wp--preset--color--accent-dark);
}

/* -----------------------------------------------------------
   about-story
   ----------------------------------------------------------- */
.about-story__stat {
	text-align: center;
}

.about-story__stat-number {
	margin: 0 0 var(--wp--preset--spacing--1);
	color: var(--wp--preset--color--accent);
	font-family: var(--wp--preset--font-family--display);
	font-size: var(--wp--preset--font-size--xl);
	font-weight: 600;
	font-variant-numeric: lining-nums;
}

/* A differenza delle altre sezioni "alignfull" del tema (trust-bar,
   hero-search, ecc., azzerate sopra e indentate da un wrapper interno
   con max-width proprio), ".about-story__quote" non ha alcun wrapper
   interno: il testo del blockquote è figlio diretto del gruppo full-
   bleed. Da quando "useRootPaddingAwareAlignments" è attivo (vedi in
   cima al file), questo blocco è anche "layout":{"type":"constrained"}
   nel proprio pattern (about-story.php) — riceve quindi già un
   "has-global-padding" reale da WordPress stesso: azzerare qui
   padding-right/left, come si faceva prima di quell'attivazione,
   toglierebbe l'unico margine orizzontale che il testo ha, facendolo
   tornare a toccare il bordo reale dello schermo su mobile. */
.about-story__quote {
	padding-top: var(--vik-section-space-y-compact);
	padding-bottom: var(--vik-section-space-y-compact);
	text-align: center;
}

@media (max-width: 1023px) {
	.about-story__quote {
		padding-top: var(--vik-section-space-y-compact-tablet);
		padding-bottom: var(--vik-section-space-y-compact-tablet);
	}
}

@media (max-width: 767px) {
	.about-story__quote {
		padding-top: var(--vik-section-space-y-compact-mobile);
		padding-bottom: var(--vik-section-space-y-compact-mobile);
	}
}

.about-story__quote .wp-block-quote {
	padding: 0;
	border: none;
}

.about-story__quote .wp-block-quote cite {
	display: block;
	margin-top: var(--wp--preset--spacing--4);
	font-family: var(--wp--preset--font-family--display);
	font-style: italic;
	font-size: var(--wp--preset--font-size--sm);
	color: var(--wp--preset--color--white);
	opacity: 0.85;
}

.about-story__quote .wp-block-button__link {
	border-radius: var(--vik-radius);
}

.about-story__section hr.wp-block-separator.about-story__divider {
	width: 28px;
	height: 1px;
	margin: var(--wp--preset--spacing--6) 0 0;
	background-color: var(--wp--preset--color--accent);
	border: none;
}

.about-story__aside {
	margin-top: var(--wp--preset--spacing--4);
	font-family: var(--wp--preset--font-family--display);
	font-variant-numeric: lining-nums;
	font-style: italic;
	color: var(--wp--preset--color--text-soft);
}

/* gallery-page-header è stata rimossa: Galleria ora usa il blocco
   condiviso vik-base/page-header (density "spacious", contentAlign
   "center") — vedi ".page-header" più sopra in questo file. */

/* -----------------------------------------------------------
   gallery-masonry
   ----------------------------------------------------------- */
.gallery-masonry {
	columns: 1;
	column-gap: var(--wp--preset--spacing--4);
}

@media (min-width: 768px) {
	.gallery-masonry {
		columns: 2;
	}
}

@media (min-width: 1024px) {
	.gallery-masonry {
		columns: 3;
	}
}

.gallery-masonry__item {
	position: relative;
	display: block;
	margin-bottom: var(--wp--preset--spacing--4);
	overflow: hidden;
	border-radius: var(--vik-radius);
	break-inside: avoid;
	cursor: zoom-in;
}

.gallery-masonry__item img {
	display: block;
	width: 100%;
	border-radius: var(--vik-radius);
	transition: transform 0.25s ease;
}

/* Overlay + icona "espandi" al passaggio del mouse/focus da tastiera:
   niente elementi aggiunti nel markup (che romperebbe la validazione
   del blocco core/image al primo salvataggio), tutto via pseudo-elementi
   sul contenitore .gallery-masonry__item — comportamento aggiunto in
   JS solo per tabindex/aria/apertura lightbox (assets/js/gallery-lightbox.js).
   L'icona è la stessa "maximize-2" self-hosted già usata per il set
   Lucide del tema (assets/icons/lucide/), applicata via mask così da
   poterla colorare in bianco senza un secondo file. */
.gallery-masonry__item::before {
	content: "";
	position: absolute;
	inset: 0;
	background-color: rgba(20, 16, 12, 0.28);
	opacity: 0;
	transition: opacity 0.25s ease;
}

.gallery-masonry__item::after {
	content: "";
	position: absolute;
	top: 50%;
	left: 50%;
	width: 28px;
	height: 28px;
	background-color: var(--wp--preset--color--white);
	-webkit-mask-image: url("../icons/lucide/maximize-2.svg");
	mask-image: url("../icons/lucide/maximize-2.svg");
	-webkit-mask-repeat: no-repeat;
	mask-repeat: no-repeat;
	-webkit-mask-position: center;
	mask-position: center;
	-webkit-mask-size: contain;
	mask-size: contain;
	opacity: 0;
	transform: translate(-50%, -50%) scale(0.85);
	transition: opacity 0.25s ease, transform 0.25s ease;
}

.gallery-masonry__item:hover img,
.gallery-masonry__item:focus-visible img {
	transform: scale(1.06);
}

.gallery-masonry__item:hover::before,
.gallery-masonry__item:focus-visible::before,
.gallery-masonry__item:hover::after,
.gallery-masonry__item:focus-visible::after {
	opacity: 1;
	transform: translate(-50%, -50%) scale(1);
}

.gallery-masonry__item:focus-visible {
	outline: 2px solid var(--wp--preset--color--accent);
	outline-offset: 3px;
}

@media (prefers-reduced-motion: reduce) {
	.gallery-masonry__item img,
	.gallery-masonry__item::before,
	.gallery-masonry__item::after {
		transition: none;
	}
}

/* -----------------------------------------------------------
   gallery-lightbox — overlay a schermo intero costruito da
   assets/js/gallery-lightbox.js (un solo nodo condiviso, riusato per
   ogni apertura, non ricreato ad ogni click). Frecce prev/next stesso
   stile di .experiences-carousel__arrow (cerchio 44px, stesso font-size
   per i glifi ‹ ›), qui su sfondo scuro quindi bordo/riempimento chiari
   invece di background-alt.
   ----------------------------------------------------------- */
.gallery-lightbox {
	position: fixed;
	inset: 0;
	z-index: 9999;
}

.gallery-lightbox[hidden] {
	display: none;
}

.gallery-lightbox__backdrop {
	position: absolute;
	inset: 0;
	background-color: rgba(20, 16, 12, 0.92);
}

.gallery-lightbox__dialog {
	box-sizing: border-box;
	position: relative;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	height: 100%;
	padding: var(--wp--preset--spacing--6);
}

.gallery-lightbox__figure {
	position: relative;
	margin: 0;
	max-width: min(1200px, 90vw);
	max-height: 85vh;
}

.gallery-lightbox__image {
	display: block;
	max-width: min(1200px, 90vw);
	max-height: 85vh;
	width: auto;
	height: auto;
	border-radius: var(--vik-radius);
	box-shadow: 0 24px 48px rgba(0, 0, 0, 0.35);
}

.gallery-lightbox__close,
.gallery-lightbox__arrow {
	position: absolute;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	border: 1px solid rgba(255, 255, 255, 0.4);
	border-radius: 100px;
	background-color: rgba(255, 255, 255, 0.08);
	color: var(--wp--preset--color--white);
	cursor: pointer;
	transition: background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease;
}

.gallery-lightbox__close:hover,
.gallery-lightbox__arrow:hover {
	background-color: var(--wp--preset--color--accent);
	border-color: var(--wp--preset--color--accent);
	color: var(--wp--preset--color--white);
}

.gallery-lightbox__close:focus-visible,
.gallery-lightbox__arrow:focus-visible {
	outline: 2px solid var(--wp--preset--color--white);
	outline-offset: 2px;
}

.gallery-lightbox__close {
	top: var(--wp--preset--spacing--5);
	right: var(--wp--preset--spacing--5);
	font-size: 20px;
	line-height: 1;
}

.gallery-lightbox__arrow {
	top: 50%;
	transform: translateY(-50%);
	font-size: var(--wp--preset--font-size--lg);
}

.gallery-lightbox__arrow--prev {
	left: var(--wp--preset--spacing--5);
}

.gallery-lightbox__arrow--next {
	right: var(--wp--preset--spacing--5);
}

.gallery-lightbox__counter {
	position: absolute;
	bottom: var(--wp--preset--spacing--5);
	left: 50%;
	transform: translateX(-50%);
	margin: 0;
	color: rgba(255, 255, 255, 0.75);
	font-family: var(--wp--preset--font-family--display);
	font-variant-numeric: lining-nums;
	font-size: var(--wp--preset--font-size--sm);
	letter-spacing: 0.04em;
}

@media (max-width: 767px) {
	.gallery-lightbox__dialog {
		padding: var(--wp--preset--spacing--4);
	}

	.gallery-lightbox__close,
	.gallery-lightbox__arrow {
		width: 38px;
		height: 38px;
	}

	.gallery-lightbox__close {
		top: var(--wp--preset--spacing--3);
		right: var(--wp--preset--spacing--3);
	}

	.gallery-lightbox__arrow--prev {
		left: var(--wp--preset--spacing--3);
	}

	.gallery-lightbox__arrow--next {
		right: var(--wp--preset--spacing--3);
	}
}

/* -----------------------------------------------------------
   blog-preview
   ----------------------------------------------------------- */
.blog-preview__grid {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--wp--preset--spacing--6);
	margin: 0;
	padding: 0;
	list-style: none;
}

@media (min-width: 768px) {
	.blog-preview__grid {
		grid-template-columns: repeat(3, 1fr);
	}
}

.blog-preview__image img {
	display: block;
	width: 100%;
	height: 220px;
	object-fit: cover;
	border-radius: var(--vik-radius);
}

/* -----------------------------------------------------------
   Sistema animazioni in entrata — vedi assets/js/animations.js
   e plugin vik-base-animations
   ----------------------------------------------------------- */
[data-animate="fade"] {
	opacity: 0;
	transition: opacity var(--vik-anim-duration) var(--vik-anim-ease);
}

[data-animate="slide-up"] {
	opacity: 0;
	transform: translateY(32px);
	transition: opacity var(--vik-anim-duration) var(--vik-anim-ease), transform var(--vik-anim-duration) var(--vik-anim-ease);
}

[data-animate="slide-left"] {
	opacity: 0;
	transform: translateX(-32px);
	transition: opacity var(--vik-anim-duration) var(--vik-anim-ease), transform var(--vik-anim-duration) var(--vik-anim-ease);
}

/* Usata dalla card flottante di Rooms List — lista-02 (vedi
   applyRoomsListLista02() in assets/js/vikbooking-dom.js): entra
   dall'alto verso il basso invece che da sotto verso l'alto come
   "slide-up", coerente con la card ancorata in top:24px sull'immagine. */
[data-animate="slide-down"] {
	opacity: 0;
	transform: translateY(-32px);
	transition: opacity var(--vik-anim-duration) var(--vik-anim-ease), transform var(--vik-anim-duration) var(--vik-anim-ease);
}

[data-animate].is-visible {
	opacity: 1;
	transform: none;
}

/* Nell'editor (theme.css è anche editor style, body.editor-styles-wrapper
   nel canvas) animations.js non gira: i blocchi dinamici che stampano
   data-animate da PHP (es. vik-base/page-header, anteprima via
   ServerSideRender) restavano a opacità 0, cioè invisibili. Sul sito
   questa classe non esiste, nessun effetto. */
.editor-styles-wrapper [data-animate] {
	opacity: 1;
	transform: none;
}

/* Sicurezza aggiuntiva lato CSS: la libreria JS (assets/js/animations.js)
   già rileva "prefers-reduced-motion" e salta l'observer mostrando tutto
   da subito, ma questa regola copre anche il caso limite in cui il JS non
   sia ancora eseguito/disponibile. */
@media (prefers-reduced-motion: reduce) {
	[data-animate] {
		opacity: 1;
		transform: none;
		transition: none;
	}
}

/* -----------------------------------------------------------
   vikbooking-packages (blocks/vikbooking-packages/render.php) —
   vetrina "Pacchetti" VikBooking: 1 card in evidenza + fino a 2 card
   affiancate, eventuali pacchetti aggiuntivi in una griglia normale
   sotto (mai più di 3 nella disposizione asimmetrica, così il layout non
   si rompe indipendentemente da quanti pacchetti l'editor seleziona).
   ----------------------------------------------------------- */
.vikbooking-packages__grid {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--vik-grid-gap);
}

@media (min-width: 1024px) {
	.vikbooking-packages__grid {
		grid-template-columns: 1.6fr 1fr;
	}

	.vikbooking-packages__grid--solo {
		grid-template-columns: 1fr;
	}
}

.vikbooking-packages__side {
	display: flex;
	flex-direction: column;
	gap: var(--vik-grid-gap);
}

.vikbooking-packages__more {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
	gap: var(--vik-grid-gap);
	margin-top: var(--wp--preset--spacing--4);
}

.vikbooking-packages__card {
	position: relative;
	display: flex;
	flex-direction: column;
	justify-content: flex-end;
	min-height: 320px;
	overflow: hidden;
	border-radius: var(--vik-radius);
	background-color: var(--wp--preset--color--background-alt);
}

.vikbooking-packages__card--featured {
	min-height: 420px;
}

@media (min-width: 1024px) {
	.vikbooking-packages__card {
		min-height: 0; /* l'altezza la dà il grid: la riga segue la card in evidenza */
	}

	.vikbooking-packages__side .vikbooking-packages__card {
		flex: 1 1 0;
	}

	.vikbooking-packages__card--featured {
		min-height: 520px;
	}
}

.vikbooking-packages__image {
	position: absolute;
	inset: 0;
	z-index: 0;
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.vikbooking-packages__card::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 1;
	background: linear-gradient(180deg, rgba(20, 16, 12, 0) 45%, rgba(20, 16, 12, 0.75) 100%);
	pointer-events: none;
}

/* Eccezione rispetto al mockup di riferimento (solo la card in evidenza
   aveva un badge a sfondo pieno, le altre mostravano il prezzo come testo
   semplice sovrapposto alla foto): qui il badge terracotta pieno è
   applicato SEMPRE, su ogni card, per leggibilità garantita
   indipendentemente da cosa mostra la foto sottostante. */
.vikbooking-packages__price-badge {
	position: absolute;
	top: 0;
	right: 0;
	z-index: 2;
	padding: var(--wp--preset--spacing--2) var(--wp--preset--spacing--3);
	background-color: var(--wp--preset--color--accent);
	border-radius: 0 0 0 var(--vik-radius);
	text-align: right;
}

.vikbooking-packages__price-label,
.vikbooking-packages__price-suffix {
	display: block;
	color: var(--wp--preset--color--white);
	font-size: 9px;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	opacity: 0.85;
}

.vikbooking-packages__price-value {
	display: block;
	margin: 2px 0;
	color: var(--wp--preset--color--white);
	font-family: var(--wp--preset--font-family--display);
	font-variant-numeric: lining-nums;
	font-size: 22px;
}

.vikbooking-packages__card--featured .vikbooking-packages__price-value {
	font-size: 28px;
}

.vikbooking-packages__content {
	position: relative;
	z-index: 2;
	padding: var(--wp--preset--spacing--4);
}

.vikbooking-packages__card--featured .vikbooking-packages__content {
	padding: var(--wp--preset--spacing--5);
}

.vikbooking-packages__eyebrow {
	margin: 0 0 var(--wp--preset--spacing--1);
	color: var(--vik-overlay-ivory);
	font-style: italic;
	font-size: var(--wp--preset--font-size--xs);
}

.vikbooking-packages__title {
	margin: 0 0 var(--wp--preset--spacing--2);
	color: var(--wp--preset--color--white);
	font-family: var(--wp--preset--font-family--display);
	font-size: 22px;
	font-weight: 500;
}

.vikbooking-packages__card--featured .vikbooking-packages__title {
	font-size: 30px;
}

.vikbooking-packages__desc {
	margin: 0 0 var(--wp--preset--spacing--2);
	color: rgba(255, 255, 255, 0.85);
	font-size: var(--wp--preset--font-size--sm);
}

.vikbooking-packages__rooms {
	margin: 0 0 var(--wp--preset--spacing--3);
	color: rgba(255, 255, 255, 0.7);
	font-size: var(--wp--preset--font-size--xs);
}

.vikbooking-packages__cta {
	display: inline-block;
	padding: var(--wp--preset--spacing--2) var(--wp--preset--spacing--4);
	background-color: var(--wp--preset--color--accent);
	border-radius: var(--vik-radius);
	color: var(--wp--preset--color--white);
	font-size: var(--wp--preset--font-size--sm);
	text-decoration: none;
	transition: background-color 0.2s ease;
}

.vikbooking-packages__cta:hover {
	background-color: var(--wp--preset--color--accent-dark);
}

.vikbooking-packages__cta--disabled {
	background-color: rgba(255, 255, 255, 0.25);
	color: rgba(255, 255, 255, 0.6);
	cursor: not-allowed;
	pointer-events: none;
}

/* Messaggi "niente da mostrare" (plugin non attivo / nessun pacchetto
   live / nessuna pagina di destinazione configurata): mai un errore, ma
   privi di senso per un visitatore del sito — nascosti di default,
   visibili solo dentro l'editor. Stesso meccanismo di .amenity-card__badge
   qui sopra. */
.vikbooking-packages__editor-notice {
	display: none;
	padding: var(--wp--preset--spacing--3) var(--wp--preset--spacing--4);
	background-color: #fdf2d0;
	border: 1px solid #e3c766;
	border-radius: var(--vik-radius);
	color: var(--wp--preset--color--ink);
	font-size: var(--wp--preset--font-size--sm);
}

.editor-styles-wrapper .vikbooking-packages__editor-notice {
	display: block;
	margin-bottom: var(--wp--preset--spacing--4);
}

/* -----------------------------------------------------------
   vikbooking-packages — variante "grid" (attributo layout="grid"):
   griglia simmetrica a 3 colonne, foto in alto + corpo scheda sotto
   (nessun testo sovrapposto alla foto, a differenza della variante
   "featured" qui sopra). Le classi __card-* qui sotto sono indipendenti
   da quelle della variante "featured" (niente ancestor-scoping): stesso
   approccio già usato tra .room-overlay-name / .amenity-card__title,
   dichiarazioni proprie invece di condividere regole tra contesti
   chiaro/scuro diversi.
   ----------------------------------------------------------- */
.vikbooking-packages__uniform-grid {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--wp--preset--spacing--6);
}

@media (min-width: 768px) {
	.vikbooking-packages__uniform-grid {
		grid-template-columns: repeat(2, 1fr);
	}
}

@media (min-width: 1024px) {
	.vikbooking-packages__uniform-grid {
		grid-template-columns: repeat(3, 1fr);
	}
}

.vikbooking-packages__card--grid {
	display: flex;
	flex-direction: column;
	justify-content: flex-start; /* sovrascrive il "flex-end" della variante "featured" (lì serve a spingere il testo sovrapposto in basso): qui la foto deve restare in cima a prescindere da quanto testo segue */
	min-height: 0; /* sovrascrive il min-height della variante "featured", qui l'altezza la dà il contenuto */
	background-color: var(--wp--preset--color--background);
}

.vikbooking-packages__card--grid::after {
	content: none; /* niente gradiente: la variante "grid" non ha testo sovrapposto alla foto */
}

.vikbooking-packages__card-media {
	position: relative;
	aspect-ratio: 4 / 3;
	overflow: hidden;
}

.vikbooking-packages__card--grid .vikbooking-packages__image {
	position: static; /* la variante "featured" la posiziona assoluta a coprire la card intera, qui basta riempire .vikbooking-packages__card-media */
}

.vikbooking-packages__card-body {
	display: flex;
	flex: 1;
	flex-direction: column;
	padding: var(--wp--preset--spacing--4);
}

.vikbooking-packages__card-eyebrow {
	margin: 0 0 var(--wp--preset--spacing--1);
	color: var(--wp--preset--color--accent);
	font-size: var(--wp--preset--font-size--xs);
	font-weight: 600;
	letter-spacing: 0.05em;
	text-transform: uppercase;
}

.vikbooking-packages__card-title {
	margin: 0 0 var(--wp--preset--spacing--2);
	color: var(--wp--preset--color--ink);
	font-family: var(--wp--preset--font-family--display);
	font-size: var(--wp--preset--font-size--lg);
	font-weight: 500;
}

.vikbooking-packages__card-desc {
	margin: 0 0 var(--wp--preset--spacing--3);
	color: var(--wp--preset--color--text-soft);
	font-size: var(--wp--preset--font-size--sm);
}

.vikbooking-packages__card-rooms {
	margin: 0 0 var(--wp--preset--spacing--3);
	color: var(--wp--preset--color--text-soft);
	font-size: var(--wp--preset--font-size--xs);
}

.vikbooking-packages__card-meta-row {
	display: flex;
	align-items: flex-end;
	justify-content: space-between;
	gap: var(--wp--preset--spacing--3);
	margin-top: auto; /* spinge sempre la riga prezzo/CTA in fondo alla card, a prescindere da quanto testo la precede — stesso trucco di .room-split-footer */
	padding-top: var(--wp--preset--spacing--2);
}

.vikbooking-packages__card-price {
	margin: 0;
	line-height: 1.2;
}

.vikbooking-packages__card-price-label,
.vikbooking-packages__card-price-suffix {
	display: block;
	color: var(--wp--preset--color--text-soft);
	font-size: 11px;
	letter-spacing: 0.04em;
	text-transform: uppercase;
}

.vikbooking-packages__card-price-value {
	color: var(--wp--preset--color--ink);
	font-family: var(--wp--preset--font-family--display);
	font-variant-numeric: lining-nums;
	font-size: 30px;
}

.vikbooking-packages__cta--grid {
	flex-shrink: 0;
	padding: var(--wp--preset--spacing--2) var(--wp--preset--spacing--3);
	font-size: var(--wp--preset--font-size--xs);
	font-weight: 600;
	letter-spacing: 0.04em;
	text-transform: uppercase;
}

/* experiences-page-header è stata rimossa: gli archivi Esperienze/Eventi
   ora usano il blocco condiviso vik-base/page-header (titleSource
   "archive", density "spacious", contentAlign "center") — vedi
   ".page-header" più sopra in questo file, dove ".page-header
   .wp-block-query-title" mantiene lo stesso "font-weight: 600" di qui,
   per restare invariati pixel per pixel. */

/* -----------------------------------------------------------
   experiences-archive — griglia della pagina archivio "Esperienze".
   Stesso schema a 3 colonne di .vikbooking-packages__uniform-grid
   (foto in alto, corpo scheda sotto, nessun overlay) ma sul Query Loop
   nativo del CPT "esperienza" invece del blocco
   vik-base/vikbooking-packages: righe incomplete restano allineate a
   sinistra per comportamento naturale di CSS grid, nessun elemento
   fantasma necessario.
   ----------------------------------------------------------- */
.experiences-archive {
	padding-top: var(--vik-section-space-y);
	padding-bottom: var(--vik-section-space-y);
}

@media (max-width: 1023px) {
	.experiences-archive {
		padding-top: var(--vik-section-space-y-tablet);
		padding-bottom: var(--vik-section-space-y-tablet);
	}
}

@media (max-width: 767px) {
	.experiences-archive {
		padding-top: var(--vik-section-space-y-mobile);
		padding-bottom: var(--vik-section-space-y-mobile);
	}
}

.experiences-archive__grid {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--vik-grid-gap);
	margin: 0;
	padding: 0;
	list-style: none;
}

/*
 * Azzera il margin-top che il Query Loop nativo (".is-layout-flow", vedi
 * classi sull'<ul> sopra) inietta di default su ogni <li> tranne il primo
 * (":where(.is-layout-flow) > :not(:first-child)" nel CSS core, pensato
 * per uno stack verticale, non per una griglia a più colonne). Senza
 * questo override la prima card di ogni riga resta senza quel margine
 * mentre le altre lo ricevono, disallineandole verticalmente tra loro —
 * qui la spaziatura deve venire solo dal "gap" della grid qui sopra.
 * Specificità di classe, sufficiente a battere il ":where()" (specificità
 * zero) di WordPress senza bisogno di "!important".
 */
.experiences-archive__grid > li {
	margin-block-start: 0;
}

@media (min-width: 768px) {
	.experiences-archive__grid {
		grid-template-columns: repeat(2, 1fr);
	}
}

@media (min-width: 1024px) {
	.experiences-archive__grid {
		grid-template-columns: repeat(3, 1fr);
	}
}

.experience-card {
	display: flex;
	flex-direction: column;
	height: 100%;
	overflow: hidden;
	background-color: var(--wp--preset--color--white);
	border: 0.5px solid var(--wp--preset--color--line);
	border-radius: var(--vik-radius);
}

.experience-card__image {
	margin: 0;
}

/*
 * ".experience-card__image" è anche la classe dell'<img> della card-blocco
 * overlay (vik-base/experience-card, più sopra: "height: 100%"), regola
 * che qui colpiva la <figure>: chiedeva tutta l'altezza della card e il
 * flex a colonna la restringeva in proporzione, così la card con l'estratto
 * più corto teneva una figure più alta (spazio vuoto sotto la foto) e il
 * titolo scendeva rispetto alle card vicine. Altezza = quella della foto.
 */
.experience-card > .experience-card__image {
	flex-shrink: 0;
	height: auto;
}

.experience-card__image img {
	display: block;
	width: 100%;
	height: 220px;
	object-fit: cover;
}

.experience-card__body {
	display: flex;
	flex: 1;
	flex-direction: column;
	padding: var(--wp--preset--spacing--4);
}

.experience-card__title {
	margin: 0 0 var(--wp--preset--spacing--2);
	color: var(--wp--preset--color--ink);
	font-family: var(--wp--preset--font-family--display);
	font-size: var(--wp--preset--font-size--md);
	font-weight: 600;
}

.experience-card__title a {
	color: inherit;
	text-decoration: none;
}

.experience-card__excerpt {
	margin: 0 0 var(--wp--preset--spacing--4);
	color: var(--wp--preset--color--text-soft);
	font-size: 13px;
}

.experience-card__excerpt p {
	margin: 0;
}

.experience-card__cta {
	display: inline-flex;
	align-items: center;
	gap: var(--wp--preset--spacing--2);
	margin-top: auto;
	color: var(--wp--preset--color--accent);
	font-size: var(--wp--preset--font-size--xs);
	font-weight: 600;
	letter-spacing: 0.08em;
	text-decoration: none;
	text-transform: uppercase;
}

.experience-card__cta::after {
	content: "\2192";
	transition: transform 0.2s ease;
}

.experience-card__cta:hover::after {
	transform: translateX(4px);
}

/* -----------------------------------------------------------
   experiences-grid — blocco vik-base/experiences-grid (blocks/
   experiences-grid/), la griglia della PAGINA Esperienze. Riusa
   ".experiences-archive"/".experiences-archive__grid"/".experience-card"
   qui sopra; qui solo ciò che il template d'archivio otteneva dal Group
   "constrained" (larghezza massima) più filtro e paginazione, che il
   Query Loop nativo non aveva.
   ----------------------------------------------------------- */
.experiences-grid__wrapper {
	max-width: 1200px;
	margin-inline: auto;
}

/*
 * A larghezza piena (allineamento di default nei pattern e nel template
 * Eventi) i due blocchi griglia annullano il padding orizzontale della
 * pagina: senza questo, su mobile le card toccavano i bordi dello schermo
 * (misurato: 0px a 390px, anche sull'archivio Eventi preesistente). Stesso
 * gutter della pagina, quindi su desktop resta il max-width 1200px.
 */
.experiences-grid.alignfull,
.events-archive.alignfull {
	padding-right: var(--wp--style--root--padding-right);
	padding-left: var(--wp--style--root--padding-left);
}

.experiences-grid__filter {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: var(--wp--preset--spacing--2);
	margin-bottom: var(--wp--preset--spacing--6);
}

.experiences-grid__filter-item {
	padding: var(--wp--preset--spacing--2) var(--wp--preset--spacing--4);
	border: 1px solid var(--wp--preset--color--line);
	border-radius: 100px;
	color: inherit;
	font-size: var(--wp--preset--font-size--sm);
	text-decoration: none;
	transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease;
}

.experiences-grid__filter-item:hover,
.experiences-grid__filter-item.is-active {
	border-color: var(--wp--preset--color--accent);
	background-color: var(--wp--preset--color--accent);
	color: var(--wp--preset--color--white);
}

.experiences-grid__no-results {
	color: var(--wp--preset--color--text-soft);
	text-align: center;
}

.experiences-grid__pagination {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: var(--wp--preset--spacing--2);
	margin-top: var(--wp--preset--spacing--8);
}

.experiences-grid__pagination .page-numbers {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 42px;
	height: 42px;
	padding: 0 var(--wp--preset--spacing--2);
	border: 1px solid var(--wp--preset--color--line);
	border-radius: 100px;
	color: inherit;
	font-size: var(--wp--preset--font-size--sm);
	text-decoration: none;
}

.experiences-grid__pagination a.page-numbers:hover,
.experiences-grid__pagination .page-numbers.current {
	border-color: var(--wp--preset--color--accent);
	background-color: var(--wp--preset--color--accent);
	color: var(--wp--preset--color--white);
}

.experiences-grid__pagination .page-numbers.dots {
	border-color: transparent;
}

/* -----------------------------------------------------------
   experiences-cta — variante a sfondo pieno di .cta-banner, vedi
   patterns/experiences-cta.php per il perché di un pattern separato.
   Stesso caso di ".about-story__quote" più sopra: "alignfull" +
   "layout":{"type":"constrained"} nel pattern (experiences-cta.php ed
   events-cta.php, che riusa questa stessa classe), niente wrapper
   interno — il padding orizzontale reale arriva da "has-global-padding"
   (WordPress, vedi "useRootPaddingAwareAlignments" in theme.json), non
   va azzerato qui o il testo torna a toccare il bordo su mobile.
   ----------------------------------------------------------- */
.experiences-cta {
	padding-top: var(--vik-section-space-y-compact);
	padding-bottom: var(--vik-section-space-y-compact);
	text-align: center;
}

@media (max-width: 1023px) {
	.experiences-cta {
		padding-top: var(--vik-section-space-y-compact-tablet);
		padding-bottom: var(--vik-section-space-y-compact-tablet);
	}
}

@media (max-width: 767px) {
	.experiences-cta {
		padding-top: var(--vik-section-space-y-compact-mobile);
		padding-bottom: var(--vik-section-space-y-compact-mobile);
	}
}

/* -----------------------------------------------------------
   event-card — card evento condivisa tra events-archive (griglia
   archivio, blocks/events-grid) ed events-showcase (carosello homepage,
   blocks/events-showcase). Stesso disegno di .experience-card
   (immagine in alto, corpo scheda sotto, nessun overlay), con l'aggiunta
   del badge data/badge "Concluso" sovrapposti alla foto — vedi
   inc/event-card.php per il markup e inc/event-badge.php per la logica
   dei due badge.
   ----------------------------------------------------------- */
.event-card {
	display: flex;
	flex-direction: column;
	height: 100%;
	overflow: hidden;
	background-color: var(--wp--preset--color--white);
	border: 0.5px solid var(--wp--preset--color--line);
	border-radius: var(--vik-radius);
}

.event-card--past {
	opacity: 0.55;
}

.event-card__media {
	position: relative;
}

.event-card__image {
	display: block;
	width: 100%;
	height: 220px;
	object-fit: cover;
}

.event-card__body {
	display: flex;
	flex: 1;
	flex-direction: column;
	padding: var(--wp--preset--spacing--4);
}

.event-card__title {
	margin: 0 0 var(--wp--preset--spacing--2);
	color: var(--wp--preset--color--ink);
	font-family: var(--wp--preset--font-family--display);
	font-size: var(--wp--preset--font-size--md);
	font-weight: 600;
}

.event-card__title a {
	color: inherit;
	text-decoration: none;
}

.event-card__excerpt {
	margin: 0 0 var(--wp--preset--spacing--4);
	color: var(--wp--preset--color--text-soft);
	font-size: 13px;
}

.event-card__cta {
	display: inline-flex;
	align-items: center;
	gap: var(--wp--preset--spacing--2);
	margin-top: auto;
	color: var(--wp--preset--color--accent);
	font-size: var(--wp--preset--font-size--xs);
	font-weight: 600;
	letter-spacing: 0.08em;
	text-decoration: none;
	text-transform: uppercase;
}

.event-card__cta::after {
	content: "\2192";
	transition: transform 0.2s ease;
}

.event-card__cta:hover::after {
	transform: translateX(4px);
}

/*
 * Titoli troncati a una riga SOLO dentro la vetrina homepage: titoli di
 * lunghezza diversa tra le card visibili contemporaneamente nel carosello
 * sfalsano verticalmente excerpt/CTA sotto. Non applicato a
 * .event-card__title in generale: la griglia archivio (blocks/events-grid)
 * non ha questo vincolo di allineamento riga-per-riga.
 */
.events-showcase .event-card__title {
	display: -webkit-box;
	overflow: hidden;
	line-clamp: 1;
	-webkit-line-clamp: 1;
	-webkit-box-orient: vertical;
}

/* -----------------------------------------------------------
   event-date-badge — badge data overlay in alto a sinistra sulla foto,
   tre formati (giorno singolo / range stesso mese / range a cavallo di
   mese, quest'ultimo con classe modificatrice --compact) — vedi
   inc/event-badge.php. Sfondo chiaro traslucido + sfocatura + ombra
   leggera: unico caso nel tema con box-shadow su un badge, necessaria
   qui perché la foto sotto varia da evento a evento (diversamente dai
   badge su sfondi fissi come .room-badge-price).
   ----------------------------------------------------------- */
.event-date-badge {
	position: absolute;
	top: var(--wp--preset--spacing--3);
	left: var(--wp--preset--spacing--3);
	z-index: 2;
	display: flex;
	flex-direction: column;
	align-items: center;
	min-width: 52px;
	padding: var(--wp--preset--spacing--2) var(--wp--preset--spacing--3);
	background: rgba(250, 250, 248, 0.92);
	backdrop-filter: blur(6px);
	-webkit-backdrop-filter: blur(6px);
	border-radius: var(--vik-radius);
	box-shadow: 0 6px 16px rgba(0, 0, 0, 0.14);
}

.event-date-badge__top {
	font-family: var(--wp--preset--font-family--display);
	font-size: 20px;
	font-weight: 600;
	line-height: 1;
	color: var(--wp--preset--color--ink);
	font-variant-numeric: lining-nums;
}

.event-date-badge__bottom {
	margin-top: var(--wp--preset--spacing--1);
	color: var(--wp--preset--color--text-soft);
	font-size: 9px;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	font-variant-numeric: lining-nums;
}

.event-date-badge--compact {
	min-width: 0;
}

.event-date-badge--compact .event-date-badge__top {
	font-size: 13px;
	white-space: nowrap;
}

/*
 * Badge "Concluso" — stesso linguaggio visivo (non la stessa classe, DOM
 * diverso) di ".vbo-unavailable-block" in vikbooking-overrides.css: pill
 * outline neutra, non colorata. Solo nella sezione "Eventi passati"
 * dell'archivio.
 */
.event-badge-concluso {
	position: absolute;
	top: var(--wp--preset--spacing--3);
	right: var(--wp--preset--spacing--3);
	z-index: 2;
	padding: var(--wp--preset--spacing--1) var(--wp--preset--spacing--3);
	background: rgba(250, 250, 248, 0.9);
	border: 1px solid var(--wp--preset--color--line);
	border-radius: 100px;
	color: var(--wp--preset--color--text-soft);
	font-size: var(--wp--preset--font-size--xs);
	letter-spacing: 0.04em;
	text-transform: uppercase;
}

/* -----------------------------------------------------------
   events-archive — griglia dell'archivio Eventi (blocks/events-grid,
   templates/archive-evento.html). Stesso schema di .experiences-archive
   (righe incomplete allineate a sinistra, nessun placeholder fantasma),
   con l'aggiunta delle due sezioni opzionali Prossimi/Passati.
   ----------------------------------------------------------- */
.events-archive {
	padding-top: var(--vik-section-space-y);
	padding-bottom: var(--vik-section-space-y);
}

@media (max-width: 1023px) {
	.events-archive {
		padding-top: var(--vik-section-space-y-tablet);
		padding-bottom: var(--vik-section-space-y-tablet);
	}
}

@media (max-width: 767px) {
	.events-archive {
		padding-top: var(--vik-section-space-y-mobile);
		padding-bottom: var(--vik-section-space-y-mobile);
	}
}

.events-archive__wrapper {
	max-width: 1200px;
	margin-inline: auto;
}

.events-archive__grid {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--vik-grid-gap);
	margin: 0;
	padding: 0;
	list-style: none;
}

@media (min-width: 768px) {
	.events-archive__grid {
		grid-template-columns: repeat(2, 1fr);
	}
}

@media (min-width: 1024px) {
	.events-archive__grid {
		grid-template-columns: repeat(3, 1fr);
	}
}

.events-archive__no-results {
	color: var(--wp--preset--color--text-soft);
	text-align: center;
}

/*
 * Divisore tra le sezioni "Prossimi eventi"/"Eventi passati" (solo con
 * l'opzione plugin "Mostra eventi passati" attiva): piccola label
 * uppercase + hairline a piena larghezza, stesso linguaggio per
 * entrambe le intestazioni di sezione.
 */
.events-archive__section-label {
	margin: var(--wp--preset--spacing--8) 0 var(--wp--preset--spacing--6);
	text-align: center;
}

.events-archive__section-label:first-child {
	margin-top: 0;
}

.events-archive__section-label span {
	display: inline-block;
	margin-bottom: var(--wp--preset--spacing--3);
	color: var(--wp--preset--color--text-soft);
	font-size: var(--wp--preset--font-size--xs);
	letter-spacing: 0.08em;
	text-transform: uppercase;
}

.events-archive__section-label::after {
	content: "";
	display: block;
	border-top: 1px solid var(--wp--preset--color--line);
}

/* -----------------------------------------------------------
   events-showcase-section — wrapper editoriale (patterns/events-showcase-
   section.php) che dà al blocco vik-base/events-showcase il proprio
   header (eyebrow + H2 + sottotitolo, stesso schema di .packages-featured/
   .amenities-grid-section) e uno sfondo background-alt, per separarlo
   visivamente dalla sezione Pacchetti che lo precede in homepage. Il
   sottotitolo replica lo stile di ".page-header p:last-child" (colonna
   stretta, colore text-soft) invece di un ".section-head p" generico:
   nessun'altra section-head del tema ha ancora un sottotitolo, quindi
   niente utility condivisa finché non serve altrove.
   ----------------------------------------------------------- */
.events-showcase-section .section-head p:last-child {
	max-width: 560px;
	margin-left: auto;
	margin-right: auto;
	margin-top: var(--wp--preset--spacing--3);
	margin-bottom: 0;
	color: var(--wp--preset--color--text-soft);
}

/* -----------------------------------------------------------
   events-showcase — vetrina homepage per gli Eventi (blocks/events-showcase),
   carosello condiviso con experience-card/experiences-carousel (vedi
   inc/carousel-track.php, vik_base_render_carousel_wrapper()). Stesso
   linguaggio visivo di .experiences-carousel per track/frecce.
   ----------------------------------------------------------- */
.events-showcase__wrapper {
	max-width: 1400px;
	margin-inline: auto;
	padding-bottom: var(--wp--preset--spacing--6);
}

.events-showcase__track {
	display: flex;
	gap: var(--wp--preset--spacing--4);
	overflow-x: auto;
	scroll-snap-type: x mandatory;
	scroll-behavior: smooth;
	-webkit-overflow-scrolling: touch;
}

.events-showcase__track > .event-card {
	flex: 0 0 84%;
	scroll-snap-align: start;
}

@media (min-width: 768px) {
	.events-showcase__track > .event-card {
		flex: 0 0 calc( ( 100% - ( var( --vik-carousel-visible, 3 ) - 1 ) * var( --wp--preset--spacing--4 ) ) / var( --vik-carousel-visible, 3 ) );
	}
}

.events-showcase__nav {
	display: flex;
	justify-content: flex-end;
	gap: var(--wp--preset--spacing--2);
	margin-top: var(--wp--preset--spacing--4);
}

.events-showcase__arrow {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	border: 1px solid var(--wp--preset--color--text-soft);
	border-radius: 100px;
	background-color: var(--wp--preset--color--background-alt);
	color: var(--wp--preset--color--ink);
	font-size: var(--wp--preset--font-size--lg);
	cursor: pointer;
	transition: background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease;
}

.events-showcase__arrow:hover {
	background-color: var(--wp--preset--color--accent);
	color: var(--wp--preset--color--white);
}

/*
 * Bottone di chiusura sezione "Vedi tutti gli eventi", sotto il carosello,
 * sempre presente (auto e curata) — pieno/uppercase, distinto per
 * gerarchia visiva dai link testuali "Scopri di più →" delle singole card.
 */
.events-showcase__footer {
	display: flex;
	justify-content: center;
	margin-top: var(--wp--preset--spacing--6);
}

.events-showcase__cta-all {
	display: inline-flex;
	align-items: center;
	padding: var(--wp--preset--spacing--3) var(--wp--preset--spacing--6);
	background-color: var(--wp--preset--color--accent);
	border-radius: var(--vik-radius);
	color: var(--wp--preset--color--white);
	font-size: var(--wp--preset--font-size--xs);
	font-weight: 600;
	letter-spacing: 0.08em;
	text-decoration: none;
	text-transform: uppercase;
	transition: background-color 0.2s ease;
}

.events-showcase__cta-all:hover {
	background-color: var(--wp--preset--color--accent-dark);
}

/*
 * Notice "niente da mostrare" (plugin non attivo / nessun evento
 * selezionato / nessuno più pubblicato): mai un errore sul frontend,
 * visibile solo in editor — stesso meccanismo di
 * .vikbooking-packages__editor-notice.
 */
.events-archive__editor-notice,
.events-showcase__editor-notice,
.experiences-showcase__editor-notice {
	display: none;
	padding: var(--wp--preset--spacing--3) var(--wp--preset--spacing--4);
	background-color: #fdf2d0;
	border: 1px solid #e3c766;
	border-radius: var(--vik-radius);
	color: var(--wp--preset--color--ink);
	font-size: var(--wp--preset--font-size--sm);
}

.editor-styles-wrapper .events-archive__editor-notice,
.editor-styles-wrapper .events-showcase__editor-notice,
.editor-styles-wrapper .experiences-showcase__editor-notice {
	display: block;
	margin-bottom: var(--wp--preset--spacing--4);
}

/*
 * vik-base/experiences-showcase senza esperienze da mostrare (plugin non
 * attivo / nessuna pubblicata / nessuna selezionata): sul frontend il
 * blocco stampa solo il notice qui sopra (visibile solo in editor),
 * quindi frecce e contatore del pattern che lo ospita (experiences-
 * carousel.php/experiences-dark.php) non avrebbero nulla da scorrere —
 * nascosti anche loro.
 */
.experiences-carousel:has(.experiences-showcase--empty) .experiences-carousel__nav,
.experiences-dark:has(.experiences-showcase--empty) .experiences-dark__foot {
	display: none;
}

/* -----------------------------------------------------------
   single-content — colonna di lettura di templates/single-esperienza.html
   e templates/single-evento.html (post-title + post-content, testo
   libero scritto dal cliente in editor: nessun campo strutturato, solo
   il contenitore attorno). Stesso principio di .legal-page-content
   (colonna più stretta della contentSize di pagina per la leggibilità
   di testo denso), qui però via un "contentSize" dedicato sul blocco
   stesso (760px, vedi i due template) invece di padding, dato che il
   blocco non è align:full. Solo l'immagine in evidenza (.single-hero
   sotto, align:"wide" nel template) rompe questa colonna per restare
   più larga — l'unico elemento che lo fa.

   "wideSize":"1200px" è impostato esplicitamente accanto a
   "contentSize" nel layout del blocco (vedi i due template): senza,
   WP genera per quell'istanza la regola
   ".wp-container-...-XXXXXXXX > .alignwide { max-width: 760px }"
   invece di usare var(--wp--style--global--wide-size) — un blocco con
   contentSize custom ma senza un wideSize altrettanto esplicito fa
   presumere al core wideSize == contentSize, quindi "align:wide" sulla
   hero non romperebbe affatto la colonna.

   Sotto i 1023px il viewport scende sotto la contentSize (760px) del
   blocco: da lì in giu margin:auto smette di generare aria ai lati (a
   375px i figli sono letteralmente a 0px dal bordo, misurato) - stesso
   problema/stessa soluzione di .legal-page-content più sopra, padding
   orizzontale esplicito ai due breakpoint sotto, valori identici
   (spacing--6 tablet, spacing--5 mobile).
   ----------------------------------------------------------- */
.single-back-link {
	margin: 0 0 var(--wp--preset--spacing--4);
}

.single-back-link a {
	color: var(--wp--preset--color--accent);
	font-size: var(--wp--preset--font-size--sm);
	font-weight: 600;
	text-decoration: none;
}

.single-back-link a:hover {
	text-decoration: underline;
}

/*
 * single-hero — figure di wp:post-featured-image. Altezza fissa +
 * object-fit:cover (stessa tecnica di ".event-card__image") invece di
 * lasciare l'aspect ratio nativa della foto: oggi la hero occupa quasi
 * l'intera prima schermata perché renderizza a piena altezza intrinseca.
 * position:relative è l'aggancio per il badge data iniettato via PHP
 * su single-evento.html (vik_base_render_event_single_badge(), vedi
 * inc/event-badge.php) — stesso posizionamento assoluto di
 * ".event-date-badge" dentro ".event-card__media".
 */
.single-hero.wp-block-post-featured-image {
	position: relative;
	margin: 0 0 var(--wp--preset--spacing--7);
}

.single-hero.wp-block-post-featured-image img {
	display: block;
	width: 100%;
	height: 480px;
	object-fit: cover;
	border-radius: var(--vik-radius);
}

.single-content .wp-block-post-title {
	margin: 0 0 var(--wp--preset--spacing--6);
	font-family: var(--wp--preset--font-family--display);
	font-size: 42px;
	font-weight: 500;
	line-height: 1.15;
}

@media (max-width: 1023px) {
	.single-content {
		padding-left: var(--wp--preset--spacing--6);
		padding-right: var(--wp--preset--spacing--6);
	}

	.single-hero.wp-block-post-featured-image img {
		height: 380px;
	}
}

@media (max-width: 767px) {
	.single-content {
		padding-left: var(--wp--preset--spacing--5);
		padding-right: var(--wp--preset--spacing--5);
	}

	.single-hero.wp-block-post-featured-image img {
		height: 260px;
	}

	.single-content .wp-block-post-title {
		font-size: 30px;
	}
}

/* -----------------------------------------------------------
   error-404 — templates/404.html. Pagina centrata verticalmente e
   orizzontalmente nello spazio sotto l'header (non un blocco in cima
   seguito da vuoto): flex column su ".error-404" invece del layout
   "constrained" nativo, perché qui non c'è alcun elemento che debba
   rompere la colonna in larghezza (a differenza di .single-content) —
   solo testo/CTA centrati, quindi la larghezza di lettura è un
   semplice max-width sul sottotitolo, non contentSize/wideSize.
   "--header-height" è la stessa custom property scritta da
   assets/js/header-height.js e già riusata da ".hero-bg.is-height-full"
   per lo stesso motivo (altezza reale dell'header, diversa tra
   desktop/mobile perché la nav va a capo sotto il logo).
   ----------------------------------------------------------- */
.error-404 {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	min-height: calc(100vh - var(--header-height, 80px));
	padding: var(--wp--preset--spacing--9) var(--wp--preset--spacing--5);
	text-align: center;
}

/*
 * font-variant-numeric:lining-nums — senza, Cormorant Garamond rende le
 * cifre in "oldstyle figures" (altezze/discendenti disomogenee, es. lo
 * "0" più basso del "4"), lo stesso bug già noto e risolto allo stesso
 * modo su ".event-date-badge__top" in questo file.
 */
.error-404__code {
	margin: 0 0 var(--wp--preset--spacing--2);
	color: var(--wp--preset--color--accent);
	font-family: var(--wp--preset--font-family--display);
	font-size: 160px;
	font-weight: 500;
	line-height: 1;
	font-variant-numeric: lining-nums;
}

.error-404__title {
	margin: 0 0 var(--wp--preset--spacing--4);
	font-size: 34px;
	font-weight: 500;
}

.error-404__subtitle {
	max-width: 460px;
	margin: 0 auto var(--wp--preset--spacing--7);
	color: var(--wp--preset--color--text-soft);
}

.error-404__actions {
	gap: var(--wp--preset--spacing--5);
}

.error-404__actions .wp-block-button__link {
	border-radius: var(--vik-radius);
}

@media (max-width: 1023px) {
	.error-404__code {
		font-size: 120px;
	}
}

/* -----------------------------------------------------------
   site-footer — colonne, contatti, riga finale

   Il padding della sezione vive qui (non come style inline sul blocco
   wp:group in parts/footer.html) proprio per poterlo ridurre sotto i
   767px senza "!important": uno style attribute sul blocco batterebbe
   comunque qualunque selettore di classe, indipendentemente dalla sua
   specificità.
   ----------------------------------------------------------- */
footer {
	margin-block-start: 0px;
}
.site-footer {
	padding: var(--wp--preset--spacing--9) var(--wp--preset--spacing--8) var(--wp--preset--spacing--6);
}

.site-footer a {
	color: rgba(255, 255, 255, 0.78);
	text-decoration: none;
	transition: color 200ms ease;
}

.site-footer a:hover {
	color: var(--wp--preset--color--accent);
}

.site-footer__brand-name,
.site-footer__brand-name a {
	font-family: var(--wp--preset--font-family--display);
	font-size: 30px;
	font-weight: 500;
	color: var(--wp--preset--color--white);
}

.site-footer__tagline {
	margin-top: var(--wp--preset--spacing--2);
	max-width: 220px;
	font-size: var(--wp--preset--font-size--sm);
	color: var(--vik-overlay-ivory);
}

.site-footer__social {
	margin-top: var(--wp--preset--spacing--6);
}

.site-footer__social .wp-block-social-link-anchor {
	width: 40px;
	height: 40px;
	border: 1px solid rgba(255, 255, 255, 0.25);
	border-radius: 50%;
	transition: background-color 200ms ease, border-color 200ms ease;
	justify-content: center;
}

.site-footer__social .wp-block-social-link-anchor:hover {
	background-color: var(--wp--preset--color--accent);
	border-color: var(--wp--preset--color--accent);
}

.site-footer__label {
	margin-bottom: var(--wp--preset--spacing--4);
	font-size: 11px;
	font-weight: 600;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: rgba(255, 255, 255, 0.52);
}

.site-footer__nav .wp-block-navigation-item__content {
	font-size: var(--wp--preset--font-size--sm);
}

.site-footer__contact-row {
	align-items: center;
	margin-bottom: var(--wp--preset--spacing--3);
}

.site-footer__contact-row--address {
	align-items: flex-start;
}

.site-footer__contact-row p {
	font-size: var(--wp--preset--font-size--sm);
	line-height: 1.5;
}

.site-footer__divider {
	margin-top: var(--wp--preset--spacing--8);
	border-top-color: rgba(255, 255, 255, 0.14);
}

.site-footer__bottom {
	padding-top: var(--wp--preset--spacing--5);
}

.site-footer__copyright,
.site-footer__copyright p,
.site-footer__legal {
	margin: 0;
	font-size: var(--wp--preset--font-size--xs);
	color: rgba(255, 255, 255, 0.52);
}

.site-footer__legal a {
	color: rgba(255, 255, 255, 0.6);
}

@media (max-width: 1023px) {
	.site-footer {
		padding-right: var(--wp--preset--spacing--6);
		padding-left: var(--wp--preset--spacing--6);
	}

	.site-footer__columns.wp-block-columns {
		row-gap: var(--wp--preset--spacing--7);
	}
}

@media (max-width: 767px) {
	.site-footer {
		padding-top: var(--wp--preset--spacing--7);
		padding-right: var(--wp--preset--spacing--5);
		padding-left: var(--wp--preset--spacing--5);
	}

	.site-footer__bottom {
		flex-direction: column;
		align-items: flex-start;
		gap: var(--wp--preset--spacing--3);
	}
}

@media (max-width: 767px) {
	.error-404__code {
		font-size: 88px;
	}

	.error-404__title {
		font-size: 28px;
	}

	.error-404__actions {
		flex-direction: column;
		gap: var(--wp--preset--spacing--3);
	}
}
