/**
 * IQ Layer — shared bones for everything that opens over the page (F1).
 *
 * Substrate: native <dialog> / Popover API (see assets/js/iq-layer.js and
 * docs/foundations/layer.md). Both render in the TOP LAYER, which ignores
 * z-index entirely. That does not make the --iq-z-* tokens dead: they govern
 * the in-flow, non-top-layer path (a non-modal drawer rendered in place, or
 * an engine without the APIs, where the element's no-JS fallback applies).
 * Each layer element's doc must say which path it takes.
 *
 * Visuals stay with the elements — an E2 modal picks surface-raised,
 * radius-lg, shadow-lg; this file carries only what every layer must get
 * right. It declares no transitions, so it needs no `-effective` motion
 * mirrors; a layer element that adds an entrance animation must route it
 * through the mirrors and join the selector lists in iq-base.css.
 */

/* Scroll lock, engaged by iq-layer.js while a MODAL layer is open — the top
   layer does not stop the page from scrolling behind it.

   `overflow: hidden` alone removes a classic scrollbar and the page reflows
   the gutter's width wider. The compensation is MEASURED by iq-layer.js, not
   assumed: the --gutter class is added only when the page actually had a
   classic scrollbar (an overlay-scrollbar platform or a short page loses no
   width, and blindly reserving a gutter there would shift the page the other
   way). `scrollbar-gutter: stable` holds the space in engines that honor it
   under overflow:hidden; --iq-scrollbar-comp padding makes up exactly the
   width that was still lost. The value is a runtime measurement, which is why
   it is an inline custom property and not a Tokens::schema() entry.

   Never `position: fixed` body-locking — it loses the scroll position on
   iOS; overflow on the root keeps it, so there is nothing to restore. */
html.iq-scroll-locked {
	overflow: hidden;
}

html.iq-scroll-locked--gutter {
	scrollbar-gutter: stable;
	padding-inline-end: var(--iq-scrollbar-comp, 0px);
}

/* Reflow (WCAG 1.4.10 / 1.4.4): a layer scrolls INTERNALLY at 320px CSS
   width and 400% zoom instead of growing past the viewport — never a fixed
   height. The UA caps a top-layer dialog similarly; declaring it here keeps
   the guarantee on the in-flow path too, and the dvh/dvw pair upgrades the
   static-viewport cap so mobile browser chrome cannot cover a layer's end
   (engines without dynamic units keep the vh/vw line). */
.iq-layer {
	box-sizing: border-box;
	max-inline-size: calc(100vw - 2 * var(--iq-space-md, 1rem));
	max-inline-size: calc(100dvw - 2 * var(--iq-space-md, 1rem));
	max-block-size: calc(100vh - 2 * var(--iq-space-md, 1rem));
	max-block-size: calc(100dvh - 2 * var(--iq-space-md, 1rem));
	overflow: auto;
	/* A wheel or swipe that reaches the layer's own end must not start
	   scrolling the page behind it — the lock covers modals, this covers the
	   non-modal layers too. */
	overscroll-behavior: contain;
}

/* The scrim. Scoped to dialogs: popovers (dropdown, tooltip, toast) get a
   ::backdrop pseudo as well, and dimming the page under a dropdown would be
   wrong. ::backdrop inherits from its originating element in current
   engines, so the token — including its .dark value — resolves there; older
   engines take the fallback literal. The pair is deliberately not in
   Contrast::relations(): a scrim exists to REDUCE the contrast of what is
   behind it (see class-tokens.php). */
dialog.iq-layer::backdrop {
	background: var(--iq-color-overlay, rgba(15, 23, 42, 0.5));
}

/* Bricks assigns display:flex to .brxe-block. A closed dialog and a closed
   popover are display:none via UA rules only, and author CSS beats the UA at
   any specificity — so a layer that is also a Bricks block would sit
   permanently open on the canvas and the page. Same compensation the tab
   panels carry for [hidden]; !important so a generated #brxe-* rule cannot
   re-open it either. */
dialog.iq-layer:not([open]) {
	display: none !important;
}

.iq-layer[popover]:not(:popover-open) {
	display: none !important;
}

/* Forced colors (Windows High Contrast) — F4 baseline, see
   docs/foundations/forced-colors.md. A floating panel's boundary is
   normally carried by elevation (box-shadow) over a scrim — both discarded
   by the forcing — so every layer gets a real border here, or a dropdown
   would be an indistinguishable patch of Canvas over the page. */
@media (forced-colors: active) {
	.iq-layer {
		border: 1px solid CanvasText;
	}
}
