/**
 * aysen-menu v2.0.0 frontend styles.
 * Scoped, no body portal, no Builder-only hacks.
 */

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

.aysen-menu {
	--aysen-menu-bg: rgba(255, 255, 255, 0.82);
	--aysen-menu-panel-bg: rgba(255, 255, 255, 0.96);
	--aysen-menu-text: #111827;
	--aysen-menu-muted: #6b7280;
	--aysen-menu-border: rgba(17, 24, 39, 0.1);
	--aysen-menu-radius: 22px;
	--aysen-menu-panel-radius: 28px;
	--aysen-menu-shadow: 0 24px 80px rgba(15, 23, 42, 0.16);
	--aysen-menu-gap: 4px;
	/* v1.4.2: real frontend inspection (Playwright, computed styles) found
	   the v1.4.1 fix never actually took effect visually -- an item using
	   the plugin's existing item-meta "referenced menu" feature
	   (Aysen_Menu_Item_Meta: enabled + menu_id) rendered a 7-column,
	   1368px-wide panel, because that mega-style multi-root case and a
	   plain 2-level dropdown share the exact same `.aysen-menu__panel` /
	   `.aysen-menu__panel-inner` CSS with no mode separation. Restored to
	   1120px -- its correct role now that it is used ONLY for the true
	   mega case (`.aysen-menu__item.is-mega`, see below); the plain-
	   dropdown case uses its own fixed 360px cap, not this variable. */
	--aysen-menu-panel-max: 1120px;
	position: relative;
	z-index: 10;
	width: 100%;
	color: var(--aysen-menu-text);
	direction: inherit;
}

/* Full Width Menu (Menu Layout toggle, off by default): breaks the outer
   `.aysen-menu` wrapper out to the full viewport width using the standard
   negative-margin technique -- works correctly as long as the module's
   Divi row/column is itself horizontally centered on the page (the normal
   case); a column that is NOT centered (e.g. an off-center layout inside a
   multi-column row) is a known limitation of this technique, not fixable
   from CSS alone. Guarded to `min-width: 981px` -- the same fixed boundary
   the `@media (max-width: 980px)` mobile-drawer block below already uses --
   so this desktop/tablet-only breakout can never leak into the mobile
   accordion's own compact, stacked layout. `.aysen-menu__inner` (a plain,
   always-present wrapper around `.aysen-menu__bar`, unstyled when this
   class is absent) is what keeps the actual menu content at a comfortable,
   centered, padded width instead of stretching every item edge to edge. */
@media (min-width: 981px) {
	.aysen-menu--full-width {
		width: 100vw;
		max-width: 100vw;
		margin-inline-start: calc(50% - 50vw);
		margin-inline-end: calc(50% - 50vw);
	}

	.aysen-menu--full-width .aysen-menu__inner {
		max-width: var(--aysen-menu-content-max-width, 1180px);
		margin-inline: auto;
		padding-inline: 24px;
	}

	/* Menu Alignment (existing "layout" setting) still governs how the
	   controlled inner container sits inside the now-full-width bar --
	   Left/Right push it to that edge instead of centering it, matching
	   the same alignment intent the setting already has for the item
	   list itself. Center keeps the default centered inner container
	   (margin-inline: auto above).

	   v1.5.5 RTL fix: this used `margin-inline-start`/`-end`, which are
	   LOGICAL (they flip meaning with `direction`) -- the exact same bug
	   class already fixed for `justify-content` below, just missed here.
	   With `direction: rtl` active (see the `.rtl .aysen-menu` rule further
	   down), `margin-inline-start: 0` zeroed the PHYSICAL RIGHT margin, so
	   selecting "Left" pushed the inner content to the visual right instead
	   -- confirmed live on the real page (Full Width Menu + RTL). "Left"/
	   "Right" are physical/visual labels here too, so the fix is the same:
	   plain physical `margin-left`/`margin-right`, immune to `direction`. */
	.aysen-menu--full-width.aysen-menu--align-left .aysen-menu__inner {
		margin-left: 0;
	}

	.aysen-menu--full-width.aysen-menu--align-right .aysen-menu__inner {
		margin-right: 0;
	}
}

.aysen-menu--notice .aysen-menu__notice {
	padding: 14px 18px;
	border: 1px dashed var(--aysen-menu-border);
	border-radius: 12px;
	font-size: 13px;
	color: var(--aysen-menu-muted);
}

/* v1.1.3: .aysen-menu__bar intentionally has no styling -- it is a neutral
   structural wrapper only (kept because the renderer/Builder preview still
   emit it), so it no longer creates its own visual layer on top of the
   module's actual background. */

.aysen-menu__list,
.aysen-menu__sublist {
	list-style: none !important;
	margin: 0;
	padding: 0;
}

.aysen-menu__list {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: var(--aysen-menu-gap);
	width: 100%;
}

/* v1.2.1 Trigger Surface Behavior Fix: the surface wrapping .aysen-menu__list
   is what each tier's Trigger Mode CSS (see build_instance_style()) shows/
   hides/positions -- display:contents in Normal Menu mode, so it never
   generates its own box and the list above renders exactly as if
   unwrapped, inline in the bar. In Icon/Text modes the same wrapper
   becomes a detached, absolutely-positioned dropdown/drawer surface
   instead (positioning only, no decorative styling). */
.aysen-menu__surface {
	width: 100%;
}

/* Menu Alignment fix: `flex-start`/`flex-end` are LOGICAL (they follow the
   flex container's writing direction) -- on an RTL page (`direction: rtl`
   computed on `.aysen-menu`), `flex-start` resolves to the visual RIGHT
   and `flex-end` to the visual LEFT, so selecting "Left" rendered the menu
   on the right and vice versa. The Builder labels ("Left"/"Right") are
   physical/visual terms, not logical start/end, so the CSS uses the
   literal `left`/`right` `justify-content` keywords (CSS Box Alignment,
   supported in all modern browsers) -- these always align to the visual
   left/right edge of the container regardless of `direction`, guaranteeing
   the selected label always matches what the user sees, in both LTR and
   RTL, and regardless of whether WordPress's own `is_rtl()`/`.rtl` body
   class happens to be active -- this mapping does not read `direction` at
   all, so it needs no RTL detection of its own to be correct. "Space
   Between" has been removed from the Builder options (module.json) and
   from Aysen_Menu_Renderer's allow-list -- a legacy saved "space-between"
   value now sanitizes to "center" before it ever reaches a class name, so
   this selector is intentionally no longer emitted; the shared base rule
   above (`.aysen-menu__list{justify-content:center}`) is what a legacy
   value falls back to.

   v1.5.5: renamed from `aysen-menu--layout-*` to `aysen-menu--align-*` --
   explicit "align" naming makes the visual-alignment intent unambiguous
   at the selector level (Aysen_Menu_Renderer emits the new class name;
   the Divi 5 Builder preview JS now emits the same class for the same
   saved value, see class-aysen-menu-divi5-builder-js.php's Edit()). */
.aysen-menu--align-left .aysen-menu__list { justify-content: left; }
.aysen-menu--align-center .aysen-menu__list { justify-content: center; }
.aysen-menu--align-right .aysen-menu__list { justify-content: right; }

/* v1.3.0 Menu Design (Phase 3): Menu Direction. */
.aysen-menu--direction-horizontal .aysen-menu__list { flex-direction: row; }
.aysen-menu--direction-vertical .aysen-menu__list { flex-direction: column; }

/* v1.3.1 Menu Layout Presets: all rules target .aysen-menu__bar/__list/__link
   only (never the module wrapper Divi's own native Background/Sizing/
   Spacing/Border/Box Shadow controls target), so those native controls
   remain fully independent and can still override/layer on top. Plain
   class selectors, no !important, "default" adds no rules at all. */

.aysen-menu--preset-minimal .aysen-menu__link:hover,
.aysen-menu--preset-minimal .aysen-menu__link:focus-visible {
	background: transparent;
}

/* v1.3.3: no preset below hardcodes border-radius. Rounded corners (Glass's
   soft corners, Pill's rounded/pill shape, Floating's rounded card) are
   achieved by setting a radius through the native Divi Border controls
   (module-level Border, Menu Border, or Trigger Border) -- this stylesheet
   only ever provides the non-radius part of each look (translucency/blur,
   padding, shadow, background). */

.aysen-menu--preset-glass .aysen-menu__bar {
	background: rgba(255, 255, 255, 0.6);
	border: 1px solid rgba(255, 255, 255, 0.35);
	backdrop-filter: blur(12px);
	-webkit-backdrop-filter: blur(12px);
}

.aysen-menu--preset-pill .aysen-menu__bar {
	padding: 4px 8px;
}

.aysen-menu--preset-underline .aysen-menu__link {
	border-bottom: 2px solid transparent;
}

.aysen-menu--preset-underline .aysen-menu__link:hover,
.aysen-menu--preset-underline .aysen-menu__link:focus-visible {
	background: transparent;
	border-bottom-color: currentColor;
}

.aysen-menu--preset-floating .aysen-menu__bar {
	background: #fff;
	box-shadow: 0 12px 30px rgba(15, 23, 42, 0.12);
}

.aysen-menu--preset-compact .aysen-menu__list {
	gap: 0;
}

.aysen-menu--preset-compact .aysen-menu__link,
.aysen-menu--preset-compact .aysen-menu__toggle {
	min-height: 32px;
	padding: 6px 10px;
}

.aysen-menu__item {
	position: relative;
	display: flex;
	align-items: center;
}

/* v1.5.1 Attached position-stability fix: an Attached panel must anchor to
   the stable .aysen-menu wrapper (or, when Trigger Mode has opened a real
   .aysen-menu__surface box, that surface) -- never to whichever item is
   currently hovered. CSS containing-block resolution walks up the DOM to
   the nearest POSITIONED ancestor; `.aysen-menu__item` is `position:
   relative` by default (needed for Detached, which IS meant to anchor to
   its own item), so an Attached panel nested inside it was resolving its
   `top`/`inset-inline-start`/`width` against the ITEM's own box --
   different for every item, which is exactly why the panel visibly moved
   depending on which item was hovered (confirmed via real computed-style
   proof: identical --aysen-dropdown-shift-x math, applied against a
   per-item base position, still yields a per-item result once the base
   itself differs). Removing `position` from the item (falling back to
   `static`) makes it transparent to containing-block resolution, so the
   panel's containing block becomes `.aysen-menu` itself (or the open
   surface) -- the SAME element regardless of which item is hovered.
   `align-self: stretch` closes the resulting vertical gap at the source:
   the item's own box now always reaches the full row height (the bar's
   height), so `top: 100%` on the panel (now relative to .aysen-menu)
   lines up flush with the item's own visual bottom edge too, with no
   dead zone to bridge -- the prior JS-computed hover-bridge pseudo-
   element this rule replaced is no longer needed for any panel type. */
.aysen-menu__item--attached {
	position: static;
	align-self: stretch;
}

/* v1.5.2 hover-bridge (reinstated, JS-driven): real measurement found
   `align-self: stretch` above does not always fully close the vertical
   gap between an item's own rendered box and the panel's top edge (the
   flex line's cross-size can still exceed the stretched item's actual
   height depending on sibling content) -- a real gap of ~20px was
   confirmed via computed getBoundingClientRect() values even with
   stretch applied. Rather than trust that gap is always zero, this
   `::after` covers whatever gap actually measures for THIS item
   (`--aysen-attached-bridge-height`, computed once per open by
   `initAttachedHoverStability()` in aysen-menu.js, defaulting to 0px if
   unmeasured/not needed). Pointer events dispatched on a `::after` box
   target the HOST element (the item) per spec, so hovering this bridge
   fires the item's own `mouseenter`/`mouseleave` -- no separate JS
   wiring needed here, it plugs directly into the existing open/close
   state machine. Positioned below the item only (never overlapping the
   link itself), so it never blocks clicks on real menu links.

   v1.5.4 false-open fix: `top: 100%` / `inset-inline-start: 0` / `width:
   100%` used to resolve against this pseudo-element's CONTAINING BLOCK,
   not its host item -- and since `.aysen-menu__item--attached` is
   `position: static` (see above, intentional for the PANEL's own
   anchoring), the containing block these percentages resolved against
   was `.aysen-menu` itself, the same wide/sticky ancestor the panel
   anchors to. Real browser proof: with Full Width Menu active, this
   stretched the bridge to the ENTIRE bar's width (0-1400px) starting at
   the BAR's own bottom edge, not the item's -- turning "hover empty
   space anywhere below the menu bar" into a false open trigger for
   whichever item last measured a bridge, confirmed via a real user
   screen recording plus live elementFromPoint proof. Switched to pixel
   values computed by sizeHoverBridge() relative to `.aysen-menu`
   (`--aysen-attached-bridge-left/-top/-width`), which is what actually
   scopes this box back to the item's own footprint regardless of which
   ancestor ends up being the true containing block. Physical `left` is
   intentional (not `inset-inline-start`): the JS math is done in
   viewport pixels via getBoundingClientRect(), which are always
   physical, so a logical property here would silently mismatch under
   RTL. */
.aysen-menu__item--attached::after {
	content: '';
	position: absolute;
	top: var(--aysen-attached-bridge-top, 0px);
	left: var(--aysen-attached-bridge-left, 0px);
	width: var(--aysen-attached-bridge-width, 0px);
	height: var(--aysen-attached-bridge-height, 0px);
	pointer-events: auto;
}

.aysen-menu__link,
.aysen-menu__toggle,
.aysen-menu__group-title,
.aysen-menu__sublink {
	text-decoration: none;
	line-height: 1.2;
}

.aysen-menu__link,
.aysen-menu__toggle {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-height: 42px;
	padding: 10px 14px;
	border: 0;
	/* v1.3.3: no default border-radius here -- rounded corners are only
	   ever added by the native Divi Border controls (module-level Border,
	   Menu Border, or Trigger Border), never hardcoded by this stylesheet. */
	background: transparent;
	color: var(--aysen-menu-text);
	font: inherit;
	font-size: 14px;
	font-weight: 500;
	letter-spacing: -0.01em;
	cursor: pointer;
	transition: background-color 180ms ease, color 180ms ease, transform 180ms ease;
}

.aysen-menu__link:hover,
.aysen-menu__link:focus-visible,
.aysen-menu__toggle:hover,
.aysen-menu__toggle:focus-visible,
.aysen-menu__item.is-panel-open > .aysen-menu__link,
.aysen-menu__item:hover > .aysen-menu__link {
	background: rgba(17, 24, 39, 0.07);
	color: var(--aysen-menu-text);
	outline: none;
}

.aysen-menu__panel-toggle {
	display: none;
	align-items: center;
	justify-content: center;
	width: 36px;
	height: 36px;
	padding: 0;
	border: 0;
	border-radius: 999px;
	background: rgba(17, 24, 39, 0.06);
	color: currentColor;
	font-size: 20px;
	line-height: 1;
	cursor: pointer;
}

.aysen-menu__panel {
	/* v1.4.1/v1.4.2/v1.4.3: `top` used to be `calc(100% + 12px)` -- a
	   permanent 12px gap between the item's bottom edge and the panel's
	   top edge that belonged to neither element's hoverable box. `:hover`
	   on `.aysen-menu__item` only persists while the pointer is over the
	   item or one of its DOM descendants (the panel qualifies once
	   reached), but that dead strip in between was over neither, so the
	   panel closed before the pointer ever reached it. Docking flush at
	   `top: 100%` (0 gap) removes the dead zone entirely -- no JS delay
	   needed since hover open/close here is pure CSS (see aysen-menu.js --
	   hover mode never toggles a JS class, only :hover/:focus-within do).

	   v1.4.3 correction: v1.4.2 anchored the mega-mode panel with
	   `inset-inline-start: 50%` + `translate(-50%, ...)` -- centering a
	   WIDE panel on a NARROW parent item. Real frontend inspection showed
	   this drags the panel far to the visual left of the item on a
	   typical viewport (a 1120px-wide panel centered on a ~100px item
	   extends ~510px past each side of the item), reported as "opening
	   from the left" instead of "under the item". The anchor is now
	   UNIFIED for both modes -- always `inset-inline-start: 0` (the
	   panel's start edge flush with the item's own start edge, i.e.
	   directly under it) -- only WIDTH differs between normal/mega below.
	   `--aysen-dropdown-shift-x` is written by aysen-menu.js only when the
	   anchored panel would overflow the viewport edge (see
	   positionDropdownPanel()); it defaults to 0px (no shift) so the
	   parent item remains the primary anchor in the normal case, per this
	   phase's explicit requirement to never default-position from the
	   page edge. This shared rule only carries properties common to BOTH
	   modes -- width differs by mode, added below via `.is-mega`/default
	   split. Kept at a single class selector (0,1,0) specificity so native
	   Divi decoration output for `dropdownBox` (always at least a 2-class
	   generated selector) can freely override any of these. */
	position: absolute;
	top: 100%;
	inset-inline-start: 0;
	inset-inline-end: auto;
	z-index: 20;
	transform: translateX(var(--aysen-dropdown-shift-x, 0px)) translateY(-6px);
	padding: 16px;
	border: 1px solid var(--aysen-menu-border);
	border-radius: var(--aysen-menu-panel-radius);
	background: var(--aysen-menu-panel-bg);
	box-shadow: var(--aysen-menu-shadow);
	opacity: 0;
	visibility: hidden;
	pointer-events: none;
	transition: opacity 180ms ease, transform 180ms ease, visibility 180ms ease;
	backdrop-filter: saturate(180%) blur(22px);
	-webkit-backdrop-filter: saturate(180%) blur(22px);
}

/* v1.4.2: mode separation. A "normal dropdown" (plain direct children) and
   a true "mega panel" (item-meta enabled + a referenced menu_id --
   `Aysen_Menu_Item_Meta`, an existing feature, now also exposed as the
   `is-mega` class on `.aysen-menu__item` in `top_item_html()`) were
   sharing this exact same panel/grid CSS with no way to tell them apart,
   which is why a plain dropdown was rendering as a wide multi-column mega
   block (confirmed via real computed styles: 1368px wide, 7 grid columns).
   `:where(...)` wraps the mode selector so it contributes ZERO specificity
   beyond the plain `.aysen-menu__panel`/`.aysen-menu__panel-inner`/etc.
   selector already has -- this guarantees native Divi decoration output
   (`dropdownBox` Sizing, always >= 2 classes) can still override either
   mode's default width/alignment without a specificity fight. Only WIDTH
   differs between the two modes now (see anchor unification note above). */
:where(.aysen-menu__item:not(.is-mega)) > .aysen-menu__panel {
	width: max-content;
	min-width: 220px;
	max-width: min(360px, calc(100vw - 32px));
}

:where(.aysen-menu__item.is-mega) > .aysen-menu__panel {
	width: min(var(--aysen-menu-panel-max), calc(100vw - 32px));
	max-width: var(--aysen-menu-panel-max);
}

/* Dropdown Layout Preset (corrected): two controlled desktop-dropdown
   layouts, now applied to EVERY panel including mega/contained ones --
   Aysen_Menu_Renderer::panel_html() emits exactly one of `--attached`
   (default) or `--detached` on every `.aysen-menu__panel`. Real browser
   proof on the production page (whose only has-panel item is mega) found
   the previous non-mega-only gate meant this class never reached that
   item at all, so toggling the setting had no visible effect there --
   fixed by removing the gate in the renderer. `--full` (mega-only,
   two-class selector below) still wins over either preset via
   specificity, so a genuinely full-width mega panel is unaffected.
   Trigger surface and mobile drawer remain untouched by either rule below.

   Detached: an alias for the compact/anchored behavior already
   established above (`:not(.is-mega)`'s own default) -- kept as its own
   explicit rule so it no longer depends on a negation once a panel
   carries an explicit `--detached` class. Deliberately NOT wrapped in
   `:where()` here -- unlike the mode-gate rules above (where only the
   `:not(.is-mega)` CHECK is wrapped, leaving the targeted `.aysen-menu__
   panel` class outside contributing its own (0,1,0)), wrapping the ENTIRE
   selector (including the class actually being targeted) in `:where()`
   zeroes its specificity completely -- which would always lose to the
   (0,1,0) compact-mode rule above regardless of source order. A plain
   class selector here matches that same (0,1,0), so source order (this
   rule comes later) correctly decides the tie. */
.aysen-menu__panel--detached {
	width: max-content;
	min-width: 220px;
	max-width: min(360px, calc(100vw - 32px));
}

/* Attached (default): a wide surface flush under the menu bar, anchored to
   the stable .aysen-menu wrapper (never the hovered item -- see
   `.aysen-menu__item--attached`'s `position: static` above, which makes
   `.aysen-menu` the containing block these `inset-inline-*`/`width`
   values resolve against). Pure CSS, no JS measurement of any per-item
   rect: the panel's outer geometry (top/left/width) is therefore
   identical no matter which item is hovered. `transform` is pinned to a
   plain fade/slide with no horizontal component -- Attached must never
   pick up Detached's viewport-overflow `--aysen-dropdown-shift-x`, which
   is why this rule overrides transform explicitly rather than relying on
   the shared base rule's `var(--aysen-dropdown-shift-x, 0px)` fallback. */
.aysen-menu__panel--attached {
	top: 100%;
	inset-inline-start: 0;
	inset-inline-end: 0;
	width: 100%;
	max-width: none;
	padding: 0;
	border-radius: 0;
	transform: translateY(-6px);
}

/* Full Width Menu + Attached: the panel's containing block is already
   `.aysen-menu` itself (see `.aysen-menu__item--attached`'s `position:
   static` above), so `width: 100%` above already tracks `.aysen-menu`'s
   own box automatically once THAT becomes 100vw -- this rule is an
   explicit, redundant safety net (not the actual mechanism), matching
   the same `min-width: 981px` mobile exclusion as the outer breakout so
   it can never affect the mobile accordion's own forced `width: 100%`
   panel layout. */
@media (min-width: 981px) {
	.aysen-menu--full-width .aysen-menu__panel--attached {
		width: 100vw;
		max-width: 100vw;
	}
}

/* v1.4.6: "full width" (the existing per-item "Panel width: Full-width
   panel" admin option, Aysen_Menu_Item_Meta::META_WIDTH) is now scoped to
   REQUIRE the mega item context (`.aysen-menu__item--mega`, new in this
   phase, alongside the existing `is-mega`) before it can stretch a panel
   to near-viewport width. This is defense-in-depth: `save_fields()`
   already deletes width/variant/class meta whenever "Enable mega panel"
   is unchecked, so a plain (non-mega) dropdown item cannot currently
   acquire `--full` through the admin UI at all -- but scoping the CSS
   this way means even a future data/code path that produced `--full` on
   a non-mega item could never stretch it, rather than silently trusting
   PHP-side data integrity alone. Two classes (0,2,0) so it still wins
   over the (0,1,0) `:where()` mode defaults above. */
.aysen-menu__item--mega > .aysen-menu__panel--full {
	inset-inline-start: 0;
	inset-inline-end: auto;
	width: calc(100vw - 32px);
	max-width: calc(100vw - 32px);
}

/* v1.5.2 hover-stability fix: raw `:hover`/`:focus-within` is excluded for
   `--attached` panels here (`:not(.aysen-menu__panel--attached)`) -- an
   Attached panel is not conceptually "owned" by the hovered item's own
   hitbox (its containing block is `.aysen-menu`, see `.aysen-menu__item
   --attached`'s `position: static` above), so native `:hover` continuity
   is fragile: the moment the pointer leaves the item's own small box en
   route to the wide panel below, the browser's `:hover` state (binary,
   zero grace period) stops matching instantly, closing the panel before
   the pointer arrives -- confirmed via real user screen recording.
   Attached panels are opened/closed exclusively by aysen-menu.js's
   `initAttachedHoverStability()`, which manages `.is-panel-open` with a
   grace-delay close that re-checks live `:hover` state on both the item
   and its panel before actually closing (see that function for the full
   containment logic) -- `.is-panel-open` below is that single source of
   truth. Detached/mega (non-attached) panels are unaffected: their
   containing block IS the hovered item itself (flush, zero gap), already
   verified stable under plain CSS `:hover`/`:focus-within`, so they keep
   using it here (also still needed for keyboard-only `:focus-within`
   support on those panels, and for click-mode's own use of
   `.is-panel-open`, both unchanged). */
.aysen-menu--open-hover .aysen-menu__item:hover > .aysen-menu__panel:not(.aysen-menu__panel--attached),
.aysen-menu--open-hover .aysen-menu__item:focus-within > .aysen-menu__panel:not(.aysen-menu__panel--attached),
.aysen-menu__item.is-panel-open > .aysen-menu__panel {
	opacity: 1;
	visibility: visible;
	pointer-events: auto;
	transform: translateX(var(--aysen-dropdown-shift-x, 0px)) translateY(0);
}

.aysen-menu__panel-inner {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
	gap: 18px;
}

/* Normal dropdown mode never needs the multi-column mega grid -- a plain
   2-level menu always renders each direct child as its own root/group (see
   panel_html()), so a lone CSS Grid `1fr` track still claims all
   distributable space even when its container is intrinsically sized --
   the real cause of the "tiny text centered in a huge empty box" symptom.
   Switched to a column flex stack (not `display:block`) specifically so
   MULTIPLE stacked groups/headings (one per direct child when none of them
   have their own children) still get consistent gap spacing between rows
   -- `gap` has no effect under plain block layout. */
:where(.aysen-menu__item:not(.is-mega)) .aysen-menu__panel-inner {
	display: flex;
	flex-direction: column;
	gap: 6px;
}

:where(.aysen-menu__item:not(.is-mega)) .aysen-menu__group {
	padding: 0;
	border-radius: 0;
}

/* Inner content container, keyed by the PRESET CLASS itself (not by
   is-mega) so a mega/contained panel gets the same treatment as a plain
   one once it also carries `--attached`/`--detached`. Reuses the existing
   `.aysen-menu__panel-inner` element (already present in the DOM for
   every panel; no new wrapper needed). Both rules are mode-gate `:where()`
   wraps (only the preset-class CHECK is zeroed, `.aysen-menu__panel-inner`
   itself stays outside contributing its own (0,1,0)) placed after the
   plain base `.aysen-menu__panel-inner` rule and the older `:not(.is-
   mega)` flex-column rule above, so each wins its own equal-specificity
   tie via source order. */
:where(.aysen-menu__panel--attached) > .aysen-menu__panel-inner {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
	gap: 24px;
	width: min(100%, var(--aysen-dropdown-attached-content-width, 980px));
	margin-inline: auto;
	padding-inline: var(--aysen-dropdown-attached-padding-inline, 24px);
	padding-block: var(--aysen-dropdown-attached-padding-block, 32px);
}

:where(.aysen-menu__panel--detached) > .aysen-menu__panel-inner {
	display: flex;
	flex-direction: column;
	gap: 6px;
	width: auto;
}

.aysen-menu__group {
	min-width: 0;
	padding: 12px;
	border-radius: 18px;
}

.aysen-menu__panel--variant-cards .aysen-menu__group {
	background: rgba(17, 24, 39, 0.045);
}

.aysen-menu__panel--variant-compact .aysen-menu__group {
	padding: 4px;
}

.aysen-menu__group-title {
	display: inline-flex;
	margin-bottom: 8px;
	color: var(--aysen-menu-text);
	font-size: 13px;
	font-weight: 700;
	letter-spacing: -0.01em;
}

/* v1.4.2: in normal dropdown mode, `.aysen-menu__group-title` (a heading
   that repeats the item's own title) is frequently the ONLY visible row a
   plain 2-level dropdown has, since `panel_html()`'s "root" items are the
   parent's direct children -- a heading-styled single row is what read as
   "tiny text floating in empty space" in the reported screenshot. Restyled
   here as a normal dropdown row (matches `.aysen-menu__sublink`'s own row
   look) whenever it appears inside a non-mega item; genuine mega headings
   (`.is-mega`) keep the original heading look above, untouched. Colors/
   sizes stay inside `:where()` so Dropdown Heading (`dropdownHeading`)
   still overrides them exactly as before. */
:where(.aysen-menu__item:not(.is-mega)) .aysen-menu__group-title {
	display: block;
	width: 100%;
	margin-bottom: 0;
	padding: 8px 0;
	font-size: 14px;
	font-weight: 500;
	color: var(--aysen-menu-muted);
	text-align: start;
	white-space: nowrap;
}

:where(.aysen-menu__item:not(.is-mega)) .aysen-menu__sublist {
	display: flex;
	flex-direction: column;
	gap: 6px;
	width: 100%;
}

:where(.aysen-menu__item:not(.is-mega)) .aysen-menu__sublink {
	display: block;
	width: 100%;
	text-align: start;
	white-space: nowrap;
}

.aysen-menu__sublist {
	display: grid;
	/* v1.4.1: was 2px -- too tight for the "poor spacing" baseline
	   complaint; still fully overridable via Dropdown Item Spacing. */
	gap: var(--aysen-menu-dropdown-gap, 6px);
}

.aysen-menu__sublink {
	display: flex;
	padding: 8px 0;
	border-radius: 10px;
	color: var(--aysen-menu-muted);
	font-size: 14px;
	transition: color 160ms ease, transform 160ms ease;
}

.aysen-menu__sublink:hover,
.aysen-menu__sublink:focus-visible {
	color: var(--aysen-menu-text);
	transform: translateX(2px);
	outline: none;
}

.aysen-menu__toggle {
	gap: 10px;
}

.aysen-menu__toggle-lines {
	display: grid;
	gap: 4px;
	width: 18px;
}

.aysen-menu__toggle-lines span {
	display: block;
	height: 2px;
	border-radius: 2px;
	background: currentColor;
	transition: transform 180ms ease, opacity 180ms ease;
}

.aysen-menu.is-open .aysen-menu__toggle-lines span:nth-child(1) {
	transform: translateY(6px) rotate(45deg);
}

.aysen-menu.is-open .aysen-menu__toggle-lines span:nth-child(2) {
	opacity: 0;
}

.aysen-menu.is-open .aysen-menu__toggle-lines span:nth-child(3) {
	transform: translateY(-6px) rotate(-45deg);
}

/* v1.2.0 Trigger Settings: Mobile Trigger Icon variants. Each variant
   renders different markup (see Aysen_Menu_Renderer::toggle_icon_html());
   this is the minimum structural CSS needed for each to actually look
   distinct -- no new colors, shadows, or decorative styling. */

.aysen-menu__toggle-lines--dots {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 4px;
	width: 18px;
	height: 4px;
}

.aysen-menu__toggle-lines--dots span {
	width: 4px;
	height: 4px;
	border-radius: 50%;
	background: currentColor;
}

.aysen-menu__toggle-lines--chevron {
	display: block;
	width: 12px;
	height: 12px;
}

.aysen-menu__toggle-lines--chevron span {
	display: block;
	width: 100%;
	height: 100%;
	border-right: 2px solid currentColor;
	border-bottom: 2px solid currentColor;
	transform: rotate(45deg);
	transition: transform 180ms ease;
}

.aysen-menu.is-open .aysen-menu__toggle-lines--chevron span {
	transform: rotate(225deg);
}

.aysen-menu__toggle-lines--plus {
	position: relative;
	width: 18px;
	height: 18px;
}

.aysen-menu__toggle-lines--plus span {
	position: absolute;
	top: 50%;
	left: 50%;
	background: currentColor;
	transition: transform 180ms ease;
}

.aysen-menu__toggle-lines--plus span:nth-child(1) {
	width: 18px;
	height: 2px;
	transform: translate(-50%, -50%);
}

.aysen-menu__toggle-lines--plus span:nth-child(2) {
	width: 2px;
	height: 18px;
	transform: translate(-50%, -50%);
}

.aysen-menu.is-open .aysen-menu__toggle-lines--plus span:nth-child(2) {
	transform: translate(-50%, -50%) rotate(90deg);
	opacity: 0;
}

/* v1.2.0 Sticky Mode state classes. "sticky" and "sticky-scroll-up" are
   sticky-positioned from the start; "sticky-offset" only becomes sticky
   once JS adds .is-sticky-armed after the configured scroll offset is
   passed. Scoped to this module instance only -- no global/body-level
   positioning. */

.aysen-menu--sticky-sticky,
.aysen-menu--sticky-sticky-scroll-up {
	position: sticky;
	top: 0;
	transition: transform 200ms ease;
}

.aysen-menu--sticky-sticky-scroll-up.is-sticky-hidden {
	transform: translateY(-100%);
}

.aysen-menu--sticky-sticky-offset.is-sticky-armed {
	position: sticky;
	top: 0;
}

/* v1.4.4: the v1.4.3 fullscreen trigger-mode overlay (surface promoted to
   `position:fixed`, `.aysen-menu` and its toggle escalated to z-index
   999999/1000000, nested dropdown panels forced static/full-width/
   vertical while open) has been explicitly cancelled -- real frontend
   testing found it created overlapping/conflicting states with normal
   desktop hover dropdowns, since both live under the same z-index-
   promoted `.aysen-menu` ancestor. Trigger mode's opened surface is back
   to the original simple, compact, absolute-positioned box (see
   Aysen_Menu_Renderer::build_instance_style()); nested dropdown panels
   inside it use their normal default positioning again, with no special-
   casing for this context. */

.aysen-menu--builder-preview .aysen-menu__list {
	display: flex;
}

.aysen-menu--builder-preview .aysen-menu__panel {
	position: static;
	width: auto;
	max-width: none;
	margin-top: 10px;
	transform: none;
	opacity: 1;
	visibility: visible;
	pointer-events: auto;
}

@media (max-width: 980px) {
	.aysen-menu__toggle {
		align-self: stretch;
		justify-content: flex-start;
	}

	.aysen-menu__list {
		flex-direction: column;
		align-items: stretch;
		gap: 4px;
		padding-top: 8px;
	}

	.aysen-menu__item {
		align-items: stretch;
		justify-content: space-between;
		flex-wrap: wrap;
		width: 100%;
	}

	.aysen-menu__link {
		justify-content: flex-start;
		flex: 1 1 auto;
	}

	.aysen-menu__panel-toggle {
		display: inline-flex;
		margin: 3px 4px 0 0;
	}

	.aysen-menu__panel {
		position: static;
		flex: 0 0 100%;
		width: 100%;
		max-width: none;
		margin: 4px 0 8px;
		padding: 8px 12px 12px;
		box-shadow: none;
		transform: none;
		display: none;
		opacity: 1;
		visibility: visible;
		pointer-events: auto;
		background: rgba(17, 24, 39, 0.04);
	}

	.aysen-menu__item.is-panel-open > .aysen-menu__panel {
		display: block;
	}

	.aysen-menu__panel-inner {
		grid-template-columns: 1fr;
		gap: 6px;
	}
}

.rtl .aysen-menu,
body.rtl .aysen-menu {
	direction: rtl;
	text-align: right;
}

.rtl .aysen-menu__sublink:hover,
body.rtl .aysen-menu__sublink:hover,
.rtl .aysen-menu__sublink:focus-visible,
body.rtl .aysen-menu__sublink:focus-visible {
	transform: translateX(-2px);
}
