:root {
	--xpro-blue: #4AA7DF;
	--xpro-purple: #3D2EA0;
	--xpro-charcoal: #55595E;
	--xpro-light-grey: #F2F2F2;
}
.loader-holder span , .par-dec    , .ser-title h3:before , .custom-skillbar ,  .con-link  , header:before , nav li a:before , .brochure-box a i.pdf-ic , .footer-info h4:before , .footer-serv-holder ul li:before ,    .color-bg , .section-title h2:before  , ul.tabs li.current .tb-item , .separator , .vis-filter li a.gallery-filter-active , .con-heading:before , .team-item  h3:before  , .form-submit button , .serv-nav  li a.act-ser , .serv-nav  li a:hover , .btn-nav li a i , .serv-sidebar  h3:before , .page-title-dec , .selectbox li:hover , .irs-single , .por-link  , .sidebar-filters li a.gallery-filter-active   , .dec-filter li a.gallery-filter-active , .sidebar-social  li a , .page-nav a , .single-slider-holder .customNavigation a , .single-carousel-holder .customNavigation a ,  .post-tags li a:hover , article h4:before , .pagination a.current-page , .search-submit , .widget-sidebar  h3:before   ,   .footer-bg-pin , .to-top:hover , .show-cart_count , .ps__thumb-y , .tc-pagination .swiper-pagination-bullet.swiper-pagination-bullet-active   , .testimonilas-text .star-rating:after  , .announcement h3 span , .order-wrap:after , .breadcrumbs-list a:before , .page-title h3:before , .det-box-media span  , .det-box-media:after , .serv_number:after , .det-list:after , .promo-link i , .pagination a.current-page , .post-tooltip  , .post-media_img:before , .ss-slider-controls2 .ss-slider-pagination .swiper-pagination-bullet , .pagination  a:hover , .widget-posts-descr:after  , .content-nav:before , .nice-select .option.focus,.nice-select .option.selected.focus  , .irs-bar , .irs-bar-edge , .mapzoom-in  , .mapzoom-out , .scrollContorl , .map-links_tabs a.ml_act , .card-item  i , .contact-social li a:hover , .close-contact-form:hover , .error-wrap h2:before , .radio-group input[type=radio]:checked + label  , .grid-item_price .add_cart:hover  , .detbox_notifer , .coupon-holder button:hover , .shop-tabs-menu li.current a , .shop-tabs-menu:after , .item-related_title:before , .grid-item h3 a:hover:before , .inline-filter .gallery-filters a:before , .column-filters a.gallery-filter-active , .column-filters a:hover    , .hidden-filter a.gallery-filter-active , .hidden-filter a:hover , .serv-nav  li a.act-scrlink , .single-zoom i  , .team-social li a:hover  , .about-img-hotifer , .about-img:before , .notifer-block:after , .notifer-block h4:before , .half-carousel-title-item h2:before   , .content-inner .cf-inner .inner h2:after , .content-inner .cf-inner .inner:after , .hero-counter-cont_wrap:after , .st-text:before , .half-carousel-content:before , .wst_dec:before  , .boxed-contai ner:before  , .team-single_header_img:before , .contats-list_widget li i  , .contats-list_widget li:hover , .team-single_header_content h2:before , .main-register .tabs-menu li.current a  , .progress-bar__progress, .hero-slider-pagination .swiper-pagination-bullet  , .hero-wrap-title_item h3:before  , .shop-item-grid_title h3:before , .hero-search-submit:hover , .hp_popup , .lg-actions .lg-next, .lg-actions .lg-prev , .order-wrap h4:before {
	background:#4AA7DF
}
.nav-holder nav li a.act-link , .nav-holder nav li ul a.act-link  , .show-reg-form i , .show-reg-form:hover ,   .color-text , .topbar-social li a , .copy-right span , .footer-contacts li a i  , .slider-box-item h4  , .sl-tabs li i  , .testimon-slider-holder .item a , .det-list li span , .det-list li a , .det-list li:before  , .box-item a , .team-item  h3:hover a , .con-list ul li i , .det-box h3 a:hover , .dynamic-title h2 a ,   .panel-button , .top-bar-header-contact li a:hover , nav ul li ul li a.act-link , .footer-serv-holder li a:hover , .footer-social li a  , .top-bar-header-contact li i , .to-top   , .footer-contacts li i , .footer-contacts li a:hover , .fw_hours span  , .dl-footer_btn:hover i , .footer_link  , .subfooter-nav li a , .nav-holder nav li a i , .header-tooltip , .close-share-btn , .share-icon  , .nav-holder nav li a:hover , .header-cart_wrap_footer a , .box-widget-content  .widget-posts-descr a:hover  , .cc-btn , .star-rating i  , .swiper-slide-active .testi-item .testi-number , .tc-button , .btn-nav li a:hover:before   , .breadcrumbs .container:before , .hero-scroll-down-notifer i  , .det-box-link    , .promo-link:hover i , .btn , .post-tags li a , .tagcloud li a   , .pagination  a , .post-opt li i , .ss-slider-cont , .cat-item   span , .box-media-zoom , .widget-posts-date i   , .content-nav li a.ln i , .content-nav li a.rn i  , .post-single-tags a , .add_comm i , .comment-reply-link , .pr-subtitle span  , .card-item:hover i , .card-link:hover , .contact-social li a  , .shop-rage-wrap .srw_btn:hover     , .shop-header h4 span , .load-more_btn   , .grid-item_price .add_cart , .pr-remove i , .cart-totals  button:hover , h4.cart-title span  , .coupon-holder button , .leave-rating label  , .item-related h3 a:hover , .grid-item h3 a:before , .grid-det_category a:hover , .grid-item h3 a:hover , .cf-counter , .hidden-filter .count-folio , .shf_btn , .shf_btn:hover:before , .video-box-btn , .slide-numb , .team-content  h4 a:hover , .tf-btn i  , .darkbg_2 .section-title  h4  , .inline-facts h6  , .about-img-title  , .nb_btn:hover , .ts_btn  , .hcw_btn   , .serv-num , .dec-icon  , .hc-item_title , .hcc_btn , .wide_section-title h5 , .boxed-facts h6  , .half-carousel-content h3 a:hover , .team-single-social li  a  , .team-contact_btn:hover  , .contats-list_widget li:hover i , .soc-log a , .filter-tags input:checked:after , .custom-form label span , .main-register .tabs-menu li  a  , .accordion-lite-header  i , .hero-wrap-title_item h3  , .hero-slider-cont , .hero-wrap-title_item h2 span , .play-pause_slider , .subcribe-form .subscribe-button  , .hero-search-title i   , .hero-search-submit , .hc_btn:hover , .menusb li i , .menusb a.act-link , .menusb a.back:before , .tbhc_btn i , .mob-hid_btn {
	color:#4AA7DF
}
.border-decor:before , footer  , nav li ul  , .nice-select:after , blockquote  {
	border-color:#4AA7DF
}
.btn.dark-bg i {
	color:#4AA7DF!important
}
/* XPro secondary accent (purple) — hover/interactive states only, kept
   distinct from the primary blue used for backgrounds/buttons/borders
   above. Appended after the primary block so cascade order wins for
   these specific selectors without touching the verified block above. */
.add_cart:hover, .card-item:hover, .card-link:hover, .close-contact-form:hover,
.hero-search-submit:hover, .promo-link:hover, .shf_btn:hover,
.show-reg-form:hover, .srw_btn:hover, .team-contact_btn:hover, .to-top:hover {
	color: #3D2EA0;
}

/* Blue-background text-contrast fix — these elements paired the blue
   background utility (.color-bg) with charcoal or near-white text,
   both of which fail contrast against XPro Blue (verified: white/blue
   2.7:1, charcoal/blue 2.64:1 — both fail the 4.5:1 minimum). Moved
   to a charcoal background + white text instead, since white holds up
   cleanly against charcoal (7:1) and charcoal-on-charcoal was
   previously an active bug on hover (.hc_btn). Elements that already
   used black text on blue (.log-submit-btn, .ord-link) are untouched —
   black-on-this-blue already passes at 7.9:1, no change needed.
   .hc_btn, .nb_btn, .dl-footer_btn moved out of the shared purple-hover
   list above and given their own complete hover rules here, since a
   background change needs to travel with its text color, not be split
   across two separately-cascading rules (that split was the root cause
   of the charcoal-hover-invisibility bug fixed this round). */
.cf-inner_title.color-bg, .hc-counter.color-bg, .testim-link.color-bg,
.about-img-title.color-bg, .about-img-hotifer.color-bg p,
.about-img-hotifer.color-bg h4, .about-img-hotifer.color-bg h5,
.dl-footer_btn.color-bg {
	color: #fff;
}
.cf-inner_title.color-bg, .hc-counter.color-bg, .testim-link.color-bg,
.about-img-title.color-bg, .about-img-hotifer.color-bg, .dl-footer_btn.color-bg {
	background: #55595E;
}
.testim-link.color-bg:hover, .dl-footer_btn.color-bg:hover {
	background: #3D2EA0;
	color: #fff;
}

/* hc_btn / nb_btn pulled out of the charcoal group above: both are used
   inside .darkbg_2 (solid charcoal) sections — "View all Projects" in
   half-carousel-title, "View All Services" in notifer-block — where a
   charcoal button background blended invisibly into its own charcoal
   parent, the exact bug already fixed once for boxed-container-title
   and dl-footer_btn. Given blue XPro background, black text (matches
   the site-wide .btn convention), purple hover — reads clearly against
   both a charcoal section and the hero slider's dark photo overlay. */
.hc_btn.color-bg, .nb_btn.color-bg {
	background: #4AA7DF;
	color: #000;
}
.hc_btn.color-bg:hover, .nb_btn.color-bg:hover {
	background: #3D2EA0;
	color: #fff;
}

/* .boxed-container-title keeps the vivid blue "pop" the template
   originally intended for its .color-bg utility class (this box is
   meant to stand out, not blend in) — the fix here is text color, not
   background. Black passes at 7.9:1 against this blue; white/charcoal
   both fail (2.7:1 / 2.64:1), same numbers established on the button
   review. The .btn nested inside this box is overridden separately
   below — the site-wide .btn is now blue-background itself (see
   style.css), which would vanish against a blue card exactly like the
   charcoal-on-charcoal bug earlier, so it gets the reverse treatment
   here: charcoal background, white text, purple on hover. */
.boxed-container-title.color-bg h2, .boxed-container-title.color-bg h4,
.boxed-container-title.color-bg p {
	color: #000;
}
.boxed-container-title.color-bg .btn {
	background: #55595E;
	color: #fff;
}
.boxed-container-title.color-bg .btn:hover {
	background: #3D2EA0;
	color: #fff;
}

/* Root-cause fix: this file's original template ships a large legacy
   selector list near the top (unrelated to any brand work — it's the
   template's own pre-existing "accent text color" list) that includes
   bare `.btn` and `.inline-facts h6`, forcing color:#4AA7DF (blue) on
   both. Because this file loads after style.css, that legacy rule wins
   over style.css's `.btn { color:#000; }` regardless of specificity
   ties — producing invisible blue-on-blue button text everywhere the
   plain .btn class is used with no special container (Read More About
   Us, Send Message, Our Story Video), and turning the "Skilled
   Professionals" stat label an unintended blue instead of its designed
   soft white. Fixed here, after that legacy list in file order, so
   these two win cleanly. */
.btn {
	color: #000;
}
.inline-facts h6 {
	color: rgba(255,255,255,0.7);
}

/* dl-footer_btn (Company Presentation.PDF) was charcoal-on-charcoal —
   the footer's own background is charcoal too, so the button had no
   visible shape distinguishing it from the footer behind it, even
   though its text was technically readable. Same lesson as the
   Request-a-Quote card: matching a surface's own background makes a
   button disappear as a *shape*, not just as text. Given blue XPro
   background, black text now (site-wide .btn convention). */
.dl-footer_btn.color-bg {
	background: #4AA7DF;
	color: #000;
}
.dl-footer_btn.color-bg:hover {
	background: #3D2EA0;
	color: #fff;
}

/* Hero stat counters ("55 Skilled Professionals" etc.) — numbers now
   XPro Blue per explicit request, replacing plain white. Honest flag:
   blue-on-charcoal here originally measured 2.65:1 with the full-
   saturation brand blue, which fails even WCAG's relaxed "large text"
   minimum (3:1) — confirmed a real problem on mobile, where the stat
   numbers were getting swallowed by the background. Lightened to a
   tint of the same blue (still clearly on-brand) that measures 4.28:1,
   comfortably past the large-text minimum, plus extra weight on
   mobile specifically since that's where it was hardest to read. */
.num {
	color: #9AD1EE;
	font-weight: 800;
}
@media (max-width: 768px) {
	.num {
		font-weight: 900;
	}
}

/* "Our Story" section's equipment-count carousel (55 Lifting Cranes,
   48 Excavators, 26 Elevators, 71 Caterpillars) sits on a .darkbg_2
   box (#55595E). .hc-item_num (the number) is explicitly white and
   fine, but .hc-item_title (the label underneath) had no color set at
   all in style.css — it was inheriting body's default text color,
   which is #55595E, the *exact same hex* as its own background. Not
   just low contrast: literally invisible, same color on same color. */
.hc-item_title {
	color: #fff;
}

/* Homepage "What We Do" heading — trims the trailing "We Are XPro."
   clause on mobile only, to save vertical space on a heading that's
   already 3 lines there; kept on desktop where there's room. */
@media (max-width: 768px) {
	.xpro-hide-mobile {
		display: none;
	}
}

/* .tbhc_btn (the mobile-only "Our Contacts" header link, swapped in
   for the full contact list below 1064px) already gets its icon color
   from color.css's shared blue-icon selector list, but making it
   explicit here guarantees it against any future edit to that list. */
.tbhc_btn i {
	color: var(--xpro-blue);
}

/* Redundant with the main nav's own Contact link one tap away —
   removed rather than just made more visible. style.css turns this on
   at the same 1064px breakpoint it hides the full contact list, so
   this override needs to match that exact breakpoint to fully cancel
   it, not the narrower 768px used elsewhere in this file. */
@media only screen and (max-width: 1064px) {
	.tbhc_btn {
		display: none;
	}
}
/* Below 630px, style.css already hides .top-bar-header-contact (at
   1064px) and .topbar-social (at 630px) — combined with .tbhc_btn now
   hidden too, .top-bar had nothing left inside it, just its own empty
   70px charcoal background rendering as a blank grey banner. Between
   630-1064px the social icons are still there and worth keeping, so
   this only hides the whole bar where it would otherwise be empty. */
@media only screen and (max-width: 630px) {
	.top-bar {
		display: none;
	}
}

/* Homepage "Built on quality" stats band (.bold-facts, the dark card
   right after "View Our Company Presentation" — "+50 Heavy Equipment"
   etc). Explicit request: 2 rows of 2, not 4 separate full-width
   stacked rows.

   First attempt at this (width:50% on .inline-facts, still float:left
   from style.css's base .inline-facts rule) produced a staggered brick
   pattern instead of a clean grid, confirmed via screenshot — classic
   float behavior with unequal-height siblings: "Heavy Equipment" wraps
   to 2 lines, "Core Services" doesn't, so their bottom edges land at
   different heights, and every float after that packs into whatever
   gap is next available rather than the next visual row. Floats
   fundamentally can't produce a clean grid once siblings have
   different heights — the real fix is flex on the parent, not a width
   tweak on the children. */
@media (max-width: 768px) {
	.bold-facts {
		display: flex;
		flex-wrap: wrap;
	}
	.bold-facts .inline-facts {
		width: 50%;
		flex: 0 0 50%;
		float: none;
		padding: 15px 10px 15px 50px;
		box-sizing: border-box;
	}
	.bold-facts .inline-facts:after {
		left: 20px;
	}
	.bold-facts .inline-facts .num {
		font-size: 22px;
	}
}

/* Footer bottom row restructure: Terms/Privacy moved next to the
   copyright (XPro's own legal info, left side); the Cyfamod builder
   credit is now the *only* thing in .subfooter-nav (right side),
   styled quieter/smaller than a real nav link — the goal is that it
   visibly reads as "attribution," not "part of XPro's own links." */
.copy-right a {
	color: rgba(255,255,255,0.61);
	text-decoration: underline;
	margin-left: 6px;
}
.copy-right a:hover {
	color: #4AA7DF;
}
.site-credit a {
	color: rgba(255,255,255,0.4);
	font-size: 10px;
	letter-spacing: 0.5px;
}
/* Pushed clear of the fixed WhatsApp/scroll-to-top buttons, which sit
   in this same bottom-right corner at every scroll position — without
   this the credit link renders directly underneath them at the
   bottom of the page. */
.subfooter-nav.site-credit {
	margin-right: 200px;
}
@media only screen and (max-width: 756px) {
	.subfooter-nav.site-credit {
		margin-right: 0;
		padding-bottom: 70px;
	}
}
.site-credit a:hover {
	color: rgba(255,255,255,0.7);
}

/* Hero slide small heading (e.g. "Your local source for construction
   solutions") was forced blue by the same pre-existing legacy selector
   list that caused the .btn and "Skilled Professionals" bugs earlier.
   On a bright, sky-heavy photo this isn't just low-contrast, it's a
   color match — blue text over a blue-toned sky is genuinely hard to
   separate regardless of overlay darkness. White reads reliably
   against the dark overlay on any of the three hero photos. */
.hero-wrap-title_item h3 {
	color: #fff;
}

/* Closing "Get A Quote" CTA band (.announcement.color-bg) — h3/p need
   explicit black, the legacy selector list forces .announcement h3 span
   blue-on-blue (avoided by not using a <span> at all here, but setting
   color explicitly too as a safety net). The .btn inside needs its own
   override for the same reason as boxed-container-title's button: the
   site-wide .btn is blue, and this parent is also blue — same color
   would blend the button into its own background. Charcoal instead. */
.announcement.color-bg h3, .announcement.color-bg p {
	color: #000;
}
.announcement.color-bg .btn {
	background: #55595E;
	color: #fff;
}
.announcement.color-bg .btn:hover {
	background: #3D2EA0;
	color: #fff;
}

/* .hwt_dec removed from all 4 hero slides entirely (index.php) after
   reviewing real screenshots — it rendered as an awkward, purposeless
   dark rectangle on every slide, not just an inconsistent one, and the
   per-slide tuning attempted here made it worse rather than better.
   No CSS override needed anymore; the base .hwt_dec rule in style.css
   is now simply unused since nothing in the HTML references it. */

/* Get A Quote CTA band — reverted to the original left-text/right-button
   2-column layout after client review; the centered/enlarged version
   didn't read well in practice. No override needed — .announcement's
   base styling (style.css) handles this layout correctly as-is. */

/* .announcement h3's decorative line/white-accent (:before/:after) ran
   through "Ready to get started?" instead of trailing after it. First
   fix attempt (shrinking the h3 to inline-block so the decoration's
   own box matched the text width) was confirmed by screenshot to still
   not work correctly — same pattern as .hwt_dec earlier: two attempts
   at tuning something purely decorative without being able to see the
   result is enough. Removing it outright rather than trying a third
   time blind. Font-size increases on h3/p also reverted here — the
   request was specifically to enlarge the Get A Quote *button*, not
   the whole section; that scope-creep is undone, only the button
   itself (below) is bigger. */
.announcement h3:before, .announcement h3:after {
	display: none;
}

/* Get A Quote button: bigger, shifted toward the center of its column,
   more right-margin breathing room, larger text, plus a pulse
   animation to draw the eye — per direct request ("draw attention,
   get people to click it"). First attempt (box-shadow glow only) was
   too subtle against the button's own blue to register as "pulsing" —
   redone combining a scale transform with a stronger, higher-contrast
   ring so the motion itself is obvious, not just a faint color shift.
   Kept scoped to .cta-btn-col rather than global .btn so this doesn't
   affect every other button on the site. */
.cta-btn-col {
	text-align: center;
	padding-right: 40px;
}
.cta-btn-col .btn.big-btn {
	float: none;
	display: inline-block;
	height: 70px;
	line-height: 70px;
	padding: 0 60px;
	font-size: 16px;
	font-weight: 700;
	margin-top: 10px;
}
@keyframes xproPulse {
	0%   { transform: scale(1);    box-shadow: 0 0 0 0 rgba(255, 255, 255, 0.7); }
	50%  { transform: scale(1.06); box-shadow: 0 0 0 16px rgba(255, 255, 255, 0); }
	100% { transform: scale(1);    box-shadow: 0 0 0 0 rgba(255, 255, 255, 0); }
}
.pulse-btn {
	animation: xproPulse 1.6s ease-in-out infinite;
}
@media (prefers-reduced-motion: reduce) {
	.pulse-btn {
		animation: none;
	}
}

/* M3 service subpages — solid-color banner in place of a photo, since every
   existing bg/ image is already used elsewhere on the site (no repeats). */
.page-title-wrap.no-photo {
	background: linear-gradient(135deg, var(--xpro-charcoal) 0%, var(--xpro-purple) 100%);
}
.page-title-wrap.no-photo:before {
	background: none;
}
/* Page-title banners render at roughly 6:1 (very wide, short) while
   the source photos are 1.78:1 — that gap is the real problem, not
   the crop position. No background-position can rescue a photo whose
   subjects are spread across the full vertical frame when the visible
   band is this short. Making the banner meaningfully taller (min-height
   below) is what actually reduces the crop, not fiddling with position. */
.page-title-wrap {
	min-height: 460px;
	display: flex;
	align-items: center;
}
.page-title-wrap .bg {
	height: 108%;
	top: -4%;
	background-position: center center !important;
}
.page-title h3:before,
.page-title h1:before {
	background: var(--xpro-blue);
}
.page-title h1 {
	float: left;
	width: 100%;
	font-weight: 800;
	color: #fff;
	text-transform: uppercase;
	text-align: left;
	font-size: 34px;
	padding-bottom: 10px;
	margin: 0;
	position: relative;
}
.page-title h1:before {
	content: '';
	position: absolute;
	left: 0;
	height: 4px;
	width: 40px;
	top: -20px;
	z-index: 2;
}
.page-title h1:after {
	content: '';
	position: absolute;
	left: 40px;
	height: 1px;
	width: 80px;
	top: -17px;
	z-index: 1;
	background: rgba(255,255,255,0.5);
}
@media (max-width: 768px) {
	.page-title h1 {
		font-size: 28px;
	}
}

/* M3 quote form fields — select/tel/number/file, matching the existing
   .custom-form text-input treatment in style.css */
.custom-form select,
.custom-form input[type=tel],
.custom-form input[type=number] {
	float: left;
	border: 1px solid #e1e1e1;
	background: #f9f9f9;
	width: 100%;
	padding: 15px 30px;
	color: #000;
	font-size: 12px;
	font-family: 'Poppins', sans-serif;
	margin-bottom: 20px;
	height: auto;
}
.custom-form input[type=file] {
	float: left;
	width: 100%;
	border: 1px dashed #ccc;
	background: #f9f9f9;
	padding: 15px;
	margin-bottom: 6px;
	font-size: 12px;
	font-family: 'Poppins', sans-serif;
}
.custom-form .form-hint {
	float: left;
	width: 100%;
	font-size: 11px;
	color: #888;
	margin-bottom: 20px;
}

/* Quote form placeholder text — lighter grey than the template
   default (#666, font-weight 500), which read too dark/heavy and
   competed with actual typed input instead of receding into the
   background like a hint should. */
.custom-form input::placeholder,
.custom-form textarea::placeholder,
.custom-form input::-webkit-input-placeholder,
.custom-form textarea::-webkit-input-placeholder {
	color: #aaa;
	font-weight: 400;
}
.custom-form input:-moz-placeholder,
.custom-form textarea:-moz-placeholder,
.custom-form input::-moz-placeholder,
.custom-form textarea::-moz-placeholder {
	color: #aaa;
	font-weight: 400;
	opacity: 1;
}

/* Quote form submit buttons — centered instead of the site-wide
   default .btn { float: left }, since these forms are standalone
   (not sitting next to other inline content that float was meant
   to wrap around). */
.custom-form .btn-centered {
	float: none;
	display: table;
	margin: 20px auto 0;
}
/* Quote form 2-column field rows (name/email, phone/location, etc.) —
   bootstrap's .row/.col-md-6 already does the layout; this just
   restores the vertical rhythm .custom-form input normally gets from
   its own margin-bottom, since nesting in col-md-6 doesn't change
   that, but needs a touch more row spacing at the row level. */
.custom-form .row {
	margin-bottom: 4px;
}

/* M3 Hiring page — two-form tab switcher (Client Request / Register as Worker),
   reusing the .tabs-menu/.tabs-act pattern already wired in js/scripts.js
   but scoped to .quote-tabs so it doesn't inherit the register-modal's styling. */
.quote-tabs .tabs-menu {
	float: left;
	width: 100%;
	margin-bottom: 30px;
	border-bottom: 1px solid #e1e1e1;
}
.quote-tabs .tabs-menu li {
	float: left;
	list-style: none;
	margin-right: 10px;
}
.quote-tabs .tabs-menu li a {
	float: left;
	padding: 14px 26px;
	font-size: 13px;
	font-weight: 600;
	color: var(--xpro-charcoal);
	border-bottom: 3px solid transparent;
}
.quote-tabs .tabs-menu li.current a {
	color: var(--xpro-purple);
	border-bottom: 3px solid var(--xpro-blue);
}
.quote-tabs .tab-content {
	float: left;
	width: 100%;
}

/* Honeypot field for the quote forms — real visitors never see or fill
   this in, so anything submitted with it filled is a bot. Formspree
   recognizes the name "_gotcha" and silently discards those submissions. */
.xpro-hp {
	position: absolute !important;
	left: -9999px !important;
	width: 1px;
	height: 1px;
	overflow: hidden;
}

/* Procurement subpage — materials list shown as pills instead of a
   plain paragraph list, matching the .tagcloud pill styling elsewhere
   in the template but without faking them as links. */
.material-tags {
	float: left;
	width: 100%;
	list-style: none;
	margin: 10px 0 20px;
	padding: 0;
}
.material-tags li {
	float: left;
	font-size: 11px;
	text-transform: uppercase;
	font-weight: 600;
	padding: 11px 22px;
	margin: 0 8px 8px 0;
	border-radius: 2px;
	background: transparent;
	border: 1px solid #ddd;
	color: var(--xpro-charcoal);
	transition: all .2s ease-in-out;
	cursor: default;
}
.material-tags li:hover {
	border-color: var(--xpro-purple);
	color: var(--xpro-purple);
}
/* Centered CTA variant for the "Get A Quote" bands at the bottom of
   each service subpage — replaces the default two-column
   (text-left/button-right) order-wrap layout with a centered stack. */
.order-wrap.centered-cta {
	text-align: center;
}
.order-wrap.centered-cta h4 {
	float: none;
	width: 100%;
	margin-bottom: 18px;
}
.order-wrap.centered-cta .ord-link {
	float: none;
	display: inline-block;
}

.material-tags-note {
	float: left;
	width: 100%;
	clear: both;
	font-style: italic;
	font-size: 12px;
	color: #888;
	margin: 4px 0 20px;
}

/* Email-fallback CTA under each quote form — a real button with equal
   visual weight to the submit button, not a quiet text link, per
   client direction to actively encourage the email path (better for
   attachments than Formspree's free tier). Charcoal instead of the
   form's brand-blue submit button, so the two remain visually
   distinguishable as two different actions. */
.email-fallback-divider {
	float: left;
	width: 100%;
	text-align: center;
	position: relative;
	margin: 30px 0 20px;
}
.email-fallback-divider span {
	position: relative;
	display: inline-block;
	padding: 0 16px;
	background: #f9f9f9;
	font-size: 11px;
	text-transform: uppercase;
	font-weight: 700;
	color: #999;
	z-index: 2;
}
.email-fallback-divider:before {
	content: '';
	position: absolute;
	top: 50%;
	left: 0;
	right: 0;
	height: 1px;
	background: #e1e1e1;
	z-index: 1;
}
.email-cta {
	float: left;
	width: 100%;
	text-align: center;
	background: var(--xpro-charcoal);
	color: #fff;
	border: none;
	border-radius: 2px;
	padding: 0 30px;
	height: 60px;
	line-height: 60px;
	font-weight: 700;
	font-size: 13px;
	text-transform: uppercase;
	transition: all .2s ease-in-out;
}
.email-cta:hover {
	background: var(--xpro-purple);
	color: #fff;
}
.email-cta i {
	margin-right: 10px;
}
.email-fallback-caption {
	float: left;
	width: 100%;
	text-align: center;
	font-size: 11px;
	color: #888;
	margin-top: 10px;
}

/* Service subpage category grids. Built as its own component rather
   than reusing .card-item — that class was designed for a horizontal
   layout (icon absolutely-positioned on the left, text indented via
   padding-left:90px), which is why the icon overflowed the box once
   dropped into this vertical flex-column card: absolute positioning
   doesn't respect the flex column at all, it just anchors to the
   card's edges regardless of content height. This component keeps
   the icon in normal document flow instead. */
.service-grid.row {
	display: flex;
	flex-wrap: wrap;
}
.service-grid.row > [class*="col-"] {
	display: flex;
}
.xpro-feature-card {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	width: 100%;
	height: 100%;
	box-sizing: border-box;
	background: #fff;
	border: 1px solid #eee;
	padding: 30px 25px;
	margin-bottom: 20px;
	transition: all .3s ease-in-out;
}
.xpro-feature-card:hover {
	box-shadow: 0 19px 20px rgba(58, 87, 135, 0.08);
}
.xpro-feature-card .icon-circle {
	flex-shrink: 0;
	width: 60px;
	height: 60px;
	line-height: 60px;
	text-align: center;
	border-radius: 50%;
	background: var(--xpro-blue);
	color: #000;
	font-size: 22px;
	margin-bottom: 18px;
}
.xpro-feature-card h4 {
	text-align: center;
	width: 100%;
	margin-bottom: 14px;
}
.xpro-feature-card p {
	text-align: center;
	width: 100%;
}
.service-sublist {
	flex: 1;
	width: 100%;
	list-style: none;
	margin: 0;
	padding: 0;
	text-align: left;
}
.service-sublist li {
	font-size: 12px;
	color: #666;
	line-height: 1.7;
	padding-left: 20px;
	position: relative;
	text-align: left;
}
.service-sublist li:before {
	font-family: Font Awesome\ 5 Pro;
	content: "\f00c";
	position: absolute;
	left: 0;
	top: 3px;
	font-size: 10px;
	color: var(--xpro-blue);
}
.service-sublist.two-col {
	column-count: 2;
	column-gap: 16px;
}
.service-sublist.two-col li {
	break-inside: avoid;
}

/* Header "Get A Quote" nav item — styled as a pill CTA so it stands out
   from the plain text links rather than blending in as just another
   nav item. */
.nav-holder nav li a.nav-cta {
	background: var(--xpro-blue);
	color: #000 !important;
	padding: 5px 20px;
	border-radius: 20px;
	margin-top: 2px;
}
.nav-holder nav li a.nav-cta:hover {
	background: var(--xpro-purple);
	color: #fff !important;
}

/* WhatsApp floating widget — site-wide, injected from partials/footer.php.
   A popup panel on click, not a bare wa.me redirect link, per the
   playbook's guidance: keep the standard recognizable WhatsApp glyph on
   the button itself (don't fight it with a brand-logo swap), reserve
   brand real estate for the avatar inside the opened panel instead. */
.xpro-wa-widget {
	position: fixed;
	right: 24px;
	bottom: 24px;
	z-index: 9999;
}
/* Fixed scroll-to-top button, reusing .to-top's existing click-to-scroll
   JS behavior (js/scripts.js) — just given fixed positioning here so it
   floats to the left of the WhatsApp button instead of only appearing
   inline at the bottom of the footer bar. */
.xpro-scrolltop-btn.to-top {
	position: fixed;
	right: 100px;
	bottom: 24px;
	top: auto;
	margin-top: 0;
	width: 60px;
	height: 60px;
	line-height: 60px;
	text-align: center;
	border-radius: 50%;
	background: var(--xpro-blue);
	color: #000;
	font-size: 22px;
	cursor: pointer;
	box-shadow: 0 6px 20px rgba(0, 0, 0, 0.25);
	transition: all .2s ease-in-out;
	z-index: 9999;
}
.xpro-scrolltop-btn.to-top:hover {
	background: var(--xpro-purple);
	color: #fff;
	transform: scale(1.08);
}
@media (max-width: 480px) {
	.xpro-scrolltop-btn.to-top {
		right: 92px;
		width: 50px;
		height: 50px;
		line-height: 50px;
		font-size: 18px;
	}
}
.xpro-wa-button {
	position: relative;
	width: 60px;
	height: 60px;
	border-radius: 50%;
	background: #25D366;
	color: #fff;
	display: flex;
	align-items: center;
	justify-content: center;
	font-size: 28px;
	cursor: pointer;
	box-shadow: 0 6px 20px rgba(0, 0, 0, 0.25);
	transition: transform .2s ease-in-out;
	animation: xproWaPulse 2.2s ease-in-out infinite;
}
.xpro-wa-button:hover {
	transform: scale(1.08);
}
.xpro-wa-badge {
	position: absolute;
	top: -2px;
	right: -2px;
	width: 20px;
	height: 20px;
	border-radius: 50%;
	background: #FF3B30;
	color: #fff;
	font-size: 11px;
	font-weight: 700;
	display: flex;
	align-items: center;
	justify-content: center;
	border: 2px solid #fff;
}
.xpro-wa-widget.xpro-wa-open .xpro-wa-badge {
	display: none;
}
@keyframes xproWaPulse {
	0%   { box-shadow: 0 6px 20px rgba(0, 0, 0, 0.25), 0 0 0 0 rgba(37, 211, 102, 0.6); }
	70%  { box-shadow: 0 6px 20px rgba(0, 0, 0, 0.25), 0 0 0 14px rgba(37, 211, 102, 0); }
	100% { box-shadow: 0 6px 20px rgba(0, 0, 0, 0.25), 0 0 0 0 rgba(37, 211, 102, 0); }
}
.xpro-wa-panel {
	position: absolute;
	right: 0;
	bottom: 76px;
	width: 300px;
	background: #fff;
	border-radius: 8px;
	box-shadow: 0 12px 40px rgba(0, 0, 0, 0.2);
	overflow: hidden;
	opacity: 0;
	visibility: hidden;
	transform: translateY(12px);
	transition: all .25s ease-in-out;
}
.xpro-wa-widget.xpro-wa-open .xpro-wa-panel {
	opacity: 1;
	visibility: visible;
	transform: translateY(0);
}
.xpro-wa-panel-header {
	background: #075E54;
	padding: 16px;
	display: flex;
	align-items: center;
	gap: 12px;
	position: relative;
}
.xpro-wa-avatar {
	width: 40px;
	height: 40px;
	border-radius: 50%;
	background: #fff;
	padding: 4px;
	box-sizing: border-box;
	flex-shrink: 0;
}
.xpro-wa-panel-header h5 {
	color: #fff;
	font-size: 14px;
	font-weight: 700;
	margin: 0 0 3px;
}
.xpro-wa-status {
	color: rgba(255, 255, 255, 0.8);
	font-size: 11px;
}
.xpro-wa-status i {
	color: #4AE54A;
	font-size: 7px;
	margin-right: 4px;
	vertical-align: middle;
}
.xpro-wa-close {
	position: absolute;
	top: 12px;
	right: 14px;
	color: rgba(255, 255, 255, 0.8);
	cursor: pointer;
	font-size: 14px;
}
.xpro-wa-close:hover {
	color: #fff;
}
.xpro-wa-panel-body {
	padding: 16px;
	background: #ECE5DD;
}
.xpro-wa-bubble {
	background: #fff;
	border-radius: 8px;
	padding: 12px 14px;
	font-size: 13px;
	line-height: 1.5;
	color: #333;
	box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
}
.xpro-wa-start-btn {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 8px;
	background: #25D366;
	color: #fff;
	font-size: 13px;
	font-weight: 700;
	text-transform: uppercase;
	padding: 14px;
	transition: background .2s ease-in-out;
}
.xpro-wa-start-btn:hover {
	background: #1DA851;
	color: #fff;
}
.xpro-wa-start-btn i {
	font-size: 18px;
}
@media (max-width: 480px) {
	.xpro-wa-panel {
		width: calc(100vw - 48px);
	}
}
@media (prefers-reduced-motion: reduce) {
	.xpro-wa-button, .xpro-wa-panel {
		transition: none;
		animation: none;
	}
}

/* Team card photos — forced to a fixed aspect ratio with object-fit:cover
   instead of each card taking its own natural image height (the default
   .respimg behaviour: width:100%, height:auto). Without this, a square
   photo (like the CEO's) renders visibly taller than the existing team
   photos' ~1.5:1 landscape ratio, breaking card-height consistency across
   the slider — and this fixes it durably for any future team photo,
   regardless of its source aspect ratio, not just this one swap. */
.team-item .det-box-media {
	aspect-ratio: 3 / 2;
	overflow: hidden;
	/* Safari/iOS flex + aspect-ratio bug: a flex item (this div, inside
	   .team-item's column flex) with aspect-ratio but no explicit width
	   can fail to resolve height correctly on older WebKit — an
	   implicit width from flex "stretch" isn't always enough. Explicit
	   width plus min-height:0 (flex items default to min-height:auto,
	   which fights aspect-ratio sizing in the same bug family) is the
	   standard defensive fix. */
	width: 100%;
	min-height: 0;
}
.team-item .det-box-media img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: center top;
}

/* Contact page address card — the address text is long enough to wrap
   across multiple lines, and .card-link's float:left alone wasn't
   enough to force left-aligned wrapped lines in this context. */
.card-item .card-link {
	text-align: left;
	width: 100%;
}

/* About page "Why Choose Us" cards — same equal-height problem as the
   team cards, different component (.card-item is a horizontal
   icon-left card, not the vertical .xpro-feature-card), so it needs
   its own scoped fix rather than reusing that one. Scoped to
   .equal-cards specifically so it doesn't affect .card-item usage
   elsewhere (e.g. Contact's 3-column info cards). */
.row.equal-cards {
	display: flex;
	flex-wrap: wrap;
}
.row.equal-cards > [class*="col-"] {
	display: flex;
}
.row.equal-cards .card-item {
	width: 100%;
	height: 100%;
	box-sizing: border-box;
}

/* .clearfix is used as a standalone <div class="clearfix"></div> in 12
   files across this codebase, but the class itself was never actually
   defined anywhere in style.css/plugins.css/color.css — every one of
   those divs has been a complete no-op. This is the real reason the
   earlier clearfix div added after Contact's "Our office:" heading
   didn't fix the map overlap: there was no clear:both behind it to
   do anything. Defining it properly here fixes that, and any other
   spot on the site quietly relying on it without working. */
.clearfix {
	clear: both;
	float: none;
	width: 100%;
}

/* Team card sizing — real root cause, found after the aspect-ratio
   image fix alone wasn't enough: Swiper's own default CSS already
   stretches .swiper-slide to equal height across the row (flex +
   height:100%, no autoHeight option set on this instance), but
   .team-item — the actual visible card, with the border/shadow that
   makes it read as a "card" at all — never had height:100% of its
   own. So the invisible slide container was equal-height the whole
   time; the visible bordered box inside it just sat at its natural
   content height and didn't fill it, which is what actually reads as
   "the cards aren't the same size." */
.team-item {
	height: 100%;
	display: flex;
	flex-direction: column;
	box-sizing: border-box;
}
.team-content {
	flex: 1;
	display: flex;
	flex-direction: column;
}

/* Portfolio grid cards — the 4 project images (images/bg/long/1-4.jpg)
   have 4 different native aspect ratios (0.75, 1.04, 0.82, 0.80), so
   .respimg's default width:100%/height:auto gave every card a
   different image height on top of Bootstrap 3's float grid never
   equal-heighting columns to begin with. Scoped to .portfolio-grid
   only — .det-box/.det-box-media are reused all over the site
   (services.php's grid, the single-service intro boxes) and most of
   those usages should NOT be forced into this treatment. */
.row.portfolio-grid {
	display: flex;
	flex-wrap: wrap;
}
.row.portfolio-grid > [class*="col-"] {
	display: flex;
}
.portfolio-grid .det-box {
	width: 100%;
	display: flex;
	flex-direction: column;
}
.portfolio-grid .det-box-media {
	aspect-ratio: 4 / 3;
	overflow: hidden;
	/* Same Safari/iOS flex + aspect-ratio gap bug as .team-item's photo
	   box above — explicit width plus min-height:0 defends against it. */
	width: 100%;
	min-height: 0;
}
.portfolio-grid .det-box-media img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: center;
}
.portfolio-grid .det-box-ietm {
	flex: 1;
	display: flex;
	flex-direction: column;
}
.hero-wrap-title_item h1 {
	font-size: 45px;
	text-align: left;
	text-transform: uppercase;
	color: #fff;
	font-weight: bold;
	line-height: 60px;
	padding-top: 10px;
	margin: 0;
}
@media (max-width: 768px) {
	.hero-wrap-title_item h1 {
		font-size: 35px;
		line-height: 45px;
	}
}

/* Page loader — swaps the template's 3-bar spinner for the actual XPro
   logo (wordmark, not the icon-only mark already used for the favicon
   and WhatsApp avatar), pulsing in place instead of bouncing bars.
   style.css's .loader-holder is a fixed 60x60 box sized for the old
   3-bar spinner; the wordmark is ~2.2:1, so the box is widened and
   re-centered here to actually show it rather than shrinking it into
   a sliver. */
.loader-holder {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 160px;
	height: 72px;
	margin: -36px 0 0 -80px;
}
.xpro-loader-logo {
	width: 100%;
	height: 100%;
	object-fit: contain;
	animation: xproLoaderPulse 1.1s ease-in-out infinite;
}
@keyframes xproLoaderPulse {
	0%, 100% { transform: scale(0.82); opacity: 0.55; }
	50% { transform: scale(1); opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
	.xpro-loader-logo {
		animation: none;
	}
}

/* .hex-bg is a fixed 450px-wide decorative pattern, position:absolute,
   painted after non-positioned content per normal CSS stacking rules —
   it sits on top of the section's text everywhere it's used. On desktop
   that only grazes a far corner of a much wider section; on mobile the
   same fixed-size box covers most of the section, including headings.
   Purely decorative in every usage, so hide it below tablet width
   instead of trying to rescale/reposition a fixed-px background. */
@media (max-width: 768px) {
	.hex-bg {
		display: none;
	}
}

/* Mobile-only auto-rotating carousel utility. Applied to static card
   grids (service feature cards, Why Choose Us cards) that stack to
   full-width blocks of uneven height on mobile once content length
   varies card to card. Gated entirely behind the media query so
   desktop layout/CSS is completely untouched — this only changes
   behavior below the tablet breakpoint. flex-wrap:nowrap plus
   align-items' default "stretch" is what makes every card equal
   height (matching the tallest), same trick used for team/portfolio
   cards elsewhere, just applied to a horizontal-scroll track instead
   of a wrapping grid. Auto-advance itself is handled by the small
   script appended to js/scripts.js.

   Selector is doubled (.xpro-mobile-carousel.xpro-mobile-carousel) to
   match the (0,2,0) specificity of .service-grid.row and
   .row.equal-cards, both of which set flex-wrap:wrap unconditionally
   — without this, their higher-specificity wrap would beat this
   rule's nowrap even inside the media query, since a media query adds
   no specificity of its own. */
@media (max-width: 768px) {
	.xpro-mobile-carousel.xpro-mobile-carousel {
		display: flex;
		flex-wrap: nowrap;
		overflow-x: auto;
		scroll-snap-type: x mandatory;
		-webkit-overflow-scrolling: touch;
		scrollbar-width: none;
		-ms-overflow-style: none;
	}
	.xpro-mobile-carousel.xpro-mobile-carousel::-webkit-scrollbar {
		display: none;
	}
	.xpro-mobile-carousel.xpro-mobile-carousel > [class*="col-"] {
		display: flex;
		flex: 0 0 100%;
		max-width: 100%;
		scroll-snap-align: start;
	}
	.xpro-mobile-carousel .card-item {
		width: 100%;
		height: 100%;
		box-sizing: border-box;
		margin-bottom: 0;
	}
}

/* Mobile hamburger menu icon — was black (style.css default), reading
   as low-contrast/invisible against whatever's behind it at the point
   it's actually used (mobile, header can read grey depending on
   surrounding chrome). Explicit brand blue instead. */
.nav-button span {
	background: var(--xpro-blue);
}

/* Homepage "Why Choose Us" cards (.col-md-8.xpro-mobile-carousel >
   .col-md-6 x4). Same underlying template bug as the "What We Do"
   grid: .col-md-6 only gets its 50%-width rule at min-width:1064px,
   and .xpro-mobile-carousel's own rules only kick in at max-width:768px
   — leaving a 769-1063px gap where these 4 cards have no width rule
   at all and shrink-wrap unpredictably.

   Uses flex on the parent, not float:left on the children — the
   .bold-facts stats band above hit a real bug taking the float route:
   cards with different content heights (a 2-line description next to
   a 1-line one) make float:left pack into a staggered brick pattern
   instead of a clean grid, confirmed via screenshot. Flex-wrap avoids
   that structurally, each row is independent regardless of height
   differences between cards. */
@media (min-width: 769px) and (max-width: 1063px) {
	.col-md-8.xpro-mobile-carousel {
		display: flex;
		flex-wrap: wrap;
	}
	.col-md-8.xpro-mobile-carousel > .col-md-6 {
		width: 50%;
		flex: 0 0 50%;
		float: none;
		box-sizing: border-box;
	}
}
