/*
 * GENERATED FILE - DO NOT EDIT.
 *
 * Built by tools/build-css.py from:
 *     gtmmenu.mobile.css   the mobile baseline
 *     gtmmenu.desktop.css  the desktop layer, expanded once per breakpoint
 *
 * Edit those, then run `./build.sh` (or `python3 tools/build-css.py`). Editing
 * this file works exactly until the next build overwrites it.
 */


/**
 * GTM Menu - mod_gtmmenu
 *
 * Mobile-first. Everything below is the small-screen baseline; the desktop
 * layer is added on top from the breakpoint configured per module instance.
 *
 * @copyright  (C) 2026 Gestimark
 * @license    GNU General Public License version 2 or later
 */

/* ==========================================================================
   Design tokens
   Override any of these from your template to restyle the whole menu.
   ========================================================================== */

.gtm-menu {
	--gtm-font-family: inherit;
	--gtm-font-size: 16px;

	/*
	 * A multiplier on that size, for patterns that want larger type without
	 * taking the setting away from whoever chose it.
	 *
	 * The overlay used to declare `--gtm-font-size: 1.25rem` on the panel body,
	 * which is a flat override: a reader who asked for 18px got 20px, and the
	 * field quietly meant nothing in that pattern. A factor composes instead -
	 * 18px still reads as 18, just 1.25 times bigger where the sheet is
	 * full-screen.
	 */
	--gtm-font-scale: 1;

	--gtm-font-weight: 500;

	--gtm-color: #16181d;
	--gtm-color-muted: #6b7280;
	--gtm-color-accent: #1d4ed8;

	/* Spelled out rather than shortened: the Dispatcher compares each setting
	   against the value declared here to decide whether a file is needed, and
	   a comparison is easier to trust when both sides read the same. */
	--gtm-panel-bg: #ffffff;
	--gtm-panel-width: min(87vw, 21.5rem);
	--gtm-panel-shadow: 0 0 2.5rem rgba(0, 0, 0, 0.18);
	--gtm-panel-pad-x: 1.25rem;
	--gtm-panel-pad-y: 0.5rem;

	--gtm-link-color: var(--gtm-color);
	/*
	 * Both states start as no-ops: the same colour the entry already has, and no
	 * background at all.
	 *
	 * They used to default to the accent blue and to a faint dark wash, which was
	 * a reasonable house style right up until the Hover and Current Page tabs
	 * existed. Once every transformation has a switch, a switch that is off has
	 * to mean nothing happens - and it did not: with the whole of both tabs
	 * turned off, entries still went blue and still darkened under the pointer.
	 * Reported as a bug, and it was one: the form was promising something the
	 * stylesheet contradicted.
	 *
	 * The consequence is deliberate. A module nobody has configured now gives no
	 * hover feedback at all, where before it gave a little. That is the honest
	 * reading of "off", and the two tabs are three clicks away.
	 */
	--gtm-link-color-hover: var(--gtm-link-color);
	--gtm-link-color-current: var(--gtm-link-color);
	--gtm-link-bg-hover: transparent;

	/*
	 * What an entry becomes under the pointer, and what the entry for the page
	 * you are on becomes permanently. Two states, the same four properties.
	 *
	 * Every default here is a no-op, and that is the whole design: the weights
	 * repeat the resting weight, the decorations repeat the `none` the base link
	 * already sets, and both backgrounds are transparent. So the pair of rules
	 * further down can declare all four unconditionally - no `:not()`, no second
	 * selector for "when nothing is configured" - and a module with both tabs
	 * switched off renders as though neither existed.
	 *
	 * The four colour and background tokens above follow the same rule, for the
	 * same reason. See the note on them.
	 */
	--gtm-link-weight-hover: var(--gtm-font-weight);
	--gtm-link-decoration-hover: none;
	--gtm-link-weight-current: var(--gtm-font-weight);
	--gtm-link-decoration-current: none;
	--gtm-link-bg-current: transparent;

	--gtm-link-pad-y: 12px;

	/* The floor under every menu row. Aliased to the tap size rather than
	   written as 44px, so raising one raises the other by default - but it is a
	   token of its own, because shrinking a row must not shrink the hamburger
	   with it. The Dispatcher compares its setting against 44. */
	--gtm-row-min-height: var(--gtm-tap-size);

	--gtm-heading-color: var(--gtm-color-muted);

	--gtm-border-color: rgba(0,0,0,0.08);
	--gtm-indent: 1rem;

	/* Between a label and its sub-menu icon. Its own token rather than a share of
	   the link's `gap`, which also spaces an item's image from its text: two
	   different distances that happen to sit on the same axis. */
	--gtm-icon-gap: 0.5rem;
	--gtm-radius: 0.375rem;
	--gtm-tap-size: 2.75rem;

	--gtm-backdrop-bg: rgba(15, 18, 25, 0.55);
	--gtm-duration: 260ms;
	--gtm-easing: cubic-bezier(0.4, 0, 0.2, 1);
	--gtm-z: 1040;

	--gtm-focus-color: var(--gtm-color-accent);
	--gtm-focus-width: 2px;
	--gtm-focus-offset: 2px;

	/*
	 * The pitch - one bar plus one gap - is 8px, and that number is the whole
	 * point. Bars are placed one pitch apart, so the pitch decides the subpixel
	 * phase each of them lands on once the device pixel ratio scales it. At the
	 * old 7px pitch and a ratio of 1.25 the three bars fell on phases 0, 3/4 and
	 * 1/2: each got antialiased differently and the icon read as three unequal
	 * lines. 8px stays whole at 1.25, 1.5 and 2, so every bar shares one phase
	 * and rasterises identically.
	 *
	 * Pixels rather than rem for the same reason: a template that sets an odd
	 * root font size would otherwise reintroduce fractional gaps. The width is
	 * free to scale, only the vertical rhythm has to stay on the grid.
	 */
	/* Transparent by default, so the button is only its icon until someone
	   asks for a badge. Spelled the way the Dispatcher spells it. */
	--gtm-toggle-bg: rgba(0,0,0,0);
	--gtm-toggle-color: var(--gtm-color);

	--gtm-burger-width: 1.375rem;
	--gtm-burger-bar: 2px;
	--gtm-burger-gap: 6px;
	--gtm-burger-height: calc(3 * var(--gtm-burger-bar) + 2 * var(--gtm-burger-gap));

	/* The bar is deliberately flush and transparent: it is meant to float over
	   the page, so anything it paints would be a band across the design.
	   Spelled the way the Dispatcher spells it, or a setting left alone stops
	   comparing equal and every install writes a file for nothing. */
	--gtm-bar-gap: 0.5rem;
	--gtm-bar-pad-x: 0rem;
	--gtm-bar-bg: rgba(0,0,0,0);

	/*
	 * `--gtm-bar-height` is deliberately NOT declared here, and that is load
	 * bearing. Every use of it reads `var(--gtm-bar-height, <fallback>)`, so an
	 * undeclared token is what "no height was chosen" means: the bar sizes
	 * itself to its content, exactly as it did before the setting existed.
	 * Declaring it here - even as `auto` - would silence all three fallbacks at
	 * once, and the reservation below would quietly stop reserving.
	 */

	/*
	 * One token holding the whole shorthand, rather than four holding a corner
	 * each. There were four to begin with, and they went: `border-radius` takes
	 * a second set of radii after a slash - horizontal radii before it, vertical
	 * after - which turns each corner into an ellipse rather than a quarter
	 * circle. Four numbers cannot say that, so the setting is a free-text field
	 * taking the notation whole, pasted out of a rounding generator. Once that
	 * field exists it also covers `24px` and `0 0 24px 24px`, and the per-corner
	 * fields were only a longer way of typing the same thing.
	 */
	--gtm-bar-radius: 0;

	--gtm-brand-height: 40px;

	/*
	 * The logo's badge. Its shape is a radius rather than a class, unlike the
	 * hamburger's: a class cannot change at a breakpoint, and these two have to.
	 * The generated stylesheet writes them inside a media query instead.
	 *
	 * It held one of three preset shapes until 0.1.22 and now takes a whole
	 * `border-radius` notation, the same as the bar. Note what the presets used
	 * to hide: the fully rounded one was a large pixel radius, never `50%`,
	 * because 50% on a box wider than it is tall draws an ellipse. The field's
	 * description carries that warning now, since nothing else can.
	 */
	--gtm-brand-bg: rgba(0,0,0,0);
	--gtm-brand-radius: 0;

	/*
	 * The badge's shadow, in two tokens the declaration puts back together:
	 * `box-shadow: var(--gtm-brand-shadow-offset) var(--gtm-brand-shadow-color)`.
	 *
	 * Two rather than one because a `box-shadow` is a length shorthand with a
	 * colour on the end, and those are the two things this module already knows
	 * how to carry - a free-text shorthand and a colour picker. Holding the whole
	 * notation in one field meant a colour typed by hand, which meant an allowlist
	 * chasing CSS's colour syntaxes; it was tried in 0.1.36 and the very first
	 * value typed into it, `rgb(0 0 0 / 20%)`, was refused. Composed here, the
	 * colour never passes through a pattern at all.
	 *
	 * The defaults are what make an unset shadow cost nothing: no offset, no blur
	 * and a fully transparent colour paint precisely nothing. So there is no `none`
	 * to special-case, and cancelling a desktop shadow is just a colour at zero
	 * opacity - the idiom the bar's background already uses.
	 *
	 * What the pair cannot express is a stack of comma-separated layers, or
	 * `inset`. Neither has ever been asked of a logo badge.
	 */
	--gtm-brand-shadow-offset: 0 0 0;
	--gtm-brand-shadow-color: rgba(0,0,0,0);

	/*
	 * Nudges the logo, badge and all, from wherever the layout put it.
	 *
	 * An inset on a relatively positioned box, not a margin, and that is the whole
	 * point: it displaces what is painted without touching what was laid out. The
	 * auto block margin below therefore keeps doing its job - centring the logo
	 * while it fits, letting it hang off the bottom once it does not - and the bar's
	 * height, and the reservation that follows it, stay exactly what they were.
	 *
	 * `auto` on a side means "no offset there", which is why the default is simply
	 * `auto`. Note what CSS does with a fully specified shorthand: top and bottom
	 * cannot both apply, so top wins, and left beats right the same way. Moving the
	 * logo up or towards the start therefore means leaving `auto` on the opposite
	 * side - `auto 0 8px 24px` lifts it 8px and pushes it 24px in.
	 */
	--gtm-brand-inset: auto;

	/* Spacing around the hamburger, independent of the bar and of the logo.
	   Zero here; anything else arrives from the generated per-instance sheet.
	   Measured to the bars you can see, not to the tap target around them -
	   see the toggle section for why the two differ per axis. */
	--gtm-toggle-margin-top: 0px;
	--gtm-toggle-margin-bottom: 0px;
	--gtm-toggle-margin-side: 0px;

	--gtm-image-max-height: 2rem;
}

/* ==========================================================================
   Root
   ========================================================================== */

.gtm-menu {
	position: relative;
	font-family: var(--gtm-font-family);
	font-size: var(--gtm-font-size);
	color: var(--gtm-color);
}

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

/*
 * The frame generates no box below the breakpoint, so the bar, the backdrop and
 * the panel stay direct children of the nav and every rule in this file goes on
 * meaning what it says. It becomes a real box only in the desktop layer, where
 * something other than the nav has to be the thing that gets fixed - see the
 * comment on it in the layout.
 */
.gtm-menu__frame {
	display: contents;
}

.gtm-menu :focus-visible {
	outline: var(--gtm-focus-width) solid var(--gtm-focus-color);
	outline-offset: var(--gtm-focus-offset);
}

/* Screen-reader-only text. Self-contained so the module never depends on the
   template shipping a .visually-hidden utility. */
.gtm-menu__sr {
	position: absolute !important;
	width: 1px !important;
	height: 1px !important;
	padding: 0 !important;
	margin: -1px !important;
	overflow: hidden !important;
	clip: rect(0, 0, 0, 0) !important;
	white-space: nowrap !important;
	border: 0 !important;
}

/* Scroll lock, applied to <html> *and* <body> while a floating panel is open -
   whichever of the two the host template made its scroll container. See
   lockScroll() in the script for what locking only <html> left behind. */
.gtm-menu-scroll-lock {
	overflow: hidden !important;
}

/*
 * Worn for a single frame while the layout crosses the breakpoint.
 *
 * The two layers park the panel in different places: above the breakpoint at
 * `transform: none` with transitions off, below it off-screen with transitions
 * on. Crossing therefore changes a transitionable property at the very moment
 * its transition becomes live, and the browser does what it is told - it
 * animates. Measured resizing 1400 to 390: the panel slid 375px over 39 frames,
 * a closing animation nobody asked for.
 *
 * Only someone dragging a window edge, or rotating a tablet across the
 * boundary, ever sees it. That is still a flash of something that did not
 * happen, and the cure is one class for one frame.
 */
.gtm-menu--switching,
.gtm-menu--switching *,
.gtm-menu--switching *::before,
.gtm-menu--switching *::after {
	transition: none !important;
}

/* ==========================================================================
   Bar - the always-visible strip: brand on one side, hamburger on the other
   ========================================================================== */

/*
 * The bar carries a z-index of its own, and that is not cosmetic.
 *
 * .gtm-menu is positioned but has no z-index, so it paints in the positioned
 * layer where nothing but document order decides who wins. Any positioned
 * element further down the page - a slider, a hero, a template header pulled up
 * by a negative margin - therefore paints straight over the hamburger. Giving
 * the bar a stacking level of its own is the only thing that keeps it reachable
 * whatever the host template stacks around it.
 *
 * The level stops short of the panel's so an open panel still covers the bar,
 * which is what the close button in the panel head assumes.
 */
.gtm-menu__bar {
	position: relative;
	z-index: calc(var(--gtm-z) + 2);
	display: flex;
	align-items: center;
	gap: var(--gtm-bar-gap);
	height: var(--gtm-bar-height, auto);
	min-height: var(--gtm-tap-size);
	padding-inline: var(--gtm-bar-pad-x);

	/*
	 * The box itself catches nothing. Its two children take their clicks back
	 * below, so whatever the box does or does not paint - a band thinner than
	 * itself, or a logo overhanging it - it can never sit invisibly over the
	 * page stealing a click meant for a slider control underneath.
	 */
	pointer-events: none;
}

.gtm-menu__brand,
.gtm-menu__toggle {
	pointer-events: auto;
}

/*
 * The painted band, and the reason it is a pseudo-element rather than the bar's
 * own background.
 *
 * A configurable bar height has to leave the logo's height alone - that is the
 * entire point of the setting - so a logo taller than the band has to overhang
 * it. Put the height on the bar itself and that overhang is centred, half of it
 * above the bar; with the bar fixed to the top of the viewport that half is off
 * screen, and the logo reads as cropped. Sizing the box to its content and
 * painting the band inside it puts the whole overhang below, where it shows.
 *
 * It also frees the band from the 44px tap target: the box keeps that floor for
 * the button's sake while the band is free to be thinner than it.
 *
 * `inset-block: 0` together with a height is the over-constrained case, and it
 * resolves in the band's favour - the bottom inset is the one dropped - so
 * `auto` stretches to the full box and a length pins the band to the top.
 *
 * The negative z-index puts the band behind the bar's content but inside the
 * bar's own stacking context, so it cannot fall behind the page. And there is
 * no `overflow: hidden` anywhere near it on purpose: it would clip the very
 * overhang this arrangement exists to keep. The cost is that a logo badge at
 * the very edge can spill past a rounded corner.
 */
.gtm-menu__bar::before {
	content: '';
	position: absolute;
	inset-block: 0;
	inset-inline: 0;
	z-index: -1;
	height: var(--gtm-bar-height, auto);
	background-color: var(--gtm-bar-bg);
	border-radius: var(--gtm-bar-radius);
	pointer-events: none;
}

/*
 * Fixed rather than sticky, and that is a deliberate limitation.
 *
 * position: sticky only sticks inside the scroll box of its own ancestor, and
 * the bar's ancestor here is a module position barely taller than the bar
 * itself - so sticky would have nowhere to travel and would never come unstuck.
 * Fixed lifts the bar out of flow entirely, which is also what "floating over a
 * transparent background" asks for: the page slides underneath it.
 *
 * The trade-off is that the bar no longer reserves its own height, so the
 * content behind it starts at the top of the viewport.
 */
.gtm-menu--fixed .gtm-menu__bar {
	position: fixed;
	inset-block-start: 0;
	inset-inline: 0;
}

/*
 * Giving the module position back the height the fixed bar took out of the flow.
 *
 * A fixed bar reserves nothing, so the module below starts at the top of the
 * viewport and the bar covers it. Invisible while the bar is transparent, which
 * is why it went unnoticed for so long; obvious the moment the band is painted.
 *
 * Opt-in rather than automatic, because floating over the page is what the fixed
 * bar is for - a translucent header over a hero is a real design, and reserving
 * would put a blank strip above it.
 *
 * The value has to equal the bar's own height or the reservation is itself a
 * misalignment - and the first attempt got that wrong in a way worth recording.
 * It took the tallest of the height setting, the logo and the hamburger, because
 * back then the box grew with the logo. So a logo overhanging a 90px bar pushed
 * the next module down by the logo's full height, leaving a band of empty page
 * between the bar and the content. The logo's height was deciding the layout,
 * which is exactly what it must never do.
 *
 * Now that the box is pinned, the answer is simply the height that was set. The
 * fallback covers the other case: with no height chosen the bar is content-sized,
 * so the reservation restates that content - the logo, or the tap target plus
 * whatever the hamburger's spacing adds, whichever is taller.
 *
 * A logo taller than the bar therefore hangs over the content below, on purpose.
 * That is what a big round logo on a slim bar is for, and the bar catches no
 * clicks outside its children, so nothing underneath becomes unreachable.
 */
.gtm-menu--reserve {
	min-height: var(--gtm-bar-band);
}


/* ==========================================================================
   Brand
   ========================================================================== */

/*
 * The badge hugs the image: no padding, so an untouched module looks exactly as
 * it did before the background existed. A logo is rarely square, so the fully
 * rounded option is a pill radius rather than 50% - 50% on a wide box gives an
 * ellipse, which reads as a mistake. On a square-ish logo the pill is a circle.
 */
/*
 * `margin-block: auto` rather than the bar's `align-items: center`, and this one
 * line is what keeps the logo's height out of the bar's height.
 *
 * Auto margins in flexbox only ever absorb *positive* free space: when the logo
 * is shorter than the bar they split the slack and centre it, and when it is
 * taller they resolve to zero instead of going negative. So the logo centres
 * while it fits and hangs off the bottom once it does not - never off the top,
 * which with a bar fixed to the top of the viewport would mean off screen.
 *
 * `align-items: center` cannot do that: it centres either way, so a logo taller
 * than the bar loses half its overhang above the viewport. Cross-axis auto
 * margins take precedence over align-self, which is why nothing else changes.
 *
 * Being able to pin the bar's own height is what this buys, and with it the
 * reservation that follows the band rather than the logo. Nothing a user can set
 * takes it away: the position setting is an inset, which moves the paint and leaves
 * the layout - and this margin - alone.
 */
.gtm-menu__brand {
	display: inline-flex;
	flex: 0 0 auto;
	align-items: center;
	margin-block: auto;

	/* Positioned only so the inset has something to offset from. With the default
	   `auto` it changes nothing, and it never affects the layout - which is why the
	   auto margin above survives it. */
	position: relative;
	inset: var(--gtm-brand-inset);
	transition: opacity var(--gtm-duration) var(--gtm-easing);
	color: inherit;
	text-decoration: none;
	background-color: var(--gtm-brand-bg);
	border-radius: var(--gtm-brand-radius);

	/* Nothing clips this: the bar deliberately carries no `overflow: hidden`, for
	   the logo's overhang, and the shadow rides along on that. It paints above the
	   bar's band, both being inside the bar's own stacking context with the band
	   held behind at z-index -1. */
	box-shadow: var(--gtm-brand-shadow-offset) var(--gtm-brand-shadow-color);
}

/*
 * The height token holds the default only. Any other value arrives from the
 * generated per-instance stylesheet, as `#gtm-menu-<id> { --gtm-brand-height }`
 * - specificity (1,0,0) against this file's (0,1,0), so it wins regardless of
 * load order. Keep the default expressed in px: the Dispatcher compares the
 * setting against 40 to decide whether a file is needed at all.
 */

/*
 * Two classes rather than one, on purpose. Templates routinely ship
 * `.some-position img { width: 100% }`, which is (0,1,1) and would stretch the
 * logo to the full width of the bar. Scoping by the menu root as well takes the
 * selector to (0,2,0) and settles the cascade without !important.
 */
.gtm-menu .gtm-menu__brand-image {
	display: block;
	width: auto;
	max-width: 100%;
	height: var(--gtm-brand-height);
	object-fit: contain;
}

/* ==========================================================================
   Hamburger toggle
   ========================================================================== */

/*
 * The spacing settings are measured to the bars, not to the button.
 *
 * The tap target is a 44px square, because touch targets have to be; the icon
 * inside it is 22 wide and 18 tall. Centring that in the square leaves 11px of
 * slack horizontally and 13px vertically. A margin applied to the button
 * therefore lands 11px from the edge on one axis and 13px on the other, and
 * "20px all round" comes out visibly uneven - which is exactly what it looks
 * like, since the tap target is invisible and the bars are not.
 *
 * So each axis gives back its own slack. Both insets are derived from the size
 * tokens rather than written down, so retuning the icon cannot silently put the
 * spacing out again.
 *
 * The `max()` floor keeps the button from taking a negative margin, which would
 * push the tap target out of the bar - off the top of the viewport once the bar
 * is fixed. The cost is that a setting below the slack does nothing: the icon
 * cannot sit closer to the edge than its own tap target allows.
 */
.gtm-menu {
	--gtm-toggle-inset-x: calc((var(--gtm-tap-size) - var(--gtm-burger-width)) / 2);
	--gtm-toggle-inset-y: calc((var(--gtm-tap-size) - var(--gtm-burger-height)) / 2);

	--gtm-toggle-offset-top: max(0px, calc(var(--gtm-toggle-margin-top) - var(--gtm-toggle-inset-y)));
	--gtm-toggle-offset-bottom: max(0px, calc(var(--gtm-toggle-margin-bottom) - var(--gtm-toggle-inset-y)));
	--gtm-toggle-offset-side: max(0px, calc(var(--gtm-toggle-margin-side) - var(--gtm-toggle-inset-x)));

	/*
	 * The spacing actually in force, whichever reference is in play. The three
	 * offsets above measure to the bars; a visible badge switches the reference
	 * to the button's own edge, and `--toggle-boxed` re-points these at the raw
	 * settings. Everything downstream reads these and stops caring which case it
	 * is in - the margins, the height the button contributes, and the insets of a
	 * fixed button all followed from one choice made in one place.
	 */
	--gtm-toggle-pad-top: var(--gtm-toggle-offset-top);
	--gtm-toggle-pad-bottom: var(--gtm-toggle-offset-bottom);
	--gtm-toggle-pad-side: var(--gtm-toggle-offset-side);

	/* What the button occupies once its spacing is counted - the height it
	   contributes to a content-sized bar. Named because two other things restate
	   it, and a repeated calc() is a calc() that drifts. */
	--gtm-toggle-outer: calc(
		var(--gtm-tap-size) + var(--gtm-toggle-pad-top) + var(--gtm-toggle-pad-bottom)
	);

	/*
	 * The height of the painted band, as an expression rather than a measurement.
	 * The reservation needs it, and so does a fixed button that has to keep the
	 * place it held inside the bar. Undeclared `--gtm-bar-height` means no height
	 * was chosen, so the bar is content-sized and the band is that content.
	 */
	--gtm-bar-band: var(--gtm-bar-height, var(--gtm-toggle-outer));

	/* And the box around it, which keeps the tap target's floor even when the
	   band is thinner than the button. */
	--gtm-bar-box: max(var(--gtm-tap-size), var(--gtm-bar-band));
}

/* The logo only counts when there is one: the setting can be on and still be
   ignored, when the first menu item carries no image or has children. */
.gtm-menu--has-brand {
	--gtm-bar-band: var(--gtm-bar-height, max(var(--gtm-brand-height), var(--gtm-toggle-outer)));
}

/*
 * Auto margins rather than justify-content, so the same two rules serve with or
 * without a brand. With no brand they centre or push the lone button; with one,
 * the brand keeps the start and the free space all collects on the toggle's
 * leading edge.
 *
 * The outer margin is applied to whichever side the button is aligned to, which
 * is the only side that means anything: the other one carries the `auto` that
 * does the aligning, and overriding it would undo the alignment. Centred, both
 * are auto and neither is offered.
 */
.gtm-menu--toggle-center .gtm-menu__toggle {
	margin-inline: auto;
}

.gtm-menu--toggle-end .gtm-menu__toggle {
	margin-inline-start: auto;
	margin-inline-end: var(--gtm-toggle-pad-side);
}

.gtm-menu--toggle-start .gtm-menu__toggle {
	margin-inline-start: var(--gtm-toggle-pad-side);
}

/*
 * Vertical placement inside a bar the logo may have made much taller than the
 * button. Centred by default, which is why a bigger logo appears to push the
 * burger down - it does not move, the bar grows around it.
 *
 * Pair the alignment with the margins: aligned to the top with a top margin,
 * the button sits exactly that far from the top edge. Left centred, flexbox
 * centres the whole margin box instead, so the same margin only shifts it half
 * as far - correct per spec, and rarely what anyone means.
 */
.gtm-menu--burger-top .gtm-menu__toggle {
	align-self: flex-start;
}

.gtm-menu--burger-bottom .gtm-menu__toggle {
	align-self: flex-end;
}

.gtm-menu__toggle {
	display: flex;
	flex: 0 0 auto;
	align-items: center;
	justify-content: center;
	width: var(--gtm-tap-size);
	height: var(--gtm-tap-size);
	margin-block: var(--gtm-toggle-pad-top) var(--gtm-toggle-pad-bottom);
	padding: 0;
	color: var(--gtm-toggle-color);
	background-color: var(--gtm-toggle-bg);
	border: 0;
	border-radius: var(--gtm-radius);
	cursor: pointer;
	-webkit-tap-highlight-color: transparent;
}

/* Shape of that background. The bars themselves draw with currentColor, which
   is why setting `color` above is all it takes to recolour them. */
.gtm-menu--toggle-shape-square .gtm-menu__toggle {
	border-radius: 0;
}

.gtm-menu--toggle-shape-round .gtm-menu__toggle {
	border-radius: 50%;
}

/*
 * Once the button has a background it becomes the visible object, so the
 * spacing settings go back to measuring it rather than the bars inside it.
 *
 * The compensation above exists because a 44px tap target around a 22x18 icon
 * is invisible: measuring to the box would have left uneven margins nobody
 * could account for. Paint that box and the reasoning inverts - the edge you
 * see is the edge you are positioning. Same principle either way: measure to
 * whatever is visible.
 */
.gtm-menu--toggle-boxed {
	--gtm-toggle-pad-top: var(--gtm-toggle-margin-top);
	--gtm-toggle-pad-bottom: var(--gtm-toggle-margin-bottom);
	--gtm-toggle-pad-side: var(--gtm-toggle-margin-side);
}

/* ==========================================================================
   Fixed hamburger, scrolling bar
   ==========================================================================

   The third state of "what stays at the top": not the whole bar, only the
   button. The bar keeps its place in the flow, so the band and the logo scroll
   away with the page and the bar reserves its own height by existing - which is
   why the reservation setting has nothing to offer here and is not shown.

   Leaving the flex flow means the auto margins that placed the button stop
   meaning anything, so the placement is restated as insets. It is restated from
   the same tokens, deliberately: the button has to sit exactly where it sat
   inside the bar, or it would jump the moment the page is scrolled - and, worse,
   sit visibly wrong before anyone scrolls at all.

   This block sits after the placement rules above on purpose. `margin: 0` below
   has the same specificity as the auto margins that placed the button, so only
   source order settles it - measured first at 18px from the edge instead of 9,
   the inset and a surviving margin quietly adding up.
   ========================================================================== */

.gtm-menu--fixed-toggle .gtm-menu__toggle {
	position: fixed;
	z-index: var(--gtm-z);
	margin: 0;
}

/* Vertically: where the button sat in the bar. `max()` floors each at the top of
   the viewport, since a band thinner than the button would otherwise compute a
   negative inset and push it off screen. */
.gtm-menu--fixed-toggle.gtm-menu--burger-top .gtm-menu__toggle {
	inset-block-start: var(--gtm-toggle-pad-top);
}

/*
 * Centred is the one that is not simply (box - button) / 2. In the flex bar it is
 * the button's *margin box* that gets centred, so an asymmetric spacing shifts it
 * off the middle by half the difference - `align-self` centring the margin box is
 * correct per spec, and it is what the eye has already been shown. Restating that
 * exactly is the whole point: half the leftover, then the top spacing on top.
 */
.gtm-menu--fixed-toggle.gtm-menu--burger-middle .gtm-menu__toggle {
	inset-block-start: max(0px, calc(
		(var(--gtm-bar-box) - var(--gtm-tap-size)
			+ var(--gtm-toggle-pad-top) - var(--gtm-toggle-pad-bottom)) / 2
	));
}

.gtm-menu--fixed-toggle.gtm-menu--burger-bottom .gtm-menu__toggle {
	inset-block-start: max(
		0px,
		calc(var(--gtm-bar-box) - var(--gtm-tap-size) - var(--gtm-toggle-pad-bottom))
	);
}

/* Horizontally: the side it was aligned to, with the spacing already resolved
   against whichever reference is in force. Centred needs both insets so the auto
   margins have a width to divide. */
.gtm-menu--fixed-toggle.gtm-menu--toggle-end .gtm-menu__toggle {
	inset-inline-end: var(--gtm-toggle-pad-side);
}

.gtm-menu--fixed-toggle.gtm-menu--toggle-start .gtm-menu__toggle {
	inset-inline-start: var(--gtm-toggle-pad-side);
}

.gtm-menu--fixed-toggle.gtm-menu--toggle-center .gtm-menu__toggle {
	inset-inline: 0;
	margin-inline: auto;
}

/* Flex rather than three absolutely positioned bars: absolute bars all collapse
   onto each other into a single thick line the moment a host template flattens
   the height of their container. Flex degrades gracefully instead. */
.gtm-menu__burger {
	display: flex;
	flex: 0 0 auto;
	flex-direction: column;
	justify-content: space-between;
	gap: var(--gtm-burger-gap);
	width: var(--gtm-burger-width);
	height: var(--gtm-burger-height);
}

.gtm-menu__burger-bar {
	display: block;
	flex: 0 0 auto;
	width: 100%;
	height: var(--gtm-burger-bar);
	background-color: currentColor;
	border-radius: var(--gtm-burger-bar);
	transition:
		transform var(--gtm-duration) var(--gtm-easing),
		opacity calc(var(--gtm-duration) / 2) var(--gtm-easing);
}

/*
 * Morph into a cross while the panel is open. The outer bars travel to the
 * middle, which sits exactly half the free space away from each of them.
 */
.gtm-menu.is-open .gtm-menu__burger-bar:nth-child(1) {
	transform: translateY(calc((var(--gtm-burger-height) - var(--gtm-burger-bar)) / 2)) rotate(45deg);
}

.gtm-menu.is-open .gtm-menu__burger-bar:nth-child(2) {
	opacity: 0;
}

.gtm-menu.is-open .gtm-menu__burger-bar:nth-child(3) {
	transform: translateY(calc((var(--gtm-burger-height) - var(--gtm-burger-bar)) / -2)) rotate(-45deg);
}

/* The inline pattern keeps the panel in flow, so the toggle must not morph
   away from the user while the list pushes the page down. */
.gtm-menu--inline.is-open .gtm-menu__burger-bar:nth-child(2) {
	opacity: 1;
}

/* ==========================================================================
   Backdrop
   ========================================================================== */

.gtm-menu__backdrop {
	position: fixed;
	inset: 0;
	z-index: var(--gtm-z);
	background-color: var(--gtm-backdrop-bg);
	opacity: 0;
	transition: opacity var(--gtm-duration) var(--gtm-easing);
}

.gtm-menu__backdrop[hidden] {
	display: none;
}

.gtm-menu.is-open .gtm-menu__backdrop {
	opacity: 1;
}

/* ==========================================================================
   Panel - shared
   ========================================================================== */

/*
 * The panel sets its own text colour, and that is not decoration.
 *
 * Everything the panel owns besides the links - the chevrons, the close cross,
 * the back button, the panel title - draws itself with `currentColor` or
 * `color: inherit`. Without this rule they inherit from .gtm-menu, whose colour
 * is --gtm-color, while the links use --gtm-link-color. The two are the same by
 * default, so nothing looks wrong until someone recolours the panel: give it a
 * dark background and light links, and every chevron stays near-black and
 * vanishes.
 *
 * Anchoring the panel to the link colour keeps the chrome with the text it
 * belongs to, whatever the palette.
 */
.gtm-menu__panel {
	color: var(--gtm-link-color);
	background-color: var(--gtm-panel-bg);
}

/* One wrapper around head + body, so the inline pattern can collapse the whole
   panel with a single grid row instead of one row per child. */
.gtm-menu__panel-inner {
	display: flex;
	flex-direction: column;
	width: 100%;
	min-height: 0;
}

.gtm-menu__panel-head {
	display: flex;
	align-items: center;
	gap: 0.5rem;
	min-height: calc(var(--gtm-tap-size) + 0.5rem);
	padding: 0.25rem calc(var(--gtm-panel-pad-x) - 0.5rem);
	border-bottom: 1px solid var(--gtm-border-color);
}

.gtm-menu__panel-title {
	flex: 1 1 auto;
	overflow: hidden;
	font-weight: 600;
	text-align: center;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.gtm-menu__back {
	display: inline-flex;
	flex: 0 0 auto;
	align-items: center;
	gap: 0.25rem;
	min-height: var(--gtm-tap-size);
	padding: 0 0.5rem;
	color: inherit;
	font: inherit;
	background: none;
	border: 0;
	border-radius: var(--gtm-radius);
	cursor: pointer;
}

.gtm-menu__back[hidden] {
	display: none;
}

.gtm-menu__panel-body {
	padding: var(--gtm-panel-pad-y) 0;
}

/* ==========================================================================
   Panel - off-canvas
   ========================================================================== */

.gtm-menu--offcanvas .gtm-menu__panel,
.gtm-menu--overlay .gtm-menu__panel {
	position: fixed;
	z-index: calc(var(--gtm-z) + 1);
	display: flex;
	visibility: hidden;
	transition:
		transform var(--gtm-duration) var(--gtm-easing),
		opacity var(--gtm-duration) var(--gtm-easing),
		visibility 0s linear var(--gtm-duration);
}

/*
 * The bar outranks the panel, and that reverses a choice this file made for a long
 * time. Its level is set on `.gtm-menu__bar` further up: two above `--gtm-z`, the
 * panel being at +1.
 *
 * The burger already morphs into a cross - it always has - but the panel used to
 * sit above the bar, so nobody ever saw it: the panel covered the bar, and the
 * cross people clicked was a separate button in the panel's own head. Letting the
 * bar win means the control that opened the menu is the control that closes it,
 * with the colour, badge, shape, size and spacing it already has. Nothing about the
 * cross needs configuring, because it is not a second icon.
 *
 * Unconditional, not `.is-open`, and that detail is a bug fix. Raising the bar only
 * while the panel was open meant it dropped back the instant the class went - while
 * the panel was still 260ms from leaving. The cross morphed back into a burger
 * behind the closing panel, so the animation ran and could not be seen. With the
 * panel hidden whenever it is closed, there is nothing for a conditional to buy.
 *
 * The bar reaching over the panel is why the panel reserves its height - see the
 * padding below.
 */
/*
 * The logo steps aside while a floating panel is open, and the reason is worth stating:
 * raising the bar raised *both* its children, and only one of them has business
 * over an open menu. A logo painted on top of the panel reads as belonging to the
 * menu, when it belongs to the page underneath it.
 *
 * Faded rather than dropped behind the panel, which would have been the obvious
 * move and is a trap. The bar has a stacking context of its own - it has needed
 * one since 0.1.4, or a positioned slider paints over the burger - and the band is
 * an absolutely positioned pseudo-element at `z-index: -1` inside it. Take the
 * context away and that -1 escapes to the nearest ancestor that has one, painting
 * the band behind the page's own backgrounds. The logo would go under the panel,
 * and the bar's colour would vanish with it.
 *
 * Faded rather than `display: none` for a smaller reason: the bar would reflow
 * around the gap as it went, and the logo would snap back instead of returning
 * with the panel.
 */
.gtm-menu--offcanvas.is-open .gtm-menu__brand,
.gtm-menu--overlay.is-open .gtm-menu__brand {
	opacity: 0;
	pointer-events: none;
}

/*
 * And the panel keeps its content out from under it. `--gtm-bar-box` is the bar's
 * real height, tap-target floor included, so this tracks a configured bar height
 * without restating it. It replaces the space the panel head used to occupy for
 * exactly this reason, so nothing here gets tighter than it was.
 */
.gtm-menu--offcanvas .gtm-menu__panel {
	padding-block-start: var(--gtm-bar-box);
}

/*
 * The overlay reserves the same room at both ends, and the second one is not
 * decoration: its menu is centred, so a reservation on one side only moves the
 * centre down by half the bar. Padding both ends keeps the middle of the content
 * box on the middle of the screen, while still keeping a long menu out from under
 * the band when it starts at the top and scrolls.
 */
.gtm-menu--overlay .gtm-menu__panel {
	padding-block: var(--gtm-bar-box);
}

.gtm-menu--offcanvas.is-open .gtm-menu__panel,
.gtm-menu--overlay.is-open .gtm-menu__panel {
	visibility: visible;
	transition:
		transform var(--gtm-duration) var(--gtm-easing),
		opacity var(--gtm-duration) var(--gtm-easing),
		visibility 0s;
}

.gtm-menu--offcanvas .gtm-menu__panel {
	top: 0;
	bottom: 0;
	width: var(--gtm-panel-width);
	max-width: 100%;
	box-shadow: var(--gtm-panel-shadow);
}

.gtm-menu--offcanvas.gtm-menu--end .gtm-menu__panel {
	right: 0;
	transform: translateX(100%);
}

.gtm-menu--offcanvas.gtm-menu--start .gtm-menu__panel {
	left: 0;
	transform: translateX(-100%);
}

.gtm-menu--offcanvas.is-open .gtm-menu__panel {
	transform: translateX(0);
}

/* ==========================================================================
   Panel - full-screen overlay
   ========================================================================== */

/*
 * How the overlay arrives. Each rule below describes only the *closed* state -
 * where the panel waits - and the single open rule at the end sends it home.
 *
 * The order of these rules is load bearing. `.gtm-menu--overlay.is-open
 * .gtm-menu__panel` and `.gtm-menu--overlay.gtm-menu--motion-left
 * .gtm-menu__panel` are both (0,3,0), so nothing but source order separates them
 * while the panel is open. The open rule therefore comes last, after every
 * variant. Put a variant after it and that direction would never open.
 */
.gtm-menu--overlay .gtm-menu__panel {
	inset: 0;
}

/* The default, and what the overlay has always done: a fade with just enough
   scale to read as arriving rather than appearing. */
.gtm-menu--overlay .gtm-menu__panel,
.gtm-menu--overlay.gtm-menu--motion-fade .gtm-menu__panel {
	opacity: 0;
	transform: scale(0.98);
}

/*
 * The four slides keep full opacity on purpose. A full-screen sheet is opaque, so
 * fading it as well reads as two effects fighting: what sells the movement is the
 * edge travelling across the screen, not the panel materialising.
 */
.gtm-menu--overlay.gtm-menu--motion-start .gtm-menu__panel {
	opacity: 1;
	transform: translateX(-100%);
}

.gtm-menu--overlay.gtm-menu--motion-end .gtm-menu__panel {
	opacity: 1;
	transform: translateX(100%);
}

.gtm-menu--overlay.gtm-menu--motion-top .gtm-menu__panel {
	opacity: 1;
	transform: translateY(-100%);
}

.gtm-menu--overlay.gtm-menu--motion-bottom .gtm-menu__panel {
	opacity: 1;
	transform: translateY(100%);
}

/* Last, and deliberately so - see the note above. `none` rather than `scale(1)`
   or `translate(0)`, since one rule now has to undo any of five starting points. */
.gtm-menu--overlay.is-open .gtm-menu__panel {
	opacity: 1;
	transform: none;
}

/*
 * A full-screen sheet is centred, both ways. An indent would fight that, so the
 * overlay zeroes the token the accordion steps its levels in with rather than
 * out-specifying three nested rules - depth is left to the chevron here.
 */
.gtm-menu--overlay {
	--gtm-indent: 0rem;
}

.gtm-menu--overlay .gtm-menu__panel-body {
	--gtm-link-pad-y: 1rem;

	/*
	 * A factor, not a size, now that the link states its own. `font-size` alone
	 * would no longer reach a link - it stopped inheriting one - and a flat
	 * `--gtm-font-size` here would go on overriding the reader's setting, which
	 * is what made "Text size" mean nothing in this pattern. Scoped to the panel,
	 * which is as far as the larger type was ever meant to go.
	 */
	--gtm-font-scale: 1.25;

	display: flex;
	flex-direction: column;
	font-size: calc(var(--gtm-font-size) * var(--gtm-font-scale));
	text-align: center;
}

/* Every level, not just the first: a centred sheet with centred top entries and
   left-aligned sub-entries reads as a mistake. */
.gtm-menu--overlay .gtm-menu__row {
	justify-content: center;
}

/*
 * The label, and `text-align` cannot do it.
 *
 * The link is a flex container - it has to be, it lines an optional menu icon up
 * with its text - and `text-align` does not position flex items, `justify-content`
 * does. So the `text-align: center` the body sets, and which the link dutifully
 * inherits, moved nothing at all. Every box measurement said the labels were
 * centred, because the link stretches across the row and its box centre really was
 * the panel's; only measuring the ink showed them sitting hard left.
 */
.gtm-menu--overlay .gtm-menu__link {
	justify-content: center;
}

/*
 * The link stops stretching, so what gets centred is the whole entry - label plus
 * its sub-menu icon - rather than the label alone.
 *
 * This is a deliberate reversal. Until 0.1.31 both affordances were pulled out of
 * the flow so that every label, parent or leaf, sat on one axis. The icon has to
 * count towards the item's width instead: once entries are laid out side by side
 * rather than stacked, an icon outside the box makes the gaps between items uneven,
 * and no amount of per-item padding can put that right.
 *
 * The price is the one that choice carries: a parent's label sits about half an
 * icon left of a leaf's. Chosen knowingly, with the desktop layer in view.
 *
 * The base rule keeps `flex: 1 1 auto` on the link, so the stacked patterns keep a
 * label whose tap target and hover background span the whole row. Here the link is
 * only as wide as it needs to be, which is also what the desktop layer will want.
 *
 * Doubled root class for the specificity, and it is needed: `.gtm-menu
 * .gtm-menu__link` declares `flex` at the same (0,2,0) and sits *later* in the
 * file, so `.gtm-menu--overlay .gtm-menu__link` lost on source order and the link
 * went on filling the row. Anything here that contends with that rule needs (0,3,0)
 * - the neighbouring `justify-content` only works because the base sets no value
 * for it to beat.
 */
.gtm-menu.gtm-menu--overlay .gtm-menu__link {
	flex: 0 1 auto;
}

/*
 * Vertically centred with `margin-block: auto` rather than `justify-content:
 * center` on the body, and the difference is not stylistic.
 *
 * Auto margins absorb only *positive* free space. A menu that fits sits in the
 * middle; one that does not gets margins of zero instead of negative ones, so it
 * starts at the top of the scroll area and every entry stays reachable. Centring
 * the container instead overflows equally in both directions, and the first
 * entries end up above the scroll origin where nothing can bring them back. Same
 * property, same reason, as the logo in the bar.
 */
.gtm-menu--overlay .gtm-menu__panel-body > .gtm-menu__list {
	margin-block: auto;
}

/*
 * A drill-down level is its own absolutely positioned sheet, so it needs the
 * treatment applied again. Scoped to drill-down deliberately: an accordion's
 * sub-menu is a grid row that collapses to nothing, and auto margins have no
 * business in the middle of that animation.
 */
.gtm-menu--overlay.gtm-menu--sub-drilldown .gtm-menu__submenu {
	display: flex;
	flex-direction: column;
}

.gtm-menu--overlay.gtm-menu--sub-drilldown .gtm-menu__submenu > .gtm-menu__list {
	margin-block: auto;
}

/* ==========================================================================
   Panel - inline (pushes the page content down)
   ========================================================================== */

.gtm-menu--inline .gtm-menu__panel {
	display: grid;
	grid-template-rows: 0fr;
	transition: grid-template-rows var(--gtm-duration) var(--gtm-easing);
}

.gtm-menu--inline.is-open .gtm-menu__panel {
	grid-template-rows: 1fr;
}

.gtm-menu--inline .gtm-menu__panel-inner {
	overflow: hidden;
}

/* ==========================================================================
   Scrolling area
   ========================================================================== */

.gtm-menu--offcanvas .gtm-menu__panel-inner,
.gtm-menu--overlay .gtm-menu__panel-inner {
	flex: 1 1 auto;
}

.gtm-menu--offcanvas .gtm-menu__panel-body,
.gtm-menu--overlay .gtm-menu__panel-body {
	flex: 1 1 auto;
	min-height: 0;
	overflow-y: auto;
	overscroll-behavior: contain;
	-webkit-overflow-scrolling: touch;
	padding-bottom: max(var(--gtm-panel-pad-y), env(safe-area-inset-bottom));
}

/* ==========================================================================
   Lists and items
   ========================================================================== */

/*
 * The module resets its own boxes, at (0,2,0), and both halves were earned.
 *
 * A host template styles lists and list items for article content, and those
 * rules land on the menu too. This module's test site carries
 * `li { padding-top: 10px }` - unopposed, since nothing here used to touch
 * .gtm-menu__item - and `ul:not(.mod-menu) { margin-bottom: 30px }`, which at
 * (0,1,1) beat a bare `.gtm-menu__list { margin: 0 }`.
 *
 * The second one is the nastier of the two. A margin sits outside the box, so
 * it survives the accordion collapsing that box to zero: every closed sub-menu
 * kept reserving 30px, and only the entries that had children came out taller.
 * The result reads as random spacing rather than as a leak.
 */
.gtm-menu .gtm-menu__list,
.gtm-menu .gtm-menu__item {
	margin: 0;
	padding: 0;
}

.gtm-menu .gtm-menu__list {
	list-style: none;
}

.gtm-menu__row {
	display: flex;
	align-items: stretch;
	gap: var(--gtm-icon-gap);
}

/*
 * Scoped through the root, and the extra class is the whole point.
 *
 * Host templates ship blanket element rules - this module's own test site has
 * `a { color: #fff }` sitting in the template stylesheet. That is (0,0,1)
 * against a lone `.gtm-menu__link` at (0,1,0), so we win, but by one step and
 * only as long as nobody adds `.something a`. Losing that race turns every
 * clickable entry white while the non-clickable ones - Joomla separators, which
 * render as spans - keep their colour, so the menu half-disappears in a way
 * that looks like a bug in the module.
 *
 * (0,2,0) puts the whole family out of reach of any element-level rule. The
 * headings and the hover states move up with it, or they would lose to the very
 * rule they are meant to override.
 */
.gtm-menu .gtm-menu__link {
	display: flex;
	flex: 1 1 auto;
	align-items: center;
	column-gap: 0;
	min-height: var(--gtm-row-min-height);
	padding: var(--gtm-link-pad-y) var(--gtm-panel-pad-x);
	color: var(--gtm-link-color);
	font: inherit;

	/*
	 * The size is stated, not inherited, and that is a fix rather than a
	 * flourish.
	 *
	 * `font: inherit` takes the size from the parent, which is a `<li>` inside a
	 * `<ul>` - precisely the elements a host template resets. This module's own
	 * test site ships `body, div, span, ..., li { font-size: 18px }` and a second
	 * rule taking those to `1.2rem` above 1201px, both at (0,0,1) and both
	 * unopposed, because nothing here used to declare a size on the link at all.
	 *
	 * The effect was that "Text size" did nothing whatsoever on that template, at
	 * any width: measured, the token went from 16px to 30px on the root while
	 * every link stayed at the template's 18px. Reading the token here puts the
	 * setting back in charge, and the heading variant below - sized in `em` -
	 * starts scaling with it instead of with whatever the template decided.
	 */
	font-size: calc(var(--gtm-font-size) * var(--gtm-font-scale));
	font-weight: var(--gtm-font-weight);
	text-align: inherit;
	text-decoration: none;
	background: none;
	border: 0;
	cursor: pointer;
	transition:
		color var(--gtm-duration) var(--gtm-easing),
		background-color var(--gtm-duration) var(--gtm-easing);
}

/*
 * The boxes the text actually sits in, each stating that it inherits its size.
 *
 * Declaring the size on the link was not enough, and the reason is worth keeping:
 * the visible label is a `<span>` inside the link, and a host template that
 * resets `span` beats anything the link says, because the link is not what the
 * rule is on. The test site ships `p, span, li, h4, h3, h5, a { font-size:
 * 1.2rem }` above 1201px - measured, the link resolved the configured 14px while
 * every label rendered at 19.2px, so "Text size" appeared to do nothing at all
 * even though the token, the generated sheet and the link all agreed.
 *
 * `inherit` rather than the token, so a label follows whatever its own link
 * resolved - the heading variant's 0.8125 factor included - instead of restating
 * a calculation that would then have two places to drift apart in.
 *
 * (0,2,0) and (0,2,1) here against an element selector's (0,0,1). Specificity
 * settles it whatever the template's media queries do, which is the point: this
 * has to hold against rules we never get to see.
 */
.gtm-menu .gtm-menu__label,
.gtm-menu .gtm-menu__panel-title,
.gtm-menu .gtm-menu__back > span {
	font-size: inherit;
}

.gtm-menu .gtm-menu__link:hover,
.gtm-menu .gtm-menu__link:focus-visible {
	color: var(--gtm-link-color-hover);
	background-color: var(--gtm-link-bg-hover);
	font-weight: var(--gtm-link-weight-hover);
	/*
	 * `!important`, and only here.
	 *
	 * Nothing else beats `!important`, and host templates reach for it on this
	 * very property: this module's test site ships `a { text-decoration: none
	 * !important }` inside a `@media screen` block. Measured, the underline
	 * setting worked on a group heading - a `<button>`, which `a` never matches -
	 * and did nothing at all on an ordinary link, which is most of a menu.
	 *
	 * The cost is bounded on purpose. It sits on the two state rules and not on
	 * the base one, so a template can still decide how a resting entry is
	 * decorated; and since the default of both tokens is `none`, which is what
	 * the base rule already says, an untouched module renders exactly as before.
	 * What a template gives up is decorating hover or current itself - which is
	 * what these settings are for.
	 */
	text-decoration: var(--gtm-link-decoration-hover) !important;
}

/*
 * Titled separators land here: Joomla editors use them as non-clickable parents
 * for a branch, so they read as section labels rather than links - small, muted
 * and set in capitals to say "this is a group, not a destination".
 *
 * On a menu built almost entirely of them that reads as an index instead of a
 * navigation, which is what the plain variant below is for.
 */
.gtm-menu .gtm-menu__link--heading {
	color: var(--gtm-heading-color);

	/* Against the setting, not against `em`. An `em` here would resolve on the
	   parent row, which is a box the host template is free to size - and does:
	   the test site takes every `div` to 1.2rem above 1201px, so a "smaller"
	   heading came out larger than the links around it. */
	font-size: calc(var(--gtm-font-size) * var(--gtm-font-scale) * 0.8125);
	font-weight: 600;
	letter-spacing: 0.04em;
	text-transform: uppercase;
	cursor: default;
}

.gtm-menu .gtm-menu__link--heading:hover {
	color: var(--gtm-heading-color);
	background: none;
}

/*
 * A group label that owns its branch is a control, and has to say so. The rules
 * above turn hover feedback off, because a heading is normally inert; these put
 * it back for the one case where the whole row opens the sub-menu.
 *
 * (0,3,0) against the (0,2,1) of the hover rules above, so it wins on both the
 * muted and the plain heading style without either needing to know about it.
 */
.gtm-menu .gtm-menu__link--heading.gtm-menu__link--toggle {
	cursor: pointer;
}

.gtm-menu .gtm-menu__link--heading.gtm-menu__link--toggle:hover,
.gtm-menu .gtm-menu__link--heading.gtm-menu__link--toggle:focus-visible {
	color: var(--gtm-link-color-hover);
	background-color: var(--gtm-link-bg-hover);

	/* Restated, because the heading rules above set a weight of their own at
	   (0,2,0) and this selector is the only thing that outranks them. Without
	   these two, a group label that owns its branch would answer the hover
	   colour but ignore the hover weight. */
	font-weight: var(--gtm-link-weight-hover);
	text-decoration: var(--gtm-link-decoration-hover) !important;
}

/* Same weight and size as a real link, so a branch parent no longer looks like
   a caption. Still not clickable, so still no hover colour.
   Ties with the heading rules above at (0,2,0) and wins on source order, so it
   has to stay below them. */
.gtm-menu--headings-plain .gtm-menu__link--heading,
.gtm-menu--headings-plain .gtm-menu__link--heading:hover {
	color: var(--gtm-link-color);

	/* "The same size as a real link", said the way a real link says it.
	   `inherit` used to mean that and stopped the day the link declared its own
	   size: it then meant "whatever the host template put on the row", which on
	   the test site is 18px flat and 1.2rem above 1201px. */
	font-size: calc(var(--gtm-font-size) * var(--gtm-font-scale));

	font-weight: var(--gtm-font-weight);
	letter-spacing: normal;
	text-transform: none;
}

/*
 * The entry for the page you are on, and its ancestors - Joomla marks the first
 * `is-current` and the branch above it `is-active`, and both read as "you are
 * here", so both are dressed the same.
 *
 * (0,3,0), which beats the hover rule's (0,2,1): hovering the current entry
 * leaves it looking current rather than swapping it for the hover state. That
 * was already true of the colour before the other three joined it, and it is
 * the right way round - the pointer is transient, the page you are on is not.
 */
.is-current > .gtm-menu__row > .gtm-menu__link,
.is-active > .gtm-menu__row > .gtm-menu__link {
	color: var(--gtm-link-color-current);
	background-color: var(--gtm-link-bg-current);
	font-weight: var(--gtm-link-weight-current);
	/*
	 * `!important`, and only here.
	 *
	 * Nothing else beats `!important`, and host templates reach for it on this
	 * very property: this module's test site ships `a { text-decoration: none
	 * !important }` inside a `@media screen` block. Measured, the underline
	 * setting worked on a group heading - a `<button>`, which `a` never matches -
	 * and did nothing at all on an ordinary link, which is most of a menu.
	 *
	 * The cost is bounded on purpose. It sits on the two state rules and not on
	 * the base one, so a template can still decide how a resting entry is
	 * decorated; and since the default of both tokens is `none`, which is what
	 * the base rule already says, an untouched module renders exactly as before.
	 * What a template gives up is decorating hover or current itself - which is
	 * what these settings are for.
	 */
	text-decoration: var(--gtm-link-decoration-current) !important;
}

/* Scoped through .gtm-menu on purpose. Templates routinely ship a blanket
   `.some-position img { width: 100% }`, which outranks a lone class and blows
   menu icons up to the full panel width. */
.gtm-menu .gtm-menu__image {
	flex: 0 0 auto;
	/* What the link's `gap` used to give it. Explicit now, because the icon at the
	   other end of the label wants a different distance and one `gap` cannot serve
	   two. */
	margin-inline-end: 0.625rem;
	width: auto;
	max-width: 100%;
	max-height: var(--gtm-image-max-height);
}

.gtm-menu__separator {
	display: block;
	height: 1px;
	margin: 0.5rem var(--gtm-panel-pad-x);
	background-color: var(--gtm-border-color);
}

/* ==========================================================================
   Expander
   ========================================================================== */

.gtm-menu__expander {
	display: inline-flex;
	flex: 0 0 auto;
	align-items: center;
	justify-content: center;
	width: var(--gtm-tap-size);
	padding: 0;
	color: inherit;
	background: none;
	border: 0;
	border-radius: var(--gtm-radius);
	cursor: pointer;
	-webkit-tap-highlight-color: transparent;
}

.gtm-menu__expander:hover,
.gtm-menu__expander:focus-visible {
	color: var(--gtm-link-color-hover);
}

/*
 * A square wearing two borders, turned a half-quarter: the corner becomes the
 * arrowhead. Rotating a square leaves the ink lopsided inside its own box - it
 * bunches up on the side the head points at, by about a quarter of the box -
 * so every variant pulls it back by 25% along the axis it points down. The axis
 * therefore follows the rotation: X pointing right or left, Y pointing down.
 * Correcting the wrong axis moves the glyph off the text rather than centring
 * it, which is precisely what this rule used to do with a translateY.
 */
.gtm-menu__chevron {
	display: block;
	width: 0.5rem;
	height: 0.5rem;
	border-right: 2px solid currentColor;
	border-bottom: 2px solid currentColor;
	transform: translateX(-25%) rotate(-45deg);
	transition: transform var(--gtm-duration) var(--gtm-easing);
}

.gtm-menu__chevron--back {
	transform: translateX(25%) rotate(135deg);
}

/*
 * When the whole row is the toggle, the chevron follows the label instead of
 * riding to the far end - `space-between` and an `auto` margin used to send it
 * there. It belongs to the label, so it travels with it, and it counts towards the
 * item's width: that is what keeps the gaps between items even once they sit side
 * by side rather than stacked.
 */
.gtm-menu__link--toggle .gtm-menu__chevron {
	margin-inline-start: var(--gtm-icon-gap);
}

/* ==========================================================================
   Sub-menu icon - plus / minus
   Everything below excludes the back control: its chevron means "back", not
   "there is a branch here", so the setting has no business rewriting it.
   ========================================================================== */

/*
 * The plus is two bars, and the minus is the same plus with one bar laid flat.
 * Drawing it that way rather than swapping glyphs means the change animates,
 * and it survives any colour: both bars are currentColor, like the chevron.
 */
.gtm-menu--icon-plusminus .gtm-menu__chevron:not(.gtm-menu__chevron--back) {
	position: relative;
	width: 0.75rem;
	height: 0.75rem;
	border: 0;
	transform: none;
}

.gtm-menu--icon-plusminus .gtm-menu__chevron:not(.gtm-menu__chevron--back)::before,
.gtm-menu--icon-plusminus .gtm-menu__chevron:not(.gtm-menu__chevron--back)::after {
	content: "";
	position: absolute;
	top: calc(50% - 1px);
	left: 0;
	width: 100%;
	height: 2px;
	background-color: currentColor;
	border-radius: 2px;
	transition: transform var(--gtm-duration) var(--gtm-easing);
}

.gtm-menu--icon-plusminus .gtm-menu__chevron:not(.gtm-menu__chevron--back)::after {
	transform: rotate(90deg);
}

/*
 * Cancels the accordion's quarter turn, which lives further down the file.
 * `:not()` carries the specificity of its argument, so this reaches (0,4,0)
 * against that rule's (0,3,0) and wins outright - the icon block can therefore
 * stay together here instead of being scattered to satisfy source order.
 */
.gtm-menu--icon-plusminus [aria-expanded="true"] .gtm-menu__chevron:not(.gtm-menu__chevron--back) {
	transform: none;
}

.gtm-menu--icon-plusminus [aria-expanded="true"] .gtm-menu__chevron:not(.gtm-menu__chevron--back)::after {
	transform: rotate(0deg);
}

/* ==========================================================================
   Sub-menu icon - none
   ========================================================================== */

/*
 * The glyph goes, the control does not. In "link and toggle" the expander is a
 * separate button and this leaves it with nothing to show - still 44px, still
 * clickable, but invisible. That combination is called out in the setting's
 * description; it belongs to whoever picks it, not to the stylesheet to guess.
 */
.gtm-menu--icon-none .gtm-menu__chevron:not(.gtm-menu__chevron--back) {
	display: none;
}

/* ==========================================================================
   Sub-menus - accordion
   ========================================================================== */

.gtm-menu--sub-accordion .gtm-menu__submenu {
	display: grid;
	grid-template-rows: 0fr;
	transition: grid-template-rows var(--gtm-duration) var(--gtm-easing);
}

.gtm-menu--sub-accordion .gtm-menu__submenu > .gtm-menu__list {
	min-height: 0;
	overflow: hidden;
}

.gtm-menu--sub-accordion .gtm-menu__submenu.is-open {
	grid-template-rows: 1fr;
}

/*
 * The chevron of the open row turns a quarter turn, not a half.
 *
 * Pointing down says "this is unfolded, below". Pointing up - the half turn -
 * says "fold me back", which is the same information told backwards and reads
 * as a mirror of the closed state rather than as its consequence. A quarter
 * turn also keeps the travel short enough that the eye follows it.
 */
.gtm-menu--sub-accordion [aria-expanded="true"] .gtm-menu__chevron {
	transform: translateY(-25%) rotate(45deg);
}

/* Each level steps in, so depth stays readable without borders. */
.gtm-menu--sub-accordion .gtm-menu__submenu .gtm-menu__link {
	padding-left: calc(var(--gtm-panel-pad-x) + var(--gtm-indent));
}

.gtm-menu--sub-accordion .gtm-menu__submenu .gtm-menu__submenu .gtm-menu__link {
	padding-left: calc(var(--gtm-panel-pad-x) + var(--gtm-indent) * 2);
}

.gtm-menu--sub-accordion .gtm-menu__submenu .gtm-menu__submenu .gtm-menu__submenu .gtm-menu__link {
	padding-left: calc(var(--gtm-panel-pad-x) + var(--gtm-indent) * 3);
}

/* ==========================================================================
   Sub-menus - drill-down
   ========================================================================== */

/* Levels slide over one another inside the body, so the body becomes the stage
   and the root list takes over the scrolling. */
.gtm-menu--sub-drilldown:not(.gtm-menu--inline) .gtm-menu__panel-body {
	position: relative;
	overflow: hidden;
}

.gtm-menu--sub-drilldown:not(.gtm-menu--inline) .gtm-menu__panel-body > .gtm-menu__list {
	height: 100%;
	overflow-y: auto;
	overscroll-behavior: contain;
	-webkit-overflow-scrolling: touch;
}

.gtm-menu--sub-drilldown:not(.gtm-menu--inline) .gtm-menu__submenu {
	position: absolute;
	inset: 0;
	z-index: 1;
	overflow-y: auto;
	overscroll-behavior: contain;
	-webkit-overflow-scrolling: touch;
	background-color: var(--gtm-panel-bg);
	transform: translateX(100%);
	visibility: hidden;
	transition:
		transform var(--gtm-duration) var(--gtm-easing),
		visibility 0s linear var(--gtm-duration);
}

.gtm-menu--sub-drilldown:not(.gtm-menu--inline) .gtm-menu__submenu.is-open {
	transform: translateX(0);
	visibility: visible;
	transition:
		transform var(--gtm-duration) var(--gtm-easing),
		visibility 0s;
}

/* The chevron points forward at every depth - it never opens in place. */
.gtm-menu--sub-drilldown .gtm-menu__chevron {
	transform: translateX(-25%) rotate(-45deg);
}

/* Sliding panels need a fixed stage to slide across, which the in-flow inline
   pattern has none of. There, a level simply replaces the previous one and the
   page reflows around it. */
.gtm-menu--inline.gtm-menu--sub-drilldown .gtm-menu__submenu {
	height: 0;
	overflow: hidden;
	visibility: hidden;
}

.gtm-menu--inline.gtm-menu--sub-drilldown .gtm-menu__submenu.is-open {
	height: auto;
	overflow: visible;
	visibility: visible;
}

/* Once a level is showing, its parent list steps aside instead of stacking
   above it. */
.gtm-menu--inline.gtm-menu--sub-drilldown .gtm-menu__item--parent:has(> .gtm-menu__submenu.is-open) > .gtm-menu__row,
.gtm-menu--inline.gtm-menu--sub-drilldown .gtm-menu__list:has(> .gtm-menu__item > .gtm-menu__submenu.is-open) > .gtm-menu__item:not(:has(> .gtm-menu__submenu.is-open)) {
	display: none;
}

/* ==========================================================================
   Permanently expanded branches ("parent behaviour: link only")
   ========================================================================== */

.gtm-menu__submenu.is-static {
	position: static;
	height: auto;
	overflow: visible;
	transform: none;
	visibility: visible;
	grid-template-rows: 1fr;
	transition: none;
}

/* ==========================================================================
   Motion preferences
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
	.gtm-menu {
		--gtm-duration: 1ms;
	}

	.gtm-menu *,
	.gtm-menu *::before,
	.gtm-menu *::after {
		transition-duration: 1ms !important;
		animation-duration: 1ms !important;
	}
}

/* ==========================================================================
   Desktop layer - sm (576px and up)
   Generated from gtmmenu.desktop.css. Edit that file, not this one.
   ========================================================================== */

@media (min-width: 576px) {
	/* ==========================================================================
	   Desktop layer - THE SOURCE, written once

	   This file is expanded five times into media/css/gtmmenu.css, once per named
	   breakpoint, by tools/build-css.py. Write `.gtm-menu--bp-sm` and the generator
	   emits `.gtm-menu--bp-sm` ... `.gtm-menu--bp-xxl`, each inside its own query.
	   Never write a suffixed class here.

	   Two rules hold this file together.

	   1. EVERY selector starts with `.gtm-menu.gtm-menu--bp-sm`, root doubled. Not
	      decoration: the mobile layer scopes its patterns at (0,2,0) and, in one
	      case, at (0,3,0) - `.gtm-menu.gtm-menu--overlay .gtm-menu__link` doubles
	      its own root for exactly the same reason. A single root here would put
	      this layer at (0,2,0), where it would lose to the pattern it is meant to
	      replace, and the loss would depend on which rule happened to sit lower in
	      the file. Doubling puts the floor at (0,3,0), which beats every pattern
	      rule outright and ties only with that one - and ties fall this way, since
	      the generated file appends this block last.

	   2. CANCEL SHORTHANDS WITH SHORTHANDS. The patterns position their panels with
	      `inset: 0`. Overriding it with `inset-block-start` alone leaves the other
	      three sides live, and the box silently stretches to the corner the mobile
	      layer chose. Every reset below therefore restates the whole `inset`.

	   What is deliberately NOT here: no burger at any width above the breakpoint,
	   so nothing in this file gives the toggle a desktop variant - its colour,
	   shape, alignment and spacing stay mobile-only settings. The logo does survive
	   the breakpoint, which is why it has two sets of everything.
	   ========================================================================== */

	/*
	 * The frame becomes the row, and the bar stops being a box.
	 *
	 * `display: contents` on the bar promotes the logo to a direct flex item of the
	 * frame, sitting beside the panel. That is what makes the three alignments mean
	 * anything: each one distributes the space *after* the logo. Keep the bar as a
	 * real box and the panel has to be positioned over it instead, at which point
	 * "aligned to the logo" would render as "underneath the logo".
	 *
	 * The frame also inherits what the bar used to carry - the padding, the gap, the
	 * stacking level. The stacking level is the one that is not cosmetic: .gtm-menu
	 * is positioned without a z-index, so it paints where document order alone
	 * decides, and any positioned element further down the page paints over it. The
	 * bar carries `--gtm-z + 2` for that reason at mobile widths; here the whole row
	 * needs it, dropdowns included.
	 *
	 * Why the frame rather than the nav: the fixed mode below has to take the whole
	 * row out of the flow, and a fixed box reserves no height. The nav has to stay
	 * in the flow to go on doing that, so it cannot be the thing that gets fixed.
	 */
	.gtm-menu.gtm-menu--bp-sm {
		/*
		 * Desktop-only tokens. Declared on the nav rather than the frame so the
		 * generated per-instance sheet has a stable place to override them from
		 * inside its own media query, and inside the breakpoint so they cannot leak
		 * down to mobile.
		 */
		/*
		 * The link's own padding, rather than the mobile `--gtm-link-pad-y`. That
		 * token is rewritten by the overlay pattern on the panel body, so reading it
		 * here would make a desktop row's height depend on which mobile pattern
		 * happens to be selected.
		 */
		--gtm-desktop-link-pad-y: 0.5rem;
		--gtm-desktop-link-pad-x: 0.875rem;
		--gtm-desktop-item-gap: 0rem;
		--gtm-desktop-dropdown-min-width: 12rem;

		/*
		 * What a dropdown uses instead of the bar's own values. Each one defaults to
		 * the matching entry token, so a dropdown follows the bar until somebody says
		 * otherwise and no setting is needed to keep things as they are.
		 *
		 * No cycle here, although it reads like one: this is the nav, where
		 * `--gtm-font-size` is a real value; the substitution below happens on the
		 * dropdown, against the value it inherited from here.
		 */
		--gtm-desktop-dropdown-font-size: var(--gtm-font-size);
		--gtm-desktop-dropdown-link-color: var(--gtm-link-color);
		--gtm-desktop-dropdown-link-color-hover: var(--gtm-link-color-hover);
		--gtm-desktop-dropdown-link-color-current: var(--gtm-link-color-current);

		/*
		 * How far the dropdown sits below the bar. Zero means flush with the bottom
		 * of the band; a negative value pulls it up into the bar, which is what a
		 * bar with an elliptical rounding needs - its bottom edge is a curve, so
		 * "flush" is a different number at each end and the box has to overlap the
		 * shallow side to close the gap on the deep one.
		 */
		--gtm-desktop-dropdown-offset: 0px;
		--gtm-desktop-dropdown-shadow: 0 8px 24px rgba(0, 0, 0, 0.16);
	}

	.gtm-menu.gtm-menu--bp-sm .gtm-menu__frame {
		position: relative;
		z-index: calc(var(--gtm-z) + 2);
		display: flex;
		align-items: center;
		gap: var(--gtm-bar-gap);

		/*
		 * Capped, exactly as the bar caps itself below the breakpoint - and the cap
		 * is what keeps the page from starting a logo's height further down.
		 *
		 * Without it the row is as tall as its tallest item, which is the logo, so a
		 * 253px logo over a 70px band reserved 253px of flow and left 183px of empty
		 * page under the colour. Measured on the site, and reported as such.
		 *
		 * The logo goes on overhanging because `margin-block: auto` on it resolves to
		 * zero once it no longer fits, dropping the overhang below the band where it
		 * shows. That is the same mechanism the bar has always relied on; copying the
		 * declaration rather than inventing a second way to say it is the point.
		 *
		 * `auto` when no bar height is set, so "let the content decide" still means
		 * what it means everywhere else.
		 */
		height: var(--gtm-bar-height, auto);
		min-height: var(--gtm-tap-size);
		padding-inline: var(--gtm-bar-pad-x);

		/*
		 * The row spans the full width whether or not it has anything to put there,
		 * so its own box catches nothing and every interactive descendant takes its
		 * clicks back. Same reasoning as the bar's at mobile widths, and it matters
		 * more here: the empty half of a right-aligned menu sits directly over a
		 * hero or a slider.
		 */
		pointer-events: none;
	}

	/*
	 * The painted band moves up to the frame, because the bar no longer has a box to
	 * paint it on - and a band the width of the logo is not a band.
	 *
	 * Declared exactly as the bar's is, over-constraint included: `inset-block: 0`
	 * together with a height resolves in the band's favour, dropping the bottom
	 * inset, so `auto` stretches to the full row and a length pins the band to the
	 * top. Any simplification here changes what an unset bar height means.
	 */
	.gtm-menu.gtm-menu--bp-sm .gtm-menu__frame::before {
		content: '';
		position: absolute;
		inset-block: 0;
		inset-inline: 0;
		z-index: -1;
		height: var(--gtm-bar-height, auto);
		background-color: var(--gtm-bar-bg);
		border-radius: var(--gtm-bar-radius);
		pointer-events: none;
	}

	.gtm-menu.gtm-menu--bp-sm .gtm-menu__bar {
		display: contents;
	}

	/* Whether a `display: contents` element still generates its pseudo-elements is
	   not something to leave to the browser: cancelled explicitly, or the band
	   risks being painted twice - once at the row's width, once at the logo's. */
	.gtm-menu.gtm-menu--bp-sm .gtm-menu__bar::before {
		content: none;
	}

	/*
	 * The burger goes, and with it everything that only ever served it. The panel
	 * head belongs to the drill-down, which has no meaning once every level is a
	 * dropdown; the backdrop dims a page behind a floating panel, and nothing
	 * floats here.
	 *
	 * `display: none` at (0,3,0) also settles the fixed-toggle variant, which pins
	 * the button to the viewport at (0,2,0) - a burger left fixed above the
	 * breakpoint would hang in the corner over a menu that already shows every
	 * entry.
	 */
	.gtm-menu.gtm-menu--bp-sm .gtm-menu__toggle,
	.gtm-menu.gtm-menu--bp-sm .gtm-menu__backdrop,
	.gtm-menu.gtm-menu--bp-sm .gtm-menu__panel-head {
		display: none;
	}

	/*
	 * A fixed row fixes the frame, not the bar - the bar has no box left to fix,
	 * and the panel would not follow it if it had. The mobile rule targets the bar
	 * at (0,2,0) and simply stops applying once the bar is `display: contents`.
	 *
	 * The nav stays exactly where it was, so `--reserve` goes on reserving the
	 * height through its own `min-height`, unchanged and untouched.
	 */
	.gtm-menu.gtm-menu--bp-sm.gtm-menu--fixed .gtm-menu__frame {
		position: fixed;
		inset: 0 0 auto;
	}

	.gtm-menu.gtm-menu--bp-sm .gtm-menu__brand {
		flex: 0 0 auto;
	}

	/* ==========================================================================
	   The panel becomes the row of entries
	   ========================================================================== */

	/*
	 * Everything the three patterns did to this box is undone in one place: the
	 * off-canvas fixes it to a side and gives it a width, the overlay stretches it
	 * over the viewport and fades it in, the inline pattern collapses it with a
	 * zero grid row. Undoing them piecemeal, pattern by pattern, would mean three
	 * near-identical blocks and a fourth the day a pattern is added.
	 *
	 * `inset` and `transform` are restated whole for the reason at the top of this
	 * file. `min-width: 0` lets a long menu shrink rather than push the logo off
	 * the row - flex items refuse to go below their content width without it.
	 */
	.gtm-menu.gtm-menu--bp-sm .gtm-menu__panel {
		position: static;
		z-index: auto;
		display: flex;
		flex: 1 1 auto;

		/*
		 * The entries centre on the painted band, not on the row.
		 *
		 * The row is as tall as its tallest item, which is the logo - and a logo is
		 * routinely taller than the band, since that overhang is the whole point of
		 * a separate bar height. Left to `align-items: center` on the row, the
		 * entries centre on the logo instead and hang below the colour: measured at
		 * 90px down a 180px row against a 100px band, half of every label off the
		 * band. So the panel takes the band's height, pinned to the top, and centres
		 * inside that.
		 *
		 * `--gtm-bar-band` is the same token the bar's own height and the fixed
		 * hamburger's insets are computed from - one number, one place.
		 */
		align-self: flex-start;
		height: var(--gtm-bar-band);
		align-items: stretch;
		inset: auto;
		width: auto;
		min-width: 0;
		max-height: none;
		padding: 0;
		background: none;
		visibility: visible;
		opacity: 1;
		transform: none;
		transition: none;
		overflow: visible;
		pointer-events: none;
	}

	/* The alignment setting, and the only thing it touches. Free space lives
	   between the logo and the entries, so this decides which end of it they sit
	   at. */
	.gtm-menu.gtm-menu--bp-sm.gtm-menu--menu-end .gtm-menu__panel {
		justify-content: flex-end;
	}

	.gtm-menu.gtm-menu--bp-sm.gtm-menu--menu-center .gtm-menu__panel {
		justify-content: center;
	}

	.gtm-menu.gtm-menu--bp-sm.gtm-menu--menu-start .gtm-menu__panel {
		justify-content: flex-start;
	}

	.gtm-menu.gtm-menu--bp-sm .gtm-menu__panel-inner {
		flex: 0 1 auto;
		flex-direction: row;
		align-items: stretch;
		width: auto;
		min-width: 0;
	}

	/*
	 * The overlay pattern dresses this box for a full-screen sheet - 1.25rem type,
	 * centred text, its own vertical rhythm - and every one of those leaks into a
	 * dropdown, where they read as a mistake. Undone here rather than in a rule
	 * scoped to the overlay, since the next pattern to style the body would leak in
	 * exactly the same way.
	 */
	.gtm-menu.gtm-menu--bp-sm .gtm-menu__panel-body {
		display: flex;
		/* Restated because the overlay lays this box out as a column, where
		   `align-items: stretch` stretches across the width instead of the height
		   and the chain quietly stops here. */
		flex-direction: row;
		flex: 0 1 auto;
		align-items: stretch;
		min-width: 0;
		padding: 0;

		/*
		 * The overlay enlarges its sheet by a factor on this box. Above the
		 * breakpoint there is no sheet - the entries are a row on the bar - so the
		 * factor goes back to 1 and the desktop text size is read as written.
		 */
		--gtm-font-scale: 1;

		font-size: inherit;
		text-align: start;
		overflow: visible;
	}

	/* The top level, and only the top level, lies down. Deeper lists keep the
	   block direction they already had, which is what a dropdown wants.

	   `stretch` rather than `center`, and it is the dropdowns that need it: they
	   hang off `inset-block-start: 100%`, so an item as tall as its label would
	   open them halfway up the band, across the colour. Full-height items put that
	   100% exactly on the band's bottom edge - and give the pointer a taller strip
	   to cross on its way down into the branch. */
	.gtm-menu.gtm-menu--bp-sm .gtm-menu__panel-body > .gtm-menu__list {
		display: flex;
		align-items: stretch;
		gap: var(--gtm-desktop-item-gap);

		/*
		 * The overlay centres this list with `margin-block: auto`, and an auto
		 * margin in a flex container swallows the free space before `stretch` ever
		 * sees it - so the list stayed 44px tall inside a 100px band and the
		 * dropdowns opened 28px above it. Cancelling the margin is what lets the
		 * chain of `stretch` above actually reach the items.
		 */
		margin-block: 0;
		height: auto;
		padding: 0;
		overflow: visible;
	}

	/* The label stays its own height inside that full-height item, so the hover
	   background is a pill on the band rather than a full-height block. */
	.gtm-menu.gtm-menu--bp-sm .gtm-menu__panel-body > .gtm-menu__list > .gtm-menu__item {
		display: flex;
		align-items: center;
	}

	/* Each parent is the positioning context for its own dropdown. Only parents:
	   giving every item a containing block would cost nothing today and confuse
	   the next person looking for why an item is positioned. */
	.gtm-menu.gtm-menu--bp-sm .gtm-menu__item--parent {
		position: relative;
	}

	/* `justify-content` here and on the link below undoes the overlay's centring,
	   which otherwise centres every dropdown entry against its box. */
	.gtm-menu.gtm-menu--bp-sm .gtm-menu__row {
		justify-content: flex-start;
		pointer-events: auto;
	}

	/*
	 * A row that no longer fills a column.
	 *
	 * `flex: 0 1 auto` is the shrink-but-do-not-grow the overlay pattern already
	 * uses, and it is what makes an item's width its own content - label, gap and
	 * chevron together - so the spacing between entries stays even. The mobile
	 * default grows the link to fill the row, which is right when rows are stacked
	 * and meaningless when they sit side by side.
	 *
	 * `white-space: nowrap` because a wrapped entry in a horizontal bar reads as
	 * two entries.
	 */
	.gtm-menu.gtm-menu--bp-sm .gtm-menu__link {
		flex: 0 1 auto;
		justify-content: flex-start;
		padding-block: var(--gtm-desktop-link-pad-y);
		padding-inline: var(--gtm-desktop-link-pad-x);
		white-space: nowrap;
	}

	/* ==========================================================================
	   Dropdowns
	   ========================================================================== */

	/*
	 * One reset for every sub-menu at every depth, whatever the mobile mode did to
	 * it. The accordion collapses these with `grid-template-rows: 0fr` and an
	 * `overflow: hidden`; the drill-down slides them in from the side with a
	 * transform, at (0,3,0), which is why the root is doubled here as everywhere.
	 *
	 * Hidden with `visibility` rather than `display: none` so the box can be
	 * measured while closed - the flip below needs a width, and a display-none box
	 * has none. The delayed `visibility` transition is the standard trick for
	 * keeping it out of the tab order until the fade finishes.
	 */
	.gtm-menu.gtm-menu--bp-sm .gtm-menu__submenu {
		position: absolute;
		inset: calc(100% + var(--gtm-desktop-dropdown-offset)) auto auto 0;
		z-index: 1;
		display: block;
		width: max-content;
		min-width: var(--gtm-desktop-dropdown-min-width);
		max-width: 20rem;
		height: auto;
		padding-block: var(--gtm-panel-pad-y);
		background-color: var(--gtm-panel-bg);
		border-radius: var(--gtm-radius);
		box-shadow: var(--gtm-desktop-dropdown-shadow);
		visibility: hidden;
		opacity: 0;
		transform: none;
		overflow: visible;
		pointer-events: auto;
		transition:
			opacity var(--gtm-duration) var(--gtm-easing),
			visibility 0s linear var(--gtm-duration);
	}

	/*
	 * A dropdown restyles itself by re-pointing the base tokens, not by out-ranking
	 * the rules that read them.
	 *
	 * The alternative was a rule per property, each scoped through `.gtm-menu__submenu`
	 * and each having to beat the one it replaced - and there are more of those than
	 * it first looks: the link, the muted heading with its 0.8125 factor, the plain
	 * heading, the hover state, the current page. Five selectors to write, five
	 * specificities to get right, and a sixth to remember the day another is added.
	 *
	 * Re-declaring the tokens on the box instead means every one of those rules goes
	 * on saying exactly what it said before and quietly reads the dropdown's values
	 * inside the dropdown. Nothing to out-specify, and a rule added later inherits
	 * the behaviour for free.
	 *
	 * The values come from the nav, where they resolved against the bar's own tokens,
	 * so `--gtm-font-size: var(--gtm-desktop-dropdown-font-size)` is a substitution
	 * of an inherited value rather than a self-reference.
	 */
	.gtm-menu.gtm-menu--bp-sm .gtm-menu__submenu {
		--gtm-font-size: var(--gtm-desktop-dropdown-font-size);
		--gtm-link-color: var(--gtm-desktop-dropdown-link-color);
		--gtm-link-color-hover: var(--gtm-desktop-dropdown-link-color-hover);
		--gtm-link-color-current: var(--gtm-desktop-dropdown-link-color-current);
	}

	/* A branch below the first opens beside its parent, not under it. */
	.gtm-menu.gtm-menu--bp-sm .gtm-menu__submenu .gtm-menu__submenu {
		inset: 0 auto auto 100%;
	}

	/*
	 * A dropdown that would run off the right edge is flipped by the script, which
	 * measures it and adds this class. CSS cannot ask where the viewport ends, and
	 * the alternative - anchoring the last few items to the right on principle -
	 * guesses at how many "the last few" is and is wrong at every other width.
	 */
	.gtm-menu.gtm-menu--bp-sm .gtm-menu__submenu--flip {
		inset: calc(100% + var(--gtm-desktop-dropdown-offset)) 0 auto auto;
	}

	.gtm-menu.gtm-menu--bp-sm .gtm-menu__submenu .gtm-menu__submenu--flip {
		inset: 0 100% auto auto;
	}

	/*
	 * What opens a dropdown, in the two trigger modes.
	 *
	 * Hover mode answers to the pointer and to the keyboard alike: `:focus-within`
	 * is what lets Tab walk into a branch without the script being involved at all.
	 * Click mode deliberately leaves both out - a branch that opened on focus would
	 * contradict the button the reader just chose not to press - and answers only
	 * to `is-open`, which the script sets.
	 *
	 * `.is-static` is excluded because it carries `is-open` from the markup: the
	 * "link only" parent behaviour leaves branches permanently expanded, which is a
	 * stacked-list idea. Here those branches are ordinary dropdowns, and since that
	 * behaviour prints no button at all, hover is the only affordance they have.
	 */
	.gtm-menu.gtm-menu--bp-sm[data-desktop-trigger="hover"] .gtm-menu__item:hover > .gtm-menu__submenu,
	.gtm-menu.gtm-menu--bp-sm[data-desktop-trigger="hover"] .gtm-menu__item:focus-within > .gtm-menu__submenu,
	.gtm-menu.gtm-menu--bp-sm .gtm-menu__item:hover > .gtm-menu__submenu.is-static,
	.gtm-menu.gtm-menu--bp-sm .gtm-menu__item:focus-within > .gtm-menu__submenu.is-static,
	.gtm-menu.gtm-menu--bp-sm .gtm-menu__submenu.is-open:not(.is-static) {
		visibility: visible;
		opacity: 1;
		transition:
			opacity var(--gtm-duration) var(--gtm-easing),
			visibility 0s;
	}

	/* Inside a dropdown the entries stack again, so the mobile link geometry is
	   the right one - full width, its own row. */
	.gtm-menu.gtm-menu--bp-sm .gtm-menu__submenu .gtm-menu__link {
		flex: 1 1 auto;
		padding-inline: var(--gtm-panel-pad-x);
		white-space: normal;
	}

	/* ==========================================================================
	   Chevrons
	   ========================================================================== */

	/*
	 * `:not(.gtm-menu--icon-plusminus)` guards every rule in this section, and it is
	 * not defensive tidiness.
	 *
	 * The plus/minus variant is not a chevron that points somewhere - it is two bars
	 * in a box that deliberately carries `transform: none`, because the box must not
	 * turn at all. These rules out-specify that `none` by several classes, so without
	 * the guard they turned the plus 45 degrees and it rendered as a multiplication
	 * sign, at every width above the breakpoint, in both trigger modes. Measured, not
	 * guessed: the element resolved `rotate(45deg)` where the variant had asked for
	 * nothing.
	 *
	 * Direction says where the branch opens: down at the top level, sideways below
	 * it. Every transform here restates the whole thing and puts the 25% nudge on the
	 * axis it points down - the compensation for a rotated square's ink sitting
	 * lopsided in its own box. The wrong axis moves the glyph off the text instead of
	 * centring it; see the base chevron rule in the mobile layer.
	 */
	.gtm-menu.gtm-menu--bp-sm:not(.gtm-menu--icon-plusminus) .gtm-menu__panel-body > .gtm-menu__list > .gtm-menu__item > .gtm-menu__row .gtm-menu__chevron {
		transform: translateY(-25%) rotate(45deg);
	}

	/*
	 * Open, at the top level: the chevron turns to point back up at the bar.
	 *
	 * A half turn here, where the accordion takes a quarter, and the difference is
	 * the affordance. An accordion unfolds a branch *below* the row, so pointing down
	 * describes where the content went; a dropdown is already below by construction,
	 * so down would say nothing and up is the only thing left to say - "this is the
	 * one that is open, press again to close it". It is also what every other
	 * dropdown on the web does, which counts for more than symmetry with the mobile
	 * layer nobody sees at the same time.
	 *
	 * Three ways in, because "open" has no single expression here. Hover mode never
	 * touches `aria-expanded` - the branch opens in CSS - so the state has to be read
	 * off the item, and `:focus-within` is what makes the turn happen for a keyboard
	 * as well. Click mode has a real button with a real `aria-expanded`, and reads it.
	 */
	.gtm-menu.gtm-menu--bp-sm:not(.gtm-menu--icon-plusminus)[data-desktop-trigger="hover"] .gtm-menu__panel-body > .gtm-menu__list > .gtm-menu__item:hover > .gtm-menu__row .gtm-menu__chevron,
	.gtm-menu.gtm-menu--bp-sm:not(.gtm-menu--icon-plusminus)[data-desktop-trigger="hover"] .gtm-menu__panel-body > .gtm-menu__list > .gtm-menu__item:focus-within > .gtm-menu__row .gtm-menu__chevron,
	.gtm-menu.gtm-menu--bp-sm:not(.gtm-menu--icon-plusminus) .gtm-menu__panel-body > .gtm-menu__list > .gtm-menu__item > .gtm-menu__row [aria-expanded="true"] .gtm-menu__chevron {
		transform: translateY(25%) rotate(-135deg);
	}

	/* Below the first level a branch opens beside its parent, so the chevron already
	   points where the content will appear and has nothing to say when it opens. */
	.gtm-menu.gtm-menu--bp-sm:not(.gtm-menu--icon-plusminus) .gtm-menu__submenu .gtm-menu__chevron {
		transform: translateX(-25%) rotate(-45deg);
	}

	/*
	 * The plus becomes a minus, by the same three ways in.
	 *
	 * The mobile layer already draws this - the minus is the plus with one bar laid
	 * flat - but it hangs the change on `aria-expanded`, which hover mode never sets.
	 * Only the open state needs restating here; the closed one is the variant's own,
	 * and the guard above is what leaves it alone.
	 */
	.gtm-menu.gtm-menu--bp-sm.gtm-menu--icon-plusminus[data-desktop-trigger="hover"] .gtm-menu__item:hover > .gtm-menu__row .gtm-menu__chevron:not(.gtm-menu__chevron--back)::after,
	.gtm-menu.gtm-menu--bp-sm.gtm-menu--icon-plusminus[data-desktop-trigger="hover"] .gtm-menu__item:focus-within > .gtm-menu__row .gtm-menu__chevron:not(.gtm-menu__chevron--back)::after,
	.gtm-menu.gtm-menu--bp-sm.gtm-menu--icon-plusminus .gtm-menu__row [aria-expanded="true"] .gtm-menu__chevron:not(.gtm-menu__chevron--back)::after {
		transform: rotate(0deg);
	}
}

/* ==========================================================================
   Desktop layer - md (768px and up)
   Generated from gtmmenu.desktop.css. Edit that file, not this one.
   ========================================================================== */

@media (min-width: 768px) {
	/* ==========================================================================
	   Desktop layer - THE SOURCE, written once

	   This file is expanded five times into media/css/gtmmenu.css, once per named
	   breakpoint, by tools/build-css.py. Write `.gtm-menu--bp-md` and the generator
	   emits `.gtm-menu--bp-sm` ... `.gtm-menu--bp-xxl`, each inside its own query.
	   Never write a suffixed class here.

	   Two rules hold this file together.

	   1. EVERY selector starts with `.gtm-menu.gtm-menu--bp-md`, root doubled. Not
	      decoration: the mobile layer scopes its patterns at (0,2,0) and, in one
	      case, at (0,3,0) - `.gtm-menu.gtm-menu--overlay .gtm-menu__link` doubles
	      its own root for exactly the same reason. A single root here would put
	      this layer at (0,2,0), where it would lose to the pattern it is meant to
	      replace, and the loss would depend on which rule happened to sit lower in
	      the file. Doubling puts the floor at (0,3,0), which beats every pattern
	      rule outright and ties only with that one - and ties fall this way, since
	      the generated file appends this block last.

	   2. CANCEL SHORTHANDS WITH SHORTHANDS. The patterns position their panels with
	      `inset: 0`. Overriding it with `inset-block-start` alone leaves the other
	      three sides live, and the box silently stretches to the corner the mobile
	      layer chose. Every reset below therefore restates the whole `inset`.

	   What is deliberately NOT here: no burger at any width above the breakpoint,
	   so nothing in this file gives the toggle a desktop variant - its colour,
	   shape, alignment and spacing stay mobile-only settings. The logo does survive
	   the breakpoint, which is why it has two sets of everything.
	   ========================================================================== */

	/*
	 * The frame becomes the row, and the bar stops being a box.
	 *
	 * `display: contents` on the bar promotes the logo to a direct flex item of the
	 * frame, sitting beside the panel. That is what makes the three alignments mean
	 * anything: each one distributes the space *after* the logo. Keep the bar as a
	 * real box and the panel has to be positioned over it instead, at which point
	 * "aligned to the logo" would render as "underneath the logo".
	 *
	 * The frame also inherits what the bar used to carry - the padding, the gap, the
	 * stacking level. The stacking level is the one that is not cosmetic: .gtm-menu
	 * is positioned without a z-index, so it paints where document order alone
	 * decides, and any positioned element further down the page paints over it. The
	 * bar carries `--gtm-z + 2` for that reason at mobile widths; here the whole row
	 * needs it, dropdowns included.
	 *
	 * Why the frame rather than the nav: the fixed mode below has to take the whole
	 * row out of the flow, and a fixed box reserves no height. The nav has to stay
	 * in the flow to go on doing that, so it cannot be the thing that gets fixed.
	 */
	.gtm-menu.gtm-menu--bp-md {
		/*
		 * Desktop-only tokens. Declared on the nav rather than the frame so the
		 * generated per-instance sheet has a stable place to override them from
		 * inside its own media query, and inside the breakpoint so they cannot leak
		 * down to mobile.
		 */
		/*
		 * The link's own padding, rather than the mobile `--gtm-link-pad-y`. That
		 * token is rewritten by the overlay pattern on the panel body, so reading it
		 * here would make a desktop row's height depend on which mobile pattern
		 * happens to be selected.
		 */
		--gtm-desktop-link-pad-y: 0.5rem;
		--gtm-desktop-link-pad-x: 0.875rem;
		--gtm-desktop-item-gap: 0rem;
		--gtm-desktop-dropdown-min-width: 12rem;

		/*
		 * What a dropdown uses instead of the bar's own values. Each one defaults to
		 * the matching entry token, so a dropdown follows the bar until somebody says
		 * otherwise and no setting is needed to keep things as they are.
		 *
		 * No cycle here, although it reads like one: this is the nav, where
		 * `--gtm-font-size` is a real value; the substitution below happens on the
		 * dropdown, against the value it inherited from here.
		 */
		--gtm-desktop-dropdown-font-size: var(--gtm-font-size);
		--gtm-desktop-dropdown-link-color: var(--gtm-link-color);
		--gtm-desktop-dropdown-link-color-hover: var(--gtm-link-color-hover);
		--gtm-desktop-dropdown-link-color-current: var(--gtm-link-color-current);

		/*
		 * How far the dropdown sits below the bar. Zero means flush with the bottom
		 * of the band; a negative value pulls it up into the bar, which is what a
		 * bar with an elliptical rounding needs - its bottom edge is a curve, so
		 * "flush" is a different number at each end and the box has to overlap the
		 * shallow side to close the gap on the deep one.
		 */
		--gtm-desktop-dropdown-offset: 0px;
		--gtm-desktop-dropdown-shadow: 0 8px 24px rgba(0, 0, 0, 0.16);
	}

	.gtm-menu.gtm-menu--bp-md .gtm-menu__frame {
		position: relative;
		z-index: calc(var(--gtm-z) + 2);
		display: flex;
		align-items: center;
		gap: var(--gtm-bar-gap);

		/*
		 * Capped, exactly as the bar caps itself below the breakpoint - and the cap
		 * is what keeps the page from starting a logo's height further down.
		 *
		 * Without it the row is as tall as its tallest item, which is the logo, so a
		 * 253px logo over a 70px band reserved 253px of flow and left 183px of empty
		 * page under the colour. Measured on the site, and reported as such.
		 *
		 * The logo goes on overhanging because `margin-block: auto` on it resolves to
		 * zero once it no longer fits, dropping the overhang below the band where it
		 * shows. That is the same mechanism the bar has always relied on; copying the
		 * declaration rather than inventing a second way to say it is the point.
		 *
		 * `auto` when no bar height is set, so "let the content decide" still means
		 * what it means everywhere else.
		 */
		height: var(--gtm-bar-height, auto);
		min-height: var(--gtm-tap-size);
		padding-inline: var(--gtm-bar-pad-x);

		/*
		 * The row spans the full width whether or not it has anything to put there,
		 * so its own box catches nothing and every interactive descendant takes its
		 * clicks back. Same reasoning as the bar's at mobile widths, and it matters
		 * more here: the empty half of a right-aligned menu sits directly over a
		 * hero or a slider.
		 */
		pointer-events: none;
	}

	/*
	 * The painted band moves up to the frame, because the bar no longer has a box to
	 * paint it on - and a band the width of the logo is not a band.
	 *
	 * Declared exactly as the bar's is, over-constraint included: `inset-block: 0`
	 * together with a height resolves in the band's favour, dropping the bottom
	 * inset, so `auto` stretches to the full row and a length pins the band to the
	 * top. Any simplification here changes what an unset bar height means.
	 */
	.gtm-menu.gtm-menu--bp-md .gtm-menu__frame::before {
		content: '';
		position: absolute;
		inset-block: 0;
		inset-inline: 0;
		z-index: -1;
		height: var(--gtm-bar-height, auto);
		background-color: var(--gtm-bar-bg);
		border-radius: var(--gtm-bar-radius);
		pointer-events: none;
	}

	.gtm-menu.gtm-menu--bp-md .gtm-menu__bar {
		display: contents;
	}

	/* Whether a `display: contents` element still generates its pseudo-elements is
	   not something to leave to the browser: cancelled explicitly, or the band
	   risks being painted twice - once at the row's width, once at the logo's. */
	.gtm-menu.gtm-menu--bp-md .gtm-menu__bar::before {
		content: none;
	}

	/*
	 * The burger goes, and with it everything that only ever served it. The panel
	 * head belongs to the drill-down, which has no meaning once every level is a
	 * dropdown; the backdrop dims a page behind a floating panel, and nothing
	 * floats here.
	 *
	 * `display: none` at (0,3,0) also settles the fixed-toggle variant, which pins
	 * the button to the viewport at (0,2,0) - a burger left fixed above the
	 * breakpoint would hang in the corner over a menu that already shows every
	 * entry.
	 */
	.gtm-menu.gtm-menu--bp-md .gtm-menu__toggle,
	.gtm-menu.gtm-menu--bp-md .gtm-menu__backdrop,
	.gtm-menu.gtm-menu--bp-md .gtm-menu__panel-head {
		display: none;
	}

	/*
	 * A fixed row fixes the frame, not the bar - the bar has no box left to fix,
	 * and the panel would not follow it if it had. The mobile rule targets the bar
	 * at (0,2,0) and simply stops applying once the bar is `display: contents`.
	 *
	 * The nav stays exactly where it was, so `--reserve` goes on reserving the
	 * height through its own `min-height`, unchanged and untouched.
	 */
	.gtm-menu.gtm-menu--bp-md.gtm-menu--fixed .gtm-menu__frame {
		position: fixed;
		inset: 0 0 auto;
	}

	.gtm-menu.gtm-menu--bp-md .gtm-menu__brand {
		flex: 0 0 auto;
	}

	/* ==========================================================================
	   The panel becomes the row of entries
	   ========================================================================== */

	/*
	 * Everything the three patterns did to this box is undone in one place: the
	 * off-canvas fixes it to a side and gives it a width, the overlay stretches it
	 * over the viewport and fades it in, the inline pattern collapses it with a
	 * zero grid row. Undoing them piecemeal, pattern by pattern, would mean three
	 * near-identical blocks and a fourth the day a pattern is added.
	 *
	 * `inset` and `transform` are restated whole for the reason at the top of this
	 * file. `min-width: 0` lets a long menu shrink rather than push the logo off
	 * the row - flex items refuse to go below their content width without it.
	 */
	.gtm-menu.gtm-menu--bp-md .gtm-menu__panel {
		position: static;
		z-index: auto;
		display: flex;
		flex: 1 1 auto;

		/*
		 * The entries centre on the painted band, not on the row.
		 *
		 * The row is as tall as its tallest item, which is the logo - and a logo is
		 * routinely taller than the band, since that overhang is the whole point of
		 * a separate bar height. Left to `align-items: center` on the row, the
		 * entries centre on the logo instead and hang below the colour: measured at
		 * 90px down a 180px row against a 100px band, half of every label off the
		 * band. So the panel takes the band's height, pinned to the top, and centres
		 * inside that.
		 *
		 * `--gtm-bar-band` is the same token the bar's own height and the fixed
		 * hamburger's insets are computed from - one number, one place.
		 */
		align-self: flex-start;
		height: var(--gtm-bar-band);
		align-items: stretch;
		inset: auto;
		width: auto;
		min-width: 0;
		max-height: none;
		padding: 0;
		background: none;
		visibility: visible;
		opacity: 1;
		transform: none;
		transition: none;
		overflow: visible;
		pointer-events: none;
	}

	/* The alignment setting, and the only thing it touches. Free space lives
	   between the logo and the entries, so this decides which end of it they sit
	   at. */
	.gtm-menu.gtm-menu--bp-md.gtm-menu--menu-end .gtm-menu__panel {
		justify-content: flex-end;
	}

	.gtm-menu.gtm-menu--bp-md.gtm-menu--menu-center .gtm-menu__panel {
		justify-content: center;
	}

	.gtm-menu.gtm-menu--bp-md.gtm-menu--menu-start .gtm-menu__panel {
		justify-content: flex-start;
	}

	.gtm-menu.gtm-menu--bp-md .gtm-menu__panel-inner {
		flex: 0 1 auto;
		flex-direction: row;
		align-items: stretch;
		width: auto;
		min-width: 0;
	}

	/*
	 * The overlay pattern dresses this box for a full-screen sheet - 1.25rem type,
	 * centred text, its own vertical rhythm - and every one of those leaks into a
	 * dropdown, where they read as a mistake. Undone here rather than in a rule
	 * scoped to the overlay, since the next pattern to style the body would leak in
	 * exactly the same way.
	 */
	.gtm-menu.gtm-menu--bp-md .gtm-menu__panel-body {
		display: flex;
		/* Restated because the overlay lays this box out as a column, where
		   `align-items: stretch` stretches across the width instead of the height
		   and the chain quietly stops here. */
		flex-direction: row;
		flex: 0 1 auto;
		align-items: stretch;
		min-width: 0;
		padding: 0;

		/*
		 * The overlay enlarges its sheet by a factor on this box. Above the
		 * breakpoint there is no sheet - the entries are a row on the bar - so the
		 * factor goes back to 1 and the desktop text size is read as written.
		 */
		--gtm-font-scale: 1;

		font-size: inherit;
		text-align: start;
		overflow: visible;
	}

	/* The top level, and only the top level, lies down. Deeper lists keep the
	   block direction they already had, which is what a dropdown wants.

	   `stretch` rather than `center`, and it is the dropdowns that need it: they
	   hang off `inset-block-start: 100%`, so an item as tall as its label would
	   open them halfway up the band, across the colour. Full-height items put that
	   100% exactly on the band's bottom edge - and give the pointer a taller strip
	   to cross on its way down into the branch. */
	.gtm-menu.gtm-menu--bp-md .gtm-menu__panel-body > .gtm-menu__list {
		display: flex;
		align-items: stretch;
		gap: var(--gtm-desktop-item-gap);

		/*
		 * The overlay centres this list with `margin-block: auto`, and an auto
		 * margin in a flex container swallows the free space before `stretch` ever
		 * sees it - so the list stayed 44px tall inside a 100px band and the
		 * dropdowns opened 28px above it. Cancelling the margin is what lets the
		 * chain of `stretch` above actually reach the items.
		 */
		margin-block: 0;
		height: auto;
		padding: 0;
		overflow: visible;
	}

	/* The label stays its own height inside that full-height item, so the hover
	   background is a pill on the band rather than a full-height block. */
	.gtm-menu.gtm-menu--bp-md .gtm-menu__panel-body > .gtm-menu__list > .gtm-menu__item {
		display: flex;
		align-items: center;
	}

	/* Each parent is the positioning context for its own dropdown. Only parents:
	   giving every item a containing block would cost nothing today and confuse
	   the next person looking for why an item is positioned. */
	.gtm-menu.gtm-menu--bp-md .gtm-menu__item--parent {
		position: relative;
	}

	/* `justify-content` here and on the link below undoes the overlay's centring,
	   which otherwise centres every dropdown entry against its box. */
	.gtm-menu.gtm-menu--bp-md .gtm-menu__row {
		justify-content: flex-start;
		pointer-events: auto;
	}

	/*
	 * A row that no longer fills a column.
	 *
	 * `flex: 0 1 auto` is the shrink-but-do-not-grow the overlay pattern already
	 * uses, and it is what makes an item's width its own content - label, gap and
	 * chevron together - so the spacing between entries stays even. The mobile
	 * default grows the link to fill the row, which is right when rows are stacked
	 * and meaningless when they sit side by side.
	 *
	 * `white-space: nowrap` because a wrapped entry in a horizontal bar reads as
	 * two entries.
	 */
	.gtm-menu.gtm-menu--bp-md .gtm-menu__link {
		flex: 0 1 auto;
		justify-content: flex-start;
		padding-block: var(--gtm-desktop-link-pad-y);
		padding-inline: var(--gtm-desktop-link-pad-x);
		white-space: nowrap;
	}

	/* ==========================================================================
	   Dropdowns
	   ========================================================================== */

	/*
	 * One reset for every sub-menu at every depth, whatever the mobile mode did to
	 * it. The accordion collapses these with `grid-template-rows: 0fr` and an
	 * `overflow: hidden`; the drill-down slides them in from the side with a
	 * transform, at (0,3,0), which is why the root is doubled here as everywhere.
	 *
	 * Hidden with `visibility` rather than `display: none` so the box can be
	 * measured while closed - the flip below needs a width, and a display-none box
	 * has none. The delayed `visibility` transition is the standard trick for
	 * keeping it out of the tab order until the fade finishes.
	 */
	.gtm-menu.gtm-menu--bp-md .gtm-menu__submenu {
		position: absolute;
		inset: calc(100% + var(--gtm-desktop-dropdown-offset)) auto auto 0;
		z-index: 1;
		display: block;
		width: max-content;
		min-width: var(--gtm-desktop-dropdown-min-width);
		max-width: 20rem;
		height: auto;
		padding-block: var(--gtm-panel-pad-y);
		background-color: var(--gtm-panel-bg);
		border-radius: var(--gtm-radius);
		box-shadow: var(--gtm-desktop-dropdown-shadow);
		visibility: hidden;
		opacity: 0;
		transform: none;
		overflow: visible;
		pointer-events: auto;
		transition:
			opacity var(--gtm-duration) var(--gtm-easing),
			visibility 0s linear var(--gtm-duration);
	}

	/*
	 * A dropdown restyles itself by re-pointing the base tokens, not by out-ranking
	 * the rules that read them.
	 *
	 * The alternative was a rule per property, each scoped through `.gtm-menu__submenu`
	 * and each having to beat the one it replaced - and there are more of those than
	 * it first looks: the link, the muted heading with its 0.8125 factor, the plain
	 * heading, the hover state, the current page. Five selectors to write, five
	 * specificities to get right, and a sixth to remember the day another is added.
	 *
	 * Re-declaring the tokens on the box instead means every one of those rules goes
	 * on saying exactly what it said before and quietly reads the dropdown's values
	 * inside the dropdown. Nothing to out-specify, and a rule added later inherits
	 * the behaviour for free.
	 *
	 * The values come from the nav, where they resolved against the bar's own tokens,
	 * so `--gtm-font-size: var(--gtm-desktop-dropdown-font-size)` is a substitution
	 * of an inherited value rather than a self-reference.
	 */
	.gtm-menu.gtm-menu--bp-md .gtm-menu__submenu {
		--gtm-font-size: var(--gtm-desktop-dropdown-font-size);
		--gtm-link-color: var(--gtm-desktop-dropdown-link-color);
		--gtm-link-color-hover: var(--gtm-desktop-dropdown-link-color-hover);
		--gtm-link-color-current: var(--gtm-desktop-dropdown-link-color-current);
	}

	/* A branch below the first opens beside its parent, not under it. */
	.gtm-menu.gtm-menu--bp-md .gtm-menu__submenu .gtm-menu__submenu {
		inset: 0 auto auto 100%;
	}

	/*
	 * A dropdown that would run off the right edge is flipped by the script, which
	 * measures it and adds this class. CSS cannot ask where the viewport ends, and
	 * the alternative - anchoring the last few items to the right on principle -
	 * guesses at how many "the last few" is and is wrong at every other width.
	 */
	.gtm-menu.gtm-menu--bp-md .gtm-menu__submenu--flip {
		inset: calc(100% + var(--gtm-desktop-dropdown-offset)) 0 auto auto;
	}

	.gtm-menu.gtm-menu--bp-md .gtm-menu__submenu .gtm-menu__submenu--flip {
		inset: 0 100% auto auto;
	}

	/*
	 * What opens a dropdown, in the two trigger modes.
	 *
	 * Hover mode answers to the pointer and to the keyboard alike: `:focus-within`
	 * is what lets Tab walk into a branch without the script being involved at all.
	 * Click mode deliberately leaves both out - a branch that opened on focus would
	 * contradict the button the reader just chose not to press - and answers only
	 * to `is-open`, which the script sets.
	 *
	 * `.is-static` is excluded because it carries `is-open` from the markup: the
	 * "link only" parent behaviour leaves branches permanently expanded, which is a
	 * stacked-list idea. Here those branches are ordinary dropdowns, and since that
	 * behaviour prints no button at all, hover is the only affordance they have.
	 */
	.gtm-menu.gtm-menu--bp-md[data-desktop-trigger="hover"] .gtm-menu__item:hover > .gtm-menu__submenu,
	.gtm-menu.gtm-menu--bp-md[data-desktop-trigger="hover"] .gtm-menu__item:focus-within > .gtm-menu__submenu,
	.gtm-menu.gtm-menu--bp-md .gtm-menu__item:hover > .gtm-menu__submenu.is-static,
	.gtm-menu.gtm-menu--bp-md .gtm-menu__item:focus-within > .gtm-menu__submenu.is-static,
	.gtm-menu.gtm-menu--bp-md .gtm-menu__submenu.is-open:not(.is-static) {
		visibility: visible;
		opacity: 1;
		transition:
			opacity var(--gtm-duration) var(--gtm-easing),
			visibility 0s;
	}

	/* Inside a dropdown the entries stack again, so the mobile link geometry is
	   the right one - full width, its own row. */
	.gtm-menu.gtm-menu--bp-md .gtm-menu__submenu .gtm-menu__link {
		flex: 1 1 auto;
		padding-inline: var(--gtm-panel-pad-x);
		white-space: normal;
	}

	/* ==========================================================================
	   Chevrons
	   ========================================================================== */

	/*
	 * `:not(.gtm-menu--icon-plusminus)` guards every rule in this section, and it is
	 * not defensive tidiness.
	 *
	 * The plus/minus variant is not a chevron that points somewhere - it is two bars
	 * in a box that deliberately carries `transform: none`, because the box must not
	 * turn at all. These rules out-specify that `none` by several classes, so without
	 * the guard they turned the plus 45 degrees and it rendered as a multiplication
	 * sign, at every width above the breakpoint, in both trigger modes. Measured, not
	 * guessed: the element resolved `rotate(45deg)` where the variant had asked for
	 * nothing.
	 *
	 * Direction says where the branch opens: down at the top level, sideways below
	 * it. Every transform here restates the whole thing and puts the 25% nudge on the
	 * axis it points down - the compensation for a rotated square's ink sitting
	 * lopsided in its own box. The wrong axis moves the glyph off the text instead of
	 * centring it; see the base chevron rule in the mobile layer.
	 */
	.gtm-menu.gtm-menu--bp-md:not(.gtm-menu--icon-plusminus) .gtm-menu__panel-body > .gtm-menu__list > .gtm-menu__item > .gtm-menu__row .gtm-menu__chevron {
		transform: translateY(-25%) rotate(45deg);
	}

	/*
	 * Open, at the top level: the chevron turns to point back up at the bar.
	 *
	 * A half turn here, where the accordion takes a quarter, and the difference is
	 * the affordance. An accordion unfolds a branch *below* the row, so pointing down
	 * describes where the content went; a dropdown is already below by construction,
	 * so down would say nothing and up is the only thing left to say - "this is the
	 * one that is open, press again to close it". It is also what every other
	 * dropdown on the web does, which counts for more than symmetry with the mobile
	 * layer nobody sees at the same time.
	 *
	 * Three ways in, because "open" has no single expression here. Hover mode never
	 * touches `aria-expanded` - the branch opens in CSS - so the state has to be read
	 * off the item, and `:focus-within` is what makes the turn happen for a keyboard
	 * as well. Click mode has a real button with a real `aria-expanded`, and reads it.
	 */
	.gtm-menu.gtm-menu--bp-md:not(.gtm-menu--icon-plusminus)[data-desktop-trigger="hover"] .gtm-menu__panel-body > .gtm-menu__list > .gtm-menu__item:hover > .gtm-menu__row .gtm-menu__chevron,
	.gtm-menu.gtm-menu--bp-md:not(.gtm-menu--icon-plusminus)[data-desktop-trigger="hover"] .gtm-menu__panel-body > .gtm-menu__list > .gtm-menu__item:focus-within > .gtm-menu__row .gtm-menu__chevron,
	.gtm-menu.gtm-menu--bp-md:not(.gtm-menu--icon-plusminus) .gtm-menu__panel-body > .gtm-menu__list > .gtm-menu__item > .gtm-menu__row [aria-expanded="true"] .gtm-menu__chevron {
		transform: translateY(25%) rotate(-135deg);
	}

	/* Below the first level a branch opens beside its parent, so the chevron already
	   points where the content will appear and has nothing to say when it opens. */
	.gtm-menu.gtm-menu--bp-md:not(.gtm-menu--icon-plusminus) .gtm-menu__submenu .gtm-menu__chevron {
		transform: translateX(-25%) rotate(-45deg);
	}

	/*
	 * The plus becomes a minus, by the same three ways in.
	 *
	 * The mobile layer already draws this - the minus is the plus with one bar laid
	 * flat - but it hangs the change on `aria-expanded`, which hover mode never sets.
	 * Only the open state needs restating here; the closed one is the variant's own,
	 * and the guard above is what leaves it alone.
	 */
	.gtm-menu.gtm-menu--bp-md.gtm-menu--icon-plusminus[data-desktop-trigger="hover"] .gtm-menu__item:hover > .gtm-menu__row .gtm-menu__chevron:not(.gtm-menu__chevron--back)::after,
	.gtm-menu.gtm-menu--bp-md.gtm-menu--icon-plusminus[data-desktop-trigger="hover"] .gtm-menu__item:focus-within > .gtm-menu__row .gtm-menu__chevron:not(.gtm-menu__chevron--back)::after,
	.gtm-menu.gtm-menu--bp-md.gtm-menu--icon-plusminus .gtm-menu__row [aria-expanded="true"] .gtm-menu__chevron:not(.gtm-menu__chevron--back)::after {
		transform: rotate(0deg);
	}
}

/* ==========================================================================
   Desktop layer - lg (992px and up)
   Generated from gtmmenu.desktop.css. Edit that file, not this one.
   ========================================================================== */

@media (min-width: 992px) {
	/* ==========================================================================
	   Desktop layer - THE SOURCE, written once

	   This file is expanded five times into media/css/gtmmenu.css, once per named
	   breakpoint, by tools/build-css.py. Write `.gtm-menu--bp-lg` and the generator
	   emits `.gtm-menu--bp-sm` ... `.gtm-menu--bp-xxl`, each inside its own query.
	   Never write a suffixed class here.

	   Two rules hold this file together.

	   1. EVERY selector starts with `.gtm-menu.gtm-menu--bp-lg`, root doubled. Not
	      decoration: the mobile layer scopes its patterns at (0,2,0) and, in one
	      case, at (0,3,0) - `.gtm-menu.gtm-menu--overlay .gtm-menu__link` doubles
	      its own root for exactly the same reason. A single root here would put
	      this layer at (0,2,0), where it would lose to the pattern it is meant to
	      replace, and the loss would depend on which rule happened to sit lower in
	      the file. Doubling puts the floor at (0,3,0), which beats every pattern
	      rule outright and ties only with that one - and ties fall this way, since
	      the generated file appends this block last.

	   2. CANCEL SHORTHANDS WITH SHORTHANDS. The patterns position their panels with
	      `inset: 0`. Overriding it with `inset-block-start` alone leaves the other
	      three sides live, and the box silently stretches to the corner the mobile
	      layer chose. Every reset below therefore restates the whole `inset`.

	   What is deliberately NOT here: no burger at any width above the breakpoint,
	   so nothing in this file gives the toggle a desktop variant - its colour,
	   shape, alignment and spacing stay mobile-only settings. The logo does survive
	   the breakpoint, which is why it has two sets of everything.
	   ========================================================================== */

	/*
	 * The frame becomes the row, and the bar stops being a box.
	 *
	 * `display: contents` on the bar promotes the logo to a direct flex item of the
	 * frame, sitting beside the panel. That is what makes the three alignments mean
	 * anything: each one distributes the space *after* the logo. Keep the bar as a
	 * real box and the panel has to be positioned over it instead, at which point
	 * "aligned to the logo" would render as "underneath the logo".
	 *
	 * The frame also inherits what the bar used to carry - the padding, the gap, the
	 * stacking level. The stacking level is the one that is not cosmetic: .gtm-menu
	 * is positioned without a z-index, so it paints where document order alone
	 * decides, and any positioned element further down the page paints over it. The
	 * bar carries `--gtm-z + 2` for that reason at mobile widths; here the whole row
	 * needs it, dropdowns included.
	 *
	 * Why the frame rather than the nav: the fixed mode below has to take the whole
	 * row out of the flow, and a fixed box reserves no height. The nav has to stay
	 * in the flow to go on doing that, so it cannot be the thing that gets fixed.
	 */
	.gtm-menu.gtm-menu--bp-lg {
		/*
		 * Desktop-only tokens. Declared on the nav rather than the frame so the
		 * generated per-instance sheet has a stable place to override them from
		 * inside its own media query, and inside the breakpoint so they cannot leak
		 * down to mobile.
		 */
		/*
		 * The link's own padding, rather than the mobile `--gtm-link-pad-y`. That
		 * token is rewritten by the overlay pattern on the panel body, so reading it
		 * here would make a desktop row's height depend on which mobile pattern
		 * happens to be selected.
		 */
		--gtm-desktop-link-pad-y: 0.5rem;
		--gtm-desktop-link-pad-x: 0.875rem;
		--gtm-desktop-item-gap: 0rem;
		--gtm-desktop-dropdown-min-width: 12rem;

		/*
		 * What a dropdown uses instead of the bar's own values. Each one defaults to
		 * the matching entry token, so a dropdown follows the bar until somebody says
		 * otherwise and no setting is needed to keep things as they are.
		 *
		 * No cycle here, although it reads like one: this is the nav, where
		 * `--gtm-font-size` is a real value; the substitution below happens on the
		 * dropdown, against the value it inherited from here.
		 */
		--gtm-desktop-dropdown-font-size: var(--gtm-font-size);
		--gtm-desktop-dropdown-link-color: var(--gtm-link-color);
		--gtm-desktop-dropdown-link-color-hover: var(--gtm-link-color-hover);
		--gtm-desktop-dropdown-link-color-current: var(--gtm-link-color-current);

		/*
		 * How far the dropdown sits below the bar. Zero means flush with the bottom
		 * of the band; a negative value pulls it up into the bar, which is what a
		 * bar with an elliptical rounding needs - its bottom edge is a curve, so
		 * "flush" is a different number at each end and the box has to overlap the
		 * shallow side to close the gap on the deep one.
		 */
		--gtm-desktop-dropdown-offset: 0px;
		--gtm-desktop-dropdown-shadow: 0 8px 24px rgba(0, 0, 0, 0.16);
	}

	.gtm-menu.gtm-menu--bp-lg .gtm-menu__frame {
		position: relative;
		z-index: calc(var(--gtm-z) + 2);
		display: flex;
		align-items: center;
		gap: var(--gtm-bar-gap);

		/*
		 * Capped, exactly as the bar caps itself below the breakpoint - and the cap
		 * is what keeps the page from starting a logo's height further down.
		 *
		 * Without it the row is as tall as its tallest item, which is the logo, so a
		 * 253px logo over a 70px band reserved 253px of flow and left 183px of empty
		 * page under the colour. Measured on the site, and reported as such.
		 *
		 * The logo goes on overhanging because `margin-block: auto` on it resolves to
		 * zero once it no longer fits, dropping the overhang below the band where it
		 * shows. That is the same mechanism the bar has always relied on; copying the
		 * declaration rather than inventing a second way to say it is the point.
		 *
		 * `auto` when no bar height is set, so "let the content decide" still means
		 * what it means everywhere else.
		 */
		height: var(--gtm-bar-height, auto);
		min-height: var(--gtm-tap-size);
		padding-inline: var(--gtm-bar-pad-x);

		/*
		 * The row spans the full width whether or not it has anything to put there,
		 * so its own box catches nothing and every interactive descendant takes its
		 * clicks back. Same reasoning as the bar's at mobile widths, and it matters
		 * more here: the empty half of a right-aligned menu sits directly over a
		 * hero or a slider.
		 */
		pointer-events: none;
	}

	/*
	 * The painted band moves up to the frame, because the bar no longer has a box to
	 * paint it on - and a band the width of the logo is not a band.
	 *
	 * Declared exactly as the bar's is, over-constraint included: `inset-block: 0`
	 * together with a height resolves in the band's favour, dropping the bottom
	 * inset, so `auto` stretches to the full row and a length pins the band to the
	 * top. Any simplification here changes what an unset bar height means.
	 */
	.gtm-menu.gtm-menu--bp-lg .gtm-menu__frame::before {
		content: '';
		position: absolute;
		inset-block: 0;
		inset-inline: 0;
		z-index: -1;
		height: var(--gtm-bar-height, auto);
		background-color: var(--gtm-bar-bg);
		border-radius: var(--gtm-bar-radius);
		pointer-events: none;
	}

	.gtm-menu.gtm-menu--bp-lg .gtm-menu__bar {
		display: contents;
	}

	/* Whether a `display: contents` element still generates its pseudo-elements is
	   not something to leave to the browser: cancelled explicitly, or the band
	   risks being painted twice - once at the row's width, once at the logo's. */
	.gtm-menu.gtm-menu--bp-lg .gtm-menu__bar::before {
		content: none;
	}

	/*
	 * The burger goes, and with it everything that only ever served it. The panel
	 * head belongs to the drill-down, which has no meaning once every level is a
	 * dropdown; the backdrop dims a page behind a floating panel, and nothing
	 * floats here.
	 *
	 * `display: none` at (0,3,0) also settles the fixed-toggle variant, which pins
	 * the button to the viewport at (0,2,0) - a burger left fixed above the
	 * breakpoint would hang in the corner over a menu that already shows every
	 * entry.
	 */
	.gtm-menu.gtm-menu--bp-lg .gtm-menu__toggle,
	.gtm-menu.gtm-menu--bp-lg .gtm-menu__backdrop,
	.gtm-menu.gtm-menu--bp-lg .gtm-menu__panel-head {
		display: none;
	}

	/*
	 * A fixed row fixes the frame, not the bar - the bar has no box left to fix,
	 * and the panel would not follow it if it had. The mobile rule targets the bar
	 * at (0,2,0) and simply stops applying once the bar is `display: contents`.
	 *
	 * The nav stays exactly where it was, so `--reserve` goes on reserving the
	 * height through its own `min-height`, unchanged and untouched.
	 */
	.gtm-menu.gtm-menu--bp-lg.gtm-menu--fixed .gtm-menu__frame {
		position: fixed;
		inset: 0 0 auto;
	}

	.gtm-menu.gtm-menu--bp-lg .gtm-menu__brand {
		flex: 0 0 auto;
	}

	/* ==========================================================================
	   The panel becomes the row of entries
	   ========================================================================== */

	/*
	 * Everything the three patterns did to this box is undone in one place: the
	 * off-canvas fixes it to a side and gives it a width, the overlay stretches it
	 * over the viewport and fades it in, the inline pattern collapses it with a
	 * zero grid row. Undoing them piecemeal, pattern by pattern, would mean three
	 * near-identical blocks and a fourth the day a pattern is added.
	 *
	 * `inset` and `transform` are restated whole for the reason at the top of this
	 * file. `min-width: 0` lets a long menu shrink rather than push the logo off
	 * the row - flex items refuse to go below their content width without it.
	 */
	.gtm-menu.gtm-menu--bp-lg .gtm-menu__panel {
		position: static;
		z-index: auto;
		display: flex;
		flex: 1 1 auto;

		/*
		 * The entries centre on the painted band, not on the row.
		 *
		 * The row is as tall as its tallest item, which is the logo - and a logo is
		 * routinely taller than the band, since that overhang is the whole point of
		 * a separate bar height. Left to `align-items: center` on the row, the
		 * entries centre on the logo instead and hang below the colour: measured at
		 * 90px down a 180px row against a 100px band, half of every label off the
		 * band. So the panel takes the band's height, pinned to the top, and centres
		 * inside that.
		 *
		 * `--gtm-bar-band` is the same token the bar's own height and the fixed
		 * hamburger's insets are computed from - one number, one place.
		 */
		align-self: flex-start;
		height: var(--gtm-bar-band);
		align-items: stretch;
		inset: auto;
		width: auto;
		min-width: 0;
		max-height: none;
		padding: 0;
		background: none;
		visibility: visible;
		opacity: 1;
		transform: none;
		transition: none;
		overflow: visible;
		pointer-events: none;
	}

	/* The alignment setting, and the only thing it touches. Free space lives
	   between the logo and the entries, so this decides which end of it they sit
	   at. */
	.gtm-menu.gtm-menu--bp-lg.gtm-menu--menu-end .gtm-menu__panel {
		justify-content: flex-end;
	}

	.gtm-menu.gtm-menu--bp-lg.gtm-menu--menu-center .gtm-menu__panel {
		justify-content: center;
	}

	.gtm-menu.gtm-menu--bp-lg.gtm-menu--menu-start .gtm-menu__panel {
		justify-content: flex-start;
	}

	.gtm-menu.gtm-menu--bp-lg .gtm-menu__panel-inner {
		flex: 0 1 auto;
		flex-direction: row;
		align-items: stretch;
		width: auto;
		min-width: 0;
	}

	/*
	 * The overlay pattern dresses this box for a full-screen sheet - 1.25rem type,
	 * centred text, its own vertical rhythm - and every one of those leaks into a
	 * dropdown, where they read as a mistake. Undone here rather than in a rule
	 * scoped to the overlay, since the next pattern to style the body would leak in
	 * exactly the same way.
	 */
	.gtm-menu.gtm-menu--bp-lg .gtm-menu__panel-body {
		display: flex;
		/* Restated because the overlay lays this box out as a column, where
		   `align-items: stretch` stretches across the width instead of the height
		   and the chain quietly stops here. */
		flex-direction: row;
		flex: 0 1 auto;
		align-items: stretch;
		min-width: 0;
		padding: 0;

		/*
		 * The overlay enlarges its sheet by a factor on this box. Above the
		 * breakpoint there is no sheet - the entries are a row on the bar - so the
		 * factor goes back to 1 and the desktop text size is read as written.
		 */
		--gtm-font-scale: 1;

		font-size: inherit;
		text-align: start;
		overflow: visible;
	}

	/* The top level, and only the top level, lies down. Deeper lists keep the
	   block direction they already had, which is what a dropdown wants.

	   `stretch` rather than `center`, and it is the dropdowns that need it: they
	   hang off `inset-block-start: 100%`, so an item as tall as its label would
	   open them halfway up the band, across the colour. Full-height items put that
	   100% exactly on the band's bottom edge - and give the pointer a taller strip
	   to cross on its way down into the branch. */
	.gtm-menu.gtm-menu--bp-lg .gtm-menu__panel-body > .gtm-menu__list {
		display: flex;
		align-items: stretch;
		gap: var(--gtm-desktop-item-gap);

		/*
		 * The overlay centres this list with `margin-block: auto`, and an auto
		 * margin in a flex container swallows the free space before `stretch` ever
		 * sees it - so the list stayed 44px tall inside a 100px band and the
		 * dropdowns opened 28px above it. Cancelling the margin is what lets the
		 * chain of `stretch` above actually reach the items.
		 */
		margin-block: 0;
		height: auto;
		padding: 0;
		overflow: visible;
	}

	/* The label stays its own height inside that full-height item, so the hover
	   background is a pill on the band rather than a full-height block. */
	.gtm-menu.gtm-menu--bp-lg .gtm-menu__panel-body > .gtm-menu__list > .gtm-menu__item {
		display: flex;
		align-items: center;
	}

	/* Each parent is the positioning context for its own dropdown. Only parents:
	   giving every item a containing block would cost nothing today and confuse
	   the next person looking for why an item is positioned. */
	.gtm-menu.gtm-menu--bp-lg .gtm-menu__item--parent {
		position: relative;
	}

	/* `justify-content` here and on the link below undoes the overlay's centring,
	   which otherwise centres every dropdown entry against its box. */
	.gtm-menu.gtm-menu--bp-lg .gtm-menu__row {
		justify-content: flex-start;
		pointer-events: auto;
	}

	/*
	 * A row that no longer fills a column.
	 *
	 * `flex: 0 1 auto` is the shrink-but-do-not-grow the overlay pattern already
	 * uses, and it is what makes an item's width its own content - label, gap and
	 * chevron together - so the spacing between entries stays even. The mobile
	 * default grows the link to fill the row, which is right when rows are stacked
	 * and meaningless when they sit side by side.
	 *
	 * `white-space: nowrap` because a wrapped entry in a horizontal bar reads as
	 * two entries.
	 */
	.gtm-menu.gtm-menu--bp-lg .gtm-menu__link {
		flex: 0 1 auto;
		justify-content: flex-start;
		padding-block: var(--gtm-desktop-link-pad-y);
		padding-inline: var(--gtm-desktop-link-pad-x);
		white-space: nowrap;
	}

	/* ==========================================================================
	   Dropdowns
	   ========================================================================== */

	/*
	 * One reset for every sub-menu at every depth, whatever the mobile mode did to
	 * it. The accordion collapses these with `grid-template-rows: 0fr` and an
	 * `overflow: hidden`; the drill-down slides them in from the side with a
	 * transform, at (0,3,0), which is why the root is doubled here as everywhere.
	 *
	 * Hidden with `visibility` rather than `display: none` so the box can be
	 * measured while closed - the flip below needs a width, and a display-none box
	 * has none. The delayed `visibility` transition is the standard trick for
	 * keeping it out of the tab order until the fade finishes.
	 */
	.gtm-menu.gtm-menu--bp-lg .gtm-menu__submenu {
		position: absolute;
		inset: calc(100% + var(--gtm-desktop-dropdown-offset)) auto auto 0;
		z-index: 1;
		display: block;
		width: max-content;
		min-width: var(--gtm-desktop-dropdown-min-width);
		max-width: 20rem;
		height: auto;
		padding-block: var(--gtm-panel-pad-y);
		background-color: var(--gtm-panel-bg);
		border-radius: var(--gtm-radius);
		box-shadow: var(--gtm-desktop-dropdown-shadow);
		visibility: hidden;
		opacity: 0;
		transform: none;
		overflow: visible;
		pointer-events: auto;
		transition:
			opacity var(--gtm-duration) var(--gtm-easing),
			visibility 0s linear var(--gtm-duration);
	}

	/*
	 * A dropdown restyles itself by re-pointing the base tokens, not by out-ranking
	 * the rules that read them.
	 *
	 * The alternative was a rule per property, each scoped through `.gtm-menu__submenu`
	 * and each having to beat the one it replaced - and there are more of those than
	 * it first looks: the link, the muted heading with its 0.8125 factor, the plain
	 * heading, the hover state, the current page. Five selectors to write, five
	 * specificities to get right, and a sixth to remember the day another is added.
	 *
	 * Re-declaring the tokens on the box instead means every one of those rules goes
	 * on saying exactly what it said before and quietly reads the dropdown's values
	 * inside the dropdown. Nothing to out-specify, and a rule added later inherits
	 * the behaviour for free.
	 *
	 * The values come from the nav, where they resolved against the bar's own tokens,
	 * so `--gtm-font-size: var(--gtm-desktop-dropdown-font-size)` is a substitution
	 * of an inherited value rather than a self-reference.
	 */
	.gtm-menu.gtm-menu--bp-lg .gtm-menu__submenu {
		--gtm-font-size: var(--gtm-desktop-dropdown-font-size);
		--gtm-link-color: var(--gtm-desktop-dropdown-link-color);
		--gtm-link-color-hover: var(--gtm-desktop-dropdown-link-color-hover);
		--gtm-link-color-current: var(--gtm-desktop-dropdown-link-color-current);
	}

	/* A branch below the first opens beside its parent, not under it. */
	.gtm-menu.gtm-menu--bp-lg .gtm-menu__submenu .gtm-menu__submenu {
		inset: 0 auto auto 100%;
	}

	/*
	 * A dropdown that would run off the right edge is flipped by the script, which
	 * measures it and adds this class. CSS cannot ask where the viewport ends, and
	 * the alternative - anchoring the last few items to the right on principle -
	 * guesses at how many "the last few" is and is wrong at every other width.
	 */
	.gtm-menu.gtm-menu--bp-lg .gtm-menu__submenu--flip {
		inset: calc(100% + var(--gtm-desktop-dropdown-offset)) 0 auto auto;
	}

	.gtm-menu.gtm-menu--bp-lg .gtm-menu__submenu .gtm-menu__submenu--flip {
		inset: 0 100% auto auto;
	}

	/*
	 * What opens a dropdown, in the two trigger modes.
	 *
	 * Hover mode answers to the pointer and to the keyboard alike: `:focus-within`
	 * is what lets Tab walk into a branch without the script being involved at all.
	 * Click mode deliberately leaves both out - a branch that opened on focus would
	 * contradict the button the reader just chose not to press - and answers only
	 * to `is-open`, which the script sets.
	 *
	 * `.is-static` is excluded because it carries `is-open` from the markup: the
	 * "link only" parent behaviour leaves branches permanently expanded, which is a
	 * stacked-list idea. Here those branches are ordinary dropdowns, and since that
	 * behaviour prints no button at all, hover is the only affordance they have.
	 */
	.gtm-menu.gtm-menu--bp-lg[data-desktop-trigger="hover"] .gtm-menu__item:hover > .gtm-menu__submenu,
	.gtm-menu.gtm-menu--bp-lg[data-desktop-trigger="hover"] .gtm-menu__item:focus-within > .gtm-menu__submenu,
	.gtm-menu.gtm-menu--bp-lg .gtm-menu__item:hover > .gtm-menu__submenu.is-static,
	.gtm-menu.gtm-menu--bp-lg .gtm-menu__item:focus-within > .gtm-menu__submenu.is-static,
	.gtm-menu.gtm-menu--bp-lg .gtm-menu__submenu.is-open:not(.is-static) {
		visibility: visible;
		opacity: 1;
		transition:
			opacity var(--gtm-duration) var(--gtm-easing),
			visibility 0s;
	}

	/* Inside a dropdown the entries stack again, so the mobile link geometry is
	   the right one - full width, its own row. */
	.gtm-menu.gtm-menu--bp-lg .gtm-menu__submenu .gtm-menu__link {
		flex: 1 1 auto;
		padding-inline: var(--gtm-panel-pad-x);
		white-space: normal;
	}

	/* ==========================================================================
	   Chevrons
	   ========================================================================== */

	/*
	 * `:not(.gtm-menu--icon-plusminus)` guards every rule in this section, and it is
	 * not defensive tidiness.
	 *
	 * The plus/minus variant is not a chevron that points somewhere - it is two bars
	 * in a box that deliberately carries `transform: none`, because the box must not
	 * turn at all. These rules out-specify that `none` by several classes, so without
	 * the guard they turned the plus 45 degrees and it rendered as a multiplication
	 * sign, at every width above the breakpoint, in both trigger modes. Measured, not
	 * guessed: the element resolved `rotate(45deg)` where the variant had asked for
	 * nothing.
	 *
	 * Direction says where the branch opens: down at the top level, sideways below
	 * it. Every transform here restates the whole thing and puts the 25% nudge on the
	 * axis it points down - the compensation for a rotated square's ink sitting
	 * lopsided in its own box. The wrong axis moves the glyph off the text instead of
	 * centring it; see the base chevron rule in the mobile layer.
	 */
	.gtm-menu.gtm-menu--bp-lg:not(.gtm-menu--icon-plusminus) .gtm-menu__panel-body > .gtm-menu__list > .gtm-menu__item > .gtm-menu__row .gtm-menu__chevron {
		transform: translateY(-25%) rotate(45deg);
	}

	/*
	 * Open, at the top level: the chevron turns to point back up at the bar.
	 *
	 * A half turn here, where the accordion takes a quarter, and the difference is
	 * the affordance. An accordion unfolds a branch *below* the row, so pointing down
	 * describes where the content went; a dropdown is already below by construction,
	 * so down would say nothing and up is the only thing left to say - "this is the
	 * one that is open, press again to close it". It is also what every other
	 * dropdown on the web does, which counts for more than symmetry with the mobile
	 * layer nobody sees at the same time.
	 *
	 * Three ways in, because "open" has no single expression here. Hover mode never
	 * touches `aria-expanded` - the branch opens in CSS - so the state has to be read
	 * off the item, and `:focus-within` is what makes the turn happen for a keyboard
	 * as well. Click mode has a real button with a real `aria-expanded`, and reads it.
	 */
	.gtm-menu.gtm-menu--bp-lg:not(.gtm-menu--icon-plusminus)[data-desktop-trigger="hover"] .gtm-menu__panel-body > .gtm-menu__list > .gtm-menu__item:hover > .gtm-menu__row .gtm-menu__chevron,
	.gtm-menu.gtm-menu--bp-lg:not(.gtm-menu--icon-plusminus)[data-desktop-trigger="hover"] .gtm-menu__panel-body > .gtm-menu__list > .gtm-menu__item:focus-within > .gtm-menu__row .gtm-menu__chevron,
	.gtm-menu.gtm-menu--bp-lg:not(.gtm-menu--icon-plusminus) .gtm-menu__panel-body > .gtm-menu__list > .gtm-menu__item > .gtm-menu__row [aria-expanded="true"] .gtm-menu__chevron {
		transform: translateY(25%) rotate(-135deg);
	}

	/* Below the first level a branch opens beside its parent, so the chevron already
	   points where the content will appear and has nothing to say when it opens. */
	.gtm-menu.gtm-menu--bp-lg:not(.gtm-menu--icon-plusminus) .gtm-menu__submenu .gtm-menu__chevron {
		transform: translateX(-25%) rotate(-45deg);
	}

	/*
	 * The plus becomes a minus, by the same three ways in.
	 *
	 * The mobile layer already draws this - the minus is the plus with one bar laid
	 * flat - but it hangs the change on `aria-expanded`, which hover mode never sets.
	 * Only the open state needs restating here; the closed one is the variant's own,
	 * and the guard above is what leaves it alone.
	 */
	.gtm-menu.gtm-menu--bp-lg.gtm-menu--icon-plusminus[data-desktop-trigger="hover"] .gtm-menu__item:hover > .gtm-menu__row .gtm-menu__chevron:not(.gtm-menu__chevron--back)::after,
	.gtm-menu.gtm-menu--bp-lg.gtm-menu--icon-plusminus[data-desktop-trigger="hover"] .gtm-menu__item:focus-within > .gtm-menu__row .gtm-menu__chevron:not(.gtm-menu__chevron--back)::after,
	.gtm-menu.gtm-menu--bp-lg.gtm-menu--icon-plusminus .gtm-menu__row [aria-expanded="true"] .gtm-menu__chevron:not(.gtm-menu__chevron--back)::after {
		transform: rotate(0deg);
	}
}

/* ==========================================================================
   Desktop layer - xl (1200px and up)
   Generated from gtmmenu.desktop.css. Edit that file, not this one.
   ========================================================================== */

@media (min-width: 1200px) {
	/* ==========================================================================
	   Desktop layer - THE SOURCE, written once

	   This file is expanded five times into media/css/gtmmenu.css, once per named
	   breakpoint, by tools/build-css.py. Write `.gtm-menu--bp-xl` and the generator
	   emits `.gtm-menu--bp-sm` ... `.gtm-menu--bp-xxl`, each inside its own query.
	   Never write a suffixed class here.

	   Two rules hold this file together.

	   1. EVERY selector starts with `.gtm-menu.gtm-menu--bp-xl`, root doubled. Not
	      decoration: the mobile layer scopes its patterns at (0,2,0) and, in one
	      case, at (0,3,0) - `.gtm-menu.gtm-menu--overlay .gtm-menu__link` doubles
	      its own root for exactly the same reason. A single root here would put
	      this layer at (0,2,0), where it would lose to the pattern it is meant to
	      replace, and the loss would depend on which rule happened to sit lower in
	      the file. Doubling puts the floor at (0,3,0), which beats every pattern
	      rule outright and ties only with that one - and ties fall this way, since
	      the generated file appends this block last.

	   2. CANCEL SHORTHANDS WITH SHORTHANDS. The patterns position their panels with
	      `inset: 0`. Overriding it with `inset-block-start` alone leaves the other
	      three sides live, and the box silently stretches to the corner the mobile
	      layer chose. Every reset below therefore restates the whole `inset`.

	   What is deliberately NOT here: no burger at any width above the breakpoint,
	   so nothing in this file gives the toggle a desktop variant - its colour,
	   shape, alignment and spacing stay mobile-only settings. The logo does survive
	   the breakpoint, which is why it has two sets of everything.
	   ========================================================================== */

	/*
	 * The frame becomes the row, and the bar stops being a box.
	 *
	 * `display: contents` on the bar promotes the logo to a direct flex item of the
	 * frame, sitting beside the panel. That is what makes the three alignments mean
	 * anything: each one distributes the space *after* the logo. Keep the bar as a
	 * real box and the panel has to be positioned over it instead, at which point
	 * "aligned to the logo" would render as "underneath the logo".
	 *
	 * The frame also inherits what the bar used to carry - the padding, the gap, the
	 * stacking level. The stacking level is the one that is not cosmetic: .gtm-menu
	 * is positioned without a z-index, so it paints where document order alone
	 * decides, and any positioned element further down the page paints over it. The
	 * bar carries `--gtm-z + 2` for that reason at mobile widths; here the whole row
	 * needs it, dropdowns included.
	 *
	 * Why the frame rather than the nav: the fixed mode below has to take the whole
	 * row out of the flow, and a fixed box reserves no height. The nav has to stay
	 * in the flow to go on doing that, so it cannot be the thing that gets fixed.
	 */
	.gtm-menu.gtm-menu--bp-xl {
		/*
		 * Desktop-only tokens. Declared on the nav rather than the frame so the
		 * generated per-instance sheet has a stable place to override them from
		 * inside its own media query, and inside the breakpoint so they cannot leak
		 * down to mobile.
		 */
		/*
		 * The link's own padding, rather than the mobile `--gtm-link-pad-y`. That
		 * token is rewritten by the overlay pattern on the panel body, so reading it
		 * here would make a desktop row's height depend on which mobile pattern
		 * happens to be selected.
		 */
		--gtm-desktop-link-pad-y: 0.5rem;
		--gtm-desktop-link-pad-x: 0.875rem;
		--gtm-desktop-item-gap: 0rem;
		--gtm-desktop-dropdown-min-width: 12rem;

		/*
		 * What a dropdown uses instead of the bar's own values. Each one defaults to
		 * the matching entry token, so a dropdown follows the bar until somebody says
		 * otherwise and no setting is needed to keep things as they are.
		 *
		 * No cycle here, although it reads like one: this is the nav, where
		 * `--gtm-font-size` is a real value; the substitution below happens on the
		 * dropdown, against the value it inherited from here.
		 */
		--gtm-desktop-dropdown-font-size: var(--gtm-font-size);
		--gtm-desktop-dropdown-link-color: var(--gtm-link-color);
		--gtm-desktop-dropdown-link-color-hover: var(--gtm-link-color-hover);
		--gtm-desktop-dropdown-link-color-current: var(--gtm-link-color-current);

		/*
		 * How far the dropdown sits below the bar. Zero means flush with the bottom
		 * of the band; a negative value pulls it up into the bar, which is what a
		 * bar with an elliptical rounding needs - its bottom edge is a curve, so
		 * "flush" is a different number at each end and the box has to overlap the
		 * shallow side to close the gap on the deep one.
		 */
		--gtm-desktop-dropdown-offset: 0px;
		--gtm-desktop-dropdown-shadow: 0 8px 24px rgba(0, 0, 0, 0.16);
	}

	.gtm-menu.gtm-menu--bp-xl .gtm-menu__frame {
		position: relative;
		z-index: calc(var(--gtm-z) + 2);
		display: flex;
		align-items: center;
		gap: var(--gtm-bar-gap);

		/*
		 * Capped, exactly as the bar caps itself below the breakpoint - and the cap
		 * is what keeps the page from starting a logo's height further down.
		 *
		 * Without it the row is as tall as its tallest item, which is the logo, so a
		 * 253px logo over a 70px band reserved 253px of flow and left 183px of empty
		 * page under the colour. Measured on the site, and reported as such.
		 *
		 * The logo goes on overhanging because `margin-block: auto` on it resolves to
		 * zero once it no longer fits, dropping the overhang below the band where it
		 * shows. That is the same mechanism the bar has always relied on; copying the
		 * declaration rather than inventing a second way to say it is the point.
		 *
		 * `auto` when no bar height is set, so "let the content decide" still means
		 * what it means everywhere else.
		 */
		height: var(--gtm-bar-height, auto);
		min-height: var(--gtm-tap-size);
		padding-inline: var(--gtm-bar-pad-x);

		/*
		 * The row spans the full width whether or not it has anything to put there,
		 * so its own box catches nothing and every interactive descendant takes its
		 * clicks back. Same reasoning as the bar's at mobile widths, and it matters
		 * more here: the empty half of a right-aligned menu sits directly over a
		 * hero or a slider.
		 */
		pointer-events: none;
	}

	/*
	 * The painted band moves up to the frame, because the bar no longer has a box to
	 * paint it on - and a band the width of the logo is not a band.
	 *
	 * Declared exactly as the bar's is, over-constraint included: `inset-block: 0`
	 * together with a height resolves in the band's favour, dropping the bottom
	 * inset, so `auto` stretches to the full row and a length pins the band to the
	 * top. Any simplification here changes what an unset bar height means.
	 */
	.gtm-menu.gtm-menu--bp-xl .gtm-menu__frame::before {
		content: '';
		position: absolute;
		inset-block: 0;
		inset-inline: 0;
		z-index: -1;
		height: var(--gtm-bar-height, auto);
		background-color: var(--gtm-bar-bg);
		border-radius: var(--gtm-bar-radius);
		pointer-events: none;
	}

	.gtm-menu.gtm-menu--bp-xl .gtm-menu__bar {
		display: contents;
	}

	/* Whether a `display: contents` element still generates its pseudo-elements is
	   not something to leave to the browser: cancelled explicitly, or the band
	   risks being painted twice - once at the row's width, once at the logo's. */
	.gtm-menu.gtm-menu--bp-xl .gtm-menu__bar::before {
		content: none;
	}

	/*
	 * The burger goes, and with it everything that only ever served it. The panel
	 * head belongs to the drill-down, which has no meaning once every level is a
	 * dropdown; the backdrop dims a page behind a floating panel, and nothing
	 * floats here.
	 *
	 * `display: none` at (0,3,0) also settles the fixed-toggle variant, which pins
	 * the button to the viewport at (0,2,0) - a burger left fixed above the
	 * breakpoint would hang in the corner over a menu that already shows every
	 * entry.
	 */
	.gtm-menu.gtm-menu--bp-xl .gtm-menu__toggle,
	.gtm-menu.gtm-menu--bp-xl .gtm-menu__backdrop,
	.gtm-menu.gtm-menu--bp-xl .gtm-menu__panel-head {
		display: none;
	}

	/*
	 * A fixed row fixes the frame, not the bar - the bar has no box left to fix,
	 * and the panel would not follow it if it had. The mobile rule targets the bar
	 * at (0,2,0) and simply stops applying once the bar is `display: contents`.
	 *
	 * The nav stays exactly where it was, so `--reserve` goes on reserving the
	 * height through its own `min-height`, unchanged and untouched.
	 */
	.gtm-menu.gtm-menu--bp-xl.gtm-menu--fixed .gtm-menu__frame {
		position: fixed;
		inset: 0 0 auto;
	}

	.gtm-menu.gtm-menu--bp-xl .gtm-menu__brand {
		flex: 0 0 auto;
	}

	/* ==========================================================================
	   The panel becomes the row of entries
	   ========================================================================== */

	/*
	 * Everything the three patterns did to this box is undone in one place: the
	 * off-canvas fixes it to a side and gives it a width, the overlay stretches it
	 * over the viewport and fades it in, the inline pattern collapses it with a
	 * zero grid row. Undoing them piecemeal, pattern by pattern, would mean three
	 * near-identical blocks and a fourth the day a pattern is added.
	 *
	 * `inset` and `transform` are restated whole for the reason at the top of this
	 * file. `min-width: 0` lets a long menu shrink rather than push the logo off
	 * the row - flex items refuse to go below their content width without it.
	 */
	.gtm-menu.gtm-menu--bp-xl .gtm-menu__panel {
		position: static;
		z-index: auto;
		display: flex;
		flex: 1 1 auto;

		/*
		 * The entries centre on the painted band, not on the row.
		 *
		 * The row is as tall as its tallest item, which is the logo - and a logo is
		 * routinely taller than the band, since that overhang is the whole point of
		 * a separate bar height. Left to `align-items: center` on the row, the
		 * entries centre on the logo instead and hang below the colour: measured at
		 * 90px down a 180px row against a 100px band, half of every label off the
		 * band. So the panel takes the band's height, pinned to the top, and centres
		 * inside that.
		 *
		 * `--gtm-bar-band` is the same token the bar's own height and the fixed
		 * hamburger's insets are computed from - one number, one place.
		 */
		align-self: flex-start;
		height: var(--gtm-bar-band);
		align-items: stretch;
		inset: auto;
		width: auto;
		min-width: 0;
		max-height: none;
		padding: 0;
		background: none;
		visibility: visible;
		opacity: 1;
		transform: none;
		transition: none;
		overflow: visible;
		pointer-events: none;
	}

	/* The alignment setting, and the only thing it touches. Free space lives
	   between the logo and the entries, so this decides which end of it they sit
	   at. */
	.gtm-menu.gtm-menu--bp-xl.gtm-menu--menu-end .gtm-menu__panel {
		justify-content: flex-end;
	}

	.gtm-menu.gtm-menu--bp-xl.gtm-menu--menu-center .gtm-menu__panel {
		justify-content: center;
	}

	.gtm-menu.gtm-menu--bp-xl.gtm-menu--menu-start .gtm-menu__panel {
		justify-content: flex-start;
	}

	.gtm-menu.gtm-menu--bp-xl .gtm-menu__panel-inner {
		flex: 0 1 auto;
		flex-direction: row;
		align-items: stretch;
		width: auto;
		min-width: 0;
	}

	/*
	 * The overlay pattern dresses this box for a full-screen sheet - 1.25rem type,
	 * centred text, its own vertical rhythm - and every one of those leaks into a
	 * dropdown, where they read as a mistake. Undone here rather than in a rule
	 * scoped to the overlay, since the next pattern to style the body would leak in
	 * exactly the same way.
	 */
	.gtm-menu.gtm-menu--bp-xl .gtm-menu__panel-body {
		display: flex;
		/* Restated because the overlay lays this box out as a column, where
		   `align-items: stretch` stretches across the width instead of the height
		   and the chain quietly stops here. */
		flex-direction: row;
		flex: 0 1 auto;
		align-items: stretch;
		min-width: 0;
		padding: 0;

		/*
		 * The overlay enlarges its sheet by a factor on this box. Above the
		 * breakpoint there is no sheet - the entries are a row on the bar - so the
		 * factor goes back to 1 and the desktop text size is read as written.
		 */
		--gtm-font-scale: 1;

		font-size: inherit;
		text-align: start;
		overflow: visible;
	}

	/* The top level, and only the top level, lies down. Deeper lists keep the
	   block direction they already had, which is what a dropdown wants.

	   `stretch` rather than `center`, and it is the dropdowns that need it: they
	   hang off `inset-block-start: 100%`, so an item as tall as its label would
	   open them halfway up the band, across the colour. Full-height items put that
	   100% exactly on the band's bottom edge - and give the pointer a taller strip
	   to cross on its way down into the branch. */
	.gtm-menu.gtm-menu--bp-xl .gtm-menu__panel-body > .gtm-menu__list {
		display: flex;
		align-items: stretch;
		gap: var(--gtm-desktop-item-gap);

		/*
		 * The overlay centres this list with `margin-block: auto`, and an auto
		 * margin in a flex container swallows the free space before `stretch` ever
		 * sees it - so the list stayed 44px tall inside a 100px band and the
		 * dropdowns opened 28px above it. Cancelling the margin is what lets the
		 * chain of `stretch` above actually reach the items.
		 */
		margin-block: 0;
		height: auto;
		padding: 0;
		overflow: visible;
	}

	/* The label stays its own height inside that full-height item, so the hover
	   background is a pill on the band rather than a full-height block. */
	.gtm-menu.gtm-menu--bp-xl .gtm-menu__panel-body > .gtm-menu__list > .gtm-menu__item {
		display: flex;
		align-items: center;
	}

	/* Each parent is the positioning context for its own dropdown. Only parents:
	   giving every item a containing block would cost nothing today and confuse
	   the next person looking for why an item is positioned. */
	.gtm-menu.gtm-menu--bp-xl .gtm-menu__item--parent {
		position: relative;
	}

	/* `justify-content` here and on the link below undoes the overlay's centring,
	   which otherwise centres every dropdown entry against its box. */
	.gtm-menu.gtm-menu--bp-xl .gtm-menu__row {
		justify-content: flex-start;
		pointer-events: auto;
	}

	/*
	 * A row that no longer fills a column.
	 *
	 * `flex: 0 1 auto` is the shrink-but-do-not-grow the overlay pattern already
	 * uses, and it is what makes an item's width its own content - label, gap and
	 * chevron together - so the spacing between entries stays even. The mobile
	 * default grows the link to fill the row, which is right when rows are stacked
	 * and meaningless when they sit side by side.
	 *
	 * `white-space: nowrap` because a wrapped entry in a horizontal bar reads as
	 * two entries.
	 */
	.gtm-menu.gtm-menu--bp-xl .gtm-menu__link {
		flex: 0 1 auto;
		justify-content: flex-start;
		padding-block: var(--gtm-desktop-link-pad-y);
		padding-inline: var(--gtm-desktop-link-pad-x);
		white-space: nowrap;
	}

	/* ==========================================================================
	   Dropdowns
	   ========================================================================== */

	/*
	 * One reset for every sub-menu at every depth, whatever the mobile mode did to
	 * it. The accordion collapses these with `grid-template-rows: 0fr` and an
	 * `overflow: hidden`; the drill-down slides them in from the side with a
	 * transform, at (0,3,0), which is why the root is doubled here as everywhere.
	 *
	 * Hidden with `visibility` rather than `display: none` so the box can be
	 * measured while closed - the flip below needs a width, and a display-none box
	 * has none. The delayed `visibility` transition is the standard trick for
	 * keeping it out of the tab order until the fade finishes.
	 */
	.gtm-menu.gtm-menu--bp-xl .gtm-menu__submenu {
		position: absolute;
		inset: calc(100% + var(--gtm-desktop-dropdown-offset)) auto auto 0;
		z-index: 1;
		display: block;
		width: max-content;
		min-width: var(--gtm-desktop-dropdown-min-width);
		max-width: 20rem;
		height: auto;
		padding-block: var(--gtm-panel-pad-y);
		background-color: var(--gtm-panel-bg);
		border-radius: var(--gtm-radius);
		box-shadow: var(--gtm-desktop-dropdown-shadow);
		visibility: hidden;
		opacity: 0;
		transform: none;
		overflow: visible;
		pointer-events: auto;
		transition:
			opacity var(--gtm-duration) var(--gtm-easing),
			visibility 0s linear var(--gtm-duration);
	}

	/*
	 * A dropdown restyles itself by re-pointing the base tokens, not by out-ranking
	 * the rules that read them.
	 *
	 * The alternative was a rule per property, each scoped through `.gtm-menu__submenu`
	 * and each having to beat the one it replaced - and there are more of those than
	 * it first looks: the link, the muted heading with its 0.8125 factor, the plain
	 * heading, the hover state, the current page. Five selectors to write, five
	 * specificities to get right, and a sixth to remember the day another is added.
	 *
	 * Re-declaring the tokens on the box instead means every one of those rules goes
	 * on saying exactly what it said before and quietly reads the dropdown's values
	 * inside the dropdown. Nothing to out-specify, and a rule added later inherits
	 * the behaviour for free.
	 *
	 * The values come from the nav, where they resolved against the bar's own tokens,
	 * so `--gtm-font-size: var(--gtm-desktop-dropdown-font-size)` is a substitution
	 * of an inherited value rather than a self-reference.
	 */
	.gtm-menu.gtm-menu--bp-xl .gtm-menu__submenu {
		--gtm-font-size: var(--gtm-desktop-dropdown-font-size);
		--gtm-link-color: var(--gtm-desktop-dropdown-link-color);
		--gtm-link-color-hover: var(--gtm-desktop-dropdown-link-color-hover);
		--gtm-link-color-current: var(--gtm-desktop-dropdown-link-color-current);
	}

	/* A branch below the first opens beside its parent, not under it. */
	.gtm-menu.gtm-menu--bp-xl .gtm-menu__submenu .gtm-menu__submenu {
		inset: 0 auto auto 100%;
	}

	/*
	 * A dropdown that would run off the right edge is flipped by the script, which
	 * measures it and adds this class. CSS cannot ask where the viewport ends, and
	 * the alternative - anchoring the last few items to the right on principle -
	 * guesses at how many "the last few" is and is wrong at every other width.
	 */
	.gtm-menu.gtm-menu--bp-xl .gtm-menu__submenu--flip {
		inset: calc(100% + var(--gtm-desktop-dropdown-offset)) 0 auto auto;
	}

	.gtm-menu.gtm-menu--bp-xl .gtm-menu__submenu .gtm-menu__submenu--flip {
		inset: 0 100% auto auto;
	}

	/*
	 * What opens a dropdown, in the two trigger modes.
	 *
	 * Hover mode answers to the pointer and to the keyboard alike: `:focus-within`
	 * is what lets Tab walk into a branch without the script being involved at all.
	 * Click mode deliberately leaves both out - a branch that opened on focus would
	 * contradict the button the reader just chose not to press - and answers only
	 * to `is-open`, which the script sets.
	 *
	 * `.is-static` is excluded because it carries `is-open` from the markup: the
	 * "link only" parent behaviour leaves branches permanently expanded, which is a
	 * stacked-list idea. Here those branches are ordinary dropdowns, and since that
	 * behaviour prints no button at all, hover is the only affordance they have.
	 */
	.gtm-menu.gtm-menu--bp-xl[data-desktop-trigger="hover"] .gtm-menu__item:hover > .gtm-menu__submenu,
	.gtm-menu.gtm-menu--bp-xl[data-desktop-trigger="hover"] .gtm-menu__item:focus-within > .gtm-menu__submenu,
	.gtm-menu.gtm-menu--bp-xl .gtm-menu__item:hover > .gtm-menu__submenu.is-static,
	.gtm-menu.gtm-menu--bp-xl .gtm-menu__item:focus-within > .gtm-menu__submenu.is-static,
	.gtm-menu.gtm-menu--bp-xl .gtm-menu__submenu.is-open:not(.is-static) {
		visibility: visible;
		opacity: 1;
		transition:
			opacity var(--gtm-duration) var(--gtm-easing),
			visibility 0s;
	}

	/* Inside a dropdown the entries stack again, so the mobile link geometry is
	   the right one - full width, its own row. */
	.gtm-menu.gtm-menu--bp-xl .gtm-menu__submenu .gtm-menu__link {
		flex: 1 1 auto;
		padding-inline: var(--gtm-panel-pad-x);
		white-space: normal;
	}

	/* ==========================================================================
	   Chevrons
	   ========================================================================== */

	/*
	 * `:not(.gtm-menu--icon-plusminus)` guards every rule in this section, and it is
	 * not defensive tidiness.
	 *
	 * The plus/minus variant is not a chevron that points somewhere - it is two bars
	 * in a box that deliberately carries `transform: none`, because the box must not
	 * turn at all. These rules out-specify that `none` by several classes, so without
	 * the guard they turned the plus 45 degrees and it rendered as a multiplication
	 * sign, at every width above the breakpoint, in both trigger modes. Measured, not
	 * guessed: the element resolved `rotate(45deg)` where the variant had asked for
	 * nothing.
	 *
	 * Direction says where the branch opens: down at the top level, sideways below
	 * it. Every transform here restates the whole thing and puts the 25% nudge on the
	 * axis it points down - the compensation for a rotated square's ink sitting
	 * lopsided in its own box. The wrong axis moves the glyph off the text instead of
	 * centring it; see the base chevron rule in the mobile layer.
	 */
	.gtm-menu.gtm-menu--bp-xl:not(.gtm-menu--icon-plusminus) .gtm-menu__panel-body > .gtm-menu__list > .gtm-menu__item > .gtm-menu__row .gtm-menu__chevron {
		transform: translateY(-25%) rotate(45deg);
	}

	/*
	 * Open, at the top level: the chevron turns to point back up at the bar.
	 *
	 * A half turn here, where the accordion takes a quarter, and the difference is
	 * the affordance. An accordion unfolds a branch *below* the row, so pointing down
	 * describes where the content went; a dropdown is already below by construction,
	 * so down would say nothing and up is the only thing left to say - "this is the
	 * one that is open, press again to close it". It is also what every other
	 * dropdown on the web does, which counts for more than symmetry with the mobile
	 * layer nobody sees at the same time.
	 *
	 * Three ways in, because "open" has no single expression here. Hover mode never
	 * touches `aria-expanded` - the branch opens in CSS - so the state has to be read
	 * off the item, and `:focus-within` is what makes the turn happen for a keyboard
	 * as well. Click mode has a real button with a real `aria-expanded`, and reads it.
	 */
	.gtm-menu.gtm-menu--bp-xl:not(.gtm-menu--icon-plusminus)[data-desktop-trigger="hover"] .gtm-menu__panel-body > .gtm-menu__list > .gtm-menu__item:hover > .gtm-menu__row .gtm-menu__chevron,
	.gtm-menu.gtm-menu--bp-xl:not(.gtm-menu--icon-plusminus)[data-desktop-trigger="hover"] .gtm-menu__panel-body > .gtm-menu__list > .gtm-menu__item:focus-within > .gtm-menu__row .gtm-menu__chevron,
	.gtm-menu.gtm-menu--bp-xl:not(.gtm-menu--icon-plusminus) .gtm-menu__panel-body > .gtm-menu__list > .gtm-menu__item > .gtm-menu__row [aria-expanded="true"] .gtm-menu__chevron {
		transform: translateY(25%) rotate(-135deg);
	}

	/* Below the first level a branch opens beside its parent, so the chevron already
	   points where the content will appear and has nothing to say when it opens. */
	.gtm-menu.gtm-menu--bp-xl:not(.gtm-menu--icon-plusminus) .gtm-menu__submenu .gtm-menu__chevron {
		transform: translateX(-25%) rotate(-45deg);
	}

	/*
	 * The plus becomes a minus, by the same three ways in.
	 *
	 * The mobile layer already draws this - the minus is the plus with one bar laid
	 * flat - but it hangs the change on `aria-expanded`, which hover mode never sets.
	 * Only the open state needs restating here; the closed one is the variant's own,
	 * and the guard above is what leaves it alone.
	 */
	.gtm-menu.gtm-menu--bp-xl.gtm-menu--icon-plusminus[data-desktop-trigger="hover"] .gtm-menu__item:hover > .gtm-menu__row .gtm-menu__chevron:not(.gtm-menu__chevron--back)::after,
	.gtm-menu.gtm-menu--bp-xl.gtm-menu--icon-plusminus[data-desktop-trigger="hover"] .gtm-menu__item:focus-within > .gtm-menu__row .gtm-menu__chevron:not(.gtm-menu__chevron--back)::after,
	.gtm-menu.gtm-menu--bp-xl.gtm-menu--icon-plusminus .gtm-menu__row [aria-expanded="true"] .gtm-menu__chevron:not(.gtm-menu__chevron--back)::after {
		transform: rotate(0deg);
	}
}

/* ==========================================================================
   Desktop layer - xxl (1400px and up)
   Generated from gtmmenu.desktop.css. Edit that file, not this one.
   ========================================================================== */

@media (min-width: 1400px) {
	/* ==========================================================================
	   Desktop layer - THE SOURCE, written once

	   This file is expanded five times into media/css/gtmmenu.css, once per named
	   breakpoint, by tools/build-css.py. Write `.gtm-menu--bp-xxl` and the generator
	   emits `.gtm-menu--bp-sm` ... `.gtm-menu--bp-xxl`, each inside its own query.
	   Never write a suffixed class here.

	   Two rules hold this file together.

	   1. EVERY selector starts with `.gtm-menu.gtm-menu--bp-xxl`, root doubled. Not
	      decoration: the mobile layer scopes its patterns at (0,2,0) and, in one
	      case, at (0,3,0) - `.gtm-menu.gtm-menu--overlay .gtm-menu__link` doubles
	      its own root for exactly the same reason. A single root here would put
	      this layer at (0,2,0), where it would lose to the pattern it is meant to
	      replace, and the loss would depend on which rule happened to sit lower in
	      the file. Doubling puts the floor at (0,3,0), which beats every pattern
	      rule outright and ties only with that one - and ties fall this way, since
	      the generated file appends this block last.

	   2. CANCEL SHORTHANDS WITH SHORTHANDS. The patterns position their panels with
	      `inset: 0`. Overriding it with `inset-block-start` alone leaves the other
	      three sides live, and the box silently stretches to the corner the mobile
	      layer chose. Every reset below therefore restates the whole `inset`.

	   What is deliberately NOT here: no burger at any width above the breakpoint,
	   so nothing in this file gives the toggle a desktop variant - its colour,
	   shape, alignment and spacing stay mobile-only settings. The logo does survive
	   the breakpoint, which is why it has two sets of everything.
	   ========================================================================== */

	/*
	 * The frame becomes the row, and the bar stops being a box.
	 *
	 * `display: contents` on the bar promotes the logo to a direct flex item of the
	 * frame, sitting beside the panel. That is what makes the three alignments mean
	 * anything: each one distributes the space *after* the logo. Keep the bar as a
	 * real box and the panel has to be positioned over it instead, at which point
	 * "aligned to the logo" would render as "underneath the logo".
	 *
	 * The frame also inherits what the bar used to carry - the padding, the gap, the
	 * stacking level. The stacking level is the one that is not cosmetic: .gtm-menu
	 * is positioned without a z-index, so it paints where document order alone
	 * decides, and any positioned element further down the page paints over it. The
	 * bar carries `--gtm-z + 2` for that reason at mobile widths; here the whole row
	 * needs it, dropdowns included.
	 *
	 * Why the frame rather than the nav: the fixed mode below has to take the whole
	 * row out of the flow, and a fixed box reserves no height. The nav has to stay
	 * in the flow to go on doing that, so it cannot be the thing that gets fixed.
	 */
	.gtm-menu.gtm-menu--bp-xxl {
		/*
		 * Desktop-only tokens. Declared on the nav rather than the frame so the
		 * generated per-instance sheet has a stable place to override them from
		 * inside its own media query, and inside the breakpoint so they cannot leak
		 * down to mobile.
		 */
		/*
		 * The link's own padding, rather than the mobile `--gtm-link-pad-y`. That
		 * token is rewritten by the overlay pattern on the panel body, so reading it
		 * here would make a desktop row's height depend on which mobile pattern
		 * happens to be selected.
		 */
		--gtm-desktop-link-pad-y: 0.5rem;
		--gtm-desktop-link-pad-x: 0.875rem;
		--gtm-desktop-item-gap: 0rem;
		--gtm-desktop-dropdown-min-width: 12rem;

		/*
		 * What a dropdown uses instead of the bar's own values. Each one defaults to
		 * the matching entry token, so a dropdown follows the bar until somebody says
		 * otherwise and no setting is needed to keep things as they are.
		 *
		 * No cycle here, although it reads like one: this is the nav, where
		 * `--gtm-font-size` is a real value; the substitution below happens on the
		 * dropdown, against the value it inherited from here.
		 */
		--gtm-desktop-dropdown-font-size: var(--gtm-font-size);
		--gtm-desktop-dropdown-link-color: var(--gtm-link-color);
		--gtm-desktop-dropdown-link-color-hover: var(--gtm-link-color-hover);
		--gtm-desktop-dropdown-link-color-current: var(--gtm-link-color-current);

		/*
		 * How far the dropdown sits below the bar. Zero means flush with the bottom
		 * of the band; a negative value pulls it up into the bar, which is what a
		 * bar with an elliptical rounding needs - its bottom edge is a curve, so
		 * "flush" is a different number at each end and the box has to overlap the
		 * shallow side to close the gap on the deep one.
		 */
		--gtm-desktop-dropdown-offset: 0px;
		--gtm-desktop-dropdown-shadow: 0 8px 24px rgba(0, 0, 0, 0.16);
	}

	.gtm-menu.gtm-menu--bp-xxl .gtm-menu__frame {
		position: relative;
		z-index: calc(var(--gtm-z) + 2);
		display: flex;
		align-items: center;
		gap: var(--gtm-bar-gap);

		/*
		 * Capped, exactly as the bar caps itself below the breakpoint - and the cap
		 * is what keeps the page from starting a logo's height further down.
		 *
		 * Without it the row is as tall as its tallest item, which is the logo, so a
		 * 253px logo over a 70px band reserved 253px of flow and left 183px of empty
		 * page under the colour. Measured on the site, and reported as such.
		 *
		 * The logo goes on overhanging because `margin-block: auto` on it resolves to
		 * zero once it no longer fits, dropping the overhang below the band where it
		 * shows. That is the same mechanism the bar has always relied on; copying the
		 * declaration rather than inventing a second way to say it is the point.
		 *
		 * `auto` when no bar height is set, so "let the content decide" still means
		 * what it means everywhere else.
		 */
		height: var(--gtm-bar-height, auto);
		min-height: var(--gtm-tap-size);
		padding-inline: var(--gtm-bar-pad-x);

		/*
		 * The row spans the full width whether or not it has anything to put there,
		 * so its own box catches nothing and every interactive descendant takes its
		 * clicks back. Same reasoning as the bar's at mobile widths, and it matters
		 * more here: the empty half of a right-aligned menu sits directly over a
		 * hero or a slider.
		 */
		pointer-events: none;
	}

	/*
	 * The painted band moves up to the frame, because the bar no longer has a box to
	 * paint it on - and a band the width of the logo is not a band.
	 *
	 * Declared exactly as the bar's is, over-constraint included: `inset-block: 0`
	 * together with a height resolves in the band's favour, dropping the bottom
	 * inset, so `auto` stretches to the full row and a length pins the band to the
	 * top. Any simplification here changes what an unset bar height means.
	 */
	.gtm-menu.gtm-menu--bp-xxl .gtm-menu__frame::before {
		content: '';
		position: absolute;
		inset-block: 0;
		inset-inline: 0;
		z-index: -1;
		height: var(--gtm-bar-height, auto);
		background-color: var(--gtm-bar-bg);
		border-radius: var(--gtm-bar-radius);
		pointer-events: none;
	}

	.gtm-menu.gtm-menu--bp-xxl .gtm-menu__bar {
		display: contents;
	}

	/* Whether a `display: contents` element still generates its pseudo-elements is
	   not something to leave to the browser: cancelled explicitly, or the band
	   risks being painted twice - once at the row's width, once at the logo's. */
	.gtm-menu.gtm-menu--bp-xxl .gtm-menu__bar::before {
		content: none;
	}

	/*
	 * The burger goes, and with it everything that only ever served it. The panel
	 * head belongs to the drill-down, which has no meaning once every level is a
	 * dropdown; the backdrop dims a page behind a floating panel, and nothing
	 * floats here.
	 *
	 * `display: none` at (0,3,0) also settles the fixed-toggle variant, which pins
	 * the button to the viewport at (0,2,0) - a burger left fixed above the
	 * breakpoint would hang in the corner over a menu that already shows every
	 * entry.
	 */
	.gtm-menu.gtm-menu--bp-xxl .gtm-menu__toggle,
	.gtm-menu.gtm-menu--bp-xxl .gtm-menu__backdrop,
	.gtm-menu.gtm-menu--bp-xxl .gtm-menu__panel-head {
		display: none;
	}

	/*
	 * A fixed row fixes the frame, not the bar - the bar has no box left to fix,
	 * and the panel would not follow it if it had. The mobile rule targets the bar
	 * at (0,2,0) and simply stops applying once the bar is `display: contents`.
	 *
	 * The nav stays exactly where it was, so `--reserve` goes on reserving the
	 * height through its own `min-height`, unchanged and untouched.
	 */
	.gtm-menu.gtm-menu--bp-xxl.gtm-menu--fixed .gtm-menu__frame {
		position: fixed;
		inset: 0 0 auto;
	}

	.gtm-menu.gtm-menu--bp-xxl .gtm-menu__brand {
		flex: 0 0 auto;
	}

	/* ==========================================================================
	   The panel becomes the row of entries
	   ========================================================================== */

	/*
	 * Everything the three patterns did to this box is undone in one place: the
	 * off-canvas fixes it to a side and gives it a width, the overlay stretches it
	 * over the viewport and fades it in, the inline pattern collapses it with a
	 * zero grid row. Undoing them piecemeal, pattern by pattern, would mean three
	 * near-identical blocks and a fourth the day a pattern is added.
	 *
	 * `inset` and `transform` are restated whole for the reason at the top of this
	 * file. `min-width: 0` lets a long menu shrink rather than push the logo off
	 * the row - flex items refuse to go below their content width without it.
	 */
	.gtm-menu.gtm-menu--bp-xxl .gtm-menu__panel {
		position: static;
		z-index: auto;
		display: flex;
		flex: 1 1 auto;

		/*
		 * The entries centre on the painted band, not on the row.
		 *
		 * The row is as tall as its tallest item, which is the logo - and a logo is
		 * routinely taller than the band, since that overhang is the whole point of
		 * a separate bar height. Left to `align-items: center` on the row, the
		 * entries centre on the logo instead and hang below the colour: measured at
		 * 90px down a 180px row against a 100px band, half of every label off the
		 * band. So the panel takes the band's height, pinned to the top, and centres
		 * inside that.
		 *
		 * `--gtm-bar-band` is the same token the bar's own height and the fixed
		 * hamburger's insets are computed from - one number, one place.
		 */
		align-self: flex-start;
		height: var(--gtm-bar-band);
		align-items: stretch;
		inset: auto;
		width: auto;
		min-width: 0;
		max-height: none;
		padding: 0;
		background: none;
		visibility: visible;
		opacity: 1;
		transform: none;
		transition: none;
		overflow: visible;
		pointer-events: none;
	}

	/* The alignment setting, and the only thing it touches. Free space lives
	   between the logo and the entries, so this decides which end of it they sit
	   at. */
	.gtm-menu.gtm-menu--bp-xxl.gtm-menu--menu-end .gtm-menu__panel {
		justify-content: flex-end;
	}

	.gtm-menu.gtm-menu--bp-xxl.gtm-menu--menu-center .gtm-menu__panel {
		justify-content: center;
	}

	.gtm-menu.gtm-menu--bp-xxl.gtm-menu--menu-start .gtm-menu__panel {
		justify-content: flex-start;
	}

	.gtm-menu.gtm-menu--bp-xxl .gtm-menu__panel-inner {
		flex: 0 1 auto;
		flex-direction: row;
		align-items: stretch;
		width: auto;
		min-width: 0;
	}

	/*
	 * The overlay pattern dresses this box for a full-screen sheet - 1.25rem type,
	 * centred text, its own vertical rhythm - and every one of those leaks into a
	 * dropdown, where they read as a mistake. Undone here rather than in a rule
	 * scoped to the overlay, since the next pattern to style the body would leak in
	 * exactly the same way.
	 */
	.gtm-menu.gtm-menu--bp-xxl .gtm-menu__panel-body {
		display: flex;
		/* Restated because the overlay lays this box out as a column, where
		   `align-items: stretch` stretches across the width instead of the height
		   and the chain quietly stops here. */
		flex-direction: row;
		flex: 0 1 auto;
		align-items: stretch;
		min-width: 0;
		padding: 0;

		/*
		 * The overlay enlarges its sheet by a factor on this box. Above the
		 * breakpoint there is no sheet - the entries are a row on the bar - so the
		 * factor goes back to 1 and the desktop text size is read as written.
		 */
		--gtm-font-scale: 1;

		font-size: inherit;
		text-align: start;
		overflow: visible;
	}

	/* The top level, and only the top level, lies down. Deeper lists keep the
	   block direction they already had, which is what a dropdown wants.

	   `stretch` rather than `center`, and it is the dropdowns that need it: they
	   hang off `inset-block-start: 100%`, so an item as tall as its label would
	   open them halfway up the band, across the colour. Full-height items put that
	   100% exactly on the band's bottom edge - and give the pointer a taller strip
	   to cross on its way down into the branch. */
	.gtm-menu.gtm-menu--bp-xxl .gtm-menu__panel-body > .gtm-menu__list {
		display: flex;
		align-items: stretch;
		gap: var(--gtm-desktop-item-gap);

		/*
		 * The overlay centres this list with `margin-block: auto`, and an auto
		 * margin in a flex container swallows the free space before `stretch` ever
		 * sees it - so the list stayed 44px tall inside a 100px band and the
		 * dropdowns opened 28px above it. Cancelling the margin is what lets the
		 * chain of `stretch` above actually reach the items.
		 */
		margin-block: 0;
		height: auto;
		padding: 0;
		overflow: visible;
	}

	/* The label stays its own height inside that full-height item, so the hover
	   background is a pill on the band rather than a full-height block. */
	.gtm-menu.gtm-menu--bp-xxl .gtm-menu__panel-body > .gtm-menu__list > .gtm-menu__item {
		display: flex;
		align-items: center;
	}

	/* Each parent is the positioning context for its own dropdown. Only parents:
	   giving every item a containing block would cost nothing today and confuse
	   the next person looking for why an item is positioned. */
	.gtm-menu.gtm-menu--bp-xxl .gtm-menu__item--parent {
		position: relative;
	}

	/* `justify-content` here and on the link below undoes the overlay's centring,
	   which otherwise centres every dropdown entry against its box. */
	.gtm-menu.gtm-menu--bp-xxl .gtm-menu__row {
		justify-content: flex-start;
		pointer-events: auto;
	}

	/*
	 * A row that no longer fills a column.
	 *
	 * `flex: 0 1 auto` is the shrink-but-do-not-grow the overlay pattern already
	 * uses, and it is what makes an item's width its own content - label, gap and
	 * chevron together - so the spacing between entries stays even. The mobile
	 * default grows the link to fill the row, which is right when rows are stacked
	 * and meaningless when they sit side by side.
	 *
	 * `white-space: nowrap` because a wrapped entry in a horizontal bar reads as
	 * two entries.
	 */
	.gtm-menu.gtm-menu--bp-xxl .gtm-menu__link {
		flex: 0 1 auto;
		justify-content: flex-start;
		padding-block: var(--gtm-desktop-link-pad-y);
		padding-inline: var(--gtm-desktop-link-pad-x);
		white-space: nowrap;
	}

	/* ==========================================================================
	   Dropdowns
	   ========================================================================== */

	/*
	 * One reset for every sub-menu at every depth, whatever the mobile mode did to
	 * it. The accordion collapses these with `grid-template-rows: 0fr` and an
	 * `overflow: hidden`; the drill-down slides them in from the side with a
	 * transform, at (0,3,0), which is why the root is doubled here as everywhere.
	 *
	 * Hidden with `visibility` rather than `display: none` so the box can be
	 * measured while closed - the flip below needs a width, and a display-none box
	 * has none. The delayed `visibility` transition is the standard trick for
	 * keeping it out of the tab order until the fade finishes.
	 */
	.gtm-menu.gtm-menu--bp-xxl .gtm-menu__submenu {
		position: absolute;
		inset: calc(100% + var(--gtm-desktop-dropdown-offset)) auto auto 0;
		z-index: 1;
		display: block;
		width: max-content;
		min-width: var(--gtm-desktop-dropdown-min-width);
		max-width: 20rem;
		height: auto;
		padding-block: var(--gtm-panel-pad-y);
		background-color: var(--gtm-panel-bg);
		border-radius: var(--gtm-radius);
		box-shadow: var(--gtm-desktop-dropdown-shadow);
		visibility: hidden;
		opacity: 0;
		transform: none;
		overflow: visible;
		pointer-events: auto;
		transition:
			opacity var(--gtm-duration) var(--gtm-easing),
			visibility 0s linear var(--gtm-duration);
	}

	/*
	 * A dropdown restyles itself by re-pointing the base tokens, not by out-ranking
	 * the rules that read them.
	 *
	 * The alternative was a rule per property, each scoped through `.gtm-menu__submenu`
	 * and each having to beat the one it replaced - and there are more of those than
	 * it first looks: the link, the muted heading with its 0.8125 factor, the plain
	 * heading, the hover state, the current page. Five selectors to write, five
	 * specificities to get right, and a sixth to remember the day another is added.
	 *
	 * Re-declaring the tokens on the box instead means every one of those rules goes
	 * on saying exactly what it said before and quietly reads the dropdown's values
	 * inside the dropdown. Nothing to out-specify, and a rule added later inherits
	 * the behaviour for free.
	 *
	 * The values come from the nav, where they resolved against the bar's own tokens,
	 * so `--gtm-font-size: var(--gtm-desktop-dropdown-font-size)` is a substitution
	 * of an inherited value rather than a self-reference.
	 */
	.gtm-menu.gtm-menu--bp-xxl .gtm-menu__submenu {
		--gtm-font-size: var(--gtm-desktop-dropdown-font-size);
		--gtm-link-color: var(--gtm-desktop-dropdown-link-color);
		--gtm-link-color-hover: var(--gtm-desktop-dropdown-link-color-hover);
		--gtm-link-color-current: var(--gtm-desktop-dropdown-link-color-current);
	}

	/* A branch below the first opens beside its parent, not under it. */
	.gtm-menu.gtm-menu--bp-xxl .gtm-menu__submenu .gtm-menu__submenu {
		inset: 0 auto auto 100%;
	}

	/*
	 * A dropdown that would run off the right edge is flipped by the script, which
	 * measures it and adds this class. CSS cannot ask where the viewport ends, and
	 * the alternative - anchoring the last few items to the right on principle -
	 * guesses at how many "the last few" is and is wrong at every other width.
	 */
	.gtm-menu.gtm-menu--bp-xxl .gtm-menu__submenu--flip {
		inset: calc(100% + var(--gtm-desktop-dropdown-offset)) 0 auto auto;
	}

	.gtm-menu.gtm-menu--bp-xxl .gtm-menu__submenu .gtm-menu__submenu--flip {
		inset: 0 100% auto auto;
	}

	/*
	 * What opens a dropdown, in the two trigger modes.
	 *
	 * Hover mode answers to the pointer and to the keyboard alike: `:focus-within`
	 * is what lets Tab walk into a branch without the script being involved at all.
	 * Click mode deliberately leaves both out - a branch that opened on focus would
	 * contradict the button the reader just chose not to press - and answers only
	 * to `is-open`, which the script sets.
	 *
	 * `.is-static` is excluded because it carries `is-open` from the markup: the
	 * "link only" parent behaviour leaves branches permanently expanded, which is a
	 * stacked-list idea. Here those branches are ordinary dropdowns, and since that
	 * behaviour prints no button at all, hover is the only affordance they have.
	 */
	.gtm-menu.gtm-menu--bp-xxl[data-desktop-trigger="hover"] .gtm-menu__item:hover > .gtm-menu__submenu,
	.gtm-menu.gtm-menu--bp-xxl[data-desktop-trigger="hover"] .gtm-menu__item:focus-within > .gtm-menu__submenu,
	.gtm-menu.gtm-menu--bp-xxl .gtm-menu__item:hover > .gtm-menu__submenu.is-static,
	.gtm-menu.gtm-menu--bp-xxl .gtm-menu__item:focus-within > .gtm-menu__submenu.is-static,
	.gtm-menu.gtm-menu--bp-xxl .gtm-menu__submenu.is-open:not(.is-static) {
		visibility: visible;
		opacity: 1;
		transition:
			opacity var(--gtm-duration) var(--gtm-easing),
			visibility 0s;
	}

	/* Inside a dropdown the entries stack again, so the mobile link geometry is
	   the right one - full width, its own row. */
	.gtm-menu.gtm-menu--bp-xxl .gtm-menu__submenu .gtm-menu__link {
		flex: 1 1 auto;
		padding-inline: var(--gtm-panel-pad-x);
		white-space: normal;
	}

	/* ==========================================================================
	   Chevrons
	   ========================================================================== */

	/*
	 * `:not(.gtm-menu--icon-plusminus)` guards every rule in this section, and it is
	 * not defensive tidiness.
	 *
	 * The plus/minus variant is not a chevron that points somewhere - it is two bars
	 * in a box that deliberately carries `transform: none`, because the box must not
	 * turn at all. These rules out-specify that `none` by several classes, so without
	 * the guard they turned the plus 45 degrees and it rendered as a multiplication
	 * sign, at every width above the breakpoint, in both trigger modes. Measured, not
	 * guessed: the element resolved `rotate(45deg)` where the variant had asked for
	 * nothing.
	 *
	 * Direction says where the branch opens: down at the top level, sideways below
	 * it. Every transform here restates the whole thing and puts the 25% nudge on the
	 * axis it points down - the compensation for a rotated square's ink sitting
	 * lopsided in its own box. The wrong axis moves the glyph off the text instead of
	 * centring it; see the base chevron rule in the mobile layer.
	 */
	.gtm-menu.gtm-menu--bp-xxl:not(.gtm-menu--icon-plusminus) .gtm-menu__panel-body > .gtm-menu__list > .gtm-menu__item > .gtm-menu__row .gtm-menu__chevron {
		transform: translateY(-25%) rotate(45deg);
	}

	/*
	 * Open, at the top level: the chevron turns to point back up at the bar.
	 *
	 * A half turn here, where the accordion takes a quarter, and the difference is
	 * the affordance. An accordion unfolds a branch *below* the row, so pointing down
	 * describes where the content went; a dropdown is already below by construction,
	 * so down would say nothing and up is the only thing left to say - "this is the
	 * one that is open, press again to close it". It is also what every other
	 * dropdown on the web does, which counts for more than symmetry with the mobile
	 * layer nobody sees at the same time.
	 *
	 * Three ways in, because "open" has no single expression here. Hover mode never
	 * touches `aria-expanded` - the branch opens in CSS - so the state has to be read
	 * off the item, and `:focus-within` is what makes the turn happen for a keyboard
	 * as well. Click mode has a real button with a real `aria-expanded`, and reads it.
	 */
	.gtm-menu.gtm-menu--bp-xxl:not(.gtm-menu--icon-plusminus)[data-desktop-trigger="hover"] .gtm-menu__panel-body > .gtm-menu__list > .gtm-menu__item:hover > .gtm-menu__row .gtm-menu__chevron,
	.gtm-menu.gtm-menu--bp-xxl:not(.gtm-menu--icon-plusminus)[data-desktop-trigger="hover"] .gtm-menu__panel-body > .gtm-menu__list > .gtm-menu__item:focus-within > .gtm-menu__row .gtm-menu__chevron,
	.gtm-menu.gtm-menu--bp-xxl:not(.gtm-menu--icon-plusminus) .gtm-menu__panel-body > .gtm-menu__list > .gtm-menu__item > .gtm-menu__row [aria-expanded="true"] .gtm-menu__chevron {
		transform: translateY(25%) rotate(-135deg);
	}

	/* Below the first level a branch opens beside its parent, so the chevron already
	   points where the content will appear and has nothing to say when it opens. */
	.gtm-menu.gtm-menu--bp-xxl:not(.gtm-menu--icon-plusminus) .gtm-menu__submenu .gtm-menu__chevron {
		transform: translateX(-25%) rotate(-45deg);
	}

	/*
	 * The plus becomes a minus, by the same three ways in.
	 *
	 * The mobile layer already draws this - the minus is the plus with one bar laid
	 * flat - but it hangs the change on `aria-expanded`, which hover mode never sets.
	 * Only the open state needs restating here; the closed one is the variant's own,
	 * and the guard above is what leaves it alone.
	 */
	.gtm-menu.gtm-menu--bp-xxl.gtm-menu--icon-plusminus[data-desktop-trigger="hover"] .gtm-menu__item:hover > .gtm-menu__row .gtm-menu__chevron:not(.gtm-menu__chevron--back)::after,
	.gtm-menu.gtm-menu--bp-xxl.gtm-menu--icon-plusminus[data-desktop-trigger="hover"] .gtm-menu__item:focus-within > .gtm-menu__row .gtm-menu__chevron:not(.gtm-menu__chevron--back)::after,
	.gtm-menu.gtm-menu--bp-xxl.gtm-menu--icon-plusminus .gtm-menu__row [aria-expanded="true"] .gtm-menu__chevron:not(.gtm-menu__chevron--back)::after {
		transform: rotate(0deg);
	}
}
