/*
* Hero Headline Offset
*/
.hero-headline-offset {
	left: -180px;
}

@media (max-width: 991px) {
	.hero-headline-offset {
		left: 0;
	}
}

/*
* Home Hero - Container Height, Set Correctly on First Paint
* The hero container ships with a hardcoded style="height: 700px" in the
* HTML as a fallback, corrected by the Porto theme's own
* data-dynamic-height plugin (js/theme.js) to the right value for the
* current viewport - but that plugin only auto-runs its initial
* correction for widths under 992px ("Mobile First Load", js/theme.js);
* at >=992px 700px already happens to be correct, so it's left alone.
* On any narrower viewport (tablet/mobile), that means the container
* briefly paints at the wrong, too-tall 700px before JS runs and shrinks
* it down to the real 600/500/410px value - which visibly resized the
* background slideshow underneath it on every load once the pan/zoom
* treatment was added (previously just a static image, so the resize
* wasn't as noticeable).
*
* Fix: replicate the exact same breakpoint -> height mapping as plain
* CSS, !important so it always wins over both the hardcoded inline
* fallback and any inline height the JS plugin sets later on resize.
* Being CSS (parsed and applied in <head> before the body paints), the
* correct height is there from the very first frame - no JS timing to
* race, no flash to hide. The JS plugin keeps running harmlessly
* alongside this (data-dynamic-height/theme.js untouched); its own
* inline-height writes are just always immediately masked by this rule.
*/
.hero-dynamic-height {
	height: 700px !important;
	overflow-x: clip;
}

/* Clip the decorative title ribbon at the viewport, preserving vertical overflow. */
.main > .section:has(.hero-title-container) {
	overflow-x: clip;
}

/* Card image width is fluid; HTML height attributes must scale with it. */
.post-image .card-img-top {
	height: auto;
}

/* Improve neutral text contrast without changing the brand palette. */
:root {
	--default: #6b6b6b;
}

.text-color-grey {
	color: #6b6b6b !important;
}

.form-control::placeholder {
	color: #6b6b6b;
	opacity: 1;
}

/* Keep the contact strip below the logo's existing overlap/stacking. */
#header .header-contact-bar {
	background: #676767;
	font-size: 13px;
	line-height: 1;
	flex-shrink: 0;
}

#header .header-contact-bar > .container {
	height: 28px;
	gap: 20px;
	white-space: nowrap;
}

#header .header-contact-bar a {
	color: #fff;
	display: inline-flex;
	align-items: center;
	height: 100%;
}

#header .header-contact-bar a:hover {
	text-decoration: underline;
}

/* Hidden logo variants must not leave empty keyboard stops. */
#header .header-logo a:has(> .logo-sticky),
html.sticky-header-active #header .header-logo a:has(> .logo) {
	visibility: hidden;
}

html.sticky-header-active #header .header-logo a:has(> .logo-sticky) {
	visibility: visible;
}

@media (max-width: 991px) {
	#header .header-logo a:has(> .logo) {
		visibility: hidden;
	}
	#header .header-logo a:has(> .logo-sticky) {
		visibility: visible;
	}
}

:is(a, button, input, textarea, select):focus-visible {
	outline: 3px solid #212529;
	outline-offset: 3px;
	box-shadow: 0 0 0 3px #fff;
}

.skip-link {
	position: fixed;
	top: 8px;
	left: 8px;
	z-index: 10000;
	padding: 10px 16px;
	background: #fff;
	color: #212529;
	transform: translateY(-150%);
	opacity: 0;
}

.skip-link:focus {
	transform: none;
	opacity: 1;
}

/* Keep desktop submenus reachable by keyboard as well as pointer. */
@media (min-width: 992px) {
	#header .header-nav-main nav > ul > li.dropdown:focus-within > .dropdown-menu {
		display: block;
		opacity: 1;
		visibility: visible;
		transform: none;
	}
}

/* Keep the headline clear of the foreground engineer on phones. */
@media (max-width: 575px) {
	.hero-dynamic-height .custom-big-text-style-1 {
		font-size: clamp(2.7rem, 10vw, 3.4rem);
		letter-spacing: 2px;
	}
}

/* Scale the established diamond arrangement to fit narrow phones. */
@media (max-width: 419px) {
	.diamonds-wrapper {
		zoom: 0.8;
	}
}

@media (max-width: 991px) {
	.hero-dynamic-height {
		height: 600px !important;
	}
}

@media (max-width: 767px) {
	.hero-dynamic-height {
		height: 500px !important;
	}
}

@media (max-width: 575px) {
	.hero-dynamic-height {
		height: 410px !important;
	}
}

/*
* Home Hero - Pan & Crossfade
* An 80px travel over the 13.75s visible window gives 5.82 CSS px/s at
* every viewport width, close to the previous 1440px desktop speed.
* Extra 40px on each side provides the travel buffer; cover keeps the
* photos proportional. The existing 5% vertical crop is retained.
* Fixed pixel travel means resize needs no measurements or timer reset.
*/
.hero-bg-slideshow {
	--hero-pan-half: 40px;
}

.hero-bg-slide-layer {
	left: calc(-1 * var(--hero-pan-half)) !important;
	right: calc(-1 * var(--hero-pan-half)) !important;
	top: -2.5% !important;
	bottom: -2.5% !important;
	background-size: cover;
	background-position: center;
	background-repeat: no-repeat;
	opacity: 0;
	transform: translateX(var(--hero-pan-half));
}

/* First image is visible even without JS or while later images load.
 * Start 1.25s into the cycle, fully opaque, with the matching pan position
 * (40px - 80px * 1.25/13.75). This avoids a jump when images become ready. */
.hero-bg-slide-layer--initial {
	background-image: url("../img/hero/scene-1.webp");
	opacity: 1;
	transform: translateX(calc(var(--hero-pan-half) * 9 / 11));
}

@media (prefers-reduced-motion: no-preference) {
	.hero-bg-slideshow--ready > .hero-bg-slide-layer {
		animation: heroBgPanCrossfade 50s linear infinite backwards;
	}

	.hero-bg-slideshow > .hero-bg-slide-layer:nth-child(1) {
		animation-delay: -1.25s;
	}

	.hero-bg-slideshow > .hero-bg-slide-layer:nth-child(2) {
		animation-delay: 11.25s;
	}

	.hero-bg-slideshow > .hero-bg-slide-layer:nth-child(3) {
		animation-delay: 23.75s;
	}

	.hero-bg-slideshow > .hero-bg-slide-layer:nth-child(4) {
		animation-delay: 36.25s;
	}
}

@keyframes heroBgPanCrossfade {
	0% {
		opacity: 0;
		transform: translateX(var(--hero-pan-half));
	}
	2.5%, 25% {
		opacity: 1;
	}
	27.5% {
		opacity: 0;
		transform: translateX(calc(-1 * var(--hero-pan-half)));
	}
	100% {
		opacity: 0;
		transform: translateX(calc(-1 * var(--hero-pan-half)));
	}
}

/* Reduced motion uses only the first scene, static and cover/center. */
@media (prefers-reduced-motion: reduce) {
	.appear-animation,
	[data-appear-animation] {
		opacity: 1 !important;
		animation: none !important;
		transition: none !important;
	}

	.highlight-animated::after {
		animation: none !important;
		transition: none !important;
	}

	.hero-bg-slide-layer {
		inset: 0 !important;
		transform: none;
	}
}

/* Keep content readable without JavaScript, or if theme initialisation fails. */
html:not(.appear-animations-ready) .appear-animation {
	opacity: 1;
}

/* Scroll position supplies the sequence once columns stack on small screens. */
@media (max-width: 767px) {
	.appear-animation {
		animation-delay: 0ms !important;
	}
}

/*
* Home Hero - Scrim
* Sits above the marquee, below the text/content container
* (.container.z-index-1 holding the headline, engineer photo and
* tagline - untouched). Subtle dark tint so text contrast stays
* consistent no matter which part of which background photo is
* currently in view, without visibly darkening or flattening the
* photos themselves.
*/
.hero-bg-scrim {
	background-color: rgba(0, 0, 0, 0.18);
	pointer-events: none;
}

/*
* Footer Newsletter Form - Equal Field Heights
* First Name and Email Address sit in separate .input-group instances
* (First Name has no button, so nothing stretches it - Bootstrap's
* .input-group align-items:stretch only equalizes elements WITHIN the
* same group, not across separate ones). The submit button contains a
* 27px icon image, which - once its own padding is added - renders
* taller than a plain .form-control, so Email's group (stretched to
* match the button) ends up taller than First Name's. Pin both fields
* and the button to one explicit shared height so they match regardless
* of that content-driven sizing, and centre the icon within the
* button's now-fixed height.
*/
.newsletter .mailerlite-form .form-control,
.newsletter .mailerlite-form .btn {
	height: 44px;
}

.newsletter .mailerlite-form .btn {
	display: flex;
	align-items: center;
	justify-content: center;
}

/*
* Faster Scroll-In Animations - Mobile
* The theme sets each element's fade-in "animation-delay"/"animation-duration"
* as an inline style (from data-appear-animation-delay/-duration attributes),
* often staggered up to 1-2+ seconds per element. That choreography reads fine
* on desktop but feels laggy/uncertain on mobile scrolling. Collapse both to
* near-instant on mobile only - inline styles need !important to be overridden.
* Desktop timing is untouched.
*/
@media (max-width: 991px) {
	.appear-animation {
		animation-delay: 50ms !important;
		animation-duration: 250ms !important;
		transition-delay: 50ms !important;
		transition-duration: 250ms !important;
	}
}

/*
* Sticky Sidebar - Prevent Visual Re-Fade on Scroll
* Reported: sidebar content on the sticky-sidebar pages (data-plugin-sticky
* - About, Services, and the 5 individual service pages) fades in
* correctly on load, then appears to fade in again the first time the
* user scrolls far enough for the sticky plugin (js/theme.js) to flip
* the <aside> between static/fixed/absolute positioning.
*
* Investigated: this is NOT the earlier-diagnosed nested-wrapper bug
* (a wrapper animating on top of already-animated children) - an
* exhaustive scan found no instance of that pattern anywhere on the
* site, including these pages. The sticky position toggle is the only
* scroll-triggered mechanism active specifically on these pages, so it's
* the strongest remaining candidate, but confirming the exact rendering
* mechanism needs live browser inspection (devtools Animations panel),
* which wasn't available here.
*
* This is a mitigation, not a root-cause fix: once an element's own
* single-fire appear-animation has genuinely already completed (theme.js
* adds .appear-animation-visible after that happens, never before), pin
* its opacity at the settled end value with !important - a normal
* declaration's !important overrides a running/replaying CSS animation's
* computed value for that property regardless of what retriggers it,
* without altering the shared animation system itself or affecting the
* real first play-through. If this doesn't fully resolve it, the actual
* trigger needs identifying with devtools before a more targeted fix is
* possible.
*/
[data-plugin-sticky] .appear-animation.appear-animation-visible {
	opacity: 1 !important;
}

/*
* Header Scroll Background Opacity
* The theme's construction demo sets the sticky header background to 80%
* opacity (css/components.css). Raised further to 90% so a
* busy part of the page scrolling behind it is much less distracting.
*/
html.sticky-header-active #header .header-body {
	background: rgba(255, 255, 255, 0.9);
}

/*
* LinkedIn Ribbon - Multi-Platform Social Icons
* Each icon gets its own fixed-size solid circle so it reads clearly at a
* glance (LinkedIn blue, Instagram purple, Facebook pale blue), all
* identical in size. Static links, not buttons - no hover state needed.
*/
.ribbon-social-icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 28px;
	height: 28px;
	border-radius: 100%;
	font-size: 14px;
	text-decoration: none !important;
	flex: 0 0 auto;
}

/* Keep inline homepage icons aligned below the desktop breakpoint. */
@media (max-width: 991px) {
	.home-credibility-ribbon .ribbon-social-icon {
		vertical-align: middle;
	}
}

/* Stack and centre the homepage credibility groups on phones only. */
@media (max-width: 575px) {
	.home-credibility-ribbon {
		display: flex;
		flex-direction: column;
		text-align: center;
	}

	.home-credibility-ribbon > div {
		text-wrap: balance;
	}

	.home-credibility-ribbon > a {
		margin-left: 0 !important;
		white-space: nowrap;
	}
}

.ribbon-social-icon-linkedin {
	background-color: #0073b2;
	color: #fff !important;
}

.ribbon-social-icon-anniversary {
	background-color: #f4c542;
	color: #292929 !important;
}

.linkedin-sidebar a:hover {
	text-decoration: underline !important;
	text-decoration-thickness: 2px;
}

.linkedin-sidebar a:focus-visible {
	outline: 2px solid #292929;
	outline-offset: 3px;
}

.ribbon-social-icon-instagram {
	background-color: #8134af;
	color: #fff !important;
}

.ribbon-social-icon-facebook {
	background-color: #cfe3f7;
	color: #1a3a5c !important;
}

/*
* Trust Badges - Desaturated, Full Colour on Hover
* Grayscale applies on all devices, including touch/mobile (which has no
* hover to reveal colour, so they just stay desaturated there). The colour
* reveal on hover only fires on devices that actually support hovering.
*/
.trust-badge {
	filter: grayscale(100%);
	transition: filter 0.3s ease;
}

@media (hover: hover) {
	.trust-badge:hover {
		filter: grayscale(0%);
	}
}

/*
* Pending-info placeholders
* Marks values not yet available (email, VAT/ICO numbers, GTM ID, etc.)
* so they're easy to spot in the browser and to grep for ("todo-placeholder").
*/
.todo-placeholder {
	background: #fff3a3;
	padding: 0 4px;
	border-radius: 2px;
}

/*
* Case Study Image Placeholders
* Used on project/case-study pages where a Before/During/After photo doesn't
* exist yet. Dashed border + icon + label - visibly a placeholder, not a
* real asset, until a proper photo is supplied.
*/
.case-study-placeholder-image {
	aspect-ratio: 2 / 1;
	border: 2px dashed #ccc;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	color: #999;
	text-align: center;
	padding: 1.5rem;
}

/*
* .mb-5 Override
* Bootstrap sets this utility to margin-bottom: 3rem !important. Reduced
* site-wide to 1rem. Loaded after bootstrap.min.css so this wins the cascade
* despite both being !important.
*/
.mb-5 {
	margin-bottom: 1rem !important;
}

/*
* Service Card Extra Spacing (Home)
* .mb-5 above is reduced to 1rem (16px) site-wide. These 5 home service
* cards need 30px more than that (46px total). Scoped class, not .mb-5.
*/
.service-card-col {
	margin-bottom: 46px !important;
}

/* Home audiences: quiet open blocks, using the existing brand accent. */
.home-audiences .home-audience {
	border-top: 2px solid var(--primary);
	padding-top: 1.5rem;
}

.home-audiences .home-audience h3 {
	line-height: 1.4;
}

@media (min-width: 992px) {
	.home-audiences .home-audience h3 {
		min-height: 2.8em;
	}
}

/*
* Blog List Article Spacing (blog.html only)
* .mb-5 above is reduced to 1rem (16px) site-wide. These list cards need
* 40px more (56px total). Scoped to blog.html's list articles only -
* .post-block/.post-author etc on the single-post pages are unaffected.
*/
.blog-list-article {
	margin-bottom: 56px !important;
}

/*
* Blog List Article Separator (blog.html only)
* Adds a divider under each card's "Read Article" link so it's clearer
* where one article ends and the next begins. Skipped on the last card
* so there's no stray line sitting right before the sidebar/footer gap.
*/
.blog-list-article:not(:last-child) {
	padding-bottom: 40px;
	border-bottom: 1px solid rgba(0, 0, 0, 0.06);
}

/*
* Hero Diagonal Title Banner - 2-line fix
* The dark diagonal SVG banner behind the hero <h1> text is a fixed
* height sized for one line - it must stay that size (not grow/resize).
* When js/custom.js detects the title text wraps to 2 lines, it adds
* .hero-diagonal-title-two-line to the <h1> - shift only the text span
* up so the extra line still reads cleanly against the unchanged banner.
* The banner (.custom-svg-position-1 and its svg) is untouched here.
* Value tuned/confirmed in Chrome DevTools against the real render.
*/
.hero-diagonal-title.hero-diagonal-title-two-line > span:first-child {
	margin-top: -18px;
}

/*
* Hero Diagonal Title Banner - 2-line fix, shorter titles
* The -18px shift above was tuned against long titles that wrap onto a
* visually heavy 2nd line - short titles (<=17 characters, e.g. "Bird
* Control") look over-corrected with the same shift. js/custom.js also
* measures the title text length and adds this class (alongside
* -two-line) only when the title is short, to zero the shift back out.
* One extra class than the rule above, so this always wins regardless of
* source order.
*/
.hero-diagonal-title.hero-diagonal-title-two-line.hero-diagonal-title-two-line-short > span:first-child {
	margin-top: 0;
}

/*
* Hero Diagonal Title Banner - 2-line fix, mobile horizontal clearance
* On mobile the wrapped 2nd line otherwise gets clipped by the polygon's
* diagonal cut on its left edge. Hardcoded nudge, not calculated from
* text/line count - value tuned/confirmed in Chrome DevTools.
*/
@media (max-width: 767px) {
	.hero-diagonal-title.hero-diagonal-title-two-line > span:first-child {
		margin-right: 15px;
	}
}

/*
* Hero Title Container - Reduced Top Padding
* Bootstrap's .pt-5 utility (3rem/48px, !important) is used site-wide,
* so it can't be changed globally. This hero container needs less top
* padding to bring the polygon/breadcrumb layout together - scoped to
* just this element instead (see about.html etc: replaces "pt-5" in
* the class list on .container.position-relative).
*/
.hero-title-container {
	padding-top: 1rem;
}

/*
* Hero Breadcrumb - Relocated Below the Diagonal Title Banner
* The breadcrumb used to live inside the same col as the <h1>/polygon,
* directly above it. It's now a sibling of .row.justify-content-end
* (see about.html etc.), moved out of the polygon/title area entirely,
* and absolutely positioned within the position:relative .container so
* it lands in the grey hero band below the polygon's bottom edge.
*
* Same left at every width. Top is 118px below 992px, 168px at 992px+
* (matches the header's own mobile-nav breakpoint) - both
* tuned/confirmed in Chrome DevTools against the real render.
*/
.hero-breadcrumb-relocated {
	position: absolute;
	left: 12px;
	top: 118px;
	text-align: left;
}

@media (min-width: 992px) {
	.hero-breadcrumb-relocated {
		top: 168px;
	}
}

/*
* Mobile Submenu Smooth Expand/Collapse
* Base theme hard-swaps display:none/block on .dropdown-menu with no
* transition, unlike the smooth ~400-500ms height animation used for the
* main mobile nav. Override to a max-height + opacity transition so
* opening a submenu (e.g. Services, Company) feels consistent.
*
* margin-left is set here unconditionally (theme.css only applies it via
* `li.dropdown.open > .dropdown-menu`/`li.dropdown-submenu.open > .dropdown-menu`,
* with no transition on the property) so it no longer changes at the
* moment .open is toggled. That untransitioned jump from 20px -> 0 was
* invisible while opening (it happens under opacity: 0, before the fade
* in), but on closing it fired while the submenu was still fully opaque,
* snapping every item 20px left in a single frame before the opacity/
* height transitions played out.
*/
@media (max-width: 991px) {
	#header .header-nav-main nav > ul li.dropdown .dropdown-menu {
		display: block !important;
		max-height: 0;
		overflow: hidden;
		opacity: 0;
		margin-left: 20px;
		transition: max-height 350ms ease, opacity 300ms ease;
	}

	#header .header-nav-main nav > ul li.dropdown.open > .dropdown-menu {
		max-height: 500px;
		opacity: 1;
	}
}

/*
* Mobile Nav - Never Internally Scrollable
* Base theme caps #header .header-nav-main nav to max-height: 50vh with
* overflow-y: auto (theme.css), so once expanded content (e.g. both the
* Company and Services dropdowns open at once) exceeds half the viewport
* height, later items like Contact end up inside that internal scroll
* area instead of pushing the page taller - reachable only by dragging
* within the nav itself, not by scrolling the page. custom.js already
* resizes .header-body to fit whatever is currently expanded (see
* js/custom.js), so remove the inner cap/scrollbar and let nav grow to
* its natural content height instead.
*/
@media (max-width: 991px) {
	#header .header-nav-main nav {
		max-height: none;
		overflow: visible;
	}
}

/*
* Contact Page - Call Us / Send An Email Stacking
* Below 420px the two side-by-side blocks currently wrap unreliably via
* default flex-wrap. Force a clean stack and add spacing between them.
* Above 420px, unchanged (side by side, same height).
*/
@media (max-width: 420px) {
	.contact-methods-row .col-auto {
		flex: 0 0 100%;
		max-width: 100%;
	}

	.contact-methods-row .col-auto:nth-child(2) {
		margin-top: 30px;
	}
}

/*
* Home Hero Tagline - Mobile Font Size
* "Industrial Rope Access Specialists" beneath REACHING HIGHER uses the
* shared .text-5-5 utility (1.65em = 23.1px off a 14px body). Reduced by
* 1px on mobile only, scoped to this element (not the shared utility).
*/
@media (max-width: 991px) {
	.hero-tagline {
		font-size: 22.1px !important;
	}
}

/*
* Home Trust Badges - Mobile Row Spacing
* .mb-5 above is reduced to 1rem (16px) site-wide. These badge columns
* need 20px more (36px total) once shown 3-per-row on mobile.
*/
@media (max-width: 767px) {
	.col-4.col-sm-4.col-xl.mb-5 {
		margin-bottom: 36px !important;
	}
}

/* Share content tracks within each case-study row; the final track holds
 * the snippet and absorbs spare height without stretching the image. */
.case-studies-grid {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	column-gap: 24px;
	row-gap: 0;
}

.case-studies-grid > .case-study-card {
	display: grid;
	grid-row: span 5;
	grid-template-rows: subgrid;
	min-width: 0;
	margin-bottom: 3rem;
}

.case-studies-grid > .case-study-card[hidden] {
	display: none;
}

.case-study-card > .portfolio-item {
	display: grid;
	grid-row: span 5;
	grid-template-rows: subgrid;
	min-width: 0;
}

.case-study-card .thumb-info {
	align-self: start;
}

.case-study-card .thumb-info img {
	width: 100%;
	height: auto;
}

@media (min-width: 576px) {
	.case-studies-grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

@media (min-width: 768px) {
	.case-studies-grid {
		grid-template-columns: repeat(3, minmax(0, 1fr));
	}
}

/*
* Case Study Filter Buttons - Border + Padding
* Previously only the active button had a border-bottom; inactive
* buttons had none at all, and .px-0 left them with no horizontal
* padding. Give every button a light border and proper padding so they
* read as clickable tag/button controls.
*/
.sort-source.sort-source-style-3 .nav-link.filter-pill {
	padding: 6px 14px !important;
	border: 1px solid var(--grey-500);
	border-radius: 20px;
}

.sort-source.sort-source-style-3 .nav-link.filter-pill.active {
	border: 1px solid var(--grey-500);
	background: var(--grey-100) !important;
}

/*
* Case Study Filter Buttons - Spacing
* .nav is display:flex/flex-wrap:wrap (Bootstrap), so a single `gap` on
* the container spaces every pill evenly in both directions at once -
* horizontally between pills in the same row, and vertically between
* rows once they wrap on narrower screens. Replaces an earlier
* margin-left-only approach (.filter-pill-spacing, since removed from
* the markup) that had no vertical spacing at all once pills wrapped.
*/
.sort-source.sort-source-style-3 {
	gap: 0.6rem;
}

/*
* Author Bio Box - Flexbox Layout
* Base theme (css/theme-blog.css) floats the avatar left with a fixed
* 100px height. Once bio text wraps past that height, subsequent lines
* clear the float and lose their left indent - a float wrap-around
* limitation, not fixable with a clearfix. Flexbox guarantees every
* wrapped line keeps the same left offset regardless of length.
*/
.post-author-body {
	display: flex;
	align-items: flex-start;
}

.post-author-body .img-thumbnail {
	float: none;
	flex-shrink: 0;
	margin-right: 20px;
}

.post-author-text {
	flex: 1;
	min-width: 0;
	margin-top: -45px;
}

/*
* Header Social Icons - Always Visible
* Base theme hides these below the sm breakpoint (d-none d-sm-flex/block,
* removed in includes/header.php) so they show at every viewport width.
* Below ~360px the header row (logo + social icons + hamburger) doesn't
* have room for the icons at their natural width, and since they're
* inline-block list items they wrap onto multiple lines instead of
* shrinking. Keep them on one line and pinned to their natural width so
* it's the hamburger's side of the row that yields space instead.
*/
#header .header-nav-features:has(.header-social-icons) {
	flex-shrink: 0;
}

#header .header-social-icons.social-icons {
	white-space: nowrap;
}

/* Below ~360px there isn't room for the icons at full size next to the
 * logo and hamburger button without the header row overflowing the
 * viewport - shrink the icons and their spacing so everything still
 * fits on one line. */
@media (max-width: 359.98px) {
	#header .header-nav-features:has(.header-social-icons) {
		padding-left: 4px;
		margin-left: 0 !important;
	}

	#header .header-social-icons.social-icons li {
		margin-right: 0;
	}

	#header .header-social-icons.social-icons li a {
		width: 24px;
		height: 24px;
		line-height: 24px;
		font-size: 11px;
	}
}
