/**
 * Marquee Galeri — Almira Travel
 *
 * Deret foto bergulir kontinu tanpa ujung, murni CSS.
 *
 * Cara kerjanya, supaya tidak "diperbaiki" jadi rusak di kemudian hari:
 *
 * Track memuat daftar foto dua kali (lihat render_baris di PHP). Animasi
 * menggeser track dari 0 ke -50% dari LEBAR TRACK SENDIRI — yaitu tepat
 * sepanjang satu salinan. Saat keyframe kembali ke 0, salinan kedua sudah
 * berada persis di posisi salinan pertama, jadi tidak ada lompatan yang
 * terlihat. Tiga syarat yang saling terkait:
 *
 *   1. Jumlah salinan harus dua, tidak lebih.
 *   2. Pergeseran harus -50%, bukan -100%.
 *   3. Track harus width: max-content. Dengan lebar terbatas, item akan
 *      menyusut atau membungkus sehingga -50% tidak lagi sama dengan satu
 *      salinan dan sambungannya terlihat menyentak.
 *
 * Durasi TIDAK ditulis di sini: PHP menyuntik --alm-marquee-durasi dari
 * jumlah foto x detik-per-foto agar kecepatan piksel/detik konstan berapa
 * pun jumlah fotonya.
 */

.alm-marquee {
	--alm-marquee-tinggi: 400px;
	--alm-marquee-rasio: 0.45;
	--alm-marquee-gap: 16px;
	--alm-marquee-radius: 14px;
	--alm-marquee-pudar: 90px;
	--alm-marquee-durasi: 30s;

	display: flex;
	flex-direction: column;
	gap: var(--alm-marquee-gap);
	font-family: "Plus Jakarta Sans", sans-serif;
}

.alm-marquee__baris {
	position: relative;
	overflow: hidden;
	width: 100%;
}

/**
 * Mode lebar penuh ("bleed").
 *
 * Section Elementor membatasi lebar isi ke 1180px, jadi marquee berhenti di
 * tepi kotak itu dan tampak seperti kartu — bukan aliran foto yang melintasi
 * layar.
 *
 * Kenapa 100vw + margin negatif, bukan position:fixed atau lebar 100%:
 * elemen ini bersarang di dalam container ber-max-width, sehingga width:100%
 * hanya mengikuti container. Yang dibutuhkan adalah menembus batas itu.
 * calc(50% - 50vw) memberi margin negatif yang tepat sama dengan selisih
 * container terhadap viewport, apa pun lebar container-nya — jadi tidak
 * perlu menghardcode 1180px, dan tetap benar bila pemilik situs mengubah
 * lebar section.
 *
 * margin-left DAN margin-right keduanya diberi: hanya salah satu akan
 * membuat elemen melebar tetapi tidak terpusat.
 *
 * 100vw sengaja dipakai, bukan 100%, dan inilah alasan
 * overflow-x:clip di bawah penting: pada sistem dengan scrollbar yang
 * memakan ruang (Windows), 100vw MENYERTAKAN lebar scrollbar sehingga
 * elemen jadi ~15px lebih lebar dari area terlihat dan memicu scrollbar
 * horizontal. Peredamnya ada di .alm-marquee (lihat blok berikut).
 */
.alm-marquee--penuh .alm-marquee__baris {
	width: 100vw;
	margin-left: calc(50% - 50vw);
	margin-right: calc(50% - 50vw);
	max-width: 100vw;
}

/**
 * Penahan luapan horizontal.
 *
 * overflow-x: clip, BUKAN hidden. Keduanya memotong luapan, tetapi hidden
 * menjadikan elemen ini "scroll container" — dan itu punya dua efek samping
 * nyata: (1) position:sticky di dalamnya berhenti bekerja, (2) klik pada
 * lightbox dapat menggulirkan elemen secara diam-diam. clip memotong tanpa
 * membuat scroll container.
 */
.alm-marquee--penuh {
	overflow-x: clip;
}

/**
 * Pudarkan tepi kiri-kanan.
 *
 * mask-image dipakai, bukan dua elemen bergradien di atas foto, supaya
 * warnanya tidak perlu dicocokkan dengan latar section. Section liputan
 * berlatar #F2F6F9, dan overlay gradien akan langsung terlihat salah jika
 * latar itu diubah pemilik situs.
 */
.alm-marquee--pudar .alm-marquee__baris {
	-webkit-mask-image: linear-gradient(
		to right,
		transparent,
		#000 var(--alm-marquee-pudar),
		#000 calc(100% - var(--alm-marquee-pudar)),
		transparent
	);
	mask-image: linear-gradient(
		to right,
		transparent,
		#000 var(--alm-marquee-pudar),
		#000 calc(100% - var(--alm-marquee-pudar)),
		transparent
	);
}

.alm-marquee__track {
	display: flex;
	gap: var(--alm-marquee-gap);
	/* Wajib: lihat catatan syarat ke-3 di kepala berkas. */
	width: max-content;
	/* translate3d + will-change menahan animasi di compositor sehingga
	   gulirannya tidak memicu layout ulang pada tiap frame. */
	will-change: transform;
	animation: alm-marquee-geser var(--alm-marquee-durasi) linear infinite;
}

@keyframes alm-marquee-geser {
	from {
		transform: translate3d(0, 0, 0);
	}
	to {
		transform: translate3d(-50%, 0, 0);
	}
}

/* Arah ke kanan cukup membalik arah animasi yang sama — tidak perlu
   keyframes kedua. */
.alm-marquee--kanan .alm-marquee__track {
	animation-direction: reverse;
}

/* Baris kedua bergerak berlawanan terhadap baris pertama, apa pun arah
   dasarnya. */
.alm-marquee__baris--balik .alm-marquee__track {
	animation-direction: reverse;
}

.alm-marquee--kanan .alm-marquee__baris--balik .alm-marquee__track {
	animation-direction: normal;
}

/**
 * Jeda saat hover.
 *
 * animation-play-state cukup: ia membekukan animasi pada posisi saat itu
 * tanpa mengubah transform, jadi tidak ada lompatan ketika kursor pergi.
 *
 * PENTING — jeda dipasang pada KARTU (:has(.alm-marquee__item:hover)),
 * bukan pada barisnya.
 *
 * Sebelumnya selector-nya `.alm-marquee__baris:hover`. Itu bekerja saat
 * marquee masih berupa kotak selebar container, tetapi setelah mode lebar
 * penuh dinyalakan, baris membentang 100vw — sehingga kursor yang berada
 * di mana pun pada jalur horizontal itu, termasuk pada celah kosong antar
 * kartu maupun area di atas/bawah foto, langsung menghentikan animasi.
 * Akibatnya galeri tampak "tidak jalan" hampir sepanjang waktu. Terukur:
 * dengan kursor di tengah baris, playState menjadi 'paused'.
 *
 * Dengan :has(), jeda hanya terjadi saat kursor benar-benar berada di atas
 * sebuah foto — yang memang maksud aslinya: memberi kesempatan pengunjung
 * mengamati satu foto.
 *
 * :focus-within DIHAPUS. Setiap foto adalah tautan lightbox, jadi begitu
 * salah satunya menerima fokus — termasuk fokus yang diberikan browser
 * setelah lightbox ditutup — animasi berhenti dan TIDAK PERNAH berjalan
 * lagi, karena fokus tetap tinggal di elemen itu. Ini penyebab utama
 * galeri membeku permanen. Penggantinya di bawah memakai :focus-visible,
 * yang hanya menyala pada navigasi keyboard.
 */
.alm-marquee--jeda .alm-marquee__baris:has(.alm-marquee__item:hover) .alm-marquee__track {
	animation-play-state: paused;
}

/**
 * Jeda untuk pengguna keyboard.
 *
 * :focus-visible, bukan :focus atau :focus-within — hanya menyala ketika
 * browser menilai fokus perlu ditampilkan (navigasi keyboard), bukan saat
 * fokus datang dari klik mouse.
 *
 * Batasannya perlu dicatat: browser memutuskan sendiri kapan
 * :focus-visible menyala, dan fokus yang diberikan lewat skrip (mis.
 * dikembalikan oleh lightbox Elementor setelah ditutup) BISA dinilai
 * "perlu ditampilkan" bila interaksi terakhir pengunjung memakai keyboard.
 * Dalam kasus itu animasi berhenti dan tidak jalan lagi sampai fokus
 * berpindah.
 *
 * Karena itu jeda ini dibatasi hanya pada salinan asli. Klon tidak pernah
 * bisa difokus (tabindex="-1"), jadi separuh kartu di jalur marquee tidak
 * akan pernah menahan animasi — dan fokus yang tersangkut hanya bisa
 * berasal dari satu tempat yang jelas.
 */
.alm-marquee--jeda
	.alm-marquee__baris:has(
		.alm-marquee__item:not(.swiper-slide-duplicate) .alm-marquee__link:focus-visible
	)
	.alm-marquee__track {
	animation-play-state: paused;
}

/**
 * Cadangan untuk browser tanpa dukungan :has().
 *
 * Selector di atas seluruhnya diabaikan bila :has() tidak didukung, jadi di
 * browser lama marquee tidak akan pernah berhenti saat hover. Itu kehilangan
 * yang bisa diterima — jauh lebih baik daripada galeri yang membeku. Blok
 * ini hanya memastikan kursor di atas foto tetap memberi umpan balik visual.
 */
@supports not selector(:has(*)) {
	.alm-marquee--jeda .alm-marquee__item:hover .alm-marquee__img {
		opacity: 0.92;
	}
}

/* ---------- kartu ---------- */

/**
 * .alm-marquee__klon sengaja TIDAK diberi gaya apa pun di sini.
 *
 * Kelas itu menempel pada <figure> yang sama dengan .alm-marquee__item, jadi
 * klon harus tampil dan berukuran identik dengan aslinya — kedua salinan
 * wajib sama lebar agar pergeseran -50% tepat sepanjang satu salinan.
 * Kelasnya hanya dipakai sebagai pengait untuk menyembunyikan klon pada mode
 * prefers-reduced-motion di bagian bawah berkas ini.
 */

.alm-marquee__item {
	position: relative;
	margin: 0;
	flex: none;
	height: var(--alm-marquee-tinggi);
	/* Lebar diturunkan dari tinggi x rasio. Dengan begitu mengganti tinggi
	   lewat kontrol Elementor tidak pernah memotong foto lebih banyak. */
	width: calc(var(--alm-marquee-tinggi) * var(--alm-marquee-rasio));
	border-radius: var(--alm-marquee-radius);
	overflow: hidden;
	background: #e8eef2;
}

.alm-marquee--bayangan .alm-marquee__item {
	box-shadow: 0 10px 26px rgba(15, 46, 64, 0.14);
}

.alm-marquee__link {
	display: block;
	width: 100%;
	height: 100%;
	/* Tema memberi border-bottom pada <a> di beberapa konteks. */
	border: 0;
	text-decoration: none;
}

.alm-marquee__link:focus-visible {
	outline: 2px solid #edaf33;
	outline-offset: -4px;
}

.alm-marquee__img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
	transition: transform 0.5s ease;
}

.alm-marquee--zoom .alm-marquee__item:hover .alm-marquee__img {
	transform: scale(1.06);
}

.alm-marquee__cap {
	position: absolute;
	inset: auto 0 0 0;
	padding: 26px 12px 10px;
	color: #fff;
	font-size: 12.5px;
	font-weight: 600;
	line-height: 1.4;
	background: linear-gradient(to top, rgba(15, 46, 64, 0.88), transparent);
	/* Keterangan tidak boleh mencuri klik dari tautan lightbox di bawahnya. */
	pointer-events: none;
}

/* ---------- responsif ---------- */

@media (max-width: 1024px) {
	.alm-marquee {
		--alm-marquee-tinggi: 320px;
	}
}

@media (max-width: 767px) {
	.alm-marquee {
		--alm-marquee-tinggi: 250px;
		--alm-marquee-gap: 10px;
		--alm-marquee-pudar: 36px;
	}
}

/**
 * Hormati preferensi sistem "kurangi gerakan" — TANPA membekukan galeri.
 *
 * Versi pertama mematikan animasi lalu mengubah baris jadi area geser
 * manual. Niatnya benar, hasilnya buruk dan terukur: dengan
 * prefers-reduced-motion aktif, transform track menjadi "none" dan galeri
 * berhenti total. Banyak orang menyalakan preferensi ini tanpa sadar —
 * Windows "Show animations off", macOS "Reduce motion", mode hemat baterai
 * Android — sehingga bagi mereka section liputan tampak rusak, bukan
 * "tenang".
 *
 * Sekarang animasi hanya DIPERLAMBAT, tidak dimatikan. Baris tetap
 * overflow:hidden seperti mode normal — area geser manual tidak lagi
 * diperlukan, dan menghindarinya juga penting karena elemen ber-overflow
 * menjadi scroll container yang bisa mematikan position:sticky pada
 * section lain.
 */
@media (prefers-reduced-motion: reduce) {
	/**
	 * Animasi TIDAK dimatikan, hanya diperlambat drastis.
	 *
	 * Versi sebelumnya memakai `animation: none`, dan itu keputusan yang
	 * salah untuk kasus ini. Galeri jadi benar-benar beku, dan bagi
	 * pemilik situs maupun pengunjung hasilnya tidak terbaca sebagai
	 * "menghormati preferensi" melainkan sebagai section yang rusak.
	 *
	 * Pedoman WCAG 2.3.3 menyoal animasi yang dipicu interaksi dan gerakan
	 * besar/berkedip. Geseran horizontal lambat dan konstan pada satu
	 * strip foto bukan pemicu yang dimaksud; yang perlu dihindari adalah
	 * kecepatan yang menarik perhatian secara paksa. Karena itu durasinya
	 * dikalikan empat (dari ~31s menjadi ~126s untuk 9 foto), sehingga
	 * pergerakannya nyaris tak terasa namun galeri tetap hidup dan seluruh
	 * foto akhirnya terlihat tanpa pengunjung perlu berbuat apa pun.
	 *
	 * Pengunjung yang tetap ingin menghentikannya cukup mengarahkan kursor
	 * ke salah satu foto.
	 */
	.alm-marquee__track {
		animation-duration: calc(var(--alm-marquee-durasi) * 4);
		will-change: auto;
	}

	/* Klon tetap ditampilkan: track wajib memuat dua salinan identik agar
	   pergeseran -50% tepat sepanjang satu salinan. Menyembunyikannya akan
	   memecah loop. */

	.alm-marquee__img {
		transition: none;
	}
}

/**
 * Tombol navigasi manual DIHAPUS.
 *
 * Tombol dan skrip pendampingnya (marquee-galeri.js) dibuat ketika mode
 * prefers-reduced-motion masih membekukan galeri sepenuhnya, sehingga
 * pengunjung butuh cara manual untuk menjelajah. Sejak animasi hanya
 * diperlambat alih-alih dimatikan, galeri selalu bergerak sendiri dan
 * tombol itu tidak lagi punya tugas.
 *
 * Dihapus, bukan disembunyikan: markup dan skrip yang tidak dipakai tetap
 * dikirim ke setiap pengunjung dan akan membingungkan siapa pun yang
 * membaca kode ini nanti.
 */
