/*
Theme Name: Commercial Gear — Blue
Theme URI: https://commercialgear.com
Description: Blue-accent child theme of Hello Elementor for Commercial Gear & Sprocket. A full copy of "Hello Elementor Child" with the highlighting colour remapped from coral (#B83230 / #EC5F53) to the logo blue (#1B3FA0 / #16358A), and dark section backgrounds from navy (#0C1825) to near-black (#0B0F17) so the blue gear logo reads on them. Palette derived from next-js-blue-theme/src/app/globals.css ("LOGO-DRIVEN BRAND COLOR SYSTEM"). Content structure (CPTs, ACF) lives in a site-specific plugin, not here.
Author: Commercial Gear & Sprocket
Template: hello-elementor
Version: 1.0.0
Requires PHP: 7.4
License: GNU General Public License v3 or later
License URI: https://www.gnu.org/licenses/gpl-3.0.html
Text Domain: commercial-gear-blue
*/

/* ============================================================
   Blue-accent theme — Elementor Global Colour overrides.

   The site's highlighting colour is set in the Elementor Kit (post 7),
   which a theme cannot edit. This block re-points the Kit's generated
   CSS custom properties so every Elementor widget/section that references
   a Global Colour turns blue when THIS theme is active — no Kit change,
   fully reversible by switching back to "Hello Elementor Child".

   Per-widget HARDCODED colours (e.g. the "Site Header" and "Site Footer"
   templates set some values inline) do NOT follow globals and are not
   covered here — recolour those in the Elementor editor if needed.

   Token source: next-js-blue-theme/src/app/globals.css
   ============================================================ */
/* `body.elementor-kit-7` (specificity 0,1,1) outranks Elementor's own
   `.elementor-kit-7` (0,1,0) rule regardless of stylesheet load order. */
:root,
body.elementor-kit-7,
body.elementor-page {
	/* Accent — was #B83230 / surface #EC5F53 */
	--e-global-color-accent: #1B3FA0;
	--e-global-color-cgacsrf: #1B3FA0;   /* Accent Surface        */
	--e-global-color-cgacsrh: #16358A;   /* Accent Surface Hover  */
	--e-global-color-cgacinh: #16358A;   /* Accent Ink Hover      */
	--e-global-color-cgacond: #9DB0E4;   /* Accent On Dark        */
	/* Dark surfaces — navy → near-black so the blue logo reads */
	--e-global-color-primary: #0B0F17;
	--e-global-color-secondary: #070A10;
	--e-global-color-cgbrdod: #1C2129;   /* Border On Dark        */
	--e-global-color-cgbrddd: #141922;   /* Border On Dark Deep   */
}

/* Intentionally otherwise a straight copy of the parent child theme.
   Every colour below was remapped mechanically from coral/navy to
   blue/near-black; layout, spacing and behaviour are unchanged.
   Document further additions in wordpress-migration/MIGRATION-LOG.md
   per PROJECT.md's Custom Code Rules. */

/* ============================================================
   Global base rules — Stage 05 §10.
   These exist because Elementor Site Settings cannot express them
   cleanly. Every rule below is documented in
   wordpress-migration/05-elementor-global/ELEMENTOR-SETTINGS.md
   ============================================================ */

/* 1. Global focus ring. Elementor has no global :focus-visible setting.
   Reference: globals.css base layer. Accessibility requirement. */
:focus-visible {
	outline: 2px solid #1b3fa0;
	outline-offset: 2px;
}

/* 2. Heading overflow guard. Long uppercase tokens ("MANUFACTURING",
   part numbers) overflow viewports at 320–375px without this. */
h1, h2, h3, h4 {
	overflow-wrap: break-word;
}

/* 3. Tabular figures — spec and capacity tables compare values
   column-wise; lining figures keep digits aligned. */
table {
	font-variant-numeric: tabular-nums;
}

/* 4. Reduced-motion guard. Every hover-lift in the Next.js build is
   guarded with motion-reduce; Elementor applies transforms
   unconditionally, so this restores the guarantee. */
@media (prefers-reduced-motion: reduce) {
	.elementor-button:hover,
	.e-con:hover,
	[class*="elementor-widget"]:hover {
		transform: none !important;
	}
}

/* 5. Stop iOS Safari inflating text on orientation change. */
html {
	-webkit-text-size-adjust: 100%;
}

/* 6. Nav Menu widget text-transform override.
   Elementor Pro's nav-menu widget hard-wires its main-menu typography group's
   text-transform to the "Primary" global font (uppercase, -0.025em) via a
   base default rule with no scoped selector. Verified: setting
   menu_typography_text_transform on the widget itself is silently accepted
   into postmeta but never emitted into the generated per-widget CSS rule —
   confirmed by diffing the compiled Elementor CSS file directly. This is the
   one documented exception to "avoid unnecessary plugins/custom code":
   Elementor cannot express "no transform, no extra tracking" on this widget
   through its own controls. Reference: MainNav.tsx items are
   text-sm font-medium with no transform/tracking. */
.elementor-widget-nav-menu .elementor-nav-menu .elementor-item {
	text-transform: none;
	letter-spacing: normal;
}

/* 7. Section 3 "Our Products" — loop-grid card ordinals and hover states.
   Elementor's Loop Grid has no built-in loop-index dynamic tag and no per-item
   hover propagation to sibling elements. Both are solved here.
   Reference: next-js/src/app/page.tsx, the products .map() block —
   `group grid grid-cols-[1fr_auto] items-start gap-5 border-t ... pt-6`,
   ordinal `mt-3`/title, description `mt-2`, image `h-32 w-32 rounded-card
   overflow-hidden` with `group-hover:scale-105` on a 500ms transition.

   Ordinals (01–09): CSS counter on the loop container, emitted as ::before on
   the HTML-widget's .cgprod-ordinal span. Zero custom JS, zero extra DB fields.

   Hover state (matches Next.js's `group`/`group-hover:`): the card is an <a>
   element that fills the whole .e-loop-item box, so hovering either hits the
   same area. On hover: ordinal + title turn Accent (#1b3fa0), and the image
   zooms to 105% inside its own clipped, rounded frame. Transitions are
   disabled for users who prefer reduced motion. */

/* Counter accumulates on each loop item */
.cgprod-grid .elementor-loop-container {
	counter-reset: product-n;
}
.cgprod-grid .e-loop-item {
	counter-increment: product-n;
}

/* Ordinal rendered as ::before on the empty span */
.cgprod-ordinal::before {
	content: counter(product-n, decimal-leading-zero);
	display: block;
	font-family: 'Geist Mono', 'Courier New', monospace;
	font-size: 1.875rem;   /* 30px — text-3xl */
	font-weight: 700;
	line-height: 1;
	color: #6b6f72;        /* Border Strong — var(--e-global-color-cgbords) */
	transition: color 150ms ease;
}

/* Card layout — matches next-js/src/app/page.tsx's products .map() exactly:
   `grid grid-cols-[1fr_auto] items-start gap-5` on the card [1841676]. Text
   block [9845b10] (ordinal, title, description) is ONE grid item in column
   1; the image [d73db53] is the other grid item in column 2. `items-start`
   means each column aligns to the top of the row and is NOT stretched —
   when the text column is taller than the image, the reference genuinely
   leaves blank space below the shorter image. That's the literal Next.js
   behavior, not a bug to design around here. */
.cgprod-grid .e-loop-item [data-id="1841676"] {
	display: grid !important;
	grid-template-columns: 1fr auto !important;
	column-gap: 20px !important;
	align-items: start !important;
}
.cgprod-grid .e-loop-item [data-id="9845b10"] {
	display: flex !important;
	flex-direction: column !important;
	gap: 0 !important;
}
.cgprod-grid .e-loop-item [data-id="904880c"] {
	margin-top: 12px !important;   /* ordinal → title, mt-3 */
}
.cgprod-grid .e-loop-item [data-id="420e8e8"] {
	margin-top: 8px !important;   /* title → description, mt-2 */
}

/* Hover: ordinal and title turn Accent (#1b3fa0).
   !important on the title half only: Elementor emits its own per-widget rule
   `.elementor-145 .elementor-element-904880c .elementor-heading-title` at the
   same 4-class specificity as ours, and it's injected after this stylesheet —
   without !important it wins the tie on source order and the hover color
   never shows. */
.cgprod-grid .e-loop-item:hover .cgprod-ordinal::before {
	color: #1b3fa0;        /* Accent Ink — var(--e-global-color-accent) */
}
.cgprod-grid .e-loop-item:hover .elementor-heading-title {
	color: #1b3fa0 !important;
}

/* Title transition matches ordinal */
.cgprod-grid .e-loop-item .elementor-heading-title {
	transition: color 150ms ease;
}

/* Reduce-motion: skip the color and zoom animation */
@media (prefers-reduced-motion: reduce) {
	.cgprod-ordinal::before,
	.cgprod-grid .e-loop-item .elementor-heading-title,
	.cgprod-grid .e-loop-item .elementor-widget-image img {
		transition: none;
	}
	.cgprod-grid .e-loop-item:hover .elementor-widget-image img {
		transform: none;
	}
}

/* Image: clip to square without fixed-size container breaking flex layout.
   The card is a flex row [text block, image widget]; the image WIDGET DIV
   (not the <img>) is the actual flex item, and Elementor's `flex: 0 1 auto`
   let it shrink to fill leftover space — the <img>'s own `max-width: 100%`
   then capped it to that shrunk width, silently overriding width:128px
   below. flex-shrink:0 + max-width on the widget div itself fixes both.
   border-radius + overflow:hidden move to this wrapper (rather than the img)
   so it acts as the clipping frame for the hover zoom below — the zoomed
   img's edges stay masked at the rounded corner, matching `rounded-card
   overflow-hidden` on the Next.js wrapper. */
.cgprod-grid .e-loop-item .elementor-widget-image {
	flex-shrink: 0;
	width: 128px;
	max-width: 128px;
	border-radius: 14px;  /* --radius-card */
	overflow: hidden;
}
.cgprod-grid .e-loop-item .elementor-widget-image img {
	width:  128px;
	height: 128px;
	max-width: 128px;
	object-fit: cover;
	flex-shrink: 0;
	transition: transform 500ms cubic-bezier(0.4, 0, 0.2, 1);
}

/* Hover: image zooms to 105%, clipped by the wrapper above */
.cgprod-grid .e-loop-item:hover .elementor-widget-image img {
	transform: scale(1.05);
}

/* ============================================================
   8. Site Footer — fixes for issues Elementor cannot express
   Reference: next-js/src/components/layout/Footer.tsx
   ============================================================ */

/* 8a. Footer logo — constrain to 48px tall, auto width.
   The image widget loads attachment-full (1294px) but CSS clips it.
   Reference: className="h-12 w-auto sm:h-14" (48px / 56px) */
.elementor-element-cgftr005 img {
	height: 48px !important;
	width: auto !important;
	max-width: 220px !important;
	object-fit: contain;
}
@media (min-width: 640px) {
	.elementor-element-cgftr005 img { height: 56px !important; }
}

/* 8a-bis. Footer CTA buttons — "Call / Email us" pair.
   Reference: Footer.tsx contact CTAs — solid coral button + ghost outline button. */
.cgftr-cta-row {
	display: flex;
	flex-wrap: wrap;
	gap: 10px;
	margin: 20px 0 4px;
}
.cgftr-cta-btn {
	display: inline-flex;
	align-items: center;
	padding: 14px 28px 14px 28px;
	border-radius: 5px;
	font-size: 14px;
	font-weight: 600;
	line-height: 1.2;
	text-decoration: none;
	transition: background-color 150ms ease, border-color 150ms ease;
}
.cgftr-cta-btn--solid {
	background: #1B3FA0;
	color: #ffffff;
}
.cgftr-cta-btn--solid:hover {
	background: #15327F;
  color: #ffffff;
}
.cgftr-cta-btn--ghost {
	background: transparent;
	border: 1px solid #FFFFFF;
	color: #ffffff;
}
.cgftr-cta-btn--ghost:hover {
	color: #ffffff;
	border-color: #1B3FA0;
}
@media (prefers-reduced-motion: reduce) {
	.cgftr-cta-btn { transition: none; }
}

/* 8b. AGMA member note — coral left border + dark tinted background.
   Reference: border-l-2 border-coral-500 bg-navy-900/60 px-4 py-3 text-xs */
.elementor-element-cgftr009 .elementor-widget-container {
	border-left: 2px solid #1b3fa0;
	background: rgba(12, 24, 37, 0.6);
	padding: 12px 16px;
	font-size: 12px;
	line-height: 1.5;
	margin-top: 4px;
}

/* 8f. Footer nav column toggles — always expanded (no hamburger at any width).
   Reference: FooterNavGroup.tsx — mobile collapses by max-height, not a button.
   Use .elementor-location-footer scope so header menu is unaffected. */
.elementor-location-footer .elementor-nav-menu--toggle .elementor-menu-toggle {
	display: none !important;
}
.elementor-location-footer .elementor-nav-menu--toggle nav.elementor-nav-menu--main {
	display: block !important;
	opacity: 1 !important;
	max-height: none !important;
	overflow: visible !important;
	pointer-events: auto !important;
}
/* Mobile: tighter gap between stacked nav-menu items. (The
   flex-direction/gap rule that used to live here targeted
   [data-id="cgftr010"] — an id from an earlier footer iteration not
   present in this template at all; mobile column-stacking is handled
   by the accordion script/CSS further down instead.) */
@media (max-width: 767px) {
	.elementor-location-footer .elementor-nav-menu.sm-vertical li {
		padding: 3px 0 !important;
	}
}

/* 8f-bis. Footer nav columns — mobile accordion (cg_footer_accordion_script
   in functions.php does the class/height work; this is its paired CSS).
   Each column collapses to just its heading by default on mobile — with
   all three columns previously rendering every link expanded at once
   (per 8f above, intentional on every other breakpoint), the footer ran
   to roughly 2,500px tall on a 390px phone. */
/* Icon is injected by the script regardless of viewport (so it's already
   in place if the window is later resized down to mobile); hidden by
   default and shown only inside the mobile rule below. */
.cgftr-acc-icon {
	display: none;
}
@media (max-width: 767px) {
	.cgftr-acc-toggle .elementor-heading-title {
		display: flex !important;
		align-items: center;
		justify-content: space-between;
		gap: 12px;
		cursor: pointer;
		margin: 0 !important;
		padding: 10px 0 !important;
		border-top: 1px solid rgba(255, 255, 255, 0.1);
	}
	.cgftr-acc-icon {
		display: block;
		flex-shrink: 0;
		color: #6ba8c4;
		transition: transform 200ms ease;
	}
	.cgftr-acc-toggle.is-open .cgftr-acc-icon {
		transform: rotate(180deg);
	}
	.cgftr-acc-panel {
		transition: height 220ms ease;
	}
	.cgftr-acc-panel .elementor-nav-menu {
		padding-top: 4px !important;
		padding-bottom: 18px !important;
	}
	/* Last column's own bottom border reads as a divider before the
	   copyright bar, matching the border-top rhythm of the other two. */
	[data-id="90c88d2"] .cgftr-acc-panel {
		border-bottom: 1px solid rgba(255, 255, 255, 0.1);
	}

	/* cgftr003 (the row holding the address block + 3 nav columns)
	   carries a 40px flex-gap sized for its desktop side-by-side row —
	   not scoped down for the column stack it becomes on mobile. Each
	   column wrapper (153b90d / a65cbd8 / 90c88d2) AND its own inner
	   wrapper (321b6c3 / 36b0414 / d62d6f8) also have no padding set in
	   their own Elementor settings, so each silently inherits Elementor's
	   default 10px top+bottom — stacked two deep, that's 40px of pure
	   inherited padding per column on top of the 40px row-gap. With the
	   heading's own border-top now doing the job of separating columns,
	   all of this was pure dead space. Zeroed everywhere collapsed
	   columns don't need it. */
	[data-id="cgftr003"] {
		gap: 0 !important;
	}
	[data-id="153b90d"],
	[data-id="a65cbd8"],
	[data-id="90c88d2"],
	[data-id="321b6c3"],
	[data-id="36b0414"],
	[data-id="d62d6f8"] {
		padding-top: 0 !important;
		padding-bottom: 0 !important;
	}
}
@media (max-width: 767px) and (prefers-reduced-motion: reduce) {
	.cgftr-acc-panel,
	.cgftr-acc-icon {
		transition: none !important;
	}
}

/* 8g. Bottom bar utility nav — always horizontal, never toggles.
   Reference: flex items in a row, hover:text-white, sm:border-t */
.elementor-element-cgftr022 .elementor-menu-toggle { display: none !important; }
.elementor-element-cgftr022 nav.elementor-nav-menu--dropdown { display: none !important; }
.elementor-element-cgftr022 nav.elementor-nav-menu--main { display: block !important; }
.elementor-element-cgftr022 ul.elementor-nav-menu {
	display: flex !important;
	flex-wrap: wrap !important;
	gap: 0 !important;
	list-style: none !important;
	margin: 0 !important;
	padding: 0 !important;
}
.elementor-element-cgftr022 .elementor-item {
	color: #9bb0bf !important;
	font-size: 14px !important;
	padding: 4px 12px !important;
}
/* Separator dots between bottom-bar links */
.elementor-element-cgftr022 li + li .elementor-item::before {
	content: '\00B7' !important;
	display: inline !important;
	margin-right: 12px !important;
	color: #4a6070 !important;
}
.elementor-element-cgftr022 .elementor-item:hover { color: #fff !important; }

/* 8h. Bottom bar layout — border-top, proper spacing.
   Reference: border-t border-navy-800 mt-14 pt-8 flex justify-between */
.elementor-element-cgftr020 {
	border-top: 1px solid #1c2129 !important;
	padding-top: 32px !important;
	padding-bottom: 0 !important;
	flex-wrap: wrap;
	gap: 16px;
	align-items: center;
}
.elementor-element-cgftr021 .elementor-widget-container,
.elementor-element-cgftr021 p {
	color: #9bb0bf;
	font-size: 14px;
	margin: 0;
}
/* typography.css's body-copy <p> size out-ranks the rule above, which left
   the copyright line noticeably larger than the legal links beside it. */
.elementor-location-footer .elementor-element.elementor-element-cgftr021 p {
	font-size: 14px;
	letter-spacing: .02em;
	line-height: 1.5;
}

/* 8i. Footer main nav columns — no gap between heading and list.
   Elementor adds default padding/margin on heading widget; neutralise it. */
.elementor-element-cgftr011.elementor-widget-heading,
.elementor-element-cgftr015.elementor-widget-heading,
.elementor-element-cgftr018.elementor-widget-heading {
	margin-bottom: 0 !important;
}

/* 8j. Footer main nav row — 3 columns, no wrapping at desktop.
   Root cause: 36 + 34 + 24 = 94% plus 2 × 40px gap overflows
   the inner container between 1025–1380px, dropping the
   Capabilities+Company column to a new row.
   Fix: nowrap + redistribute widths so gaps are accounted for.
   Reference: Footer.tsx three-column layout (brand | products | nav). */
@media (min-width: 1025px) {
	.elementor-element-cgftr003 {
		flex-wrap: nowrap !important;
		align-items: flex-start !important;
		gap: 40px !important;
	}
	/* Contact / brand column — fixed at 34%, enough for logo + address */
	.elementor-element-cgftr004 {
		flex: 0 0 34% !important;
		max-width: 34% !important;
		width: 34% !important;
		box-sizing: border-box !important;
	}
	/* Products nav column — fixed at 30% (2-col menu fits comfortably) */
	.elementor-element-cgftr010 {
		flex: 0 0 30% !important;
		max-width: 30% !important;
		width: 30% !important;
		box-sizing: border-box !important;
	}
	/* Capabilities + Company column — fills all remaining space */
	.elementor-element-cgftr013 {
		flex: 1 1 0 !important;
		max-width: none !important;
		min-width: 0 !important;
		width: auto !important;
	}
}

/* 8j2. Capabilities → Company gap within the combined column */
.elementor-element-cgftr017 {
	margin-top: 40px;
	padding-top: 40px;
	border-top: 1px solid #1c2129;
}
@media (max-width: 1024px) {
	.elementor-element-cgftr017 {
		margin-top: 0;
		padding-top: 0;
		border-top: none;
	}
}

/* 8k. Footer contact column — border-bottom separator on mobile/tablet */
@media (max-width: 1024px) {
	.elementor-element-cgftr004 {
		padding-bottom: 32px;
		margin-bottom: 8px;
	}

  .cgcontact-primary {
    font-size: 14px;
  }

  .cgcontact-secondary {
    font-size: 13px;
  }
}

/* ============================================================
   9. Homepage sections §4–§13 + CTAs 1–4
   Reference: next-js/src/app/page.tsx and each section component.
   Elementor cannot express: ghost ordinals, sticky columns, JS
   slider dot nav, details/summary accordion state, card hover
   propagation from container → child text. Everything below is
   the minimal CSS to match the reference design.
   ============================================================ */

/* ── §4 Why Choose Us ──────────────────────────────────────── */
/* Reference: WhyChooseUs.tsx — 3×2 card grid, white cards on #f3f5f6,
   dark-navy icon badge, ghost ordinal top-right, bold uppercase title. */

/* 3-column card grid */
.cgwhy-grid {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: 20px;
}
@media (max-width: 1024px) { .cgwhy-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 640px)  { .cgwhy-grid { grid-template-columns: 1fr; } }

/* Individual card */
.cgwhy-card {
	background: #ffffff;
	border: 1px solid #e8eaeb;
	border-radius: 14px;
	padding: 28px;
	display: flex;
	flex-direction: column;
	gap: 0;
	transition: transform 200ms ease, box-shadow 200ms ease, border-color 200ms ease;
	position: relative;
	overflow: hidden;
}
.cgwhy-card:hover {
	transform: translateY(-4px);
	box-shadow: 0 10px 32px rgba(4,10,21,0.09);
	border-color: #d0d8dd;
}
@media (prefers-reduced-motion: reduce) {
	.cgwhy-card { transition: none; }
	.cgwhy-card:hover { transform: none; box-shadow: none; }
}

/* Top row: icon badge (left) + ghost ordinal (right) */
.cgwhy-top {
	display: flex;
	align-items: flex-start;
	justify-content: space-between;
	margin-bottom: 24px;
}

/* Icon badge — rounded square, filled with the theme Accent global
   (Elementor Global Colors → Accent = logo blue #1B3FA0). Falls back to the
   blue hex if the variable is absent. The SVG glyph is stroked white inline,
   so it reads on any accent hue. */
.cgwhy-icon-wrap {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 48px;
	height: 48px;
	background: var(--e-global-color-accent, #1b3fa0);
	border-radius: 12px;
	flex-shrink: 0;
}

/* Ghost ordinal — top-right, large mono, very light */
.cgwhy-num {
	font-family: 'Geist Mono', 'Courier New', monospace;
	font-size: 3.5rem;     /* ~56px */
	font-weight: 700;
	line-height: 0.9;
	color: #dce2e6;
	user-select: none;
	pointer-events: none;
	letter-spacing: -0.02em;
	margin-top: -4px;
}

/* Card title — bold uppercase */
.cgwhy-card-title {
  font-family: Inter, sans-serif;
	font-size: 16px;
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: 0.04em;
	color: #0b0f17;
	margin: 0 0 12px;
	line-height: 1.3;
	transition: color 150ms ease;
}
.cgwhy-card:hover .cgwhy-card-title { color: #1b3fa0; }

/* Card body */
.cgwhy-card-body {
	font-family: Inter, sans-serif;
  font-size: 14px;
  line-height: 1.5em;
  letter-spacing: 0.04em;
  color: #657e91;
	margin: 0;
}

/* Legacy selectors kept in case any other code references them */
.cgwhy-title { transition: color 150ms ease; }

/* ── §5 Capabilities (loop-grid, light bg) ─────────────────── */
/* Cap card: white card, lift + coral left border accent on hover.
   Reference: CapabilitiesGrid.tsx "group hover:-translate-y-1
   hover:border-l-2 hover:border-coral-500" */
.cgcap-card {
	transition: transform 200ms ease, box-shadow 200ms ease, border-color 200ms ease;
}
.cgcap-card:hover {
	transform: translateY(-4px);
	box-shadow: 0 8px 24px rgba(4,10,21,0.10);
	border-color: #1b3fa0 !important;  /* coral-500 */
}
.cgcap-title {
	transition: color 150ms ease;
}
.cgcap-card:hover .cgcap-title {
	color: #1b3fa0 !important;         /* accent-ink */
}
@media (prefers-reduced-motion: reduce) {
	.cgcap-card { transition: none; }
	.cgcap-card:hover { transform: none; }
}

/* ── §6 Industries (loop-grid, dark bg) ────────────────────── */
/* Reference: IndustriesGrid.tsx — dark glass cards, 3-col grid,
   title + description + arrow, coral border + bg-darken on hover
   NOTE: custom_css_classes not reliable in Elementor 4.x → use data-id selectors */

/* "All Industries" (button widget data-id=67dcc93) — REMOVED 2026-09-12.
   This block used to hardcode background, border, color, padding,
   font-size, font-weight, letter-spacing, text-transform, underline and
   the hover state, every one with !important — which meant those same
   controls in Elementor's Style tab were dead: changing the colour or
   padding in the editor produced no visible change, because this file
   always won. The button is now the site's standard primary button and
   every one of those values lives in the widget's own settings, so it
   is editable from Elementor with nothing here to override it.

   Its layout placement (right/bottom aligned beside the section
   heading) is NOT styling and stays below, where the surrounding
   flex-row layout is defined. */

/* Card container: A tag data-id=8e2e8fd */
[data-id="8e2e8fd"].e-con {
	transition: border-color 180ms ease, background 180ms ease, transform 180ms ease, box-shadow 180ms ease;
	text-decoration: none !important;
	/* Elementor's own container gap (20px) between the [title+arrow row]
	   and the description was the last big chunk of the reported dead
	   space, stacking on top of the title's own margin-bottom. */
	gap: 8px !important;
}
/* [data-id="8e2e8fd"].e-con:hover {
	border-color: #1b3fa0 !important;
	background: rgba(4,10,21,0.75) !important;
	transform: translateY(-2px);
	box-shadow: 0 6px 20px rgba(0,0,0,0.3);
} */

/* Arrow span (class added directly in HTML widget so it IS in DOM) */
.cgind-arrow {
	display: inline-block;
	color: #3d5f74;
	font-size: 16px;
	line-height: 1;
	flex-shrink: 0;
	transition: transform 150ms ease, color 150ms ease;
}
[data-id="8e2e8fd"].e-con:hover .cgind-arrow {
	transform: translate(2px, -2px);
	color: #1b3fa0;
}

@media (prefers-reduced-motion: reduce) {
	[data-id="8e2e8fd"].e-con, .cgind-arrow,
	[data-id="ee3de92"] .elementor-heading-title { transition: none; }
	[data-id="8e2e8fd"].e-con:hover { transform: none; box-shadow: none; }
	[data-id="8e2e8fd"].e-con:hover .cgind-arrow { transform: none; }
}


/* FIX: "All Industries" wraps below because 9232770 is e-con-full (width:100%).
   Override to flex-grow so it only takes needed space, freeing the right side for the button. */
[data-id="35991a9"] > [data-id="9232770"] {
	width: auto !important;
	flex: 1 1 auto !important;
	max-width: calc(100% - 180px) !important;
}

/* Button sits on the right, vertically bottom-aligned */
[data-id="35991a9"] > [data-id="67dcc93"] {
	flex-shrink: 0 !important;
	align-self: flex-end !important;
	white-space: nowrap !important;
}

/* FIX: card header row — push arrow ↗ to far right of card */
[data-id="2e51a2c"].e-con {
	justify-content: space-between !important;
	align-items: flex-start !important;
}

/* Arrow icon — slightly larger and better colour */
.cgind-arrow {
	font-size: 14px !important;
	color: #3d5f74 !important;
	line-height: 1 !important;
	margin-top: 2px !important;
}
[data-id="8e2e8fd"].e-con:hover .cgind-arrow {
	color: #1b3fa0 !important;
	transform: translate(3px, -3px);
}

/* Card description text colour */
[data-id="db39314"] p {
	color: #7a97a8 !important;
	font-size: 13px !important;
	line-height: 1.55 !important;
}

/* ── §7 Process — heading/track left-edge alignment fix ─────────────
   "How We Work" / "OUR PROCESS" (inside container 1990eb6) rendered
   10px to the right of the zigzag track below it (inside html widget
   05d94d6) — measured directly, reproducible at every viewport width
   tested (1920 down to 1100px), not a responsive-only glitch. 1990eb6
   carries no explicit padding of its own in its Elementor settings; the
   10px is Elementor's own default container padding leaking through
   where 05d94d6's sibling container (bf16fcf) explicitly zeroes its
   padding instead. Pulling 1990eb6 left by that same 10px lines its
   content up exactly with the track/cards underneath it. */
[data-id="1990eb6"] {
	margin-left: -10px !important;
}

/* ── Site-wide left-alignment QA pass (2026-09-08) ───────────────────
   Audited every homepage section's eyebrow/heading/description against
   its content grid's left edge (measured via getBoundingClientRect at
   five viewport widths, 1100–1920px). Same root cause as the Process
   fix above in both cases found: a heading-group container with no
   explicit padding of its own inherits Elementor's default 10px
   container padding, while its sibling content grid (a loop-grid or a
   container that DOES explicitly zero its padding) doesn't — so the
   heading reads 10-20px further right than the grid below it.
   Sections NOT listed here (Why Choose Us, CTA1/2, Capabilities,
   Industries, Quality, Reviews, FAQ, Contact) were measured and are
   already correctly aligned — nothing to change there. The "All
   Products"/"All Industries"/"All Articles" links sitting far from
   these numbers in the same audit are not bugs: All Products is
   deliberately centered below its grid, and Industries/Blog's links
   were deliberately moved to the right of their heading earlier this
   session — none of the three are meant to share the left edge. */

/* Products (58e92f2 > 713c9cb) — negative margin REMOVED 2026-09-12.
   This used to pull the heading group 10px LEFT to match the loop-grid
   container's edge. That was right at the time, but the product card's
   own text column (9845b10 in loop template 145) was itself leaking
   Elementor's default 10px container padding, so the visible ordinal /
   title / description sat 10px INSIDE the grid container — the heading
   lined up with the container while looking 10px left of the actual
   card text.

   9845b10 now has explicit zero padding (set in Elementor, editable
   there), so the card text sits flush with the grid container's edge.
   With the text where it belongs, this -10px hack would push the
   heading 10px left of everything else, so it is gone: heading,
   divider and card text now share one natural edge with no offset
   correction on either side. */

/* Blog (846c1fb > dc5a0b2): heading group measured 20px right of the
   loop-grid (4a44b01) — two stacked leaks here, not one: 846c1fb
   itself (holding dc5a0b2 and the "All Articles" link) has no explicit
   padding either, so its own 10px leak shifts dc5a0b2's starting
   position, and dc5a0b2 leaks another 10px on top of that. Correcting
   dc5a0b2 alone by the full 20px cancels both without touching 846c1fb
   (and so without disturbing the "All Articles" link's already-correct
   position within it). */
[data-id="dc5a0b2"] {
	margin-left: -20px !important;
}

/* Footer (Site Footer template, post 130) vs. the rest of the page.
   Two separate bugs found here, fixed in order:

   1) Internal: the company logo/address block (cgftr004) measured
      10px right of its own parent row (cgftr003) and the copyright
      bar below it (cgftr020) — the same unset-padding-leaks-
      Elementor's-default-10px pattern as Process/Products/Blog above.
      This template isn't in the homepage's own _elementor_data (it's
      a global Theme Builder template shared by every page), which is
      why the earlier homepage-only audit didn't catch it.

   2) Page-wide: even fixed internally, the whole footer still sat
      34px right of every other section's content (e.g. Contact
      directly above it, measured at 116px from the left at 1440px
      viewport width). Every homepage section centers a 1248px box
      with no padding of its own; the footer's content box (cgftr002)
      instead used a plain "width:1248px" PLUS an explicit 24px left/
      right padding on top of it (nothing else on the page does that),
      plus the same 10px default-padding leak as #1, but one layer up
      — 24 + 10 = 34.

      cgftr002 itself is only the OUTER full-width wrapper (class
      e-con-boxed); the width/padding settings actually land on its
      `.e-con-inner` CHILD, the real boxed content box — same two-
      layer pattern as every other boxed container on this site (see
      the cgcta3_o > .e-con-inner rule elsewhere in this file).
      Overriding padding alone left the box at 1140px instead of
      1248px: Elementor derives this inner box's width from a calc()
      built from the width/padding settings together, not independent
      properties, so overriding just one fed a stale value into that
      formula. Replacing width/margin/padding outright with a plain,
      ordinary centered box sidesteps the formula entirely — sized to
      1208px (not 1248px) specifically so a normally-centered box lands
      its left edge at exactly 116px, matching Contact, rather than at
      the 96px a plain 1248px box would center to on its own. */
[data-id="cgftr002"] > .e-con-inner {
	width: 100% !important;
	max-width: 1208px !important;
	margin-left: auto !important;
	margin-right: auto !important;
	padding-left: 0 !important;
	padding-right: 0 !important;
}
[data-id="cgftr004"] {
	margin-left: -10px !important;
}
/* ── §7 Process timeline — enterprise redesign (2026-09-12) ────────────
   Replaces the 2026-09-07 zigzag. Same DOM, same class names, same
   content, icons, font families, font sizes and text colors — this is a
   layout/surface/rhythm pass only, so the two functions.php scripts that
   drive it (cg_process_curtain_reveal_script + cg_process_pulse_travel_
   script) keep working untouched. The stem height stays 22px because
   that script hardcodes STEM = 22 to plot its zigzag waypoints; changing
   it here alone would desync the traveling pulse from the cards.

   What changed and why:
   - Cards were a fixed 270px tall to force a shared baseline, which left
     3 of 6 with a large empty bottom. Now each grid ROW stretches its
     cards to the tallest in that row (align-self:stretch + height:100%),
     so they still align perfectly but the box is only as tall as the row
     genuinely needs.
   - Cards were width:calc(100% + 40px) capped at max-width:240px — the
     cap meant they never used the bleed on a wide viewport, so the row
     read as small islands with big gaps. The cap is looser now and the
     bleed derives from the column-gap token.
   - The 1.5px hairline and 9px dot read as unfinished at enterprise
     scale. The rail is now a soft gradient spine and each dot gets a
     ring + halo, so the line reads deliberate rather than leftover.
   - Depth: a two-layer resting shadow and a deeper hover lift replace
     the flat 1px shadow.
   - New: a 768–1023px tablet tier (2-up card grid). Previously tablet
     fell into the 1-column mobile list, wasting half the viewport. */

.cgproc-track {
	--cgproc-line: rgba(12, 24, 37, .13);
	--cgproc-dot: #1b3fa0;
	--cgproc-icon-bg: #eef2fb;
	--cgproc-icon-fg: #1b3fa0;
	/* Surface tokens derived from the existing navy / #E8EAEB palette
	   already used site-wide; no new hues introduced. */
	--cgproc-card-bd: #e8eaeb;
	--cgproc-card-bd-hover: #c9d4e8;
	--cgproc-gap: 20px;
	display: grid;
	grid-template-columns: repeat(6, 1fr);
	grid-template-rows: auto auto auto;
	column-gap: var(--cgproc-gap);
	row-gap: 26px;
	margin: 48px 0 0 19px;
	align-items: stretch;
}

.cgproc-col { display: contents; }

/* Place each column's children into their own grid column (1–6) */
.cgproc-col:nth-child(1) > * { grid-column: 1; }
.cgproc-col:nth-child(2) > * { grid-column: 2; }
.cgproc-col:nth-child(3) > * { grid-column: 3; }
.cgproc-col:nth-child(4) > * { grid-column: 4; }
.cgproc-col:nth-child(5) > * { grid-column: 5; }
.cgproc-col:nth-child(6) > * { grid-column: 6; }

/* Dot marker on the baseline. justify-self:stretch (no explicit width)
   makes each dotwrap span its FULL column, so its own baseline segment
   can be trimmed per-column to end exactly at this dot's center. */
.cgproc-dotwrap {
	grid-row: 2;
	justify-self: stretch;
	align-self: center;
	position: relative;
	height: 28px;
	display: flex;
	align-items: center;
	justify-content: center;
}
/* Baseline segment — each dot draws only ITS OWN column's slice, so
   consecutive segments join into one continuous line while the line
   still does not exist beyond the first/last dot's center. The overhang
   is half the column gap on both sides so segments meet inside the gap
   instead of leaving a visible break at every dot. Tied to the gap
   token so the two cannot drift apart. */
.cgproc-baseline-seg {
	position: absolute;
	left: calc(var(--cgproc-gap) / -2);
	right: calc(var(--cgproc-gap) / -2);
	top: 50%;
	transform: translateY(-50%);
	height: 2px;
	border-radius: 2px;
	background: linear-gradient(90deg,
		rgba(27, 63, 160, .14) 0%,
		rgba(27, 63, 160, .22) 50%,
		rgba(27, 63, 160, .14) 100%);
	z-index: 0;
}
.cgproc-col:nth-child(1) .cgproc-baseline-seg { left: 50%; }
.cgproc-col:nth-child(6) .cgproc-baseline-seg { right: 50%; }

/* Dot — a ringed marker rather than a plain disc, so the rail reads as
   a deliberate station. The white ring keeps it legible where it
   crosses the line; the outer halo gives it presence at this size. */
.cgproc-dot {
	position: relative;
	z-index: 1;
	width: 11px;
	height: 11px;
	border-radius: 50%;
	background: var(--cgproc-dot);
	box-shadow:
		0 0 0 4px #fff,
		0 0 0 5.5px rgba(27, 63, 160, .28),
		0 0 0 10px rgba(27, 63, 160, .07);
	transition: box-shadow 220ms ease, transform 220ms ease;
}
/* Short stem linking each dot to its card. Height MUST stay 22px —
   cg_process_pulse_travel_script() hardcodes STEM = 22. */
.cgproc-dotwrap--up::before,
.cgproc-dotwrap--down::after {
	content: "";
	position: absolute;
	left: 50%;
	transform: translateX(-50%);
	width: 2px;
	height: 22px;
	border-radius: 2px;
	background: linear-gradient(var(--cgproc-line), rgba(27, 63, 160, .22));
	transition: background 220ms ease, height 220ms ease;
}
.cgproc-dotwrap--up::before { bottom: 100%; }
.cgproc-dotwrap--down::after { top: 100%; }

/* Traveling pulse — unchanged mechanism, driven per-frame from measured
   dot positions by cg_process_pulse_travel_script(). */
.cgproc-pulse {
	grid-column: 1 / -1;
	grid-row: 2;
	position: relative;
	align-self: center;
	height: 0;
	pointer-events: none;
	z-index: 2;
}
.cgproc-pulse-dot {
	position: absolute;
	top: 0;
	left: 0;
	width: 8px;
	height: 8px;
	margin: -4px 0 0 -4px;
	border-radius: 50%;
	background: var(--cgproc-dot);
	box-shadow: 0 0 10px 3px rgba(27, 63, 160, .45);
	opacity: 0;
}
.cgproc-pulse-trail {
	position: absolute;
	top: 0;
	left: 0;
	height: 2px;
	width: 0;
	border-radius: 2px;
	background: var(--cgproc-dot);
	box-shadow: 0 0 6px 1px rgba(27, 63, 160, .3);
	opacity: 0;
}
.cgproc-mobile-rail {
	display: none;
}
@media (prefers-reduced-motion: reduce) {
	.cgproc-pulse { display: none; }
}

/* Cards: one row above the baseline (up), one row below (down).
   align-self:stretch (not end/start) is what lets every card in a row
   share the tallest card's height WITHOUT a hardcoded pixel value. */
.cgproc-card--up { grid-row: 1; align-self: stretch; }
.cgproc-card--down { grid-row: 3; align-self: stretch; }

.cgproc-card {
	position: relative;
	display: flex;
	flex-direction: column;
	background: #fff;
	border: 1px solid var(--cgproc-card-bd);
	border-radius: 16px;
	padding: 22px 20px;
	/* Bleed past the card's own grid column — safe because cards
	   alternate up/down, so the neighbouring column in the SAME row is
	   always empty. Derived from the gap token: the card reclaims one
	   full gap on each side. The old fixed 240px max-width capped this
	   away on wide screens, leaving small islands. */
	width: calc(100% + (var(--cgproc-gap) * 2));
	max-width: 300px;
	margin-left: calc(var(--cgproc-gap) * -1);
	margin-right: calc(var(--cgproc-gap) * -1);
	/* Row-stretched instead of the old fixed height:270px, which left a
	   large empty bottom on the 3 shorter cards. */
	height: 100%;
	overflow: hidden;
	box-shadow:
		0 1px 2px rgba(12, 24, 37, .04),
		0 4px 16px rgba(12, 24, 37, .04);
	transition: transform 220ms ease, box-shadow 220ms ease, border-color 220ms ease, background 220ms ease,
		clip-path 950ms cubic-bezier(.16, 1, .3, 1);
}
/* Accent edge on the side the card's stem connects from — a quiet cue
   tying each card back to its dot, and the main thing that makes the
   two rows read as one system rather than two loose bands. */
.cgproc-card::after {
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	height: 3px;
	background: linear-gradient(90deg, var(--cgproc-dot), rgba(27, 63, 160, .35));
	transform: scaleX(0);
	transform-origin: left center;
	transition: transform 320ms cubic-bezier(.16, 1, .3, 1);
}
.cgproc-card--down::after { top: 0; }
.cgproc-card--up::after { bottom: 0; }
.cgproc-card:hover::after,
.cgproc-card.is-active::after { transform: scaleX(1); }

/* Curtain reveal — direction mirrors each card's position relative to
   its dot so both variants grow AWAY from the connecting stem.
   `round 16px` must match this card's border-radius or inset() clips to
   square corners throughout the reveal. */
.cgproc-card--down { clip-path: inset(0 0 100% 0 round 16px); }
.cgproc-card--down.is-revealed { clip-path: inset(0 0 0% 0 round 16px); }
.cgproc-card--up { clip-path: inset(100% 0 0 0 round 16px); }
.cgproc-card--up.is-revealed { clip-path: inset(0% 0 0 0 round 16px); }

/* One-time landing glow after the curtain finishes opening. */
@keyframes cgproc-landing-glow {
	0% { box-shadow: 0 1px 2px rgba(12, 24, 37, .04), 0 4px 16px rgba(12, 24, 37, .04), 0 0 0 0 rgba(27, 63, 160, 0); }
	35% { box-shadow: 0 1px 2px rgba(12, 24, 37, .04), 0 4px 16px rgba(12, 24, 37, .04), 0 0 0 8px rgba(27, 63, 160, .18); }
	100% { box-shadow: 0 1px 2px rgba(12, 24, 37, .04), 0 4px 16px rgba(12, 24, 37, .04), 0 0 0 0 rgba(27, 63, 160, 0); }
}
.cgproc-card.just-landed {
	animation: cgproc-landing-glow 750ms ease-out;
}
.cgproc-col:nth-child(1) .cgproc-card { transition-delay: 0ms, 0ms, 0ms, 0ms, 0ms; }
.cgproc-col:nth-child(2) .cgproc-card { transition-delay: 0ms, 0ms, 0ms, 0ms, 90ms; }
.cgproc-col:nth-child(3) .cgproc-card { transition-delay: 0ms, 0ms, 0ms, 0ms, 180ms; }
.cgproc-col:nth-child(4) .cgproc-card { transition-delay: 0ms, 0ms, 0ms, 0ms, 270ms; }
.cgproc-col:nth-child(5) .cgproc-card { transition-delay: 0ms, 0ms, 0ms, 0ms, 360ms; }
.cgproc-col:nth-child(6) .cgproc-card { transition-delay: 0ms, 0ms, 0ms, 0ms, 450ms; }

.cgproc-card:hover {
	transform: translateY(-4px);
	box-shadow:
		0 2px 4px rgba(12, 24, 37, .05),
		0 12px 28px rgba(12, 24, 37, .10);
	border-color: var(--cgproc-card-bd-hover);
}
.cgproc-card:hover .cgproc-icon {
	background: var(--cgproc-dot);
	color: #fff;
	transform: translateY(-1px);
	box-shadow: 0 6px 14px rgba(27, 63, 160, .28);
}

/* is-active — lit by cg_process_pulse_travel_script() when the traveling
   dot reaches this card, and left lit until the lap resets. The one
   moment on the page meant to look dimensional; recoloured from the old
   coral glow to the section's own navy so the palette stays as specified. */
.cgproc-card.is-active {
	transform: translateY(-6px);
	border-color: var(--cgproc-dot);
	background: linear-gradient(180deg, #ffffff 0%, #f7f9fe 100%);
	box-shadow:
		0 3px 8px rgba(27, 63, 160, .14),
		0 12px 24px rgba(27, 63, 160, .16),
		0 28px 52px rgba(27, 63, 160, .12);
}
.cgproc-card.is-active .cgproc-icon {
	background: var(--cgproc-dot);
	color: #fff;
	box-shadow: 0 6px 14px rgba(27, 63, 160, .3);
}

/* Stem + dot halo recolor once THIS dot has been visited. Stem LENGTH
   also adjusts: .is-active lifts its card 6px, so a down card moves 6px
   closer to its dot (stem shrinks to 16px) and an up card moves 6px
   farther (stem grows to 28px), keeping the stem meeting the card's real
   edge rather than overshooting. */
.cgproc-dotwrap--up.is-visited::before,
.cgproc-dotwrap--down.is-visited::after {
	background: var(--cgproc-dot);
}
.cgproc-dotwrap--down.is-visited::after { height: 16px; }
.cgproc-dotwrap--up.is-visited::before { height: 28px; }
.cgproc-dotwrap.is-visited .cgproc-dot {
	transform: scale(1.15);
	box-shadow:
		0 0 0 4px #fff,
		0 0 0 6px rgba(27, 63, 160, .45),
		0 0 0 12px rgba(27, 63, 160, .12);
}

/* Icon — squircle rather than a circle, which reads more current at
   enterprise scale and echoes the card's own 16px radius. Size, colors
   and the SVG inside are unchanged. */
.cgproc-icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 38px;
	height: 38px;
	border-radius: 11px;
	background: var(--cgproc-icon-bg);
	color: var(--cgproc-icon-fg);
	margin-bottom: 14px;
	box-shadow: inset 0 0 0 1px rgba(27, 63, 160, .07);
	transition: background 200ms ease, color 200ms ease, box-shadow 200ms ease, transform 200ms ease;
}

.cgproc-step-label {
	display: block;
	font-size: 11px;
	font-weight: 600;
	letter-spacing: .06em;
	text-transform: uppercase;
	color: #9bb0bf;
	margin-bottom: 4px;
}

.cgproc-title {
	font-size: 15px;
	font-weight: 600;
	color: #0b0f17;
	margin: 0 0 6px;
	line-height: 1.3;
}

.cgproc-body {
	font-size: 13.5px;
	line-height: 1.6;
	color: #657e91;
	margin: 0;
}

/* ── Tablet (768–1023px): 2-up card grid ──────────────────────────────
   The 6-column zigzag cannot survive this width (columns fall under
   ~110px), and dropping straight to the 1-column mobile list wastes half
   the viewport. A 2-column grid with no rail is the honest layout here:
   same cards, same order, no fake timeline. */
@media (min-width: 768px) and (max-width: 1023px) {
	.cgproc-track {
		display: grid;
		grid-template-columns: repeat(2, minmax(0, 1fr));
		grid-template-rows: none;
		column-gap: 20px;
		row-gap: 20px;
		margin-top: 4px;
	}
	.cgproc-col { display: block; }
	.cgproc-col > * { grid-column: auto; }
	.cgproc-dotwrap,
	.cgproc-pulse,
	.cgproc-mobile-rail { display: none; }
	.cgproc-card--up,
	.cgproc-card--down {
		grid-row: auto;
		align-self: stretch;
	}
	.cgproc-card {
		width: 100%;
		max-width: none;
		margin-left: 0;
		margin-right: 0;
		height: 100%;
		clip-path: none;
	}
	.cgproc-card--up::after,
	.cgproc-card--down::after { top: 0; bottom: auto; }
}

/* ── Mobile (<768px): single-column vertical timeline ─────────────── */
@media (max-width: 767px) {
	.cgproc-track {
		position: relative;
		display: flex;
		flex-direction: column;
		row-gap: 0;
	}
	.cgproc-col {
		display: flex;
		align-items: stretch;
		gap: 16px;
		padding-bottom: 20px;
	}
	.cgproc-col:last-child { padding-bottom: 0; }
	.cgproc-col > * { grid-column: unset; }
	.cgproc-dotwrap {
		order: -1;
		align-self: flex-start;
		justify-self: auto;
		width: 26px;
		margin-top: 26px;   /* aligns the dot with the card's icon row */
		flex-shrink: 0;
	}
	.cgproc-dotwrap--up::before,
	.cgproc-dotwrap--down::after,
	.cgproc-baseline-seg { display: none; }
	.cgproc-pulse {
		display: block;
		position: absolute;
		inset: 0;
		height: auto;
		grid-column: unset;
		grid-row: unset;
		align-self: unset;
	}
	/* Vertical rail — spans exactly first-dot-center to last-dot-center,
	   positioned by cg_process_pulse_travel_script(), not CSS. */
	.cgproc-mobile-rail {
		display: block;
		position: absolute;
		left: 13px;
		width: 2px;
		border-radius: 2px;
		background: var(--cgproc-line);
		z-index: 0;
	}
	.cgproc-pulse-trail {
		left: 13px;
		top: 0;
		width: 2px;
		height: 0;
	}
	.cgproc-card--up,
	.cgproc-card--down { grid-row: unset; align-self: unset; }
	.cgproc-card {
		max-width: none;
		height: auto;
		overflow: visible;
		/* No grid to bleed into here — a plain flex column, one card per
		   row — so the desktop bleed would overflow the viewport. */
		width: 100%;
		margin-left: 0;
		margin-right: 0;
	}
	/* Accent edge sits on the left on mobile, where the rail is. */
	.cgproc-card::after {
		top: 0;
		bottom: 0;
		left: 0;
		right: auto;
		width: 3px;
		height: auto;
		background: linear-gradient(180deg, var(--cgproc-dot), rgba(27, 63, 160, .35));
		transform: scaleY(0);
		transform-origin: top center;
		transition: transform 320ms cubic-bezier(.16, 1, .3, 1);
	}
	.cgproc-card:hover::after,
	.cgproc-card.is-active::after { transform: scaleY(1); }
}

@media (prefers-reduced-motion: reduce) {
	.cgproc-card { transition: none; clip-path: inset(0 0 0% 0 round 16px); }
	.cgproc-card:hover { transform: none; }
	.cgproc-card::after { transition: none; }
}

/* ── §8 Quality ─────────────────────────────────────────────── */
/* Quality image — full-bleed within its column.
   Reference: QualityCriteria.tsx — image fills column, rounded-2xl */
.cgqual-img img {
	width: 100%;
	height: auto;
	border-radius: 16px;
	object-fit: cover;
}

/* ── §9 Awards — AGMA badge area ───────────────────────────── */
/* AGMA badge — dimmed on rest, full opacity on hover */
.cgagma-badge img {
	opacity: 0.75;
	transition: opacity 200ms ease;
	max-height: 80px;
	width: auto;
	object-fit: contain;
}
.cgagma-badge:hover img { opacity: 1; }
@media (prefers-reduced-motion: reduce) {
	.cgagma-badge img { transition: none; }
}

/* ── §10 Recent Blogs (loop-grid, light bg) ─────────────────── */
/* Blog card: white card, hover lift.
   Reference: RecentBlogs.tsx "group hover:-translate-y-1 shadow-lift"

   NOTE: this card is a rendered Loop Grid item (template post 151),
   repeated once per post — its custom_css_classes setting ("cgblog-
   card" / "cgblog-title") never actually reaches the rendered markup
   in this Elementor version (verified directly in the DOM: the class
   list on the live card is only the stock elementor-element-* ones),
   so every rule below targets [data-id="d626ebf"]/[data-id="5ddcbea"]
   instead — the one attribute that DOES render, identically on all
   three repeated cards, matching the pattern used for every other
   loop-template widget on this page (Products/Capabilities/Industries
   cards all hit this same "custom class silently doesn't render"
   Elementor quirk earlier this session too). */
[data-id="d626ebf"] {
	transition: transform 200ms ease, box-shadow 200ms ease;
	/* Fixed so all three cards match regardless of title/excerpt length.
	   Now that the title block above is itself a fixed height (see
	   [data-id="5ddcbea"] below), content bottom sits at a known,
	   identical position on every card — measured at ~458px from the
	   card top, so 490px leaves a consistent ~32px footer margin
	   instead of the ~87px of dead space the old 545px value left
	   once the title-height fix stopped that gap from varying by
	   post. */
	overflow: hidden !important;
}
[data-id="d626ebf"]:hover {
	transform: translateY(-4px);
	box-shadow: 0 8px 24px rgba(4,10,21,0.10);
}
[data-id="5ddcbea"] .elementor-heading-title {
	transition: color 150ms ease;
}
[data-id="d626ebf"]:hover [data-id="5ddcbea"] .elementor-heading-title {
	color: #1b3fa0 !important;
}
/* Title → excerpt gap: the card's own flex `gap:20px` (between every
   child) plus the excerpt widget's own 4px padding-top stack to 24px —
   tightened to 8px via a negative margin-top on the excerpt only, so
   image→title and excerpt→"Read article" spacing stay untouched. */
.elementor-element-cgblog_exc {
	margin-top: -12px !important;
}
@media (prefers-reduced-motion: reduce) {
	[data-id="d626ebf"] { transition: none; }
	[data-id="d626ebf"]:hover { transform: none; }
}

/* ── §11 Reviews — infinite auto-scroll marquee (2026-09-08 redesign,
   Launch-UI-style) ───────────────────────────────────────────────
   Replaces the old manual prev/next+dots single-quote carousel with a
   continuously scrolling row of testimonial cards: track holds the 3
   sample quotes TWICE back-to-back (.cgtest-card + an aria-hidden
   duplicate set) and animates translateX(0 → -50%) on an infinite
   loop — since the second half is pixel-identical to the first, the
   reset from -50% back to 0% is invisible, giving a seamless loop
   with no JS at all. Hover pauses it (a11y: users who want to actually
   read a card no longer have to chase it); prefers-reduced-motion
   users get a static, non-animating row instead — never fully hidden,
   since the content itself is still worth reading, just not endlessly
   moving. The "Sample — pending client confirmation" badge carries
   over unchanged: these are still not real customer testimonials, and
   nothing here should read as if they were (no fabricated personal
   names/photos — avatars are initials drawn from each quote's job
   title, exactly as already attributed, not invented identities). */
.cgtest-marquee {
	position: relative;
	margin-top: 20px;
	overflow: hidden;
}
.cgtest-track {
	display: flex;
	width: max-content;
	gap: 20px;
	animation: cgtest-scroll 38s linear infinite;
}
.cgtest-marquee:hover .cgtest-track {
	animation-play-state: paused;
}
@keyframes cgtest-scroll {
	from { transform: translateX(0); }
	to   { transform: translateX(-50%); }
}
.cgtest-card {
	flex: 0 0 340px;
	background: rgba(255, 255, 255, .04);
	border: 1px solid rgba(255, 255, 255, .09);
	border-radius: 16px;
	padding: 24px;
}
.cgtest-head {
	display: flex;
	align-items: center;
	gap: 12px;
	margin-bottom: 16px;
}
.cgtest-avatar {
	flex-shrink: 0;
	width: 42px;
	height: 42px;
	border-radius: 50%;
	display: flex;
	align-items: center;
	justify-content: center;
	font-size: 13px;
	font-weight: 700;
	color: #fff;
	letter-spacing: .02em;
}
.cgtest-name {
	margin: 0;
	font-size: 14.5px;
	font-weight: 600;
	color: #fff;
	line-height: 1.3;
}
.cgtest-role {
	margin: 2px 0 0;
	font-size: 12.5px;
	color: #9bb0bf;
	line-height: 1.3;
}
.cgtest-quote {
	margin: 0;
	font-family: Inter, sans-serif;
  font-size: 14px;
  line-height: 1.5em;
  letter-spacing: 0.04em;
  color: #657e91;
}
@media (max-width: 639px) {
	.cgtest-card { flex-basis: 280px; padding: 20px; }
}
@media (prefers-reduced-motion: reduce) {
	.cgtest-track { animation: none; }
	/* Without the animation, the duplicated second half (there only to
	   make the loop seamless) would just sit visible next to the first,
	   showing the same 3 quotes twice in a row — hide it. */
	.cgtest-track > [aria-hidden="true"] { display: none; }
}

/* ── §12 FAQ ─────────────────────────────────────────────────── */

/* Left intro column — sticky at desktop so it anchors while the
   accordion scrolls past it.
   Reference: FaqAccordion.tsx — sticky left column in lg layout. */
.cgfaq-intro {
	position: sticky;
	top: 100px;
	align-self: flex-start;
	padding-right: 24px;
}
@media (max-width: 1024px) {
	.cgfaq-intro {
		position: static;
		padding-right: 0;
		padding-bottom: 40px;
		margin-bottom: 8px;
		border-bottom: 1px solid #e8eaeb;
	}
}

/* "Browse all FAQs" link in intro column */
.cgfaq-all-link {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	color: #1b3fa0;
	font-weight: 600;
	font-size: 14px;
	text-decoration: none;
  text-transform: uppercase;
	transition: gap 150ms ease, color 150ms ease;
}
.cgfaq-all-link:hover {
	color: #1b3fa0;
	gap: 12px;
}
@media (prefers-reduced-motion: reduce) {
	.cgfaq-all-link { transition: none; }
	.cgfaq-all-link:hover { gap: 8px; }
}

/* Accordion container */
.cgfaq-list {
	border-bottom: 1px solid #e8eaeb;
}

/* Each FAQ item */
.cgfaq-item {
	border-top: 1px solid #e8eaeb;
}
.cgfaq-item[open] {
	/* Subtle bg tint when open to lift the active item */
	background: #fafbfc;
	margin: 0 -20px;
	padding: 0 20px;
	border-radius: 4px;
}

/* Summary row */
.cgfaq-item summary {
	cursor: pointer;
	list-style: none;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 16px;
	padding: 22px 0;
	user-select: none;
}
.cgfaq-item summary::-webkit-details-marker { display: none; }

/* Question text */
.cgfaq-q {
	font-size: 15px;
	font-weight: 600;
	line-height: 1.45;
	color: #0b0f17;
	transition: color 150ms ease;
}
.cgfaq-item[open] .cgfaq-q {
	color: #1b3fa0;
}

/* +/× toggle icon */
.cgfaq-icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 28px;
	height: 28px;
	border-radius: 9999px;
	background: #f3f5f6;
	border: 1px solid #e8eaeb;
	color: #0b0f17;
	font-size: 17px;
	font-weight: 400;
	line-height: 1;
	flex-shrink: 0;
	transition: background 150ms ease, color 150ms ease, border-color 150ms ease;
}
.cgfaq-item[open] .cgfaq-icon {
	background: #1b3fa0;
	border-color: #1b3fa0;
	color: #fff;
}

/* Answer body — height-animated open/close.
   .cgfaq-ans is the clip box (height driven by JS, 0 → scrollHeight → auto);
   .cgfaq-ans-inner carries the padding so the clip box's own box-sizing
   never fights the measured height. Override the UA <details> rule
   (details:not([open]) > *:not(summary) { display:none }) so the content
   stays in the render tree — and animatable — through the whole collapse,
   only the JS-driven height hides it. */
.cgfaq-item > .cgfaq-ans {
	display: block !important;
	height: 0;
	overflow: hidden;
	transition: height 280ms ease;
}
.cgfaq-ans-inner {
	padding-bottom: 22px;
}
.cgfaq-ans-inner p {
	margin: 0;
	font-size: 14px;
  line-height: 1.5em;
  font-family: Inter, sans-serif;
  font-weight: 400;
  line-height: 1.5em;
  letter-spacing: 0.04em;
  color: rgb(138, 147, 163);
}

@media (prefers-reduced-motion: reduce) {
	.cgfaq-q,
	.cgfaq-icon,
	.cgfaq-ans { transition: none; }
}

/* ── CTA banners ─────────────────────────────────────────────── */
/* CTA 1 — coral diagonal gradient section.
   The diagonal gradient is set in Elementor background settings;
   CSS here adds the clip-path skew effect that matches CtaDiagonal.tsx */
.cgcta1 {
	position: relative;
	overflow: hidden;
}
/* Diagonal skew via pseudo element — decorative only */
.cgcta1::before {
	content: '';
	position: absolute;
	top: -40px;
	right: -5%;
	width: 40%;
	height: calc(100% + 80px);
	background: rgba(0,0,0,0.08);
	transform: skewX(-8deg);
	pointer-events: none;
}

/* ── Section spacing — ensure each section has comfortable padding ── */
/* Sections that don't already define padding in Elementor settings */
#cgsec4_o, #cgsec5_o, #cgsec6_o, #cgsec7_o,
#cgsec8_o, #cgsec9_o, #cgsec10_o, #cgsec11_o,
#cgsec12_o, #cgsec13_o {
	scroll-margin-top: 80px;
}

/* ── Eyebrow / section-label utility ────────────────────────── */
/* Elementor's heading widget has no eyebrow concept. We use the
   "HTML tag = span" heading, relying on the global-style eyebrow
   token. This just ensures the text widget that carries the eyebrow
   label renders inline-block so it doesn't stretch full width. */
.elementor-widget-heading .elementor-heading-title[style*="text-transform: uppercase"][style*="font-size: 11px"],
.elementor-widget-heading .elementor-heading-title[style*="text-transform:uppercase"][style*="font-size:11px"] {
	display: inline-block;
}

/* ── Loop grid gap normalization ───────────────────────────── */
/* Loop grids for capabilities and blogs share 3-col layout.
   Elementor's gap setting sometimes needs reinforcement on mobile. */
.cgcap-grid .elementor-loop-container,
.cgblog-grid .elementor-loop-container {
	gap: 24px !important;
}
@media (max-width: 767px) {
	.cgcap-grid .elementor-loop-container,
	.cgblog-grid .elementor-loop-container {
		gap: 16px !important;
	}
}

/* ============================================================
   10. FAQ + Contact two-column side-by-side layout fix.
   Root cause: Elementor flex_size:'grow' does not always emit
   flex-grow:1 in the generated CSS. The second column defaults
   to its natural content width (~1228px) which, combined with
   flex-wrap:wrap on the row, causes it to fall below the first
   column. Fix: force nowrap + flex:1 on both second columns.
   ============================================================ */

/* §12 FAQ — row: no wrap; accordion column: fill remaining space */
@media (min-width: 1025px) {
	/* Intro column — fixed at 32% */
	.elementor-element-2d5c897 {
		flex: 0 0 32% !important;
		max-width: 32% !important;
		width: 32% !important;
		box-sizing: border-box !important;
	}
	/* Accordion column — fills all remaining space */
	.elementor-element-80a23ce {
		flex: 1 1 0 !important;
		min-width: 0 !important;
		width: auto !important;
		max-width: none !important;
	}
}

/* §13 Contact — row: no wrap; form column: fill remaining space */
@media (min-width: 1025px) {
	/* Info column — fixed at 38% */
	.elementor-element-442a888 {
		flex: 0 0 38% !important;
		max-width: 38% !important;
		width: 38% !important;
		box-sizing: border-box !important;
	}
	/* Form column — fills remaining 62% minus gap */
	.elementor-element-d444c84 {
		flex: 1 1 0 !important;
		min-width: 0 !important;
		width: auto !important;
		max-width: none !important;
	}
}

/* ============================================================
   11. §2 Stats / Counter panel — dark card on very dark bg.
   Reference: StatCounters.tsx
   - Dark panel card (border #1c2129, radius 20px) centered
   - Large white bold counter numbers (~60px)
   - Coral uppercase labels (#1b3fa0)
   - Muted gray descriptions (#9bb0bf)
   - Vertical dividers between the 4 columns
   ============================================================ */

/* Ensure stat columns share width equally */
.cgstat-panel > .elementor-container,
.cgstat-panel > * {
	display: flex !important;
	flex-direction: row !important;
}
.cgstat-col {
	flex: 1 1 0 !important;
	min-width: 0 !important;
	display: flex !important;
	flex-direction: column !important;
	align-items: center !important;
	justify-content: center !important;
}
/* Vertical dividers between the stat tiles.
   These are NOT drawn by this border — the visible hairline is the 1px
   grid-gap on cgs2grid letting that container's own background show
   through between the white tiles, so cgs2grid's BACKGROUND COLOUR is
   what actually sets the divider colour (both are #E8EAEB, set in
   Elementor on cgs2grid — editable there, not here).
   The border below is kept only as the fallback for the mobile 2x2
   stack further down, and is matched to the same colour so the two
   techniques can never disagree. It was #f7faff, a leftover from when
   this card was dark navy, which was invisible on today's white tiles. */
[data-id="cgs2t2"],
[data-id="cgs2t3"],
[data-id="cgs2t4"] {
	border-left: 1px solid #E8EAEB !important;
}

/* Counter number — Elementor counter widget renders .elementor-counter-number */
.cgstat-col .elementor-counter-number-wrapper {
	font-size: 60px !important;
	font-weight: 700 !important;
	color: #ffffff !important;
	line-height: 1 !important;
	letter-spacing: -0.02em !important;
	font-family: inherit !important;
}
.cgstat-col .elementor-counter-number,
.cgstat-col .elementor-counter-number-prefix,
.cgstat-col .elementor-counter-number-suffix {
	font-size: inherit !important;
	font-weight: inherit !important;
	color: inherit !important;
	line-height: inherit !important;
	letter-spacing: inherit !important;
}

/* Override any Elementor-generated typography for counter numbers
   (these are set via style attribute by the widget JS) */
.cgstat-col .elementor-counter-number-wrapper[style] {
	font-size: 60px !important;
	color: #ffffff !important;
}

@media (max-width: 767px) {
	/* On mobile, stack 2×2 */
	.cgstat-panel {
		flex-wrap: wrap !important;
	}
	[data-id="cgs2t1"],
	[data-id="cgs2t2"],
	[data-id="cgs2t3"],
	[data-id="cgs2t4"] {
		flex: 0 0 50% !important;
		min-width: 50% !important;
		border-left: none !important;
	}
	/* Bottom dividers for top row */
	[data-id="cgs2t1"],
	[data-id="cgs2t2"] {
		border-bottom: 1px solid #E8EAEB !important;
	}
	/* Right divider between the two in each row */
	[data-id="cgs2t1"],
	[data-id="cgs2t3"] {
		border-right: 1px solid #E8EAEB !important;
	}
}

/* ============================================================
   12. Capabilities loop grid — equal card heights + hover.
   Widget: [data-id="ed8de9e"]  Template: elementor-149
   Card:   .elementor-element-5513af7
   (border #e8eaeb, radius 14px, padding 28px, flex-column)

   Problem: custom_css_classes ('cgcap-grid') is not reliably
   applied by Elementor 4.x, so target by data-id instead.
   CSS grid stretches the e-loop-item cells to row height, but
   the chain inside doesn't pass that height down to the card.
   Fix: make each level in the chain flex:1 / flex-column.
   ============================================================ */

/* 1. Reinforce align-items: stretch on the grid */
[data-id="ed8de9e"] .elementor-loop-container {
	align-items: stretch !important;
}

/* 2. e-loop-item (direct grid child) → flex column so inner
   .elementor wrapper can grow to fill the grid-cell height */
[data-id="ed8de9e"] .e-loop-item {
	display: flex !important;
	flex-direction: column !important;
}

/* 3. .elementor root inside the loop item → grow & flex */
[data-id="ed8de9e"] .e-loop-item > .elementor {
	flex: 1 !important;
	display: flex !important;
	flex-direction: column !important;
}

/* 4. Card container fills all remaining height */
[data-id="ed8de9e"] .elementor-element-5513af7 {
	flex: 1 !important;
	min-height: 0 !important;
}

/* ── Redesign (2026-09-08, per client-supplied Next.js reference) ──────
   Back to the section's original single-column header (eyebrow/title/
   description stacked on top, full width) — the two-column sticky-
   sidebar layout from the previous request is gone, along with the
   photo-led card designs before it (both the "1 featured + 2×2 grid"
   mockup and the "single card per line" list). The Next.js reference
   uses a plain bordered card — no image at all — title, description,
   and (added per this request; the reference itself doesn't have one)
   a "Read More" link. Grid: 3 cards on row 1, 2 on row 2, matching the
   reference exactly. */
[data-id="cgsec5_i"] > .e-con-inner {
	flex-direction: column !important;
}
[data-id="cgcapleft"] {
	flex: 1 1 auto !important;
	max-width: none !important;
	position: static !important;
}
[data-id="ed8de9e"] {
	/* Elementor gives this widget its own internal default width (a
	   flex-basis computed from a --container-widget-flex-grow custom
	   property, independent of the parent's flex-direction) that was
	   quietly rendering it at exactly 50% of the section width — width
	   and flex-basis both forced to override it. */
	flex: 1 1 100% !important;
	width: 100% !important;
}
[data-id="ed8de9e"] .elementor-loop-container {
	max-height: none !important;
	overflow: visible !important;
	padding-right: 0 !important;
}

/* No image in this section — the card template still carries the
   image widget (6b80a53) for the sections that DO use it elsewhere;
   simplest to hide it here than to strip it from a shared template. */
[data-id="ed8de9e"] .elementor-element-6b80a53 {
	display: none !important;
}

/* Bordered card, no photo — title, description, "Read More" link. */
[data-id="ed8de9e"] .elementor-element-5513af7 {
	border-radius: 12px !important;
	padding: 28px !important;
	overflow: visible !important;
	gap: 0 !important;
	transition: border-color 200ms ease, box-shadow 200ms ease;
}
[data-id="ed8de9e"] .elementor-element-5513af7:hover {
	border-color: #1b3fa0 !important;
	box-shadow: 0 8px 24px rgba(4, 10, 21, 0.08);
}

[data-id="ed8de9e"] .elementor-element-5513af7:hover [data-id="0269ef9"] .elementor-heading-title {
	color: #1b3fa0 !important;
}

.cgcap-learnmore {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	margin-top: 16px;
	font-size: 12px;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.06em;
	color: #1b3fa0;
	transition: gap 150ms ease;
}
[data-id="ed8de9e"] .elementor-element-5513af7:hover .cgcap-learnmore {
	gap: 10px;
}

/* Desktop: 3 cards on row 1, 2 on row 2 — a 6-column base so both row
   widths divide evenly (row-1 cards each span 2 of 6, row-2 cards each
   span 3 of 6); normal grid auto-flow then places row 2 on its own
   line with no explicit grid-row needed. nth-of-type, not nth-child —
   Elementor injects one leading <style> tag as a sibling before the
   .e-loop-item divs, which throws nth-child's count off by one. */
@media (min-width: 900px) {
	[data-id="ed8de9e"] .elementor-loop-container {
		grid-template-columns: repeat(6, 1fr) !important;
		align-items: stretch !important;
	}
	[data-id="ed8de9e"] .e-loop-item:nth-of-type(1),
	[data-id="ed8de9e"] .e-loop-item:nth-of-type(2),
	[data-id="ed8de9e"] .e-loop-item:nth-of-type(3) {
		grid-column: span 2 !important;
	}
	[data-id="ed8de9e"] .e-loop-item:nth-of-type(4),
	[data-id="ed8de9e"] .e-loop-item:nth-of-type(5) {
		grid-column: span 3 !important;
	}
	[data-id="ed8de9e"] .elementor-element-5513af7 {
		height: 100%;
	}
}

@media (prefers-reduced-motion: reduce) {
	[data-id="ed8de9e"] .elementor-element-5513af7 {
		transition: none;
	}
}

/* ══════════════════════════════════════════════════════════════════════
   COMPREHENSIVE SECTION AUDIT FIXES — 2026-09-05
   Issues found: dark text on dark bg (CTA-2, Testimonials), process
   padding, contrast, icon weight, arrow brightness, spacing.
   ══════════════════════════════════════════════════════════════════════ */


/* ── §13 CTA-3 — alignment: inner max-width now boxed via data fix;
       CSS backup in case Elementor still stretches left side.
       1248px — matches every other section's content column (incl.
       the Certifications card directly above it); briefly widened to
       1800px on request, then reverted to line up with that card. */
[data-id="cgcta3_o"] > .e-con-inner {
	max-width: 1248px !important;
	margin-left: auto !important;
	margin-right: auto !important;
	padding-left: 0 !important;
	padding-right: 0 !important;
}

/* ── CTA-3 "Our quality system is open for inspection" — rebuilt
   2026-09-13 as native Elementor Pro widgets (container + image +
   heading + text-editor + buttons) so every piece is separately
   editable in the Elementor panel. Visual design (dark rounded card,
   34% photo/66% content split, typography, buttons) is unchanged from
   the previous custom-HTML version — these rules just fill in the
   handful of things Elementor's own controls don't reach (the image
   filling its column via absolute positioning, and the mobile
   side-by-side button row). */
[data-id="cgqcimg01"] {
	position: relative !important;
	overflow: hidden;
	flex: 0 0 34% !important;
	width: 34% !important;
	min-height: 380px !important;
}
[data-id="cgqcimgw1"] {
	position: absolute !important;
	inset: 0;
	width: 100% !important;
	height: 100%;
}
[data-id="cgqcimgw1"] .elementor-widget-container,
[data-id="cgqcimgw1"] .e-con-inner {
	height: 100%;
}
[data-id="cgqcimgw1"] img {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}
[data-id="cgqccont1"] {
	flex: 1 1 auto !important;
	width: auto !important;
	min-width: 0;
}
@media (max-width: 900px) {
	[data-id="cgqcrow01"] {
		max-width: 100% !important;
	}
	[data-id="cgqcimg01"] {
		flex-basis: auto !important;
		width: 100% !important;
		min-height: 220px !important;
	}
	[data-id="cgqccont1"] {
		width: 100% !important;
		max-width: 100% !important;
		box-sizing: border-box;
	}
	[data-id="cgqcdesc1"],
	[data-id="cgqcdesc1"] p {
		max-width: 100% !important;
	}
}
@media (max-width: 767px) {
	/* Side by side, not stacked — matches the original mobile layout
	   where both buttons share one row instead of wrapping to a
	   column. */
	[data-id="cgqcbtnrow"] {
		flex-wrap: nowrap !important;
		max-width: 100%;
	}
	[data-id="cgqcbtn01"],
	[data-id="cgqcbtn02"] {
		flex: 1 1 0;
		min-width: 0;
	}
	[data-id="cgqcbtn01"] .elementor-button,
	[data-id="cgqcbtn02"] .elementor-button {
		width: 100%;
		justify-content: center;
		text-align: center;
		padding-left: 10px;
		padding-right: 10px;
	}
}
@media (prefers-reduced-motion: reduce) {
	[data-id="cgqcbtn01"] .elementor-button,
	[data-id="cgqcbtn02"] .elementor-button {
		transition: none;
	}
}

/* ── §8 Industries — ↗ arrow: brighter for better contrast on dark card ─ */
/* Was #3d5f74 = ~2.0:1 on dark card bg. Brighter = better readability.   */
.cgind-arrow {
	color: #6ba8c4 !important;   /* ~3.5:1 on rgba(4,10,21,0.45) card bg */
}
[data-id="8e2e8fd"].e-con:hover .cgind-arrow {
	color: #1b3fa0 !important;
	transform: translate(3px, -3px);
}

/* .cgind-arrow is now an inline Lucide SVG ("arrow-up-right", MIT
   licensed, lucide.dev) instead of the Unicode "↗" character it used to
   be — the glyph rendered as a solid emoji-style boxed icon on some
   platforms' font fallback, which read as an unwanted "solid icon" the
   line-art SVG replaces. stroke="currentColor" on the SVG itself means
   the color rules above still work unchanged. */
.cgind-arrow {
	display: block !important;   /* drop the inline-SVG baseline gap */
	flex-shrink: 0 !important;
}

/* Loop-card widgets are native (editable in Elementor):
   - Industry Card (template 150): the arrow is an Icon widget (de5743b,
     class cgind-arrow) showing an uploaded line-art SVG, so .cgind-arrow is
     now the widget wrapper; keep the glyph line-art and sized to 16px.
   - Blog Card (template 151): "Read article →" is a Heading widget
     (8420dab, class cgblog-more) — plain text because the whole card is
     already the link; the excerpt is a Text Editor (cgblog_exc) using the
     Post Excerpt dynamic tag (bare text, no <p>), styled by the
     .elementor-element-cgblog_exc rules further down. */
:is(.cgind-arrow, [data-id="de5743b"]) .elementor-icon-wrapper { line-height: 0; }
:is(.cgind-arrow, [data-id="de5743b"]) .elementor-icon { display: block; font-size: 16px !important; color: inherit !important; }
:is(.cgind-arrow, [data-id="de5743b"]) .elementor-icon svg { width: 16px; height: 16px; }
:is(.cgind-arrow, [data-id="de5743b"]) .elementor-icon :is(svg, svg *) { fill: none !important; stroke: currentColor !important; }
:is(.cgblog-more, [data-id="8420dab"]) .elementor-heading-title {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	margin-top: 16px;
	font: 700 13px/1.3 "Inter", sans-serif !important;
	letter-spacing: .05em !important;
	text-transform: uppercase !important;
	color: #1b3fa0 !important;
}

/* Row [2e51a2c] = title + arrow, side by side (flex-direction:row,
   space-between). On narrow cards the row had no explicit nowrap, so
   the arrow occasionally wrapped onto its OWN line below the title —
   stretching the row from ~50px to ~99px tall and pushing the
   description down with it (the reported "wasted space"). Keeping both
   on one line and letting the title's own text wrap within its own
   column removes that dead space entirely. */
[data-id="2e51a2c"] {
	flex-wrap: nowrap !important;
	gap: 12px !important;
}
[data-id="ee3de92"] {
	flex: 1 1 auto !important;
	min-width: 0 !important;   /* allow the title to wrap instead of forcing the row wider */
}

/* ── Industry card title icons — REMOVED (2026-09-12) ─────────────────
   The nine per-industry Lucide icons that used to live here were CSS
   `::before` background-images keyed off each card's href, which meant
   they were invisible to Elementor and could only be changed in this
   file. They're replaced by a real Image widget (id "cgindimg") in the
   Industries loop template (post 150), bound to the dynamic
   "post-featured-image" tag — so each card's image is now the Featured
   Image of its own `industry` post, swappable from the Elementor Image
   control / Media Library with no code change. The title is a plain
   text row again; only the layout reset below remains. */
[data-id="ee3de92"] h3.elementor-heading-title {
	display: block !important;
}

/* ── Industry card media ──────────────────────────────────────────────
   Sizing only — a fixed aspect ratio so all nine cards keep the same
   rhythm regardless of the uploaded image's dimensions. Everything
   else (the image itself, its border-radius, spacing, alt text) stays
   editable from the Image widget's Content/Style tabs.

   Keyed off [data-id="cgindimg"], not the widget's `custom_css_classes`
   — Elementor 4.x does not render that key for these elements (see the
   same finding behind the [data-id=...] rules above), so the stable
   widget id is what CSS can actually hook. All nine cards share this id
   because they're nine renders of the one loop template. */
[data-id="cgindimg"] img {
	display: block;
	width: 100%;
	aspect-ratio: 3 / 2;
	object-fit: cover;
	background: #f1f5f9;   /* placeholder ground before the image paints */
}

/* ── Industry cards — equal height per row (2026-09-12) ───────────────
   The grid used to run in Elementor's masonry mode, which deliberately
   staggers items to different heights — no amount of stretch can
   equalise cards while that's on, so masonry was switched OFF in the
   loop-grid widget's own settings (post 16, widget 76f3c44) and this
   block does the equalising the normal grid way.

   Three levels have to stretch, because each is a separate box between
   the grid track and the card's border:
     .elementor-grid          the CSS-grid container itself
     .e-loop-item             Elementor's per-item wrapper
     a[data-id="8e2e8fd"]     the bordered card
   Stretch is the grid default, but each level must also pass the full
   track height DOWN to the next — a wrapper that hugs its content
   leaves the card short regardless of the track. No fixed heights: the
   tallest card in each row sets the height, at every breakpoint, and
   the single-column mobile layout is unaffected (one item per row). */
[data-id="76f3c44"] .elementor-grid {
	align-items: stretch;
}
[data-id="76f3c44"] .elementor-loop-container > .e-loop-item {
	display: flex;
	height: 100%;
}
[data-id="76f3c44"] .e-loop-item > a[data-id="8e2e8fd"] {
	height: 100%;
	width: 100%;
}

/* Inside the card: image and title keep their natural size, and the
   description takes the leftover space so every card's text block
   starts at the same y-offset and the card bottom is flush. The
   description is the flex item that grows — not the image — so the
   image area stays exactly as designed. */
[data-id="8e2e8fd"] > [data-id="db39314"] {
	flex-grow: 1;
}

/* ── Icons — ensure all icon wrappers use light weight (not bold) ──────── */
/* cgwhy-icon-wrap (Why Choose Us), cgfaq-icon (FAQ) already fw=400 ✓
   Add for any generic Elementor icon widgets that might inherit bold */
.elementor-icon i,
.elementor-icon svg,
[class*="cgwhy"] i,
[class*="cgfaq"] i {
	font-weight: 300 !important;   /* light / thin weight icons */
}

/* ── Eyebrow contrast — on light sections coral needs to be slightly ────
   darker to clear 4.5:1 AA. #1b3fa0 = 3.5:1 on white, #1b3fa0 = 4.6:1  */
/* Only darken on white/light-bg sections; keep bright coral on dark bg   */
[data-id="cgsec3_o"]  .cgwhy-eyebrow,    /* Why Choose Us */
[data-id="cgsec4_o"]  .cgwhy-eyebrow,
[data-id="cgsec5_o"]  [data-id="4f35b2d"] .elementor-heading-title,
[data-id="cgsec7_o"]  [data-id="a97f15b"] .elementor-heading-title,
[data-id="cgsec8_o"]  [data-id] .elementor-heading-title[style*="ec5f53"],
[data-id="cgsec9_o"]  [data-id] .elementor-heading-title[style*="ec5f53"],
[data-id="cgsec10_o"] [data-id] .elementor-heading-title[style*="ec5f53"],
[data-id="cgsec12_o"] [data-id] .elementor-heading-title[style*="ec5f53"],
[data-id="cgsec13_o"] [data-id] .elementor-heading-title[style*="ec5f53"],
[data-id="cgcta4_o"]  [data-id] .elementor-heading-title[style*="ec5f53"] {
	color: #1b3fa0 !important;   /* 4.6:1 on white — passes WCAG AA */
}

/* ── FAQ expand/collapse icon — REMOVED (2026-09-08).
   This dated from when the icon was literally a "+"/"×" text
   character; it's now a real Lucide SVG (see .cgfaq-icon above), but
   this rule's `color: #9bb0bf !important` was left behind and — since
   !important always wins regardless of source order or the later,
   more-specific .cgfaq-item[open] .cgfaq-icon rule — was silently
   keeping the OPEN state's × muted grey-blue instead of white, right
   on top of its own solid red circle: exactly the low-contrast,
   "X is not readable" bug reported against it. */

/* ── Capabilities cards — equalise heights within each row ─────────── */
/* Row 2 was 28px taller than row 1 due to longer titles.
   Enforce min-height so both rows feel consistent. */
[data-id="ed8de9e"] .elementor-element-5513af7 {
	min-height: 200px !important;
}

/* ── Contact section (§17) — info card consistent min-height ────────── */
[data-id="cgsec13_o"] .elementor-column,
[data-id="cgsec13_o"] .e-con {
	box-sizing: border-box !important;
}

/* Reduced-motion rollup for all new animations */
@media (prefers-reduced-motion: reduce) {
	.cgind-arrow { transition: none !important; }
}

/* ══════════════════════════════════════════════════════════════════════
   §11 Quality + §12 Awards — design review fixes 2026-09-05
   ══════════════════════════════════════════════════════════════════════ */

/* ── Quality checklist — clean, lightweight list with thin coral marker ── */
.cgq-list {
	list-style: none;
	margin: 24px 0 32px;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: 18px;
}
.cgq-list li {
	display: flex;
	align-items: flex-start;
	gap: 12px;
	font-size: 14px;
	line-height: 1.5em;
	letter-spacing: 0.05em;
	color: #8A93A3;
}
/* Thin coral check using ::before — Lucide "check" icon, replaces heavy filled circle */
.cgq-list li::before {
	content: "";
	display: inline-block;
	flex-shrink: 0;
	width: 18px;
	height: 18px;
	margin-top: 2px;
	border: 1.5px solid #1b3fa0;
	border-radius: 50%;
	background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%231B3FA0' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E") center/10px no-repeat;
}

/* ── Quality Criteria section redesign ──────────────────────────────────
   Was image-left / text-right — the exact same shape as the Quality CTA
   card sitting directly above it (photo + panel), so the two sections
   read as accidental duplicates back to back. The image column here was
   also only ever a "pending upload" placeholder (see f6c5f1d), so there
   was no real photo lost by dropping it: the checklist (8bed7f5) and
   "Read our quality policy" link (d3ec534) were moved out of the text
   column (e0d35c2) and into 2cf6e29 — the column that used to hold the
   image — via a direct _elementor_data edit.

   Later requests removed the placeholder image entirely (qcimgnew, a
   widget added at one point to fill dead space next to a taller
   checklist card — also deleted from _elementor_data, not just hidden)
   and asked for the checklist to sit directly under the description
   instead of beside it — a single stacked column now: eyebrow, heading,
   description, then the checklist card full-width below. */
[data-id="2cf6e29"] {
	display: flex;
	order: 2;
}
[data-id="e0d35c2"] {
	order: 1;
	/* Same "unset container padding leaks Elementor's own default 10px"
	   bug hit repeatedly elsewhere this session (Process, Products,
	   Blog, Footer) — e0d35c2 has no "padding" key in its own Elementor
	   settings at all, so it silently inherits that default on EVERY
	   side, not just the left: content sat 10px right of where every
	   other section's header text starts (106px, confirmed against the
	   Capabilities section's own heading), AND the description carried
	   an invisible 10px of padding-bottom that was quietly inflating
	   the gap down to the checklist card past its intended 72px.
	   Zeroing the padding directly (the actual bug) rather than just
	   compensating the left edge with a negative margin (an earlier,
	   incomplete fix) resolves both at once. */
	padding: 0 !important;
}
/* Eyebrow→H2 and H2→description — this section wants a slightly more
   generous 26px here (client spec) than the 16px shared by every other
   header block on the page (see the big margin-top:16 rule lists
   further down); scoped with an extra ancestor selector so it wins on
   specificity without touching that shared rule (0,1,0) and affecting
   every other section that reuses it. */
[data-id="e0d35c2"] [data-id="7d4d066"],
[data-id="e0d35c2"] [data-id="ec47c38"] {
	margin-top: 26px !important;
}
/* "THE CHECKLIST" label was CSS-generated content (::before) — not a
   real Elementor element, so it had no Text property to select/edit in
   the editor at all. Replaced with a real heading widget
   (cgchecklisthdg, first child of this card) carrying the same style
   directly in its own settings; nothing left to do here. */
.cgq-list {
	margin: 0 !important;
	/* Keeps checklist text a comfortable reading width instead of
	   stretching every line across the full card — left-aligned (no
	   auto margin), not centered. */
	max-width: 900px;
}
[data-id="d3ec534"] {
	max-width: 900px;
	margin-top: 34px !important;
	padding-top: 26px;
	border-top: 1px solid #e8eaeb;
}

/* Quality "Read our quality policy" link — proper coral contrast, and a
   deliberate tertiary-CTA feel (arrow nudges right on hover) rather
   than looking like it's just floating text at the bottom of the
   card. ──────────────────────────────────────────────────────────── */
[data-id="d3ec534"] a,
[data-id="d3ec534"] p {
	display: inline-flex !important;
	align-items: center;
	color: #1b3fa0 !important;   /* 4.6:1 on white — AA pass */
	font-size: 14px !important;
	font-weight: 600 !important;
	letter-spacing: 0.04em !important;
	text-decoration: underline !important;
	text-underline-offset: 3px !important;
	text-decoration-color: rgba(184,50,48,0.4) !important;
}
[data-id="d3ec534"] a:hover,
[data-id="d3ec534"] p:hover {
	color: #16358a !important;
	text-decoration-color: #16358a !important;
}
[data-id="d3ec534"] .cg-arrow-fix {
	transition: transform 150ms ease;
}
[data-id="d3ec534"] a:hover .cg-arrow-fix,
[data-id="d3ec534"] p:hover .cg-arrow-fix {
	transform: translateX(4px);
}
@media (prefers-reduced-motion: reduce) {
	[data-id="d3ec534"] .cg-arrow-fix { transition: none; }
}

/* ── Stack, don't split into columns — the checklist card and the text
   column (e0d35c2) are both direct children of the same row container
   (05dea21, "flex_direction: row" in its own Elementor settings); one
   column rule below forces both of them to full width, one per line.
   The gap between them (desc → checklist card) is also set here —
   72px, the client's spec — rather than as a margin on the card, so
   there's a single source of truth for that one measurement. */

[data-id="2cf6e29"],
[data-id="e0d35c2"] {
	flex: 1 1 100% !important;
	width: 100% !important;
	max-width: 100% !important;
	min-width: 0 !important;
}

[data-id="dc10db8"] {
	background: #ffffff !important;
	border-radius: 16px !important;
	box-shadow: 0 2px 16px rgba(4,10,21,0.07) !important;
}

/* Dead rule removed (CSS-generated-content audit, 2026-09-09):
   [data-id="f6c5f1d"]::after used to overlay a "Quality photo — pending
   upload" badge on a placeholder image widget. That widget (f6c5f1d)
   no longer exists in this page's _elementor_data at all — the Quality
   Criteria section was restructured twice since (image column removed,
   checklist moved under the description), so this rule has matched
   nothing for a while. Confirmed via a live-page check before removal. */

/* ============================================================
   MOBILE RESPONSIVE OVERRIDES  (max-width: 767px)
   Fixes all layout, slider, heading, and spacing issues found
   in the 390px QA audit.
   ============================================================ */

/* ── Helper: hide scrollbar on sliders ───────────────────── */
.cgmob-slider::-webkit-scrollbar { display: none !important; }
.cgmob-slider { scrollbar-width: none !important; }

@media (max-width: 767px) {

  /* ── 2. Stats section: 2 × 2 grid ───────────────────────── */
  [data-id="cgsec2"] > .e-con-inner {
    display: grid !important;
    grid-template-columns: 1fr 1fr !important;
    gap: 0 !important;
  }
  [data-id="cgsec2"] > .e-con-inner > .e-con {
    border-right: 1px solid rgba(155, 176, 191, 0.12) !important;
    border-bottom: 1px solid rgba(155, 176, 191, 0.12) !important;
    padding: 32px 16px !important;
    justify-content: center !important;
    text-align: center !important;
  }
  [data-id="cgsec2"] > .e-con-inner > .e-con:nth-child(even) {
    border-right: none !important;
  }
  [data-id="cgsec2"] > .e-con-inner > .e-con:last-child,
  [data-id="cgsec2"] > .e-con-inner > .e-con:nth-last-child(2) {
    border-bottom: none !important;
  }

  /* ── 3. Loop Grid → horizontal swipe slider ──────────────── */
  /* Shared slider styles for Products, Capabilities, Industries.
     (Note: the Next.js reference renders Products as a plain stacked
     grid with no carousel — but the client wants a working swipe
     slider here on mobile regardless, matching the other two "What
     We Make"-style sections. No "swipe to explore" hint label on
     Products per an earlier explicit request to remove it — Capabilities
     and Industries keep theirs.) */
  [data-id="995582e"] .elementor-loop-container,
  [data-id="ed8de9e"] .elementor-loop-container,
  [data-id="76f3c44"] .elementor-loop-container {
    display: flex !important;
    flex-direction: row !important;
    flex-wrap: nowrap !important;
    overflow-x: auto !important;
    -webkit-overflow-scrolling: touch !important;
    scroll-snap-type: x mandatory !important;
    scroll-behavior: smooth !important;
    gap: 12px !important;
    /* Bleed to viewport edge, show peek of next card */
    padding: 4px 20px 20px !important;
    margin-left: -20px !important;
    margin-right: -20px !important;
    scrollbar-width: none !important;
    /* Products and Capabilities keep flex-start: `stretch` there matches
       every card to the TALLEST of all 9 (not just the 1-2 in view),
       leaving dead space under the shorter ones — the excess white space
       reported below the description on card 01/02. Each sizes to its own
       content. Industries is overridden to stretch just below; see the note
       there for why the trade-off goes the other way for that one. */
    align-items: flex-start !important;
    /* Override any grid layout */
    grid-template-columns: unset !important;
  }
  [data-id="995582e"] .elementor-loop-container::-webkit-scrollbar,
  [data-id="ed8de9e"] .elementor-loop-container::-webkit-scrollbar,
  [data-id="76f3c44"] .elementor-loop-container::-webkit-scrollbar {
    display: none !important;
  }

  /* Products: full-width card, one per view, navigated by the arrow
     buttons (added below) as well as swipe. */
  [data-id="995582e"] .e-loop-item {
    flex: 0 0 100% !important;
    width: 100% !important;
    max-width: 100% !important;
    scroll-snap-align: start !important;
    height: auto !important;
    min-height: unset !important;
  }

  /* Capabilities: full-width card, one per view — its own dot-paginated
     carousel, distinct from the Industries peek-slider below. */
  [data-id="ed8de9e"] .e-loop-item {
    flex: 0 0 100% !important;
    width: 100% !important;
    max-width: 100% !important;
    scroll-snap-align: start !important;
    height: auto !important;
    min-height: unset !important;
  }

  /* Industries: full-width card, one per view — its own progress-bar
     carousel, see "INDUSTRIES — mobile carousel" below. */
  [data-id="76f3c44"] .e-loop-item {
    flex: 0 0 100% !important;
    width: 100% !important;
    max-width: 100% !important;
    scroll-snap-align: start !important;
    height: auto !important;
  }

  /* Industries — equal card height on mobile too (2026-09-12).
     This reverses the flex-start default above FOR INDUSTRIES ONLY.
     The earlier dead-space objection applied to a ragged multi-card
     strip; this carousel shows exactly ONE card per view (flex 0 0 100%
     above), so a uniform height is what keeps the card frame and the
     .cgind-slider-track progress bar beneath it from jumping on every
     swipe — and no shorter card is ever seen next to a taller one.
     Still no fixed pixel height: the tallest card sets it, so it
     adapts to content and font-size changes on its own. */
  [data-id="76f3c44"] .elementor-loop-container {
    align-items: stretch !important;
  }
  [data-id="76f3c44"] .e-loop-item > a[data-id="8e2e8fd"] {
    height: 100% !important;
    /* nowrap is load-order insurance, not cosmetic (2026-09-13).
       The card is a COLUMN flex container and Elementor's default
       --flex-wrap is `wrap`. Combined with the fixed height the rule
       above imposes, that is a live bug: the loop container measures
       its equal height while the lazy-loaded card images are still 0px
       tall, locking in a height (~238px) too short for the real
       content. When an image then loads and the column overflows,
       `wrap` does what it is told and flows the description widget
       into a SECOND COLUMN — rendering it ~263px to the RIGHT of the
       card, outside the border, as unreadable clipped text at the
       screen edge. Only the first few cards (the ones scrolled into
       view early enough to load) exhibit it, which is why it reads as
       intermittent. nowrap forces the overflow to stay vertical, where
       min-height below can absorb it. */
    flex-wrap: nowrap !important;
    /* Let the card grow past the locked equal height instead of
       clipping the description: height:100% sets the floor, content
       sets the real ceiling. */
    height: auto !important;
    min-height: 100% !important;
  }

  /* ── 4. Industries section header fixes ──────────────────── */
  /* Main heading: 40px breaks on 390px — reduce to 28px */
  [data-id="7af7ece"] .elementor-heading-title {
    word-break: normal !important;
    overflow-wrap: break-word !important;
  }

  /* Header row (description + "All Industries" link):
     Force column stack so the link sits below the description.
     padding-bottom:48px (desktop-appropriate spacing before the card
     grid, from this widget's own settings) isn't scoped to mobile —
     stacked on top of the already-present 20px gap before the grid
     widget below, that read as a large dead gap on a narrow screen.
     Reduced to 16px, matching the tighter mobile spacing used
     elsewhere (Products/Blog). */
  [data-id="35991a9"].e-con {
    flex-direction: column !important;
    align-items: flex-start !important;
    gap: 12px !important;
    padding-bottom: 16px !important;
  }
  [data-id="35991a9"] > [data-id="9232770"] {
    width: 100% !important;
    max-width: 100% !important;
    flex: 1 1 auto !important;
  }
  [data-id="35991a9"] > [data-id="67dcc93"] {
    width: auto !important;
    flex: 0 0 auto !important;
    align-self: flex-start !important;
  }

  /* Capabilities: same "unscoped desktop spacing" issue as 35991a9 above,
     just a different property — the card grid (ed8de9e) carries its own
     margin-top:48px (desktop-appropriate gap below the header text), not
     scoped to mobile. Stacked on top of the section's own gap, that read
     as a large empty gap above the cards on a narrow screen. Reduced to
     16px, matching the 35991a9 treatment. */
  [data-id="ed8de9e"] {
    margin-top: 16px !important;
  }

  /* Why Choose Us: same unscoped-desktop-spacing bug again — header
     wrapper (bf9519f) carries its own padding-bottom:48px (desktop
     gap before the reasons grid below), not scoped to mobile. Reduced
     to 16px, matching the 35991a9 / ed8de9e treatment above. */
  [data-id="bf9519f"] {
    padding-bottom: 16px !important;
  }

  /* FAQ: same bug again, this time via flex `gap` rather than padding
     or margin — c7a8a91 (wraps the 32%-wide intro column + the
     accordion column) carries a 72px row-gap sized for when those two
     columns sit side-by-side on desktop. At mobile width both columns
     force to 100% and stack, but the 72px gap between them didn't
     shrink with them, reading as a large dead gap before the
     accordion. Reduced to 20px, matching normal mobile section
     rhythm. */
  [data-id="c7a8a91"] {
    gap: 20px !important;
  }

  /* ── 8. Mega menu: already mobile-responsive via hamburger ── */
  /* Ensure utility bar wraps cleanly */
  [data-id="cghdr003"].e-con {
    flex-wrap: wrap !important;
    gap: 4px 16px !important;
  }

  /* ── 9/10. Certifications section: mobile layout now lives in the
     .cgcert-wrap media query (§ certifications redesign) below, next to
     the rest of that block's rules — nothing to override here. */

  /* ── 11. Contact section: single column ──────────────────── */
  [data-id="cgsec13_o"] > .e-con-inner {
    flex-direction: column !important;
    gap: 40px !important;
  }

  /* ── 12. Blog cards: already single column — add spacing ─── */
  [data-id="4a44b01"] .elementor-loop-container {
    gap: 16px !important;
  }

  /* ── 13. FAQ items: tighten padding ──────────────────────── */
  [data-id="cgsec12_o"] .elementor-toggle-item {
    padding: 14px 0 !important;
  }

  /* ── 14. Swipe hint: show "swipe" label above slider ──────── */
  /* Products (cgsec3) excluded — it isn't a slider, see note above.
     Capabilities (cgsec5_o) excluded — its own dot pagination replaces
     the text hint. Industries (cgsec6_o) excluded — its own progress
     bar replaces it too, see "INDUSTRIES — mobile carousel" below. */

} /* end @media (max-width: 767px) */

/* ── Tablet (768px–1024px) spot fixes ────────────────────── */
@media (min-width: 768px) and (max-width: 1024px) {

  /* Stats: keep 2-col on tablet too */
  [data-id="cgsec2"] > .e-con-inner {
    display: grid !important;
    grid-template-columns: repeat(2, 1fr) !important;
    gap: 0 !important;
  }

  /* Products / Capabilities / Industries loop: 2-col grid on tablet */
  [data-id="995582e"] .elementor-loop-container,
  [data-id="ed8de9e"] .elementor-loop-container {
    grid-template-columns: repeat(2, 1fr) !important;
  }
  [data-id="76f3c44"] .elementor-loop-container {
    grid-template-columns: repeat(2, 1fr) !important;
    gap: 12px !important;
  }
}

/* ============================================================
   MOBILE FIXES ROUND 2
   ============================================================ */

@media (max-width: 767px) {

  /* ── Stats: flex-wrap 2×2 (grid didn't fire against Elementor flex) */
  [data-id="cgsec2"] > .e-con-inner {
    flex-direction: row !important;
    flex-wrap: wrap !important;
    align-items: stretch !important;
  }
  [data-id="cgsec2"] > .e-con-inner > .e-con {
    flex: 0 0 50% !important;
    max-width: 50% !important;
    width: 50% !important;
    box-sizing: border-box !important;
    padding: 28px 12px !important;
    border-right: 1px solid #E8EAEB !important;
    border-bottom: 1px solid #E8EAEB !important;
    text-align: center !important;
    justify-content: flex-start !important;
    align-items: center !important;
  }
  [data-id="cgsec2"] > .e-con-inner > .e-con:nth-child(2n) {
    border-right: none !important;
  }
  [data-id="cgsec2"] > .e-con-inner > .e-con:nth-last-child(-n+2) {
    border-bottom: none !important;
  }

  /* ── Sliders: remove negative margin bleed, fix left clip */
  [data-id="995582e"] .elementor-loop-container,
  [data-id="ed8de9e"] .elementor-loop-container,
  [data-id="76f3c44"] .elementor-loop-container {
    margin-left: 0 !important;
    margin-right: 0 !important;
    padding: 4px 0 16px !important;
    scroll-padding-left: 0 !important;
  }

  /* Products, Capabilities, Industries: full-width, one card per view
     (see round-1 rule above) */
  [data-id="995582e"] .e-loop-item,
  [data-id="ed8de9e"] .e-loop-item,
  [data-id="76f3c44"] .e-loop-item {
    flex: 0 0 100% !important;
    width: 100% !important;
    max-width: 100% !important;
  }
}

/* ══════════════════════════════════════════════════════════════════
   CAPABILITIES — mobile carousel (unique design)
   A deliberately distinct identity from the other two mobile sliders:
   Products is flat text-beside-image cards with an arrow+counter pager;
   Industries is full-width cards with a passive progress-bar track.
   Capabilities leans into its real photography (all 5 entries have
   genuine Card Images — see the note on widget 6b80a53 above): a
   taller full-bleed hero photo per card, a numbered badge overlaid on
   the photo itself (echoing the Products ordinal, but as a badge on the
   image rather than mono text beside it), and dot pagination instead
   of arrows. Mobile-only — desktop keeps its plain 3-col grid.        */
@media (max-width: 767px) {
  /* Stays square (aspect-ratio:1/1, set as the base rule above) rather
     than the old fixed 200px landscape height — this card is the only
     one visible at a time on mobile, so a full-width square reads as a
     bigger, cleaner hero than a short letterboxed crop did. */
  [data-id="ed8de9e"] .elementor-element-6b80a53 img {
    height: auto !important;
    aspect-ratio: 1 / 1 !important;
  }

  /* Numbered badge overlaid on the photo's top-left corner. Own counter
     (cgcap-n) so it can't collide with the Products ordinal counter. */
  [data-id="ed8de9e"] .elementor-loop-container {
    counter-reset: cgcap-n;
  }
  [data-id="ed8de9e"] .e-loop-item {
    counter-increment: cgcap-n;
  }
  [data-id="ed8de9e"] .elementor-element-6b80a53 {
    position: relative !important;
  }
  [data-id="ed8de9e"] .elementor-element-6b80a53::before {
    content: counter(cgcap-n, decimal-leading-zero);
    position: absolute;
    top: 12px;
    left: 12px;
    width: 34px;
    height: 34px;
    border-radius: 9999px;
    background: rgba(184, 50, 48, 0.92);
    color: #fff;
    font-family: 'Geist Mono', 'Courier New', monospace;
    font-size: 13px;
    font-weight: 700;
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow: 0 2px 6px rgba(12, 24, 37, 0.25);
    z-index: 2;
  }
}

/* Dot pagination (injected by functions.php's
   cg_capabilities_slider_dots_script) — mobile-only, same display:none
   pattern as the Products pager above. */
.cgcap-slider-dots {
  display: none;
}
@media (max-width: 767px) {
  .cgcap-slider-dots {
    display: flex !important;
    justify-content: center;
    align-items: center;
    gap: 8px;
    margin: 16px 0;
  }
  .cgcap-slider-dot {
    width: 8px;
    height: 8px;
    border-radius: 9999px;
    background: #d8dde1;
    border: none;
    padding: 0;
    cursor: pointer;
    transition: background-color 200ms ease, width 200ms ease;
  }
  .cgcap-slider-dot.is-active {
    width: 22px;
    background: #1b3fa0;
  }
}

/* ══════════════════════════════════════════════════════════════════
   INDUSTRIES — mobile carousel (unique design)
   The third and last "What We Make"-style mobile slider, deliberately
   distinct from the other two: Products uses an arrow+counter pager,
   Capabilities uses dot pagination. Industries' cards are the darkest
   and most technical-looking of the three (navy card, Lucide category
   icon, ↗ link arrow) — a passive progress TRACK fits that register
   better than another set of buttons: swipe-only navigation, with a
   slim accent-filled bar plus a small counter as the only chrome,
   instead of tappable controls. Mobile-only — desktop keeps its plain
   3-col grid untouched. */
.cgind-slider-track {
  display: none;
}
@media (max-width: 767px) {
  .cgind-slider-track {
    display: block !important;
    margin: 16px 0 8px;
  }
  .cgind-slider-bar {
    position: relative;
    height: 3px;
    border-radius: 9999px;
    background: rgba(155, 176, 191, 0.18);
    overflow: hidden;
  }
  .cgind-slider-fill {
    position: absolute;
    top: 0;
    left: 0;
    height: 100%;
    border-radius: 9999px;
    background: #1b3fa0;
    transition: width 250ms ease;
  }
  .cgind-slider-count {
    display: block;
    margin-top: 8px;
    font-family: 'Geist Mono', 'Courier New', monospace;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.06em;
    color: #6ba8c4;
  }
}

/* ── Products slider — prev/next arrow nav (injected by functions.php's
   cg_products_slider_arrows_script) ─────────────────────────────────
   Hidden by default; shown only on mobile, where Products is a
   full-width, one-card slider. Above 767px the .cgprod-slider-nav
   element still exists in the DOM (JS always injects it) but Products
   is a plain 2-col grid there, so the buttons stay display:none.

   The loop container's height is set inline by the same script, to the
   currently-visible card only (all 9 cards share one non-wrapping flex
   row, so its natural height locks to the tallest of the nine — this is
   also why `overflow: hidden` + a height transition sit here, so a
   shorter card doesn't show a sliver of the next taller one during the
   resize, and the height change itself animates instead of jumping). */
@media (max-width: 767px) {
  [data-id="995582e"] .elementor-loop-container,
  [data-id="ed8de9e"] .elementor-loop-container,
  [data-id="76f3c44"] .elementor-loop-container {
    /* Same reasoning applies to Capabilities (ed8de9e) and Industries
       (76f3c44): align-items is flex-start, not stretch, so each card in
       the row sits at its own natural height — meaning taller siblings
       NOT currently in view still contribute to the container's total
       scrollHeight even though only one card's height drives the
       explicitly-set container height. Left as the browser default
       (auto), that mismatch surfaced as a spurious vertical scrollbar
       any time a taller off-screen card existed in the same row.
       overflow-y:hidden simply clips that invisible overhang instead. */
    overflow-y: hidden !important;
    transition: height 220ms ease !important;
  }
}
.cgprod-slider-nav {
  display: none;
}
@media (max-width: 767px) {
  /* Normal document flow — its own row above the card grid, not an
     overlay. width:100% + justify-content:flex-end right-aligns the
     pill within that row without needing position:absolute. */
  /* Grid, not flex: with 3 items, flex's justify-content:space-between only
     anchors the outer two to the edges — the middle item (the counter)
     lands wherever the leftover space puts it, not necessarily centered.
     1fr auto 1fr guarantees prev at the true left edge, next at the true
     right edge, and the counter exactly centered between them regardless
     of button size. */
  .cgprod-slider-nav {
    display: grid !important;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    width: 100%;
    gap: 12px;
    padding: 8px 12px;
    border-radius: 9999px;
    box-sizing: border-box;
  }
  .cgprod-slider-prev {
    justify-self: start;
  }
  .cgprod-slider-next {
    justify-self: end;
  }
  .cgprod-slider-count {
    justify-self: center;
  }
  .cgprod-slider-count {
    min-width: 0;
    text-align: center;
    font-family: 'Geist Mono', 'Courier New', monospace;
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.04em;
    color: #6b6f72;
  }
  /* 44x44 — Apple HIG / Material minimum touch target. The earlier 28px
     buttons were noticeably below both guidelines. */
  .cgprod-slider-arrow {
    width: 44px;
    height: 44px;
    flex-shrink: 0;
    border-radius: 9999px;
    /* A visible border at rest, not just a shadow: white-on-white with
       only `box-shadow: 0 1px 2px rgba(...,0.12)` was too subtle to read
       as a button against the section's white background — it only
       became visible once hovered (solid red fill). The border gives it
       a defined edge at rest, regardless of hover state. */
    border: 1.5px solid #d8dde1;
    background: #fff;
    color: #0b0f17;
    font-size: 20px;
    line-height: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    cursor: pointer;
    box-shadow: 0 1px 2px rgba(12, 24, 37, 0.08);
    transition: background-color 150ms ease, color 150ms ease,
      border-color 150ms ease, box-shadow 150ms ease, transform 150ms ease;
  }
  .cgprod-slider-arrow:hover,
  .cgprod-slider-arrow:focus-visible {
    background: #1b3fa0;
    border-color: #1b3fa0;
    color: #fff;
    box-shadow: 0 2px 6px rgba(184, 50, 48, 0.35);
  }
  .cgprod-slider-arrow:active {
    transform: scale(0.94);
  }
  /* Disabled: opacity alone made a white button vanish against the white
     section background (the earlier bug this replaces). Keep the button
     shape fully visible — solid fill, no shadow — and mute only the
     icon color, so "disabled" reads as a state, not as "not rendered". */
  .cgprod-slider-arrow:disabled {
    background: #d1d5db;
    border-color: #d1d5db;
    color: #6b7280;
    box-shadow: none;
    cursor: not-allowed;
  }
  .cgprod-slider-arrow:disabled:hover {
    background: #d1d5db;
    border-color: #d1d5db;
    color: #6b7280;
  }
}

/* ── Products (995582e/cgsec3) card — mobile sizing ─────────
   The card keeps its side-by-side [text, image] row inside the slider
   (matches next-js/src/app/page.tsx's `grid-cols-[1fr_auto]` — the
   image never moves below the text). Only the thumbnail shrinks below
   the `sm:` breakpoint: `h-28 w-28` (112px) vs `sm:h-32 sm:w-32`
   (128px) in the reference. */
@media (max-width: 767px) {
  [data-id="995582e"] .e-loop-item .elementor-widget-image,
  [data-id="995582e"] .e-loop-item .elementor-widget-image img {
    width: 112px !important;
    max-width: 112px !important;
    height: 112px !important;
  }
}

/* ── Stats 2×2 grid — correct selectors (round 3) ────────── */
@media (max-width: 767px) {
  /* The actual flex row container holding the 4 stat blocks */
  [data-id="cgs2grid"].e-con {
    flex-direction: row !important;
    flex-wrap: wrap !important;
    align-items: stretch !important;
    gap: 0 !important;
  }
  /* Each stat block → 50% width */
  [data-id="cgs2t1"].e-con,
  [data-id="cgs2t2"].e-con,
  [data-id="cgs2t3"].e-con,
  [data-id="cgs2t4"].e-con {
    flex: 0 0 50% !important;
    max-width: 50% !important;
    width: 50% !important;
    min-width: 0 !important;
    box-sizing: border-box !important;
    padding: 28px 8px !important;
    border-right: 1px solid #E8EAEB !important;
    border-bottom: 1px solid #E8EAEB !important;
  }
  /* Right column: no right border */
  [data-id="cgs2t2"].e-con,
  [data-id="cgs2t4"].e-con {
    border-right: none !important;
  }
  /* Bottom row: no bottom border */
  [data-id="cgs2t3"].e-con,
  [data-id="cgs2t4"].e-con {
    border-bottom: none !important;
  }
}

/* ── Stats 2×2 — fix flex-direction on inner wrapper (round 4) */
@media (max-width: 767px) {
  /* The ACTUAL flex container is .e-con-inner inside cgs2grid */
  [data-id="cgs2grid"] > .e-con-inner {
    flex-direction: row !important;
    flex-wrap: wrap !important;
    gap: 0 !important;
    align-items: stretch !important;
  }
  /* Keep stat items at 50% width */
  [data-id="cgs2grid"] > .e-con-inner > [data-id="cgs2t1"],
  [data-id="cgs2grid"] > .e-con-inner > [data-id="cgs2t2"],
  [data-id="cgs2grid"] > .e-con-inner > [data-id="cgs2t3"],
  [data-id="cgs2grid"] > .e-con-inner > [data-id="cgs2t4"] {
    flex: 0 0 50% !important;
    max-width: 50% !important;
    width: 50% !important;
    min-width: 0 !important;
    box-sizing: border-box !important;
  }
}

/* ── Stats 2×2 — FINAL: cgs2grid is e-grid (CSS grid, not flex) */
@media (max-width: 767px) {
  /* Override Elementor's 1-col mobile grid with 2×2 */
  [data-id="cgs2grid"].e-grid {
    grid-template-columns: repeat(2, 1fr) !important;
    grid-template-rows: auto !important;  /* reset 4 fixed rows from desktop layout */
    gap: 0 !important;
  }
  /* Reset old rounds' flex/width overrides (match .e-con specificity); grid places items */
  [data-id="cgs2t1"].e-con,
  [data-id="cgs2t2"].e-con,
  [data-id="cgs2t3"].e-con,
  [data-id="cgs2t4"].e-con {
    flex: none !important;
    width: auto !important;
    max-width: 100% !important;
    min-width: 0 !important;
    box-sizing: border-box !important;
    padding: 20px 8px !important;
    justify-content: center !important;
  }
  [data-id="cgs2t1"],
  [data-id="cgs2t3"] {
    border-right: 1px solid #E8EAEB !important;
  }
  [data-id="cgs2t1"],
  [data-id="cgs2t2"] {
    border-bottom: 1px solid #E8EAEB !important;
  }
}

/* ══════════════════════════════════════════════════════════════════
   HERO BANNER ANIMATION
   Ken Burns slow zoom (::before layer) + rotating gear outlines (JS)
   + enhanced directional scrim (::after)
   Reference: HeroSlider.tsx — Ken Burns zoom, framer-motion crossfade
   ══════════════════════════════════════════════════════════════════ */

/* 1. Clip the zoom to the hero bounds */
[data-id="cghero01"] {
  overflow: hidden !important;
  position: relative !important;
  isolation: isolate !important;
}

/* 2. Remove Elementor's static background — replaced by animated ::before */
[data-id="cghero01"] {
  background-image: none !important;
  background-color: #070a10 !important;   /* fallback while image loads */
}

/* 3. Animated background layer — 10% bleed on all sides to hide edges during zoom.
   Stack the directional scrim gradient ON TOP of the hero image in one declaration.
   !important required to beat Elementor's .elementor-element-cghero01::before
   rule (2-class specificity vs our 1-attribute selector). */
[data-id="cghero01"]::before {
  content: ''   !important;
  position: absolute !important;
  inset: -10%   !important;
  width: 120%   !important;
  height: 120%  !important;
  /* Scrim gradient layered over the hero image in a single background-image stack */
  background-image:
    linear-gradient(
      105deg,
      rgba(4, 10, 21, 0.86) 0%,
      rgba(4, 10, 21, 0.68) 42%,
      rgba(4, 10, 21, 0.35) 72%,
      rgba(4, 10, 21, 0.18) 100%
    ),
    url("/wp-content/uploads/2026/09/hero-banner.png") !important;
  background-size: cover     !important;
  background-position: 55% center !important;
  background-repeat: no-repeat !important;
  animation: cgHeroKenBurns 26s ease-in-out infinite alternate !important;
  z-index: 0   !important;
  will-change: transform;
  transform-origin: center center;
}

/* 4. ::after not used — scrim is baked into ::before background stack (gradient+image) */
[data-id="cghero01"]::after {
  display: none !important;
}

/* 5. Hero content above gear decorations and ::before layer */
[data-id="cghero01"] > .e-con-inner {
  position: relative !important;
  z-index: 2 !important;
}

/* 6. Ken Burns keyframes — scale + subtle drift for depth */
@keyframes cgHeroKenBurns {
  0%   { transform: scale(1.00) translate(0.0%,  0.0%); }
  20%  { transform: scale(1.04) translate(-1.2%,  0.6%); }
  40%  { transform: scale(1.06) translate( 0.8%, -1.0%); }
  60%  { transform: scale(1.05) translate( 1.4%,  0.4%); }
  80%  { transform: scale(1.07) translate(-0.6%, -0.8%); }
  100% { transform: scale(1.09) translate( 0.4%,  1.2%); }
}

/* 7. Gear decoration elements — injected by hero-anim.js
   z-index: 1 sits above the ::before (0) but below content (2) */
.cg-hero-gear {
  position: absolute !important;
  pointer-events: none !important;
  z-index: 1;
  will-change: transform;
  transform-origin: center center !important;
}

@keyframes cgGearCW  { to { transform: rotate( 360deg); } }
@keyframes cgGearCCW { to { transform: rotate(-360deg); } }

/* 8. Honour reduced-motion preference */
@media (prefers-reduced-motion: reduce) {
  [data-id="cghero01"]::before {
    animation: none !important;
    transform: scale(1.04); /* static slight zoom */
  }
  .cg-hero-gear { display: none !important; }
}

/* ============================================================
   BUTTON & LINK COLOR CONSISTENCY — Stage 05 QA round
   Design system:
     Primary   — #1b3fa0 bg · white text · 10px radius
     Ghost-dark — transparent · rgba(255,255,255,0.40) border · white text
     Ghost-light — transparent · rgba(12,24,37,0.28) border · #0b0f17 text
     Inverted  — white bg · #1b3fa0 text (used on red-bg CTAs)
   ============================================================ */


/* Hero ghost "Explore Products" (cghero08) — MIGRATED to Elementor's own
   Button widget controls (border color/width/radius, hover background/
   border/text color) as part of the site-wide CSS→Elementor properties
   pass. This CSS override is gone; the values now live in the widget's
   own settings (editable from Elementor: select the button → Style tab
   → Border / Hover). Kept only as a note so a future search for
   "cghero08" still finds why it looks the way it does. */

/* ── 3. CTA2 sketch section "→ Call 800.491.1073" (782eee7)
   Was: identical red fill as primary — looks like duplicate CTA
   Fix: ghost-dark (transparent + white border) so primary/secondary read clearly ── */
[data-id="782eee7"] .elementor-button {
  background-color: transparent !important;
  background-image: none !important;
  border: 1.5px solid rgba(255, 255, 255, 0.38) !important;
  color: #ffffff !important;
}
[data-id="782eee7"] .elementor-button:hover {
  background-color: rgba(255, 255, 255, 0.09) !important;
  border-color: rgba(255, 255, 255, 0.68) !important;
  color: #ffffff !important;
}

/* ── 4. CTA3 "See capabilities" — REMOVED. That widget (a3a3698) no
   longer exists; the Quality CTA (cgcta3_o) was rebuilt as a single
   custom HTML card (.cgqualcta-*, see further down) with the same
   red-fill/white-text button, image+content layout matching the
   client-provided reference. ── */

/* ── 5. Blog section "All articles →" (26811e7) — plain underlined
   link now, not a bordered/filled button, matching "All Products"
   (03de915) and "All Industries" (67dcc93) elsewhere on the page.
   Was: red-filled outline button; see the layout fix further down
   (846c1fb/dc5a0b2) for why it used to wrap onto its own row instead
   of sitting beside the heading. */
[data-id="26811e7"] .elementor-button {
  border: none !important;
  background: transparent !important;
  background-color: transparent !important;
  color: #0b0f17 !important;
  text-decoration: underline !important;
  text-underline-offset: 3px !important;
  padding: 0 !important;
  min-height: 0 !important;
  box-shadow: none !important;
}
[data-id="26811e7"] .elementor-button:hover {
  color: #1b3fa0 !important;
  background: transparent !important;
  background-color: transparent !important;
}

/* ── 6. Final CTA "☎ 800.491.1073" (0031c3b) — on light-bg section
   Was: red fill + dark navy text rgb(12,24,37) — wrong combination
   Fix: ghost-light (transparent + dark border + dark text) ── */
[data-id="0031c3b"] .elementor-button {
  background-color: transparent !important;
  background-image: none !important;
  border: 1.5px solid rgba(12, 24, 37, 0.28) !important;
  color: #0b0f17 !important;
}
[data-id="0031c3b"] .elementor-button:hover {
  background-color: rgba(12, 24, 37, 0.06) !important;
  border-color: rgba(12, 24, 37, 0.55) !important;
  color: #0b0f17 !important;
}

/* ── 7. "All Industries →" (67dcc93) — REMOVED.
   This used to add a border + padding + border-radius, turning it back
   into a bordered "ghost-dark" button that fought with the underlined-
   link rule above it — same border + underline showing at once. The
   link treatment (red underline, see above) is the one true style now. */

/* ── 8. "All Products" (03de915) — plain underlined link, not a
   bordered button (matches the "All Industries"/"All Capabilities"
   link treatment elsewhere on the page, which never had a border). */
[data-id="03de915"] .elementor-button {
  border: none !important;
  background: transparent !important;
  color: #0b0f17 !important;
  text-decoration: underline !important;
  text-underline-offset: 3px !important;
  padding: 0 !important;
  min-height: 0 !important;
}
[data-id="03de915"] .elementor-button:hover {
  color: #1b3fa0 !important;
}

/* ── 9. Contact section (cgsec13_o) — form/icons/typography redesign
   2026-09-08: previously plain default Elementor form-field styling
   (thin uniform border, no focus state, inconsistent field heights)
   and inline-styled contact icons with no hover feedback at all. ── */

/* Contact icons (617a9b9) — rebuilt with real classes instead of the
   original inline styles, so hover states are actually possible. */
.cgcontact-info {
	margin-top: 32px;
	display: flex;
	flex-direction: column;
	gap: 20px;
}
.cgcontact-row {
	display: flex;
	align-items: center;
	gap: 14px;
	margin: -8px;
	padding: 8px;
	border-radius: 12px;
	transition: background-color 150ms ease;
}
.cgcontact-row--top {
	align-items: flex-start;
}
.cgcontact-row:hover {
	background: rgba(12, 24, 37, .04);
}
.cgcontact-icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 42px;
	height: 42px;
	min-width: 42px;
	border-radius: 50%;
	background: #1B3FA0;
	color: #FFFFFF;
	box-shadow: 0 2px 6px rgba(12, 24, 37, .18);
	transition: background-color 150ms ease, color 150ms ease, transform 150ms ease;
}
.cgcontact-row:hover .cgcontact-icon {
	background: #15327F;
	color: #FFFFFF;
	transform: scale(1.06);
}
.cgcontact-primary {
	display: block;
	font-weight: 600;
	font-size: 16px;
	color: #0b0f17;
	text-decoration: none;
	transition: color 150ms ease;
}
a.cgcontact-primary:hover,
.cgcontact-secondary--link:hover {
	color: #1b3fa0;
}
.cgcontact-secondary {
	display: block;
	margin-top: 2px;
	font-size: 14px;
	color: #657e91;
}
.cgcontact-secondary--link {
	text-decoration: none;
	transition: color 150ms ease;
}
@media (prefers-reduced-motion: reduce) {
	.cgcontact-row,
	.cgcontact-icon,
	.cgcontact-primary,
	.cgcontact-secondary--link {
		transition: none;
	}
	.cgcontact-row:hover .cgcontact-icon {
		transform: none;
	}
}

/* Form (ca68205) — labels, fields, focus state, button */
[data-id="ca68205"] .elementor-field-label {
	font-size: 13px !important;
	font-weight: 600 !important;
	color: #0b0f17 !important;
	margin-bottom: 6px !important;
	letter-spacing: .01em;
}
[data-id="ca68205"] .elementor-field-group {
	margin-bottom: 20px !important;
}
[data-id="ca68205"] .elementor-field-textual {
	border: 1.5px solid #e2e6ea !important;
	border-radius: 10px !important;
	padding: 12px 14px !important;
	min-height: 48px;
	font-size: 15px !important;
	color: #0b0f17 !important;
	background: #fff !important;
	box-shadow: none !important;
	transition: border-color 150ms ease, box-shadow 150ms ease;
}
[data-id="ca68205"] textarea.elementor-field-textual {
	min-height: 128px;
	resize: vertical;
}
[data-id="ca68205"] .elementor-field-textual::placeholder {
	color: #9bb0bf;
	opacity: 1;
}
[data-id="ca68205"] .elementor-field-textual:hover {
	border-color: #cbd3da !important;
}
[data-id="ca68205"] .elementor-field-textual:focus {
	outline: none;
	border-color: #1b3fa0 !important;
	box-shadow: 0 0 0 3px rgba(184, 50, 48, .12) !important;
}
@media (prefers-reduced-motion: reduce) {
	[data-id="ca68205"] .elementor-field-textual {
		transition: none;
	}
}


/* ── 10. Primary red button hover — subtle darken ──
   cghero07 MIGRATED to its own explicit button_hover_background_color /
   button_hover_text_color in Elementor's Button widget settings (Style
   tab → Hover), as part of the CSS→Elementor properties pass — removed
   from this shared rule. 58ed281 / 9e1148d still pending their own
   section's turn. */
[data-id="58ed281"] .elementor-button:hover,
[data-id="9e1148d"] .elementor-button:hover {
  background-color: #16358a !important;
  color: #ffffff !important;
}


[data-id="d19e24e"] .elementor-button:hover {
  background-color: #f5f5f5 !important;
  color: #16358a !important;
}

/* ── 12. CTA3 "Our quality policy" — REMOVED, same reason as #4 above. ── */

/* ============================================================
   SPACING & ALIGNMENT FIXES — Stage 05 QA round
   Based on Puppeteer computed-style audit across all sections.
   ============================================================ */

/* ── 1. PROCESS SECTION — remove double padding ──────────────
   cgsec7_o has section-level padding T:96 B:96 PLUS its
   .e-con-inner also has T:96 B:96 → 192px wasted per side.
   Remove only the inner wrapper duplication.               */
[data-id="cgsec7_o"] > .e-con-inner {
  padding-top: 0 !important;
  padding-bottom: 0 !important;
}

/* Stats number headings — small gap to label below */
[data-id="cgs2t1"] .elementor-heading-title,
[data-id="cgs2t2"] .elementor-heading-title,
[data-id="cgs2t3"] .elementor-heading-title,
[data-id="cgs2t4"] .elementor-heading-title {
  margin-bottom: 6px !important;
}
/* Hero heading — keep tight, CTA buttons sit below body text */
[data-id="cghero01"] .elementor-heading-title {
  margin-bottom: 12px !important;
}
/* CTA centred headings — more space to body copy below */
[data-id="cgcta4_o"] .elementor-heading-title {
  margin-bottom: 20px !important;
}

/* ── 5. WHY CHOOSE US — reduce gap between intro & cards ─────
   Large empty space between the body text paragraph and the
   6-card grid below. Tighten the bottom margin on text widget. */
[data-id="cgsec4_o"] .elementor-widget-text-editor {
  margin-bottom: 0 !important;
}
[data-id="cgsec4_o"] .elementor-widget-text-editor p:last-child {
  margin-bottom: 0 !important;
}

/* ── 6. CTA2 SKETCH — buttons side-by-side on desktop ────────
   Puppeteer identified the button wrapper as data-id="a97b9a5"
   (flex-column, gap:20px). Change to flex-row so both buttons
   sit on the same line. Wrap on mobile.                     */
[data-id="a97b9a5"] {
  flex-direction: row !important;
  align-items: center !important;
  flex-wrap: wrap !important;
  gap: 16px !important;
}
[data-id="a97b9a5"] > .elementor-element {
  flex: 0 0 auto !important;
  max-width: none !important;
}
@media (max-width: 767px) {
  /* Stacked, each full width — tried side-by-side first (flex:1 1 0
     sharing the row) but that forced small padding/font-size to fit
     both labels, and the request came back for full-width buttons
     instead. Full width also gives a much larger tap target than half
     a 310px-wide row split two ways. */
  [data-id="a97b9a5"] {
    flex-direction: column !important;
    align-items: stretch !important;
    gap: 12px !important;
  }
  [data-id="a97b9a5"] > .elementor-element {
    width: 100% !important;
  }
  [data-id="a97b9a5"] .elementor-button {
    width: 100% !important;
    justify-content: center !important;
  }
}

/* ── 7. BLOG SECTION — "See all" link beside the heading, not below.
   846c1fb (row, space-between, wrap) holds two children: dc5a0b2 (the
   eyebrow/H2/description block) and 26811e7 (the link). dc5a0b2's own
   Elementor "content_width: full" setting makes it claim the ENTIRE
   row width by default, leaving zero room for 26811e7 beside it, so
   flex-wrap sends the link onto its own line below — same root cause
   as the industries card icon+title wrapping bug fixed elsewhere on
   this page. Fix: stop the row from wrapping, let the text block
   shrink to fit, and keep the link at its own natural width.
   Desktop-only (≥768px): forcing nowrap at mobile widths, where there
   is nowhere near enough room for the H2 AND the link on one line,
   squeezed the H2 down to almost nothing — with wrapping forbidden,
   the browser had no option left but to break every single word (and
   then every letter) onto its own line to fit the sliver of width it
   was left, producing a column of single characters running the
   height of the screen. Mobile keeps its natural stack instead. */
@media (min-width: 768px) {
  [data-id="846c1fb"] {
    flex-wrap: nowrap !important;
  }
  [data-id="dc5a0b2"] {
    flex: 1 1 auto !important;
    min-width: 0 !important;
  }
  [data-id="26811e7"] {
    flex-shrink: 0 !important;
  }
}

/* ── 8. WIDGET-TO-WIDGET SPACING — consistent rhythm ─────────
   All text-editor widgets get bottom breathing room so the
   next widget (buttons, cards) has clean separation.        */
.elementor-widget-text-editor {
  margin-bottom: 8px !important;
}

/* ── 9. BUTTON WIDGETS — consistent top margin rhythm ────────
   Button widgets after headings or text blocks need 8px extra
   so the gap reads clearly without excessive space.         */
.elementor-widget-heading + .elementor-widget-button,
.elementor-widget-text-editor + .elementor-widget-button {
  margin-top: 8px !important;
}

/* ═══════════════════════════════════════════════════════════════
   MOBILE RESPONSIVE FIXES — 390px (≤767px)
   Verified with Puppeteer at 390×844px.
   Covers M1–M24 from the mobile QA report.
   ═══════════════════════════════════════════════════════════════ */

@media (max-width: 767px) {

  /* ── M5  HERO CTA BUTTONS — 40px → 48px height ─────────────────
     Computed at 219×40px and 215×42px — below 44px touch minimum.
     Increase padding to 16px each side. Also full-width for easy
     tapping on narrow screens.                                     */
  [data-id="cghero07"] .elementor-button,
  [data-id="cghero08"] .elementor-button {
    padding-top: 16px !important;
    padding-bottom: 16px !important;
    min-height: 48px !important;
    width: 100% !important;
    box-sizing: border-box !important;
    justify-content: center !important;
  }

  /* ── M8  "ALL PRODUCTS" BUTTON — full-width + 48px ─────────────
     Computed at 165×38px, left-aligned and narrow.
     margin-top also tightened here: at 56px (mt-14, matches desktop)
     it reads as excessive white space stacked on top of the loop
     item's own ~32px trailing gap, on a mobile view that only ever
     shows one card row at a time. */
  [data-id="03de915"] {
    width: 100% !important;
    margin-top: 24px !important;
  }
  [data-id="03de915"] .elementor-button-wrapper {
    width: 100% !important;
  }
  [data-id="03de915"] .elementor-button {
    min-height: 48px !important;
    padding-top: 14px !important;
    padding-bottom: 14px !important;
    width: 100% !important;
    justify-content: center !important;
    box-sizing: border-box !important;
  }

  /* ── M9 "ALL INDUSTRIES" — REMOVED. This dated from when it was a
     bordered full-width button; it's a plain underlined link now
     (matching "All Products"/"All Articles"), left-aligned beside the
     description via align-self:flex-start further up this file — a
     forced width:100%+centered box here fought that and re-centered
     it, which is the bug this removal fixes. See the two "M9 PATCH"
     blocks further down, also removed for the same reason. */

  /* ── M6  HAMBURGER BUTTON — 40×40 → min 44×44px ────────────────  */
  .cgmm-mob-btn {
    min-width: 44px !important;
    min-height: 44px !important;
    display: flex !important;
    align-items: center !important;
    justify-content: center !important;
  }

  /* ── M10  TEXT CTA LINKS — minimum 44px tap height ─────────────
     "Read our quality policy →"  186×21px
     "See all certifications →"   153×21px
     "Browse all FAQs"            132×21px                         */
  .cgfaq-all-link {
    display: inline-block !important;
    padding-top: 12px !important;
    padding-bottom: 12px !important;
  }
  [data-id="cgsec8_o"] a:not(.elementor-button),
  [data-id="cgsec9_o"] a:not(.elementor-button) {
    display: inline-block !important;
    padding-top: 11px !important;
    padding-bottom: 11px !important;
  }

  /* ── M24  REVIEWS — removed. The manual prev/next+dots carousel this
     targeted was replaced by an auto-scrolling marquee (§11 above),
     which has no tap targets of its own to size. */

  /* ── M14  HERO GEARS — hide on mobile ──────────────────────────
     Three of four gears are 50–211px outside the hero's right edge
     and visually clipped by overflow:hidden — invisible to users.
     Hiding eliminates the wasted animation and CPU work on mobile. */
  .cg-hero-gear {
    display: none !important;
  }

  /* ── M20  BLOG "ALL ARTICLES" ORDER — CSS not possible ─────────
     The button (widget 846c1fb > heading/body container) and blog
     loop-grid (widget 4a44b01) are siblings in the section's
     .e-con-inner but not in the same flex parent, so CSS `order`
     cannot reorder them. Requires Elementor editor change.
     Current state: "All articles →" appears above the preview
     cards. Acceptable as a "see all" teaser.                      */

  /* ── GLOBAL — Loop-grid images fill card width ─────────────────
     Ensure card images don't overflow their column at 100% width.
     Products (cgsec3) excluded: its thumbnail is a fixed square that
     sits beside the text column, not a full-width card image — see
     "Products — mobile, no slider" below. Capabilities (cgsec5_o)
     excluded too: its mobile carousel sets a fixed photo height —
     see "Capabilities — mobile carousel" below. */
  [data-id="cgsec6_o"] .elementor-loop-container.elementor-grid img {
    max-width: 100% !important;
    height: auto !important;
    width: 100% !important;
  }

  /* ── GLOBAL — Wrap guard: no element wider than viewport ────────
     Belt-and-suspenders for any stray px-width element on mobile. */
  [data-id="cgsec3"]  .elementor-widget-container,
  [data-id="cgsec5_o"] .elementor-widget-container,
  [data-id="cgsec6_o"] .elementor-widget-container {
    max-width: 100% !important;
    overflow: hidden !important;
  }

} /* end @media (max-width: 767px) */

/* ── M9 PATCH / M9 PATCH v2 — REMOVED. Same reason as the M9 block
   above: "All Industries" is a plain underlined link now, not a
   bordered button, so it doesn't need (or want) a full-width,
   centered, 48px tap-target box — that's exactly what was re-centering
   it against the align-self:flex-start left-alignment fix. */

/* ═══════════════════════════════════════════════════════════════
   HEADER LOGO / NAV ALIGNMENT
   Problem: cghdr003 (top bar) and cghdr006 (logo + nav bar) are
   e-con-boxed containers whose .e-con-inner maxWidth is 1140px,
   placing content at x=150px (24px outer-pad + 126px auto-margin).
   Every page section uses a 1248px content box at x=96px
   (hero inner left:96, headings left:96, cards left:96).
   The logo therefore sits 54px to the right of all section content.

   Fix: Override the .e-con-inner max-width to 1248px inside both
   header boxed rows. At 1440px viewport:
     outer-pad 24px + (1440-48-1248)/2 = 24+72 = 96px ✓

   The Elementor-generated rule is:
     .elementor-element-cghdr006 > .e-con-inner { max-width: ... }
   We must match or exceed 0-2-0 specificity.
   ═══════════════════════════════════════════════════════════════ */
.elementor-element.elementor-element-cghdr003 > .e-con-inner,
.elementor-element.elementor-element-cghdr006 > .e-con-inner {
  max-width: 1248px !important;
}

/* ── Certifications section — rebuilt 2026-09-13 as native Elementor
   Pro widgets (container + image + heading + icon-list + buttons) so
   every logo, heading, badge and button is separately editable in the
   Elementor panel. Visual design (bordered-off logo column, 2-column
   checkmarked credential list, dashed placeholder pills, "See all"
   link) is unchanged from the previous custom-HTML version. */
/* Elementor's own inline-layout rule is
   ".elementor-widget .elementor-icon-list-items.elementor-inline-items"
   (0,3,0) — matching both classes here to equal that specificity, then
   winning on source order (theme CSS loads after the widget CSS). */
[data-id="cgcertlist1"].elementor-widget .elementor-icon-list-items.elementor-inline-items {
	display: grid !important;
	grid-template-columns: repeat(2, 1fr);
	gap: 16px 28px;
	flex-wrap: unset;
	margin-inline: 0;
}
[data-id="cgcertlist1"] .elementor-icon-list-item {
	align-items: flex-start;
	margin-inline: 0 !important;
}
[data-id="cgcertlist1"] .elementor-icon-list-icon {
	margin-top: 2px;
}
@media (max-width: 767px) {
	[data-id="cgcertlist1"].elementor-widget .elementor-icon-list-items.elementor-inline-items {
		grid-template-columns: 1fr;
		text-align: left;
	}
	[data-id="cgcertpendrow"] {
		text-align: left;
	}
}
/* Pills — shrink each to its own content width instead of stretching
   to fill the flex row (Elementor containers default to flex-grow). */
[data-id="cgcpwrap1"],
[data-id="cgcpwrap2"],
[data-id="cgcpwrap3"] {
	flex: 0 0 auto !important;
	width: auto !important;
}

/* ═══════════════════════════════════════════════════════════════
   MOBILE FIXES — ROUND 2 (≤767px)
   Second-pass audit at 390×844px. Covers issues 1–30.
   ═══════════════════════════════════════════════════════════════ */

@media (max-width: 767px) {

  /* ── ISSUES 1/2/3 — Header: hide dark top bar → 80px header ──
     cghdr002 = the dark section containing AGMA bar + phone rows.
     Hiding it drops header from 232px → ~80px (logo bar only).
     Phone number remains available in footer "Call" button.      */
  [data-id="cghdr002"] {
    display: none !important;
  }

  /* ── ISSUES 14–26 — Scroll margin: clear 80px sticky header ──
     Prevents section headings being obscured by the fixed header
     when navigating via anchor links (hamburger menu items).     */
  [data-id="cghero01"],  [data-id="cgsec2"],    [data-id="cgintro_o"],
  [data-id="cgsec3"],    [data-id="cgsec4_o"],  [data-id="cgcta1_o"],
  [data-id="cgsec5_o"],  [data-id="cgsec6_o"],  [data-id="cgsec7_o"],
  [data-id="cgcta2_o"],  [data-id="cgsec8_o"],  [data-id="cgsec9_o"],
  [data-id="cgcta3_o"],  [data-id="cgsec10_o"], [data-id="cgsec11_o"],
  [data-id="cgsec12_o"], [data-id="cgsec13_o"], [data-id="cgcta4_o"] {
    scroll-margin-top: 82px;
  }

  /* ── ISSUE 4 — Hero CTA buttons: true full-width ──────────────
     Widget cghero07/08 computed at 219px despite width:100% on
     .elementor-button because the widget DIV itself is fixed-width.
     Match 0-2-0 Elementor specificity to override.               */
  .elementor-element.elementor-element-cghero06 {
    align-items: stretch !important;
  }
  .elementor-element.elementor-element-cghero07,
  .elementor-element.elementor-element-cghero08 {
    width: 100% !important;
    align-self: stretch !important;
  }
  .elementor-element.elementor-element-cghero07 .elementor-button-wrapper,
  .elementor-element.elementor-element-cghero08 .elementor-button-wrapper {
    width: 100% !important;
  }
  .elementor-element.elementor-element-cghero07 .elementor-button,
  .elementor-element.elementor-element-cghero08 .elementor-button {
    width: 100% !important;
    box-sizing: border-box !important;
    justify-content: center !important;
    display: flex !important;
  }

  /* ── ISSUE 8 — CTA1 "Request a quote →" button: full-width ────
     d19e24e = button widget (193px in 342px container).
     14a1d63 = button row container (has align-items:flex-start).  */
  .elementor-element.elementor-element-14a1d63 {
    align-items: stretch !important;
  }
  .elementor-element.elementor-element-d19e24e {
    width: 100% !important;
    align-self: stretch !important;
  }
  .elementor-element.elementor-element-d19e24e .elementor-button-wrapper {
    width: 100% !important;
  }
  .elementor-element.elementor-element-d19e24e .elementor-button {
    width: 100% !important;
    box-sizing: border-box !important;
    justify-content: center !important;
    display: flex !important;
  }

  /* ── ISSUE 20 — Blog "All articles →" button: full-width ───────
     26811e7 = button widget (137px in 310px container dc5a0b2).   */
  .elementor-element.elementor-element-dc5a0b2 {
    align-items: stretch !important;
  }
  .elementor-element.elementor-element-26811e7 {
    width: 100% !important;
    align-self: stretch !important;
  }
  .elementor-element.elementor-element-26811e7 .elementor-button-wrapper {
    width: 100% !important;
  }
  .elementor-element.elementor-element-26811e7 .elementor-button {
    width: 100% !important;
    box-sizing: border-box !important;
    justify-content: center !important;
    display: flex !important;
  }

  /* ── ISSUE 21 — Blog "Read article →" links: 44px touch target ─
     8420dab widget renders at 272×38px — below 44px minimum.     */
  [data-id="8420dab"] {
    min-height: 44px !important;
    display: flex !important;
    align-items: center !important;
  }
  [data-id="8420dab"] a,
  [data-id="8420dab"] .elementor-post__read-more {
    padding-top: 3px !important;
    padding-bottom: 3px !important;
    min-height: 44px !important;
    display: inline-flex !important;
    align-items: center !important;
    box-sizing: border-box !important;
  }

  /* ── ISSUE 13 — Process: reduce 48px gap below intro text ──────
     bf16fcf (intro text container) has padding-bottom: 48px,
     creating excess white space before Step 01 card grid.        */
  [data-id="bf16fcf"] {
    padding-bottom: 16px !important;
  }

  /* ── ISSUES 29/30 — Footer nav links: 44px touch target ────────
     Footer nav links (All Products, Bevel Gears, etc.) render at
     282×31px — below 44px. Add top/bottom padding on all non-button
     footer links. Legal links (Privacy Policy, etc.) same fix.    */
  [data-id="cgftr001"] ul li a {
    display: block !important;
    padding-top: 6px !important;
    padding-bottom: 6px !important;
    min-height: 44px !important;
    line-height: 1.4 !important;
    box-sizing: border-box !important;
  }
  /* Legal links in footer (Privacy Policy, Site Map, LinkedIn) */

}

@keyframes cg-blog-gear-spin {
	from { transform: rotate(0deg); }
	to { transform: rotate(360deg); }
}
@keyframes cg-blog-gear-spin-rev {
	from { transform: rotate(360deg); }
	to { transform: rotate(0deg); }
}
@media (max-width: 767px) {
	[data-id="cgsec10_o"]::before { width: 220px; height: 220px; top: -60px; right: -60px; }
	[data-id="cgsec10_o"]::after { width: 150px; height: 150px; bottom: -40px; left: -40px; }
}
@media (prefers-reduced-motion: reduce) {
	[data-id="cgsec10_o"]::before,
	[data-id="cgsec10_o"]::after {
		animation: none;
	}
}

/* ─── cgsec10_o: Blog card image + excerpt styling ────────────────────────
   The image widget [e68d8ea] used to render Elementor's blank placeholder
   (no dynamic tag was ever wired up) with a "SAMPLE IMAGE" badge overlaid
   so it couldn't be mistaken for real content — see functions.php's
   fix-blog-image.php equivalent DB edit. It's now bound to the
   post-featured-image dynamic tag and every blog post has a real
   uploaded photo, so the badge is removed; the widget renders its own
   <img> with no wrapper needed for anything else here.                    */

/* Blog excerpt (theme-post-excerpt widget cgblog_exc): small grey text, 3-line clamp.
   padding-top: 0 here (not the original 4px) — see the margin-top:-12px
   rule above §10, which does the actual title→excerpt gap tightening;
   this is just the left/right/bottom padding that rule doesn't touch. */

.elementor-element-cgblog_exc p,
body .elementor-element.elementor-element-cgblog_exc:not(:has(p)) {   /* Post Excerpt dynamic tag prints bare text (no <p>) */
  font-family: "Inter", Sans-serif;
  font-size: 16px;
  font-weight: 400;
  line-height: 1.5em;
  letter-spacing: 0.02em;
  color: #8A93A3;
  display: -webkit-box !important;
  -webkit-line-clamp: 3 !important;
  -webkit-box-orient: vertical !important;
  overflow: hidden !important;
}

/* ══════════════════════════════════════════════════════════════════
   HOMEPAGE H2 SECTION-HEADER CONSISTENCY
   Reference: every homepage H2 uses the identical `mt-4 text-section
   uppercase ...` class combo — confirmed across all 14 call sites
   (page.tsx, WhyChooseUs, CtaSections ×5, CapabilitiesGrid,
   IndustriesGrid, ProcessFlow, QualityCriteria, RecentBlogs, Reviews,
   FaqAccordion, HomeContact). --text-section computes to 40px/700 at
   desktop widths (globals.css); mt-4 = 16px.

   In the WP build most of these fell back to a bigger default
   (52px/800 — coincidentally the exact value of the UNUSED --text-hero
   token, so likely Elementor's or the theme's own global H2 style
   winning instead) rather than the correct 40px/700 override, and the
   eyebrow→H2 / H2→description gaps varied between 8/12/20px across
   sections instead of the reference's uniform 16px on both. Fixed here
   consistently across all 15 header instances (Products has 2 CTA
   sections using this pattern, counted once each below).

   Explicit data-id lists, not a blanket `h2.elementor-heading-title`
   rule: the footer's "PRODUCTS / CAPABILITIES / COMPANY" column labels
   are also literal <h2> tags at a deliberately small 12px, and a
   blanket rule would blow them up to 40px too.

   Gap mechanics: each header is [eyebrow, H2, description] as flex
   siblings in a column container with its OWN `gap` (20/12/8px per
   section) — flex `gap` and a child's `margin-top` are ADDITIVE, not
   either-or, so the parent's gap must be zeroed before a clean 16px
   margin-top on the H2/description will produce the right total. */



/* Zero each header's flex-gap; margin-top:16px added per-widget below */
[data-id="713c9cb"],
[data-id="bf9519f"],
[data-id="a3a8529"],
[data-id="9232770"],
[data-id="1990eb6"],
[data-id="3cbadac"],
[data-id="e0d35c2"],
[data-id="dc5a0b2"],
[data-id="3f5e3b9"],
[data-id="2d5c897"],
[data-id="442a888"],
[data-id="ee7ccb9"],
[data-id="cgsec5_i"] > .e-con-inner,
[data-id="cgcta3_o"] > .e-con-inner {
  gap: 0 !important;
}

/* H2 margin-top: 16px (mt-4) from the eyebrow above.
   22efd1d and f0b2d6e are excluded — they're the first child in their
   container (no eyebrow above), so a top margin there would just add
   unwanted space instead of replacing a gap. */
[data-id="58a8684"],
[data-id="d7ab7ba"],
[data-id="d59765f"],
[data-id="7af7ece"],
[data-id="938d8d4"],
[data-id="a0b8c70"],
[data-id="7d4d066"],
[data-id="0807998"],
[data-id="df051f3"],
[data-id="f768c21"],
[data-id="06fb878"],
[data-id="623f076"] {
  margin-top: 16px !important;
}

/* Description margin-top: 16px (mt-4) from the H2 above.
   f385d5b (Credentials) is excluded — nothing follows it in that
   container. */
[data-id="47d1dbf"],
[data-id="93efbaf"],
[data-id="c7330d8"],
[data-id="47da426"],
[data-id="debf9a6"],
[data-id="d019746"],
[data-id="1b8eb7b"],
[data-id="ec47c38"],
[data-id="72d949d"],
[data-id="31f40fa"],
[data-id="0f81f42"],
[data-id="2f3ff48"],
[data-id="c126fc6"],
[data-id="3a66c51"] {
  margin-top: 16px !important;
}

/* FAQ eyebrow (7401680) carries its own margin-bottom: 12px on the
   WIDGET element itself (not its .elementor-heading-title child), which
   stacks with 06fb878's margin-top: 16px above (flex siblings' margin
   and gap are additive) for 28px total instead of 16px — the one
   outlier among all 15 headers. Zeroed directly here rather than
   chasing down the original rule. */
[data-id="7401680"] {
  margin-bottom: 0 !important;
}

/* ── "→" arrow fix (site-wide) ────────────────────────────────────
   Companion to functions.php's cg_fix_arrow_alignment_script, which
   replaces every "→" character on the page with this inline SVG
   (Lucide "arrow-right"). The Unicode glyph itself was rejected as a
   fix target — every font on this site carries so much built-in empty
   space inside the character's own em-box that no consistent `top`
   offset lined it up with the surrounding text's cap-height. An SVG
   isn't subject to that: `vertical-align` positions it reliably, and
   `stroke="currentColor"` (set on the SVG itself) means it always
   matches whatever text color surrounds it, including on :hover. Sized
   in em units so it scales with whatever heading/button font-size
   it's dropped into. */
.cg-arrow-fix {
  width: 0.85em;
  height: 0.85em;
  margin-left: 0.15em;
  vertical-align: -0.1em;
  flex-shrink: 0;
}

/* ══════════════════════════════════════════════════════════════════
   SITE-WIDE THEMED BACKGROUND DECORATION
   Every major section below gets 1-2 faint line-art SVG motifs tied to
   that section's own subject (a compass for drawings/sketches, a
   sprocket for Products, a factory for Industries, a caliper for
   Quality, a shield for Certifications, a gauge for Stats, and so on)
   — inline data URIs, so there's zero extra network request and the
   file stays lightweight. Each drifts or spins slowly and continuously
   (durations tuned per icon size — bigger, slower) at very low opacity
   so it reads as ambient texture, never competing with real content.
   Content keeps its own stacking layer (every direct child of the section,
   z-index:1) above the decoration (z-index:0); prefers-reduced-motion
   freezes every animation without hiding the artwork itself.
   ══════════════════════════════════════════════════════════════════ */

@keyframes cg-bg-spin {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}
@keyframes cg-bg-spin-rev {
  from { transform: rotate(360deg); }
  to { transform: rotate(0deg); }
}
@keyframes cg-bg-float {
  0%, 100% { transform: translate(0, 0) rotate(0deg); }
  50% { transform: translate(14px, -10px) rotate(6deg); }
}
@keyframes cg-bg-float-rev {
  0%, 100% { transform: translate(0, 0) rotate(0deg); }
  50% { transform: translate(-14px, 10px) rotate(-6deg); }
}

@media (max-width: 767px) {
  [data-id="cgsec2"]::before { width: 143px; height: 143px; }
  [data-id="cgsec2"]::after { width: 88px; height: 88px; }
  [data-id="cgintro_o"]::before { width: 132px; height: 132px; }
  [data-id="cgintro_o"]::after { width: 83px; height: 83px; }
  [data-id="cgsec3"]::before { width: 165px; height: 165px; }
  [data-id="cgsec3"]::after { width: 94px; height: 94px; }
  [data-id="cgcta1_o"]::after { width: 121px; height: 121px; }
  [data-id="cgsec5_o"]::before { width: 116px; height: 116px; }
  [data-id="cgsec5_o"]::after { width: 72px; height: 72px; }
  [data-id="cgsec6_o"]::before { width: 143px; height: 143px; }
  [data-id="cgsec6_o"]::after { width: 83px; height: 83px; }
  [data-id="cgsec7_o"]::before { width: 110px; height: 110px; }
  [data-id="cgcta3_o"]::before { width: 121px; height: 121px; }
  [data-id="cgsec9_o"]::before { width: 121px; height: 121px; }
  [data-id="cgsec9_o"]::after { width: 72px; height: 72px; }
  [data-id="cgcta2_o"]::before { width: 121px; height: 121px; }
  [data-id="cgsec11_o"]::before { width: 110px; height: 110px; }
  [data-id="cgsec11_o"]::after { width: 72px; height: 72px; }
  [data-id="cgsec12_o"]::before { width: 121px; height: 121px; }
  [data-id="cgsec13_o"]::before { width: 110px; height: 110px; }
  [data-id="cgsec13_o"]::after { width: 66px; height: 66px; }
}

/* ============================================================
   13. §2 Stats — counter panel overlaps the hero banner
   Reference: client screenshot — the stat card straddles the
   hero / next-section boundary, roughly half over the hero photo
   and half below it, casting a shadow onto the section below.

   Elementor has no negative-margin control on containers, and
   cgsec2's own decoration rule sets `overflow:hidden` (would clip
   a negatively-offset child). Handled here:

   - cgsec2 loses its 64px top padding and is pulled up by
     --cg-stat-rise (≈ half the panel's rendered height) via a
     negative top margin, so the panel's top half sits over the hero.
   - cgsec2's background switches from the near-black stats band
     (#040a15) to the same light grey as the Intro section below
     (#F3F5F6): the panel's lower half — and the empty space beside
     it — then reads as one continuous light band flowing into Intro,
     with no dark strip left behind. The panel card keeps its own
     dark fill (§11 above), so it still reads as a card on both halves.
   - cgsec2's drifting-gauge decorations are white at 6% opacity —
     invisible on the new light bg — so they're hidden here.
   - position:relative + z-index lift the section (and panel) above
     the hero's animated ::before/::after image layers.
   - Responsive: the rise shrinks on tablet and is removed entirely
     on mobile, where the panel becomes a tall 2×2 grid and any
     overlap would cover the hero headline.
   ============================================================ */
[data-id="cgsec2"] {
	/* ≈ half the panel's rendered height (~200px desktop), so the panel
	   straddles the hero's bottom edge ~50/50. */
	--cg-stat-rise: 100px;
	position: relative;
	z-index: 3;
	overflow: visible !important;
	background-color: transparent !important;
	padding-top: 0 !important;
	padding-bottom: 64px !important;
	margin-top: calc(var(--cg-stat-rise) * -1) !important;
}
/* The light band is drawn by ::after starting --cg-stat-rise DOWN from
   the section top — i.e. right at the hero's original bottom edge —
   and running to the section bottom. The top --cg-stat-rise of the
   section stays transparent, so the hero photo shows through there and
   the panel's upper half genuinely overlaps the visible hero. A solid
   background on the section itself would instead cover the hero across
   the whole overlap zone, leaving the panel sitting flat on the light
   band with no real overlap. */
[data-id="cgsec2"]::before {
	display: none !important;
}
[data-id="cgsec2"]::after {
	display: block !important;
	content: "" !important;
	position: absolute !important;
	left: 0 !important;
	right: 0 !important;
	top: var(--cg-stat-rise) !important;
	bottom: 0 !important;
	width: auto !important;
	height: auto !important;
	z-index: 0 !important;
	pointer-events: none !important;
	animation: none !important;
}
/* Panel (and its wrappers) above the band and the hero's animated
   layers; shadow makes the overlap read as a raised card. */
[data-id="cgsec2in"],
[data-id="cgsec2"] .cgstat-panel,
[data-id="cgs2grid"] {
	position: relative;
	z-index: 1 !important;
}
[data-id="cgsec2"] .cgstat-panel,
[data-id="cgs2grid"] {
	border: 1px solid #E8EAEB !important;
	box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12) !important;
}

@media (min-width: 768px) and (max-width: 1024px) {
	[data-id="cgsec2"] { --cg-stat-rise: 70px; }
}
@media (max-width: 767px) {
	/* Panel is a tall 2×2 grid here — no overlap, normal flow. */
	[data-id="cgsec2"] {
		--cg-stat-rise: 0px;
		margin-top: 0 !important;
		padding-top: 36px !important;
		background-color: #F3F5F6 !important;
	}
	[data-id="cgsec2"]::after { display: none !important; }
}

@media (prefers-reduced-motion: reduce) {
  [data-id="cgsec2"]::before, [data-id="cgsec2"]::after { animation: none !important; }
  [data-id="cgintro_o"]::before, [data-id="cgintro_o"]::after { animation: none !important; }
  [data-id="cgsec3"]::before, [data-id="cgsec3"]::after { animation: none !important; }
  [data-id="cgcta1_o"]::before, [data-id="cgcta1_o"]::after { animation: none !important; }
  [data-id="cgsec5_o"]::before, [data-id="cgsec5_o"]::after { animation: none !important; }
  [data-id="cgsec6_o"]::before, [data-id="cgsec6_o"]::after { animation: none !important; }
  [data-id="cgsec7_o"]::before, [data-id="cgsec7_o"]::after { animation: none !important; }
  [data-id="cgcta3_o"]::before, [data-id="cgcta3_o"]::after { animation: none !important; }
  [data-id="cgsec9_o"]::before, [data-id="cgsec9_o"]::after { animation: none !important; }
  [data-id="cgcta2_o"]::before, [data-id="cgcta2_o"]::after { animation: none !important; }
  [data-id="cgsec11_o"]::before, [data-id="cgsec11_o"]::after { animation: none !important; }
  [data-id="cgsec12_o"]::before, [data-id="cgsec12_o"]::after { animation: none !important; }
  [data-id="cgsec13_o"]::before, [data-id="cgsec13_o"]::after { animation: none !important; }
}

/* ============================================================
   14. Typography system — Space Grotesk (display/headings) + Inter (UI/body)
   Client type scale, 2026-09-11. Replaces the old Geist / Geist Mono system.

   The scale itself lives in the Elementor kit (post 7 Global Fonts):
     Primary   → H1 / main headings   Space Grotesk 600  clamp(64→76px)  lh 1.02  ls -0.02  (sentence case)
     Secondary → H2                   Space Grotesk 600  clamp(42→52px)  lh 1.08  ls -0.015 (sentence case)
     Text      → Body                 Inter 400          clamp(16→18px)  lh 1.6
     Accent    → Technical Numbers    Space Grotesk 600  clamp(36→56px)  lh 1.0   ls -0.01
     Hero Display / Band Heading / Card Title / Body Small / Eyebrow / Button / Nav Link
       remapped to the same two families at the spec sizes/weights.
   Eyebrow / Category keeps its uppercase + 0.08em tracking (it's a label, not a heading).

   This block is only the BACKFILL for what the kit can't reach:
   per-widget typography overrides baked into the homepage's _elementor_data,
   and a couple of base safety nets. Elementor loads both webfonts from Google
   Fonts (kit "Accent"/"Primary" families); Geist Mono is still loaded (theme
   functions.php) for the decorative 01–09 ordinals only.
   ============================================================ */

/* 14a. Base safety nets — anything that escapes an Elementor typography var
   still lands on the right family. */
body,
button,
input,
select,
textarea {
	font-family: "Inter", Sans-serif;
}
h1, h2, h3, h4, h5, h6,
.elementor-heading-title {
	font-family: "Inter", Sans-serif;
}


/* ============================================================
   INDUSTRIES PAGES — 2026-09-14
   Archive (/industries/) + single (/industries/{slug}/) Theme Builder
   templates. Elementor's native controls cover layout/spacing/color for
   every widget on these pages; the two rules below style markup produced
   by the [cg_industry_list] / [cg_industry_related] shortcodes (HTML
   widget output), which have no Elementor style controls of their own —
   documented per PROJECT.md's Custom Code Rules.
   ============================================================ */

/* Challenges / What We Make bulleted lists (industries/[slug] reference:
   a small accent dot + leading-relaxed item text). */
.cg-ind-list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: 12px;
}
.cg-ind-list-item {
	display: flex;
	gap: 12px;
	align-items: flex-start;
	line-height: 1.6;
	color: var(--e-global-color-text, #393E42);
}
.cg-ind-dot {
	display: inline-block;
	width: 6px;
	height: 6px;
	margin-top: 10px;
	flex-shrink: 0;
	border-radius: 50%;
	background: var(--e-global-color-accent, #B83230);
}

/* Related-links row (industries/[slug] reference: inline links with a
   2px accent-coloured bottom border). */
.cg-ind-related {
	display: flex;
	flex-wrap: wrap;
	gap: 16px 24px;
}
.cg-ind-related-link {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	font-weight: 600;
	font-size: 14px;
	color: var(--e-global-color-primary, #0C1825);
	border-bottom: 2px solid var(--e-global-color-accent, #B83230);
	padding-bottom: 2px;
	text-decoration: none;
	transition: color 150ms ease;
}
.cg-ind-related-link:hover {
	color: var(--e-global-color-accent, #B83230);
}


/* ============================================================
   CAPABILITIES PAGES — 2026-09-15
   Archive (/capabilities/) + single (root URLs, e.g.
   /custom-gear-cutting/) Theme Builder templates. Elementor's native
   controls cover layout/spacing/color for every widget on these pages;
   the rules below style markup produced by the [cg_capability_equipment]
   / [cg_capability_related] shortcodes (HTML widget output), which have
   no Elementor style controls of their own — documented per PROJECT.md's
   Custom Code Rules. Reuses the same accent-dot and card idioms as the
   2026-09-14 Industries block above rather than inventing new ones.
   ============================================================ */

/* Equipment groups (reference: EquipmentList in
   components/blocks/primitives.tsx) — operation heading, optional note,
   monospace machine list with an accent dot bullet, laid out as cards in
   a two-column grid on wider screens. */
.cg-cap-equipment {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
	gap: 24px;
}
.cg-cap-eq-group {
	border: 1px solid var(--e-global-color-border, #E4E4E1);
	border-radius: 8px;
	padding: 20px 24px;
}
.cg-cap-eq-op {
	margin: 0 0 8px;
	font-size: 16px;
	font-weight: 600;
	color: var(--e-global-color-primary, #0C1825);
}
.cg-cap-eq-note {
	margin: 0 0 12px;
	font-size: 13px;
	font-style: italic;
	color: var(--e-global-color-text, #393E42);
}
.cg-cap-eq-machines {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: 8px;
}
.cg-cap-eq-machine {
	display: flex;
	gap: 10px;
	align-items: flex-start;
	font-family: "Roboto Mono", "Courier New", monospace;
	font-size: 13px;
	line-height: 1.5;
	color: var(--e-global-color-text, #393E42);
}

/* Related grid (reference: RelatedGrid in
   components/templates/PageTemplate.tsx) — section-label eyebrow, title,
   summary, card border that darkens on hover. */
.cg-cap-related-grid {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
	gap: 24px;
}
.cg-cap-related-card {
	display: block;
	border: 1px solid var(--e-global-color-border, #E4E4E1);
	border-radius: 8px;
	padding: 24px;
	text-decoration: none;
	transition: border-color 150ms ease, background-color 150ms ease;
}
.cg-cap-related-card:hover {
	border-color: var(--e-global-color-accent, #B83230);
	background: var(--e-global-color-surface, #F7F6F3);
}
.cg-cap-related-label {
	margin: 0 0 8px;
	font-size: 11px;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.08em;
	color: var(--e-global-color-text, #393E42);
}
.cg-cap-related-title {
	margin: 0 0 8px;
	font-size: 16px;
	font-weight: 600;
	color: var(--e-global-color-primary, #0C1825);
}
.cg-cap-related-summary {
	margin: 0;
	font-size: 14px;
	line-height: 1.6;
	color: var(--e-global-color-text, #393E42);
}

/* Example photos (reference: ExampleGrid in components/blocks/
   primitives.tsx) — photographed equipment/output, name + process line,
   in a 3-up card grid. Used by [cg_capability_examples]. */
.cg-cap-examples {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
	gap: 24px;
}
.cg-cap-example-card {
	overflow: hidden;
	border: 1px solid var(--e-global-color-border, #E4E4E1);
	border-radius: 8px;
	background: var(--e-global-color-background, #fff);
}
.cg-cap-example-photo img {
	display: block;
	width: 100%;
	aspect-ratio: 4 / 3;
	object-fit: cover;
}
.cg-cap-example-body {
	padding: 20px;
}
.cg-cap-example-name {
	margin: 0;
	font-weight: 600;
	color: var(--e-global-color-primary, #0C1825);
}
.cg-cap-example-process {
	margin: 10px 0 0;
	font-size: 14px;
	line-height: 1.5;
	color: var(--e-global-color-text, #393E42);
}

/* Process groups (reference: ProcessList in components/blocks/
   primitives.tsx) — used by [cg_capability_processes] on Stock Sprockets &
   Chains ("Sprocket Types" / "Chain Types"). */
.cg-cap-process-groups {
	display: flex;
	flex-direction: column;
	gap: 40px;
}
.cg-cap-process-heading {
	margin: 0 0 8px;
	font-size: 22px;
	font-weight: 600;
	color: var(--e-global-color-primary, #0C1825);
}
.cg-cap-process-intro {
	margin: 0 0 20px;
	color: var(--e-global-color-text, #393E42);
}
.cg-cap-process-items {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
	gap: 20px;
}
.cg-cap-process-item {
	border: 1px solid var(--e-global-color-border, #E4E4E1);
	border-radius: 8px;
	padding: 18px 20px;
	background: var(--e-global-color-surface, #F7F6F3);
}
.cg-cap-process-item-name {
	margin: 0 0 8px;
	font-size: 15px;
	font-weight: 600;
	color: var(--e-global-color-primary, #0C1825);
}
.cg-cap-process-item-desc {
	margin: 0;
	font-size: 13px;
	line-height: 1.6;
	color: var(--e-global-color-text, #393E42);
}

/* Bullets (reference: Bullets in components/blocks/primitives.tsx) — used
   by [cg_capability_bullets] on Designer and Engineer Resources
   ("Reference Tables"). */
.cg-cap-bullets-groups {
	display: flex;
	flex-direction: column;
	gap: 32px;
}
.cg-cap-bullets-heading {
	margin: 0 0 8px;
	font-size: 22px;
	font-weight: 600;
	color: var(--e-global-color-primary, #0C1825);
}
.cg-cap-bullets-intro {
	margin: 0 0 16px;
	color: var(--e-global-color-text, #393E42);
}
.cg-cap-bullets-list {
	list-style: none;
	margin: 0;
	padding: 20px 24px;
	border: 1px solid var(--e-global-color-border, #E4E4E1);
	border-radius: 8px;
	display: flex;
	flex-direction: column;
	gap: 10px;
}
.cg-cap-bullet-item {
	display: flex;
	gap: 10px;
	align-items: flex-start;
	color: var(--e-global-color-text, #393E42);
}

/* Closing prose (trailing prose block after equipment/bullets/process
   content) — used by [cg_capability_closing] on Designer & Engineer
   Resources and Stock Sprockets & Chains. Typography matches the native
   theme-post-content rendering of the leading prose block, since both
   read as the same "prose" block kind in the reference. */
.cg-cap-closing-prose h2 {
	margin: 0 0 16px;
	font-size: 28px;
	font-weight: 600;
	color: var(--e-global-color-primary, #0C1825);
}
.cg-cap-closing-prose p {
	margin: 0 0 16px;
	font-size: 18px;
	line-height: 1.7;
	color: var(--e-global-color-text, #393E42);
}
.cg-cap-closing-prose p:last-child {
	margin-bottom: 0;
}

/* ============================================================
   PRODUCTS PAGES — 2026-09-15
   Archive (/products/) + single (root URLs, e.g. /spur-gears/) Theme
   Builder templates. [cg_product_bullets] and [cg_product_related] reuse
   the .cg-cap-bullets-*/.cg-cap-related-* rules above verbatim (identical
   markup shape to their Capability counterparts), so only the two
   Product-specific shortcodes below — [cg_product_capacity] and
   [cg_product_standards], which have no Capability equivalent — need new
   rules here. Reference: SpecTable / the standards pill-chip list in
   PageHero, both in components/templates/PageTemplate.tsx.
   ============================================================ */

/* Capacity table (reference: SpecTable in components/blocks/
   primitives.tsx) — label/value rows, optional inline note. */
.cg-prod-capacity {
	display: flex;
	flex-direction: column;
}
.cg-prod-capacity-heading {
	margin: 0 0 16px;
	font-size: 28px;
	font-weight: 600;
	color: var(--e-global-color-primary, #0C1825);
}
.cg-prod-capacity-table {
	width: 100%;
	border-collapse: collapse;
	border: 1px solid var(--e-global-color-border, #E4E4E1);
	border-radius: 8px;
	overflow: hidden;
}
.cg-prod-capacity-row {
	border-bottom: 1px solid var(--e-global-color-border, #E4E4E1);
}
.cg-prod-capacity-row:last-child {
	border-bottom: none;
}
.cg-prod-capacity-label {
	width: 40%;
	padding: 14px 20px;
	text-align: left;
	font-size: 14px;
	font-weight: 600;
	color: var(--e-global-color-primary, #0C1825);
	background: var(--e-global-color-surface, #F7F6F3);
}
.cg-prod-capacity-value {
	padding: 14px 20px;
	font-size: 14px;
	line-height: 1.5;
	color: var(--e-global-color-text, #393E42);
}
.cg-prod-capacity-note {
	display: block;
	margin-top: 4px;
	font-size: 12px;
	font-style: italic;
	color: var(--e-global-color-text, #393E42);
	opacity: 0.75;
}

/* Standards chip list (reference: the standards pill-chip list rendered in
   PageHero for products with a `standards` array, e.g. splines). Rendered
   in the body here rather than the shared hero band, which is a single
   Theme Builder container across all 9 products. */
.cg-prod-standards {
	display: flex;
	flex-direction: column;
}
.cg-prod-standards-heading {
	margin: 0 0 16px;
	font-size: 28px;
	font-weight: 600;
	color: var(--e-global-color-primary, #0C1825);
}
.cg-prod-standards-list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-wrap: wrap;
	gap: 10px;
}
.cg-prod-standard-chip {
	display: flex;
	align-items: baseline;
	gap: 8px;
	border: 1px solid var(--e-global-color-border, #E4E4E1);
	border-radius: 999px;
	padding: 8px 16px;
	background: var(--e-global-color-surface, #F7F6F3);
}
.cg-prod-standard-code {
	font-family: "Roboto Mono", "Courier New", monospace;
	font-size: 13px;
	font-weight: 600;
	color: var(--e-global-color-primary, #0C1825);
}
.cg-prod-standard-title {
	font-size: 12px;
	color: var(--e-global-color-text, #393E42);
}

/* Leading prose (reference: the single leading Prose block, rendered via
   the native theme-post-content widget reading post_content) — typography
   matches .cg-cap-closing-prose so products and capabilities read the same
   weight of body copy. */
.cg-prod-prose h2 {
	margin: 0 0 16px;
	font-size: 28px;
	font-weight: 600;
	color: var(--e-global-color-primary, #0C1825);
}
.cg-prod-prose p {
	margin: 0 0 16px;
	font-size: 18px;
	line-height: 1.7;
	color: var(--e-global-color-text, #393E42);
}
.cg-prod-prose p:last-child {
	margin-bottom: 0;
}

/* ============================================================
   9. 404 — Page Not Found (template-parts/404.php).
   Overrides hello-elementor's bare "The page can't be found." fallback.
   Header/footer are unaffected — this only styles the content between them.
   Left/right card: left is the message + actions, right is a sidebar list
   of popular sections, each with a one-line description.
   ============================================================ */
.cg-404 {
	display: flex;
	justify-content: center;
	padding: 64px 24px;
	background: #ffffff;
}
.cg-404-card {
	display: grid;
	grid-template-columns: 1.15fr 0.85fr;
	max-width: 1000px;
	width: 100%;
	background: #ffffff;
	border: 1px solid #e5e9ec;
	border-radius: 16px;
	overflow: hidden;
	box-shadow: 0 8px 30px rgba(11, 15, 23, 0.06);
}

/* Left — message + actions */
.cg-404-left {
	padding: 64px 48px;
}
.cg-404-icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 64px;
	height: 64px;
	margin-bottom: 24px;
	border-radius: 999px;
	background: rgba(27, 63, 160, 0.08);
	color: #1b3fa0;
}
.cg-404-icon .cg-icon {
	width: 32px;
	height: 32px;
}
.cg-404-code {
	margin: 0;
	font-family: 'Geist Mono', 'Courier New', monospace;
	font-size: 88px;
	font-weight: 700;
	line-height: 1;
	color: #B83230;
}
.cg-404-title {
	margin: 8px 0 16px;
	font-size: 32px;
	font-weight: 700;
	color: var(--e-global-color-primary, #0C1825);
}
.cg-404-body {
	margin: 0 0 32px;
	max-width: 40ch;
	font-size: 16px;
	line-height: 1.7;
	color: var(--e-global-color-text, #4a6070);
}
.cg-404-actions {
	display: flex;
	flex-wrap: wrap;
	gap: 12px;
}
.cg-404-btn {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	padding: 14px 28px;
	border-radius: 5px;
	font-size: 14px;
	font-weight: 600;
	line-height: 1.2;
	text-decoration: none;
	transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease;
}
.cg-404-btn .cg-icon {
	width: 16px;
	height: 16px;
}
.cg-404-btn--solid {
	background: #1b3fa0;
	color: #ffffff;
	border: 1px solid #1b3fa0;
}
.cg-404-btn--solid:hover {
	background: #15327F;
	border-color: #15327F;
	color: #ffffff;
}
.cg-404-btn--ghost {
	background: transparent;
	border: 1px solid #d5dbe0;
	color: var(--e-global-color-primary, #0C1825);
}
.cg-404-btn--ghost:hover {
	border-color: #1b3fa0;
	color: #1b3fa0;
}

/* Right — sidebar of popular sections */
.cg-404-right {
	padding: 64px 40px;
	background: #f8f9fa;
	border-left: 1px solid #e5e9ec;
}
.cg-404-right-title {
	margin: 0 0 20px;
	font-size: 13px;
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: 0.04em;
	color: var(--e-global-color-text, #6b6f72);
}
.cg-404-linklist {
	display: flex;
	flex-direction: column;
	gap: 4px;
	margin: 0;
	padding: 0;
	list-style: none;
}
.cg-404-linklist-item {
	display: flex;
	align-items: flex-start;
	gap: 14px;
	padding: 14px;
	margin: 0 -14px;
	border-radius: 10px;
	text-decoration: none;
	transition: background-color 150ms ease;
}
.cg-404-linklist-item:hover {
	background: rgba(27, 63, 160, 0.06);
}
.cg-404-linklist-icon {
	display: flex;
	align-items: center;
	justify-content: center;
	flex-shrink: 0;
	width: 36px;
	height: 36px;
	border-radius: 8px;
	background: #ffffff;
	border: 1px solid #e5e9ec;
	color: #1b3fa0;
}
.cg-404-linklist-icon .cg-icon {
	width: 18px;
	height: 18px;
}
.cg-404-linklist-text {
	display: flex;
	flex-direction: column;
	gap: 2px;
	flex: 1 1 auto;
}
.cg-404-linklist-label {
	font-size: 15px;
	font-weight: 600;
	color: var(--e-global-color-primary, #0C1825);
}
.cg-404-linklist-desc {
	font-size: 13px;
	line-height: 1.5;
	color: var(--e-global-color-text, #6b6f72);
}
.cg-404-linklist-arrow {
	display: flex;
	align-items: center;
	flex-shrink: 0;
	margin-top: 8px;
	color: #9bb0bf;
	transition: transform 150ms ease;
}
.cg-404-linklist-arrow .cg-icon {
	width: 16px;
	height: 16px;
}
.cg-404-linklist-item:hover .cg-404-linklist-arrow {
	transform: translateX(3px);
	color: #1b3fa0;
}

@media (max-width: 860px) {
	.cg-404-card {
		grid-template-columns: 1fr;
	}
	.cg-404-right {
		border-left: none;
		border-top: 1px solid #e5e9ec;
	}
}
@media (max-width: 480px) {
	.cg-404 { padding: 32px 16px; }
	.cg-404-left, .cg-404-right { padding: 40px 24px; }
	.cg-404-code { font-size: 64px; }
	.cg-404-title { font-size: 26px; }
	.cg-404-actions { flex-direction: column; align-items: stretch; }
}
@media (prefers-reduced-motion: reduce) {
	.cg-404-btn, .cg-404-linklist-item, .cg-404-linklist-arrow {
		transition: none;
	}
}

/* ============================================================
   10. Downloads page (Resources → Downloads, post 93) — document
   cards + category filter bar.

   Card typography/colors/spacing live on the "Download Card" Elementor
   loop-item template's own widget controls (editable in Elementor). The
   rules below cover only what those controls can't express: the inline
   SVG icon, the hover choreography, and the JS-driven filter bar (see
   cg_downloads_filter_script() in functions.php).

   TWO ELEMENTOR QUIRKS worth knowing, both confirmed by inspecting the
   compiled CSS rather than assumed:
   1. The "CSS Classes" advanced setting is NOT rendered into the HTML
      for containers/widgets — only raw HTML widgets keep a literal
      class. So rules here target Elementor's own auto-generated
      per-element id class (.elementor-element-dlcard001 etc.), which
      always renders.
   2. Style → Hover controls emit NO :hover CSS at all for elements
      inside a loop-item template, so every hover state below is written
      by hand here instead of set in the editor.
   ============================================================ */
.elementor-element-dlcard001 {
	box-shadow: 0 1px 2px rgba(16, 24, 40, 0.04);
	transition: border-color 200ms ease, box-shadow 200ms ease, transform 200ms ease;
}
.elementor-element-dlcard001:hover {
	border-color: #b9c4d8 !important;
	box-shadow: 0 12px 28px -10px rgba(15, 37, 87, 0.22) !important;
	transform: translateY(-2px);
}

/* Icon column — a plain accent-colored glyph sitting on the title's
   optical baseline, not a filled badge. Fixed width so the body column
   beside it keeps a straight left edge across every card. */
.elementor-element-dlicon001 {
	flex: 0 0 auto !important;
	width: auto !important;
}
.cg-dl-icon {
	display: inline-flex;
	margin-top: 1px;
	color: #1b3fa0;
	transition: color 200ms ease, transform 200ms ease;
}
.cg-dl-icon svg {
	width: 22px;
	height: 22px;
}
.elementor-element-dlcard001:hover .cg-dl-icon {
	color: #0f2557;
	transform: translateY(-1px);
}

/* Body column — min-width:0 lets long descriptions wrap instead of
   forcing the flex row wider than the card. */
.elementor-element-dlbody001 {
	flex: 1 1 auto !important;
	min-width: 0 !important;
}

/* Category label — a quiet uppercase tag opposite the title, no pill.
   cg_downloads_filter_script() adds .cg-dl-cat--{key} on load so each
   category carries its own tint; the muted default below is the
   fallback for anything the script doesn't recognize. */
.elementor-element-dlcat001 {
	flex: 0 0 auto !important;
	width: auto !important;
	white-space: nowrap;
}
.cg-dl-cat--gear .elementor-heading-title { color: #1b3fa0 !important; }
.cg-dl-cat--spline .elementor-heading-title { color: #0b8075 !important; }
.cg-dl-cat--formula .elementor-heading-title { color: #7c3abd !important; }
.cg-dl-cat--inspection .elementor-heading-title { color: #b45f06 !important; }
.cg-dl-cat--general .elementor-heading-title { color: #7a8699 !important; }

/* Download action — a text link with a leading arrow drawn in CSS,
   pinned to the bottom of the body column so the links line up across
   a row of cards regardless of description length. */
.elementor-element-dlbtn001 {
	margin-top: auto !important;
	width: auto !important;
}
.elementor-element-dlbtn001 .elementor-button {
	display: inline-flex;
	align-items: center;
	gap: 7px;
	background: transparent !important;
	border: 0 !important;
	box-shadow: none !important;
}
.elementor-element-dlbtn001 .elementor-button::before {
	content: "";
	width: 15px;
	height: 15px;
	flex: 0 0 auto;
	background-color: currentColor;
	-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 15V3'/%3E%3Cpath d='M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4'/%3E%3Cpath d='m7 10 5 5 5-5'/%3E%3C/svg%3E") center / contain no-repeat;
	mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 15V3'/%3E%3Cpath d='M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4'/%3E%3Cpath d='m7 10 5 5 5-5'/%3E%3C/svg%3E") center / contain no-repeat;
	transition: transform 200ms ease;
}
.elementor-element-dlbtn001 .elementor-button:hover {
	color: #0f2557 !important;
}
.elementor-element-dlbtn001 .elementor-button:hover::before {
	transform: translateY(2px);
}
.elementor-element-dlbtn001 .elementor-button-text {
	border-bottom: 1px solid transparent;
	transition: border-color 200ms ease;
}
.elementor-element-dlbtn001 .elementor-button:hover .elementor-button-text {
	border-bottom-color: currentColor;
}

/* Hide a card while it's filtered out. JS toggles this class rather
   than inline display:none, so it's easy to find/override in one place. */
.cg-dl-hidden {
	display: none !important;
}

/* Category filter bar */
.cg-dl-filterbar {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	margin: 0 0 32px;
}
.cg-dl-filter {
	appearance: none;
	cursor: pointer;
	padding: 9px 18px;
	border: 1px solid #e5e9ec;
	border-radius: 999px;
	background: #ffffff;
	color: #4a6070;
	font-family: Inter, sans-serif;
	font-size: 13px;
	font-weight: 600;
	transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease;
}
.cg-dl-filter:hover {
	border-color: #1b3fa0;
	color: #1b3fa0;
}
.cg-dl-filter.is-active {
	background: #1b3fa0;
	border-color: #1b3fa0;
	color: #ffffff;
}

/* ============================================================
   11. Hero icon badge. (The Downloads hero now uses the shared
   resource-hero.css design; its old glow rules were removed.)
   ============================================================ */
.cg-hero-icon {
	position: relative;
	z-index: 1;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 48px;
	height: 48px;
	margin-bottom: 20px;
	border-radius: 12px;
	background: rgba(157, 176, 228, 0.12);
	box-shadow: inset 0 0 0 1px rgba(157, 176, 228, 0.25);
	color: #9DB0E4;
}
.cg-hero-icon svg {
	width: 24px;
	height: 24px;
}

/* ============================================================
   12. Downloads page CTA band ("Let us solve your gear challenge").
   Background gradient + text/link colors are set on the container and
   button widgets directly (editable in Elementor); this adds the one
   thing those controls can't — a decorative glow — plus button hover
   states written as plain CSS, since (as established above for the
   card template) this Elementor version doesn't reliably emit :hover
   CSS from the Style → Hover controls.
   ============================================================ */
.elementor-element-dwn0cta {
	overflow: hidden;
}
.elementor-element-dwn0cta::before {
	content: "";
	position: absolute;
	bottom: -160px;
	left: -100px;
	width: 420px;
	height: 420px;
	border-radius: 50%;
	background: radial-gradient(circle, rgba(255, 255, 255, 0.08), transparent 70%);
	pointer-events: none;
}
.elementor-element-dwn0cta .elementor-element-populated {
	position: relative;
	z-index: 1;
}
.elementor-element-dwn0ctabtn1 .elementor-button,
.elementor-element-dwn0ctabtn2 .elementor-button {
	transition: background-color 200ms ease, transform 200ms ease;
}
.elementor-element-dwn0ctabtn1:hover .elementor-button {
	background-color: #eef1f8 !important;
	transform: translateY(-2px);
}
.elementor-element-dwn0ctabtn2:hover .elementor-button {
	background-color: rgba(255, 255, 255, 0.12) !important;
	transform: translateY(-2px);
}

/* ============================================================
   13. Blog listing page (Resources → Blog, post 91) — featured article,
   grid cards, and the search/sort toolbar.

   Card typography/colors/spacing live on the "Blog Card — Featured" and
   "Blog Card — Grid" Elementor loop-item templates' own widget controls
   (editable in Elementor). The rules below cover only what those can't:
   the image/read-time-badge overlay, the meta row layout, and hover
   states (per the two Elementor quirks already documented above —
   CSS Classes not rendering on containers, and no :hover CSS generated
   inside loop-item templates — both confirmed by inspecting compiled
   CSS, so hover here is hand-written rather than set in the editor).
   ============================================================ */

/* Read-time badge, overlaid on the bottom-right corner of the card image. */
.cgblog-readtime {
	position: absolute;
	right: 10px;
	bottom: 10px;
	padding: 4px 10px;
	border-radius: 6px;
	background: rgba(11, 15, 23, 0.72);
	backdrop-filter: blur(2px);
	color: #ffffff;
	font-family: Inter, sans-serif;
	font-size: 11px;
	font-weight: 600;
}

/* "Featured" chip — sits on the same line as the category eyebrow, right-
   aligned against it (bfeyebrowrow is a flex row, space-between), rather
   than overlaid on the image — the clearest signal that this card isn't
   just "the big one" but deliberately the pick of the list. */
.elementor-element-bfeyebrowrow {
	flex-wrap: wrap;
}
.cgblog-featured-badge {
	display: inline-flex;
	flex: 0 0 auto;
	align-items: center;
	gap: 5px;
	padding: 5px 10px;
	border-radius: 6px;
	background: #1b3fa0;
	color: #ffffff;
	font-family: Inter, sans-serif;
	font-size: 11px;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.04em;
}

/* Category badge — compact, sits above the title, not stretched. */
.elementor-element-bfcat,
.elementor-element-bgcat {
	width: fit-content !important;
	max-width: max-content;
}

/* Meta row — avatar circle + author name / date, all on one baseline. */
.elementor-element-bfmeta .elementor-widget-image img,
.elementor-element-bgmeta .elementor-widget-image img {
	display: block;
	border-radius: 999px;
}
.cgblog-date {
	font-family: Inter, sans-serif;
	font-size: 13px;
	color: #8a93a3;
}
.cgblog-date time {
	font: inherit;
	color: inherit;
}

/* Featured article card. Targets Elementor's own auto-generated
   per-element id class, not the "cgblog-lead" class set in the editor —
   confirmed that one doesn't render here (same quirk documented at
   style.css §10 for the Home page's blog card). */
.elementor-element-blogfeat01 {
	text-decoration: none;
	display: flex;
	transition: border-color 200ms ease, box-shadow 200ms ease;
	box-shadow: 0 1px 2px rgba(16, 24, 40, 0.04);
}
.elementor-element-blogfeat01:hover {
	border-color: #b9c4d8 !important;
	box-shadow: 0 16px 32px -12px rgba(15, 37, 87, 0.2) !important;
}
.elementor-element-blogfeat01 .cgblog-readtime {
	font-size: 12px;
}

/* Grid cards */
.elementor-element-bloggrid01 {
	text-decoration: none;
	box-shadow: 0 1px 2px rgba(16, 24, 40, 0.04);
	transition: border-color 200ms ease, box-shadow 200ms ease, transform 200ms ease;
}
.elementor-element-bloggrid01:hover {
	border-color: #b9c4d8 !important;
	box-shadow: 0 14px 28px -10px rgba(15, 37, 87, 0.18) !important;
	transform: translateY(-3px);
}
.elementor-element-bgtitl .elementor-heading-title {
	transition: color 200ms ease;
}
.elementor-element-bloggrid01:hover .elementor-element-bgtitl .elementor-heading-title {
	color: #1b3fa0 !important;
}
.elementor-element-bgbody {
	display: flex !important;
	flex-direction: column;
	flex: 1 1 auto;
}
/* Pushes the meta row (avatar + date) to the card's bottom edge so it
   lines up across a row regardless of title length — Elementor's own
   margin control doesn't accept the keyword "auto" (it emits the invalid
   "margin:autopx", confirmed in the compiled CSS), so this is set here
   as plain CSS instead. */
.elementor-element-bgspacer {
	margin-top: auto !important;
	flex: 1 1 auto;
}

@media (max-width: 767px) {
	.elementor-element-blogfeat01 {
		flex-direction: column;
	}
}
@media (prefers-reduced-motion: reduce) {
	.elementor-element-blogfeat01,
	.elementor-element-bloggrid01 {
		transition: none;
	}
}

/* ============================================================
   14. Article Single template (post 2386) — modern/minimalist detail
   page: header meta row, article body typography, and the dynamic
   Table of Contents (populated from the article's own H2s by
   cg_article_toc_script() in functions.php — see that function for
   why this couldn't be done as a fixed Elementor list).
   ============================================================ */
html {
	scroll-behavior: smooth;
}
.cgart-dot {
	display: inline-block;
	width: 3px;
	height: 3px;
	border-radius: 50%;
	background: #c3c9d1;
}
.cgart-meta-text {
	font-family: Inter, sans-serif;
	font-size: 14px;
	color: #667085;
}

/* Article body — clean, generous, readable measure. Elementor's Post
   Content widget has no typography controls of its own (it just prints
   the_content()), so the actual prose styling lives here. */
.elementor-element-art0content h2 {
	margin: 40px 0 16px;
	font-family: "Space Grotesk", sans-serif;
	font-size: 24px;
	font-weight: 700;
	line-height: 1.3;
	color: #0c1825;
	scroll-margin-top: 24px;
}
.elementor-element-art0content > .elementor-widget-container > *:first-child,
.elementor-element-art0content h2:first-child {
	margin-top: 0;
}
.elementor-element-art0content p {
	margin: 0 0 20px;
	font-family: Inter, sans-serif;
	font-size: 17px;
	line-height: 1.75;
	color: #344054;
}
.elementor-element-art0content ul,
.elementor-element-art0content ol {
	margin: 0 0 20px;
	padding-left: 22px;
	font-family: Inter, sans-serif;
	font-size: 17px;
	line-height: 1.75;
	color: #344054;
}
.elementor-element-art0content li {
	margin-bottom: 6px;
}
.elementor-element-art0content a {
	color: #1b3fa0;
	text-decoration: underline;
	text-underline-offset: 2px;
}

body.single-article {
	background: #ffffff;
}

/* §15. Article share row (cg_share_buttons shortcode) */
.cgart-share {
	display: flex;
	align-items: center;
	gap: 8px;
	flex-wrap: wrap;
}
.cgart-share-label {
	font-family: Inter, sans-serif;
	font-size: 13px;
	font-weight: 600;
	color: #667085;
	margin-right: 2px;
}
.cgart-share-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 32px;
	height: 32px;
	border-radius: 50%;
	background: #f3f5f6;
	color: #475467;
	border: none;
	cursor: pointer;
	transition: background-color 150ms ease, color 150ms ease, transform 150ms ease;
}
.cgart-share-btn svg {
	width: 15px;
	height: 15px;
	fill: currentColor;
}
.cgart-share-btn:hover {
	background: #1b3fa0;
	color: #fff;
	transform: translateY(-1px);
}
.cgart-share-copy.is-copied {
	background: #12b76a;
	color: #fff;
}

.elementor-element-art0metaleft {
	flex: 1 1 auto;
	min-width: 0;
}
.elementor-element-art0metashare {
	flex: 0 0 auto;
}

@media (max-width: 599px) {
	.elementor-element-art0meta {
		flex-direction: column !important;
		align-items: flex-start !important;
	}
	.elementor-element-art0metashare {
		width: 100%;
	}
}

/* §16. Article body blockquote — editorial pull-quote style */
.elementor-element-art0content blockquote {
	margin: 28px 0;
	padding: 4px 0 4px 22px;
	border-left: 3px solid #1b3fa0;
	font-family: 'Playfair Display', Georgia, serif;
	font-size: 22px;
	line-height: 1.5;
	font-style: italic;
	color: #1d2939;
}
.elementor-element-art0content blockquote p {
	margin: 0;
}
.elementor-element-art0content blockquote cite {
	display: block;
	margin-top: 10px;
	font-family: Inter, sans-serif;
	font-size: 13px;
	font-style: normal;
	font-weight: 600;
	color: #667085;
}

/* ══════════════════════════════════════════════════════════════════════
   Top info bar (header template 315, container .cgtb) — site-wide.
   Slim navy strip in the site's mono spec-label style. Copy is edited in
   Elementor → Site Header → "Top bar — left / right" text widgets; each
   item is a <span class="cgtb-item"> or <a class="cgtb-item">, separated
   by <span class="cgtb-sep"></span>. Hidden on tablet/mobile (Elementor).
   ══════════════════════════════════════════════════════════════════════ */
.elementor-element.cgtb.e-con {
	background:
		linear-gradient(90deg, rgba(53, 99, 224, .16), transparent 30%, transparent 70%, rgba(53, 99, 224, .12)),
		#07111F !important;
	border-bottom: 1px solid rgba(157, 184, 255, .14) !important;
	--padding-top: 0px !important;
	--padding-bottom: 0px !important;
}
.cgtb > .e-con,
.cgtb > .e-con-inner > .e-con { --padding-top: 0px !important; --padding-bottom: 0px !important; min-height: 40px; }
:is(.cgtb-left, .cgtb-right),
:is(.cgtb-left, .cgtb-right) p {
	margin: 0 !important;
	font-family: "Geist Mono", ui-monospace, SFMono-Regular, Menlo, monospace !important;
	font-size: 12px !important;
	font-weight: 500 !important;
	line-height: 40px !important;
	letter-spacing: .14em !important;
	text-transform: uppercase !important;
	/* Light steel blue — readable on the navy bar without going white. */
	color: #BCCBE4 !important;
	white-space: nowrap;
}
:is(.cgtb-left, .cgtb-right) p { display: flex; align-items: center; }
.cgtb-right p { justify-content: flex-end; }
.cgtb-item { display: inline-flex; align-items: center; gap: 8px; color: inherit !important; text-decoration: none !important; }
/* Values (AGMA, phone numbers): pale blue tint, brightest in the bar. */
.cgtb-item strong { color: #DCE7FF; font-weight: 600; }
/* Labels (MEMBER COMPANY, TOLL-FREE, DIRECT): brand ice blue. */
.cgtb-k { color: #9DB8FF; }
a.cgtb-item { color: #DCE7FF !important; transition: color .25s ease; }
a.cgtb-item:hover { color: #9DB8FF !important; }
.cgtb-sep { display: inline-block; width: 1px; height: 12px; margin: 0 16px; background: rgba(157, 184, 255, .4); }
/* Live "status" dot before AGMA */
.cgtb-item--live::before {
	content: "";
	width: 6px;
	height: 6px;
	border-radius: 50%;
	background: #9DB8FF;
	box-shadow: 0 0 0 0 rgba(157, 184, 255, .6);
	animation: cgtbPulse 2.4s ease-out infinite;
}
.cgtb-item--live { gap: 0; }
.cgtb-item--live::before { margin-right: 10px; }
.cgtb-item--live strong { margin-right: 0; }
@keyframes cgtbPulse { 70% { box-shadow: 0 0 0 7px rgba(157, 184, 255, 0); } 100% { box-shadow: 0 0 0 0 rgba(157, 184, 255, 0); } }
/* Small icons */
.cgtb-item--phone::before,
.cgtb-item--mail::before {
	content: "";
	width: 12px;
	height: 12px;
	background: #9DB8FF;
	-webkit-mask: var(--cgtb-i) center / contain no-repeat;
	        mask: var(--cgtb-i) center / contain no-repeat;
}
.cgtb-item--phone { --cgtb-i: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M22 16.9v3a2 2 0 0 1-2.2 2 19.8 19.8 0 0 1-8.6-3.1 19.5 19.5 0 0 1-6-6A19.8 19.8 0 0 1 2.1 4.2 2 2 0 0 1 4.1 2h3a2 2 0 0 1 2 1.7c.1.9.4 1.8.7 2.7a2 2 0 0 1-.5 2.1L8 9.8a16 16 0 0 0 6 6l1.3-1.3a2 2 0 0 1 2.1-.4c.9.3 1.8.6 2.7.7a2 2 0 0 1 1.7 2z'/%3E%3C/svg%3E"); }
.cgtb-item--mail { --cgtb-i: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='2' y='4' width='20' height='16' rx='2'/%3E%3Cpath d='m22 7-10 6L2 7'/%3E%3C/svg%3E"); text-transform: none !important; letter-spacing: .04em; }
@media (max-width: 1200px) { .cgtb-sep { margin: 0 11px; } :is(.cgtb-left, .cgtb-right) p { letter-spacing: .1em !important; } }
@media (prefers-reduced-motion: reduce) { .cgtb-item--live::before { animation: none; } }

/* Downloads filter: per-category count pill ([cg_download_filters]) */
.cg-dl-filter__n { display: inline-grid; place-items: center; min-width: 22px; height: 22px; margin-left: 6px; padding: 0 6px; border-radius: 999px; background: #F1F4F8; font-size: 11.5px; font-weight: 600; line-height: 1; color: #5A6678; }
.cg-dl-filter.is-active .cg-dl-filter__n { background: rgba(255, 255, 255, .22); color: #fff; }
