/**
 * Image Hotspots block – shared styles (frontend + editor canvas).
 *
 * Class contract mirrors the editor preview (edit.js + editor.css):
 * .wpminty-ih-image frame, .wpminty-ih__img base image, .wpminty-ih__marker
 * hotspots placed by percentage coordinates, and the front-end-only
 * .wpminty-ih__popover tooltips. The popover is anchored by the view
 * script through Floating UI (fixed strategy + inline transform).
 *
 * Breakpoints mirror theme.json settings.viewport (mobile 600px,
 * tablet 960px) statically.
 */

/*
 * Frame: keeps its height while the base image loads through the
 * --wpminty-ih-ratio variable set inline by render.php.
 */
.wpminty-ih-image {
	position: relative;
	aspect-ratio: var(--wpminty-ih-ratio, 16 / 9);
}

/* Base image: auto-fits its natural size up to the container width.
 * Never object-fit: cover – hotspot coordinates are percentages of the
 * rendered box, and cover would crop the image, shifting the pinned
 * subjects away from their markers. */
.wpminty-ih__img {
	display: block;
	max-width: 100%;
	height: auto;
	border-radius: inherit;
}

/*
 * Hotspot markers: placed by inline left/top percentages (plus the matching
 * --wpminty-ih-x/y custom properties) and centered through the translate
 * offset. The marker glyph (svg icon or text label) is real markup inside
 * the button (see render.php / edit.js); ::before stays reserved for the
 * ripple attention ring and ::after for the mobile expanded hit area.
 * Appearance comes from wrapper variables: marker color, glyph color,
 * border width/color/radius, plus the glyph geometry pair marker-icon-size /
 * marker-padding. The marker size is content-driven — icon size plus the
 * inner padding on each side (16px + 2x4px = 24px at defaults) — and
 * box-sizing: border-box keeps any border inside that box.
 */
.wpminty-ih__marker {
	display: flex;
	align-items: center;
	justify-content: center;
	position: absolute;
	top: var(--wpminty-ih-y, 50%);
	left: var(--wpminty-ih-x, 50%);
	box-sizing: border-box;
	padding: var(--wpminty-ih-marker-padding, 4px);
	border: var(--wpminty-ih-marker-border-width, 0px) solid var(--wpminty-ih-marker-border-color, transparent);
	border-radius: var(--wpminty-ih-marker-radius, 50%);
	transform: translate(-50%, -50%);
	background: var(--wpminty-ih-marker-color, #fff);
	box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.25);
	color: var(--wpminty-ih-marker-icon-color, rgba(0, 0, 0, 0.55));
	font: inherit;
	cursor: pointer;
	transition:
		transform 120ms ease-in-out,
		background-color 120ms ease-in-out,
		box-shadow 120ms ease-in-out;
}

/*
 * Marker glyph. Icons size to the --wpminty-ih-marker-icon-size token and
 * flex-center in the padded marker slot; the marker box itself grows to
 * fit (icon size + 2x padding), so no overflow clamping is needed. Text
 * labels share the same token as their font-size and clamp to a single
 * line capped near 1.6x the marker width. Both ignore pointer events so
 * the button keeps owning the gesture.
 */
svg.wpminty-ih__glyph {
	display: block;
	width: var(--wpminty-ih-marker-icon-size, 16px);
	height: var(--wpminty-ih-marker-icon-size, 16px);
	pointer-events: none;
}

.wpminty-ih__glyph--text {
	display: block;
	overflow: hidden;
	max-width: calc((var(--wpminty-ih-marker-icon-size, 16px) + var(--wpminty-ih-marker-padding, 4px) * 2) * 1.6);
	font-size: var(--wpminty-ih-marker-icon-size, 16px);
	font-weight: 600;
	line-height: 1;
	white-space: nowrap;
	text-overflow: ellipsis;
	pointer-events: none;
}

.wpminty-ih__marker:hover {
	transform: translate(-50%, -50%) scale(1.12);
}

/* Open marker: previews the active color. Falls back to the regular marker
 * color when no active color is set. */
.wpminty-ih__marker.is-active {
	background: var(--wpminty-ih-marker-active-color, var(--wpminty-ih-marker-color, #fff));
}

/* Keyboard focus ring: white outline plus a dark halo reads on both
 * light and dark imagery. */
.wpminty-ih__marker:focus-visible {
	outline: 2px solid #fff;
	outline-offset: 3px;
	box-shadow:
		0 0 0 2px rgba(0, 0, 0, 0.25),
		0 0 0 5px rgba(0, 0, 0, 0.35);
}

/*
 * Attention (ambient) effects, block-level on every marker. Each preset
 * owns a property channel the hover scale never touches (scale /
 * rotate / box-shadow / pseudo ring geometry), mirroring the ButtonIcon
 * channel separation: hover keeps the transform channel, attention uses
 * the individual transform properties, so both can run at once. All
 * rules sit behind the motion preference; reduced-motion users get a
 * static marker.
 *
 * Glow is the DEFAULT effect: the base marker rule carries it, and
 * render.php emits no attn class for the 'glow' preset. The explicit
 * --attn-{grow,swing,glow,ripple} classes swap in their preset, and
 * --attn-none cancels the animation entirely.
 */
@media (prefers-reduced-motion: no-preference) {

	/* Default: every marker breathes the glow ring unless a preset
	 * class overrides the animation. */
	.wpminty-ih__marker {
		animation: wpminty-ih-attn-glow 2.2s ease-in-out infinite;
	}

	/* Preset overrides use the doubled-class pattern (0-2-0 specificity)
	 * so they reliably beat the 0-1-0 base glow rule regardless of
	 * cascade order after stylesheet minify/merge. */

	/* Explicit 'None' choice: cancel the base glow animation. */
	.wpminty-ih__marker.wpminty-ih__marker--attn-none {
		animation: none;
	}

	.wpminty-ih__marker.wpminty-ih__marker--attn-grow {
		animation: wpminty-ih-attn-grow 2s ease-in-out infinite;
	}

	.wpminty-ih__marker.wpminty-ih__marker--attn-swing {
		animation: wpminty-ih-attn-swing 1.6s ease-in-out infinite;
	}

	.wpminty-ih__marker.wpminty-ih__marker--attn-glow {
		animation: wpminty-ih-attn-glow 2.2s ease-in-out infinite;
	}

	/* Ripple: two hairline rings expanding out of the marker on a 1.5s
	 * cycle, the second phase-shifted by .5s. Rings are pseudo-element
	 * boxes (absolute, inset 0, border-box) so they never affect layout.
	 * Below 600px the ::after slot is claimed back by the touch hit
	 * area (see the mobile block), leaving the ::before ring there.
	 * The rings animate on the pseudo-elements while the marker itself
	 * must silence the base glow — otherwise both effects layer. */
	.wpminty-ih__marker.wpminty-ih__marker--attn-ripple {
		animation: none;
	}

	.wpminty-ih__marker--attn-ripple::before,
	.wpminty-ih__marker--attn-ripple::after {
		content: "";
		position: absolute;
		inset: 0;
		box-sizing: border-box;
		border: 1px solid var(--wpminty-ih-marker-color, #fff);
		border-radius: inherit;
		pointer-events: none;
		animation: wpminty-ih-attn-ripple 1.5s ease-out infinite;
	}

	.wpminty-ih__marker--attn-ripple::after {
		animation-delay: 0.5s;
	}
}

@keyframes wpminty-ih-attn-grow {

	0%,
	100% {
		scale: 1;
	}

	50% {
		scale: 1.12;
	}
}

@keyframes wpminty-ih-attn-swing {

	0%,
	100% {
		rotate: 0deg;
	}

	25% {
		rotate: 10deg;
	}

	75% {
		rotate: -10deg;
	}
}

/* Glow keeps the base dark halo and breathes a spread ring in the marker
 * color. Animating box-shadow is paint-only on this tiny element. */
@keyframes wpminty-ih-attn-glow {

	0%,
	100% {
		box-shadow:
			0 0 0 2px rgba(0, 0, 0, 0.25),
			0 0 0 0 color-mix(in srgb, var(--wpminty-ih-marker-color, #fff) 40%, transparent);
	}

	50% {
		box-shadow:
			0 0 0 2px rgba(0, 0, 0, 0.25),
			0 0 0 9px color-mix(in srgb, var(--wpminty-ih-marker-color, #fff) 40%, transparent);
	}
}

@keyframes wpminty-ih-attn-ripple {

	0% {
		scale: 1;
		opacity: 0.8;
	}

	100% {
		scale: 2.1;
		opacity: 0;
	}
}

/*
 * Touch comfort below the mobile breakpoint (600px): an invisible
 * ::after expands the hit area to at least 44px without changing the
 * visual marker. Pointer hit testing includes pseudo-element boxes. The
 * ripple variant override below restores the hit-area geometry for the
 * ::after slot the ripple ring would otherwise own (its ring selector
 * is more specific than the plain marker one).
 */
@media (max-width: 600px) {

	.wpminty-ih__marker::after,
	.wpminty-ih__marker--attn-ripple::after {
		content: "";
		position: absolute;
		top: 50%;
		left: 50%;
		width: max(44px, calc(var(--wpminty-ih-marker-icon-size, 16px) + var(--wpminty-ih-marker-padding, 4px) * 2 + 20px));
		height: max(44px, calc(var(--wpminty-ih-marker-icon-size, 16px) + var(--wpminty-ih-marker-padding, 4px) * 2 + 20px));
		transform: translate(-50%, -50%);
		border-radius: 50%;
	}

	/* The ripple ::before ring keeps animating on small screens; only
	 * the second (::after) ring yields its slot to the hit area. */
	.wpminty-ih__marker--attn-ripple::after {
		inset: auto;
		border: none;
		scale: 1;
		opacity: 1;
		animation: none;
	}
}

/*
 * Popover tooltip.
 *
 * Base geometry: fixed-positioned at the viewport origin so the view
 * script can place it with a single inline transform (translate x/y
 * from Floating UI). The explicit longhand resets cancel the UA popover
 * sheet (inset: 0 / margin: auto / border: solid / padding / Canvas
 * colors) so the tooltip matches the editor preview look.
 *
 * The popover box itself never clips (overflow visible) because the
 * ::after arrow lives just outside the border box; scrolling and the
 * height cap belong to the inner .wpminty-ih__popover-body instead.
 *
 * Unified popover styling flows from wrapper custom properties (see
 * render.php): background, text, border width/color and radius. The
 * fallbacks equal the attribute defaults, so a block without custom
 * popover settings renders with this exact look.
 */
.wpminty-ih__popover {
	position: fixed;
	top: 0;
	left: 0;
	right: auto;
	bottom: auto;
	z-index: 100000; /* Fallback stacking context; the top layer ignores it. */
	box-sizing: border-box;
	width: min(var(--wpminty-ih-tooltip-width, 260px), calc(100vw - 2rem));
	max-width: min(var(--wpminty-ih-tooltip-width, 260px), calc(100vw - 2rem));
	max-height: none;
	margin: 0;

	/* Explicit override of the UA [popover] default (overflow: auto),
	 * which would clip the ::after arrow placed just outside the border
	 * box and raise a scrollbar from the 8px overflow. The inner
	 * .wpminty-ih__popover-body owns scrolling and the height cap (a
	 * scroll container here would clip the arrow — even overflow-y
	 * alone computes overflow-x to auto). */
	overflow: visible;
	overscroll-behavior: contain;
	padding: 0;
	border: var(--wpminty-ih-popover-border-width, 0px) solid var(--wpminty-ih-popover-border-color, transparent);
	border-radius: var(--wpminty-ih-popover-radius, 5px);
	background: var(--wpminty-ih-popover-bg, #fff);
	box-shadow: 0 6px 24px rgba(0, 0, 0, 0.16);
	color: var(--wpminty-ih-popover-text, #1e1e1e);
	text-align: left;
	opacity: 0;

	/* Entrance uses the independent translate property so it composes
	 * with the JS-owned inline transform instead of fighting it. */
	translate: 0 6px;
	transition:
		opacity 160ms ease-out,
		translate 160ms ease-out;
}

/*
 * Visibility model:
 * - Popover API browsers: the UA sheet hides [popover]; :popover-open
 *   re-shows it and doubles as the transition/animation target.
 * - Legacy browsers (no Popover API): the [popover] attribute has no UA
 *   rule, so the explicit display: none below keeps tooltips hidden;
 *   the view script's .is-open class is the fallback show state.
 */
.wpminty-ih__popover[popover] {
	display: none;
}

.wpminty-ih__popover:popover-open,
.wpminty-ih__popover.is-open {
	display: block;
	opacity: 1;
	translate: 0 0;
}

/* Inner scroll container: keeps the popover box itself unclipped so
 * the arrow renders, while long tooltip content still scrolls within
 * the 60vh cap. */
.wpminty-ih__popover-body {
	max-height: 60vh;
	overflow-y: auto;
	overscroll-behavior: contain;
	padding: clamp(12px, 2vw, 20px);
}

/* Entrance animation. @starting-style support implies :popover-open
 * support; older browsers simply show the popover without a transition. */
@starting-style {

	.wpminty-ih__popover:popover-open,
	.wpminty-ih__popover.is-open {
		opacity: 0;
		translate: 0 6px;
	}
}

/* Optional media inside the tooltip. */
.wpminty-ih__popover-media {
	margin: 0 0 12px;
}

.wpminty-ih__popover-media .wpminty-ih__popover-img {
	display: block;
	width: auto;
	max-width: 100%;
	height: auto;
	border-radius: 6px;
}

.wpminty-ih__popover-title {
	margin: 0 0 6px;
	font-size: 16px;
	font-weight: 600;
	line-height: 1.3;
	color: var(--wpminty-ih-popover-title-color, inherit);
}

.wpminty-ih__popover-content {
	margin: 0;
	font-size: 14px;
	line-height: 1.55;
}

.wpminty-ih__popover-content p {
	margin: 0 0 8px;
}

.wpminty-ih__popover-content p:last-child {
	margin-bottom: 0;
}

.wpminty-ih__popover-content ul,
.wpminty-ih__popover-content ol {
	margin: 0 0 8px;
	padding-left: 1.25em;
}

/* Inline links inside the tooltip body follow the popover text color
 * instead of the theme link color, keeping the unified popover look. */
.wpminty-ih__popover-content a {
	color: inherit;
}

/*
 * CTA link. Solid variant (default): background from the dedicated btn-bg
 * token (falling back to the legacy btn-color accent), text from btn-text.
 * Button border geometry flows from the btn-border-* tokens; the radius
 * defaults to 0 (square button) and can be rounded via the panel control.
 */
.wpminty-ih__popover-link {
	display: inline-flex;
	align-items: center;
	margin-top: 12px;
	padding: 7px 14px;
	border: var(--wpminty-ih-popover-btn-border-width, 0px) solid var(--wpminty-ih-popover-btn-border-color, transparent);
	border-radius: var(--wpminty-ih-popover-btn-radius, 0px);
	background: var(--wpminty-ih-popover-btn-bg, var(--wpminty-ih-popover-btn-color, #1e1e1e));
	color: var(--wpminty-ih-popover-btn-text, #fff);
	font-size: 14px;
	font-weight: 500;
	line-height: 1.2;
	text-decoration: none;
	transition:
		background-color 120ms ease-in-out,
		border-color 120ms ease-in-out,
		color 120ms ease-in-out;
}

/* Solid hover/focus: the button color darkened. */
.wpminty-ih__popover-link:hover,
.wpminty-ih__popover-link:focus-visible {
	background: color-mix(in srgb, var(--wpminty-ih-popover-btn-bg, var(--wpminty-ih-popover-btn-color, #1e1e1e)) 82%, #000);
	color: var(--wpminty-ih-popover-btn-text, #fff);
}

.wpminty-ih__popover-link:focus-visible {
	outline: 2px solid #fff;
	outline-offset: 2px;
}

/* Outline variant (wrapper class from render.php): transparent fill
 * with the button color carrying both the border and the text. */
.wpminty-ih--btn-outline .wpminty-ih__popover-link {
	border-color: var(--wpminty-ih-popover-btn-color, #1e1e1e);
	background: transparent;
	color: var(--wpminty-ih-popover-btn-color, #1e1e1e);
}

.wpminty-ih--btn-outline .wpminty-ih__popover-link:hover,
.wpminty-ih--btn-outline .wpminty-ih__popover-link:focus-visible {
	border-color: color-mix(in srgb, var(--wpminty-ih-popover-btn-color, #1e1e1e) 82%, #000);
	background: transparent;
	color: color-mix(in srgb, var(--wpminty-ih-popover-btn-color, #1e1e1e) 82%, #000);
}

/*
 * Popover shadow presets (wrapper class from render.php; 'md' is the
 * base .wpminty-ih__popover shadow above and needs no class). These sit
 * before the mobile sheet block so the sheet's dedicated top-edge
 * shadow — kept for every preset, since a docked sheet reads as broken
 * without it — keeps winning in the source order.
 */
.wpminty-ih--shadow-none .wpminty-ih__popover {
	box-shadow: none;
}

.wpminty-ih--shadow-sm .wpminty-ih__popover {
	box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12);
}

.wpminty-ih--shadow-md .wpminty-ih__popover {
	box-shadow: 0 6px 24px rgba(0, 0, 0, 0.16);
}

.wpminty-ih--shadow-lg .wpminty-ih__popover {
	box-shadow:
		0 10px 20px rgba(0, 0, 0, 0.15),
		0 24px 48px rgba(0, 0, 0, 0.22);
}

/*
 * Popover arrow (CSS triangle via ::after).
 *
 * The arrow points from the popover edge toward the marker. Direction
 * is driven by data-placement on the popover element itself (render.php
 * seeds it, the view script updates it after Floating UI computePosition
 * resolves). Floating UI semantics: placement "top" puts the popover
 * ABOVE the marker, so the arrow sits on the popover's bottom edge and
 * points down — every rule below follows that mapping. Only the base
 * direction is used (top/bottom/left/right); variant suffixes like
 * -start/-end are stripped.
 *
 * ::before is reserved for the mobile drag handle (see below). The arrow
 * is hidden on mobile where the popover becomes a bottom sheet.
 *
 * The triangle uses the border trick: a zero-sized element with
 * transparent side borders and one colored edge. Positioning places the
 * colored edge flush with the popover outer border edge.
 */
.wpminty-ih__popover:popover-open::after,
.wpminty-ih__popover.is-open::after {
	content: "";
	position: absolute;
	width: 0;
	height: 0;
	display: none;
}

/* Arrow pointing down — popover is above the marker (placement top). */
.wpminty-ih__popover:popover-open[data-placement="top"]::after,
.wpminty-ih__popover.is-open[data-placement="top"]::after {
	display: block;
	bottom: calc(-1 * var(--wpminty-ih-popover-arrow-size, 8px));
	left: 50%;
	transform: translateX(-50%);
	border-left: var(--wpminty-ih-popover-arrow-size, 8px) solid transparent;
	border-right: var(--wpminty-ih-popover-arrow-size, 8px) solid transparent;
	border-top: var(--wpminty-ih-popover-arrow-size, 8px) solid var(--wpminty-ih-popover-bg, #fff);
}

/* Arrow pointing up — popover is below the marker (placement bottom). */
.wpminty-ih__popover:popover-open[data-placement="bottom"]::after,
.wpminty-ih__popover.is-open[data-placement="bottom"]::after {
	display: block;
	top: calc(-1 * var(--wpminty-ih-popover-arrow-size, 8px));
	left: 50%;
	transform: translateX(-50%);
	border-left: var(--wpminty-ih-popover-arrow-size, 8px) solid transparent;
	border-right: var(--wpminty-ih-popover-arrow-size, 8px) solid transparent;
	border-bottom: var(--wpminty-ih-popover-arrow-size, 8px) solid var(--wpminty-ih-popover-bg, #fff);
}

/* Arrow pointing right — popover is left of the marker (placement left). */
.wpminty-ih__popover:popover-open[data-placement="left"]::after,
.wpminty-ih__popover.is-open[data-placement="left"]::after {
	display: block;
	right: calc(-1 * var(--wpminty-ih-popover-arrow-size, 8px));
	top: 50%;
	transform: translateY(-50%);
	border-top: var(--wpminty-ih-popover-arrow-size, 8px) solid transparent;
	border-bottom: var(--wpminty-ih-popover-arrow-size, 8px) solid transparent;
	border-left: var(--wpminty-ih-popover-arrow-size, 8px) solid var(--wpminty-ih-popover-bg, #fff);
}

/* Arrow pointing left — popover is right of the marker (placement right). */
.wpminty-ih__popover:popover-open[data-placement="right"]::after,
.wpminty-ih__popover.is-open[data-placement="right"]::after {
	display: block;
	left: calc(-1 * var(--wpminty-ih-popover-arrow-size, 8px));
	top: 50%;
	transform: translateY(-50%);
	border-top: var(--wpminty-ih-popover-arrow-size, 8px) solid transparent;
	border-bottom: var(--wpminty-ih-popover-arrow-size, 8px) solid transparent;
	border-right: var(--wpminty-ih-popover-arrow-size, 8px) solid var(--wpminty-ih-popover-bg, #fff);
}

/*
 * Mobile bottom sheet (≤600px): any open popover docks to the bottom of
 * the viewport. The view script skips Floating UI positioning in this
 * mode and clears the inline transform, so these styles own the layout.
 */
@media (max-width: 600px) {

	.wpminty-ih__popover:popover-open,
	.wpminty-ih__popover.is-open {
		top: auto;
		right: 0;
		bottom: 0;
		left: 0;
		width: 100%;
		max-width: 100%;
		max-height: 60vh;
		border-radius: var(--wpminty-ih-popover-radius, 5px) var(--wpminty-ih-popover-radius, 5px) 0 0;
		border-bottom: none;
		box-shadow: 0 -8px 32px rgba(0, 0, 0, 0.22);
		overflow: visible;

		/* Slide-up entrance for the sheet variant. */
		translate: 0 0;
	}

	/* Extra headroom above the content for the drag-handle bar. */
	.wpminty-ih__popover:popover-open .wpminty-ih__popover-body,
	.wpminty-ih__popover.is-open .wpminty-ih__popover-body {
		padding-top: calc(clamp(12px, 2vw, 20px) + 12px);
	}

	@starting-style {

		.wpminty-ih__popover:popover-open,
		.wpminty-ih__popover.is-open {
			opacity: 0;
			translate: 0 40px;
		}
	}

	/* Drag-handle bar: purely visual affordance for the sheet. */
	.wpminty-ih__popover::before {
		content: "";
		position: absolute;
		top: 8px;
		left: 50%;
		width: 36px;
		height: 4px;
		border-radius: 999px;
		background: rgba(0, 0, 0, 0.15);
		transform: translateX(-50%);
	}

	/* Arrow is hidden on mobile (bottom sheet has no anchored marker). */
	.wpminty-ih__popover::after {
		display: none;
	}
}

/*
 * Tablet (601–960px): the standard anchored tooltip applies; the global
 * width clamp (min(var, 100vw - 2rem)) already keeps it inside the
 * narrower viewport, so no extra rules are needed.
 */

/* Skeleton placeholder shown until an image is chosen. */
.wpminty-ih__placeholder {
	margin: 0;
	padding: 24px;
	background: #f0f0f0;
	color: #757575;
	font-size: 14px;
	text-align: center;
}

/* Respect reduced-motion preferences: swap transitions for instant
 * state changes. */
@media (prefers-reduced-motion: reduce) {

	.wpminty-ih__marker,
	.wpminty-ih__popover,
	.wpminty-ih__popover-link {
		transition: none;
	}
}
