/*
 * Superior Homes Modal -- core engine styles.
 *
 * Structure (all dialogs share this shape):
 *
 *   dialog.shk-modal            <- the native <dialog>; also the sizing box
 *     .shk-modal__dialog        <- inner flex wrapper (padding, layout)
 *       .shk-modal__close       <- close button
 *       .shk-modal__content     <- scrollable content region
 *
 * There is no separate ".shk-modal__overlay" element: the native
 * <dialog>'s own ::backdrop pseudo-element is used instead. It is more
 * reliable than a hand-built overlay div (correct stacking in the
 * browser's top layer, no z-index fights with the rest of the page) and
 * is still fully styleable via dialog.shk-modal::backdrop below.
 *
 * Every size/spacing value has a var() fallback, so this file works even
 * if the theme's tokens.css is absent or the theme changes later. Where
 * a Superior Homes token of the same name already exists (--color-*,
 * --space-*, --radius-*, --transition), it is reused automatically.
 */

:root {
	--shk-modal-width: 640px;
	--shk-modal-max-width: 92vw;
	--shk-modal-max-height: 85vh;
	--shk-modal-viewport-margin: 16px; /* extra outer gap enforced on top of --shk-modal-max-width/-height, see dialog.shk-modal below */
	--shk-modal-radius: var(--radius-md, 8px);
	--shk-modal-bg: var(--color-white, #fff);
	--shk-modal-text: var(--color-text, #1f1f1f);
	--shk-modal-overlay-color: rgba(0, 0, 0, 0.55);
	--shk-modal-padding: var(--space-lg, 32px);
	--shk-modal-gap: var(--space-sm, 16px);
	--shk-modal-transition: var(--transition, 0.25s ease);
	--shk-modal-shadow: 0 20px 60px rgba(0, 0, 0, 0.25);

	/* Close button (v1.1.0, per-modal overridable -- see
	   Renderer::build_style()). Defaults below reproduce the exact
	   pre-v1.1.0 hardcoded appearance. */
	--shk-modal-close-size: 36px;
	--shk-modal-close-icon-size: 20px;
	--shk-modal-close-bg: rgba(0, 0, 0, 0.06);
	--shk-modal-close-color: var(--shk-modal-text);
	--shk-modal-close-radius: 50%;
	--shk-modal-close-top-space: var(--shk-modal-gap);
	--shk-modal-close-right-space: var(--shk-modal-gap);
}

/* -------------------------------------------------------------------- */
/* Body scroll lock, applied to <html> while any SHK modal is open.     */
/* -------------------------------------------------------------------- */

html.shk-modal-open {
	overflow: hidden;
}

/* -------------------------------------------------------------------- */
/* The dialog itself.                                                   */
/* -------------------------------------------------------------------- */

dialog.shk-modal {
	box-sizing: border-box;
	width: var(--shk-modal-width);
	/* min() layers --shk-modal-viewport-margin on top of the existing
	   --shk-modal-max-width/-height constraints as a floor, not a
	   replacement -- whichever constraint is tighter wins, so raising the
	   margin can only ever pull the modal further from the viewport edge,
	   never override a deliberately larger --shk-modal-max-width/-height.
	   The default 16px margin only binds below ~400px viewport width,
	   where the mobile rules further down already take over -- so it
	   changes nothing about current desktop sizing. */
	max-width: min(var(--shk-modal-max-width), calc(100vw - (var(--shk-modal-viewport-margin) * 2)));
	max-height: min(var(--shk-modal-max-height), calc(100vh - (var(--shk-modal-viewport-margin) * 2)));
	margin: auto;
	padding: 0;
	border: 0;
	border-radius: var(--shk-modal-radius);
	background: var(--shk-modal-bg);
	color: var(--shk-modal-text);
	box-shadow: var(--shk-modal-shadow);
	/* visible, not hidden: lets .shk-modal__close--outside (below) render
	   as a badge straddling the corner instead of being clipped off at
	   it. The rounded-corner content clipping this used to do moves to
	   .shk-modal__dialog just below instead -- .shk-modal__content's own
	   overflow-y:auto (further down) is the actual scroll mechanism and
	   is unaffected either way. */
	overflow: visible;
}

/* Width Mode "Content Width": hugs whatever is actually inside (an <img>
   at its own rendered width, most commonly) instead of a fixed number --
   good for a single banner/flyer image, where a guessed fixed Width
   reliably either leaves empty side gaps or clips/shrinks the image
   awkwardly instead of matching it exactly. The max-width rule above
   still applies regardless of width mode, so this is still safely capped
   on a narrow viewport -- fit-content never overflows past it. Higher
   specificity than the plain "dialog.shk-modal" rule above (one more
   attribute selector), so this reliably wins over width: var(...) for
   any modal in this mode without needing !important; see
   Renderer::build_style() for why that variable is never even emitted
   for a Content Width modal in the first place. */
dialog.shk-modal[data-shk-width-mode="content"] {
	width: fit-content;
}

dialog.shk-modal::backdrop {
	background: var(--shk-modal-overlay-color);
}

dialog.shk-modal[data-shk-overlay="0"]::backdrop {
	background: transparent;
}

.shk-modal__dialog {
	display: flex;
	flex-direction: column;
	max-height: inherit;
	height: 100%;
	/* The rounded-corner content clipping dialog.shk-modal itself used to
	   do (see its own overflow comment above) -- moved one level in so
	   .shk-modal__close--outside can render outside that corner without
	   being clipped by it. border-radius: inherit takes the dialog's own
	   computed radius since border-radius is not normally an inherited
	   property. */
	overflow: hidden;
	border-radius: inherit;
}

/* A real flex-flow item -- NOT position: absolute over the content below
   -- deliberately. It is always the first child of .shk-modal__dialog
   (see Renderer::build_modal_markup()), so giving it its own genuine row
   here reserves real vertical space for it in normal document flow. That
   guarantees .shk-modal__content can never render underneath it, for any
   content whatsoever, with no padding-vs-button-size magic number to
   keep in sync (an earlier absolute-positioned version of this button
   relied on exactly that, and content wide/tall enough could still end
   up underneath it). When close_button is off, this element does not
   exist in the DOM at all, so .shk-modal__content is simply the sole
   flex child and this rule has nothing to do.

   Scoped under "dialog.shk-modal" (not just ".shk-modal__close" alone)
   deliberately -- Elementor's Kit generates a global button/input/
   .elementor-button style block (".elementor-kit-7 button {...}") that
   applies site-wide to every plain <button> once Elementor is active,
   even on a page with no Elementor content at all, and that selector's
   specificity (one class + one element) is HIGHER than a bare
   ".shk-modal__close" class selector alone. Without this, the Kit's
   own background-color/color/border-radius silently won against every
   one of these properties -- including the plugin's own *default*
   values, not just an admin-configured override -- for as long as
   Elementor has been active on this site. Reusing the dialog's own
   existing wrapping selector (already used for e.g. dialog.shk-modal
   above) raises specificity just enough to reliably win, the same fix
   already proven for Featured Items Carousel's arrow buttons -- no
   !important needed. */
dialog.shk-modal .shk-modal__close {
	align-self: flex-end;
	flex: 0 0 auto;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: var(--shk-modal-close-size);
	height: var(--shk-modal-close-size);
	margin: var(--shk-modal-close-top-space) var(--shk-modal-close-right-space) 0;
	padding: 0;
	border: 0;
	border-radius: var(--shk-modal-close-radius);
	background: var(--shk-modal-close-bg);
	color: var(--shk-modal-close-color);
	font: inherit;
	cursor: pointer;
	transition: background var(--shk-modal-transition), filter var(--shk-modal-transition);
}

/* Close Button Position ("Top Left"). align-self swaps which end of the
   cross axis the button sticks to (still the same flex row, still the
   first child, still normal document flow -- see the structural note
   above), and the margin swaps sides to match so "Side Spacing" always
   means "distance from whichever edge the button is actually on". */
dialog.shk-modal[data-shk-close-position="left"] .shk-modal__close {
	align-self: flex-start;
	margin: var(--shk-modal-close-top-space) 0 0 var(--shk-modal-close-right-space);
}

/* Close Button "Outside the Modal": a floating badge centered exactly on
   the corner (half outside the rounded border, half inside) instead of
   sitting inside the modal's own padding. Taking it out of flow with
   position: absolute here removes it from .shk-modal__dialog's flex row
   entirely -- .shk-modal__content simply expands to fill the space that
   would otherwise have been reserved for it, which is correct: there is
   no "underneath the button" to protect content from once the button no
   longer overlaps the content area at all.

   No explicit `position: relative` is needed on either ancestor for this
   to resolve against dialog.shk-modal specifically: a <dialog> shown via
   showModal() is fixed-positioned by the UA stylesheet (top-layer
   rendering) and .shk-modal__dialog itself stays position: static, so it
   is skipped as a containing block and this resolves against the dialog
   element itself -- exactly the box whose corner this should straddle.
   Top/Side Spacing (--shk-modal-close-top-space/-right-space) do not
   apply in this mode -- see the checkbox's own admin description; it is
   always exactly centered on the corner, with no independent per-modal
   tuning (yet). box-shadow keeps it readably visible over BOTH the
   modal's own background (its inside half) and the ::backdrop behind it
   (its outside half), regardless of what Background Color is set. */
dialog.shk-modal[data-shk-close-outside="1"] .shk-modal__close {
	position: absolute;
	top: calc(var(--shk-modal-close-size) / -2);
	right: calc(var(--shk-modal-close-size) / -2);
	margin: 0;
	box-shadow: 0 2px 8px rgba(0, 0, 0, 0.25);
}

dialog.shk-modal[data-shk-close-outside="1"][data-shk-close-position="left"] .shk-modal__close {
	right: auto;
	left: calc(var(--shk-modal-close-size) / -2);
}

/* filter: brightness() darkens/lightens whatever --shk-modal-close-bg
   actually is (transparent-black default, or any admin-chosen color)
   instead of a hardcoded hover rgba that would only look right against
   the default background. */
dialog.shk-modal .shk-modal__close:hover,
dialog.shk-modal .shk-modal__close:focus-visible {
	filter: brightness(0.88);
}

dialog.shk-modal .shk-modal__close:focus-visible {
	outline: 2px solid var(--color-accent, #f28c28);
	outline-offset: 2px;
}

.shk-modal__close-icon {
	width: var(--shk-modal-close-icon-size);
	height: var(--shk-modal-close-icon-size);
	display: block;
}

.shk-modal__close-icon--text {
	width: auto;
	height: auto;
	font-size: var(--shk-modal-close-icon-size);
	line-height: 1;
}

.shk-modal__content {
	flex: 1 1 auto;
	overflow-y: auto;
	-webkit-overflow-scrolling: touch;
	padding: var(--shk-modal-padding);
}

/* Shown only to users who can edit the modal, when its configured
   content failed to render for some reason (see Renderer::elementor_notice()). */
.shk-modal__admin-notice {
	margin: 0;
	padding: 12px 16px;
	border: 1px dashed #c00;
	border-radius: var(--radius-sm, 4px);
	background: #fff4f4;
	color: #c00;
	font-size: 13px;
}

/* Visually-hidden accessible title (every modal has one, even when the
   author's chosen content starts with something other than a heading,
   so aria-labelledby always resolves to real text). Self-contained --
   does not depend on the theme defining .screen-reader-text. */
.shk-modal__sr-title {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}

/* -------------------------------------------------------------------- */
/* Trigger convenience class, used by [shk_modal_trigger].              */
/* Deliberately NOT named "shk-modal-*" (single hyphen) -- that prefix  */
/* is reserved for the "shk-modal-{id}" trigger convention and must     */
/* never collide with a decorative class.                               */
/* -------------------------------------------------------------------- */

.shk-modal__trigger {
	cursor: pointer;
}

/* -------------------------------------------------------------------- */
/* Animation (progressive enhancement; browsers without @starting-style */
/* support simply show/hide the dialog instantly -- fully functional,   */
/* just not animated).                                                  */
/* -------------------------------------------------------------------- */

@media (prefers-reduced-motion: no-preference) {
	dialog.shk-modal[data-shk-animation="fade"] {
		transition:
			opacity var(--shk-modal-transition),
			transform var(--shk-modal-transition),
			display var(--shk-modal-transition) allow-discrete,
			overlay var(--shk-modal-transition) allow-discrete;
		opacity: 1;
		transform: translateY(0) scale(1);
	}

	dialog.shk-modal[data-shk-animation="fade"]::backdrop {
		transition: opacity var(--shk-modal-transition), display var(--shk-modal-transition) allow-discrete, overlay var(--shk-modal-transition) allow-discrete;
		opacity: 1;
	}

	@starting-style {
		dialog.shk-modal[data-shk-animation="fade"][open] {
			opacity: 0;
			transform: translateY(8px) scale(0.98);
		}

		dialog.shk-modal[data-shk-animation="fade"][open]::backdrop {
			opacity: 0;
		}
	}
}

/* -------------------------------------------------------------------- */
/* Mobile behaviour.                                                    */
/* -------------------------------------------------------------------- */

@media (max-width: 600px) {
	dialog.shk-modal[data-shk-mobile-fullscreen="1"] {
		width: 100%;
		max-width: 100vw;
		height: 100%;
		max-height: 100vh;
		border-radius: 0;
		margin: 0;
	}

	dialog.shk-modal:not([data-shk-mobile-fullscreen="1"]) {
		width: 100%;
		max-width: 94vw;
	}

	.shk-modal__content {
		padding: var(--space-md, 24px);
	}

	/* Mobile Fullscreen leaves no rounded corner to straddle, and the
	   dialog itself now spans the full viewport -- "outside" would push
	   the button half off-screen, inaccessible. Falls back to the normal
	   in-flow position (same values the non-outside rule above already
	   uses) rather than leaving a close button a visitor cannot reach. */
	dialog.shk-modal[data-shk-mobile-fullscreen="1"][data-shk-close-outside="1"] .shk-modal__close {
		position: static;
		top: auto;
		right: auto;
		left: auto;
		align-self: flex-end;
		margin: var(--shk-modal-close-top-space) var(--shk-modal-close-right-space) 0;
		box-shadow: none;
	}

	dialog.shk-modal[data-shk-mobile-fullscreen="1"][data-shk-close-outside="1"][data-shk-close-position="left"] .shk-modal__close {
		align-self: flex-start;
		margin: var(--shk-modal-close-top-space) 0 0 var(--shk-modal-close-right-space);
	}
}
