/* =============================================================================
 * 20-chrome.css -- header, primary nav, footer. The chrome the theme now OWNS.
 *
 * BYTE-IDENTICAL across both sites. This file is the reason Astra, TT4, HFE,
 * ElementsKit and Elementor Pro's Theme Builder can all update freely without
 * stranding either site: none of them render chrome any more.
 *
 * Markup contract -- from _shared/php/chrome-header.php, chrome-footer.php,
 * nav-walker.php and nav.js:
 *
 *   #page.qt-site
 *     header#masthead.qt-header[.qt-header--stacked]     (brand.php header_layout)
 *       .qt-header__inner
 *         .qt-brand > .qt-brand__link[--text] > .qt-brand__logo | .qt-brand__wordmark
 *         button.qt-nav-toggle > .qt-nav-toggle__bar
 *         nav#qt-primary-nav.qt-nav[.is-open]
 *           > ul#qt-primary-menu.qt-menu.qt-menu--primary
 *               > li[.qt-has-children][.is-open]
 *                   > a  [> img.qt-menu__img]
 *                   > button.qt-submenu-toggle
 *                   > ul.sub-menu
 *         .qt-header__cta > .qt-header__phone            (only when brand.php has a phone)
 *             [> span.qt-header__phone-label + span.qt-header__phone-number]
 *                                                        (only with brand.php phone_label)
 *         a.qt-btn.qt-btn--primary.qt-header__quote      (only when brand.php has quote_url)
 *             DIRECT child of .qt-header__inner, NOT inside .qt-header__cta --
 *             it needs to be a flex item of the header row to claim a full-width
 *             line of its own below 1024px. Nested one level deeper, `flex: 1 1
 *             100%` would resolve against .qt-header__cta and do nothing.
 *             Source order of cta/quote swaps with brand.php header_quote_first.
 *     #content.site-content > .ast-container.qt-container
 *     footer#colophon.qt-footer[.qt-footer--columns] -- the sheet GROUND
 *       .qt-footer__inner                            -- the painted BAND
 *         .qt-footer__nav > ul#qt-footer-menu.qt-menu.qt-menu--footer
 *             the whole <nav> is absent on GF -- chrome-footer.php resolves the
 *             menu BEFORE emitting the wrapper, so an unresolved slot costs no
 *             element and no --qt-space-3 gap. Also absent with footer_menu false
 *         [.qt-footer__main                            -- only with footer_brand
 *           > .qt-footer__brand > p.qt-footer__brand-logo | p.qt-footer__wordmark,
 *                                 p.qt-footer__tagline, p.qt-footer__blurb,
 *                                 p.qt-footer__badge]
 *         nav.qt-footer__sitemap                       -- brand.php link groups
 *           > .qt-footer__group                        (inside __main when it exists)
 *               > h2.qt-footer__group-title#qt-footer-group-N
 *               + ul.qt-footer__links[aria-labelledby] > li > a[.qt-footer__link--lead]
 *               [+ h2 + ul ...]                        a 'stack' group, same column
 *             absent entirely unless brand.php['footer_link_groups'] yields at
 *             least one group with at least one usable link -- same
 *             build-then-emit discipline as the footer menu above
 *         .qt-footer__cols > .qt-footer__col.qt-footer__col--N
 *             N is the SIDEBAR id, not the position. AT registers 1, GF 3; only
 *             sidebars with a widget in them render, so GF ships 2 today
 *         .qt-footer__legal > .qt-footer__copyright
 *
 * BREAKPOINT: 1024px, and it is not negotiable here. nav.js hard-codes
 * matchMedia('(min-width: 1024px)') to reset the mobile nav, and 30-sheet.css
 * switches the sheet gutter at the same width. Three files, one number.
 * The parity gate measures 390 / 768 / 1366, so 768 behaves as MOBILE on both
 * sites -- which also matches Astra scaling root text to 14.592px at <=768.
 * ========================================================================== */

/* ---- header shell --------------------------------------------------------
 * AT MEASURED (.ast-primary-header-bar, all 8 surfaces x 3 widths):
 *   background #FFFFFF, border-bottom 1px solid #EAEAEA, content height 80px.
 * GF MEASURED (#header): a background IMAGE (the banner), border-radius
 *   10px 10px 0 0, margin-top 20px, height 310px at 1366.
 * Both are expressible as the same rule; the tokens differ. */
.qt-header {
	background-color: var(--qt-header-bg);
	background-image: var(--qt-header-bg-image);
	background-repeat: no-repeat;
	background-position: left top;
	border-bottom: var(--qt-border-w) solid var(--qt-header-border);
	border-radius: var(--qt-header-radius);
	position: relative;
	z-index: 20;
}

.qt-header__inner {
	display: flex;
	align-items: center;
	justify-content: space-between;
	flex-wrap: wrap;
	gap: var(--qt-space-3);
	max-width: var(--qt-measure);
	margin-inline: auto;
	padding-inline: var(--qt-gutter);
	min-height: var(--qt-header-h-mobile);
}

/* flex-wrap is a MOBILE declaration and it is load-bearing there: .qt-nav asks
 * for `flex: 1 1 100%; order: 3` so the open panel can take a line of its own
 * under the brand and the toggle. In a nowrap row that 100% basis is
 * unreachable and the panel is squeezed onto the toggle's line instead.
 *
 * It goes back to nowrap at >=1024 ON PURPOSE, and this is the part that is
 * easy to get wrong. Flex lines are filled from each item's HYPOTHETICAL main
 * size, and .qt-menu--primary is itself a wrap container, so the nav's
 * hypothetical size is the sum of every top-level item on one line. On
 * GlobeFreight that is several times --qt-measure. Allowing a wrap here
 * therefore does NOT hand the nav a tidy second row: the nav overflows line 2
 * on its own and strands .qt-header__cta on a THIRD line. A nav that shares the
 * row beats a phone number sitting alone under it. */
@media (min-width: 1024px) {
	.qt-header__inner {
		flex-wrap: nowrap;
		min-height: var(--qt-header-h);
		padding-inline: var(--qt-gutter-lg);
	}
}

/* ---- brand ---------------------------------------------------------------
 * The colour is --qt-wordmark-ink and NOT --qt-ink-heading, which is what this
 * rule used to read. --qt-ink-heading is the heading ink for the WHITE SHEET;
 * once GlobeFreight's header-bg became #2B2622 it put the wordmark at 1.18:1 on
 * the band, and it could not be flipped to white because the same token paints
 * every h1-h6 in 10-reset, 40-content, 50-components and 60-forms. A token that
 * follows the band is the only thing that serves both surfaces.
 * GF MEASURED #FFFFFF on #2B2622 = 14.97:1. AT is unchanged. */

/* .qt-brand WAS A PLAIN BLOCK, and that put every logo a few px high. A block
 * holding an inline-flex link lays the link on a line box: the image sits on
 * the BASELINE and the strut's descender space hangs under it, so the box the
 * header row centres is taller than the logo. MEASURED 2026-09-10 at 1366 --
 * AT: .qt-brand 63px for a 56px mark, 8px above / 16px below in the 80px bar;
 * GF: 102px for a 96px mark, 6px above / 13px below in 115px.
 * As a flex container the link is blockified, the line box and its strut go,
 * and the brand is exactly the logo's height. MEASURED after, same widths:
 * AT 12/12, GF 10/9. Below 1024 both marks move 2-3px down in their row. */
.qt-brand {
	display: flex;
	align-items: center;
}

.qt-brand__link {
	display: inline-flex;
	align-items: center;
	gap: var(--qt-space-2);
	text-decoration: none;
	color: var(--qt-wordmark-ink);
}

.qt-brand__link:hover,
.qt-brand__link:focus {
	text-decoration: none;
}

.qt-brand__logo {
	display: block;
	/* HEIGHT is the binding constraint inside a band; width follows from the
	 * aspect ratio. Width-only capping rendered GlobeFreight's 1303x569 artwork
	 * 350x153 inside a 115px header. max-width stays as the secondary guard for
	 * a squat logo, and `width:auto` stops a wide one being squashed. */
	max-height: var(--qt-logo-max-h-mobile);
	max-width: var(--qt-logo-max-w);
	width: auto;
	height: auto;
	/* The artwork is supplied on its own opaque ground matched to --qt-header-bg.
	 * Should a transparent version ever replace it, nothing here needs to change. */
	object-fit: contain;
}

/* The text wordmark is what BOTH sites render until D5's cleared artwork
 * exists. R7: GlobeFreight's current logo has "a division of IC-Express" baked
 * into the artwork, which CLAUDE.md forbids publishing -- so this is not a
 * placeholder, it is the shipping state for GF until the owner approves a
 * replacement. Style it properly. */
/* MOBILE-FIRST, and the smaller size here is a MEASUREMENT, not taste.
 *
 * At --qt-fs-h3 (24px) with white-space:nowrap, "AutoTransport" is ~165px. Add
 * the 44px toggle, a nowrap phone number at ~110px, two --qt-space-3 gaps and
 * 2x --qt-gutter of padding and the row needs ~399px inside a 390px viewport.
 * flex-wrap then strands .qt-header__cta on a line of its own -- the same
 * failure the desktop nowrap comment above describes, arriving from the other
 * direction. --qt-fs-h4 buys ~27px and the row fits.
 *
 * GlobeFreight is unaffected: its brand renders artwork, and .qt-brand__logo is
 * capped by --qt-logo-max-h-mobile rather than by this rule. */
.qt-brand__wordmark {
	font-family: var(--qt-font-heading);
	font-size: var(--qt-fs-h4);
	font-weight: var(--qt-fw-heading);
	line-height: 1.1;
	letter-spacing: var(--qt-ls-heading);
	text-transform: none;
	color: inherit;
	white-space: nowrap;
}

@media (min-width: 1024px) {
	.qt-brand__wordmark {
		font-size: var(--qt-fs-h3);
	}
}

/* ---- primary nav ---------------------------------------------------------
 * Mobile first: the nav is a panel that nav.js opens. Desktop (>=1024px) it is
 * an inline row. AT MEASURED a.menu-link: padding 0 16px, line-height 80px,
 * font-size 16px, colour #111111, hover #C2431C, current #045CB4.
 * GF MEASURED .menu-primary: a #F0F0F0 gradient pill, border-radius 5px,
 * box-shadow 0 0 10px #323232, height/line-height 43px, item colour #5D5D5D,
 * item padding 0 60px. Both are the same rule with different tokens. */
.qt-nav {
	display: none;
	flex: 1 1 100%;
	order: 3;
}

.qt-nav.is-open {
	display: block;
}

.qt-menu--primary {
	list-style: none;
	margin: 0;
	padding: 0;
	background-color: var(--qt-nav-bg);
	background-image: var(--qt-nav-bg-image);
	border-radius: var(--qt-nav-radius);
	box-shadow: var(--qt-nav-shadow);
	font-size: var(--qt-fs-nav);
	font-weight: var(--qt-fw-nav);
}

.qt-menu--primary li {
	position: relative;
	list-style: none;
}

/* Padding gives a >= 24x24 target measured UNIONED WITH THE LABEL. At the
 * mobile size the block padding alone clears 44px. */
.qt-menu--primary a {
	display: block;
	padding: var(--qt-space-2) var(--qt-gutter);
	color: var(--qt-nav-ink);
	text-transform: var(--qt-nav-transform);
	text-decoration: none;
	min-height: var(--qt-control-min);
	transition: var(--qt-transition);
}

/* Two signals, one rule. AutoTransport MEASURED changes the INK (#111111 ->
 * #C2431C on hover, #045CB4 when current) and leaves the background alone.
 * GlobeFreight's heritage nav does the opposite: the ink stays #5D5D5D and
 * li:hover paints a horizontal grey gradient. Both sites supply both tokens,
 * so neither site carries a rule the other has to fight. */
.qt-menu--primary a:hover,
.qt-menu--primary a:focus-visible {
	color: var(--qt-nav-ink-hover);
	background-image: var(--qt-nav-bg-hover);
	text-decoration: none;
}

.qt-menu--primary .current-menu-item > a,
.qt-menu--primary .current_page_item > a,
.qt-menu--primary .current-menu-ancestor > a {
	color: var(--qt-nav-ink-current);
	background-image: var(--qt-nav-bg-current);
}

@media (min-width: 1024px) {

	/* Desktop gets the full cap. This file is MOBILE-FIRST, so the base rule
	 * above carries --qt-logo-max-h-mobile and this overrides it -- putting
	 * the desktop value in the base rule would render a 64px logo inside a
	 * 64px mobile bar with zero clearance. */
	.qt-brand__logo {
		max-height: var(--qt-logo-max-h);
	}

	.qt-nav {
		display: block;
		flex: 0 1 auto;
		order: 0;
	}

	.qt-menu--primary {
		display: flex;
		flex-wrap: wrap;
		align-items: center;
		justify-content: flex-end;
	}

	/* The chevron belongs BESIDE its label, not under it. At >=1024
	 * .qt-submenu-toggle drops to position:static, and the <a> ahead of it is
	 * display:block, so inside a block <li> the button is pushed onto a line of
	 * its own -- one dead 8px row per parent item, on both sites.
	 *
	 * Direct children ONLY. `.qt-menu--primary li` would also catch the
	 * .sub-menu items, and a flex row there lays the dropdown's links out
	 * side-by-side instead of stacking them. Mobile is untouched: the toggle is
	 * position:absolute below 1024 and needs the <li> to stay a block box for
	 * the <a> to fill. */
	.qt-menu--primary > li {
		display: flex;
		align-items: center;
	}

	/* Pulling the chevron up beside the label costs the <a> its full-width
	 * block box, so a:hover no longer paints under the button -- a ~18px
	 * unpainted notch on every parent item, and only on the sites that signal
	 * hover with a background. Paint the ITEM, which is what GlobeFreight's
	 * heritage nav MEASURED does anyway (li:hover lays a horizontal grey
	 * gradient; the ink stays #5D5D5D). Free on AutoTransport, which signals
	 * hover by ink and supplies --qt-nav-bg-hover: none. Focus stays on the
	 * anchor's :focus-visible rule -- :focus-within here would also fire on a
	 * mouse click, which is the distinction that rule exists to keep. */
	.qt-menu--primary > li:hover {
		background-image: var(--qt-nav-bg-hover);
	}

	/* white-space: no-op on a nav that fits. Where the row IS too narrow the
	 * menu is meant to break BETWEEN items -- .qt-menu--primary already carries
	 * flex-wrap -- rather than split a two-word label down the middle and take
	 * the height of the whole bar with it. */
	.qt-menu--primary > li > a {
		padding: var(--qt-nav-item-pad);
		line-height: var(--qt-lh-nav);
		white-space: nowrap;
	}
}

/* Depth-2 submenu. 17 items on both sites; the heritage nav had dropdowns.
 * On mobile the submenu is a disclosure driven by nav.js's real <button>;
 * on desktop it is an absolutely positioned panel opened by hover OR by the
 * same button, so keyboard and touch both work. Hover alone is not reachable. */
.qt-menu--primary .sub-menu {
	list-style: none;
	margin: 0;
	padding: 0;
	display: none;
	background-color: var(--qt-submenu-bg);
	border: var(--qt-border-w) solid var(--qt-submenu-border);
	border-radius: var(--qt-radius);
	box-shadow: var(--qt-submenu-shadow);
}

.qt-menu--primary li.is-open > .sub-menu {
	display: block;
}

.qt-menu--primary .sub-menu a {
	padding-inline-start: calc(var(--qt-gutter) * 2);
}

@media (min-width: 1024px) {

	.qt-menu--primary .sub-menu {
		position: absolute;
		inset-block-start: 100%;
		inset-inline-start: 0;
		min-width: 220px;
		z-index: 30;
	}

	.qt-menu--primary li:hover > .sub-menu,
	.qt-menu--primary li:focus-within > .sub-menu {
		display: block;
	}

	.qt-menu--primary .sub-menu a {
		padding: var(--qt-space-2) var(--qt-gutter);
		line-height: normal;
	}
}

/* nav.js injects this button before every .sub-menu.
 *
 * `color: inherit` was wrong the moment a header band stopped matching the
 * page: the button's ancestors up to <body> paint no colour, so the chevron
 * inherited --qt-ink (#333333) rather than the nav ink beside it -- 1.18:1 on
 * GlobeFreight's #2B2622 band. At >=1024 it is pointer-events:none decoration
 * and the cost is only cosmetic, but BELOW 1024 it is the real disclosure
 * control for GF's three submenus, and an invisible control is a defect, not a
 * detail. --qt-nav-ink is by definition legible on --qt-nav-bg. */
.qt-submenu-toggle {
	position: absolute;
	inset-block-start: 0;
	inset-inline-end: 0;
	width: 44px;
	height: 44px;
	background: transparent;
	border: 0;
	cursor: pointer;
	color: var(--qt-nav-ink);
}

.qt-submenu-toggle::before {
	content: "";
	display: block;
	width: 8px;
	height: 8px;
	margin: 0 auto;
	border-inline-end: 2px solid currentColor;
	border-block-end: 2px solid currentColor;
	transform: rotate(45deg);
	transition: var(--qt-transition);
}

.qt-submenu-toggle[aria-expanded="true"]::before {
	transform: rotate(-135deg);
}

@media (min-width: 1024px) {
	.qt-submenu-toggle {
		position: static;
		width: auto;
		height: auto;
		padding: 0 var(--qt-space-1);
		pointer-events: none;
	}
}

/* An image used AS a menu label. nav-walker.php rebuilds GlobeFreight item
 * #138's raw <img> title into this element rather than printing it as literal
 * text. It has to be styled or the fix trades one visible defect for another. */
.qt-menu__img {
	display: inline-block;
	max-height: 1.5em;
	width: auto;
	vertical-align: middle;
}

/* ---- mobile toggle -------------------------------------------------------
 * 44x44 -- above the 24x24 WCAG 2.2 floor and at Apple HIG comfort. */
.qt-nav-toggle {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	padding: 0;
	background: transparent;
	border: 0;
	color: var(--qt-nav-ink);
	cursor: pointer;
}

.qt-nav-toggle__bar,
.qt-nav-toggle__bar::before,
.qt-nav-toggle__bar::after {
	display: block;
	width: 22px;
	height: 2px;
	background-color: currentColor;
	transition: var(--qt-transition);
}

.qt-nav-toggle__bar {
	position: relative;
}

.qt-nav-toggle__bar::before,
.qt-nav-toggle__bar::after {
	content: "";
	position: absolute;
	inset-inline-start: 0;
}

.qt-nav-toggle__bar::before { inset-block-start: -7px; }
.qt-nav-toggle__bar::after  { inset-block-start: 7px; }

.qt-nav-toggle[aria-expanded="true"] .qt-nav-toggle__bar {
	background-color: transparent;
}

.qt-nav-toggle[aria-expanded="true"] .qt-nav-toggle__bar::before {
	inset-block-start: 0;
	transform: rotate(45deg);
}

.qt-nav-toggle[aria-expanded="true"] .qt-nav-toggle__bar::after {
	inset-block-start: 0;
	transform: rotate(-45deg);
}

@media (min-width: 1024px) {
	.qt-nav-toggle {
		display: none;
	}
}

/* ---- parent-theme button bleed --------------------------------------------
 * MEASURED live on AutoTransport, 2026-09-10: Astra's generic `button` rules
 * (main.min.css plus its inline CSS) reach both chrome buttons --
 *   box-shadow 0 1px 2px rgba(0,0,0,.05) and border-radius 4px: every chevron
 *     and the hamburger drew as a faint raised box
 *   padding 12px 24px on the mobile submenu chevron, leaving its 44px box no
 *     content width, so the chevron sat off-centre
 *   button:focus  background-color --ast-global-color-1 -- a blue square behind
 *     the X after every tap, because a tap leaves focus on the button
 *   button:hover  color #FFFFFF -- white bars on a white header
 *   button:focus  outline 0 at (0,1,1), beating 10-reset's :focus-visible at
 *     (0,1,0): no keyboard focus ring on either control
 * `.qt-header` in front lifts all of this to (0,2,1). The ink is --qt-nav-ink in
 * every state, legible on --qt-header-bg by definition on both sites, and so is
 * the restored ring: --qt-focus-ring is dark ink and would vanish on a dark
 * header band. The stacked header's own chevron padding and hover ink sit at
 * (0,3,x) and still win. */
.qt-header .qt-nav-toggle,
.qt-header .qt-nav-toggle:hover,
.qt-header .qt-nav-toggle:focus,
.qt-header .qt-submenu-toggle,
.qt-header .qt-submenu-toggle:hover,
.qt-header .qt-submenu-toggle:focus {
	background-color: transparent;
	background-image: none;
	box-shadow: none;
	border-radius: 0;
	color: var(--qt-nav-ink);
}

.qt-header .qt-submenu-toggle {
	padding: 0;
}

.qt-header .qt-nav-toggle:focus-visible,
.qt-header .qt-submenu-toggle:focus-visible {
	outline: 2px solid var(--qt-nav-ink);
	outline-offset: -2px;
}

@media (min-width: 1024px) {
	/* Restores the desktop value from the .qt-submenu-toggle block above,
	 * which the padding: 0 just before this would otherwise override. */
	.qt-header .qt-submenu-toggle {
		padding: 0 var(--qt-space-1);
	}
}

/* ---- header CTA ---------------------------------------------------------
 * RETRACTION: an earlier revision of this comment said "both are empty today
 * pending the owner, so this selector matches nothing on either site". That
 * stopped being true when the numbers landed -- AT brand.php carries
 * 086 9990 559 and GF carries the owner-supplied number -- and the block below
 * shipped to two live headers with no rules at all behind it.
 *
 * It is the third child of a space-between row, so the only thing it needs is
 * to hold its own: the number is white-space:nowrap, so a shrunk box would not
 * reflow it, it would spill it. flex: 0 0 auto is what keeps the nav, not the
 * phone, absorbing the squeeze. */
.qt-header__cta {
	display: flex;
	align-items: center;
	gap: var(--qt-space-2);
	flex: 0 0 auto;
}

/* Same story as the wordmark, one step worse. This read --qt-accent, which is
 * the submit-button BACKGROUND in five places -- so it cannot be lightened to
 * clear the band without changing the colour of every button on both sites. On
 * GF's #2B2622 the raw accent #F1592A measures 4.42:1 and FAILS AA; the
 * band-scoped token carries #F26A3F at 4.92:1 instead. AT is unchanged. */
.qt-header__phone {
	display: inline-flex;
	align-items: center;
	/* A phone number IS a tap target, and it was not one. WCAG 2.2 SC 2.5.8
	 * measures the target unioned with the label: a 16px line of text is ~19px
	 * tall, under the 24px floor. This is the single most-tapped thing in the
	 * header on a phone, so it gets HIG comfort rather than the bare floor. */
	min-height: 44px;
	font-weight: var(--qt-fw-heading);
	color: var(--qt-phone-ink);
	white-space: nowrap;
	text-decoration: none;
}

.qt-header__phone:hover,
.qt-header__phone:focus-visible {
	text-decoration: underline;
}

/* The optional eyebrow (brand.php phone_label). Label and number stack right-
 * aligned inside the one link, so the tap target and the accessible name cover
 * both. The label reads --qt-nav-ink, which is legible on --qt-header-bg by
 * definition on both sites, muted by opacity rather than by a new colour token:
 * AT #111111 at .72 on #FFFFFF computes #545454, 7.5:1. Only the number takes
 * the hover underline -- underlining a 10px uppercase eyebrow is noise. */
.qt-header__phone:has(> .qt-header__phone-label) {
	flex-direction: column;
	align-items: flex-end;
	justify-content: center;
	line-height: 1.2;
}

.qt-header__phone:has(> .qt-header__phone-label):hover,
.qt-header__phone:has(> .qt-header__phone-label):focus-visible {
	text-decoration: none;
}

.qt-header__phone:hover .qt-header__phone-number,
.qt-header__phone:focus-visible .qt-header__phone-number {
	text-decoration: underline;
}

.qt-header__phone-label {
	font-size: 10px;
	font-weight: var(--qt-fw-heading);
	letter-spacing: .12em;
	text-transform: uppercase;
	color: var(--qt-nav-ink);
	opacity: .72;
}

/* ---- the header quote CTA ------------------------------------------------
 * The header carried a phone and no quote action at all, on a site whose whole
 * purpose is collecting quote requests. NN/g's hidden-navigation study is the
 * argument for putting it here rather than only in the menu: hiding an action
 * roughly halves the chance it is used, and this is THE action.
 *
 * It composes .qt-btn--primary from 50-components.css rather than restating
 * those values -- one home for what a primary button looks like. Only the
 * PLACEMENT lives here.
 *
 * Renders only when brand.php supplies quote_url, so a site that has not set
 * one ships no empty button. GlobeFreight is therefore unaffected until its
 * brand.php gains the key -- the same safe-degrade the phone block uses. */
.qt-header__quote {
	/* Below 1024 it takes a full-width line of its own UNDER the brand row.
	 * The alternative -- squeezing it inline -- needs ~447px of content in a
	 * 390px viewport, so something would wrap anyway; better to choose WHAT
	 * wraps than to let flex decide. A permanently visible primary action is
	 * also what the competitor teardown found in the sites that convert. */
	order: 4;
	flex: 1 1 100%;
	justify-content: center;
}

@media (min-width: 1024px) {
	.qt-header__quote {
		order: 0;
		flex: 0 0 auto;
	}
}

/* Header-scoped button overrides. NOT declared in 00-tokens.css on purpose:
 * each var() falls back to exactly what .qt-btn / .qt-btn--primary resolve to,
 * so a site that sets none of them renders its button unchanged -- AT's hover
 * and active fall back to --qt-accent-dark / --qt-accent-deep, which is what
 * 50-components paints there today. A site opts in with brand.php tokens
 * 'quote-bg', 'quote-ink', 'quote-fs', 'quote-pad'. GlobeFreight needs this:
 * its comp button is #F05020 with a 19px bold label, which clears AA as LARGE
 * text where the 15px default would not.
 *
 * `.qt-header` in front is load-bearing. 50-components.css loads AFTER this
 * file, so at equal specificity .qt-btn--primary(:hover) would win. */
.qt-header .qt-header__quote {
	background-color: var(--qt-quote-bg, var(--qt-accent));
	border-color: var(--qt-quote-bg, var(--qt-accent));
	color: var(--qt-quote-ink, var(--qt-accent-contrast));
	font-size: var(--qt-quote-fs, var(--qt-fs-base));
	padding: var(--qt-quote-pad, var(--qt-control-pad));
}

.qt-header .qt-header__quote:hover,
.qt-header .qt-header__quote:focus-visible {
	background-color: var(--qt-quote-bg, var(--qt-accent-dark));
	border-color: var(--qt-quote-bg, var(--qt-accent-dark));
	color: var(--qt-quote-ink, var(--qt-accent-contrast));
}

.qt-header .qt-header__quote:active {
	background-color: var(--qt-quote-bg, var(--qt-accent-deep));
	border-color: var(--qt-quote-bg, var(--qt-accent-deep));
}

/* ---- stacked header (brand.php header_layout => 'stacked') --------------
 * OWNER-DIRECTED, 2026-09-10 (AutoTransport comp "header polish A-v2"): the
 * brand row carries logo | phone | quote, and the primary nav takes a full-
 * width row of its own underneath, left-aligned under the logo. The header sits
 * INSIDE the sheet column, like the footer band, instead of bleeding edge to
 * edge. Every rule is scoped to the modifier, so a site without the key is
 * untouched -- GlobeFreight's comp keeps the one-row header.
 *
 * width: 100% for the same reason as .qt-footer below: Astra makes #page a
 * flex column, and auto inline margins on a flex item shrink it to content. */
.qt-header--stacked {
	width: 100%;
	max-width: var(--qt-measure);
	margin-inline: auto;
}

/* Below 1024: brand | phone | toggle on the first line, the open nav panel and
 * then the full-width quote CTA under it. The DOM order is brand, toggle, nav,
 * phone, quote, and space-between would park the toggle mid-row between logo
 * and phone -- MEASURED x166 of 390 before this. auto margin pushes phone and
 * toggle to the end together. */
.qt-header--stacked .qt-header__cta {
	order: 1;
	margin-inline-start: auto;
}

.qt-header--stacked .qt-nav-toggle {
	order: 2;
}

@media (min-width: 1024px) {

	/* A grid, not the flex row: the nav needs a row of its own with a rule
	 * across the FULL header width, while the brand row keeps its gutter. The
	 * gutter therefore moves from the container onto the row's two ends. */
	.qt-header--stacked .qt-header__inner {
		display: grid;
		grid-template-columns: minmax(0, 1fr) auto auto;
		grid-template-areas:
			"brand cta quote"
			"nav   nav nav";
		align-items: center;
		column-gap: var(--qt-space-3);
		row-gap: 0;
		max-width: none;
		min-height: 0;
		padding-inline: 0;
	}

	.qt-header--stacked .qt-brand {
		grid-area: brand;
		min-height: var(--qt-header-h);
		padding-inline-start: var(--qt-gutter-lg);
	}

	.qt-header--stacked .qt-header__cta {
		grid-area: cta;
		margin-inline-start: 0;
	}

	.qt-header--stacked .qt-header__quote {
		grid-area: quote;
		margin-inline-end: var(--qt-gutter-lg);
		min-height: calc(var(--qt-header-h) * .7);
		padding-inline: var(--qt-space-4);
	}

	.qt-header--stacked .qt-nav {
		grid-area: nav;
		border-top: var(--qt-border-w) solid var(--qt-header-border);
	}

	.qt-header--stacked .qt-menu--primary {
		justify-content: flex-start;
	}

	/* A parent item is ONE tab: label, chevron, one painted box. The label
	 * gives up its end padding and the chevron takes it, so the gap between
	 * them is small and the tab's right edge matches its left. */
	.qt-header--stacked .qt-menu--primary > li.qt-has-children > a {
		padding-inline-end: var(--qt-space-1);
	}

	.qt-header--stacked .qt-menu--primary > li > .qt-submenu-toggle {
		padding-inline: var(--qt-space-1) var(--qt-space-3);
	}

	.qt-header--stacked .qt-submenu-toggle::before {
		width: 6px;
		height: 6px;
	}

	/* Hover, open and CURRENT all read as the same tab: the item paints, and a
	 * 3px accent rule sits on the nav row's bottom edge. The rule is an inset
	 * shadow, not a border, so no state changes the row height. Current keeps
	 * its own ink (--qt-nav-ink-current) so "you are here" still differs from
	 * "you are pointing here". */
	.qt-header--stacked .qt-menu--primary > li:hover,
	.qt-header--stacked .qt-menu--primary > li:focus-within,
	.qt-header--stacked .qt-menu--primary > li.is-open {
		background-image: var(--qt-nav-bg-hover);
		box-shadow: inset 0 calc(var(--qt-border-w) * -3) 0 var(--qt-accent);
	}

	.qt-header--stacked .qt-menu--primary > li.current-menu-item,
	.qt-header--stacked .qt-menu--primary > li.current-menu-ancestor,
	.qt-header--stacked .qt-menu--primary > li.current_page_item,
	.qt-header--stacked .qt-menu--primary > li.current-page-ancestor {
		background-image: var(--qt-nav-bg-current);
		box-shadow: inset 0 calc(var(--qt-border-w) * -3) 0 var(--qt-accent);
	}

	/* The li paints the tab, so the anchor must not. The base rules paint
	 * `a:hover` and `.current-menu-* > a` too, and a child's background sits ON
	 * TOP of its parent's inset shadow: MEASURED live, the accent rule showed
	 * only under the chevron and was hidden under the label. */
	.qt-header--stacked .qt-menu--primary > li > a,
	.qt-header--stacked .qt-menu--primary > li > a:hover,
	.qt-header--stacked .qt-menu--primary > li > a:focus-visible {
		background-image: none;
	}

	.qt-header--stacked .qt-menu--primary > li:hover > .qt-submenu-toggle,
	.qt-header--stacked .qt-menu--primary > li:focus-within > .qt-submenu-toggle {
		color: var(--qt-nav-ink-hover);
	}

	.qt-header--stacked .qt-menu--primary > li.current-menu-item > .qt-submenu-toggle,
	.qt-header--stacked .qt-menu--primary > li.current-menu-ancestor > .qt-submenu-toggle,
	.qt-header--stacked .qt-menu--primary > li.current-page-ancestor > .qt-submenu-toggle {
		color: var(--qt-nav-ink-current);
	}

	/* The chevron turns up while its panel shows. Hover opens the panel at this
	 * width without touching aria-expanded, so the existing [aria-expanded]
	 * rule alone would leave it pointing down over an open panel. */
	.qt-header--stacked .qt-menu--primary > li:hover > .qt-submenu-toggle::before,
	.qt-header--stacked .qt-menu--primary > li:focus-within > .qt-submenu-toggle::before {
		transform: rotate(-135deg);
	}

	/* The panel hangs flush from the tab: square, ruled rows, bold labels. */
	.qt-header--stacked .qt-menu--primary .sub-menu {
		border-radius: 0;
		min-width: 214px;
	}

	.qt-header--stacked .qt-menu--primary .sub-menu li + li {
		border-top: var(--qt-border-w) solid var(--qt-submenu-border);
	}

	.qt-header--stacked .qt-menu--primary .sub-menu a {
		padding: 12px 16px;
		font-size: var(--qt-fs-small);
		font-weight: var(--qt-fw-heading);
		white-space: nowrap;
	}
}

/* ---- footer --------------------------------------------------------------
 * THE FOOTER SETS ITS OWN BACKGROUND ON THE FOOTER ELEMENT. That is the whole
 * point of the child theme owning the chrome.
 *
 * MEASURED on AutoTransport: footer#colophon itself computes rgba(0,0,0,0);
 * the #2B2622 band is painted by Astra's INNER footer-builder rows
 * (.site-primary-footer-wrap / .site-below-footer-wrap), and those rows do not
 * render at all on the four classic surfaces (404, search, page 79, post 158).
 * So classic and Elementor surfaces do not match today -- kit CSS is absent on
 * the classic templates, which the plan confirms visually.
 *
 * NOTE, AND THIS MATTERS: the automated claim that AutoTransport's footer text
 * renders "white on white at 1:1" on those surfaces was RETRACTED. A rendered
 * screenshot (at-classic-footer-check.png, 2026-08-06) shows white text on a
 * dark band, perfectly readable. The harvester scored the OUTER <p>/<div>,
 * whose computed colour is the inherited body ink, while the visible text is
 * inside child spans that hardcode color:#ffffff. Painting the background on
 * the footer element is a CONSOLIDATION -- one rule, both surfaces, no
 * dependency on Astra's builder rows -- not a repair of a defect that exists.
 *
 * Do not "fix" AutoTransport's footer-html-1 / footer-html-2 /
 * footer-copyright-editor widgets. Against a dark footer their hardcoded white
 * is correct, and it renders correctly today. */

/* TWO LAYERS, AND THE SPLIT IS THE FIX.
 *
 * footer#colophon is a SIBLING of #content, so it lands OUTSIDE .qt-container
 * -- the white sheet from 30-sheet.css. Painting the band on the footer
 * ELEMENT therefore bled it edge-to-edge under a sheet that stops at
 * --qt-measure, and on GlobeFreight the result reads as a slab dropped on the
 * bare texture rather than the bottom of the card. Heritage had it the other
 * way round: #footer-widgets lived INSIDE #wrap. The measured tokens say the
 * same thing out loud -- a full-bleed viewport band does not carry
 * border-radius:5px and box-shadow:0 0 10px #323232; an inset card does.
 *
 * So .qt-footer is now the SHEET GROUND (--qt-sheet at --qt-measure) and
 * .qt-footer__inner is the BAND (every footer token it used to hold). The band
 * already had max-width:--qt-measure, so it fills the ground exactly and the
 * white shows only in the two TOP corners, where the band's own radius rounds
 * away from a square-topped ground -- which is the join heritage had, and which
 * is what welds this element to the sheet stopping directly above it.
 *
 * The ground's BOTTOM corners take --qt-footer-radius, not --qt-sheet-radius,
 * and that is not a slip: GF measures the sheet at 10px and the footer box at
 * 5px, so a 10px ground under a 5px band leaves the band's corners poking
 * outside the curve. overflow:hidden would fix it and would also clip
 * --qt-footer-shadow (MEASURED 0 0 10px #323232), which is the more visible
 * loss. Matching the two radii costs nothing on either site -- AT is 0/0.
 *
 * On AutoTransport the band is square and opaque, so the ground never shows at
 * all and the only change there is that the dark bar now stops at 1240px
 * instead of at the viewport edge.
 *
 * Not done in PHP. chrome-footer.php's closing order (.ast-container/#content
 * then #page) is load-bearing for Astra's five non-Elementor surfaces, and
 * nothing here needs the footer moved inside #content to work.
 *
 * width: 100% IS NOT REDUNDANT, AND IT IS ASTRA'S DOING. Where Astra is the
 * parent it prints `#page { display: flex; flex-direction: column }` inline
 * (astra-theme-css-inline-css), which makes this footer a FLEX ITEM -- and auto
 * inline margins on a flex item absorb the cross-axis space instead of letting
 * the item stretch. The footer shrank to its content: MEASURED 253px wide at
 * 390, 768 and 1366 on AutoTransport, a skinny dark column centred on the
 * texture. With an explicit width the auto margins only centre what
 * max-width leaves over. In block flow (GlobeFreight's #page MEASURES block)
 * width:100% resolves to exactly what auto did, because this box carries no
 * padding and no border. */
.qt-footer {
	width: 100%;
	max-width: var(--qt-measure);
	margin-inline: auto;
	background-color: var(--qt-sheet);
	border-radius: 0 0 var(--qt-footer-radius) var(--qt-footer-radius);
	color: var(--qt-footer-ink);
}

.qt-footer__inner {
	max-width: var(--qt-measure);
	margin-inline: auto;
	padding-inline: var(--qt-gutter);
	padding-block: var(--qt-space-5) var(--qt-space-3);
	background-color: var(--qt-footer-bg);
	background-image: var(--qt-footer-bg-image);
	border-top: var(--qt-border-w) solid var(--qt-footer-rule);
	border-radius: var(--qt-footer-radius);
	box-shadow: var(--qt-footer-shadow);
	display: flex;
	flex-direction: column;
	gap: var(--qt-space-3);
}

@media (min-width: 1024px) {
	.qt-footer__inner {
		padding-inline: var(--qt-gutter-lg);
	}
}

/* A footer that carries a MENU puts the menu and the link groups on one row.
 *
 * Stacked in a full-width band, AutoTransport's three menu links and its
 * contact group both hug the left edge and leave most of the band empty. A
 * wrapping row with space-between puts the menu left and the contact group
 * right, and the legal line keeps a full-width line of its own underneath.
 * align-items: baseline sets "About Us" on the same line as the "Contact
 * AutoTransport" heading, not 3px above it.
 *
 * NO MEDIA QUERY, deliberately, so the 1024px rule in this file's header is
 * not bent for a footer. The row wraps on content: the two blocks need ~455px
 * side by side, so 390 stacks them (350px of band) and 768 and 1366 do not.
 * MEASURED 2026-09-10: menu x20 / contact x541 at 768, x83 / x1076 at 1366.
 *
 * Keyed on the menu's PRESENCE rather than on a site, and today that is AT
 * only: GlobeFreight resolves no footer menu, chrome-footer.php emits no
 * .qt-footer__nav there, and its sitemap + widget-column stack is unchanged
 * (MEASURED identical at 390, 768 and 1366 with and without these rules). */
.qt-footer__inner:has(> .qt-footer__nav) {
	flex-direction: row;
	flex-wrap: wrap;
	justify-content: space-between;
	align-items: baseline;
	column-gap: var(--qt-space-5);
}

.qt-footer__inner:has(> .qt-footer__nav) > .qt-footer__legal {
	flex: 1 1 100%;
}

/* MEASURED AT: footer link and footer svg both #FFFFFF on #2B2622 -- 14.97:1.
 * MEASURED GF: #footer-widgets a is #5397B4 on the #F0F0F0 gradient -- 2.86:1,
 * which FAILS AA. That failure is present in the heritage target AND on the
 * live site; it is pre-existing, not introduced here, and the plan says decide
 * it explicitly rather than silently. It is NOT silently fixed here: GF's
 * brand.php ships the measured #5397B4 and the exception is documented. */
.qt-footer a {
	color: var(--qt-footer-link);
	text-decoration: none;
}

/* Hover and focus CHANGE COLOUR, not decoration alone -- owner, 2026-09-10:
 * with link and ink both #FFFFFF the underline was the only thing that moved.
 *
 * --qt-footer-link-hover is OPTIONAL: a var() fallback, deliberately not
 * declared in 00-tokens.css (same pattern as the quote-* tokens). It is TEXT on
 * the footer BAND, so its floor is 4.5:1 against footer-bg, not the sheet --
 * and the accent fallback is an on-white token that fails on both dark bands,
 * which is why both brand.php files set it.
 *
 * The lead link is listed because its own colour rule below is (0,3,1) and
 * would out-rank (0,2,1) here, keeping the phone white on hover.
 *
 * AT: Elementor kit 163's custom CSS carries `#colophon a:hover { color:
 * #F15A29 !important }` and `#colophon a { color: #FFFFFF !important }`. No
 * theme rule beats either, so on AutoTransport this rule is inert until that
 * kit CSS is removed. MEASURED 2026-09-10. */
.qt-footer a:hover,
.qt-footer a:focus,
.qt-footer .qt-footer__links a.qt-footer__link--lead:hover,
.qt-footer .qt-footer__links a.qt-footer__link--lead:focus {
	color: var(--qt-footer-link-hover, var(--qt-accent));
	text-decoration: underline;
}

/* currentColor keeps the social icons matched to the footer ink on both sites
 * -- AT MEASURED #colophon svg { fill: currentColor } and #FFFFFF at 14.97:1. */
.qt-footer svg {
	fill: currentColor;
}

/* The focus ring is an ink colour, which is invisible on AT's dark footer.
 * Re-point it to the footer ink here rather than weakening the global rule. */
.qt-footer :focus-visible {
	outline-color: var(--qt-footer-ink);
}

.qt-menu--footer {
	display: flex;
	flex-wrap: wrap;
	gap: var(--qt-space-2) var(--qt-space-3);
	list-style: none;
	margin: 0;
	padding: 0;
}

.qt-menu--footer a {
	display: inline-block;
	padding-block: var(--qt-space-1);
	min-height: var(--qt-control-min);
}

/* Gate: zero href="#" in the footer. That is a served-HTML grep, not a CSS
 * concern -- noted here because this is where someone would look. */

/* Footer sitemap -- the headed link columns from brand.php['footer_link_groups'].
 * Distinct from .qt-footer__cols below: that grid is WIDGET areas and its column
 * count is a token because it is MEASURED per site. This one is navigation the
 * theme owns, so the count is not a token at all -- auto-fit means a site can add
 * or drop a group in brand.php without touching this file or inventing a
 * --qt-sitemap-cols nobody measured.
 *
 * No template below 1024: a bare `display: grid` stacks every group full-width,
 * which is what a thumb wants and what the 390 parity viewport measures. */
.qt-footer__sitemap {
	display: grid;
	gap: var(--qt-space-3);
}

@media (min-width: 1024px) {
	.qt-footer__sitemap {
		grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
	}
}

.qt-footer__links {
	list-style: none;
	margin: 0;
	padding: 0;
}

/* The 24px floor is WCAG 2.2 SC 2.5.8; a 15px line plus 5px padding-block
 * clears it at 25px.
 *
 * .qt-footer__col a is in this rule because WIDGET content was the gap. The
 * footer menu had the treatment and the sitemap gets it by construction, but a
 * link typed into a text widget got nothing -- MEASURED at 20px in a headless
 * render at all three parity viewports, which is under the floor. GlobeFreight's
 * phone number and its only email link are both exactly that, so the two most
 * valuable targets in the footer were the two that missed. Widget markup is
 * arbitrary and owner-edited, so the floor has to come from here; it cannot be
 * left to whoever writes the widget. */
.qt-footer__links a,
.qt-footer__col a {
	display: inline-block;
	padding-block: var(--qt-space-1);
	min-height: var(--qt-control-min);
}

/* Footer columns. AT renders 1, GF renders 3 (.footer-widgets-1/2/3 in the
 * heritage markup, carrying the Visa-Mastercard composite badge in column 1
 * and a Facebook like-box iframe in column 3 -- NOT a trust badge, that claim
 * was refuted). The count is a token so the grid stays byte-identical. */
.qt-footer__cols {
	display: grid;
	gap: var(--qt-space-3);
}

@media (min-width: 1024px) {
	.qt-footer__cols {
		grid-template-columns: repeat(var(--qt-footer-cols), minmax(0, 1fr));
	}

	/* --qt-footer-cols is the REGISTERED count. The RENDERED count is decided
	 * per request: quadtech_render_footer_widgets() emits a .qt-footer__col only
	 * for a sidebar is_active_sidebar() says has something in it. GlobeFreight
	 * registers three and fills two (qt-footer-3 is empty), so the badge and the
	 * contact block were being laid out across two thirds of the footer with a
	 * dead third track holding the remainder. Collapse to what actually
	 * rendered.
	 *
	 * :has() takes the specificity of its argument, so these beat the rule above
	 * wherever they match, order notwithstanding. Where :has() is unsupported
	 * the grid falls back to the registered count -- today's behaviour, not a
	 * worse one. repeat(auto-fit, minmax(0, 1fr)) is NOT the shorter way to
	 * write this: auto-fit resolves its repetition count from a definite track
	 * size, and a 0 minimum makes that count infinite, so the whole declaration
	 * is invalid. */
	.qt-footer__cols:has(> .qt-footer__col:nth-child(1):last-child) {
		grid-template-columns: minmax(0, 1fr);
	}

	.qt-footer__cols:has(> .qt-footer__col:nth-child(2):last-child) {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

/* min-width:0 on both, or a long unbroken string in one cell refuses to shrink
 * and the whole grid overflows. That is the 390 horizontal-overflow gate. */
.qt-footer__col,
.qt-footer__group {
	min-width: 0;
}

/* `color: inherit` is load-bearing, not tidiness: 10-reset paints every h1-h6
 * --qt-ink-heading, which is #333333 on BOTH sites, and AutoTransport's footer
 * band is dark. Inheriting picks up --qt-footer-ink instead. A sitemap heading
 * and a widget heading sit side by side in the same band, so they read the same
 * token rather than drifting apart. */
.qt-widget__title,
.qt-footer__group-title {
	font-size: var(--qt-fs-h4);
	color: inherit;
	margin-block-end: var(--qt-space-2);
}

.qt-footer__legal {
	border-top: var(--qt-border-w) solid var(--qt-footer-rule);
	padding-block-start: var(--qt-space-3);
	font-size: var(--qt-fs-small);
	text-align: center;
}

/* ---- columns footer (brand.php footer_brand) -----------------------------
 * OWNER-DIRECTED, 2026-09-10 (AT "footer polish B", GF "chrome together C"):
 * one row of Brand | link groups... at >=1024, stacked below. Every rule is
 * scoped to .qt-footer--columns / .qt-footer__main, which chrome-footer.php
 * emits only when the brand column produced markup, so a site without
 * footer_brand renders exactly as before.
 *
 * The groups are EQUAL columns in auto flow rather than a template with a
 * count, so AT's four and GF's four -- or a site's three -- need no per-site
 * track list. The brand/sitemap split is a var() with a fallback for the same
 * reason the quote vars are: not in 00-tokens, opt-in through brand tokens
 * 'footer-main-cols'. The default is AT's comp: a 262px brand track and four
 * ~199px groups inside the 1160px band at 1240. */
.qt-footer__main {
	display: grid;
	gap: var(--qt-space-4);
}

.qt-footer--columns .qt-footer__sitemap {
	/* 240px, not rem: Astra rescales the root to 14.592px at <=768, which
	 * would move the wrap point. 768 gets two columns, 390 gets one. */
	grid-template-columns: repeat(auto-fit, minmax(min(240px, 100%), 1fr));
	gap: var(--qt-space-4) var(--qt-space-3);
}

@media (min-width: 1024px) {
	.qt-footer--columns .qt-footer__inner {
		padding-inline: calc(var(--qt-gutter-lg) * 2);
		gap: var(--qt-space-5);
	}

	.qt-footer__main {
		grid-template-columns: var(--qt-footer-main-cols, minmax(0, 13fr) minmax(0, 43fr));
		column-gap: var(--qt-space-4);
	}

	.qt-footer--columns .qt-footer__sitemap {
		grid-template-columns: none;
		grid-auto-flow: column;
		grid-auto-columns: minmax(0, 1fr);
		column-gap: var(--qt-space-4);
	}
}

/* Brand-column rhythm. The reset gives every p a --qt-space-4 bottom margin at
 * (0,0,1); `.qt-footer__brand p` clears it at (0,1,1), and the per-part rules
 * below re-add spacing at (0,2,0) so they win without !important. */
.qt-footer__brand p {
	margin: 0;
}

.qt-footer__brand .qt-footer__wordmark,
.qt-footer__brand .qt-footer__brand-logo {
	margin-block-end: var(--qt-space-3);
}

.qt-footer__brand .qt-footer__tagline {
	margin-block-end: var(--qt-space-2);
}

.qt-footer__brand .qt-footer__badge {
	margin-block-start: var(--qt-space-3);
}

/* The text mark carries the accent as a bar, not as ink: #C2431C text on the
 * #2B2622 band would be 2.9:1. A 4px bar is a non-text graphic and the white
 * wordmark beside it is 14.97:1. */
.qt-footer__wordmark {
	font-family: var(--qt-font-heading);
	font-size: var(--qt-fs-h3);
	font-weight: 700;
	line-height: 1.1;
	padding-inline-start: var(--qt-space-2);
	border-inline-start: 4px solid var(--qt-accent);
}

.qt-footer__brand-img {
	display: block;
	width: auto;
	height: auto;
	max-width: 100%;
	max-height: var(--qt-footer-logo-max-h, var(--qt-logo-max-h));
}

.qt-footer__tagline {
	font-size: 11px;
	font-weight: 700;
	letter-spacing: .16em;
	text-transform: uppercase;
	opacity: var(--qt-footer-title-opacity, .78);
}

/* 15em at 14px is the comp's ~210px measure: four short lines, not two long. */
.qt-footer__blurb {
	font-size: var(--qt-fs-small);
	line-height: 1.7;
	max-width: 15em;
}

.qt-footer__badge-img {
	display: block;
	width: auto;
	height: auto;
	max-width: 100%;
}

/* Group titles become quiet labels. Muted by OPACITY on the footer ink rather
 * than a new colour token: white at .78 on #2B2622 computes #D0CFCE, 9.6:1. GF's comp
 * titles are full white and set 'footer-title-opacity' => '1'. */
.qt-footer--columns .qt-footer__group-title {
	font-size: var(--qt-fs-small);
	font-weight: 700;
	letter-spacing: .14em;
	line-height: 1.3;
	text-transform: uppercase;
	opacity: var(--qt-footer-title-opacity, .78);
	margin-block-end: var(--qt-space-2);
}

/* A 'stack' group opens under the one above it, in the same column. */
.qt-footer--columns .qt-footer__links + .qt-footer__group-title {
	margin-block-start: var(--qt-space-4);
}

.qt-footer--columns .qt-footer__links a {
	font-size: calc(var(--qt-fs-base) - 1px);
	line-height: 1.5;
	overflow-wrap: anywhere;
}

/* The lead link -- a phone number -- is the most-tapped thing in the footer, so
 * it gets HIG comfort (44px) and heading weight, the same treatment the header
 * phone already has. Specificity (0,3,1) so it beats the columns rule above. */
.qt-footer .qt-footer__links a.qt-footer__link--lead {
	display: inline-flex;
	align-items: center;
	min-height: 44px;
	font-size: calc(var(--qt-fs-base) * 1.125);
	font-weight: var(--qt-fw-heading);
	/* Opt-in, not in 00-tokens: GF's comp sets its phone white while its
	 * footer links stay accent-blue. AT's link ink is already white. */
	color: var(--qt-footer-lead-ink, var(--qt-footer-link));
}
