/*
 * Cascade Menu for Elementor — frontend styles.
 *
 * Colors, typography, borders, shadows and sizing are emitted by Elementor
 * itself (via each control's `selectors`), scoped to the widget instance
 * through {{WRAPPER}}. Layout values that several rules need to share are
 * passed in as CSS custom properties, also set by Elementor. This file only
 * supplies structure, open/closed state, and animation.
 *
 * Animation timings come in as four separate properties instead of one
 * duration, so a single transition declaration can express every animation
 * mode without competing rules overwriting each other's shorthand:
 *   --cmfe-fade-ms   opacity duration   (0ms = no fade)
 *   --cmfe-slide-ms  transform duration (0ms = no slide)
 *   --cmfe-slide-x   slide start offset (0px = no slide)
 *   --cmfe-vis-ms    visibility hold, = max(fade, slide)
 */

.cmfe-cascade-menu,
.cmfe-cascade-menu *,
.cmfe-cascade-menu *::before,
.cmfe-cascade-menu *::after {
	box-sizing: border-box;
}

.cmfe-cascade-menu {
	position: relative;
}

/* Panel placement. "outside" leaves the first level filling the widget box,
   so panels open past its right edge and overflow it.

   "inside" keeps the whole construct within the widget: the first level is
   narrowed to a set width and every flyout shares the remaining space,
   pinned from that width to the widget's right edge. Making the entries
   static hands the panels' containing block to the nav, which is what lets
   `left`/`right` measure against the widget box instead of against a single
   entry — and, as a side effect, lets them escape the first level's own
   scroll container without any scripted positioning. Deeper levels stack
   over the same area rather than cascading further right, because there is
   no room to the right of the widget by definition. */
.cmfe-place-inside > .cmfe-level {
	width: var(--cmfe-first-w, 260px);
}

.cmfe-place-inside .cmfe-item {
	position: static;
}

.cmfe-place-inside .cmfe-panel:not(.cmfe-panel--inline) {
	top: 0;
	left: var(--cmfe-first-w, 260px);
	right: 0;
	width: auto;
}

/* A percentage min-height resolves against the containing block, which in
   this placement is the nav — and the nav is exactly as tall as the first
   level, since the panels themselves are out of flow. So a panel holding
   only a couple of entries still reaches down to the bottom of the first
   level, while a longer one keeps growing past it. */
.cmfe-match-h.cmfe-place-inside .cmfe-panel:not(.cmfe-panel--inline) {
	min-height: 100%;
}

.cmfe-level {
	list-style: none;
	margin: 0;
	padding: 0;
}

.cmfe-item {
	position: relative;
	/* Themes routinely style bare `li` (e.g. `li { margin-bottom: 12px }`),
	   which would silently add spacing the widget's own gap control does not
	   know about. Reset it here so the gap below is the only source of
	   spacing between entries. */
	margin: 0;
	padding: 0;
	/* Keeps an entry from being split across two columns when a panel
	   is configured to render its list in multiple columns. */
	break-inside: avoid;
	-webkit-column-break-inside: avoid;
}

/* Adjacent-sibling rather than a bottom margin with a :last-child reset,
   so the gap also behaves correctly inside multi-column panels. */
.cmfe-item + .cmfe-item {
	margin-top: var(--cmfe-item-gap, 0px);
}

.cmfe-item-link {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 0.5em;
	text-decoration: none;
	cursor: pointer;
}

.cmfe-item-label {
	min-width: 0;
}

.cmfe-nowrap .cmfe-item-label {
	white-space: nowrap;
}

.cmfe-wrap .cmfe-item-label {
	overflow-wrap: anywhere;
	word-break: break-word;
}

.cmfe-item-icon {
	display: inline-flex;
	align-items: center;
	line-height: 0;
	flex: 0 0 auto;
}

.cmfe-item-icon svg {
	fill: currentColor;
	display: block;
}

/* Only becomes a scroll container when a max height was actually set —
   an unconditional `overflow-y: auto` would clip every flyout panel. When
   this class is present, cascade-menu.js switches panels to fixed
   positioning so they can still escape the scrolling box. */
.cmfe-scroll > .cmfe-level {
	max-height: var(--cmfe-menu-max-h, none);
	overflow-y: auto;
	/* Required, not cosmetic: per spec a non-visible overflow on one axis
	   turns `visible` on the other axis into `auto`, so scrolling vertically
	   would otherwise also produce a horizontal scrollbar. */
	overflow-x: hidden;
}

.cmfe-panel {
	position: absolute;
	top: 0;
	left: 100%;
	z-index: 100;
	width: calc(
		var(--cmfe-panel-w, 240px) * var(--cmfe-cols, 1)
		+ var(--cmfe-col-gap, 0px) * (var(--cmfe-cols, 1) - 1)
	);
	opacity: 0;
	visibility: hidden;
	pointer-events: none;
	transform: translateX(var(--cmfe-slide-x, 0px));
	transition:
		opacity var(--cmfe-fade-ms, 0ms) ease,
		transform var(--cmfe-slide-ms, 0ms) ease,
		visibility var(--cmfe-vis-ms, 0ms) linear;
}

/* JS is the single source of truth for open state (hover-intent, click,
   keyboard, or touch tap all funnel into the same class toggle), so CSS
   never reacts to raw :hover — that would conflict with click-only mode. */
.cmfe-item.cmfe-open > .cmfe-panel {
	opacity: 1;
	visibility: visible;
	pointer-events: auto;
	transform: translateX(0);
}

/* Absolutely positioned children still count towards a scroll container's
   scrollable overflow, so a tall closed panel would put a scrollbar on the
   list even when every entry fits. Taking the panels out of the page flow
   entirely avoids that; cascade-menu.js already places them by hand in
   these modes, so nothing depends on their static position. */
   Not needed in "inside" placement: there the panels already hang off the
   nav rather than off an entry, so they neither get clipped by the list nor
   count towards its overflow. */
.cmfe-scroll:not(.cmfe-place-inside) .cmfe-panel:not(.cmfe-panel--inline),
.cmfe-panel-scroll:not(.cmfe-place-inside) .cmfe-panel:not(.cmfe-panel--inline) {
	position: fixed;
}

.cmfe-panel > .cmfe-level {
	column-count: var(--cmfe-cols, 1);
	column-gap: var(--cmfe-col-gap, 0px);
}

.cmfe-panel-scroll .cmfe-panel:not(.cmfe-panel--inline) {
	max-height: var(--cmfe-panel-max-h, none);
	overflow-y: auto;
	overflow-x: hidden;
}

/* Inline levels: children are listed underneath their parent entry inside
   the current panel instead of opening a panel of their own. Always
   visible, never a toggle, and deliberately free of the panel chrome
   (Elementor's panel styling selectors exclude this class). */
.cmfe-panel--inline {
	position: static;
	width: auto;
	max-height: none;
	overflow: visible;
	opacity: 1;
	visibility: visible;
	pointer-events: auto;
	transform: none;
	transition: none;
	z-index: auto;
	padding-inline-start: var(--cmfe-inline-indent, 16px);
}

.cmfe-panel--inline > .cmfe-level {
	column-count: 1;
}

/* Panel anchoring: by default a panel opens level with the entry that
   triggered it. In "top" mode it is pinned to the top of the list it
   belongs to, so every panel of a level starts at the same height. */
.cmfe-align-top .cmfe-item {
	position: static;
}

/* Excluded in "inside" placement, where the nav must stay the panels'
   containing block for the left/right pinning above to measure the widget. */
.cmfe-align-top:not(.cmfe-place-inside) .cmfe-level {
	position: relative;
}

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

.cmfe-item-link:focus-visible {
	outline: 2px solid currentColor;
	outline-offset: 2px;
}

.cmfe-empty-notice {
	padding: 1em;
	border: 1px dashed #c00;
	color: #c00;
}
