/**
 * NL Mobile Tree Menu — structural stylesheet.
 *
 * IMPORTANT: this file deliberately never sets colour, background, font,
 * font-size, line-height, border, border-radius, box-shadow, text-transform,
 * or hover/focus colours. Every rule here exists to make the CSS-only
 * expand/collapse mechanism *work* (display, position, visibility,
 * transform, transition, indentation, hiding the native radio inputs). The
 * host site's own stylesheet is expected to supply all visual styling for
 * .nlmtm-link, .nlmtm-title, .nlmtm-row, etc. — this file will not fight it.
 *
 * How the expand/collapse mechanism works (no JavaScript anywhere):
 *   - Every menu item with children gets a hidden <input type="radio"> of
 *     its own ("open"), plus its sibling group shares one extra hidden
 *     "none" radio (see includes/class-nlmtm-walker.php).
 *   - All of a group's "open" radios and its one "none" radio share a single
 *     `name`, so the browser's native radio semantics guarantee at most one
 *     of them is ever :checked — opening a sibling automatically closes
 *     whichever one was open before, and checking "none" closes it too.
 *   - `:has()` lets us style the <li> itself based on whether its own "open"
 *     radio is checked, without any JS reading/writing classes.
 *   - Two invisible labels are stacked on top of the visible chevron (or, for
 *     items with no real URL, the whole row): one targets the item's own
 *     "open" radio, the other targets the group's "none" radio. Only one is
 *     ever click-through (`pointer-events`) at a time, controlled by the same
 *     :has() check, so clicking the same toggle again while open closes it.
 * ------------------------------------------------------------------------
 */

/* ---------------------------------------------------------------------
 * Reset: remove default browser list styling so the indentation math
 * below is predictable. This is a structural reset, not decorative
 * spacing — no visual/brand styling is implied.
 * ------------------------------------------------------------------- */
.nlmtm-menu,
.nlmtm-submenu {
	list-style: none;
	margin: 0;
	padding: 0;
}

.nlmtm-item {
	position: relative;
}

/* ---------------------------------------------------------------------
 * Indentation: each nesting level sits 10px deeper than its parent.
 * Depth is written inline per submenu-wrap by the walker as `--nlmtm-depth`
 * (see includes/class-nlmtm-walker.php, Walker::start_lvl()), so this
 * works for unlimited depth without hardcoding a fixed number of levels.
 * The custom property is set on .nlmtm-submenu-wrap and inherits down to
 * .nlmtm-submenu (custom properties inherit by default), so indentation is
 * unaffected by the wrap element existing purely for the animation below.
 * ------------------------------------------------------------------- */
.nlmtm-submenu {
	padding-inline-start: calc(var(--nlmtm-depth, 1) * 10px);
}

/* ---------------------------------------------------------------------
 * Submenu expand/collapse animation ("fade and wipe").
 *
 * display:none/block can't be transitioned, and animating to/from an
 * unknown, variable "auto" height normally requires JS — except for the
 * CSS Grid `fr`-unit trick: a grid container whose only track is
 * `grid-template-rows: 0fr` (collapsed) or `1fr` (expanded) *can* have that
 * track size transitioned, because `fr` resolves against the track's
 * content-based size rather than a fixed pixel value. `.nlmtm-submenu-wrap`
 * (the walker-emitted <div> wrapping each <ul class="nlmtm-submenu">) is
 * the grid container; `.nlmtm-submenu` is its single row/grid item, with
 * `overflow: hidden; min-height: 0;` so the row can actually shrink to 0fr
 * instead of the content forcing a minimum. This composes correctly for
 * unlimited nesting: each level's wrap independently tracks its own open
 * state, and a nested wrap's own transition runs inside its ancestor's
 * content box without any fixed max-height guess.
 *
 * Paired with an opacity fade for the "fade" half of "fade and wipe". Both
 * are purely presentational/motion, not colour or branding, so they don't
 * conflict with this file's "structure only" rule — and respect
 * prefers-reduced-motion below.
 * ------------------------------------------------------------------- */
.nlmtm-submenu-wrap {
	display: grid;
	grid-template-rows: 0fr;
	opacity: 0;
	transition: grid-template-rows 0.3s ease, opacity 0.2s ease;
	/*
	 * Read by assets/js/scroll-into-view.js's native scrollIntoView() call
	 * (the browser honours scroll-margin-* automatically) so a site with a
	 * sticky/fixed header can keep the newly opened submenu from landing
	 * underneath it — set --nlmtm-scroll-offset (e.g. to the header's
	 * height in px) on :root or .nlmtm-nav. Defaults to 0 (align flush
	 * with the very top of the viewport).
	 */
	scroll-margin-top: var(--nlmtm-scroll-offset, 0px);
}

.nlmtm-submenu-wrap > .nlmtm-submenu {
	overflow: hidden;
	min-height: 0;
}

.nlmtm-item:has(> .nlmtm-radio-open:checked) > .nlmtm-submenu-wrap {
	grid-template-rows: 1fr;
	opacity: 1;
	transition: grid-template-rows 0.3s ease, opacity 0.25s ease 0.05s;
}

@media (prefers-reduced-motion: reduce) {
	.nlmtm-submenu-wrap {
		transition: none;
	}
}

/* ---------------------------------------------------------------------
 * Row layout: positions the link/title against the toggle chevron.
 * Flex here is structural (it is what makes the chevron sit at the end
 * of the row); it carries no colour, font, or spacing opinions.
 * ------------------------------------------------------------------- */
.nlmtm-row {
	display: flex;
	align-items: center;
	justify-content: space-between;
}

.nlmtm-link,
.nlmtm-static {
	display: inline-flex;
	align-items: center;
	flex: 1 1 auto;
	min-width: 0;
}

/* ---------------------------------------------------------------------
 * Toggle hit areas.
 *
 * .nlmtm-toggle-wrap wraps just the chevron (items with a real URL — the
 * title stays a separate, normal <a>). .nlmtm-row-toggle wraps the whole
 * title + chevron (items with no real URL, per the spec's "entire title is
 * the expand control" rule). Both are position:relative boxes sized by
 * their normal-flow visible content (title/chevron); the two hit labels are
 * stretched to cover that exact box via position:absolute + inset, and are
 * otherwise invisible (screen-reader-text only) so they never duplicate the
 * visible title/chevron on screen.
 * ------------------------------------------------------------------- */
.nlmtm-toggle-wrap,
.nlmtm-row-toggle {
	position: relative;
	display: inline-flex;
	align-items: center;
	flex: 0 0 auto;
}

.nlmtm-row-toggle {
	flex: 1 1 auto;
	justify-content: space-between;
	min-width: 0;
}

/*
 * Minimum touch-target size for the chevron-only toggle (real-URL items,
 * where the chevron is a separate control from the title link).
 *
 * The visible chevron SVG is only 1em square — at typical nav font sizes
 * that is far below the ~44px minimum interactive target size recommended
 * by WCAG 2.5.5 and both major mobile platform guidelines. Without this,
 * the invisible hit-labels (sized to match the chevron via inset:0 below)
 * are so small that touch taps land on the adjacent title link instead of
 * the chevron — a functional bug, not a visual/branding one, so widening
 * this box does not conflict with the "structure only" rule above.
 *
 * Growing .nlmtm-toggle-wrap's own flex-basis (rather than letting the
 * invisible label bleed past its box into the link's territory) is what
 * keeps this safe: the row is display:flex/justify-content:space-between
 * with .nlmtm-link set to flex:1 1 auto, so enlarging the toggle box simply
 * reserves more of the row for itself — it can never overlap the link.
 */
.nlmtm-toggle-wrap {
	justify-content: center;
	min-width: 44px;
	min-height: 44px;
}

/*
 * touch-action: manipulation removes the browser's default double-tap-to-zoom
 * gesture delay/disambiguation on this element. On Chromium-based mobile
 * browsers (e.g. Android Edge/Chrome), a small tappable target without this
 * can have taps swallowed by that gesture-detection window entirely rather
 * than just mis-landing on a neighbour — which matches "chevron does nothing
 * at all" reports on mobile Edge that don't reproduce on mobile Safari
 * (WebKit's touch handling is more forgiving of small/ambiguous targets).
 * This is a functional/interaction property, not a visual one, so it holds
 * to the same "structure only" rule as the rest of this file.
 */
.nlmtm-toggle-label {
	position: absolute;
	inset: 0;
	cursor: pointer;
	touch-action: manipulation;
	-webkit-touch-callout: none;
}

/* Only one of the two stacked labels is ever click-through at a time. */
.nlmtm-expand-hit {
	pointer-events: auto;
}

.nlmtm-collapse-hit {
	pointer-events: none;
}

.nlmtm-item:has(> .nlmtm-radio-open:checked) > .nlmtm-row .nlmtm-expand-hit {
	pointer-events: none;
}

.nlmtm-item:has(> .nlmtm-radio-open:checked) > .nlmtm-row .nlmtm-collapse-hit {
	pointer-events: auto;
}

/* ---------------------------------------------------------------------
 * Chevron: Feather "chevron-up", sized in `em` and coloured via
 * currentColor so it inherits the surrounding text's size/colour instead
 * of the plugin imposing its own. Closed = pointing up (0deg). Open =
 * rotated 180deg (pointing down). Exactly one chevron element exists per
 * item (never duplicated across the two hit labels), so this transition is
 * a genuine single-element rotation, not a swap between two static icons.
 * ------------------------------------------------------------------- */
.nlmtm-chevron-visual {
	display: inline-flex;
	pointer-events: none;
}

.nlmtm-chevron {
	display: block;
	flex-shrink: 0;
	height: auto;
	aspect-ratio: 1 / 1;
	/*
	 * max-width/max-height cap the icon at a sane size regardless of what
	 * an external stylesheet sets `width` to. There's a pre-existing,
	 * unrelated Bricks Builder custom-CSS rule on the live header element
	 * (`#brxe-pxpnmw svg.nlmtm-chevron { width: 3em; }` — see 1.2.0's
	 * changelog entry) that used to render as a squashed 3em x 1em icon
	 * before the aspect-ratio fix above; fixing the distortion without a
	 * cap meant it became a genuinely huge 3em x 3em icon instead, which
	 * is worse. `max-width`/`max-height` are resolved independently of
	 * `width`/`height` in the CSS box model (the used size is always
	 * `min(width, max-width)`), so this wins regardless of the other
	 * rule's higher (ID-based) specificity — no !important needed, and it
	 * doesn't fight legitimate host resizing via font-size, only an
	 * absolute-unit/oversized `width` override specifically.
	 */
	max-width: 1.25em;
	max-height: 1.25em;
	transform: rotate(0deg);
	transition: transform 0.25s ease;
}

/* ---------------------------------------------------------------------
 * Hide the radio inputs visually without removing them from the
 * accessibility tree or the keyboard tab order — a "visually hidden"
 * clip technique, not display:none/visibility:hidden. Keyboard and
 * screen reader users can still reach and operate every toggle directly.
 * ------------------------------------------------------------------- */
.nlmtm-radio,
.screen-reader-text {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0;
}

/* ---------------------------------------------------------------------
 * The mechanism: rotate the chevron while this item's own "open" radio is
 * checked (submenu reveal is handled by the .nlmtm-submenu-wrap rules
 * above). Because the radio shares a `name` with its siblings and its
 * group's "none" radio, checking any of those un-checks this one
 * automatically — opening a sibling, or clicking this item's own "close"
 * hit area, both close it the same way.
 * ------------------------------------------------------------------- */
.nlmtm-item:has(> .nlmtm-radio-open:checked) > .nlmtm-row .nlmtm-chevron {
	transform: rotate(180deg);
}
