/* Mega Menu Extension — frontend */

/* The item must be the positioning context and not clip the panel. */
.dnxte-has-mega-menu {
	position: static; /* full/container modes anchor to header/viewport */
}

/* Hide the item's native Divi sub-menu when a mega menu replaces it. */
.dnxte-has-mega-menu > ul.sub-menu {
	display: none !important;
}

/* Caret indicating the item has a mega menu. The item has no real sub-menu
   <ul>, so Divi's native `.menu-item-has-children` arrow never applies — draw
   our own using the same ETmodules down-arrow glyph ("3") for visual parity. */
.dnxte-has-mega-menu > a:first-child::after {
	font-family: "ETmodules";
	content: "3";
	font-size: 16px;
	font-weight: 800;
	line-height: 1;
	display: inline-block;
	margin-left: 0.3em;
	vertical-align: middle;
	transition: transform 0.2s ease;
}

/* Flip the caret while the panel is open (JS sets dnxte-mm-open for both hover
   and click triggers). */
.dnxte-has-mega-menu.dnxte-mm-open > a:first-child::after {
	transform: rotate(180deg);
}

/* Base panel — hidden until open. Values come from per-CPT settings (CSS vars
   stamped on the element by the renderer); fallbacks reproduce the old look. */
.dnxte-mega-menu-panel {
	position: absolute;
	left: 0;
	top: calc(100% + var(--mm-gap, 0px));
	z-index: var(--mm-z, 9999);
	box-sizing: border-box;
	/* Fixed base look: a panel's real appearance is styled in the Divi Builder
	   (section background etc.), which paints over this opaque white base. */
	background: #fff;
	box-shadow: 0 10px 30px rgba(0, 0, 0, 0.12);
	opacity: 0;
	visibility: hidden;
	transform: translateX(var(--mm-tx, 0)) translateY(10px);
	transition: opacity var(--mm-duration, 250ms) var(--mm-ease, ease),
		transform var(--mm-duration, 250ms) var(--mm-ease, ease),
		visibility 0s linear var(--mm-duration, 250ms);
}

/* Desktop: keep a tall panel within the screen and scroll its content instead of
   overflowing the page. --mm-max-h is set precisely by JS (override px, or the
   space below the panel); the calc() is the no-JS / pre-JS fallback. Mobile is
   excluded — the accordion drives its own inline max-height — as is the vertical
   side flyout. */
.dnxte-has-mega-menu:not(.dnxte-mm-mobile) > .dnxte-mega-menu-panel:not(.dnxte-mm-context-vertical) {
	max-height: var(--mm-max-h, calc(100vh - 120px));
	overflow-y: auto;
}

/* Closed-state transform per animation type (composed with the centering X
   offset --mm-tx, which is -50% only for full width). */
.dnxte-mega-menu-panel[data-mm-anim="slide-up"]   { transform: translateX(var(--mm-tx, 0)) translateY(10px); }
.dnxte-mega-menu-panel[data-mm-anim="slide-down"] { transform: translateX(var(--mm-tx, 0)) translateY(-10px); }
.dnxte-mega-menu-panel[data-mm-anim="zoom"]       { transform: translateX(var(--mm-tx, 0)) scale(0.96); }
.dnxte-mega-menu-panel[data-mm-anim="scale"]      { transform: translateX(var(--mm-tx, 0)) scale(0.9); }
.dnxte-mega-menu-panel[data-mm-anim="fade"]       { transform: translateX(var(--mm-tx, 0)); }
.dnxte-mega-menu-panel[data-mm-anim="none"]       { transform: translateX(var(--mm-tx, 0)); }

/* Blur Fade: animate `filter` in addition to opacity/transform. The base panel
   transition (above) doesn't list filter, so this rule re-declares the full
   transition with filter included, both closed (here) and open (below). */
.dnxte-mega-menu-panel[data-mm-anim="blur"] {
	transform: translateX(var(--mm-tx, 0));
	filter: blur(8px);
	transition: opacity var(--mm-duration, 250ms) var(--mm-ease, ease),
		transform var(--mm-duration, 250ms) var(--mm-ease, ease),
		filter var(--mm-duration, 250ms) var(--mm-ease, ease),
		visibility 0s linear var(--mm-duration, 250ms);
}
/* anim "none" = instant — DESKTOP only. The mobile accordion (.dnxte-mm-mobile,
   added by JS per the item's breakpoint) always slides regardless of this setting. */
.dnxte-has-mega-menu:not(.dnxte-mm-mobile) > .dnxte-mega-menu-panel[data-mm-anim="none"] {
	transition: none;
}

/* Open state. JS adds .dnxte-mm-open (and stamps .dnxte-mm-js on <html>); the
   :hover branch is a no-JS-only fallback — when JS runs, opening must be
   class-driven so hover intent, sibling-close and aria-expanded stay accurate.
   Transform resets to just the centering offset so every animation type lands
   in the same final spot. */
.dnxte-has-mega-menu.dnxte-mm-open > .dnxte-mega-menu-panel,
html:not(.dnxte-mm-js) .dnxte-has-mega-menu:hover > .dnxte-mega-menu-panel {
	opacity: 1;
	visibility: visible;
	transform: translateX(var(--mm-tx, 0));
	transition: opacity var(--mm-duration, 250ms) var(--mm-ease, ease),
		transform var(--mm-duration, 250ms) var(--mm-ease, ease),
		visibility 0s;
}

/* Blur Fade open state: clear the blur and re-declare the transition with
   `filter` (the generic open-state rule above doesn't transition filter). */
.dnxte-has-mega-menu.dnxte-mm-open > .dnxte-mega-menu-panel[data-mm-anim="blur"],
html:not(.dnxte-mm-js) .dnxte-has-mega-menu:hover > .dnxte-mega-menu-panel[data-mm-anim="blur"] {
	filter: none;
	transition: opacity var(--mm-duration, 250ms) var(--mm-ease, ease),
		transform var(--mm-duration, 250ms) var(--mm-ease, ease),
		filter var(--mm-duration, 250ms) var(--mm-ease, ease),
		visibility 0s;
}

/* "none" = instant: the open-state rule above re-adds a transition at higher
   specificity, so re-assert transition:none for the open/hover state too.
   Desktop only — the mobile accordion always slides. */
.dnxte-has-mega-menu.dnxte-mm-open:not(.dnxte-mm-mobile) > .dnxte-mega-menu-panel[data-mm-anim="none"],
html:not(.dnxte-mm-js) .dnxte-has-mega-menu:not(.dnxte-mm-mobile):hover > .dnxte-mega-menu-panel[data-mm-anim="none"] {
	transition: none;
}

/* Click-trigger panels must NOT reveal on hover — only the JS toggle opens them.
   Gate this to the CLOSED state (:not(.dnxte-mm-open)): when the panel IS open
   and the cursor moves into it, li:hover is true; without the guard this rule
   (higher specificity than the open-state rule) would hide the panel, the cursor
   would then fall through to the page, li:hover would drop, the open-state rule
   would re-show it — an endless show/hide blink. The guard makes the negation
   apply only while closed, so an open click panel stays put on hover. */
.dnxte-has-mega-menu:not(.dnxte-mm-open):hover > .dnxte-mega-menu-panel[data-mm-trigger="click"] {
	opacity: 0;
	visibility: hidden;
}

/* Width modes. Full width centers via left:50% + a -50% X offset carried in
   --mm-tx, so the centering composes with any animation transform above and the
   open-state rule never strips it. */
.dnxte-mega-menu-panel.dnxte-mm-width-full {
	--mm-tx: -50%;
	left: 50%;
	/* --dnxte-vw = clientWidth, set by JS: 100vw includes the scrollbar and
	   would overflow the page horizontally by its width. */
	width: var(--dnxte-vw, 100vw);
	max-width: var(--dnxte-vw, 100vw);
}

/* NOTE: container mode is CSS-anchored to the nearest positioned ancestor
   (Divi's .et_pb_menu_inner_container). In logo+nav layouts left:0/width:100%
   overshoots the nav <ul> by the logo width. mega-menu.js measures the menu
   <ul> and sets precise left/width for container mode to correct this. */
.dnxte-mega-menu-panel.dnxte-mm-width-container {
	left: 0;
	width: 100%;
}
/* custom width applies inline via the style attribute. */

/* Transparent hover bridge for the horizontal (drop-below) layout: fills the
   vertical gap between the item and the panel so moving the cursor down from the
   item into the panel doesn't cross a dead zone, fire pointerleave on the <li> and
   close the panel before you reach its content. The bridge is part of the panel
   (a <li> descendant), so the <li> stays hovered across the gap; it inherits the
   panel's visibility, so it's inert (not hit-testable) while closed. Excludes the
   vertical side-flyout (which has its own bridge) and the mobile accordion.
   Zero-height when --mm-gap is 0, so it's a no-op when no gap is set. */
.dnxte-has-mega-menu:not(.dnxte-mm-mobile) > .dnxte-mega-menu-panel:not(.dnxte-mm-context-vertical)::before {
	content: "";
	position: absolute;
	top: calc(-1 * var(--mm-gap, 0px));
	left: 0;
	width: 100%;
	height: var(--mm-gap, 0px);
}

/* Vertical Menu context: items are stacked, so the panel opens as a SIDE FLYOUT
   (to the right of the item) instead of dropping below. The Vertical Menu module
   adds .dnxte-mm-vertical to the <li> and .dnxte-mm-context-vertical to the panel;
   mega-menu.js skips its horizontal JS positioning for these and lets CSS place it.
   Gated :not(.dnxte-mm-mobile) so the mobile accordion still wins on narrow views. */
.dnxte-vmenu-item.dnxte-mm-vertical {
	position: relative;
}
.dnxte-vmenu-item.dnxte-mm-vertical:not(.dnxte-mm-mobile) > .dnxte-mega-menu-panel.dnxte-mm-context-vertical {
	top: 0;
	left: calc(100% + var(--mm-gap, 0px));
	--mm-tx: 0; /* neutralize the full-width centering offset */
}
/* Transparent hover bridge filling the gap between the item and the flyout. Without
   it the cursor crosses a dead zone moving item -> panel, fires pointerleave on the
   <li> and the panel closes before you can reach its content. The bridge is part of
   the panel (a descendant of the <li>), so the <li> stays hovered across the gap.
   Only hit-testable while the panel is open (it inherits the panel's visibility). */
.dnxte-vmenu-item.dnxte-mm-vertical:not(.dnxte-mm-mobile) > .dnxte-mega-menu-panel.dnxte-mm-context-vertical::before {
	content: "";
	position: absolute;
	top: 0;
	left: calc(-1 * var(--mm-gap, 0px));
	width: var(--mm-gap, 0px);
	height: 100%;
}
/* Full/container widths have no side-flyout meaning; give them a usable flyout
   size. Custom width is honored from its inline style — recommended for vertical. */
.dnxte-vmenu-item.dnxte-mm-vertical:not(.dnxte-mm-mobile) > .dnxte-mega-menu-panel.dnxte-mm-width-full.dnxte-mm-context-vertical,
.dnxte-vmenu-item.dnxte-mm-vertical:not(.dnxte-mm-mobile) > .dnxte-mega-menu-panel.dnxte-mm-width-container.dnxte-mm-context-vertical {
	width: 480px;
	max-width: 70vw;
}
/* Caret points toward the flyout (right) rather than down. */
.dnxte-vmenu-item.dnxte-mm-vertical:not(.dnxte-mm-mobile) > a:first-child::after,
.dnxte-vmenu-item.dnxte-mm-vertical.dnxte-mm-open:not(.dnxte-mm-mobile) > a:first-child::after {
	transform: rotate(-90deg);
}

/* Lift the flyout above sibling page content. The panel's own z-index (9999) is
   trapped in the Divi column's stacking context (a column is position:relative
   z-index:2), so a LATER sibling column/section paints over the flyout — and its
   transparent empty columns swallow clicks, which the click-outside handler then
   reads as "outside" and closes the panel. Raise the whole Divi branch (column,
   row, section) that contains an OPEN vertical mega panel above its siblings so the
   flyout paints — and receives clicks — on top. Scoped to the open state, so it's
   inert otherwise. Needs :has() (all current browsers; degrades to the old
   behavior on ancient ones). */
.et_pb_column:has(.dnxte-mm-vertical.dnxte-mm-open),
.et_pb_row:has(.dnxte-mm-vertical.dnxte-mm-open),
.et_pb_section:has(.dnxte-mm-vertical.dnxte-mm-open) {
	z-index: 99999 !important;
}

/* Neutralize Divi's nav sub-menu styling that bleeds into panel content.
   The panel lives inside the menu's <li> and renders inside #et-boc, so the
   theme rules `.et-db #et-boc .et-l .nav li ul` / `.nav li li` (specificity
   1,3,2) hit ANY list a module outputs here — forcing 240px width, absolute
   position, a white box, blue border-top, shadow and 20px li padding (e.g. a
   Person module's social icons). The ID-scoped source needs !important to
   override. Panel content is always builder modules, never a real submenu. */
.dnxte-mega-menu-panel ul {
	position: static !important;
	top: auto !important;
	left: auto !important;
	width: auto !important;
	max-width: none !important;
	padding: 0 !important;
	margin: 0 !important;
	z-index: auto !important;
	background: none !important;
	border-top: 0 !important;
	box-shadow: none !important;
	-webkit-box-shadow: none !important;
	transform: none !important;
	text-align: inherit !important;
	visibility: visible !important;
	opacity: 1 !important;
}
.dnxte-mega-menu-panel li {
	position: static !important;
	padding: 0 !important;
	margin: 0 !important;
	line-height: inherit !important;
}

/* Mobile: accordion — full width, in-flow, toggled by JS. JS adds .dnxte-mm-mobile
   to each item at/below its own breakpoint (data-mm-breakpoint), replacing the old
   fixed @media query so the switch point is per-panel. Open slides down / close
   slides up by animating max-height (display:none can't animate, and animating grid
   0fr->1fr visually snaps in Chromium). JS sets max-height to the panel's exact
   content height (expandMobile), then lifts the cap to 'none' once open, so tall
   panels are never clipped; the CSS values below are fallbacks for the no-JS path. */
.dnxte-has-mega-menu.dnxte-mm-mobile > .dnxte-mega-menu-panel {
	position: static;
	width: 100% !important;
	max-width: 100% !important;
	top: auto !important;
	transform: none !important;
	box-shadow: none;
	opacity: 1;
	display: block;
	max-height: 0;
	overflow: hidden;
	visibility: hidden;
	transition: max-height var(--mm-duration, 250ms) var(--mm-ease, ease),
		visibility 0s linear var(--mm-duration, 250ms);
}
.dnxte-has-mega-menu.dnxte-mm-mobile.dnxte-mm-open > .dnxte-mega-menu-panel {
	/* Fallback height if JS can't set an exact one; expandMobile() overrides this
	   inline with the real content height so tall panels are never clipped. */
	max-height: 100vh;
	overflow: auto;
	visibility: visible;
	transition: max-height var(--mm-duration, 250ms) var(--mm-ease, ease),
		visibility 0s;
}

/* Caret sits at the right edge of the tap row (matches Divi's native mobile
   submenu toggles) instead of inline after the label. */
.dnxte-has-mega-menu.dnxte-mm-mobile > a:first-child {
	position: relative;
}
.dnxte-has-mega-menu.dnxte-mm-mobile > a:first-child::after {
	position: absolute;
	right: 10px;
	top: 50%;
	margin-left: 0;
	transform: translateY(-50%);
}
.dnxte-has-mega-menu.dnxte-mm-mobile.dnxte-mm-open > a:first-child::after {
	transform: translateY(-50%) rotate(180deg);
}

/* "Show on Mobile: No" — suppress the panel and revert the item to a plain link
   (no accordion, no caret) while in mobile mode. */
.dnxte-has-mega-menu.dnxte-mm-mobile.dnxte-mm-no-mobile > .dnxte-mega-menu-panel {
	display: none !important;
}
.dnxte-has-mega-menu.dnxte-mm-mobile.dnxte-mm-no-mobile > a:first-child::after {
	display: none;
}

/* "Show on Mobile: Hidden" — drop the whole item (link included) below the
   breakpoint. Desktop is unaffected. */
.dnxte-has-mega-menu.dnxte-mm-mobile.dnxte-mm-hidden-mobile {
	display: none !important;
}

/* Respect reduced-motion: panels and the caret appear/disappear instantly.
   Gated to `.dnxte-mm-rm` (added by the renderer unless the per-panel
   "Reduced-motion support" setting is turned off) so a panel can opt out. */
@media (prefers-reduced-motion: reduce) {
	.dnxte-mega-menu-panel.dnxte-mm-rm,
	.dnxte-has-mega-menu:has(> .dnxte-mega-menu-panel.dnxte-mm-rm) > a:first-child::after {
		transition: none !important;
	}
}
