/**
 * ANSL Panel – structural styles only. Colors, spacing and typography belong to the project.
 */

/* ==========================================================================
   Panel Button: icon (burger or custom) + label. The label is always the accessible name,
   visually hidden by default ("Show label" outputs the per-breakpoint overrides).
   ========================================================================== */

/* Defaults with zero specificity, so any class or ID can override them.
   Transparent icon button: only the icon has a color. */
:where(.ansl-panel-button) {
	--ansl-panel-button-padding: 0.5em;
	--ansl-panel-button-line-width: 1.5em;
	--ansl-panel-button-line-height: 2px;
	--ansl-panel-button-line-gap: 0.35em;
	--ansl-panel-button-line-radius: 0;
	--ansl-panel-button-icon-color: currentColor;
	--ansl-panel-button-duration: var(--transition-duration, 0.2s); /* framework token, own fallback */

	display: inline-flex;
	align-items: center;
	gap: 0.5em;
	padding: var(--ansl-panel-button-padding);
	border: 0;
	background: none;
	color: inherit;
	font: inherit;
	cursor: pointer;
}

/* Focus ring like the framework's buttons (BFW: --btn-focus-offset), so it doesn't sit flush
   on a background; without the variable: 0 (browser behavior). */
:where(.ansl-panel-button):focus-visible {
	outline-offset: var(--btn-focus-offset, 0);
}

:where(.ansl-panel-button__label) {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
}

/* Burger */
.ansl-panel-button__burger {
	display: inline-flex;
	flex-direction: column;
	gap: var(--ansl-panel-button-line-gap);
	inline-size: var(--ansl-panel-button-line-width);
}

.ansl-panel-button__line {
	display: block;
	block-size: var(--ansl-panel-button-line-height);
	border-radius: var(--ansl-panel-button-line-radius);
	background: var(--ansl-panel-button-icon-color);
	transition-property: translate, rotate, opacity, background-color;
	transition-duration: var(--ansl-panel-button-duration);
}

/* Windows high contrast replaces backgrounds: the lines keep a system text color */
@media (forced-colors: active) {
	.ansl-panel-button__line {
		background: ButtonText;
		forced-color-adjust: none;
	}
}

/* Burger animations. Open state = [data-ansl-action="toggle"][aria-expanded="true"];
   a close button always shows it. --_offset: distance from an outer line to the center. */
:where(.ansl-panel-button) {
	--_offset: calc(var(--ansl-panel-button-line-height) + var(--ansl-panel-button-line-gap));
	--_half: calc(var(--ansl-panel-button-duration) / 2);
}

:where(.ansl-panel-button--lines-2) {
	--_offset: calc((var(--ansl-panel-button-line-height) + var(--ansl-panel-button-line-gap)) / 2);
}

/* Simple, Squeeze, Spin: outer lines meet in the center and turn into an X, a middle line fades */
:is(.ansl-panel-button--simple, .ansl-panel-button--squeeze, .ansl-panel-button--spin):is([data-ansl-action="toggle"][aria-expanded="true"], [data-ansl-action="close"]) .ansl-panel-button__line:first-child {
	translate: 0 var(--_offset);
	rotate: 45deg;
}

:is(.ansl-panel-button--simple, .ansl-panel-button--squeeze, .ansl-panel-button--spin, .ansl-panel-button--minus):is([data-ansl-action="toggle"][aria-expanded="true"], [data-ansl-action="close"]) .ansl-panel-button__line:not(:first-child, :last-child) {
	opacity: 0;
}

:is(.ansl-panel-button--simple, .ansl-panel-button--squeeze, .ansl-panel-button--spin):is([data-ansl-action="toggle"][aria-expanded="true"], [data-ansl-action="close"]) .ansl-panel-button__line:last-child {
	translate: 0 calc(var(--_offset) * -1);
	rotate: -45deg;
}

/* Squeeze: two steps. Opening: meet, then turn. Closing: turn back, then part. */
.ansl-panel-button--squeeze .ansl-panel-button__line {
	transition:
		rotate var(--_half),
		translate var(--_half) var(--_half),
		opacity 0s var(--_half),
		background-color var(--ansl-panel-button-duration);
}

.ansl-panel-button--squeeze:is([data-ansl-action="toggle"][aria-expanded="true"], [data-ansl-action="close"]) .ansl-panel-button__line {
	transition:
		translate var(--_half),
		rotate var(--_half) var(--_half),
		opacity 0s var(--_half),
		background-color var(--ansl-panel-button-duration);
}

/* Spin: the X plus a half turn of the whole icon */
.ansl-panel-button--spin .ansl-panel-button__burger {
	transition: rotate var(--ansl-panel-button-duration);
}

.ansl-panel-button--spin:is([data-ansl-action="toggle"][aria-expanded="true"], [data-ansl-action="close"]) .ansl-panel-button__burger {
	rotate: 180deg;
}

/* Minus: the lines merge into one */
.ansl-panel-button--minus:is([data-ansl-action="toggle"][aria-expanded="true"], [data-ansl-action="close"]) .ansl-panel-button__line:first-child {
	translate: 0 var(--_offset);
}

.ansl-panel-button--minus:is([data-ansl-action="toggle"][aria-expanded="true"], [data-ansl-action="close"]) .ansl-panel-button__line:last-child {
	translate: 0 calc(var(--_offset) * -1);
}

/* Icon box around the burger or the custom icons (background, padding, radius).
   Square by default (circles with radius 50%, even tap area); override: aspect-ratio: auto. */
:where(.ansl-panel-button__icon) {
	aspect-ratio: 1;
}

.ansl-panel-button__icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	color: var(--ansl-panel-button-icon-color);
	transition: background-color var(--ansl-panel-button-duration);
}

/* Custom icons: the close icon (if set) replaces the open icon while the panel is open */
.ansl-panel-button__icon-open,
.ansl-panel-button__icon-close {
	display: inline-flex;
	font-size: var(--ansl-panel-button-icon-size, 1.5em);
	line-height: 1;
}

:is(.ansl-panel-button__icon-open, .ansl-panel-button__icon-close) svg {
	width: 1em;
	height: 1em;
	fill: currentColor;
}

.ansl-panel-button--has-close-icon:not([aria-expanded="true"]) .ansl-panel-button__icon-close,
.ansl-panel-button--has-close-icon[aria-expanded="true"] .ansl-panel-button__icon-open {
	display: none;
}

@media (prefers-reduced-motion: reduce) {
	/* Important: the squeeze open state has a higher specificity */
	.ansl-panel-button .ansl-panel-button__line,
	.ansl-panel-button .ansl-panel-button__burger {
		transition: none !important;
	}
}

/* ==========================================================================
   Panel: fixed overlay. Closed: display none. Open: --open. Builder: --preview.
   Bar mode above its breakpoint: display: contents (inline breakpoint CSS).
   Panel buttons sit above the panel (same stacking context, e.g. the header row).
   ========================================================================== */

/* Defaults (zero specificity). Transition: the effect modifiers set the closed state.
   --ansl-panel-z-index has no default here, only fallbacks: set it on a common parent
   (e.g. the header row) and panel, backdrop (-1) and panel buttons (+1) follow together. */
:where(.ansl-panel) {
	--ansl-panel-duration: calc(var(--transition-duration, 0.2s) * 1.5); /* calmer than the framework's UI transitions */
	--ansl-panel-easing: var(--transition-timing, ease-out);
	--ansl-panel-translate: none; /* not 0: none → 0px would run an invisible transition */
	--ansl-panel-opacity: 1;
	--_translate: var(--ansl-panel-translate);
}

:where(.ansl-panel--fade) {
	--ansl-panel-opacity: 0;
}

:where(.ansl-panel--from-start) {
	--ansl-panel-translate: -100% 0;
}

:where(.ansl-panel--from-end) {
	--ansl-panel-translate: 100% 0;
}

:where(.ansl-panel--from-start:dir(rtl)) {
	--ansl-panel-translate: 100% 0;
}

:where(.ansl-panel--from-end:dir(rtl)) {
	--ansl-panel-translate: -100% 0;
}

:where(.ansl-panel--from-top) {
	--ansl-panel-translate: 0 -100%;
}

:where(.ansl-panel--from-bottom) {
	--ansl-panel-translate: 0 100%;
}

@media (prefers-reduced-motion: reduce) {
	.ansl-panel {
		--_translate: none;
	}
}

.ansl-panel {
	position: fixed;
	inset: 0;
	z-index: var(--ansl-panel-z-index, 100);
	flex-direction: column;
	overflow-y: auto;
	overscroll-behavior: contain;
}

/* Legible without styling: page background and framework spacing (zero specificity) */
:where(.ansl-panel) {
	padding: var(--space-m, 1.5em);
	background-color: var(--bg-body, #fff);
}

/* A close button directly in the panel: at the end (top right, like dialogs), not stretched
   across the panel's column. Zero specificity: any own setting wins. */
:where(.ansl-panel > .ansl-panel-button[data-ansl-action="close"]) {
	align-self: end;
}

/* Logged in: below the WordPress admin bar (it sits above every panel) */
:where(.admin-bar) .ansl-panel {
	margin-block-start: var(--wp-admin--admin-bar--height, 0px);
}

/* Position (full screen by default). Bricks' own width/height/position controls (ID) win. */
.ansl-panel--start,
.ansl-panel--end {
	inset-block: 0;
	inline-size: min(100%, 24rem);
}

.ansl-panel--start {
	inset-inline: 0 auto;
}

.ansl-panel--end {
	inset-inline: auto 0;
}

.ansl-panel--top,
.ansl-panel--bottom {
	inset-inline: 0;
	max-block-size: 100%;
}

.ansl-panel--top {
	inset-block: 0 auto;
}

.ansl-panel--bottom {
	inset-block: auto 0;
}

/* Important, so a display set on the element in Bricks can't show a closed panel */
.ansl-panel:not(.ansl-panel--open, .ansl-panel--closing, .ansl-panel--preview) {
	display: none !important;
}

.ansl-panel--open,
.ansl-panel--closing,
.ansl-panel--preview {
	display: flex;
}

/* Transition: only while open/closing, so crossing the breakpoint never animates.
   Opening starts from the closed state (@starting-style); closing keeps the panel
   visible via --closing until the transition ends (panel.js). */
.ansl-panel--open,
.ansl-panel--closing {
	transition-property: translate, opacity;
	transition-duration: var(--ansl-panel-duration);
	transition-timing-function: var(--ansl-panel-easing);
}

.ansl-panel--closing {
	translate: var(--_translate);
	opacity: var(--ansl-panel-opacity);
}

@starting-style {
	.ansl-panel--open {
		translate: var(--_translate);
		opacity: var(--ansl-panel-opacity);
	}
}

/* Toggle and close buttons of the open panel above it (panel.js, until its closing
   transition ends); "open" buttons and the buttons of other panels stay under it */
:where(.ansl-panel-button--above) {
	position: relative;
	z-index: calc(var(--ansl-panel-z-index, 100) + 1);
}

/* Layer: behind the header. #brx-header becomes the stacking context (zero specificity,
   so sticky positioning from Bricks or plugins wins); inside it the header rows and their
   backgrounds paint above the panel, the page content stays below. */
:where(#brx-header:has(.ansl-panel--behind)) {
	position: relative;
	z-index: var(--ansl-header-z-index, 10);
}

.ansl-panel.ansl-panel--behind {
	z-index: -1;
}

.ansl-panel--behind + .ansl-panel__backdrop {
	z-index: -2;
}

/* Backdrop: sibling after the panel, below it (z-index - 1). Fades with the panel. */
:where(.ansl-panel__backdrop) {
	--ansl-panel-duration: calc(var(--transition-duration, 0.2s) * 1.5); /* calmer than the framework's UI transitions */
	--ansl-panel-easing: var(--transition-timing, ease-out);
}

.ansl-panel__backdrop {
	position: fixed;
	inset: 0;
	z-index: calc(var(--ansl-panel-z-index, 100) - 1);
	display: none;
	background-color: rgb(0 0 0 / 0.5);
	transition: opacity var(--ansl-panel-duration) var(--ansl-panel-easing);
}

.ansl-panel--open + .ansl-panel__backdrop,
.ansl-panel--closing + .ansl-panel__backdrop {
	display: block;
}

.ansl-panel--closing + .ansl-panel__backdrop {
	opacity: 0;
}

@starting-style {
	.ansl-panel--open + .ansl-panel__backdrop {
		opacity: 0;
	}
}

/* Builder: panel.js inserts the real backdrop after preview panels (the Vue template has
   one root), so color, image, gradient and filter look like on the frontend. */
.ansl-panel--preview + .ansl-panel__backdrop {
	display: block;
}

.ansl-scroll-lock {
	overflow: hidden;
}
