/* =========================================================================
   Mega Menu — frontend styles
   =========================================================================
   Non-fullscreen panels: opened via CSS :hover (no JS toggle needed).
   Fullscreen panels: opened via JS (.is-open on the li).
   All panel coordinates (top/left/width/height) are set by JS on load + resize.
   ========================================================================= */

/* Mega-menu panel close-fade timing — single source of truth. Both the
   opacity and transform close-fades can run at different durations (see the
   base .wooforge-mm-panel rule below), so the delay that finally flips
   visibility/content-visibility to hidden must wait for whichever of the
   two is LONGER, not either one specifically — that's what the max() does.
   --wf-mm-panel-close-total is also read by #masthead's own delayed
   z-index fall in main.css (see the comment there), so #masthead doesn't
   drop below the backdrop while this panel is still visibly fading out.
   Change either duration below and both the visibility flip and #masthead
   recompute automatically — nothing else to edit or keep in sync by hand. */
:root {
	--wf-mm-panel-close-delay: .15s;
	--wf-mm-panel-close-opacity-duration: .3s;
	--wf-mm-panel-close-transform-duration: .5s;
	--wf-mm-panel-close-total: calc(var(--wf-mm-panel-close-delay) + max(var(--wf-mm-panel-close-opacity-duration), var(--wf-mm-panel-close-transform-duration)));

	/* Open has no delay and no cross-property coupling to resolve (visibility
	   shows instantly, it doesn't wait for opacity/transform like close does)
	   - these two exist purely so both open durations live next to the close
	   ones above, for convenience, not because anything else reads them. */
	--wf-mm-panel-open-opacity-duration: .3s;
	--wf-mm-panel-open-transform-duration: .5s;
}

/* Mega items must NOT create their own positioning context */
.wooforge-header-menu:not(.wooforge-drawer) li.wooforge-mm-item {
	position: static;
}

/* -------------------------------------------------------------------------
   Panel base
   position:fixed lives here (not in JS) so panels are always out of flow,
   even before JS sets their top/left/width — prevents the first-hover jump.
   ------------------------------------------------------------------------- */

.wooforge-mm-panel {
	visibility: hidden;
	opacity: 0;
	pointer-events: none;
	/* Belt-and-braces against content that manages its OWN visibility inside
	   the panel (e.g. [wooforge_product_tabs]'s "active panel" stays
	   visibility:visible + pointer-events:auto so Swiper can measure it while
	   other tabs are hidden — see product-tabs.css). A descendant's own
	   visibility/pointer-events value overrides an ancestor's, so without
	   this the active tab content would render — and be hoverable — at its
	   normal position REGARDLESS of whether this panel is actually open,
	   and since :hover propagates up the DOM by ancestry (not visual
	   position, see below), hovering that content would open the menu on
	   its own. content-visibility:hidden skips the whole subtree's
	   rendering/hit-testing and cannot be locally re-enabled by a
	   descendant, unlike visibility. */
	content-visibility: hidden;
	position: fixed;
	top: 0;
	left: 0;
	z-index: 9999;
	background: #fff;
	overflow: hidden;
	transform: translateY(0px);
	/* fade-out with a .15s grace delay: hopping between two mega items keeps
	   the old panel fully visible until the new one has faded in ON TOP of it
	   (the open panel sits at a higher z-index below), so the switch reads as
	   a swap instead of a close-void-open flicker. visibility flips only
	   after delay + fade so the panel stays clickable during the grace.
	   content-visibility is a discrete property - unless it's listed here
	   too it snaps to hidden the instant :hover ends (no built-in "wait for
	   the fade" behavior), which stops the panel from being painted at all
	   before opacity/transform ever get a chance to visually animate. Giving
	   it the same 0s-duration-plus-delay treatment as visibility fixes that -
	   visibility gets this legacy behavior automatically, but content-
	   visibility is a newer discrete property that needs transition-behavior:
	   allow-discrete opted in explicitly or the delay is ignored entirely. */
	transition: opacity var(--wf-mm-panel-close-opacity-duration) ease var(--wf-mm-panel-close-delay), transform var(--wf-mm-panel-close-transform-duration) ease var(--wf-mm-panel-close-delay), visibility 0s linear var(--wf-mm-panel-close-total), content-visibility 0s linear var(--wf-mm-panel-close-total);
	transition-behavior: allow-discrete;
}

/* -------------------------------------------------------------------------
   Non-fullscreen: CSS :hover opens the panel.
   CSS :hover propagates to the li even when the mouse is over
   a position:fixed child (DOM ancestry, not visual containment).
   ------------------------------------------------------------------------- */

.wooforge-header-menu:not(.wooforge-drawer) .wooforge-mm-item:not(.wooforge-mm--fullscreen):hover > .wooforge-mm-panel {
	visibility: visible;
	content-visibility: visible;
	opacity: 1;
	pointer-events: auto;
	transform: translateY(0);
	z-index: 10000; /* above a still-fading sibling panel */
	/* fade-in: visibility shows immediately, no grace delay */
	transition: opacity var(--wf-mm-panel-open-opacity-duration) ease, transform var(--wf-mm-panel-open-transform-duration) ease, visibility 0s linear 0s;
}

/* A panel that is NOT open must not catch the mouse - itself OR any
   descendant.

   The panel's own pointer-events already reverts to none the instant :hover
   ends, but a DESCENDANT that sets its own pointer-events: auto overrides an
   ancestor's none (unlike opacity, hit-testing is re-enableable further down
   the tree). [wooforge_product_tabs] does exactly that on its active panel -
   .wooforge-tab-panel.is-active in css/product-tabs.css keeps
   visibility: visible + pointer-events: auto so Swiper can measure it.

   That left a --wf-mm-panel-close-total (650ms) window after the mouse left
   during which the fading panel's content was still hoverable. Because CSS
   :hover propagates by DOM ancestry, touching that content re-hovered the
   <li> and re-opened the menu - reported as "move back onto the panel content
   quickly and it comes back", with the pointer nowhere near the nav item.
   content-visibility: hidden in the base rule kills hit-testing for the
   subtree, but only AFTER the fade finishes; flipping it earlier is what
   causes the "fades partway then snaps invisible" bug (see the base rule).

   Only applies while the item is not hovered, so nothing changes for the
   normal path: with the pointer on the nav item the <li> IS hovered, the
   panel stays fully interactive, and moving onto it keeps it open by
   ancestry. :not(.is-open) leaves the JS-driven modes alone - fullscreen and
   click-trigger items open without :hover and would otherwise be dead.

   Side effect worth having: a closing panel can no longer be CLICKED either,
   so a link cannot be hit while it is already half-faded. */
.wooforge-header-menu:not(.wooforge-drawer) .wooforge-mm-item:not(.wooforge-mm--fullscreen):not(.is-open):not(:hover) > .wooforge-mm-panel,
.wooforge-header-menu:not(.wooforge-drawer) .wooforge-mm-item:not(.wooforge-mm--fullscreen):not(.is-open):not(:hover) > .wooforge-mm-panel * {
	pointer-events: none;
}

/* Gap bridge: invisible ::after that fills the vertical gap between the nav
   item's bottom edge and the panel's top edge (= header row bottom).
   Keeps CSS :hover active as the mouse crosses that gap.
   Coordinates are set by JS via CSS custom properties on the li element.    */

.wooforge-header-menu:not(.wooforge-drawer) .wooforge-mm-item:not(.wooforge-mm--fullscreen)::after {
	content: '';
	display: none;
	position: fixed;
	top:    var(--mm-bridge-top,  0px);
	height: var(--mm-bridge-h,    0px);
	left:   var(--mm-bridge-left, 0px);
	width:  var(--mm-bridge-w,    100vw);
	z-index: 9998;
}

.wooforge-header-menu:not(.wooforge-drawer) .wooforge-mm-item:not(.wooforge-mm--fullscreen):hover::after {
	display: block;
}

/* -------------------------------------------------------------------------
   Fullscreen: JS adds .is-open to the li.
   top and height are set by JS (anchored below the header row).
   ------------------------------------------------------------------------- */

.wooforge-mm-panel--fullscreen {
	left: 0;
	width: 100vw; /* overridden by JS with clientWidth to exclude the scrollbar */
	overflow-y: auto;
	-webkit-overflow-scrolling: touch;
	box-shadow: none;
}

.wooforge-mm-item.wooforge-mm--fullscreen.is-open > .wooforge-mm-panel--fullscreen {
	visibility: visible;
	content-visibility: visible;
	opacity: 1;
	pointer-events: auto;
	transform: translateY(0);
	transition: opacity .5s ease, transform .5s ease, visibility 0s linear 0s;
}

/* -------------------------------------------------------------------------
   Full height: full viewport height below the header, auto width.
   top and height are set by JS. left is set by JS (Floating UI or stretch).
   ------------------------------------------------------------------------- */

.wooforge-mm-panel--fullheight {
	overflow-y: auto;
	-webkit-overflow-scrolling: touch;
	box-shadow: none;
}

/* Stretch variant: panel starts at left=0 so the background extends left.
   padding-left (set by JS = nav item's left offset) pushes content to start
   under the nav item. fit-content makes the panel width = padding + content
   natural width, NOT the full viewport. box-sizing:border-box ensures
   fit-content accounts for padding in its size calculation. */
.wooforge-mm-panel--stretch {
	box-sizing: border-box;
	width: fit-content;
}

/* -------------------------------------------------------------------------
   Click mode: per-item .wooforge-mm-trigger--click (set by PHP item_classes,
   or added to all items by JS on touch devices).
   Suppress CSS :hover panel / bridge. Show via JS .is-open instead.
   ------------------------------------------------------------------------- */

.wooforge-header-menu:not(.wooforge-drawer) .wooforge-mm-item.wooforge-mm-trigger--click:not(.wooforge-mm--fullscreen):hover > .wooforge-mm-panel {
	visibility: hidden;
	opacity: 0;
	pointer-events: none;
	transform: translateY(-6px);
	/* content-visibility needs the same delayed-flip treatment as the base
	   rule above - see the comment there. This selector's own transition
	   fully replaces the base rule's for click-trigger items, so it has to
	   be repeated here rather than inherited (including allow-discrete -
	   see the base rule's comment for why content-visibility needs it). */
	transition: opacity .5s ease, transform .5s ease, visibility 0s linear .5s, content-visibility 0s linear .5s;
	transition-behavior: allow-discrete;
}

.wooforge-header-menu:not(.wooforge-drawer) .wooforge-mm-item.wooforge-mm-trigger--click:not(.wooforge-mm--fullscreen):hover::after {
	display: none;
}

.wooforge-header-menu:not(.wooforge-drawer) .wooforge-mm-item.wooforge-mm-trigger--click:not(.wooforge-mm--fullscreen).is-open > .wooforge-mm-panel {
	visibility: visible;
	content-visibility: visible;
	opacity: 1;
	pointer-events: auto;
	transform: translateY(0);
	transition: opacity .5s ease, transform .5s ease, visibility 0s linear 0s;
}

/* -------------------------------------------------------------------------
   Content layout
   ------------------------------------------------------------------------- */

.wooforge-mm-content {
	width: 100%;
}

/* boxed: limit content to container width, centered */
.wooforge-mm-content--boxed {
	max-width: var(--wooforge-max-width, 1200px);
	margin-left: auto;
	margin-right: auto;
	padding: 24px;
	box-sizing: border-box;
}

/* full: content fills the entire panel */
.wooforge-mm-content--full {
	padding: 0;
}

/* For the header design, the panel already covers the exact content area of
   the header (inner container minus its padding). The boxed layout therefore
   doesn't need an additional max-width constraint — the panel IS the box.   */
.wooforge-mm-panel--header .wooforge-mm-content--boxed {
	max-width: 100%;
}

/* -------------------------------------------------------------------------
   Close button (fullscreen only)
   ------------------------------------------------------------------------- */

.wooforge-mm-close {
	position: absolute;
	top: 12px;
	right: 12px;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 32px;
	height: 32px;
	padding: 0;
	background: transparent;
	border: none;
	cursor: pointer;
	z-index: 1;
	opacity: .6;
	transition: opacity .15s;
}

.wooforge-mm-close:hover {
	opacity: 1;
}

.wooforge-mm-close img,
.wooforge-mm-close svg {
	display: block;
	width: 16px;
	height: 16px;
	pointer-events: none;
}

/* -------------------------------------------------------------------------
   Backdrop
   ------------------------------------------------------------------------- */

.wooforge-mm-backdrop {
	visibility: hidden;
	opacity: 0;
	position: fixed;
	top: 0; /* overridden by JS to sit below the header row */
	right: 0;
	bottom: 0;
	left: 0;
	z-index: 9998;
	background: rgba(0, 0, 0, .35);
	pointer-events: none; /* must not intercept mouse events — would break CSS :hover on the nav item */
	transition: opacity .3s ease, visibility 0s linear .3s;
	/* Single source of truth for the appear-transition timing below, shared
	   by BOTH activation paths (fullscreen JS .is-visible, and the :has()
	   CSS rule for regular hover-triggered items) via var() — change these
	   two values here ONCE, not by hunting down and syncing two near-
	   identical rules by hand. */
	--wf-mm-backdrop-appear-duration: .3s;
	--wf-mm-backdrop-appear-delay: .15s;
}

/* Fullscreen backdrop: toggled by JS (.is-visible class).
   Needs pointer-events so clicking it closes the fullscreen panel.
   The delay above lets the panel's own fade-in (opacity .3s, no delay - see
   the :hover > .wooforge-mm-panel rule) get most of the way to fully opaque
   BEFORE the backdrop starts darkening behind it. Without it, both fade in
   together from 0 - the panel's own semi-transparent white background lets
   the backdrop show through it during the overlap, reading as a muddy grey
   wash instead of a clean panel-over-dimmed-page look, even though the
   panel is correctly stacked above the backdrop the entire time (this was
   never a z-index bug - see #masthead's own comment in css/main.css for
   the *closing* stacking issue, which is separate from this opacity one). */
.wooforge-mm-backdrop.is-visible {
	visibility: visible;
	opacity: 1;
	pointer-events: auto;
	transition: opacity var(--wf-mm-backdrop-appear-duration) ease var(--wf-mm-backdrop-appear-delay), visibility 0s linear 0s;
}

/* Non-fullscreen backdrop: toggled by CSS :has() when a hover-trigger backdrop item is hovered.
   Excluded for click-trigger items (.wooforge-mm-trigger--click) — those use JS .is-visible.
   pointer-events stays none so the backdrop never breaks the CSS :hover chain.
   Same timing (via the shared var()s above) as the fullscreen rule - see that comment. */
@supports selector(:has(a)) {
	body:has(
		.wooforge-header-menu:not(.wooforge-drawer)
		.wooforge-mm-item.wooforge-mm-has-backdrop:not(.wooforge-mm--fullscreen):not(.wooforge-mm-trigger--click):hover
	) .wooforge-mm-backdrop {
		visibility: visible;
		opacity: 1;
		transition: opacity var(--wf-mm-backdrop-appear-duration) ease var(--wf-mm-backdrop-appear-delay), visibility 0s linear 0s;
	}
}

/* -------------------------------------------------------------------------
   Stacking context fix for sticky header rows
   -------------------------------------------------------------------------
   When a header row becomes sticky (.is-stuck), it gets position:fixed +
   z-index:200/201, which creates its own stacking context. The mega-menu
   panel's z-index:9999 then becomes local to that context (effective root
   z-index ≈ 201), letting the backdrop at z-index:9998 paint on top of it.
   Raising #masthead to z-index:9999 makes the whole masthead subtree paint
   as one unit above the backdrop — the same trick used for fullscreen search
   in css/main.css ("body.wooforge-fullscreen-search-open #masthead").
   ------------------------------------------------------------------------- */
/* JS adds .wooforge-mm-open to body as a no-:has() fallback (fullscreen items).
   transition-delay:0 keeps the RAISE instant - the DELAYED drop back to the
   base z-index (.45s, matching this file's own panel fade-out) lives on
   #masthead's base rule in css/main.css, since transition-delay belongs to
   whichever rule is winning the cascade for `transition`, not to whichever
   rule happens to change z-index. */
body.wooforge-mm-open #masthead {
	z-index: 9999;
	transition: z-index 0s linear 0s;
}

@supports selector(:has(a)) {
	body:has(
		.wooforge-header-menu:not(.wooforge-drawer) .wooforge-mm-item:hover,
		.wooforge-header-menu:not(.wooforge-drawer) .wooforge-mm-item.is-open
	) #masthead {
		z-index: 9999;
		transition: z-index 0s linear 0s;
	}
}

/* Non-stuck row--bottom: CSS safety net that mirrors the JS fix above.
   Gives row--bottom a stacking context at z-index:0 so the panel (z-index:9999,
   step 7) always paints above it (step 6) when a mega-menu item is active. */
@supports selector(:has(a)) {
	body:has(
		.wooforge-header-menu:not(.wooforge-drawer) .wooforge-mm-item:hover,
		.wooforge-header-menu:not(.wooforge-drawer) .wooforge-mm-item.is-open
	) .wooforge-header-row--bottom:not(.is-stuck) {
		position: relative;
		z-index: 0;
	}
}
body.wooforge-mm-open .wooforge-header-row--bottom:not(.is-stuck) {
	position: relative;
	z-index: 0;
}

/* -------------------------------------------------------------------------
   Drawer (mobile) — never show mega panels inside the mobile drawer
   ------------------------------------------------------------------------- */

.wooforge-drawer .wooforge-mm-panel {
	display: none !important;
}
