/*!
 * WP-ImmoMakler vertical-thumbs gallery preset.
 *
 * Layout: main image on the left, vertical column of thumbnails on the right.
 * Hover-shows the prev/next buttons on both swipers. Up/down nav buttons on
 * the thumb strip are opt-out via the `show_thumb_nav` preset option.
 *
 * All visual knobs are exposed as CSS custom properties on the gallery
 * wrapper. Defaults are sensible for the WP-ImmoMakler default skin and
 * also represent the legacy Divi single-property gallery look. Override
 * via custom CSS or theme-builder per-instance inline `<style>` blocks.
 */

.immomakler-gallery--vertical_thumbs {

	/* Layout */
	--immomakler-gallery-gap: 10px;

	/*
	 * Thumb-strip width — the column width on the right. Each thumb's
	 * width equals this; height derives via
	 * `aspect-ratio: var(--immomakler-gallery-thumb-aspect)`. The number
	 * of thumbs visible adapts to gallery height / (width / aspect)
	 * automatically. Customers override via the Customizer's "Breite
	 * der Vorschauleiste (px)" option — exposed only when the
	 * vertical-thumbs layout is selected, so the variable name matches
	 * the user's mental model. The horizontal-thumbs preset has its
	 * own strip-height variable (see preset-horizontal-thumbs.css).
	 */
	--immomakler-gallery-vertical-thumb-width: 200px;
	--immomakler-gallery-main-aspect: 16 / 9;
	--immomakler-gallery-thumb-aspect: 16 / 9;

	/* Colors — primary color is overridden by the skin from
	 * `ImmoMakler_Options::get('link_color')` via `wp_add_inline_style`,
	 * and by the Divi module per-instance from the `controls_color` prop. */
	--immomakler-gallery-primary-color: #af1615;
	--immomakler-gallery-primary-color-inverted: #fff;

	/* Opacity */
	--immomakler-gallery-nav-opacity: 0.8;
	--immomakler-gallery-thumb-nav-opacity: 0.5;
	--immomakler-gallery-thumb-nav-opacity-hover: 0.9;
	--immomakler-gallery-thumb-default-opacity: 0.6;

	/* Sizing */
	--immomakler-gallery-nav-button-size: 30px;

	/*
	 * Hit-area width for the main-image prev/next buttons. The visible
	 * round button stays `--immomakler-gallery-nav-button-size`, but the
	 * <button> element itself extends to this width × 100% height — a
	 * wide invisible target that's much easier to land a click on
	 * (Fitts's Law). Reference: riedel-immobilien.de gallery.
	 */
	--immomakler-gallery-nav-clickarea-width: 45px;
	--immomakler-gallery-thumb-nav-height: 20px;

	/* Swiper-bundle's own variable for nav-button horizontal offset from the
	 * swiper edges. Default is 10px; the slightly larger 12px gives the round
	 * primary-color buttons more breathing room and matches the legacy Divi
	 * gallery's positioning. */
	--swiper-navigation-sides-offset: 12px;

	display: grid;
	grid-template-columns: 1fr var(--immomakler-gallery-vertical-thumb-width);
	gap: var(--immomakler-gallery-gap);

	/*
	 * `width: 100%` is required (not just `max-width: 100%`): without it the
	 * grid container sizes to content, the inner `.swiper` inherits an
	 * unbounded `width: 100%` from swiper-bundle.css, and Swiper computes
	 * each slide's width from the maxed-out container.
	 *
	 * Wrapper HEIGHT is pre-allocated via the `::before` spacer (defined
	 * just below): a zero-content pseudo-element in the main grid cell
	 * with `aspect-ratio: var(--immomakler-gallery-main-aspect)` and
	 * `width: 100%`, which establishes the grid row track at
	 * `main_column_width × main_aspect_inverse` — exactly the height JS
	 * (`syncVerticalThumbsHeight` in the loader) would otherwise set
	 * after measurement.
	 *
	 * Why this also requires `contain: size` on the thumbs swiper: post
	 * Swiper-init the thumbs swiper has `direction: 'vertical'`, so its
	 * slides stack column-wise and the wrapper's intrinsic content height
	 * sums every slide — without `contain` that sum would dominate the
	 * row track and squash the main image. The `contain: size` rule on
	 * `.immomakler-gallery__thumbs` (further below) tells the browser
	 * the swiper's box size is independent of its content, so the
	 * spacer's aspect-ratio wins the row-track size battle. Together the
	 * two rules give zero CLS on first paint AND the customer-configured
	 * main_aspect post-init, without needing JS to measure the layout.
	 *
	 * The JS function still runs as a safety net (handles `auto` aspect
	 * — the "Original" customizer option — where CSS aspect-ratio can't
	 * pre-compute a height because the image's natural aspect isn't known
	 * until load).
	 */
	width: 100%;
	max-width: 100%;
	overflow: hidden;
}

/*
 * `::before` spacer establishes the row track height via aspect-ratio.
 *
 * Sits in the same cell as the main swiper (`grid-column: 1; grid-row: 1`)
 * and is empty content — its only job is to be tall. `width: 100%` of the
 * grid cell gives it the main column's width; `aspect-ratio` then derives
 * the height (`main_column_width × main_aspect_inverse`). The grid row
 * track sizes to the spacer (the thumbs swiper's content is excluded from
 * row sizing via `contain: size` on `.immomakler-gallery__thumbs`).
 *
 * The actual main swiper, overlapping in the same cell, has `height: 100%`
 * and fills the row track. Visual stack works because grid items in the
 * same cell render in source order — `::before` is generated before
 * `.immomakler-gallery__main` so the swiper paints on top of the (empty,
 * invisible) spacer.
 */
.immomakler-gallery--vertical_thumbs::before {
	content: "";
	grid-column: 1;
	grid-row: 1;
	width: 100%;
	aspect-ratio: var(--immomakler-gallery-main-aspect);
	min-width: 0;
}

/* ---------- Main swiper ---------- */

.immomakler-gallery--vertical_thumbs .immomakler-gallery__main {

	/*
	 * Stacked in the same cell as the ::before spacer (col 1, row 1).
	 * Overlap is intentional: the spacer dictates the row height; main
	 * fills the cell. `height: 100%` resolves against the row track that
	 * the spacer established.
	 */
	grid-column: 1;
	grid-row: 1;
	position: relative;
	width: 100%;
	min-width: 0;
	height: 100%;
	overflow: hidden;
	user-select: none;

	/*
	 * Per-image rounding. Customer-configurable via the Customizer's
	 * "Rundung der Ecken (px)" option (shared with the static gallery
	 * presets). Falls back to 0 when unset — paints nothing visible.
	 * Wrapper-mode (`--rounded-wrapper` class) cancels this at the
	 * bottom of the file in favor of rounding the whole wrapper.
	 */
	border-radius: var(--immomakler-gallery-border-radius, 0);
}

.immomakler-gallery--vertical_thumbs .immomakler-gallery__main .swiper-slide {
	overflow: hidden;
	cursor: zoom-in;
	width: 100%;
}

.immomakler-gallery--vertical_thumbs .immomakler-gallery__main .swiper-slide img.immomakler-gallery__image,
.immomakler-gallery--vertical_thumbs .immomakler-gallery__main .swiper-slide picture > img.immomakler-gallery__image {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}

/* ---------- Main nav buttons (wide click area + round visible button) ----------
 *
 * See preset-horizontal-thumbs.css for the full rationale. Same pattern: the
 * <button> is a full-height, 45px-wide invisible click zone flush against the
 * swiper edge; the visible round button is a centered `::before` pseudo.
 * Wider hit-area → easier to click (Fitts's Law).
 */

.immomakler-gallery--vertical_thumbs .immomakler-gallery__prev,
.immomakler-gallery--vertical_thumbs .immomakler-gallery__next {
	width: var(--immomakler-gallery-nav-clickarea-width);
	height: 100%;
	top: 0;
	margin-top: 0;

	/* No visible background — that's the ::before's job. */
	background: transparent;
	border-radius: 0;

	/* Center the SVG icon (and the ::before visible button) inside the
	 * click zone, vertically and horizontally. */
	display: flex;
	align-items: center;
	justify-content: center;

	color: var(--immomakler-gallery-primary-color-inverted);
	visibility: hidden;
}

/* Pin prev/next flush against the swiper edges. */
.immomakler-gallery--vertical_thumbs .immomakler-gallery__prev {
	left: 0;
	right: auto;
}

.immomakler-gallery--vertical_thumbs .immomakler-gallery__next {
	right: 0;
	left: auto;
}

/* Visible round button — pseudo-element centered in the click area. */
.immomakler-gallery--vertical_thumbs .immomakler-gallery__prev::before,
.immomakler-gallery--vertical_thumbs .immomakler-gallery__next::before {
	content: "";
	position: absolute;
	top: 50%;
	left: 50%;
	transform: translate(-50%, -50%);
	width: var(--immomakler-gallery-nav-button-size);
	height: var(--immomakler-gallery-nav-button-size);
	background-color: var(--immomakler-gallery-primary-color);
	border-radius: 50%;
	opacity: var(--immomakler-gallery-nav-opacity);
	transition: opacity 200ms ease, background-color 200ms ease;
}

/*
 * Nav arrow — a CSS-masked chevron on the `::after` pseudo-element rather
 * than Swiper's injected `.swiper-navigation-icon` SVG. See the matching
 * block in preset-horizontal-thumbs.css for the full rationale (the SVG goes
 * missing in the Elementor editor preview even though the slider works; a
 * CSS-masked chevron is init-context-independent). Coloured via
 * `--immomakler-gallery-primary-color-inverted` and centred on the `::before`
 * circle. Swiper's own injected SVG is suppressed below — the `::after`
 * chevron replaces it.
 */
.immomakler-gallery--vertical_thumbs .swiper-navigation-icon {
	display: none;
}

.immomakler-gallery--vertical_thumbs .immomakler-gallery__prev::after,
.immomakler-gallery--vertical_thumbs .immomakler-gallery__next::after {
	content: "";
	position: absolute;
	top: 50%;
	left: 50%;
	z-index: 1;
	width: var(--immomakler-gallery-nav-button-size);
	height: var(--immomakler-gallery-nav-button-size);
	transform: translate(-50%, -50%);
	background-color: var(--immomakler-gallery-primary-color-inverted);
	-webkit-mask-repeat: no-repeat;
	mask-repeat: no-repeat;
	-webkit-mask-position: center;
	mask-position: center;
	-webkit-mask-size: 42% 42%;
	mask-size: 42% 42%;
}

.immomakler-gallery--vertical_thumbs .immomakler-gallery__prev::after {
	-webkit-mask-image: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%3E%3Cpath%20d='M15%204L7%2012l8%208'%20fill='none'%20stroke='%23000'%20stroke-width='2.5'%20stroke-linecap='round'%20stroke-linejoin='round'/%3E%3C/svg%3E");
	mask-image: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%3E%3Cpath%20d='M15%204L7%2012l8%208'%20fill='none'%20stroke='%23000'%20stroke-width='2.5'%20stroke-linecap='round'%20stroke-linejoin='round'/%3E%3C/svg%3E");
}

.immomakler-gallery--vertical_thumbs .immomakler-gallery__next::after {
	-webkit-mask-image: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%3E%3Cpath%20d='M9%204l8%208-8%208'%20fill='none'%20stroke='%23000'%20stroke-width='2.5'%20stroke-linecap='round'%20stroke-linejoin='round'/%3E%3C/svg%3E");
	mask-image: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%3E%3Cpath%20d='M9%204l8%208-8%208'%20fill='none'%20stroke='%23000'%20stroke-width='2.5'%20stroke-linecap='round'%20stroke-linejoin='round'/%3E%3C/svg%3E");
}

.immomakler-gallery--vertical_thumbs .immomakler-gallery__prev.swiper-button-disabled,
.immomakler-gallery--vertical_thumbs .immomakler-gallery__next.swiper-button-disabled {
	pointer-events: auto;
}

.immomakler-gallery--vertical_thumbs .immomakler-gallery__prev.swiper-button-disabled::before,
.immomakler-gallery--vertical_thumbs .immomakler-gallery__next.swiper-button-disabled::before {
	background-color: #666;
}

/* ---------- Thumbs swiper ---------- */

.immomakler-gallery--vertical_thumbs .immomakler-gallery__thumbs {

	/*
	 * In col 2 (the fixed thumbs-width column). `height: 100%` resolves
	 * against the row track that the ::before spacer established. The
	 * spacer makes the row track equal to main's intended height, so the
	 * thumbs container fills that height. Swiper's `overflow: hidden`
	 * (from swiper-bundle.css) clips slide content beyond this height,
	 * and Swiper's vertical-direction handles scrolling.
	 *
	 * `contain: size` is essential: post-init the thumbs swiper has
	 * `direction: 'vertical'`, slides stack column-wise, and the
	 * swiper-wrapper's intrinsic content height = sum of all slide
	 * heights — which would dominate the grid row-track sizing (the
	 * spacer's aspect-ratio'd height would lose). `contain: size` tells
	 * the browser this element's box-size doesn't depend on its content,
	 * so its contribution to row sizing is its CSS-defined `height: 100%`
	 * (= the row track itself — a no-op contribution). The spacer wins.
	 *
	 * Browser support: Chrome 52+, Firefox 69+, Safari 15.4+, Edge 79+.
	 */
	grid-column: 2;
	grid-row: 1;
	position: relative;
	width: 100%;
	min-width: 0;
	height: 100%;
	contain: size;
}

.immomakler-gallery--vertical_thumbs .immomakler-gallery__thumbs .swiper-slide {
	aspect-ratio: var(--immomakler-gallery-thumb-aspect);
	cursor: pointer;
	height: auto !important;

	/*
	 * Flex items default to `min-height: auto` (= min-content). The thumb
	 * image (intrinsic 165×110 = aspect 3:2) creates a min-content floor of
	 * `slideWidth × 110/165 ≈ 133px` at slideWidth=200. Declared heights
	 * smaller than that — for example 16:9's aspect-derived 112.5px, or our
	 * JS-set inline `style="height: 112.5px"` — get silently clamped UP to
	 * the floor. Result: 16:9 looks identical to 3:2 because both render
	 * at 133px.
	 *
	 * `min-height: 0 !important` disables the floor. The slide can now
	 * render at its declared height regardless of the image's intrinsic
	 * dimensions. `!important` is needed because flex's `min-height: auto`
	 * default is treated as a UA hint; our override has to be explicit.
	 */
	min-height: 0 !important;
	opacity: var(--immomakler-gallery-thumb-default-opacity);
	transition: opacity 100ms ease;

	/*
	 * Per-image rounding — `overflow: hidden` so the rounded box clips
	 * the contained `<img>` (which has its own intrinsic corners).
	 * Wrapper-mode cancels this at the bottom of the file.
	 */
	overflow: hidden;
	border-radius: var(--immomakler-gallery-border-radius, 0);
}

.immomakler-gallery--vertical_thumbs .immomakler-gallery__thumbs .swiper-slide:hover,
.immomakler-gallery--vertical_thumbs .immomakler-gallery__thumbs .swiper-slide-thumb-active {
	opacity: 1;
}

.immomakler-gallery--vertical_thumbs .immomakler-gallery__thumbs .swiper-slide img.immomakler-gallery__image,
.immomakler-gallery--vertical_thumbs .immomakler-gallery__thumbs .swiper-slide picture > img.immomakler-gallery__image {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}

/* ---------- Up/down thumb-nav arrows (opt-out via show_thumb_nav option) ---------- */

.immomakler-gallery--vertical_thumbs .immomakler-gallery__thumbs-prev,
.immomakler-gallery--vertical_thumbs .immomakler-gallery__thumbs-next {
	position: absolute;
	left: 0;
	width: 100%;
	height: var(--immomakler-gallery-thumb-nav-height);
	z-index: 2;
	color: var(--immomakler-gallery-primary-color-inverted);
	background-color: var(--immomakler-gallery-primary-color);
	opacity: var(--immomakler-gallery-thumb-nav-opacity);
	border: 0;
	margin: 0;
	padding: 0;
	cursor: pointer;
	line-height: var(--immomakler-gallery-thumb-nav-height);
	text-align: center;
	transition: opacity 500ms ease;
	visibility: hidden;
}

.immomakler-gallery--vertical_thumbs .immomakler-gallery__thumbs-prev::after,
.immomakler-gallery--vertical_thumbs .immomakler-gallery__thumbs-next::after {
	display: block;
	color: inherit;

	/*
	 * Caret sized to ~50% of the button height so it sits comfortably in the
	 * 20px-tall button without filling it edge-to-edge. Browser default
	 * font-size (~16px) would otherwise render the ▲/▼ glyphs nearly as tall
	 * as the button.
	 */
	font-size: calc(var(--immomakler-gallery-thumb-nav-height) * 0.6);
	line-height: 1;
}

.immomakler-gallery--vertical_thumbs .immomakler-gallery__thumbs-prev::after {
	content: "▲";
}

.immomakler-gallery--vertical_thumbs .immomakler-gallery__thumbs-next::after {
	content: "▼";
}

.immomakler-gallery--vertical_thumbs .immomakler-gallery__thumbs-prev {
	top: 0;
}

.immomakler-gallery--vertical_thumbs .immomakler-gallery__thumbs-next {
	bottom: 0;
}

.immomakler-gallery--vertical_thumbs .immomakler-gallery__thumbs-prev:hover,
.immomakler-gallery--vertical_thumbs .immomakler-gallery__thumbs-next:hover {
	opacity: var(--immomakler-gallery-thumb-nav-opacity-hover);
}

/*
 * Disabled state — at the strip's top/bottom.
 *
 * Two-stage fade animation (see preset-horizontal-thumbs.css for the full
 * rationale): the button first visibly grays (clear "end reached" cue),
 * then fades fully transparent and stops absorbing clicks via
 * `pointer-events: none` at the final keyframe.
 */
.immomakler-gallery--vertical_thumbs .immomakler-gallery__thumbs-prev.swiper-button-disabled,
.immomakler-gallery--vertical_thumbs .immomakler-gallery__thumbs-next.swiper-button-disabled {
	cursor: default;
	animation: immomakler-gallery-thumb-nav-fade 1.5s forwards;
}

@keyframes immomakler-gallery-thumb-nav-fade {

	0% {
		background-color: var(--immomakler-gallery-primary-color);
		opacity: var(--immomakler-gallery-thumb-nav-opacity);
		pointer-events: auto;
	}

	30% {
		background-color: #666;
		opacity: 0.4;
		pointer-events: auto;
	}

	100% {
		background-color: #666;
		opacity: 0;
		pointer-events: none;
	}
}

/* ---------- Hover-show all nav buttons (matches the legacy Divi behavior)
 *
 * Mouse: show on `:hover`, hide on mouseleave.
 * Keyboard: show when something inside is keyboard-focused
 * (`:has(:focus-visible)`); stay hidden after mouse clicks even though the
 * clicked button retains focus (`:focus-visible` does NOT match
 * mouse-click focus, which is what we want — clicking a button shouldn't
 * pin the nav row visible after the cursor leaves).
 */
.immomakler-gallery--vertical_thumbs:hover .immomakler-gallery__prev,
.immomakler-gallery--vertical_thumbs:hover .immomakler-gallery__next,
.immomakler-gallery--vertical_thumbs:hover .immomakler-gallery__thumbs-prev,
.immomakler-gallery--vertical_thumbs:hover .immomakler-gallery__thumbs-next,
.immomakler-gallery--vertical_thumbs:has(:focus-visible) .immomakler-gallery__prev,
.immomakler-gallery--vertical_thumbs:has(:focus-visible) .immomakler-gallery__next,
.immomakler-gallery--vertical_thumbs:has(:focus-visible) .immomakler-gallery__thumbs-prev,
.immomakler-gallery--vertical_thumbs:has(:focus-visible) .immomakler-gallery__thumbs-next {
	visibility: visible;
}

/* ---------- Mobile: collapse thumbs at 768px (matches the legacy Divi breakpoint)
 *
 * Default behaviour: thumbs are hidden on narrow screens (≤ 768px) — they're
 * usually too small to be useful on mobile, and giving the main image the full
 * width is a better experience. Customers can opt in to keeping the thumbs
 * visible on mobile via the Customizer's "Vorschaubilder auch auf
 * Mobilgeräten anzeigen" toggle, which adds the
 * `.immomakler-gallery--show-mobile-thumbs` modifier class to the wrapper
 * (see `gallery-swiper.php` for the wiring).
 */

@media (max-width: 768px) {

	.immomakler-gallery--vertical_thumbs {
		grid-template-columns: 1fr;
	}

	/* Spacer + main both still in col 1 / row 1; no change needed. */

	.immomakler-gallery--vertical_thumbs .immomakler-gallery__thumbs {
		display: none;
	}

	/* Opt-in: keep thumbs visible on mobile. */
	.immomakler-gallery--vertical_thumbs.immomakler-gallery--show-mobile-thumbs {
		grid-template-columns: 1fr var(--immomakler-gallery-vertical-thumb-width);
	}

	.immomakler-gallery--vertical_thumbs.immomakler-gallery--show-mobile-thumbs .immomakler-gallery__thumbs {
		display: block;
	}
}

/* ---------- Pagination dots (over the main image, only when thumbs hidden)
 *
 * See preset-horizontal-thumbs.css for the full rationale. Same pattern:
 * hidden by default, shown on `.immomakler-gallery--no-thumbs` (would only
 * apply if a future variant of vertical_thumbs renders without thumbs —
 * currently no such case ships, but the rule is symmetric and harmless)
 * and on mobile (≤ 768px) when the responsive media query has hidden the
 * thumbs column.
 */
.immomakler-gallery--vertical_thumbs .immomakler-gallery__pagination {
	display: none;
	position: absolute;
	bottom: 8px;
	left: 0;
	right: 0;
	width: 100%;
	text-align: center;
	z-index: 1;
}

.immomakler-gallery--vertical_thumbs.immomakler-gallery--no-thumbs .immomakler-gallery__pagination {
	display: block;
}

@media (max-width: 768px) {

	.immomakler-gallery--vertical_thumbs:not(.immomakler-gallery--show-mobile-thumbs) .immomakler-gallery__pagination {
		display: block;
	}
}

.immomakler-gallery--vertical_thumbs .immomakler-gallery__pagination .swiper-pagination-bullet {
	width: 8px;
	height: 8px;
	background: #fff;
	opacity: 0.6;
	margin: 0 4px;
	border-radius: 50%;
	display: inline-block;
	transition: opacity 150ms ease, background-color 150ms ease;
	cursor: pointer;
	box-shadow: 0 0 4px rgba(0, 0, 0, 0.5);
}

.immomakler-gallery--vertical_thumbs .immomakler-gallery__pagination .swiper-pagination-bullet-active {
	background: var(--immomakler-gallery-primary-color);
	opacity: 1;
}

/* ---------- "Wrapper rounded" modifier ----------
 *
 * Active when the Customizer's "Rundung anwenden auf" is "Gesamtgalerie".
 * The wrapper already has `overflow: hidden` (declared up top for the grid
 * layout, which also incidentally clips overflowing thumb slides at the
 * row-track edges). Adding `border-radius` rounds the visible bounding
 * box; the per-image radii on the main image and thumb slides (declared
 * inline in their main rule blocks above) are cancelled — only the OUTER
 * corners of the gallery are rounded.
 *
 * Mirrors the pattern used by the static_compact / static_fullwidth presets
 * (see preset-static-compact.css for the rationale).
 */
.immomakler-gallery--vertical_thumbs.immomakler-gallery--rounded-wrapper {
	border-radius: var(--immomakler-gallery-border-radius, 0);
}

.immomakler-gallery--vertical_thumbs.immomakler-gallery--rounded-wrapper .immomakler-gallery__main,
.immomakler-gallery--vertical_thumbs.immomakler-gallery--rounded-wrapper .immomakler-gallery__thumbs .swiper-slide {
	border-radius: 0;
}
