/*
Theme Name:   Trevor S1
Theme URI:    https://trevorsolution.com/
Description:  Converted from a static HTML design. Colours and logo are editable under Appearance to Customize. The front page ships the captured layout exactly; inner templates inherit the same shell.
Author:       Trevor Solution
Author URI:   https://trevorsolution.com/
Version:      1.0.0
Requires at least: 6.0
Requires PHP: 7.4
License:      GPL-2.0-or-later
License URI:  https://www.gnu.org/licenses/gpl-2.0.html
Text Domain:  trevor-s1
Tags:         one-column, custom-colors, custom-logo, custom-menu, featured-images, translation-ready
*/

/* The design's own stylesheets are enqueued from functions.php in the order the
   original document loaded them. This file carries the theme header and a few
   corrections only — anything else belongs in the Customizer, so it stays
   editable rather than hardcoded here. */

/* Inner pages have no captured hero, so give the content breathing room. The
   masthead is also in normal flow here — header_position_over is applied to the
   front page only, because floating it over a page with no hero drops the H1
   underneath the logo. */
.ts1-inner .page_content_wrap {
	padding: 5rem 0 6rem;
}

/* --- Where the page meets the footer --------------------------------------
   The front page closes on a curve: its last section is a rounded box sitting
   inside an Ink one, so the corners cut away to dark just above the footer.
   Inner pages ended on a hard straight edge instead.

   Same shape, built the other way round, because inner pages have no such
   section to lean on. The content area takes the curve and the radius the
   design uses everywhere else, and the footer is pulled up behind it by the
   same amount it is then padded by — so the Ink shows through the corners and
   nothing below moves.

   `clip`, not `hidden`: hidden would make this a scroll container, and there
   is already one bug in this file's history from exactly that. */
.ts1-inner .page_content_wrap {
	position: relative;
	z-index: 1;
	background-color: var(--theme-color-bg_color, #F5F5F5);
	border-radius: 0 0 80px 80px;
	overflow: clip;
}

.ts1-inner .footer_wrap {
	margin-top: -80px;
	padding-top: 80px;
	background-color: var(--theme-color-alt_bg_color, #122023);
}

@media (max-width: 1024px) {
	.ts1-inner .page_content_wrap {
		border-radius: 0 0 40px 40px;
	}

	.ts1-inner .footer_wrap {
		margin-top: -40px;
		padding-top: 40px;
	}
}

.ts1-inner .content_wrap {
	width: 100%;
	max-width: 1290px;
	margin-inline: auto;
	padding-inline: 1.5rem;
}

.ts1-inner .ts1-entry + .ts1-entry {
	margin-top: 4rem;
}

.ts1-inner .entry-title {
	margin-bottom: 1rem;
}

/* Structured fields from the Rezkita Content plugin. Deliberately plain, and
   they read the design's own tokens rather than restating any colour, so a
   Customizer change carries through to these blocks too. */
.ts1-sub {
	font-size: 1.25rem;
	line-height: 1.5;
	margin-bottom: 2.5rem;
	opacity: .8;
}

.ts1-section-title {
	margin-top: 3.5rem;
	margin-bottom: 1.5rem;
}

.ts1-grid {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
	gap: 1.5rem;
}

.ts1-card {
	padding: 1.75rem;
	border: 1px solid var(--theme-color-bd_color, #DADEC5);
	border-radius: 20px;
}

.ts1-card h3 {
	margin: 0 0 .5rem;
	font-size: 1.125rem;
}

.ts1-card p { margin: 0; }

/* --- The capability carousel -------------------------------------------------
   Services carry five of these and industries three or four. A wrapping grid
   fitted four across, so every service page ended with a fifth card alone on a
   second row. One sliding row holds any count.

   Built on scroll-snap rather than transforms: the row is a real scroll
   container, so trackpad, touch and keyboard all work before a line of
   JavaScript runs, and the buttons only automate what the user could already
   do. If the script never loads the row still scrolls — it just keeps its
   buttons hidden, which is the state they ship in. */
.ts1-carousel-head {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 1.5rem;
}

.ts1-carousel-controls {
	display: flex;
	gap: .5rem;
	flex: 0 0 auto;
}

.ts1-carousel-controls[hidden] {
	display: none;
}

.ts1-carousel-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	padding: 0;
	border: 1px solid var(--theme-color-bd_color, #E4E9F2);
	border-radius: 50%;
	background: transparent;
	color: var(--theme-color-title, #0F1522);
	cursor: pointer;
	transition: background-color .2s ease, border-color .2s ease, color .2s ease, opacity .2s ease;
}

.ts1-carousel-btn svg {
	width: 20px;
	height: 20px;
}

.ts1-carousel-btn:hover:not(:disabled),
.ts1-carousel-btn:focus-visible {
	background: var(--theme-color-link, #2864F6);
	border-color: var(--theme-color-link, #2864F6);
	color: #FFFFFF;
}

/* Dimmed rather than removed at the ends: a control that disappears moves the
   one beside it, and the row jumps under the pointer mid-click. */
.ts1-carousel-btn:disabled {
	opacity: .35;
	cursor: default;
}

.ts1-carousel-viewport {
	overflow-x: auto;
	overflow-y: hidden;
	scroll-snap-type: x mandatory;
	scroll-behavior: smooth;
	scrollbar-width: none;
	-ms-overflow-style: none;
	/* Room for the cards' focus ring and border, which a flush overflow clips. */
	margin: 0 -4px;
	padding: 4px;
	/* Matching the padding, or the first card snaps to scrollLeft 4 rather than
	   0 — which reads as "already scrolled" and left the Previous button
	   enabled on a row sitting at its start. */
	scroll-padding: 4px;
}

.ts1-carousel-viewport::-webkit-scrollbar {
	display: none;
}

@media (prefers-reduced-motion: reduce) {
	.ts1-carousel-viewport {
		scroll-behavior: auto;
	}
}

/* grid-auto-columns, not flex-basis: the column width is stated once as a
   fraction of the viewport minus the gaps, so "four across" stays exact
   instead of drifting as the gap changes. */
.ts1-carousel-track {
	display: grid;
	grid-auto-flow: column;
	grid-auto-columns: calc((100% - 3 * 1.5rem) / 4);
	gap: 1.5rem;
	align-items: stretch;
}

.ts1-carousel-track > .ts1-card {
	scroll-snap-align: start;
	display: flex;
	flex-direction: column;
	padding: 0;
	overflow: hidden;
}

.ts1-card-figure {
	margin: 0;
	aspect-ratio: 16 / 10;
	background: var(--theme-color-bg_color_2, #EBEEF4);
}

.ts1-card-figure img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.ts1-card-body {
	padding: 1.5rem;
}

@media (max-width: 1200px) {
	.ts1-carousel-track {
		grid-auto-columns: calc((100% - 2 * 1.5rem) / 3);
	}
}

@media (max-width: 900px) {
	.ts1-carousel-track {
		grid-auto-columns: calc((100% - 1.5rem) / 2);
	}
}

/* A fraction over one card wide on a phone, so the sliver of the next one
   says the row scrolls without needing the buttons to say it. */
@media (max-width: 640px) {
	.ts1-carousel-track {
		grid-auto-columns: 82%;
		gap: 1rem;
	}

	.ts1-carousel-head {
		flex-wrap: wrap;
	}
}

.ts1-checklist {
	list-style: none;
	padding: 0;
	margin: 0;
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
	gap: .75rem 1.5rem;
}

.ts1-checklist li {
	position: relative;
	padding-left: 1.5rem;
}

.ts1-checklist li::before {
	content: "";
	position: absolute;
	left: 0;
	top: .55em;
	width: .5rem;
	height: .5rem;
	border-radius: 50%;
	background: var(--theme-color-link, #0CA266);
}

/* --- Inner-page masthead --------------------------------------------------
   The captured masthead is the homepage's: light text designed to sit over a
   photographic hero. Inner pages have no hero behind it, so those same links
   render pale-on-white and are close to invisible. The demo site solves this
   with a second header layout; here the front-page treatment simply stops at
   the front page and inner pages take dark text. */
.ts1-inner:not(.ts1-hero-overlay) .top_panel .trx-addons-menu-link,
.ts1-inner:not(.ts1-hero-overlay) .top_panel .trx-addons-menu-link-text,
.ts1-inner:not(.ts1-hero-overlay) .top_panel .sc_layouts_logo .logo_text {
	color: var(--theme-color-title, #151E20);
}

.ts1-inner:not(.ts1-hero-overlay) .top_panel .trx-addons-nav-menu-item:hover > .trx-addons-menu-link,
.ts1-inner:not(.ts1-hero-overlay) .top_panel .trx-addons-nav-menu-item:hover > .trx-addons-menu-link .trx-addons-menu-link-text,
.ts1-inner:not(.ts1-hero-overlay) .top_panel .trx-addons-active-item > .trx-addons-menu-link,
.ts1-inner:not(.ts1-hero-overlay) .top_panel .trx-addons-active-item > .trx-addons-menu-link .trx-addons-menu-link-text {
	color: var(--theme-color-link, #0CA266);
}

.ts1-inner:not(.ts1-hero-overlay) .top_panel {
	background-color: var(--theme-color-bg_color, #F5F5F5);
}

/* --- ...except where there is a band to float over ------------------------
   The block above exists because inner pages had nothing behind the masthead.
   They do now, so the exclusion above hands those pages back to the front
   page's treatment: no strip of background, light links over the band.

   The band is Ink, darker and more even than the front page's photograph, so
   the logo is knocked to white here where on the front page it is left alone.
   That is the one place the two deliberately differ. */
.ts1-hero-overlay .top_panel {
	background-color: transparent;
}

.ts1-hero-overlay .top_panel .logo_image {
	filter: brightness(0) invert(1);
}

.ts1-hero-overlay .top_panel .sc_layouts_logo .logo_text {
	color: #fff;
}

/* --- Inner page hero ------------------------------------------------------
   The capture has no inner-page template to copy — every page on the demo is
   individually built — so this is the shared shape those pages have in common:
   an eyebrow, a large title, and a standfirst, with room to breathe under a
   masthead that is now in normal flow. */
.ts1-page-hero {
	padding: 5rem 0 3rem;
}

/* --- The page header band -------------------------------------------------
   Set an image and the band becomes one: a full-bleed photograph with the
   title over it, closing on the same 80px curve the Ink panel downpage uses.
   With no image it stays exactly as it was — this whole block is behind
   `.has-image`, which ts1_page_hero() only adds when it resolved one.

   Breaking out of the container with a viewport-width negative margin rather
   than moving the markup: the band sits inside `.content_wrap` in all five
   templates, and lifting it out of each of them is a much larger change for
   the same pixels. The inner wrapper puts the text back on the container's
   grid. Safe against a sideways scrollbar because the mobile-containment block
   already clips the body's x overflow. */
.ts1-page-hero.has-image {
	position: relative;
	width: 100vw;
	margin-left: calc(50% - 50vw);
	margin-bottom: 3.5rem;

	padding: 9rem 0 4rem;
	border-radius: 0 0 80px 80px;
	overflow: hidden;
	background-color: var(--theme-color-alt_bg_color, #122023);
	background-image: var(--ts1-hero-image);
	background-size: cover;
	background-position: center;
}

/* `.page_content_wrap` opens with a slab of air — 80px on desktop, 75 on a
   phone — which is right for a page that starts with text and wrong for one
   that starts with a full-bleed band: it leaves the band floating with a strip
   of page showing between it and the masthead. Closed at the source rather
   than by pulling the band up with a negative margin, because that margin
   would have to be kept equal to a padding that already differs per
   breakpoint. The band supplies its own top padding instead.

   Browsers without `:has()` keep the strip. It is a gap, not a fault. */
.page_content_wrap:has(> .content_wrap > .content > .ts1-page-hero.has-image),
.page_content_wrap:has(> .content_wrap > .content > .ts1-entry > .ts1-page-hero.has-image) {
	padding-top: 0;
}

/* The photograph is a photograph — it has no contract to be dark where the
   text goes. The wash is what makes the title legible over any of them, and
   it is heavier at the foot where the standfirst sits. */
.ts1-page-hero.has-image::before {
	content: "";
	position: absolute;
	inset: 0;
	/* Ink, not the near-black it used to be. Tinting the wash with the brand's
	   own dark pulls every band toward the palette instead of merely darkening
	   it — which is what keeps a warm photograph, orange patch leads say, from
	   fighting a blue page. */
	background: linear-gradient(
		to bottom,
		rgba(7, 30, 90, .62) 0%,
		rgba(7, 30, 90, .80) 100%
	);
}

.ts1-page-hero-inner {
	position: relative;
	max-width: 1290px;
	margin: 0 auto;
	padding: 0 24px;
}

/* Light type, because the band underneath is now dark whatever the photo. */
.ts1-page-hero.has-image .entry-title {
	color: #fff;
}

.ts1-page-hero.has-image .ts1-sub {
	color: rgba(255, 255, 255, .82);
}

.ts1-page-hero.has-image .ts1-eyebrow {
	color: var(--theme-color-alt_title, #E1FCAD);
}

/* The masthead floats over the band, so the top padding is not just air — it
   is the clearance the title needs to sit clear of the nav. 7.5rem leaves the
   eyebrow about 56px below a 64px masthead; 5rem left it 23px and the two read
   as one block. */
@media (max-width: 1024px) {
	.ts1-page-hero.has-image {
		padding: 7.5rem 0 3rem;
		margin-bottom: 2.5rem;
		border-radius: 0 0 40px 40px;
	}
}

.ts1-eyebrow {
	display: block;
	font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
	font-size: .75rem;
	font-weight: 500;
	text-transform: uppercase;
	letter-spacing: .12em;
	color: var(--theme-color-link, #0CA266);
	margin-bottom: 1rem;
}

.ts1-page-hero .entry-title {
	margin: 0;
	max-width: 20ch;
}

.ts1-page-hero .ts1-sub {
	margin: 1.25rem 0 0;
	max-width: 60ch;
}

/* A reading measure. Without it body copy runs the full 1290px container and
   the line length roughly doubles what is comfortable.

   Centred, not flush left. The measure works out around 808px inside a 1242px
   column, and left-aligning it left 434px of empty page down the right-hand
   side. Centring keeps the comfortable line length and loses the lopsided
   gap. */
.ts1-inner .entry-content {
	max-width: 68ch;
	margin-inline: auto;
}

/* Except where the page's own content runs the full column beneath it — the
   capability carousel on a service or industry, the phase list on Approach.
   There a narrower intro reads as a mistake however it is aligned, because the
   eye has a full-width edge directly below to compare it against. Those
   templates opt in; a prose page with nothing full-width under it keeps the
   reading measure. */
.ts1-inner .entry-content.ts1-lead-wide {
	max-width: none;
	margin-inline: 0;
}

.ts1-inner .entry-content > * + * {
	margin-top: 1.25rem;
}

/* --- Photography still owed by the client -------------------------------
   The captured photographs are the vendor's and must be replaced before
   launch. Removing them breaks the composition, so they are flagged instead.

   The flag is the `ts1-needs-photo` class and the "[PLACEHOLDER: ...]" alt
   text, both of which stay on every frame — that is what the outstanding list
   is actually built from. The outline is only ever a convenience on top.

   It is drawn inside the Elementor editor and nowhere else. Keying it on
   `.logged-in` painted it across the whole site for anyone signed in, which
   reads as a rendering fault rather than a note-to-self; an editor who needs
   to know which frames are owed is, by definition, in the editor. */
.elementor-editor-active .ts1-needs-photo {
	outline: 2px dashed rgba(255, 120, 0, .55);
	outline-offset: -6px;
}

/* --- Service cards --------------------------------------------------------
   The capture ships six cards, Rezkita has eight, so the last two are clones
   on a row of their own. Auto rows size that row to its own shorter copy and
   the grid steps down at the bottom; 1fr holds all three rows level.

   Both grids: 38ef122c is the Services page, 846aaa8 the homepage. The first
   is a full-width container and is itself the grid; the second is boxed, so
   the grid is its `.e-con-inner` and the rule has to reach one level in.

   Keyed on the element id, which is not this file's habit. A `ts1-service-grid`
   class on the container would be the readable version, but Elementor does not
   render `_css_classes` on the containers in this capture — all 36 of them
   carry one in the data and none of it reaches the HTML — so the id class
   Elementor prints itself is the only hook that actually lands. */
.elementor-element-38ef122c,
.elementor-element-846aaa8 > .e-con-inner {
	grid-auto-rows: 1fr;
}

/* The vendor gives each card `min-height: 395px`. That is measured for the
   demo's three-column-in-1100px layout, where a card is 347px wide and the
   blurb wraps to three lines and fills it. Rezkita's container is wider, the
   cards come out 410px, the same blurb wraps to two lines — and the card holds
   395px anyway. The upper half is `justify-content: space-between`, so all of
   that surplus collects in one place: the gap between the icon and the title.

   Dropping the floor lets the card close to the 370px its content actually
   wants. The row rule above still keeps every row level. */
.elementor-element-38ef122c > .e-con,
.elementor-element-846aaa8 > .e-con-inner > .e-con {
	min-height: 0;
}

/* Some surplus is unavoidable: "Backup & disaster recovery" is the one title
   that wraps to two lines, so its card genuinely needs 398px and every other
   card in a level grid is 28px taller than its content.

   What matters is where that surplus goes. `space-between` pushes it all into
   the single gap between the icon and the title, which is the space that reads
   as a mistake. Anchoring the pair to the top with a fixed 30px gap — the gap
   the demo's own cards settle at — puts the leftover at the foot of the block
   instead, above the divider, where nobody counts it. */
.elementor-element-38ef122c > .e-con > .e-con:first-child,
.elementor-element-846aaa8 > .e-con-inner > .e-con > .e-con:first-child {
	justify-content: flex-start;
	gap: 30px;
}

/* --- Footer -----------------------------------------------------------------
   The demo's newsletter posted to MetForm, which is not installed here — the
   route 404s, so the field accepted an address and dropped it. The block is a
   route to the enquiry form that does work instead.

   Matched to the site's own call-to-action button — the one behind "See all
   services" and "How we deliver" — rather than to the design system's button
   spec. The two disagree: the document asks for an 8px radius and 14/28
   padding, and every button in the captured design is a 30px pill at 18/40.
   Following the document here produced one square, tighter button among a
   dozen pills, which reads as a mistake rather than as a standard.

   The document's spec is the better one and should win, but site-wide and
   deliberately, not one button at a time. */
/* The gap is `gap`, not a margin on the paragraph. The footer flattens its
   paragraphs with a `margin-bottom: 0` that outranks anything sensible written
   here, so the 1.5rem below the text computed to zero and the button sat
   against the last line. A flex gap is not a margin and nothing in the capture
   is trying to reset it.

   `align-items: flex-start` so the button stays its own width rather than
   stretching the column. */
.ts1-footer-cta {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 30px;
	max-width: 46ch;
}

.ts1-footer-cta-text {
	margin: 0;
	color: var(--theme-color-alt_text, #C2C7D6);
}

.ts1-footer-cta-link {
	display: inline-block;
	padding: 18px 40px;
	border-radius: 30px;
	font-size: 1rem;
	font-weight: 500;
	line-height: 19px;
	text-decoration: none;
	background: var(--theme-color-link, #2864F6);
	color: #fff !important;
	transition: background-color .3s ease;
}

.ts1-footer-cta-link:hover,
.ts1-footer-cta-link:focus {
	background: var(--theme-color-hover, #1B4FD8);
	color: #fff !important;
}

/* The background word. The capture sizes it for a nine-letter word and clips
   anything longer; rewrite_footer() measures whatever word is set and hands
   the size down as --ts1-watermark-size.

   On the letter spans, not the heading. Each letter carries its own font-size
   in px rather than inheriting, so resizing the h1 moves the box and leaves
   the glyphs exactly where they were — which looks like the rule having no
   effect at all. */
.footer_wrap .trx-addons-advanced-title[style*="--ts1-watermark-size"] .sc_item_animated_block {
	font-size: var(--ts1-watermark-size) !important;
	line-height: 1 !important;
}

/* The word starts further left on a phone — the gutter is narrower — so the
   same multiple runs about 5% past the edge. */
@media (max-width: 1024px) {
	.footer_wrap .trx-addons-advanced-title[style*="--ts1-watermark-size"] .sc_item_animated_block {
		font-size: calc(var(--ts1-watermark-size) * .92) !important;
	}
}

/* --- The footer on a phone --------------------------------------------------
   The capture lays the footer out as one flex row: a left column (3c3d3b49)
   carrying the call to action *and* the copyright, and a right column
   (23fb9548) carrying the two link lists. Below the wrap point that row
   stacks, and the nesting then reads badly:

     * the copyright lands in the middle of the footer, between the button and
       the contact details, because it is a child of the left column rather
       than a sibling of the right one;
     * the two link lists keep sharing one 350px row at 158px each, so "Let's
       work together" wraps to two lines and the shorter list leaves a ~90px
       void beside the longer one.

   `order` cannot fix the first on its own — it only sorts siblings, and the
   copyright is a level deeper. `display: contents` drops the left column's own
   box at this breakpoint so its two children become direct flex items of
   7ef0cf6a, which puts all three blocks on one axis where order does work. */
@media (max-width: 767px) {
	.footer_wrap .elementor-element-7ef0cf6a {
		flex-wrap: wrap;
		/* Row gap only. Stacked, the three blocks otherwise butt together —
		   "Let's work together" sat directly under the Request a quote button
		   with nothing between them. The capture's 70px column gap is left
		   alone; it does not apply once the row has wrapped. */
		row-gap: 40px;
	}

	/* Promotes 28735973 and 170e4f4b to siblings of 23fb9548. */
	.footer_wrap .elementor-element-3c3d3b49 {
		display: contents;
	}

	.footer_wrap .elementor-element-28735973 { order: 1; width: 100%; }
	.footer_wrap .elementor-element-23fb9548 { order: 2; width: 100%; }

	/* Last — it is a legal line, not part of the navigation. */
	.footer_wrap .elementor-element-170e4f4b {
		order: 3;
		width: 100%;
	}

	/* The two link lists stack instead of splitting 350px between them. */
	.footer_wrap .elementor-element-57fcbabf {
		flex-direction: column;
		gap: 32px;
	}

	.footer_wrap .elementor-element-702f5afe,
	.footer_wrap .elementor-element-3159254a {
		width: 100%;
		flex: 0 0 auto;
	}
}

/* --- The rounded shelf on the inner pages -----------------------------------
   The homepage builds every full-bleed band as a *pair* of containers: an
   outer one painted in the colour of whatever comes next, and an inner one
   painted in its own colour and rounded `0 0 80px 80px`. The radius cuts the
   inner corners away, the outer shows through the notches, and each band ends
   up looking like a shelf resting on the one below.

   The captured inner pages have no such pair — their bands are single
   containers — so the markup trick is not available there. This reproduces the
   same result on one element: the band itself takes the radius, and an
   `::after` painted in the next band's colour fills the bottom strip *behind*
   it.

   `z-index: -1` is what puts that strip behind its own parent's background,
   and it only works because none of these bands establishes a stacking
   context — position is relative, z-index auto, no transform, filter or
   isolation (verified on all four). If one ever gains a stacking context the
   strip will paint in *front* instead and cover the band's bottom edge, which
   is the failure to look for.

   Radii track the capture's own `--border-radius` steps rather than inventing
   new ones, so the inner pages break at the same widths the homepage does. */
:root {
	--ts1-shelf: 80px;
}

@media (max-width: 1279px) {
	:root { --ts1-shelf: 60px; }
}

@media (max-width: 767px) {
	:root { --ts1-shelf: 30px; }
}

.elementor-element-3641f10,
.elementor-element-435dfbc8,
.elementor-element-6195e2f8 {
	border-radius: 0 0 var(--ts1-shelf) var(--ts1-shelf) !important;
	position: relative;
}

.elementor-element-3641f10::after,
.elementor-element-435dfbc8::after,
.elementor-element-6195e2f8::after {
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	height: var(--ts1-shelf);
	z-index: -1;
	background: var(--ts1-shelf-under);
	pointer-events: none;
}

/* The colour each band is resting on. Brand tokens rather than literals, so a
   palette change carries through here too. */

/* About — the statistics band, over the capabilities panel. */
.elementor-element-3641f10 {
	--ts1-shelf-under: var(--theme-color-bg_color_2, #EBEEF4);
}

/* About — the capabilities panel, over the page background. */
.elementor-element-435dfbc8 {
	--ts1-shelf-under: var(--theme-color-bg_color, #F5F5F5);
}

/* Services — the dark service list, over the page background. */
.elementor-element-6195e2f8 {
	--ts1-shelf-under: var(--theme-color-bg_color, #F5F5F5);
}

/* Contact had a fourth band here. It was dropped as a duplicate invitation
   (see CONTACT_DROP_IDS), and the page now ends on the enquiry form — where
   the shape into the footer is the one `.ts1-inner .page_content_wrap`
   already draws for every inner page. */

/* About's full-bleed photograph was rounded here on all four corners. That is
   gone: the client set the radius themselves in the editor — 100px on the
   bottom pair only, over a brand-blue backdrop on the section behind it, which
   turns the band into the same shelf the homepage uses. Their setting is
   carried by ABOUT_SETTINGS in s1_pages_content.py and rendered as Elementor's
   own per-element CSS, so a rule here would only fight it. */

/* --- Contact, under its new band --------------------------------------------
   The capture's opening section carries `padding: 150px 0` on its inner,
   which was right when the section opened the page and held the "Contact"
   title. The title now lives in the image band above it, so that padding sits
   under the band as 150px of nothing — against the 56px every other inner
   page runs between band and content.

   Zero rather than a smaller number: the section already sits 56px below the
   band on its own, which is exactly the offset every other inner page runs,
   so any padding on top of that is surplus.

   Keyed on the element id: `_css_classes` does not render on the captured
   containers, so a class set in the Elementor data would never arrive. The
   bottom padding is left alone; it is the gap before the closing band and
   still correct. */
.elementor-element-5a4bd36 > .e-con-inner {
	padding-top: 0;
}

/* --- The closing call to action, over a photograph --------------------------
   The band's heading is Ink (#0F1522), which was right when the panel was a
   flat light blue. It now carries a photographic background set in the editor
   (see HOME_SETTINGS in home_s1_content.py) and Ink on a dark data hall is
   invisible — the heading disappeared entirely and only the button read.

   Same treatment as the hero: a navy wash to hold the type off the picture,
   then white text. The wash is on the container's own ::before rather than a
   background-blend, so the photograph can be swapped in the editor without
   anything here needing to change. */
.elementor-element-d0f79c8 {
	position: relative;
	background-size: cover;
	background-position: center;
}

.elementor-element-d0f79c8::before {
	content: "";
	position: absolute;
	inset: 0;
	border-radius: inherit;
	background: linear-gradient(180deg, rgba(7, 30, 90, .78) 0%, rgba(7, 30, 90, .62) 100%);
	pointer-events: none;
}

/* Above the wash. The container's children are not positioned by the capture,
   so without this they paint underneath it. */
.elementor-element-d0f79c8 > * {
	position: relative;
	z-index: 1;
}

.elementor-element-d0f79c8 .elementor-heading-title {
	color: #FFFFFF !important;
}

/* The button was Ink on light blue, which had plenty of contrast. Against the
   washed photograph it is navy on navy and all but disappears. Brand blue, the
   same treatment "Get in Touch" already gets on the dark masthead. */
.elementor-element-d0f79c8 .elementor-button {
	background-color: var(--theme-color-link, #2864F6) !important;
	color: #FFFFFF !important;
}

.elementor-element-d0f79c8 .elementor-button:hover,
.elementor-element-d0f79c8 .elementor-button:focus-visible {
	background-color: var(--theme-color-hover, #1B4FD8) !important;
}

/* --- The homepage hero ------------------------------------------------------
   The capture paints this section with `inline-0f21268d.jpg`, one of the
   vendor's own photographs — a wind farm, which is their business and not this
   one, and licensed for their demo rather than for a client site.

   Overridden here rather than by replacing the file, so the substitution is
   visible in the source: this stylesheet loads last, and the captured rule is
   keyed to the element id. */
.elementor-element-608afe4 {
	/* Relative to style.css, which sits at the theme root. The %%ASSETS%%
	   token is only rewritten inside Elementor data, not in this file. */
	background-image: url("assets/images/home-hero.jpg") !important;
}

/* The capture washes the hero with a flat 20% black. That was enough for the
   pale sky it was built for and is not enough for this photograph, which is
   dark at both edges and bright through the middle — exactly where the
   headline sits. Raising the flat value would have dulled the racks at the
   same time.

   A directional wash instead: heavy on the left behind the type, clearing to
   the right so the depth of the aisle survives. Ink rather than black, for the
   same reason the page bands use it — it tints toward the palette instead of
   just darkening. */
.elementor-element-608afe4::before {
	opacity: 1 !important;
	background: linear-gradient(
		100deg,
		rgba(7, 30, 90, .90) 0%,
		rgba(7, 30, 90, .74) 30%,
		rgba(7, 30, 90, .34) 58%,
		rgba(7, 30, 90, .16) 100%
	) !important;
}

/* The old hero was a pale sky, so the masthead's dark logo read against it and
   was deliberately left alone. This one is dark at the top left, which is
   precisely where the logo sits. */
body.home .top_panel .logo_image {
	filter: brightness(0) invert(1);
}

/* --- The advantage section header ------------------------------------------
   The capture stacks these two in a flex column and then pushes the standfirst
   to the right with `align-self: flex-end`, so the eyebrow and heading sat left
   while the paragraph started two thirds across and a line lower. Whatever that
   read as in the demo, under this content it reads as a mistake.

   Both blocks centred, and their text with them — the cards below are centred
   on the same axis, so the section now has one. */
.elementor-element-ab24983,
.elementor-element-7c48edb {
	align-self: center;
	align-items: center;
	text-align: center;
}

/* The standfirst runs the full width of its own box, which is wider than the
   line wants to be. A measure keeps it from spanning further than the heading
   above it. */
.elementor-element-7c48edb {
	max-width: 62ch;
}

/* --- Tab panels -------------------------------------------------------------
   The panel is 847px wide carrying two lines of copy, so most of it was empty.
   Copy left, picture right.

   The figure states 4:3 rather than inheriting it from the file, so a
   replacement of any proportion keeps the panel the same height — otherwise
   switching tabs would jump the page as each panel sized itself differently. */
.elementor-widget-html .e-n-tabs.ts1-tabs-ready > .e-n-tabs-content > .ts1-tab-panel.has-figure.ts1-tab-active {
	display: flex;
	flex-direction: column;
	align-items: stretch;
	gap: 28px;

	/* `.ts1-tab-active` in the selector is load-bearing, not decoration. Without
	   it this rule out-specifies the show/hide rule above and sets `display:
	   flex` on all eight panels — every one visible at once, sharing the row at
	   106px each. The layout only ever applies to the panel being shown. */
	width: 100%;
}

.ts1-tab-copy {
	flex: 1 1 0;
	min-width: 0;
}

.ts1-tab-copy p {
	margin: 0;
}

/* 16:9 now the picture runs the full width of the panel. At the 4:3 it used
   when it sat in a column beside the copy, a full-width figure came out 635px
   tall and pushed the text off the fold. The files are 4:3, so `cover` takes
   the crop — which is why the ratio is stated here rather than inherited. */
.ts1-tab-figure {
	flex: 0 0 auto;
	width: 100%;
	display: block;
	aspect-ratio: 16 / 9;
	border-radius: 20px;
	overflow: hidden;
	background: var(--theme-color-bg_color_2, #EBEEF4);
}

.ts1-tab-figure img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}

@media (max-width: 900px) {
	.elementor-widget-html .e-n-tabs.ts1-tabs-ready > .e-n-tabs-content > .ts1-tab-panel.has-figure.ts1-tab-active {
		gap: 20px;
	}
}

/* --- The advantage cards ---------------------------------------------------
   Two across, not four. At four the cards came out about 200px wide inside the
   column they sit in, and every one of them broke its copy to six or seven
   lines — which is what made a section about why clients renew read as filler.
   Two columns give the text a sane measure and room for a picture above it.

   Two stated outright, not `auto-fit` with a floor: the column these sit in is
   wide enough that auto-fit chose three, which is the layout being replaced.

   Capped rather than full-bleed. The container runs to 1300px, which put each
   card at 635px against a centred heading of 550 — the cards read as a separate,
   wider layout sitting under the section rather than part of it. 880 keeps the
   pair close to the heading's own measure. */
.ts1-advantage-grid {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 30px;
	max-width: 880px;
	margin-inline: auto;
}

@media (max-width: 700px) {
	.ts1-advantage-grid {
		grid-template-columns: minmax(0, 1fr);
	}
}

.ts1-advantage-card {
	display: flex;
	flex-direction: column;
	gap: 0;
	padding: 0;
	overflow: hidden;
}

/* 16:9, stated rather than inherited from the file, so a replacement photograph
   of any proportion drops in without changing the height of its card — and its
   neighbour's, since grid rows stretch. */
.ts1-advantage-figure {
	display: block;
	width: 100%;
	aspect-ratio: 16 / 9;
	background: var(--theme-color-bg_color_2, #EBEEF4);
}

.ts1-advantage-figure img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}

.ts1-advantage-body {
	display: block;
	padding: 1.75rem;
}

.ts1-advantage-body h3 {
	margin: 0 0 .5rem;
}

.ts1-advantage-body p {
	margin: 0;
}

/* --- The running strip ------------------------------------------------------
   Oversized type crossing the page, the way the demo's marquee bands did before
   they were dropped for being empty. 42s linear and paused on hover are the
   design system's own numbers for a marquee.

   Sky rather than Navy: this is ornament, not a heading, and the design system
   is explicit that Sky is a fill colour and never body text. The markup carries
   `aria-hidden`, so it is not exposed as text either — which is what makes a
   decorative contrast the right call here rather than a rule broken. */
.ts1-marquee {
	position: relative;
	width: 100vw;
	margin-left: calc(50% - 50vw);
	padding: 3.5rem 0;
	overflow: clip;
	user-select: none;
}

.ts1-marquee-track {
	display: flex;
	align-items: center;
	width: max-content;
	animation: ts1-marquee 42s linear infinite;
}

/* Pausing on hover is the point of a marquee that carries words: it gives a
   reader a way to stop it rather than chase it. */
.ts1-marquee:hover .ts1-marquee-track,
.ts1-marquee:focus-within .ts1-marquee-track {
	animation-play-state: paused;
}

.ts1-marquee-item {
	font-size: clamp(2.75rem, 7.5vw, 7rem);
	font-weight: 700;
	line-height: 1;
	letter-spacing: -.02em;
	text-transform: uppercase;
	white-space: nowrap;
	color: var(--ts1-accent-1, #53B6E9);
}

.ts1-marquee-mark {
	flex: 0 0 auto;
	display: inline-flex;
	width: clamp(1.75rem, 4vw, 3.25rem);
	height: clamp(1.75rem, 4vw, 3.25rem);
	margin: 0 clamp(1.5rem, 3.5vw, 3.5rem);
	color: var(--theme-color-link, #2864F6);
}

.ts1-marquee-mark svg {
	width: 100%;
	height: 100%;
}

@keyframes ts1-marquee {
	from { transform: translateX(0); }
	to   { transform: translateX(-50%); }
}

/* Non-negotiable, per the design system: government accessibility requirements
   assume it. The strip stays, it simply stops moving. */
@media (prefers-reduced-motion: reduce) {
	.ts1-marquee-track {
		animation: none;
	}
}

/* --- The Who-we-are portrait ----------------------------------------------
   This slot has no height of its own: the image fills the column and the
   column takes whatever height the file's aspect ratio gives it. The frame it
   replaced was 16:9, so a near-square photograph made the section half as tall
   again — 915x905 on a 2000px screen, against a text column of about 250px.

   Capping the width alone was not enough: at 1024-1600 the column *does* have
   a fixed height, so a narrower box just cropped the same photograph taller
   and thinner. The shape has to be stated outright and then bounded.

   The shape is the demo's own, measured off it at 1440px rather than guessed:
   635x617 in a 635px column, so the image fills its column and sits very
   slightly wider than tall. An earlier version of this rule stated 3:2 at 80%
   width, which held the picture to 508x339 and left ~290px of empty column
   under it — the single biggest reason this page read as broken beside the
   original. */
/* The capture pins this widget to `height: 100%` inside a grid row, so it
   stretched to whatever the row was and dragged the photograph's height with
   it — which is why setting an aspect ratio on the image alone did nothing.
   Release the stretch first, then the ratio below actually governs. */
.elementor-element-79474a29,
.elementor-element-79474a29 > .elementor-widget-container {
	height: auto;
	align-self: start;
}

.elementor-element-79474a29 img {
	width: 100%;
	/* A pixel cap, not a percentage. The column is a fraction of the viewport,
	   so a percentage keeps the picture growing with the screen — it reached
	   915x889 at 2000px wide, half as big again as at 1440px, and dominated the
	   section. A fixed ceiling holds it at the same size on every monitor. */
	max-width: 460px;
	aspect-ratio: 635 / 617;
	height: auto;
	object-fit: cover;
}

@media (max-width: 1024px) {
	/* Single column below this width, where a near-square picture eats most of
	   a phone screen before the copy starts. The demo lets it stay square; a
	   shallower crop keeps the heading above the fold. */
	.elementor-element-79474a29 img {
		aspect-ratio: 3 / 2;
	}
}

/* --- The pale bands -------------------------------------------------------
   The skin makes one colour do two jobs: `alt_title` is headings on a dark
   ground *and* the fill behind three full-width bands — the stats row, the
   panel above the footer, and one on About. That worked while it was pale lime.

   Under the brand palette it cannot. The design system puts headings on Ink at
   White, 15.64:1, and a white band on a white page is not a band — those three
   sections simply vanished. So the heading colour stays White and the bands are
   given the palette's own light fill instead, which keeps the dark text on them
   readable where Electric or Navy would not.

   Keyed on element ids because that is how the capture keys them; there is no
   class shared by the four. Both the container and its motion layer: the
   capture styles the layer, but the colour that actually paints is the one on
   the container itself. */
.elementor-element-1631a9c,
.elementor-element-37db531,
.elementor-element-d0f79c8,
.elementor-element-3641f10,
.elementor-element-1631a9c > .elementor-motion-effects-container > .elementor-motion-effects-layer,
.elementor-element-37db531 > .elementor-motion-effects-container > .elementor-motion-effects-layer,
.elementor-element-d0f79c8 > .elementor-motion-effects-container > .elementor-motion-effects-layer,
.elementor-element-3641f10 > .elementor-motion-effects-container > .elementor-motion-effects-layer {
	background-color: var(--ts1-accent-1, #53B6E9) !important;
}

/* --- Market verticals -----------------------------------------------------
   The captured section held three blog-post cards from the demo site. Rezkita
   has no posts, so it is rebuilt as the eight sectors. Colours come from the
   design's own custom properties rather than fixed values, so a Customizer
   change reaches these too. */
/* 240, not 220. At 220 the row fits five cards of about 213px, which leaves
   165px of content once the padding is off — narrower than the word
   "Telecommunications", which was breaking mid-word into "Telecommunication /
   s". 240 gives four columns with room to spare, and eight cards fall into two
   even rows of four instead of a row of five and a row of three. */
.ts1-sector-grid {
	grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
}

/* These sit inside the Ink panel, so they inherit their colour rather than
   naming one — a fixed title colour renders invisible on a dark background. */
.ts1-sector-card {
	display: flex;
	flex-direction: column;
	gap: .5rem;
	padding: 1.5rem;
	color: inherit;
	border: 1px solid var(--theme-color-bd_color, #DADEC5);
	border: 1px solid color-mix(in srgb, currentColor 25%, transparent);
	border-radius: 20px;
	text-decoration: none;
	transition: border-color .18s ease;
}

.ts1-sector-card:hover {
	border-color: var(--theme-color-link, #0CA266);
}

/* The icon leads the card, so the number and name need to sit under it rather
   than beside it — hence the auto margin pushing the pair to the foot of the
   card, which also levels the names across a row of mixed-length labels. */
/* The dark scheme's accent, not the light one. This grid only ever renders
   inside the Ink panel, and the light accent is Electric — a deep blue that
   lands at roughly 2:1 on Ink. Sky is the palette's answer for exactly this
   (6.88:1 on Ink, per the design system's own audit). */
.ts1-sector-icon {
	display: block;
	width: 2.25rem;
	height: 2.25rem;
	margin-bottom: auto;
	color: var(--theme-color-alt_link, #53B6E9);
}

.ts1-sector-icon svg {
	width: 100%;
	height: 100%;
	display: block;
}

/* The card is the link, so the hover belongs to the whole of it. */
.ts1-sector-card:hover .ts1-sector-icon {
	color: var(--theme-color-alt_title, #E1FCAD);
}

.ts1-sector-icon,
.ts1-sector-card:hover .ts1-sector-icon {
	transition: color .18s ease;
}

.ts1-sector-num {
	font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
	font-size: .75rem;
	letter-spacing: .12em;
	color: var(--theme-color-alt_link, #53B6E9);
}

/* This grid only ever renders inside the Ink panel, so it takes the dark
   scheme's heading colour rather than inheriting the panel's muted body tone,
   which left the sector names barely legible. */
.ts1-sector-name {
	font-size: 1.125rem;
	font-weight: 600;
	color: var(--theme-color-alt_title, #E1FCAD);
}

.ts1-tab-panel p {
	margin: 0;
	max-width: 60ch;
}

/* --- Nested tabs carried as HTML ------------------------------------------
   Scoped to .ts1-tabs-ready, which the handler adds only once it is running.
   If the script fails to load the panels simply all stay visible, which is
   ugly but readable — hiding them from CSS alone would leave four fifths of
   the section permanently unreachable. */
.elementor-widget-html .e-n-tabs.ts1-tabs-ready > .e-n-tabs-content > * {
	display: none;
}

.elementor-widget-html .e-n-tabs.ts1-tabs-ready > .e-n-tabs-content > .ts1-tab-active {
	display: block;
}

/* --- and the way those tabs are meant to look -----------------------------
   The design draws this list as plain text on hairlines: no panel behind it,
   each phase separated by a rule, and the selected one marked by taking the
   rule under it dark. What was on screen instead was a grey slab with a bright
   green bar sitting in it.

   Neither of those colours is from the design. They are Elementor's stock
   nested-tabs defaults — `#f1f2f3` behind an idle title and `#61CE70`, its
   house green, behind the active one — and they show through because this
   widget is carried as HTML. The design's own values arrive by per-element CSS
   keyed to the widget id it had in the capture, and an HTML widget has no such
   id. Note the two title *colours* did arrive: #B6BAAF and #151E20 are already
   correct, which is why only the backgrounds looked wrong.

   Overriding the variables rather than the declarations, because the variables
   are the documented seam and the declarations that read them are Elementor's
   to change. */
.elementor-widget-html .e-n-tabs.ts1-tabs-ready {
	--n-tabs-title-background-color: transparent;
	--n-tabs-title-background-color-active: transparent;
	--n-tabs-title-background-color-hover: transparent;
}

.elementor-widget-html .e-n-tabs.ts1-tabs-ready .e-n-tab-title {
	border-bottom: 1px solid var(--theme-color-bd_color, #DADEC5);
	border-radius: 0;
}

/* The list needs closing at the top as well, or it starts mid-air. */
.elementor-widget-html .e-n-tabs.ts1-tabs-ready .e-n-tab-title:first-child {
	border-top: 1px solid var(--theme-color-bd_color, #DADEC5);
}

/* The whole of the selected state: the rule beneath it goes dark. Keyed on
   aria-selected, which ts1-tabs.js already maintains, so it follows the tab
   without the script needing to know about any of this. */
.elementor-widget-html .e-n-tabs.ts1-tabs-ready .e-n-tab-title[aria-selected="true"] {
	border-bottom-color: var(--theme-color-title, #151E20);
}

/* --- Elementor heading defaults ------------------------------------------
   Elementor emits a colour declaration on
   `.elementor-widget-heading .elementor-heading-title`, pointing at the global
   primary, for every heading widget that has no explicit colour of its own.
   The capture never had that rule — its headings are coloured by the design's
   own `h5, h6` selector at specificity (0,0,1), which Elementor's (0,2,0) rule
   buries. The result is every heading painted in Elementor's default blue.

   These re-assert the design's values at the same or slightly higher
   specificity, and this stylesheet loads last so they win. They stay below the
   captured per-element rules at (0,3,0), so any heading the design styled
   individually still overrides these. */
.elementor-widget-heading .elementor-heading-title {
	color: var(--theme-color-title);
}

.elementor-widget-heading h1.elementor-heading-title {
	font-family: var(--theme-font-h1_font-family);
	font-weight: var(--theme-font-h1_font-weight);
}

.elementor-widget-heading h2.elementor-heading-title {
	font-family: var(--theme-font-h2_font-family);
	font-weight: var(--theme-font-h2_font-weight);
}

.elementor-widget-heading h3.elementor-heading-title {
	font-family: var(--theme-font-h3_font-family);
	font-weight: var(--theme-font-h3_font-weight);
}

.elementor-widget-heading h4.elementor-heading-title {
	font-family: var(--theme-font-h4_font-family);
	font-weight: var(--theme-font-h4_font-weight);
}

.elementor-widget-heading h5.elementor-heading-title {
	font-family: var(--theme-font-h5_font-family);
	font-weight: var(--theme-font-h5_font-weight);
}

.elementor-widget-heading h6.elementor-heading-title {
	font-family: var(--theme-font-h6_font-family);
	font-weight: var(--theme-font-h6_font-weight);
}

/* The captured logo is a fixed-size <img>. A Customizer logo has to sit in the
   same box or the masthead reflows. */
.custom-logo-link .custom-logo {
	height: auto;
	max-height: var(--ts1-logo-height, 60px);
	width: auto;
}

/* --- Archive grid ---------------------------------------------------------
   The archives listed titles vertically, which for eight service lines read as
   a contents page. Cards give each entry a target and a shape. */
.ts1-archive-grid {
	grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
	margin-top: 1rem;
}

.ts1-archive-card {
	position: relative;
	display: flex;
	flex-direction: column;
	gap: .5rem;
	padding: 2rem;
	text-decoration: none;
	color: inherit;
}

.ts1-archive-num {
	font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
	font-size: .75rem;
	letter-spacing: .12em;
	color: var(--theme-color-link, #0CA266);
}

.ts1-archive-title {
	margin: 0;
	font-size: 1.25rem;
}

.ts1-archive-excerpt {
	margin: 0;
	color: var(--theme-color-text, #899092);
}

.ts1-archive-more {
	margin-top: auto;
	padding-top: 1rem;
	font-size: 1.25rem;
	color: var(--theme-color-link, #0CA266);
	transition: transform .18s ease;
}

.ts1-archive-card:hover .ts1-archive-more {
	transform: translateX(4px);
}

/* --- Delivery phases ------------------------------------------------------ */
.ts1-phases {
	list-style: none;
	margin: 3rem 0 0;
	padding: 0;
	counter-reset: none;
}

.ts1-phase {
	display: grid;
	grid-template-columns: 5rem 1fr;
	gap: 1.5rem;
	padding: 2rem 0;
	border-top: 1px solid var(--theme-color-bd_color, #DADEC5);
}

.ts1-phase:last-child {
	border-bottom: 1px solid var(--theme-color-bd_color, #DADEC5);
}

.ts1-phase-num {
	font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
	font-size: 1.5rem;
	line-height: 1.2;
	color: var(--theme-color-link, #0CA266);
}

.ts1-phase-title {
	margin: 0 0 .5rem;
	font-size: 1.375rem;
}

.ts1-phase-body p {
	margin: 0;
	max-width: 62ch;
}

/* What the client receives is the part procurement reads, so it is separated
   from the description rather than run on from it. */
.ts1-phase-gives {
	margin-top: .75rem !important;
	padding-top: .75rem;
	border-top: 1px dashed var(--theme-color-bd_color, #DADEC5);
	font-size: .9375rem;
}

.ts1-phase-gives-label {
	display: inline-block;
	margin-right: .5rem;
	font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
	font-size: .6875rem;
	text-transform: uppercase;
	letter-spacing: .12em;
	color: var(--theme-color-link, #0CA266);
}

@media (max-width: 640px) {
	.ts1-phase {
		grid-template-columns: 1fr;
		gap: .5rem;
	}
}

/* --- Contact -------------------------------------------------------------- */
.ts1-contact-layout {
	display: grid;
	grid-template-columns: minmax(260px, 1fr) minmax(320px, 1.4fr);
	gap: 3rem;
	align-items: start;
	margin-top: 1rem;
}

@media (max-width: 900px) {
	.ts1-contact-layout {
		grid-template-columns: 1fr;
		gap: 2.5rem;
	}
}

.ts1-contact-list {
	margin: 2rem 0 0;
}

.ts1-contact-row {
	padding: 1rem 0;
	border-top: 1px solid var(--theme-color-bd_color, #DADEC5);
}

.ts1-contact-row dt {
	font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
	font-size: .6875rem;
	text-transform: uppercase;
	letter-spacing: .12em;
	color: var(--theme-color-link, #0CA266);
	margin-bottom: .25rem;
}

.ts1-contact-row dd {
	margin: 0;
	font-size: 1.0625rem;
}

.ts1-contact-form-wrap {
	padding: 2rem;
	border: 1px solid var(--theme-color-bd_color, #DADEC5);
	border-radius: 20px;
	background: var(--theme-color-bg_color, #F5F5F5);
}

.ts1-field-row {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 1rem;
}

@media (max-width: 560px) {
	.ts1-field-row {
		grid-template-columns: 1fr;
	}
}

.ts1-field {
	margin: 0 0 1rem;
}

.ts1-field label {
	display: block;
	margin-bottom: .35rem;
	font-size: .875rem;
	font-weight: 500;
}

.ts1-field input,
.ts1-field select,
.ts1-field textarea {
	width: 100%;
	padding: .75rem 1rem;
	border: 1px solid var(--theme-color-bd_color, #DADEC5);
	border-radius: 10px;
	background: #fff;
	font: inherit;
	font-size: 1rem;
}

.ts1-field input:focus,
.ts1-field select:focus,
.ts1-field textarea:focus {
	outline: none;
	border-color: var(--theme-color-link, #0CA266);
	box-shadow: 0 0 0 3px color-mix(in srgb, var(--theme-color-link, #0CA266) 20%, transparent);
}

/* 30px below, because that is the gap the design leaves under every other
   call to action — "See all services", "How we deliver", "Email us". At 1rem
   the submit sat 16px after the consent line and read tighter than the rest. */
.ts1-consent {
	display: flex;
	gap: .625rem;
	align-items: flex-start;
	font-size: .9375rem;
	margin: 1rem 0 30px;
}

.ts1-consent input {
	margin-top: .25rem;
	flex: 0 0 auto;
}

/* Same metrics as the design's own call-to-action buttons — 18/40 in a 30px
   pill — so the enquiry form's submit is not a size of its own. It read as a
   pill either way, being taller than twice its radius, but the padding and
   weight were visibly different next to "See all services". */
.ts1-submit {
	padding: 18px 40px;
	border: 0;
	border-radius: 30px;
	background: var(--theme-color-link, #2864F6);
	color: #fff;
	font: inherit;
	font-size: 1rem;
	font-weight: 500;
	/* Pinned, not inherited. `font: inherit` brings the form's line-height with
	   it, which made this button 62px against the 55px of every other call to
	   action — same padding, taller line box. */
	line-height: 19px;
	cursor: pointer;
	transition: background-color .3s ease;
}

.ts1-submit:hover {
	background: var(--theme-color-hover, #0A975F);
}

.ts1-form-note {
	margin: 1rem 0 0;
	font-size: .8125rem;
	color: var(--theme-color-meta, #B6BAAF);
}

/* Off-screen rather than display:none — a bot reading the DOM cannot tell the
   difference, but a hidden field is a known tell. */
.ts1-hp {
	position: absolute;
	left: -9999px;
	width: 1px;
	height: 1px;
	overflow: hidden;
}

.ts1-notice {
	padding: 1rem 1.25rem;
	border-radius: 12px;
	margin: 0 0 1.5rem;
}

.ts1-notice-ok {
	background: color-mix(in srgb, var(--theme-color-link, #0CA266) 12%, transparent);
	border: 1px solid var(--theme-color-link, #0CA266);
}

.ts1-notice-bad {
	background: rgba(200, 60, 60, .1);
	border: 1px solid rgba(200, 60, 60, .5);
}


/* --- Converted demo pages ------------------------------------------------- */
.ts1-mini-card h4 {
	margin: 0 0 .35rem;
	font-size: 1.0625rem;
}

.ts1-mini-card p {
	margin: 0;
	font-size: .9375rem;
	color: var(--theme-color-text, #899092);
}

/* --- FAQ ------------------------------------------------------------------
   <details> rather than a scripted accordion: it opens without JavaScript,
   is keyboard operable for free, and the demo's own accordion widget is not
   installed here. */
.ts1-faq-item {
	border-bottom: 1px solid var(--theme-color-bd_color, #DADEC5);
}

.ts1-faq-item summary {
	display: flex;
	gap: 1.5rem;
	align-items: baseline;
	padding: 1.5rem 0;
	cursor: pointer;
	list-style: none;
}

.ts1-faq-item summary::-webkit-details-marker {
	display: none;
}

.ts1-faq-num {
	font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
	font-size: .875rem;
	color: var(--theme-color-meta, #B6BAAF);
	flex: 0 0 2rem;
}

.ts1-faq-q {
	font-size: 1.25rem;
	font-weight: 500;
	color: var(--theme-color-title, #151E20);
}

.ts1-faq-item[open] .ts1-faq-q {
	color: var(--theme-color-link, #0CA266);
}

.ts1-faq-a {
	padding: 0 0 1.5rem 3.5rem;
	max-width: 70ch;
}

.ts1-faq-a p {
	margin: 0;
	color: var(--theme-color-text, #899092);
}


/* --- Sticky masthead ------------------------------------------------------
   On scroll the vendor's JS sets trx_addons_page_scrolled on the body and its
   CSS draws the dark bar, but never re-colours the bar's contents. On an inner
   page the nav keeps the dark text it needs against a light page and vanishes
   against the bar, taking the dark PNG logo with it.

   These carry !important, which is a deliberate choice rather than laziness.
   The vendor colours the nav from generated per-element CSS —
   `.elementor-28 .elementor-element.elementor-element-30c15ef
   .trx-addons-main-nav-menu>.trx-addons-nav-menu-item>.trx-addons-menu-link`,
   five classes deep and keyed to an element id from the capture. Out-specifying
   that means hardcoding the same id here, so the rule would silently stop
   working the day the header is rebuilt. A scroll-state override is exactly the
   narrow, genuinely-should-win case !important exists for. */
/* #666 was the original value here and it was too dark: the bar it sits on is
   #122023, so the nav read at about 2.6:1 — legible only if you knew it was
   there. Light-on-ink instead, at the weight the rest of the design uses for
   secondary text on a dark ground. */
/* Top-level items only — `> li >`, not a descendant match.
   
   These colours are for the dark bar the masthead becomes on scroll. The
   dropdown that opens underneath it is a *white* panel, and an unscoped
   `.top_panel .trx-addons-menu-link` reaches into it: every submenu item came
   out white on white and simply disappeared, with the current one at Sky and
   barely better. The dropdown keeps the colours set in SUBMENU_CSS. */
body.trx_addons_page_scrolled .top_panel .trx-addons-nav-menu > li > .trx-addons-menu-link,
body.trx_addons_page_scrolled .top_panel .trx-addons-nav-menu > li > .trx-addons-menu-link .trx-addons-menu-link-text {
	color: rgba(255, 255, 255, .72) !important;
}

/* The current page keeps the accent, so you can still see where you are.
   `.trx-addons-active-item` is enough here because a filter in functions.php
   now adds that class for the ancestor cases the vendor misses — see
   nav_menu_css_class there. Sky rather than the link blue: on this Ink bar
   Electric is nearly as dim as the grey it was meant to stand out from. */
body.trx_addons_page_scrolled .top_panel .trx-addons-nav-menu > li.trx-addons-active-item > .trx-addons-menu-link,
body.trx_addons_page_scrolled .top_panel .trx-addons-nav-menu > li.trx-addons-active-item > .trx-addons-menu-link .trx-addons-menu-link-text,
body.trx_addons_page_scrolled .top_panel .trx-addons-nav-menu > li:hover > .trx-addons-menu-link,
body.trx_addons_page_scrolled .top_panel .trx-addons-nav-menu > li:hover > .trx-addons-menu-link .trx-addons-menu-link-text {
	color: var(--theme-color-alt_link, #53B6E9) !important;
}

/* The logo is an uploaded PNG and cannot be recoloured, so it is knocked to a
   white silhouette: brightness(0) flattens it to black whatever its original
   colours, invert(1) turns that white. */
body.trx_addons_page_scrolled .top_panel .logo_image {
	filter: brightness(0) invert(1) !important;
}

body.trx_addons_page_scrolled .top_panel .logo_text {
	color: #fff !important;
}

/* --- Where you are ---------------------------------------------------------
   The design marks the current item by colour alone, and colour alone could not
   carry it: over the header band that was #C7F41F against #E1FCAD for the rest,
   two pale limes a few percent apart, and on the scrolled bar the distinction
   disappeared completely.

   A rule under the item says it outright, in the same vocabulary the phases
   tabs already use for the same job, and it works on every ground the masthead
   sits on because it takes the item's own colour.

   One class, because a filter in functions.php now guarantees
   `trx-addons-active-item` is present for the ancestor cases the vendor's own
   JavaScript misses — browsing a Service or an Industry among them.

   `::before`, because `::after` on this link is already the dropdown caret. And
   `opacity: 1`, because the vendor parks this pseudo-element at zero for its
   hover animation: without it the rule computes at the right size, in the right
   place, in the right colour, and paints nothing. */
@media (min-width: 1025px) {
	.top_panel .trx-addons-nav-menu > .trx-addons-active-item > .trx-addons-menu-link {
		position: relative;
	}

	.top_panel .trx-addons-nav-menu > .trx-addons-active-item > .trx-addons-menu-link::before {
		content: "";
		position: absolute;
		left: 0;
		right: 0;
		/* Close under the text on purpose. Lower down, the rule landed on the
		   bottom edge of the scrolled bar and merged with it. */
		bottom: -.2em;
		height: 2px;
		border-radius: 2px;
		background: currentColor;
		opacity: 1;
	}
}

/* Fade the colour only. Transitioning everything makes the bar visibly reflow
   as it pins. */
.top_panel .trx-addons-menu-link,
.top_panel .trx-addons-menu-link-text,
.top_panel .logo_image,
.top_panel .logo_text {
	transition: color .2s ease, filter .2s ease;
}


/* --- The same masthead, on mobile -----------------------------------------
   The captured header holds two rows: a desktop one carrying the vendor's
   sc_layouts_row_fixed* classes, and a mobile one — the only
   `elementor-hidden-desktop` container in the masthead — carrying none of
   them. So below 1024px the bar is static: it scrolls away with the page and
   the only route back to the menu is scrolling to the top.

   `sticky`, not the `fixed` the desktop row uses. Fixed takes the row out of
   flow, so everything below jumps up by the bar's height and needs a
   compensating padding kept in step with it by hand. Sticky needs neither.

   It goes on `.top_panel`, not on the row itself. A sticky element can only
   travel inside its own parent's box, and the row's parents — `.elementor-28`
   and `.top_panel` — are both exactly the row's own 64px, so sticking it
   directly gives it nowhere to go and it scrolls away as if the rule were not
   there. `.top_panel`'s parent is `.page_wrap`, the full height of the
   document, which is the travel the bar actually needs. */
@media (max-width: 1024px) {
	/* This depends on the `overflow-x: clip` in the mobile-containment block
	   further down. Sticky is inert inside a scroll container, and `hidden`
	   makes html and body exactly that. */
	.top_panel {
		position: sticky;
		top: 0;
		z-index: 8000;
	}

	/* The homepage overlays its masthead on the hero — `.header_position_over`
	   takes it out of flow with `position: absolute`, and out-specifies the
	   rule above. Sticky would put it back in flow and push the hero down by
	   the bar's height, so that case pins with `fixed`: still out of flow, and
	   the same mechanism the desktop row uses on every page. */
	.header_position_over .top_panel {
		position: fixed;
		top: 0;
		left: 0;
		right: 0;
	}

	.top_panel .elementor-hidden-desktop.e-con {
		transition: background-color .2s ease;
	}

	/* Same body class and same bar colour the desktop row uses on scroll, so
	   the two behave identically either side of the breakpoint. */
	body.trx_addons_page_scrolled .top_panel .elementor-hidden-desktop.e-con {
		background-color: var(--theme-color-alt_bg_color, #071E5A);
	}

	/* --- The burger --------------------------------------------------------
	   The vendor fills it #E1FCAD, a pale lime meant for a dark bar. Over the
	   #F5F5F5 inner pages it is invisible: on first load the masthead reads as
	   having no menu control at all.

	   It follows the logo instead — dark over the page, knocked to white once
	   the dark bar is under it. The logo directly beside it is already treated
	   exactly this way by the block above, so the two now flip together. */
	.top_panel .trx-addons-hamburger-toggle svg path {
		fill: var(--theme-color-title, #0F1522) !important;
		transition: fill .2s ease;
	}

	/* On a page whose masthead floats over the band, dark-on-dark would put the
	   burger straight back where it started — invisible. It takes the nav's
	   colour instead, the same way it takes the logo's on a light page. */
	body.ts1-hero-overlay .top_panel .trx-addons-hamburger-toggle svg path {
		fill: var(--theme-color-alt_title, #FFFFFF) !important;
	}

	body.trx_addons_page_scrolled .top_panel .trx-addons-hamburger-toggle svg path {
		fill: #fff !important;
	}
}

@media (max-width: 1024px) and (min-width: 601px) {
	/* WordPress pins the admin bar from 601px up. Below that it scrolls away
	   with the page, so top:0 is already correct. */
	.admin-bar .top_panel {
		top: 46px;
	}
}

@media (max-width: 1024px) and (min-width: 783px) {
	.admin-bar .top_panel {
		top: 32px;
	}
}


/* An empty archive still needs to occupy the page rather than leaving the
   footer riding up under the masthead. */
.ts1-empty {
	min-height: 30vh;
	color: var(--theme-color-meta, #B6BAAF);
}


/* --- Dropdowns (desktop only) ---------------------------------------------
   The captured menu was flat, so the vendor stylesheet has nothing for a
   second level: without these rules WordPress's .sub-menu renders inline and
   pushes every child down the page.

   The whole block is inside a min-width query on purpose. Below 1024px the
   vendor swaps to its own slide-out panel, which has its own markup and
   styling — an earlier version of this leaked into that panel and laid the
   top-level items out side by side with their submenus overlapping as loose
   white cards. Mobile is the vendor's to handle. */
@media (min-width: 1025px) {
	.top_panel .trx-addons-nav-menu-item {
		position: relative;
	}

	.top_panel .trx-addons-nav-menu .sub-menu {
		position: absolute;
		top: 100%;
		left: 0;
		z-index: 60;
		min-width: 230px;
		margin: 0;
		padding: .5rem 0;
		list-style: none;
		background: var(--theme-color-bg_color, #fff);
		border: 1px solid var(--theme-color-bd_color, #DADEC5);
		border-radius: 14px;
		box-shadow: 0 18px 40px rgba(0, 0, 0, .10);

		/* Hidden but still reachable by keyboard, and animatable — display:none
		   would kill both. */
		opacity: 0;
		visibility: hidden;
		transform: translateY(6px);
		transition: opacity .16s ease, transform .16s ease, visibility .16s;
	}

	.top_panel .trx-addons-nav-menu-item:hover > .sub-menu,
	.top_panel .trx-addons-nav-menu-item:focus-within > .sub-menu {
		opacity: 1;
		visibility: visible;
		transform: translateY(0);
	}

	/* A bridge across the gap so the pointer can travel down without the panel
	   closing under it. */
	.top_panel .trx-addons-nav-menu-item > .sub-menu::before {
		content: "";
		position: absolute;
		top: -12px;
		left: 0;
		right: 0;
		height: 12px;
	}

	.top_panel .trx-addons-nav-menu .sub-menu li {
		margin: 0;
	}

	.top_panel .trx-addons-nav-menu .sub-menu .trx-addons-menu-link {
		display: block;
		padding: .55rem 1.25rem;
		white-space: nowrap;
		font-size: .9375rem;
		color: var(--theme-color-title, #151E20) !important;
	}

	.top_panel .trx-addons-nav-menu .sub-menu .trx-addons-menu-link:hover,
	.top_panel .trx-addons-nav-menu .sub-menu .current-menu-item > .trx-addons-menu-link {
		color: var(--theme-color-link, #0CA266) !important;
		background: color-mix(in srgb, var(--theme-color-link, #0CA266) 8%, transparent);
	}

	/* The last few would otherwise open off the right edge of the window. */
	.top_panel .trx-addons-nav-menu > li:nth-last-child(-n+3) .sub-menu {
		left: auto;
		right: 0;
	}

	/* A parent with children gets a caret so it reads as openable.

	   `position: static` matters: the vendor already claims this pseudo-element
	   and positions it absolutely, so inheriting that put the chevron at
	   `left: 15px` — on top of the label's first letter rather than after it.
	   Static returns it to the inline flow the margin below assumes. */
	.top_panel .trx-addons-nav-menu-item.menu-item-has-children > .trx-addons-menu-link::after {
		content: "";
		position: static;
		display: inline-block;
		width: .38em;
		height: .38em;
		margin-left: .45em;
		vertical-align: .12em;
		border-right: 1.5px solid currentColor;
		border-bottom: 1.5px solid currentColor;
		transform: rotate(45deg);
		transition: transform .16s ease;

	}

	/* The vendor parks this pseudo-element at zero opacity unless the item is
	   the current one or hovered, so only one of the three parents ever looked
	   openable and the other two were indistinguishable from the leaf items
	   beside them. An affordance that appears only once you have already found
	   the thing is not an affordance.

	   Written out to six classes because that is what the vendor's own rule
	   costs — `.trx-addons-nav-menu-item:not(.trx-addons-active-item)
	   .trx-addons-menu-link-parent:not(:hover):not(:focus)::after` — and a
	   shorter selector loses silently. */
	.top_panel .trx-addons-nav-menu > li.trx-addons-nav-menu-item.menu-item-has-children > .trx-addons-menu-link.trx-addons-menu-link-parent::after {
		opacity: 1;
	}

	.top_panel .trx-addons-nav-menu-item.menu-item-has-children:hover > .trx-addons-menu-link::after {
		transform: rotate(-135deg);
	}
}


/* --- The submenu caret, stripped of the theme's button styling -------------
   Outside the breakpoint query on purpose. These buttons exist in the markup
   at every width — the script injects them into both nav widgets, and the
   desktop one keeps a hidden copy of the panel — so at desktop sizes they were
   picking up the design's generic button rules and sitting there as 80x36
   pills with 18/40 padding. Invisible, because the panel they live in is
   hidden, but only by luck.

   The reset belongs to the element, not to a breakpoint. Sizing still does. */
.ts1-submenu-toggle {
	margin: 0;
	padding: 0;
	background: none;
	border: 0;
	border-radius: 0;
	color: inherit;
	cursor: pointer;
	-webkit-appearance: none;
	appearance: none;
}

/* --- The mobile panel ------------------------------------------------------
   The vendor opens a full-screen panel below 1024px and then renders the
   desktop menu inside it: `ul` stays `flex-direction: row`, so seven top-level
   items lay out side by side and run to x=733 in a 390px viewport, and every
   `.sub-menu` stays `display: block` with the desktop's dark link colour on
   the panel's dark ground. The result is three overlapping columns of clipped
   text with no way to close it.

   The panel itself is right — full bleed, #1D2D2D, close control top right —
   so this rebuilds what goes inside it and leaves the panel alone.

   Everything is inside the max-width query and scoped to the panel's own
   container. The desktop dropdowns in SUBMENU_CSS are a min-width block for
   the same reason in reverse: these two must never meet. */
@media (max-width: 1024px) {

	.trx-addons-mobile-menu-outer-container .trx-addons-mobile-menu-container {
		width: 100%;
		max-width: none;
		max-height: 100vh;
		margin: 0;
		padding: 6rem 1.75rem 3rem;
		overflow-y: auto;
		-webkit-overflow-scrolling: touch;
	}

	/* Column, not row. This is the whole bug. */
	.trx-addons-mobile-menu-outer-container .trx-addons-nav-menu {
		display: flex;
		flex-direction: column;
		align-items: stretch;
		width: 100%;
		margin: 0;
		padding: 0;
		list-style: none;
		text-align: left;
	}

	/* Each row is link + caret, with the submenu wrapping onto its own line.
	   `flex-direction: row` is not the default here — the vendor's list items
	   are columns, which stacks the caret under its own label and centres both.
	   The axis has to be set back explicitly, and so does the alignment: the
	   panel centres its text and the design is ranged left. */
	.trx-addons-mobile-menu-outer-container .trx-addons-nav-menu > li {
		display: flex;
		flex-direction: row;
		flex-wrap: wrap;
		align-items: center;
		justify-content: space-between;
		width: 100%;
		margin: 0;
		text-align: left;
	}

	/* `width: auto` and `min-width: 0` matter as much as the flex shorthand:
	   the vendor's link is a full-width block, which pushes the caret onto a
	   line of its own and doubles the height of every parent row.

	   The colour is the other half. The panel inherits the desktop link colour,
	   #151E20, so on #1D2D2D every item except the current page renders as
	   near-black on dark green — the menu looks empty until you highlight it. */
	.trx-addons-mobile-menu-outer-container .trx-addons-nav-menu > li > .trx-addons-menu-link {
		flex: 1 1 auto;
		width: auto;
		min-width: 0;
		justify-content: flex-start;
		padding: .5rem 0;
		font-size: 1.75rem;
		line-height: 1.3;
		text-align: left;
		white-space: normal;
		color: var(--theme-color-alt_title, #FFFFFF) !important;
	}

	.trx-addons-mobile-menu-outer-container .trx-addons-nav-menu > li > .trx-addons-menu-link .trx-addons-menu-link-text {
		color: inherit !important;
	}

	/* Once the page is scrolled, the sticky-masthead block above recolours
	   `.top_panel` nav labels for the dark bar — and the mobile panel is inside
	   `.top_panel`, so its current-page item was being repainted #0CA266 while
	   every item beside it stayed lime.

	   The doubled class is the point: that rule is five classes deep, and this
	   one has to outrank it rather than rely on being later in the file. The
	   panel is its own surface and does not want the bar's palette. */
	.trx-addons-mobile-menu-outer-container.trx-addons-mobile-menu-outer-container .trx-addons-nav-menu > li > .trx-addons-menu-link,
	.trx-addons-mobile-menu-outer-container.trx-addons-mobile-menu-outer-container .trx-addons-nav-menu > li > .trx-addons-menu-link .trx-addons-menu-link-text {
		color: var(--theme-color-alt_title, #FFFFFF) !important;
	}

	/* The caret belongs to the row above it, so it takes the row's colour. */
	.trx-addons-mobile-menu-outer-container .trx-addons-nav-menu > li > .ts1-submenu-toggle {
		color: var(--theme-color-alt_title, #FFFFFF);
	}

	/* A parent with no href is a toggle and nothing else — say so on touch. */
	.trx-addons-mobile-menu-outer-container .trx-addons-nav-menu > li > a:not([href]) {
		cursor: pointer;
	}

	/* The desktop caret is a ::after on the link. Here the caret is its own
	   button, so the decorative one would be a second arrow. */
	.trx-addons-mobile-menu-outer-container .trx-addons-menu-link::after {
		display: none !important;
	}

	/* --- The caret button --------------------------------------------------
	   Injected by ts1-mobile-menu.js, so the menu still lists every top-level
	   item if that script fails — it just cannot collapse anything. 2.75rem is
	   a 44px tap target; the caret inside it is much smaller than that.

	   Only the sizing lives in here. The reset is outside the query — see the
	   note on it below. */
	.ts1-submenu-toggle {
		flex: 0 0 auto;
		display: flex;
		align-items: center;
		justify-content: center;
		width: 2.75rem;
		height: 2.75rem;
	}

	.ts1-submenu-toggle:focus-visible {
		outline: 2px solid currentColor;
		outline-offset: -6px;
		border-radius: 6px;
	}

	.ts1-submenu-caret {
		display: block;
		width: .5rem;
		height: .5rem;
		margin-top: -.25rem;
		border-right: 2px solid currentColor;
		border-bottom: 2px solid currentColor;
		transform: rotate(45deg);
		transition: transform .18s ease;
	}

	.ts1-submenu-open > .ts1-submenu-toggle .ts1-submenu-caret {
		margin-top: .125rem;
		transform: rotate(-135deg);
	}

	/* --- The submenu -------------------------------------------------------
	   Closed by default and opened by the caret. Plain display rather than an
	   animated height: the lists run to eight items and every technique that
	   animates open does it by guessing a max-height, which clips whichever
	   list outgrows the guess. */
	.trx-addons-mobile-menu-outer-container .trx-addons-nav-menu .sub-menu {
		flex: 0 0 100%;
		display: none;
		margin: 0 0 .5rem;
		padding: .25rem 0 .5rem .25rem;
		list-style: none;
		border-left: 1px solid rgba(255, 255, 255, .16);
	}

	.trx-addons-mobile-menu-outer-container .trx-addons-nav-menu .ts1-submenu-open > .sub-menu {
		display: block;
	}

	.trx-addons-mobile-menu-outer-container .trx-addons-nav-menu .sub-menu li {
		margin: 0;
	}

	/* The desktop rule paints these #151E20, which on this panel is dark grey
	   on dark green — present in the DOM, invisible on screen. */
	.trx-addons-mobile-menu-outer-container .trx-addons-nav-menu .sub-menu .trx-addons-menu-link {
		display: block;
		padding: .5rem 0 .5rem 1rem;
		font-size: 1rem;
		line-height: 1.35;
		white-space: normal;
		color: rgba(255, 255, 255, .74) !important;
	}

	/* The label is a span inside the link and the vendor colours the span, so
	   colouring the link alone changes nothing visible. */
	.trx-addons-mobile-menu-outer-container .trx-addons-nav-menu .sub-menu .trx-addons-menu-link-text {
		color: inherit !important;
	}

	.trx-addons-mobile-menu-outer-container .trx-addons-nav-menu .sub-menu .current-menu-item > .trx-addons-menu-link,
	.trx-addons-mobile-menu-outer-container .trx-addons-nav-menu .sub-menu .trx-addons-menu-link:hover {
		color: var(--theme-color-alt_link, #53B6E9) !important;
	}

	/* --- Close ------------------------------------------------------------
	   The control is already there, at 24px in the top right corner, painted
	   #494C4F — grey on #1D2D2D, which is why the panel reads as having no way
	   out. Only the colour is wrong. */
	.trx-addons-mobile-menu-outer-container .trx-addons-mobile-menu-close,
	.trx-addons-mobile-menu-outer-container .trx-addons-toggle-close {
		color: var(--theme-color-alt_title, #FFFFFF) !important;
	}

	/* The close control sits 22px from the top, which is underneath the admin
	   bar. Visitors never see the collision; the people building the site hit
	   it every time, and conclude the panel has no way out. */
	.admin-bar .trx-addons-mobile-menu-outer-container .trx-addons-mobile-menu-close {
		top: calc( 22px + 46px );
	}

	@media (min-width: 783px) {
		.admin-bar .trx-addons-mobile-menu-outer-container .trx-addons-mobile-menu-close {
			top: calc( 22px + 32px );
		}
	}
}


/* --- Box sizing -----------------------------------------------------------
   The captured stylesheets carry no global border-box reset, so a component
   with `width: 100%` and horizontal padding is 100% *plus* the padding. That
   is what pushed every inner page ~48px wider than the viewport on a phone and
   clipped the right-hand side of every line of text.

   Scoped to this theme's own classes rather than applied globally with `*`,
   which would change the vendor's own box model underneath it. */
[class*="ts1-"],
[class*="ts1-"]::before,
[class*="ts1-"]::after {
	box-sizing: border-box;
}

.ts1-inner .content_wrap,
.ts1-inner .content_wrap_fullscreen {
	box-sizing: border-box;
}

/* --- Mobile containment ---------------------------------------------------
   Nothing may lay out wider than the viewport on a phone. Constraining every
   wrapper in the chain rather than only hiding the overflow matters: hiding it
   on <body> stops the sideways scroll but leaves the content laid out at its
   old width, so the right-hand side of every line is simply cut off instead —
   which is exactly what was happening.

   `clip`, not `hidden`. An element with `overflow-x: hidden` is a scroll
   container, and `position: sticky` is inert inside one — which is what kept
   the masthead from pinning. `clip` refuses the same overflow without becoming
   scrollable. The `:not()` is only there to out-specify the vendor's
   `html:not(.edit-post-visual-editor)`, which sets `hidden` and would
   otherwise win on specificity. Browsers without `clip` fall back to the
   vendor's `hidden`: no sideways scroll, no sticky bar. */
@media (max-width: 1024px) {
	html:not(.edit-post-visual-editor),
	body:not(.edit-post-visual-editor) {
		overflow-x: clip;
	}

	.body_wrap,
	.page_wrap,
	.page_content_wrap,
	.content_wrap,
	.content_wrap_fullscreen,
	[class*="content_wrap"] > .content {
		max-width: 100%;
		min-width: 0;
	}

	.ts1-inner .content_wrap {
		padding-inline: 1.25rem;
	}

	/* Grid and flex children default to min-width:auto, which refuses to
	   shrink below their content and is the usual reason a track blows out
	   its container. */
	.ts1-grid > *,
	.ts1-contact-layout > *,
	.ts1-field-row > *,
	.ts1-phase > * {
		min-width: 0;
	}

	/* A long unbroken string — an email address, a URL — should wrap rather
	   than widen the page. */
	.ts1-inner .entry-content,
	.ts1-page-hero,
	.ts1-sub,
	.ts1-archive-excerpt {
		overflow-wrap: anywhere;
	}

	img,
	svg,
	video,
	iframe,
	table {
		max-width: 100%;
		height: auto;
	}
}
