/* ==========================================================================
   ECI — Homepage
   ========================================================================== */

@import url('https://fonts.googleapis.com/css2?family=Golos+Text:wght@400;500;600;700&family=Inter:wght@400;500&display=swap');

/* --------------------------------------------------------------------------
   Tokens
   -------------------------------------------------------------------------- */
:root {
  /* Colors */
  --color-black: #0c0c0c;
  --color-teal-dark: #0e343d;
  --color-panel: #133e48;
  --color-panel-dark: #161616; /* rotating-card InfoBlocks fill, 4185:3729 */
  --color-white: #ffffff;
  --color-border-light: #c8c8c8;
  --color-border-mid: #818181;
  --color-border-faint: rgba(255, 255, 255, 0.3);

  --color-brand-green: #40d39f;
  --color-brand-teal: #38abc1;
  --color-brand-blue: #2f84e2;
  --gradient-brand: linear-gradient(
    90deg,
    var(--color-brand-green) 0%,
    var(--color-brand-teal) 50%,
    var(--color-brand-blue) 100%
  );
  /* Figma "Orange Gradient" — the High-Voltage accent. get_variable_defs returns
     the style name with an empty value and get_design_context flattens it to its
     first stop (#ffde8e), so the stops below come from the emitted Tailwind
     from-/via-/to- triple on the eyebrow and kicker nodes of 1552:4406. */
  --gradient-orange: linear-gradient(90deg, #ffde8e 0%, #fba440 50%, #40d39f 100%);
  /* Figma "Control Box" and "Blue Gradient" — the remaining two Solutions accents,
     tokenised alongside the orange one when the Control Boxes and Engineering
     Components pages were built. Same caveat: both read tools flatten these to
     their first stop (#fb4097 / #a8ecff), so the mid and end stops are read off
     the emitted from-/via-/to- triples, not from a variable. */
  --gradient-control-box: linear-gradient(90deg, #fb4097 0%, #a750ff 50%, #64aeff 100%);
  --gradient-blue: linear-gradient(90deg, #a8ecff 0%, #49a0ff 51.442%, #40d39f 100%);
  /* Figma "Button Gradient 3" — the Button Set fill, redesigned 2026-08-01. The
     ramp is the brand colours as before, but the alpha profile inverted: it was a
     0.8 -> 0.6 -> 0.4 fade from left to right, and is now faint at BOTH ends and
     fully opaque at the centre. Measured off the isolated render of the master
     component (641:2505) and of the People instance (726:671): alpha 0.200 at
     x=0, 1.000 at 50%, 0.200 at x=max, linear between, MAE 0.65/255 — so the
     endpoints are exactly 0.2 and the peak exactly 1, not approximations.
     The MCP flattens this to `from-[rgba(64,211,159,0.2)] via-[#38abc1]
     to-[rgba(47,132,226,0.2)]`, which reads as a plain three-stop ramp and hides
     that the centre is opaque; do not copy that literally. */
  --gradient-button: linear-gradient(
    90deg,
    rgba(64, 211, 159, 0.2) 0%,
    rgba(56, 171, 193, 1) 50%,
    rgba(47, 132, 226, 0.2) 100%
  );
  /* The hover fill on Button Set Type=Primary Light (641:2481). Re-measured
     2026-09-17 off the isolated render: alpha 0.790 at x=0, 0.596 at 50%, 0.401
     at x=max — a LINEAR 0.8 -> 0.4 across the full width, so the three stops
     below are that same line sampled at its midpoint, not a separate via stop.
     Nothing in the build uses Primary Light; kept as the solved value.
     --gradient-button-soft (0.4/0.3/0.2) used to sit above this and was DELETED
     2026-09-17: it was inferred as "half of this ramp" and matches no Figma
     variant. Both Primary (641:2482) and Primary Light (641:2484) rest at
     0.2/1/0.2, so .button--soft rests at --gradient-button like every other. */
  --gradient-button-strong: linear-gradient(
    90deg,
    rgba(64, 211, 159, 0.8) 0%,
    rgba(56, 171, 193, 0.6) 50%,
    rgba(47, 132, 226, 0.4) 100%
  );

  /* Figma "Hover Gradient" — the fill on Block 1's Gradient variant (626:1285),
     which is the hover pair of its Default variant (626:1286). */
  --gradient-hover: linear-gradient(
    90deg,
    rgba(64, 211, 159, 0.9) 0%,
    rgba(56, 171, 193, 0.65) 6.25%,
    rgba(47, 132, 226, 0.4) 12.5%,
    rgba(42, 42, 42, 0) 58.654%
  );

  /* Figma "Line Gradient 1" — the stroke style on every bordered card. It is a
     gradient, not the flat #818181 the MCP reports as its fallback: horizontal,
     #818181 at ~93.5% opacity on both side edges, fading to fully transparent at
     the centre. Measured off isolated Figma renders of five different bordered
     nodes (334–885px wide) — same profile in all of them, linear to <2/255.
     Applied via `border-image: var(--gradient-line-1) 1`, which slices it so the
     left/right edges stay solid and only the top/bottom fade — matching Figma. */
  --gradient-line-1: linear-gradient(
    90deg,
    rgba(129, 129, 129, 0.935) 0%,
    rgba(129, 129, 129, 0) 50%,
    rgba(129, 129, 129, 0.935) 100%
  );

  /* Same profile in #ebebeb — used for the rotatingCards tab bar rule, which the
     MCP also reports as a flat `#ebebeb`. Fitted off the 1:1 isolated render of
     626:2373 (1px row, 1384px wide, alpha 255 throughout): each arm is linear to
     0.5/255, running 221 at both edges down to ~12 (the page black) at the centre.
     221 = #ebebeb at 93.5% over #0c0c0c, i.e. the exact edge alpha and 50% centre
     of --gradient-line-1, so this is that style in a second colour. MAE 2.3/255. */
  --gradient-line-2: linear-gradient(
    90deg,
    rgba(235, 235, 235, 0.935) 0%,
    rgba(235, 235, 235, 0) 50%,
    rgba(235, 235, 235, 0.935) 100%
  );

  /* And a third in #c8c8c8 — the stroke on the commitment section's value cards
     and on the divider's three rings, both of which the MCP reports as a flat
     `#c8c8c8` (only stop 0). Solved 2026-08-03 off `contentsOnly` renders of
     626:1062 and 626:1139. The card's top border ramps 0.937 at x=0 to 0.039 at
     the centre and back, linear to <0.01, while its left border holds 0.937 down
     the full height — the same profile as the other two.
     NOTE the render pipeline writes PREMULTIPLIED RGB, so raw pixels read ~189,
     not 200; divide by the alpha before judging the hex (189/0.937 = 202). Do not
     "correct" this to #bdbdbd. */
  --gradient-line-3: linear-gradient(
    90deg,
    rgba(200, 200, 200, 0.935) 0%,
    rgba(200, 200, 200, 0) 50%,
    rgba(200, 200, 200, 0.935) 100%
  );

  /* Figma "Background Gradient" style — deep teal to near-black.
     Stops only; each section sets its own direction. */
  --gradient-bg-stops: #0e343d 9.135%, #0c0c0c 91.827%;

  /* Type */
  --font-heading: 'Golos Text', sans-serif;
  --font-body: 'Inter', sans-serif;

  /* Font sizes - Utopia fluid scale (https://utopia.fyi/type/calculator/).
     Built 360px -> 1512px. Each step hits its exact Figma px at the 1512px
     design width (--figmaViewportWidth) and freezes there, so wider screens
     render type at the mockup size. Minimums come from one uniform ratio:
     min = 16 * (max/16)^(ln(26/16)/ln3), which pins 48px -> 26px and leaves every
     step at or below the 16px body base unscaled. The 26px anchor (not the
     gentler 32px first tried) is deliberate: a single straight line spends the
     whole 360-1140 band climbing through sizes the old fixed-px design never
     used there, so the anchor is the one knob that pulls that band down.
     Because type is fluid there are NO font-size media queries - do not add
     one; change the step or use a different --font-N instead.
     Steps at or below 16px are hand-set, not from the formula: the curve
     converges on 16 and inverts below it (14 would come back as a 15px min, so
     type would GROW on phones). 12 and 14 use the same ~94% shrink the 18 step
     does; 10 and 16 stay flat because there is nowhere safe below them. */
  --font-10: 0.625rem; /* 10px at every width */
  --font-12: clamp(0.6875rem, 0.668rem + 0.0868vw, 0.75rem); /* 11px -> 12px */
  --font-14: clamp(0.8125rem, 0.793rem + 0.0868vw, 0.875rem); /* 13px -> 14px */
  --font-16: 1rem; /* 16px at every width */
  --font-18: clamp(1.0625rem, 1.043rem + 0.0868vw, 1.125rem); /* 17px -> 18px */
  --font-20: clamp(1.125rem, 1.0859rem + 0.1736vw, 1.25rem); /* 18px -> 20px */
  --font-22: clamp(1.125rem, 1.0469rem + 0.3472vw, 1.375rem); /* 18px -> 22px */
  --font-24: clamp(1.1875rem, 1.0898rem + 0.434vw, 1.5rem); /* 19px -> 24px */
  --font-26: clamp(1.25rem, 1.1328rem + 0.5208vw, 1.625rem); /* 20px -> 26px */
  --font-28: clamp(1.25rem, 1.0938rem + 0.6944vw, 1.75rem); /* 20px -> 28px */
  --font-32: clamp(1.375rem, 1.1797rem + 0.8681vw, 2rem); /* 22px -> 32px */
  --font-34: clamp(1.375rem, 1.1406rem + 1.0417vw, 2.125rem); /* 22px -> 34px */
  --font-36: clamp(1.4375rem, 1.1836rem + 1.1285vw, 2.25rem); /* 23px -> 36px */
  --font-38: clamp(1.4375rem, 1.1445rem + 1.3021vw, 2.375rem); /* 23px -> 38px */
  --font-40: clamp(1.5rem, 1.1875rem + 1.3889vw, 2.5rem); /* 24px -> 40px */
  --font-48: clamp(1.625rem, 1.1953rem + 1.9097vw, 3rem); /* 26px -> 48px */
  --font-55: clamp(1.75rem, 1.2227rem + 2.3438vw, 3.4375rem); /* 28px -> 55px */
  --font-58: clamp(1.75rem, 1.1641rem + 2.6042vw, 3.625rem); /* 28px -> 58px */
  --font-64: clamp(1.875rem, 1.2109rem + 2.9514vw, 4rem); /* 30px -> 64px */
  --font-78: clamp(2rem, 1.1016rem + 3.9931vw, 4.875rem); /* 32px -> 78px */

  /* Spacing scale — one fluid scale, every axis. Each token is the clamp() the
     Figma formula gives for its base px value:
     clamp(N/2, (N / --figmaViewportWidth) * 100vw, N*2), divisor 1512.
     At the 1512 design width each resolves to exactly its base px, so the trailing
     comment is the mockup measurement it came from.
     There is deliberately no separate flat px scale: the formula has no axis term,
     so the old --space-N (px) / --space-N-v / --space-N-h were three names for the
     same two values. A value that must NOT scale — a corner radius, a hairline
     offset, a delta locked to a fixed-size sibling — is written as raw px at the
     point of use with a comment saying why. */
  --space-1: clamp(2px, 0.26vw, 5px); /* 4px */
  --space-2: clamp(4px, 0.53vw, 10.2px); /* 8px */
  --space-3: clamp(6px, 0.79vw, 15.2px); /* 12px */
  --space-4: clamp(8px, 1.06vw, 20.4px); /* 16px */
  --space-5: clamp(12px, 1.59vw, 30.5px); /* 24px */
  --space-6: clamp(16px, 2.12vw, 40.7px); /* 32px */
  --space-7: clamp(24px, 3.17vw, 60.9px); /* 48px */
  --space-8: clamp(32px, 4.23vw, 81.2px); /* 64px */
  --space-9: clamp(48px, 6.35vw, 121.9px); /* 96px */
  --space-10: clamp(60px, 7.94vw, 152.4px); /* 120px */

  /* Rem-floor spacing set. This project's list is authoritative and deliberately
     overrides the copy in the coding-practices skill: ordered ascending, the 6 and
     14 steps dropped (nothing used them), and 96 and 120 added at the top.
     Each is clamp(Npx, Yrem, Yrem) == max(Npx, Yrem): the px is a hard floor and
     the rem half takes over once the user raises their root font size (html is
     1rem, so the two are equal at the 16px browser default). Used for vertical
     spacing between text elements, between text and buttons, and for button
     padding on BOTH axes -- the one sanctioned exception to the
     horizontal-padding rule. Structural/layout gaps keep using --space-*. */
  --clamp-rem-4: clamp(4px, 0.25rem, 0.25rem); /* 4px */
  --clamp-rem-8: clamp(8px, 0.5rem, 0.5rem); /* 8px */
  --clamp-rem-12: clamp(12px, 0.75rem, 0.75rem); /* 12px */
  --clamp-rem-16: clamp(16px, 1rem, 1rem); /* 16px */
  --clamp-rem-24: clamp(24px, 1.5rem, 1.5rem); /* 24px */
  --clamp-rem-32: clamp(32px, 2rem, 2rem); /* 32px */
  --clamp-rem-48: clamp(48px, 3rem, 3rem); /* 48px */
  --clamp-rem-64: clamp(64px, 4rem, 4rem); /* 64px */
  --clamp-rem-96: clamp(96px, 6rem, 6rem); /* 96px */
  --clamp-rem-120: clamp(120px, 7.5rem, 7.5rem); /* 120px */

  --contentMax: 1920px;
  --figmaViewportWidth: 1512px;
  --gutter: clamp(32px, 4.23vw, 81.2px);
}

/* --------------------------------------------------------------------------
   Reset
   -------------------------------------------------------------------------- */
*,
*::before,
*::after {
  box-sizing: border-box;
  /* No blue flash on tap. Applied to every element by request. */
  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}

/* Carve-out: text the user typed has to stay selectable, or they cannot drag,
   correct, or copy their own input in Safari and most mobile browsers. */
input,
textarea,
[contenteditable] {
  -webkit-user-select: text;
  -moz-user-select: text;
  -ms-user-select: text;
  user-select: text;
}

html {
  font-size: 1rem;
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background: var(--color-black);
  color: var(--color-white);
  font-family: var(--font-body);
  font-size: inherit;
  line-height: 1.4;
  -webkit-font-smoothing: antialiased;
}

img {
  max-width: 100%;
  display: block;
}

/* Off-canvas <svg> that only carries <defs> (gradient ramps). Taken out of flow
   so the zero-size element cannot affect layout. */
.svgDefs {
  position: absolute;
}

a {
  color: inherit;
  text-decoration: none;
}

button {
  font: inherit;
  color: inherit;
  background: none;
  border: none;
  cursor: pointer;
}

ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

h1,
h2,
h3,
h4,
p {
  margin: 0;
}

/* TEXT-WRAP TRIAL 2026-09-24 (Sam): site-wide balanced paragraph wrapping, to
   avoid one-word last lines. May be rolled back: delete this rule. */
p {
  text-wrap: pretty;
}

.container {
  padding-inline: 0;
  width: 91.53%;
  max-width: calc(var(--contentMax) * 0.9153);
  margin-inline: auto;
}

@media (max-width: 900px) {
  :root {
    --gutter: 24px;
  }
}

/* --------------------------------------------------------------------------
   Typography helpers
   -------------------------------------------------------------------------- */
.eyebrow {
  font-family: var(--font-body);
  font-weight: 500;
  font-size: var(--font-16);
  line-height: 1.15; /* was 0.938; Figma 15px on 16px */
  letter-spacing: 1px;
  text-transform: uppercase;
  margin: 0 0 var(--clamp-rem-16);
}

/* LV-07: the section eyebrow orphaned its last word onto a second line. */
.moreSolutions .eyebrow {
  text-wrap: pretty;
}

/* Figma paints a text gradient across the *whole text node's* box and only then
   clips it to the glyphs, so a highlighted word shows just the slice of the ramp
   that happens to fall under it — "Success" in Customer Success is teal→blue,
   never green. CSS `background-clip: text` uses the styled element's own box, so
   hanging the gradient on the <span> replays the entire green→blue ramp inside
   that one word. Verified against Figma renders: fitting the ramp to the pixels
   of hero 298:850 recovers an 800px box (its text-node width, MAE 0.61/255), and
   commitment 626:1176 a 680px one.

   So the gradient lives on the block that corresponds to Figma's text node, and
   the span merely punches a transparent hole through it. .rotatingCards__kicker
   was always right for the same reason — it is a whole-element gradient on a
   block whose box already equals its Figma text node (712px). */
.gradientText {
  color: transparent;
}

/* The host. Its own text keeps an opaque colour and paints over the background;
   only the transparent span lets it through. Do not give these elements a
   background-color — background-clip: text would clip that to the glyphs too.

   `blockquote` joined this list 2026-09-18 for the Engineering partnership pull
   quote. A .gradientText span in a host NOT named here renders invisible, not
   unstyled — the span is already transparent, and without the host's background
   there is nothing behind it. That is the failure mode to look for. */
:is(h1, h2, h3, p, blockquote):has(> .gradientText) {
  background-image: var(--gradient-brand);
  -webkit-background-clip: text;
  background-clip: text;
}

/* Pin each host's paint box to its Figma text-node width (node id in the
   comment). Every one of these was shrink-wrapping inside a centred flex
   parent, which silently made the gradient box as narrow as the longest line.
   Widening a centred box does not move the text — these are gradient-only.

   The boxes are written in em, against each host's own font-size, so they are a
   measure rather than a desktop pixel count: at the Figma type size every value
   below resolves to exactly the px in its comment, and when the heading's type
   steps down at a breakpoint the box steps down with it, holding the same
   characters per line — and so the same ramp slice per word — instead of
   staying 800px wide under 38px type.

   Keep the width/max-width pair rather than folding it into min(em, 100%): a
   percentage inside min() counts as auto while the browser sizes the parent, so
   every one of these that sits in a shrink-to-fit parent collapses back to the
   longest line — .megatrends went 872 -> 647 when it was written that way. */
.hero__title {
  width: 13.79em;
  max-width: 100%;
} /* 298:850   800 @58 */
section.solutions .sectionHeading {
  width: 18.75em;
  max-width: 100%;
} /* 392:1182  900 @48 */
.commitment .sectionHeading {
  width: 14.17em;
  max-width: 100%;
} /* 626:1176  680 @48 */
section.megatrends .sectionHeading {
  width: 18.17em;
  max-width: 100%;
} /* 409:79    872 @48 */
.success .sectionHeading {
  width: 18.17em;
  max-width: 100%;
} /* 416:280   872 @48 */
.life__panel h2 {
  width: 12.08em;
  max-width: 100%;
} /* 417:839   580 @48 */

.sectionHeading {
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-48);
  line-height: 1.2;
  text-align: center;
  max-width: min(18.75em, 100%); /* 900px at 48px */
  margin-inline: auto;
}

.sectionLead {
  font-size: var(--font-16);
  line-height: 1.4;
  letter-spacing: 0.1px;
  text-align: center;
  max-width: min(50em, 100%); /* 800px at 16px */
  margin: var(--clamp-rem-48) auto;
}

/* --------------------------------------------------------------------------
   Buttons
   -------------------------------------------------------------------------- */
.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-4);
  max-width: max-content;
  /* Button padding uses the --clamp-rem set on both axes (the sanctioned
     exception to the horizontal-padding rule). Figma measures 17/25; the
     nearest steps are 16 and 24. */
  padding-block: var(--clamp-rem-16);
  padding-inline: var(--clamp-rem-24);
  /* Figma "Button Set" (641:2505) strokes this with the brand ramp, not the flat
     #40D39F the MCP reports — that hex is only the gradient's first stop, which is
     how get_design_context always flattens a gradient stroke. Read off an isolated
     render of the component: x=0 (63,210,158), centre (55,171,192), x=max
     (47,132,225), alpha 255 the whole way, i.e. --gradient-brand at full opacity.
     The 0.8/0.6/0.4 fill underneath measured 202/152/101 alpha, confirming the
     stroke is a separate, opaque paint rather than the fill showing through. */
  border: 1px solid transparent;
  border-image: var(--gradient-brand) 1;
  font-family: var(--font-body);
  font-weight: 500;
  font-size: var(--font-14);
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--color-white);
  white-space: nowrap;
  background: transparent;
  transition:
    opacity 0.2s ease,
    transform 0.2s ease;
}

.button:hover {
  opacity: 0.85;
}

.button svg {
  width: 18px;
  height: 10px;
  flex-shrink: 0;
}

.button--primary {
  background: var(--gradient-button);
}
.button--soft {
  background: var(--gradient-button);
}
.button--outline {
  background: transparent;
}

/* Every Button Set Type shares one hover motion — the arrow slides 8px right,
   as gap 16 → 24 against padding-right 25 → 17, so the button keeps its 252
   width and only the icon moves. Verified identical on Primary (641:2484 →
   641:2478), Secondary (641:2477 → 641:2480) and Primary Light (641:2482 →
   641:2481). The 1px #40d39f stroke never changes state on any of them.
   opacity resets the .button:hover dim above: all three Figma hovers add or
   intensify a fill, so inheriting a fade would fight the fill change.
   Transitions sit here rather than on the .button base rule so the shared,
   hand-set transition is left alone. Note that gradient background-image does
   not interpolate in Chrome or Safari — the fills below snap, only the arrow
   travels. */
.button--primary,
.button--soft,
.button--outline {
  transition:
    opacity 0.2s ease,
    transform 0.2s ease,
    gap 0.2s ease,
    padding-right 0.2s ease;
}

.button--primary:hover,
.button--soft:hover,
.button--outline:hover {
  gap: calc(var(--space-4) + 8px);
  padding-right: calc(var(--clamp-rem-24) - var(--clamp-rem-8));
  opacity: 1;
}

/* The fill each Type moves to on hover.
   Primary (Type=Primary): Button Gradient's 0.2-alpha endpoints go fully
   opaque — that ramp is --gradient-brand, already this button's border paint.
   Outline (Type=Secondary): a transparent default gains a fill on hover, and it
   is Button Gradient itself, i.e. exactly what .button--primary rests at.
   Soft: the two .button--soft instances are Type=Primary, not Primary Light —
   the ECI Family CTA 1264:2850 measures 0.2/1/0.2 at rest (MAE 1.3/255, against
   53.3 for the 0.8->0.4 profile) and carries a white label, where Primary Light
   would be #161616. So it takes Primary's hover. .button--soft is now identical
   to .button--primary in every paint. */
.button--primary:hover {
  background: var(--gradient-brand);
}
.button--outline:hover {
  background: var(--gradient-button);
}
.button--soft:hover {
  background: var(--gradient-brand);
}

.button--compact {
  /* Figma measures 13/17; nearest --clamp-rem steps are 12 and 16. */
  padding-block: var(--clamp-rem-12);
  padding-inline: var(--clamp-rem-16);
  font-size: var(--font-12);
}

/* The header Contact Us button. Its own modifier so the header instance can be
   painted without touching every other --compact button on the site. */
.button--siteHeaderContact {
  background: rgba(12, 12, 12, 0.2);
}

/* The same Contact Us, repeated at the foot of the mobile drawer (the bar's own
   button is hidden at 900px and below). Desktop keeps only the bar button. */
.siteNavigation__contact {
  display: none;
  background: rgba(12, 12, 12, 0.2);
}

/* nowrap is right on the canvas, where the longest label ("Explore Our
   Manufacturing Footprint") is 522px inside a 1512px frame. On a phone that one
   button is wider than the viewport and drags the whole page sideways, so below
   the card breakpoint the labels are allowed to wrap. */
@media (max-width: 600px) {
  .button {
    white-space: normal;
    max-width: 100%;
    text-align: center;
  }
}

.linkCallToAction {
  display: inline-flex;
  width: max-content;
  align-items: center;
  gap: var(--space-4);
  padding-bottom: clamp(4.5px, 0.6vw, 11.5px); /* was 9px */
  /* Figma "Button Set" (678:3161) strokes this with the brand ramp too, and unlike
     the label the stroke's paint box is the WHOLE row — 127px including the 16px
     gap and the 18px arrow — so the ramp only reaches blue under the arrow tip.
     Read off an isolated render: x=0 (63,210,159), x=64 (54,170,193), x=126
     (47,133,226), alpha 255 throughout = --gradient-brand at full opacity. The
     flat #40D39F the MCP reports is just the gradient's first stop. */
  border-bottom: 1px solid transparent;
  border-image: var(--gradient-brand) 1;
  font-family: var(--font-body);
  font-weight: 500;
  font-size: var(--font-14);
  line-height: 1.15; /* was 1.143; Figma 16px on 14px */
  letter-spacing: 1.2px;
  text-transform: uppercase;
  background: var(--gradient-brand);
  /* Figma hangs this gradient on the label text node alone (~197px wide, ramp
     running end to end), not on the row that also carries the 16px gap and the
     18px arrow. Painting across the whole row would stop the ramp ~84% short of
     blue, so shrink the paint area back to the label. */
  background-size: calc(100% - (var(--space-4) + 18px)) 100%;
  background-repeat: no-repeat;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.linkCallToAction svg {
  width: 18px;
  height: 10px;
}
.linkCallToAction svg path {
  stroke: var(--color-brand-teal);
}

/* Button Set State=Default (641:2483) → State=Hover (641:2475), Type=Subtle.
   The label string is byte-identical across the two variants, so the 136 → 144
   width really is the gap opening 16 → 24, not a longer placeholder. Two deltas:
   that 8px, and a 4px #40d39f glow at 0.3. No paint changes state — label ramp,
   underline and arrow stroke are all reported the same in both variants.
   background-size has to follow the gap: it masks the ramp back onto the label
   by subtracting the gap plus the 18px arrow, so 34 → 42 as the gap grows.
   Unlike .button, filter is used rather than box-shadow, because this element's
   painted box is the text and the underline, not a filled rectangle. */
/* HOVER GROWTH DISABLED 2026-09-17, same pass as .missionVisionCard. The gap
   widened this inline-flex link by 8px, so the element itself grew; the
   background-size went with it because it masks the ramp by subtracting the gap
   plus the 18px arrow, and is meaningless once the gap holds still. The glow
   stays. To restore, put all three lines back:
       transition: gap 0.2s ease, filter 0.2s ease;
       gap: calc(var(--space-4) + 8px);
       background-size: calc(100% - (var(--space-4) + 8px + 18px)) 100%;  */
.linkCallToAction {
  transition: filter 0.2s ease;
}
.linkCallToAction:hover {
  filter: drop-shadow(0 0 4px rgba(64, 211, 159, 0.3));
}

/* --------------------------------------------------------------------------
   Header / Nav
   -------------------------------------------------------------------------- */
.siteHeader {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-block: var(--space-5) 0;
  padding-inline: 0;
  width: 87.3%;
  max-width: calc(var(--contentMax) * 0.873);
  margin-inline: auto;
}

/* Every hero gives its direct children a z-index through an `X > *` rule
   (`.hero > *` at 2, `.careersHero > *` and two others at 1). The header landed
   on the same value as the hero's body element, so the body — later in the
   markup — painted over it, and the mega menu panel could not escape: the
   panel's z-index 60 only ranks it INSIDE .siteHeader's stacking context, and
   that context was the thing losing. Lifting the header is what puts the panel
   on top.

   Keyed on the `header` ELEMENT, not on `.hero`: 44 pages wrap the nav in
   `<header class="hero …">` but careers.html uses `<header class="careersHero">`,
   and a `.hero > .siteHeader` rule silently missed it. Every wrapper is a
   `<header>`, so `header > .siteHeader` covers all of them — and at (0,1,1) it
   outranks every `X > *` rule (0,1,0) regardless of source order, which a bare
   `.siteHeader` rule here would not. */
header > .siteHeader {
  z-index: 3;
}

/* Swapped 2026-09-17 from the 217x40 inline lockup (logo-eci-inverted.svg) to
   the footer's 177x53 stacked one, so both ends of the page carry the same mark.
   The box has to move with it: the <img> below is 100%/100%, so leaving 217x40
   here would have stretched a 3.34 ratio artwork across a 5.43 one. */
.siteHeader__logo {
  display: block;
  flex-shrink: 0;
  /* aspect-ratio rather than a height, per the coding-practices skill: nothing
     inside can change this box, and 274.4/83 is the artwork's own ratio (the 2026 no-mark header lockup), so the
     mark cannot stretch however the width is set.
     Width is fluid off the 1512 reference: 140 / 1512 * 100 = 9.26vw. Floor and
     ceiling deviate from the formula's N/2 and N*2 deliberately — 70px and 280px
     are both wrong for a lockup. 120px is the mobile size this replaces, 140px
     the desktop size asked for, so the mark grows between the two and stops, and
     one rule now covers both ends (the max-width:900 override is gone).
     A plain percentage was tried first: 304x91 at 900 against 116x35 at 1200 —
     one percentage cannot serve both sides of the breakpoint. */
  width: clamp(120px, 9.26vw, 140px);
  aspect-ratio: 274.4 / 83;
  overflow: hidden;
}
.siteHeader__logo img {
  width: 100%;
  height: 100%;
}

.siteNavigation {
  display: flex;
  gap: var(--space-6);
  align-items: center;
}

/* The nav no longer holds bare <a> children — since the mega menu landed every
   link inside it is a .megaMenu__link (14px) or a .megaMenu__trigger (16px),
   both of which carry their own size. A descendant rule here would outrank
   .megaMenu__link on specificity and silently push the panel links back to 16,
   which is exactly what it did before this was scoped to the direct child. */
.siteNavigation > a {
  font-size: var(--font-16);
  font-weight: 400;
}

.navigationToggle {
  display: none;
  flex-direction: column;
  /* Whole pixels on purpose: the fluid gap (2.5px at phone widths) put the
     three 2px bars on half-pixel rows, so they rasterised unevenly spaced. */
  gap: 5px;
  padding-block: 8px;
  padding-inline: 8px;
}
.navigationToggle span {
  width: 24px;
  height: 2px;
  background: var(--color-white);
}

/* Mobile drawer. Layout replicated from jcfmontreal.org's .menuContainerMobile:
   a left-edge slide-in at 75% / 300px running the full viewport height, rows at
   12px/24px and sub-lists indented 21px. Geometry and
   timings are theirs; every paint is ECI's.

   The drawer has no logo of its own. It starts at top 0 and clears the real
   .siteHeader__logo with padding-top, and that logo is lifted above the drawer
   below — so the header logo reads as the drawer's, exactly where JCF puts
   .menuContainerMobile__logo, without adding markup to 45 generated pages. */
@media (max-width: 1079px) { /* desktop menu from 1080 (Sam, 2026-09-24); was 900 */
  /* SITE-01: the bars stay 24x2 and the box stays visually the same; the 44px
     minimums only grow the hit area around them. */
  .navigationToggle {
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: 44px;
    min-height: 44px;
  }
  .siteHeader .button {
    display: none;
  }
  /* ...except the drawer's own Contact Us, under the last row. 24px matches the
     drawer rows' inline padding so it lines up with the links above. */
  .siteHeader .siteNavigation__contact {
    display: inline-flex;
    margin: var(--clamp-rem-24) 24px 0;
    /* One step down from --compact's 12/16 (Sam, 2026-09-24). */
    padding-block: var(--clamp-rem-8);
    padding-inline: var(--clamp-rem-12);
    font-size: var(--font-14);
    letter-spacing: 1px;
  }

  /* visibility, not display, carries the closed state: a display:none box cannot
     animate, and transform alone would leave the drawer in the a11y tree and
     focusable off-screen. The 0s visibility delay holds it visible for the whole
     slide-out, then drops it. */
  .siteNavigation {
    display: block;
    position: fixed;
    top: 0;
    left: 0;
    width: 75%;
    max-width: 300px;
    height: 100vh;
    height: 100dvh;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    padding-top: var(--clamp-rem-24);
    padding-bottom: var(--clamp-rem-24);
    /* Slightly transparent in mobile mode, asked for 2026-09-22. The shader
       sits behind at 0.94, so what shows through is mostly the dimmed page. */
    background: rgba(12, 12, 12, 0.92);
    box-shadow: 0.17em 0.25em 0.3em rgba(0, 0, 0, 0.2);
    z-index: 50;
    transform: translateX(-120%);
    visibility: hidden;
    transition: transform 0.5s ease-out, visibility 0s linear 0.5s;
  }

  .siteNavigation.isOpen {
    transform: translateX(0);
    visibility: visible;
    transition: transform 0.5s ease-out, visibility 0s;
  }

  /* 2026-09-22: the drawer now slides OVER the logo rather than under it, so the
     header is no longer raised as a whole — that lift is what made the logo read
     as pinned above the open drawer. The burger alone is lifted, out of the
     header's stacking context, so it still works as the X while the drawer
     (z-index 50) covers everything else. .siteHeader keeps its
     normal z-index 3, which is what holds the desktop mega-menu above the hero.

     Splitting the two needs the header to stop being a stacking context, not to
     be raised: .hero > * gives .siteHeader a position, so its z-index sealed both
     children in with it, and a position:fixed child does NOT escape that — only
     z-index:auto does. With the context gone, each child stacks against the root,
     so the burger's 60 clears the drawer's 50 while the unpositioned logo stays
     under it. Verified with elementFromPoint at the burger's centre, which is the
     only check that proves a real tap lands on it.

     Restoring the old behaviour = put z-index 60 back on .siteHeader.isDrawerOpen
     and on .siteHeader__logo, and return the drawer's padding-top to 96px. */
  /* The drawer's own lockup, emitted by tools/mega-menu.py. Sized to the
     header's mobile logo so the two read as one mark moving, not two. */
  .siteNavigation__logo {
    display: block;
    width: 120px;
    aspect-ratio: 274.4 / 83;
    margin-inline: var(--clamp-rem-24);
    margin-bottom: var(--clamp-rem-24);
    overflow: hidden;
  }

  .siteNavigation__logo img {
    width: 100%;
    height: 100%;
  }

  .siteHeader.isDrawerOpen {
    z-index: auto;
  }

  .siteHeader.isDrawerOpen .navigationToggle {
    position: relative;
    z-index: 60;
  }

  .navigationToggle span {
    transition: transform 0.15s ease, opacity 0.15s ease;
  }
  /* A true X. The bars used to be nudged by a fixed +-7px while the gap and
     padding between them are clamped against the viewport, so the two crossings
     never coincided — at 390 they sat 5px apart, and the error grew with width.
     Centring both absolutely on the button's middle makes the cross exact at
     every width, whatever the clamps resolve to. */
  .navigationToggle.isOpen span:nth-child(1),
  .navigationToggle.isOpen span:nth-child(3) {
    position: absolute;
    top: 50%;
    left: 50%;
    margin: 0;
  }
  .navigationToggle.isOpen span:nth-child(1) {
    transform: translate(-50%, -50%) rotate(45deg);
  }
  .navigationToggle.isOpen span:nth-child(2) {
    opacity: 0;
  }
  .navigationToggle.isOpen span:nth-child(3) {
    transform: translate(-50%, -50%) rotate(-45deg);
  }
}

/* The shader is created by js/script.js rather than shipped in the markup, so
   the 45 generated pages and site-header.php did not have to be rewritten for
   one empty div. JCF paints theirs white at 0.94; ours is the page black. */
.navigationShader {
  position: fixed;
  inset: 0;
  /* 0.94 was near-opaque, so the drawer's own 0.92 had only shader behind it and
     read solid. At 0.55 the page shows through both. Taste value — raise it
     toward 0.8 to dim harder, lower it to show more of the page. */
  background: rgba(12, 12, 12, 0.55);
  z-index: 40;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.3s linear, visibility 0s linear 0.3s;
}

.navigationShader.isOpen {
  opacity: 1;
  visibility: visible;
  transition: opacity 0.3s linear, visibility 0s;
}

@media (min-width: 1080px) { /* desktop menu from 1080; was 901 */
  .navigationShader {
    display: none;
  }

  /* The drawer lockup is mobile-only; above the breakpoint the nav is the bar
     and the header carries the mark. Without this it renders inside the menu
     row at full 177x53. */
  .siteNavigation__logo {
    display: none;
  }
}

/* --------------------------------------------------------------------------
   Mega menu — Figma "Top Menu Items" 2019:7418
   -------------------------------------------------------------------------- */

/* The five triggers. Figma ships three variants per title: Default (white 16/20),
   Hover (brand ramp on the label) and Click (same ramp plus a 1px #40d39f rule
   under the 8/6 padding box, with the panel dropped below). The ramp is painted
   across the whole text node, so it hangs on the button itself, not a span. */
.megaMenu {
  display: flex;
  gap: var(--space-6);
  align-items: center;
  list-style: none;
  margin: 0;
  padding: 0;
}

.megaMenu__item {
  position: relative;
}

.megaMenu__trigger {
  display: block;
  font-family: inherit;
  font-size: var(--font-16);
  font-weight: 400;
  line-height: 1.25; /* Figma 20 on 16 */
  color: var(--color-white);
  background: none;
  border: 0;
  border-bottom: 1px solid transparent;
  padding-block: 6px;
  padding-inline: var(--clamp-rem-8);
  cursor: pointer;
  white-space: nowrap;
  transition: color 0.2s ease, border-color 0.2s ease;
}

/* Hover and Click both take the ramp. background-clip paints it, so the colour
   has to go transparent at the same time — see .gradientText for why this sits
   on the element whose box equals the Figma text node. */
.megaMenu__trigger:hover,
.megaMenu__trigger:focus-visible,
.megaMenu__trigger[aria-expanded='true'] {
  background-image: var(--gradient-brand);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

/* Click variant 2019:7551 — the rule is the flat #40d39f, not the ramp.
   Commented out 2026-09-22 at the user's request; uncomment to restore.
.megaMenu__trigger[aria-expanded='true'] {
  border-bottom-color: var(--color-brand-green);
} */

/* The dropped panel, 2019:7554. Figma gives it rgba(12,12,12,0.8), 48 padding,
   a 48 gap between the link row and the spotlight row, min-width 360 and a
   0 16px 32px rgba(0,0,0,0.08) shadow. Markets is the only one with a fixed
   width (920); the rest shrink-wrap off min-width. */
.megaMenu__panel {
  position: absolute;
  top: calc(100% + var(--clamp-rem-16));
  left: 50%;
  transform: translateX(-50%);
  z-index: 60;
  display: flex;
  flex-direction: column;
  gap: var(--space-7);
  width: max-content;
  min-width: 360px;
  max-width: calc(100vw - (var(--gutter) * 2));
  /* Padding returned to Figma's 48 (--space-7) on 2026-09-22.
     The panel is a GLASS material in Figma, radius 18 — an effect no read tool
     returns (get_design_context, get_metadata and get_screenshot all drop the
     effects array), so it was missing here until it was read via use_figma on
     2026-09-22. Glass is the translucent fill PLUS the backdrop blur: the fill
     alone was tried on 2026-09-17 and let the hero read straight through, which
     is why it had been made solid. The blur is what makes 0.8 legible. */
  padding: var(--space-7);
  background: rgba(12, 12, 12, 0.8);
  -webkit-backdrop-filter: blur(18px);
  backdrop-filter: blur(18px);
  box-shadow: 0 16px 32px rgba(0, 0, 0, 0.08);
}

.megaMenu__panel[hidden] {
  display: none;
}

/* The panels open on hover, and Figma's 16px gap between the trigger and the
   panel is dead space the pointer would cross — leaving the <li> and closing the
   panel before it arrives. This bridges the gap with a transparent strip that
   belongs to the panel, so the pointer stays inside the item the whole way. It
   is invisible and sits behind the panel's own box, so it changes nothing
   visually. Only where hover is the opener: under 900px the panels are inline
   accordions with no gap to cross. */
@media (hover: hover) and (min-width: 1080px) { /* was 901 */
  .megaMenu__panel::before {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    bottom: 100%;
    height: var(--clamp-rem-16);
  }
}

/* Edge items would push the centred panel off-screen, so they anchor to their
   own side instead. Markets is the middle trigger and stays centred. */
.megaMenu__item:first-child .megaMenu__panel {
  left: 0;
  transform: none;
}
.megaMenu__item:last-child .megaMenu__panel {
  left: auto;
  right: 0;
  transform: none;
}

.megaMenu__panel--markets {
  width: 920px;
}

.megaMenu__columns {
  display: flex;
  gap: var(--space-6);
  align-items: flex-start;
}

.megaMenu__column {
  display: flex;
  flex: 1 0 0;
  flex-direction: column;
  gap: var(--clamp-rem-24);
  min-width: 0;
}

/* Eyebrow 11/1.5px uppercase on the brand ramp, with a 32x1 ramp rule 6px under
   it (2019:7557). The rule is a pseudo-element so the label keeps a box equal to
   its Figma text node — background-clip: text on the label does not reach the
   pseudo-element's own background. */
.megaMenu__label {
  font-family: var(--font-body);
  font-size: 11px;
  font-weight: 600;
  line-height: normal;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  margin: 0;
  background-image: var(--gradient-brand);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.megaMenu__label::after {
  content: '';
  display: block;
  width: 32px;
  height: 1px;
  margin-top: clamp(3px, 0.397vw, 12px); /* Figma 6 */
  background-image: var(--gradient-brand);
}

.megaMenu__links {
  display: flex;
  flex-direction: column;
  gap: var(--clamp-rem-16);
  list-style: none;
  margin: 0;
  padding: 0;
}

.megaMenu__link {
  font-size: var(--font-14);
  font-weight: 500;
  line-height: normal;
  color: var(--color-white);
  text-decoration: none;
  transition: color 0.2s ease;
}

.megaMenu__link:hover,
.megaMenu__link:focus-visible {
  color: var(--color-brand-green);
}

/* "See All" reuses the arrow + gap shape of .linkCallToAction but at the panel's
   own 14px white weight, so it is its own modifier rather than that class. */
.megaMenu__link--seeAll {
  display: inline-flex;
  gap: var(--clamp-rem-8);
  align-items: center;
}

.megaMenu__link--seeAll svg {
  width: 18px;
  height: 10px;
  flex-shrink: 0;
}
.megaMenu__link--seeAll svg path {
  stroke: currentColor;
}

/* Not in the markup since 2026-09-22 — the spotlight tiles were removed from
   every mega menu panel. Rules kept (here and in the max-width block) so they
   can be brought back by restoring the markup. */
.megaMenu__spotlight {
  display: flex;
  flex-direction: column;
  gap: var(--clamp-rem-24);
}

.megaMenu__tiles {
  display: flex;
  gap: var(--space-5);
  align-items: stretch;
  list-style: none;
  margin: 0;
  padding: 0;
}

.megaMenu__tileItem {
  display: flex;
  flex: 1 0 0;
  min-width: 0;
}

/* 2019:7595 / 2019:7601 — 75 tall, photo cover, a right-to-left #161616 scrim
   0.8 -> 0, and the label chip bottom-left on rgba(12,12,12,0.65). The two
   Figma tiles disagree on padding (8 vs 12) and on the glow (a 6px blue
   drop-shadow vs a 12px green box-shadow); the 8 and the green glow are taken,
   since the single-tile panels all use that pair. */
.megaMenu__tile {
  position: relative;
  display: flex;
  flex: 1 0 0;
  align-items: flex-end;
  min-width: 0;
  height: auto;
  min-height: 75px;
  aspect-ratio: 3.5214;
  padding: var(--clamp-rem-8);
  overflow: hidden;
  text-decoration: none;
  transition: box-shadow 0.2s ease;
}

.megaMenu__tile:hover,
.megaMenu__tile:focus-visible {
  box-shadow: 0 0 12px rgba(64, 211, 159, 0.5);
}

.megaMenu__tileBackground {
  position: absolute;
  inset: 0;
  background-position: center;
  background-size: cover;
  background-repeat: no-repeat;
}

.megaMenu__tileBackground::after {
  content: '';
  position: absolute;
  inset: 0;
  background-image: linear-gradient(
    270deg,
    rgba(22, 22, 22, 0) 0%,
    rgba(22, 22, 22, 0.8) 100%
  );
}

.megaMenu__tile--dataCenters .megaMenu__tileBackground {
  background-image: url('../assets/images/success-data-centers.jpg');
}
.megaMenu__tile--hvac .megaMenu__tileBackground {
  background-image: url('../assets/images/success-hvac-systems.jpg');
}

.megaMenu__tileLabel {
  position: relative;
  font-family: var(--font-body);
  font-size: var(--font-14);
  font-weight: 400;
  line-height: 1.4;
  text-transform: capitalize;
  color: var(--color-white);
  background: rgba(12, 12, 12, 0.65);
  padding-block: var(--clamp-rem-8);
  padding-inline: var(--clamp-rem-16);
}

/* Under the mobile toggle the nav is already a stacked drawer, so the panels
   drop out of their absolute anchor and run as plain accordions in flow. */
/* Inside the drawer the mega menu becomes JCF's flat list: every row is a
   full-width block at 12px/24px, and an open panel is a sub-list indented 21px
   under its trigger. The gaps go to zero — the padding on each row is what
   spaces them, which is what makes the column read as one list rather than five
   stacked components. */
@media (max-width: 1079px) { /* drawer menu below 1080; was 900 */
  .megaMenu {
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    width: 100%;
  }

  .megaMenu__item {
    width: 100%;
  }

  .megaMenu__trigger {
    display: block;
    width: 100%;
    padding: 12px 24px;
    text-align: left;
    line-height: 1.35;
  }

  .megaMenu__panel,
  .megaMenu__item:first-child .megaMenu__panel,
  .megaMenu__item:last-child .megaMenu__panel {
    position: static;
    transform: none;
    width: 100%;
    min-width: 0;
    max-width: none;
    padding: 0 0 8px 21px;
    background: none;
    box-shadow: none;
  }

  .megaMenu__panel--markets {
    width: 100%;
  }

  .megaMenu__columns {
    flex-direction: column;
    gap: 0;
  }

  .megaMenu__label {
    padding: 12px 24px 4px;
  }

  .megaMenu__links {
    gap: 0;
  }

  .megaMenu__link {
    display: block;
    width: 100%;
    padding: 12px 24px;
    line-height: 1.35;
  }

  /* The spotlight is two photo tiles sized for a full-width desktop panel; at
     300px they would be the tallest thing in the drawer. Hidden here only —
     the desktop panel is untouched. */
  .megaMenu__spotlight {
    display: none;
  }
}

/* --------------------------------------------------------------------------
   Hero
   -------------------------------------------------------------------------- */
.hero {
  position: relative;
  min-height: 900px;
  display: flex;
  flex-direction: column;
  /* Swapped 2026-08-25. The hero fill on 298:787 is no longer the wiring-assembly
     photo — Figma now holds an effectively flat black 1920x1080 plate there, and
     the composited render is black to match. `wiring-assembly.png` is kept in
     assets/ so this is a one-line revert if the photo was replaced by accident.
     The scrim below is therefore a no-op over this plate; its solved values are
     left intact for the same reason. */
  /* The plate stays as the paint under the video — it is what shows if the
     video is blocked, still loading, or suppressed for reduced motion and the
     poster has not decoded yet. */
  background: url('../assets/images/hero-plate.png') center / cover no-repeat;
}

/* Home hero fills the visible screen (Sam, 2026-09-24). fit-content replaces
   the 900px floor above, so tall content still grows the box. */
.hero--home {
  height: 100svh;
  min-height: fit-content;
}

/* Background video, behind the scrim. Not an <img> on a div like the other
   background treatments, because this is real video — but it follows the same
   rule: a dedicated element, absolutely positioned, nothing else inside it.
   Written as `.hero > .hero__video` deliberately: `.hero > *` below sets
   position: relative and z-index: 1 on every child, and at equal specificity it
   would win on source order, leaving the video in flow at viewport height and
   stacked above the scrim. The child combinator takes it to (0,2,0).
   width/height are required, not redundant with inset: for an absolutely
   positioned REPLACED element, width/height:auto resolve to the intrinsic size
   (1920x1080 here) and the insets only position it — so inset alone leaves the
   video at its native size overflowing the hero. */
.hero > .hero__video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: 0;
  pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
  .hero > .hero__video {
    display: none;
  }
  /* Still show the scene, just not moving — the flat plate would otherwise be
     all that is left. */
  .hero {
    background-image: url('../assets/videos/hero-home-poster.jpg');
  }
}

/* Scrim fill on the Hero frame. get_design_context drops frame-level fills, so
   these values were solved by regressing Figma's composited render against the
   source photo: vertical, overlay #0a0a0a, knee at 70%. Reproduces the render
   to a mean error of 0.5/255. */
.hero::before {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(
    180deg,
    rgba(10, 10, 10, 0.36) 0%,
    rgba(10, 10, 10, 0.61) 70%,
    rgba(10, 10, 10, 0.99) 100%
  );
  /* Above .hero__video (z-index 0), below the content (z-index 2). Was 0, which
     tied with the video — and at equal z-index tree order wins, so the video,
     being a later child than this pseudo-element, painted straight over it. */
  z-index: 1;
}

/* Top scrim. NOT from the Figma design — added 2026-09-18 at the user's request,
   to darken the band the header sits in. Deliberately left at its author's
   values; see the two interactions noted below before changing it. */
.hero::after {
  content: "";
  position: absolute;
  width: 100%;
  height: 25%;
  min-height: 100px;
  top: 0;
  background: linear-gradient(180deg, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));
  opacity: 1;
}

/* Extra shading over the video only, under the text. The ramp above was solved
   against the original still photograph; moving footage sits brighter and more
   restless behind the headline, so the video hero takes a flat tint on top of
   it. Scoped by :has so every other hero keeps the solved treatment alone.
   Tune this one value to taste — it is deliberately a single flat alpha rather
   than a second ramp, so it cannot fight the solved one. */
.hero:has(> .hero__video)::after {
  content: '';
  position: absolute;
  inset: 0;
  /* Both of these exist only because .hero::after above now sets width/height.
     Two rules target the same pseudo-element and the cascade resolves PER
     PROPERTY, so this rule was winning `background` while inheriting that rule's
     `height: 25%` — which painted the flat tint as a hard-edged band across the
     top quarter of the homepage hero instead of the full bleed it is meant to
     be. Restating the geometry here pins it back. */
  width: 100%;
  height: 100%;
  background: rgba(10, 10, 10, 0.4);
  z-index: 1;
  pointer-events: none;
}

.hero > * {
  position: relative;
  /* 2, not 1: the scrim and the video tint sit at 1, above the video at 0. */
  z-index: 2;
}

.hero__body {
  flex: 1;
  display: flex;
  align-items: center;
  padding-block: var(--space-9);
  padding-inline: 0;
  width: 87.3%;
  max-width: calc(var(--contentMax) * 0.873);
  margin-inline: auto;
}

.hero__content {
  max-width: min(800px, 100%);
}

.hero__title {
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-58);
  line-height: 1.15; /* was 1.1 */
  text-transform: capitalize;
  margin-bottom: var(--clamp-rem-32);
}

/* 298:850 reads "Global Leader / in Complex Electrical Distribution Systems" —
   the lowercase "in" is deliberate, so this hero carries its own casing and opts
   out of the capitalize above. The other pages' h1s are still sentence-case in
   source and do rely on it. */
.hero__title--exactCase {
  text-transform: none;
}

.hero__subtitle {
  font-size: var(--font-20);
  line-height: 1.4;
  letter-spacing: 0.1px;
  margin-bottom: var(--clamp-rem-32);
  max-width: min(640px, 100%);
}

.hero__actions {
  display: flex;
  row-gap: var(--space-5);
  column-gap: var(--space-5);
  flex-wrap: wrap;
}

/* Company > About hero — Figma "Company - About" / 787:351. Structurally the same
   frame as the homepage hero (96px inset, 24px top on the header row, 96px between
   the header and the body, body centred in the leftover), so it reuses .hero and
   only overrides what the design actually changes: a 634px frame instead of 900,
   its own photo, and a 600px measure instead of 800.
   The scrim folds two Figma layers into one ramp: the photo sits at 80% opacity on
   a #0c0c0c fill (a flat 20% veil), and a `to-b` gradient of #0c0c0c at 0.2 / 0.5
   @69.231% / 1.0 sits over it. Compositing those gives 0.36 / 0.6 / 1.0, which is
   what is written below. Checked against the node render with the photo placed
   center/cover: 2.9/255 on 8x8 block averages, against 2.5 for a free three-stop
   fit — i.e. the declared numbers are as good as anything solved for, and the
   residual is resampling noise from a 1173px source upscaled to 1512. */
/* Re-read 2026-08-25 off the rebuilt hero `1373:1206` (was `787:351`). Three
   things changed: the photo is now a real ECI shot rather than the watermarked
   comp, the measure widened 600 -> 760 (`1373:1261`), and the scrim gained a
   horizontal arm — the same pair the People hero carries, i.e. fully opaque at
   x=0 clearing at 59.615%, over a vertical 0 -> 0.5 @69.231% -> 1. Read from the
   frame, not fitted. */
.hero--about {
  min-height: fit-content;
  height: 70.4444svh; /* was min-height: 634px, the Figma frame on a 900px viewport */
  background-image: url('../assets/images/about-hero.jpg');
}

.hero--about::before {
  background:
    linear-gradient(90deg, #0c0c0c 0%, rgba(12, 12, 12, 0) 59.615%),
    linear-gradient(180deg, rgba(12, 12, 12, 0) 0%, rgba(12, 12, 12, 0.5) 69.231%, #0c0c0c 100%);
}

.hero--about .hero__content {
  max-width: min(760px, 100%);
}

/* 1373:1261 is 760 wide, so that — not the homepage's 800 — is the box the
   "About" text gradient is painted across. See the gradient-host widths near the
   top. */
.hero--about .hero__title {
  width: 13.1em;
  max-width: 100%;
} /* 760 @58 */

.hero--about .hero__subtitle {
  max-width: 100%;
  margin-bottom: 0;
}

/* --------------------------------------------------------------------------
   Company > Global Locations hero  (Figma "Company - Global Locations" / 909:4103)
   -------------------------------------------------------------------------- */
/* Structurally identical to the About hero — same 96px inset, 24px header top,
   96px header-to-body gap, 600px measure — so it inherits .hero and only swaps
   the photo, the copy and the scrim.
   The scrim here is one layer richer than About's: the photo again sits at 80%
   on a #0c0c0c fill (a flat 20% veil, folded into the vertical ramp below), but
   Figma also paints a left-to-right #0c0c0c 0.8 -> 0 gradient over it so the
   copy column stays legible against the bright globe. Kept as two stacked
   layers rather than composited, since they run on different axes. */
.hero--locations {
  min-height: fit-content;
  height: 70.4444svh; /* was min-height: 634px, the Figma frame on a 900px viewport */
  background-image: url('../assets/images/global-locations-bg.png');
}

/* Re-read 2026-08-25 off `909:4103`. The scrim tightened: the horizontal arm is
   now fully opaque at x=0 and clears at 60.096% (was 0.8 fading across the whole
   width), and the vertical arm starts fully transparent (was 0.36). Same shape as
   the About and People heroes, which clear at 59.615% — this one is 60.096%.
   Read from the frame, not fitted. */
.hero--locations::before {
  background:
    linear-gradient(90deg, #0c0c0c 0%, rgba(12, 12, 12, 0) 60.096%),
    linear-gradient(180deg, rgba(12, 12, 12, 0) 0%, rgba(12, 12, 12, 0.5) 69.231%, #0c0c0c 100%);
}

.hero--locations .hero__content {
  max-width: min(760px, 100%);
}

/* Same 760-wide gradient host as About: the "Global scale," span is painted
   across the 760px text box, not the viewport. Widened from 600 on 2026-08-25
   along with the rest of the hero (1243:2145). */
.hero--locations .hero__title {
  width: 13.1em;
  max-width: 100%;
} /* 760 @58 */

.hero--locations .hero__subtitle {
  max-width: 100%;
  margin-bottom: 0;
}

/* --------------------------------------------------------------------------
   People hero  (Figma "People - Main" / 1373:1079)
   -------------------------------------------------------------------------- */
/* Added 2026-08-25 — this hero had no rule at all, so it was rendering with no
   photo. Figma stacks a #0c0c0c fill, the photo at full opacity, then the two
   ramps below (1373:1079). Unlike About/Locations/Careers the vertical ramp
   starts fully transparent, and the horizontal one starts fully OPAQUE and
   clears at 59.615% — a harder left-to-right wipe, which is what keeps the
   760px measure legible over a bright office shot. Values read from the frame,
   not fitted. */
.hero--people {
  min-height: fit-content;
  height: 70.4444svh; /* was min-height: 634px, the Figma frame on a 900px viewport */
  background-image: url('../assets/images/people-hero.jpg');
}

.hero--people::before {
  background:
    linear-gradient(90deg, #0c0c0c 0%, rgba(12, 12, 12, 0) 59.615%),
    linear-gradient(180deg, rgba(12, 12, 12, 0) 0%, rgba(12, 12, 12, 0.5) 69.231%, #0c0c0c 100%);
}

/* Container 1373:1134 */
.hero--people .hero__content {
  max-width: min(760px, 100%);
}

/* Title pill 1243:2175 — 48/9 padding on a horizontal ramp that is transparent at
   both ends and #38abc1 at 48% in the middle.
   CORRECTED 2026-09-15. The earlier note here said the top and bottom borders were
   rgba(64,211,159,0), i.e. nothing to draw. That was the MCP flattening a gradient
   stroke to its stop-0 — the classic ramp-suspect. Measured from a contentsOnly
   render of 1543:2919 (187x34): the top and bottom rows peak at alpha 254 where the
   fill only reaches 121, and solving border = (total - fill) / (1 - fill) across the
   width gives 0.25 / 0.49 / 0.99 at 12.5% / 25% / 50% — a clean 0 -> 1 -> 0 alpha
   ramp on the same brand stops. So the stroke is --gradient-brand with transparent
   ends, at FULL alpha in the middle, while the fill sits at 0.48.
   Rejected near-miss: rgba(56,171,193,0.48) on the border too (the fill's own ramp),
   which lands the centre row at 149 rather than the measured 254.
   border-image ignores border-radius, but this pill is square, so it is safe here. */
.hero__pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: clamp(4.5px, 0.6vw, 11.5px) var(--space-7); /* was 9px */
  margin: 0 0 var(--clamp-rem-24);
  border-style: solid;
  border-width: 1px 0;
  border-image: linear-gradient(
      90deg,
      rgba(64, 211, 159, 0) 0%,
      #38abc1 50%,
      rgba(47, 132, 226, 0) 100%
    )
    1;
  background: linear-gradient(
    90deg,
    rgba(64, 211, 159, 0) 0%,
    rgba(56, 171, 193, 0.48) 50%,
    rgba(47, 132, 226, 0) 100%
  );
  font-family: var(--font-body);
  font-weight: 500;
  font-size: var(--font-14);
  line-height: 1.15; /* was 1.143; Figma 16px on 14px */
  letter-spacing: 1.2px;
  text-transform: uppercase;
  text-align: center;
}

/* Breadcrumb variant. The pill becomes an <a> pointing at its parent section,
   so it only resets the anchor defaults — everything else is inherited from
   .hero__pill and the rendering is identical. */
.hero__pill--breadcrumb {
  color: inherit;
  text-decoration: none;
  cursor: pointer;
}

/* --------------------------------------------------------------------------
   About > Mission & Vision  (Figma InfoBlocks 787:412 + Frame 348 881:2671)
   -------------------------------------------------------------------------- */
/* 787:412 — flat #0c0c0c band, 120px block / 64px inline padding, 900px measure.
   Its internal rhythm is heading -> lede = 24px, not the 48px used by the
   homepage section intros. */
.missionVisionIntro {
  background: var(--color-black);
  padding-block: var(--space-10);
  padding-inline: 0;
  width: 91.53%;
  max-width: calc(var(--contentMax) * 0.9153);
  margin-inline: auto;
}

.missionVisionIntro__block {
  max-width: min(900px, 100%);
  margin-inline: auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-5);
}

.missionVisionIntro .sectionHeading {
  width: 18.75em;
  max-width: 100%;
} /* 787:415 box, 900 @48 */

/* .missionVisionIntro__lead removed 2026-08-25. Figma dropped that lede from both
   nodes that carried it — About's 787:412 and this page's 948:828 — so no page
   uses the class any more. The heading rule above is all that is left of the block. */

/* 881:2671 — two 580x650 "Block 4" slots, 32px apart, inside 160px side gutters
   and 96px of bottom padding. No fill of its own; the page black shows through. */
.missionVisionCards {
  display: flex;
  justify-content: center;
  align-items: flex-start;
  gap: var(--space-6);
  padding-block: 0 var(--space-9);
  padding-inline: 0;
  width: 78.84%;
  max-width: calc(var(--contentMax) * 0.7884);
  margin-inline: auto;
  background: var(--color-black);
}

/* The slot is Figma's 12px-padded wrapper around each card. */
.missionVisionCards__slot {
  flex: 1 0 0;
  min-width: 0;
  min-height: 650px;
  padding: var(--space-3) var(--space-3);
  display: flex;
}

.missionVisionCard {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-7);
  padding: var(--space-8) var(--space-8);
  background: var(--color-black);
  /* #818181 here is the Line Gradient 1 style flattened to its first stop by the
     MCP, not a flat border — same as every other card in this file. */
  border: 1px solid var(--color-border-mid);
  border-image: var(--gradient-line-1) 1;
}

/* Figma tightens only the Vision card's side padding to 48px (its copy is
   longer) and top-aligns its content — matched rather than normalised. */
.missionVisionCard--vision {
  padding-inline: var(--space-7);
  justify-content: flex-start;
}

/* Block 4 Default (Green 881:2753 / Blue 909:4029) → Hover (881:2754 / 909:4037).
   THE BLOCK 4 INSTANCE IS .missionVisionCards__slot, not .missionVisionCard — Frame 348 holds two
   instances and each is a whole 650 slot. So the 12px is the instance's own
   padding, and the hover state simply zeroes it; .missionVisionCard is flex: 1 inside a flex
   slot, so it fills the 650 on its own. Hover therefore triggers on the slot, which
   is also the real hit area — the 12px band belongs to the component.
   get_motion_context returns no nodes for either hover variant, so Figma models
   this as a plain variant swap; the timing here is authored, not read off the file.
   Three deltas:
   1. the instance's padding 12 → 0, which grows the card from 626 to the full 650;
   2. the card's side padding 64 → 75, absorbing 11 of the 12 each side, so the
      content column only widens ~2px and the copy does not reflow;
   3. the 1px Line Gradient 1 border gives way to an 18px glow in the block's own
      accent: #40d39f on Mission (Green), #2f84e2 on Vision (Blue).
   The border is zeroed to transparent rather than dropped, so the 1px it occupies
   stays in the box and the content holds still. Nothing inside changes between the
   variants — no element appears, and the ring, eyebrow, copy and CTA are identical.
   All three Block colours behave identically and differ only in the glow, so the
   colour is carried on --mv-glow and every Block 4 instance gets the hover: Green
   on About's Mission, Blue on its Vision, Yellow on the .moreSolutions pair that
   four other pages share these classes with. */
.missionVisionCards__slot {
  --mv-glow: var(--color-brand-green);
}

.missionVisionCard--vision {
  --mv-glow: var(--color-brand-blue);
}

/* Yellow (1355:2488 → 1355:2509). Not bound to any Figma variable and not one of
   the file's amber stops (#ffde8e / #fba440) — a raw rgba literal, alpha included. */
.moreSolutions__cards .missionVisionCards__slot {
  --mv-glow: rgba(253, 184, 19, 0.8);
}

.missionVisionCard {
  /* margin and padding-inline dropped from this list 2026-09-17 with the growth
     itself — see the hover rule below. Restore both lines to bring it back. */
  /* border-color no longer transitions (2026-09-24): hover drops the gradient
     border-image instantly, so fading the colour showed a flat grey frame for
     0.2s before it cleared. */
  transition: box-shadow 0.2s ease;
}

/* HOVER GROWTH DISABLED 2026-09-17 — asked for, temporary ("for now"). The card
   used to grow on hover; the glow and the border swap below are what remains.

   To restore, put these two declarations back at the top of the rule:
       margin: calc(var(--space-3) * -1) calc(var(--space-3) * -1);
       padding-inline: calc(var(--space-8) + 11px);
   re-add `margin` and `padding-inline` to the .missionVisionCard transition
   above, and restore the --vision / --narrow rule that followed this one:
       .missionVisionCards__slot:hover .missionVisionCard--vision,
       .missionVisionCards__slot:hover .moreSolutions__card--narrow {
         padding-inline: calc(var(--space-7) + 11px);
       }
   (that second rule existed because both layouts narrow their second card to 48
   rather than the component's 64, so it took the same +11 off its own base), and
   restore the two cancelling rules in the max-width: 900px block.

   Why it was a negative margin and not `padding: 0` on the slot, if it comes
   back: the slot is `flex: 1 0 0`, so its padding counts inside its own flex box
   — zeroing it returns 24px to the row's free space, which grow splits between
   BOTH slots and widens the resting sibling by 12px. Figma only ever changes the
   hovered instance. A negative margin left every slot's width untouched, so the
   sibling held still, and the 12px band stayed part of the hit area. */
.missionVisionCards__slot:hover .missionVisionCard {
  border-color: transparent;
  border-image: none;
  box-shadow: 0 0 18px var(--mv-glow);
}

.missionVisionCard__body {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--clamp-rem-24);
  width: 100%;
  text-align: center;
}

.missionVisionCard__body .eyebrow {
  margin: 0;
}

.missionVisionCard__text {
  font-family: var(--font-heading);
  font-weight: 400;
  font-size: var(--font-24);
  line-height: 1.2;
}

/* ---- About's Mission/Vision pair, redesigned 2026-09-14 (881:2671) ----------
   Figma replaced the two 580x650 portrait cards with a column of two full-width
   landscape cards (Block 8 `1939:3326`, Block 9 `1939:3337`), each inset 150px
   on one side so the pair reads as a stagger. Everything here is scoped to
   --stacked: 21 other pages share .missionVisionCard* for .moreSolutions and
   .productSolutions and must keep the portrait base. */
.missionVisionCards--stacked {
  flex-direction: column;
  align-items: stretch;
  gap: var(--space-6);
}

.missionVisionCards--stacked .missionVisionCards__slot {
  flex: 0 0 auto;
  min-height: 0;
  width: 100%;
}

/* W-01 2026-09-22: the 150px stagger inset was `padding-right/left: 12.58%` on a
   width:100% slot, which is the soft-margin technique — padding doing width's job.
   Converted to a real width plus an align-self, so the rendered width is readable
   from the width declaration instead of the box model.

   88.42% = (1192 - 150 + 12 + 12) / 1192. The slot keeps its 12px hover band on
   all four sides, so the card's content box measures the same 1030 it did before.
   No max-width: the slot is an inner element of .missionVisionCards, which is
   already capped at calc(var(--contentMax) * 0.7884), and that cap propagates.

   To reverse: restore `padding-right: 12.58%` / `padding-left: 12.58%` and drop
   the width and align-self below. */
.missionVisionCards--stacked .missionVisionCards__slot--indentEnd {
  width: 88.42%;
  align-self: flex-start;
}

.missionVisionCards--stacked .missionVisionCards__slot--indentStart {
  width: 88.42%;
  align-self: flex-end;
}

.missionVisionCard--row {
  flex-direction: row;
  align-items: center;
  justify-content: flex-start;
  gap: var(--space-7);
  padding: var(--space-8);
}

/* The portrait Vision card narrows its sides to 48 and top-aligns; the landscape
   pair is symmetrical, so both overrides are undone here. */
.missionVisionCards--stacked .missionVisionCard--vision {
  padding-inline: var(--space-8);
  justify-content: flex-start;
}

/* Rocket Icon Circle `I1939:3326;1939:3254` — 160px, 0.75px stroke. The MCP
   flattens the stroke to #40d39f; it is the brand ramp (recorded 2026-08-01).
   border-image cannot follow border-radius, so the ring is a masked gradient. */
.missionVisionCard__ring {
  position: relative;
  flex-shrink: 0;
  width: 160px;
  height: 160px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.missionVisionCard__ring::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 50%;
  /* The mask trick draws the ring out of the padding box, so padding IS the
     stroke width — 2px, up from the 0.75 Figma reports, which renders as a
     barely-there hairline on a 160px circle. */
  padding: 2px;
  background: var(--gradient-brand);
  -webkit-mask:
    linear-gradient(#000 0 0) content-box,
    linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask:
    linear-gradient(#000 0 0) content-box,
    linear-gradient(#000 0 0);
  mask-composite: exclude;
  pointer-events: none;
}

.missionVisionCard__ring img {
  width: 50px;
  height: 50px;
  display: block;
}

.missionVisionCard--row .missionVisionCard__body {
  align-items: flex-start;
  text-align: left;
}

/* Figma paints the eyebrow ramp across the text node, which is shrink-wrapped to
   its own copy — so the box has to be pinned, or the ramp stretches the full
   column and only its green end lands on the glyphs. */
.missionVisionCard--row .eyebrow {
  width: max-content;
  max-width: 100%;
}

@media (max-width: 900px) {
  /* No room for the stagger; fall back to the stacked-card treatment the
     portrait pair already uses, with the ring above the copy. */
  .missionVisionCards--stacked .missionVisionCards__slot--indentEnd,
  .missionVisionCards--stacked .missionVisionCards__slot--indentStart {
    padding-inline: 0;
    /* W-01 2026-09-22: the stagger is now a width, not a padding, so undoing it
       here means resetting the width and the align-self as well. */
    width: 100%;
    align-self: stretch;
  }
  .missionVisionCard--row {
    flex-direction: column;
    align-items: flex-start;
  }
  /* Centred when stacked (Sam, 2026-09-24): ring, eyebrow and copy. */
  .missionVisionCards__slot--indentEnd .missionVisionCard--row,
  .missionVisionCards__slot--indentStart .missionVisionCard--row {
    align-items: center;
  }
  .missionVisionCards__slot--indentEnd .missionVisionCard--row .missionVisionCard__body,
  .missionVisionCards__slot--indentStart .missionVisionCard--row .missionVisionCard__body {
    align-items: center;
    text-align: center;
  }
  .missionVisionCards--stacked .missionVisionCard--vision {
    padding-inline: var(--space-5);
  }
}

/* Our Journey intro — Figma Frame 338 (790:955), the 900px block centred inside
   Frame 325 (64px padding) of the Journey section 787:442. The timeline itself
   below it is not built yet. Rhythm here is eyebrow -> heading 16, heading block
   -> lede 48, matching every other section intro in the file. */
/* .leadership is Frame 338 (790:1098) — structurally identical to the Journey
   intro (same 900px block, same 16/48 rhythm, one-line heading), so it reuses
   the .journey__* internals rather than duplicating them. Its section frame is
   Frame 335 (790:1096) / Frame 325, again 64px padding. The leadership card
   grid below it (Frame 344, 852:447) is not built. */
.journey,
.leadership {
  background: var(--color-black);
  padding-block: var(--space-8);
  padding-inline: 0;
  width: 91.53%;
  max-width: calc(var(--contentMax) * 0.9153);
  margin-inline: auto;
}

/* Frame 325 (787:443) is a 96px-gap column, so the intro, the era bar, the
   slider and the dots all sit 96 apart. Not applied to .leadership: its grid
   already carries the same 96 as a margin. */
/* Frame 325's gap is a flat 96. --space-9 keeps growing past the 1512 frame and
   reaches 121.9 on a wide monitor, so it is capped at the Figma value — still
   fluid below 1512, never larger than the design. */
.journey {
  display: flex;
  flex-direction: column;
  gap: min(var(--space-9), 96px);
}

.journey__intro {
  max-width: min(900px, 100%);
  margin-inline: auto;
  display: flex;
  flex-direction: column;
  gap: var(--space-7);
  text-align: center;
}

.journey__headingGroup {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--clamp-rem-16);
}

.journey__headingGroup .eyebrow {
  margin: 0;
}

.journey .sectionHeading,
.leadership .sectionHeading {
  width: 18.75em;
  max-width: 100%;
} /* 787:446, 790:1101, 900 @48 */

.journey__lead {
  font-size: var(--font-16);
  line-height: 1.4;
  letter-spacing: 0.1px;
}

/* --------------------------------------------------------------------------
   Our Journey timeline slider — Figma Frame 339 (1330:794) + Slot (790:1027)
   -------------------------------------------------------------------------- */
/* Frame 339 is a STYLING SPEC, not a layout: its two cards are the active and
   inactive states of one slide, sat side by side (justify-end) to be compared.
   Frame 14 (789:935) is what shows the arrangement — three slides, active in the
   middle — so this runs as slick centerMode with slidesToShow 3.
   Cards are 410 wide on a 48 gap; active is 460 tall and inactive 400 and
   vertically centred, hence the flex/centre-aligned track. Slick computes slide
   widths from the track, so at 1384 the card lands at ~413 rather than exactly
   410; the 48px gap is exact. Everything active hangs off .slick-current. */
/* Era tab bar, Frame 264 (790:975). Three equal cells across the 1384 content
   width; the #ebebeb rule is the "Line Gradient Light Grey" style, which the MCP
   reports flat — reuse the already-solved --gradient-line-2 ramp, same as
   .rotatingCards__tabs and .newsTabs. Type is Golos SemiBold 16/2, inactive
   #818181, active on --gradient-brand with a 2px brand underline. */
.journeyEras::-webkit-scrollbar,
.rotatingCards__tabs::-webkit-scrollbar {
  display: none;
}

.journeyEras {
  scrollbar-width: none; /* HOME-03: hide the OS bar, still swipe/drag scrolls */
  /* ABOUT-05: capped to the slider's 1384 so the bar never runs past the cards. */
  width: 100%;
  max-width: 1384px;
  margin-inline: auto;
  display: flex;
  border-bottom: 1px solid transparent;
  border-image: var(--gradient-line-2) 1;
  overflow-x: auto;
}

.journeyEras__tab {
  flex: 1 0 0;
  min-width: 0;
  padding: 0 var(--space-8) var(--space-6);
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: var(--font-16);
  line-height: 2;
  text-align: center;
  text-transform: uppercase;
  /* #818181 as a text colour here, not a stroke — the flattened-gradient caveat
     on this hex applies to borders, and 790:985/790:987 really are flat. */
  color: var(--color-border-mid);
  border-bottom: 2px solid transparent;
  white-space: nowrap;
}

.journeyEras__tab.isActive {
  background: var(--gradient-brand);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  border-image: var(--gradient-brand) 1;
}

@media (max-width: 900px) {
  .journeyEras__tab {
    padding-inline: var(--space-5);
  }
}

/* ABOUT-03: below 1200 the three equal cells are narrower than their one-line
   labels, which printed over each other. Each tab takes its label's width and
   the strip scrolls instead (js/journey-slider.js keeps the live tab in view). */
@media (max-width: 1199px) {
  .journeyEras__tab {
    flex: 0 0 auto;
  }
}

/* The 96 above the slider is the .journey column gap (Frame 325), not a margin —
   keeping both stacked them to 192. */
.journey__slider {
  /* ABOUT-01: min-width 0 lets this flex-column child shrink; without it slick
     sized every slide to 1374px and the page scrolled sideways. */
  min-width: 0;
  width: 100%;
  max-width: 1384px;
  margin-inline: auto;
}

.journey__slider .slick-track {
  display: flex;
  align-items: center;
}

/* Three 458px slides are 1374, so a 1384 track leaves 10px in which the looped
   next slide shows as a stray sliver at the right edge. Clip to a whole number of
   slides instead. Left-aligned inside the 1384 box (block, no auto margin) so the
   first card still starts exactly on the section's 64px gutter, as Frame 14 has
   it, and the 10px of slack falls on the right where nothing renders. Below the
   design width this doesn't bind and the carousel peeks normally. */
.journey__slider .slick-list {
  max-width: calc(458px * 3);
}

/* 458 = the 410 card plus its 48 gap. The card sits at the slide's left edge and
   the leftover 48 IS the gap, which keeps the first card flush with the track's
   left edge — Frame 14 starts its first card at x=0. Slick only respects these
   widths because variableWidth is on; otherwise it overwrites them. */
.journey__slider .slick-slide {
  height: auto;
  flex: 0 0 458px;
  width: 458px;
}

/* Slick makes the current slide focusable (tabindex) and the browser rings it
   on click and on keyboard focus. The ring is not wanted on the cards. */
.journey__slider .slick-slide:focus,
.journey__slider .slick-slide:focus-visible {
  outline: none;
}

/* F2 2026-09-18: height -> min-height. Milestone copy varies per card, and a
   fixed box overflows rather than growing when a body runs long or the reader
   raises their font size. The slider sets `height: auto` on the slide itself,
   so the card is free to grow. */
.journeyCard {
  width: 410px;
  min-height: 400px;
  display: flex;
  flex-direction: column;
  background: var(--color-black);
  /* Line Gradient 1 — get_variable_defs lists the style by name with an empty
     value and get_design_context flattens it to its flat #818181 first stop. */
  border: 1px solid var(--color-border-mid);
  border-image: var(--gradient-line-1) 1;
  text-align: left;
  opacity: 0.4;
  transition:
    opacity 300ms ease,
    min-height 300ms ease,
    box-shadow 300ms ease;
}

.journey__slider .slick-current .journeyCard {
  min-height: 460px;
  opacity: 1;
  /* Figma drop shadow 0 0 15 rgba(64,211,159,0.5) — the green "this is the live
     slide" glow, and why the node renders 520 tall against a 460 frame. */
  box-shadow: 0 0 15px rgba(64, 211, 159, 0.5);
}

/* --- media band (Frame 337) ----------------------------------------------- */
.journeyCard__media {
  position: relative;
  flex: 0 0 191px;
  overflow: hidden; /* the year deliberately bleeds off the bottom edge */
  /* Inactive: the plain brand ramp running upward. */
  background: linear-gradient(
    to top,
    var(--color-brand-green) 0%,
    var(--color-brand-teal) 50%,
    var(--color-brand-blue) 100%
  );
}

/* Active: a centred elliptical ramp instead — semi-transparent blue at the middle
   out to opaque green at the edge. Figma's matrix(20.4 0 0 9.55 204 95.5) against
   r=10 puts the semi-axes at 204 x 95.5 on the 408x191 box, i.e. half the box each
   way, so this is 50% 50% and NOT 100% 100%.
   Scoped to slides that actually have a photo, because that is the only case the
   design specifies: this ramp exists to be seen THROUGH a 40%-opacity image, and
   on its own it reads as a raw green wash. Photo-less milestones keep the plain
   upward ramp above, which is what the inactive state uses. */
.journey__slider .slick-current .journeyCard:has(.journeyCard__photo) .journeyCard__media {
  background: radial-gradient(
    ellipse 50% 50% at 50% 50%,
    rgba(47, 132, 226, 0.6) 1.11%,
    rgba(56, 171, 193, 0.8) 50.56%,
    rgba(64, 211, 159, 1) 100%
  );
}

/* Only the active slide shows its photo, per the spec — the inactive card has no
   image layer at all. Slides without one just show the gradient. */
.journeyCard__photo {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0.4;
  display: none;
}

.journey__slider .slick-current .journeyCard__photo {
  display: block;
}

.journeyCard__year {
  position: absolute;
  left: 27px;
  top: 129px;
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: var(--font-64);
  line-height: 1.2;
  color: var(--color-black);
  /* A range like "2000–2006" used to wrap at the dash, and the media band's
     overflow: hidden cut off the second line. */
  white-space: nowrap;
}

.journey__slider .slick-current .journeyCard__year {
  left: 44px;
  top: 115px;
  font-size: var(--font-78);
}

/* A year range is too wide for the card at the active 78px size, so it keeps
   its inactive size when its slide is active (Sam, 2026-09-24). */
.journey__slider .slick-current .journeyCard__year--range {
  font-size: var(--font-64);
}

/* --- body (Frame 272) ----------------------------------------------------- */
.journeyCard__body {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--clamp-rem-24);
  padding: var(--space-6) var(--space-6);
  color: var(--color-white);
}

.journey__slider .slick-current .journeyCard__body {
  padding: var(--space-7) var(--space-7);
}

.journeyCard__body h3 {
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-22);
  line-height: 1.2;
}

.journeyCard__body p {
  font-size: var(--font-16);
  line-height: 1.422; /* Figma 22.75px on 16px */
}

/* --- dots (Slot 790:1027) ------------------------------------------------- */
/* Ten 8px dots on a 32px pitch, centred, 96px below the track. Inactive is a 1px
   #818181 outline with no fill. Active is a 10px disc of the brand ramp with a
   #40d39f glow — Figma draws it as an r=4 gradient fill plus an r=4.5 ring in the
   same gradient, which together are just one 10px disc, and a drop shadow with
   stdDeviation 4 (= an 8px CSS blur). The li cells are a fixed 10px so the 32px
   pitch doesn't shift as the active dot grows. */
.journey__slider .slick-dots {
  margin: var(--space-9) 0 0;
  padding: 0;
  list-style: none;
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 22px; /* 10px cell + 22 = the Slot frame's 32px pitch */
}

/* ABOUT-04: 13 dots on the 32px pitch need ~406px, wider than a phone column. */
@media (max-width: 600px) {
  .journey__slider .slick-dots {
    gap: 12px;
  }
}

.journey__slider .slick-dots li {
  width: 10px;
  height: 10px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.journey__slider .slick-dots button {
  width: 8px;
  height: 8px;
  padding: 0;
  border: 1px solid var(--color-border-mid);
  border-radius: 50%;
  background: none;
  font-size: 0;
  line-height: 0;
  color: transparent;
  cursor: pointer;
  transition:
    width 200ms ease,
    height 200ms ease;
}

.journey__slider .slick-dots .slick-active button {
  width: 10px;
  height: 10px;
  border: 0;
  background: var(--gradient-brand);
  box-shadow: 0 0 8px var(--color-brand-green);
}

/* One slide at a time below 900 (see the matching breakpoint in
   js/journey-slider.js). variableWidth is off there, so slick writes an inline
   width on the slide and these just get out of its way; the card fills it and
   sizes to its copy instead of clipping. */
@media (max-width: 900px) {
  .journey__slider .slick-slide {
    flex: 0 0 auto;
    width: auto;
  }
  .journeyCard,
  .journey__slider .slick-current .journeyCard {
    width: auto;
    height: auto;
    min-height: 400px;
  }
}

/* --------------------------------------------------------------------------
   Leadership grid — Figma Frame 344 (852:447), 1384 wide inside Frame 325
   -------------------------------------------------------------------------- */
/* 3 up, 32px column gap, 48px row gap, 96px below the intro. Figma draws it as
   five separate row frames, which is why cards match heights within a row but
   not across rows — a plain grid reproduces that. */
.leaderGrid {
  max-width: 1384px;
  margin: var(--space-9) auto 0;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  column-gap: var(--space-6);
  row-gap: var(--space-7);
}

.leaderCard {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  padding: var(--space-5) var(--space-5) var(--space-6);
  /* Line Gradient 1 again — the MCP's flat #818181 is only its first stop. */
  border: 1px solid var(--color-border-mid);
  border-image: var(--gradient-line-1) 1;
}

/* The last row holds one real card between two opacity-0 fillers in Figma. */
.leaderCard--centred {
  grid-column: 2;
}

/* F3 2026-09-18: fixed height -> aspect-ratio. Nothing inside can affect the
   height, so a ratio keeps the crop as the column narrows. 5/4 is the measured
   proportion at the design width (379 x 300 = 1.262). */
.leaderCard__photo {
  position: relative;
  aspect-ratio: 5 / 4;
  flex-shrink: 0;
  overflow: hidden;
}

.leaderCard__photo img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Crop from the bottom, so heads stay in frame. */
  object-position: top;
  position: relative;
  top: 1px; /* Sam, 2026-09-24 */
}

/* Figma fades the photo into the card from halfway down. */
.leaderCard__photo::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(
    180deg,
    rgba(12, 12, 12, 0) 50%,
    rgba(12, 12, 12, 0.5) 79.808%,
    var(--color-black) 100%
  );
}

/* Bottom-aligns the CTA no matter how tall the bio runs — Figma's cards use
   space-between on this block for the same reason. */
.leaderCard__body {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: var(--clamp-rem-32);
}

.leaderCard__text {
  display: flex;
  flex-direction: column;
  gap: var(--clamp-rem-32);
}

.leaderCard__identity {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

/* 32px Golos over the full card measure — the gradient box is the text node,
   which is the card's 392px content width, so no separate pin is needed. */
.leaderCard__name {
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-32);
  line-height: 1.15; /* was 1.1 */
  width: 100%;
}

.leaderCard__role {
  font-size: var(--font-24);
  line-height: 1.2;
}

.leaderCard__bio {
  font-size: var(--font-16);
  line-height: 1.4;
}

@media (max-width: 1200px) {
  .leaderGrid {
    grid-template-columns: repeat(2, 1fr);
  }
  .leaderCard--centred {
    grid-column: auto;
  }
}

/* ABOUT-06 2026-09-24: two-up now runs down to 700 (was one column from 900). */
@media (max-width: 699px) {
  .leaderGrid {
    grid-template-columns: 1fr;
  }
}

/* --------------------------------------------------------------------------
   Leadership biography slide-out — Figma "Bio Profile" 909:3904 (Components)
   664 x 941: 64px inline / 96px block padding, 536 measure, column gap 32.
   Reached from Mike Balsei's "Read Biography" in the prototype; the same card
   serves all twelve. Copy is the FINAL Company doc's full biographies.
   -------------------------------------------------------------------------- */
.leaderCard__biographyToggle {
  /* .linkCallToAction already paints the label, underline and arrow; a <button>
     only needs its user-agent chrome removing. background is NOT reset here —
     that property is carrying the clipped brand ramp. */
  border-top: 0;
  border-right: 0;
  border-left: 0;
  padding-top: 0;
  padding-right: 0;
  padding-left: 0;
  font: inherit;
  font-size: var(--font-14);
  cursor: pointer;
}

/* The panel slides in from the right edge and holds the viewport height, so a
   long biography scrolls inside it rather than growing the card. Figma's 941 is
   the height of Mike Balsei's copy, not a fixed box — the others run longer. */
.leaderBio {
  position: fixed;
  inset: 0 0 0 auto;
  width: 41.53%; /* 664 of 1598 -- the design width against its own frame */
  max-width: calc(var(--contentMax) * 0.4153);
  min-width: min(664px, 100%);
  height: 100%;
  max-height: none;
  margin: 0;
  padding: 0;
  overflow: hidden auto;
  overscroll-behavior: contain;
  background-color: rgba(12, 12, 12, 0.8);
  backdrop-filter: blur(12px);
  border: 1px solid var(--color-border-mid);
  border-image: var(--gradient-line-1) 1;
  box-shadow: 0 12px 30px rgba(0, 0, 0, 0.25);
  color: var(--color-white);
  /* Entry/exit is driven by .isEntered, toggled in js/leader-bio.js, rather
     than by [open] + @starting-style + `transition: display allow-discrete`.
     That newer route left the panel stuck at its starting translate here, and
     the class version has the better failure mode: if the transition never
     runs, the panel still lands in its open position instead of off-screen. */
  translate: 100% 0;
  transition: translate 0.35s ease;
}

.leaderBio.isEntered {
  translate: 0 0;
}

.leaderBio::backdrop {
  background-color: rgba(12, 12, 12, 0.6);
  opacity: 0;
  transition: opacity 0.35s ease;
}

.leaderBio.isEntered::backdrop {
  opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
  .leaderBio,
  .leaderBio::backdrop {
    transition: none;
  }
}

/* Frame 370: column, gap 32, padding 96 / 64. min-height 100% keeps the card
   filling the panel when a biography is short. */
.leaderBio__inner {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--space-6);
  min-height: 100%;
  padding: var(--space-9) var(--space-8);
}

/* 909:3951 — Golos Text Medium 36/1.2. */
.leaderBio__name {
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-36);
  line-height: 1.2;
}

/* Frames 366 / 367: label + body, gap 24. */
.leaderBio__section {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}

/* Frame 248 holds the Professional Experience block and the footer 48 apart. */
.leaderBio__closing {
  display: flex;
  flex-direction: column;
  gap: var(--space-7);
}

/* 909:3955 / 909:3964 — Inter Medium 20, tracking 1px, uppercase, brand ramp
   painted across the whole 536 text node, which is what .gradientText's host
   rule already does. */
.leaderBio__heading {
  font-family: var(--font-body);
  font-weight: 500;
  font-size: var(--font-20);
  line-height: 1.4;
  letter-spacing: 1px;
  text-transform: uppercase;
}

.leaderBio__text {
  font-size: var(--font-16);
  line-height: 1.4;
  letter-spacing: 0.1px;
}

/* Frame 371: Back button left, LinkedIn mark right. */
.leaderBio__footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-5);
}

/* 909:3966 is the standard Button Set, but its arrow points back. */
.leaderBio__back {
  cursor: pointer;
}

.leaderBio__back svg {
  rotate: 180deg;
}

.leaderBio__linkedIn {
  display: block;
  width: 40px;
  height: 40px;
  flex-shrink: 0;
  transition: filter 0.2s ease;
}

.leaderBio__linkedIn img {
  display: block;
  width: 100%;
  height: 100%;
}

.leaderBio__linkedIn:hover {
  filter: drop-shadow(0 0 4px rgba(64, 211, 159, 0.3));
}

/* Percentage widths polish 2026-09-24: the panel held its 664px floor down to
   901, then jumped to full width. Tablets get 85% (the backdrop still shows at
   the left), phones full width; each step changes the width by 150px or less. */
@media (max-width: 900px) {
  .leaderBio {
    width: 85%;
    min-width: 0;
    max-width: none;
  }
  .leaderBio__inner {
    padding: var(--space-8) var(--space-6);
  }
}

@media (max-width: 600px) {
  .leaderBio {
    width: 100%;
  }
}

/* --------------------------------------------------------------------------
   Acquisition slide-out — Figma "Acquisition Profile" 948:1650 (Components)
   960 x 894. Same panel mechanics as .leaderBio, wider and with a detail table.
   Reached from Flex-Tec's Learn More in the prototype; one design, nine
   companies, content from the FINAL Company doc.
   -------------------------------------------------------------------------- */
.acquisitionProfile {
  /* Shares .leaderBio's slide-in; only the width differs (960 vs 664). */
  position: fixed;
  inset: 0 0 0 auto;
  width: 60%;
  max-width: calc(var(--contentMax) * 0.6);
  min-width: min(960px, 100%);
  height: 100%;
  max-height: none;
  margin: 0;
  padding: 0;
  overflow: hidden auto;
  overscroll-behavior: contain;
  background-color: rgba(12, 12, 12, 0.8);
  backdrop-filter: blur(12px);
  border: 1px solid var(--color-border-mid);
  border-image: var(--gradient-line-1) 1;
  box-shadow: 0 12px 30px rgba(0, 0, 0, 0.25);
  color: var(--color-white);
  translate: 100% 0;
  transition: translate 0.35s ease;
}

.acquisitionProfile.isEntered {
  translate: 0 0;
}

.acquisitionProfile::backdrop {
  background-color: rgba(12, 12, 12, 0.6);
  opacity: 0;
  transition: opacity 0.35s ease;
}

.acquisitionProfile.isEntered::backdrop {
  opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
  .acquisitionProfile,
  .acquisitionProfile::backdrop {
    transition: none;
  }
}

/* 948:1435 — column, gap 48, padding 64 all round. */
.acquisitionProfile__inner {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--space-7);
  min-height: 100%;
  padding: var(--space-8);
}

/* 948:1436 — logo 180x79 beside the summary, gap 64. */
.acquisitionProfile__head {
  display: flex;
  align-items: flex-start;
  gap: var(--space-8);
}

.acquisitionProfile__logo {
  width: 180px;
  height: 79px;
  flex-shrink: 0;
  object-fit: contain;
  object-position: left top;
}

.acquisitionProfile__summary {
  flex: 1 0 0;
  min-width: 0;
  font-size: var(--font-16);
  line-height: 1.4;
  letter-spacing: 0.1px;
}

/* 948:1689 — the founded/acquired band. Full width, radius 22, 1px #40d39f,
   and a ramp that fades out rather than running edge to edge:
   #40d39f -> rgba(56,171,193,0.8) at 50% -> rgba(47,132,226,0.5). */
.acquisitionProfile__dates {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-5);
  padding: var(--clamp-rem-8) clamp(24px, 3.17vw, 60.9px);
  border: 1px solid var(--color-brand-green);
  border-radius: 22px;
  background: linear-gradient(
    90deg,
    #40d39f 0%,
    rgba(56, 171, 193, 0.8) 50%,
    rgba(47, 132, 226, 0.5) 100%
  );
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-14);
  line-height: 1.4;
  letter-spacing: 1px;
  text-transform: uppercase;
  text-align: center;
}

.acquisitionProfile__dates svg {
  width: 18px;
  height: 10px;
  flex-shrink: 0;
}

/* 948:1442 — the detail rows, 36 apart. */
.acquisitionProfile__detail {
  display: flex;
  flex-direction: column;
  gap: clamp(18px, 2.38vw, 45.7px); /* 36px */
}

.acquisitionProfile__row {
  display: flex;
  align-items: flex-start;
  gap: var(--space-6);
}

/* 160px label column, Golos Medium 18/1.2. */
.acquisitionProfile__rowLabel {
  width: 160px;
  flex-shrink: 0;
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-18);
  line-height: 1.2;
}

.acquisitionProfile__rowText {
  flex: 1 0 0;
  min-width: 0;
  font-size: var(--font-16);
  line-height: 1.4;
  letter-spacing: 0.1px;
}

.acquisitionProfile__chips {
  flex: 1 0 0;
  min-width: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--clamp-rem-16);
}

/* The chips are the Button Set "Subtle" variant at 12px — the same gradient
   label over a brand-ramp underline that .linkCallToAction paints at 14px. */
.acquisitionProfile__chip {
  display: inline-flex;
  width: max-content;
  max-width: 100%;
  align-items: center;
  gap: var(--clamp-rem-16);
  padding-bottom: var(--clamp-rem-8);
  border-bottom: 1px solid transparent;
  border-image: var(--gradient-brand) 1;
  font-family: var(--font-body);
  font-weight: 500;
  font-size: var(--font-12);
  line-height: 1.34;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  /* Long names break rather than run off the viewport (Sam, 2026-09-24). */
  min-width: 0;
  overflow-wrap: anywhere;
  background: var(--gradient-brand);
  background-size: calc(100% - (var(--clamp-rem-16) + 18px)) 100%;
  background-repeat: no-repeat;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

/* Capabilities have no page to link to, so they keep the treatment without the
   arrow and without the shortened paint box. */
.acquisitionProfile__chip--plain {
  background-size: 100% 100%;
}

.acquisitionProfile__chip svg {
  width: 18px;
  height: 10px;
  flex-shrink: 0;
}

.acquisitionProfile__chip svg path {
  stroke: var(--color-brand-teal);
}

/* 948:1695 — Back, then the company's own site. */
.acquisitionProfile__footer {
  display: flex;
  align-items: center;
  gap: var(--space-6);
}

.acquisitionProfile__back {
  cursor: pointer;
}

.acquisitionProfile__back svg {
  rotate: 180deg;
}

.companyCard__learnMore {
  cursor: pointer;
}

@media (max-width: 1000px) {
  .acquisitionProfile {
    width: 100%;
    min-width: 0;
    max-width: none;
  }
  .acquisitionProfile__inner {
    padding: var(--space-7) var(--space-6);
  }
  .acquisitionProfile__head {
    flex-direction: column;
    gap: var(--space-5);
  }
  .acquisitionProfile__row {
    flex-direction: column;
    gap: var(--clamp-rem-12);
  }
  .acquisitionProfile__rowLabel {
    width: auto;
  }
}

/* --------------------------------------------------------------------------
   Capability slide-out — Figma " Profile Capabilities" 1463:1207
   (the layer name really does start with a space). 1128 x 538 and LANDSCAPE,
   unlike the other two panels: the capability card sits at 400x400 on the left
   with a 536 copy column beside it. Reached from the Wire Processing / Primary
   Lead Preparation Learn More in the prototype; one design, twelve cards.
   -------------------------------------------------------------------------- */
.capabilityProfile {
  /* A centred popup, not a slide-out: the other two panels run the full
     viewport height because their content does, while this one is 1128x538 and
     fits as it is. Height is left to the content and nothing scrolls. */
  /* Explicit, because Chrome's UA sheet leaves a dialog at position: absolute
     even when modal — so without this the popup scrolls away with the page
     instead of staying put in the viewport. */
  position: fixed;
  width: 74.6%; /* 1128 of 1512 */
  max-width: calc(var(--contentMax) * 0.746);
  min-width: min(1128px, 100%);
  /* fit-content, not auto: Chrome's UA sheet pins a modal dialog's block-start
     AND block-end to 0, so an auto height stretches to the full viewport and the
     auto vertical margins collapse to 0. fit-content lets the box size to its
     content and the auto margins then centre it. */
  height: fit-content;
  /* A safety net only — at the design's 1128x538 nothing scrolls. It stops a
     short viewport from clipping the card instead. */
  max-height: 92svh;
  margin: auto;
  padding: 0;
  overflow: hidden auto;
  overscroll-behavior: contain;
  background-color: rgba(12, 12, 12, 0.8);
  backdrop-filter: blur(12px);
  border: 1px solid var(--color-border-mid);
  border-image: var(--gradient-line-1) 1;
  box-shadow: 0 12px 30px rgba(0, 0, 0, 0.25);
  color: var(--color-white);
  /* .isEntered is still what the shared script toggles; here it fades rather
     than slides. */
  opacity: 0;
  transition: opacity 0.2s ease;
}

.capabilityProfile.isEntered {
  opacity: 1;
}

.capabilityProfile::backdrop {
  background-color: rgba(12, 12, 12, 0.6);
  opacity: 0;
  transition: opacity 0.35s ease;
}

.capabilityProfile.isEntered::backdrop {
  opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
  .capabilityProfile,
  .capabilityProfile::backdrop {
    transition: none;
  }
}

/* Card left, copy right; 64 padding, 64 between the two columns. */
.capabilityProfile__inner {
  display: flex;
  align-items: center;
  gap: var(--space-8);
  padding: var(--space-8);
}

/* The Block 3 card at 400x400 — same photo treatment as the grid card it came
   from, so it reuses .capabilityCard__background and its modifiers. */
.capabilityProfile__media {
  position: relative;
  width: 400px;
  flex-shrink: 0;
  aspect-ratio: 1 / 1;
  overflow: hidden;
  border: 1px solid var(--color-border-mid);
  border-image: var(--gradient-line-1) 1;
}

.capabilityProfile__copy {
  flex: 1 0 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
}

/* 1463:1211 — gap 24 between the kicker and the heading. */
.capabilityProfile__head {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}

/* Figma paints the capability NAME as the small gradient kicker and the
   TAGLINE as the 40px heading — the reverse of the grid card, which shows the
   name large. Inter Medium 20, tracking 1px, uppercase, brand ramp. */
.capabilityProfile__kicker {
  font-family: var(--font-body);
  font-weight: 500;
  font-size: var(--font-20);
  line-height: 1.4;
  letter-spacing: 1px;
  text-transform: uppercase;
}

.capabilityProfile__heading {
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-40);
  line-height: 1.2;
}

/* 1463:1216 — gap 48 between the paragraph and the Back button. */
.capabilityProfile__body {
  display: flex;
  flex-direction: column;
  gap: var(--space-7);
  font-size: var(--font-16);
  line-height: 1.4;
  letter-spacing: 0.1px;
}

.capabilityProfile__footer {
  display: flex;
  align-items: center;
}

.capabilityProfile__back {
  cursor: pointer;
}

.capabilityProfile__back svg {
  rotate: 180deg;
}

.capabilityCard__button {
  cursor: pointer;
}

@media (max-width: 1200px) {
  .capabilityProfile {
    width: 92%;
    min-width: 0;
    max-width: none;
  }
  .capabilityProfile__inner {
    flex-direction: column;
    align-items: stretch;
    justify-content: center;
    padding: var(--space-7) var(--space-6);
  }
  .capabilityProfile__media {
    width: 100%;
    max-width: 400px;
  }
}

/* Scroll lock while a dialog owns the viewport. */
body.isDialogOpen {
  overflow: hidden;
}

/* --------------------------------------------------------------------------
   Global locations CTA — Figma Frame 263 (909:4623)
   Outer frame is 48px/64px padding; the band inside (909:4624) is a 96px/200px
   box with a 32px stack. The border is the named "Line Gradient 1" style, which
   get_design_context flattens to #818181 exactly as it does elsewhere in this
   file, so it uses --gradient-line-1 like .missionVisionCard does.
   The background is an image with a brand-ramp overlay in mix-blend overlay and
   a flat rgba(12,12,12,0.6) veil on top — the same recipe as the other photo
   bands, painted here as two stacked layers over the <img>.
   -------------------------------------------------------------------------- */
.globalCallToAction {
  background: var(--color-black);
  padding-block: var(--space-7);
  padding-inline: 0;
  width: 91.53%;
  max-width: calc(var(--contentMax) * 0.9153);
  margin-inline: auto;
}

.globalCallToAction__band {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-6);
  padding-block: var(--space-9);
  padding-inline: clamp(100px, 13.23vw, 254px); /* was 200px */
  border: 1px solid transparent;
  border-image: var(--gradient-line-1) 1;
  text-align: center;
  overflow: hidden;
}

.globalCallToAction__band > * {
  position: relative;
  z-index: 1;
}

.globalCallToAction__background {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
}

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

.globalCallToAction__background::before,
.globalCallToAction__background::after {
  content: '';
  position: absolute;
  inset: 0;
}

.globalCallToAction__background::before {
  background: var(--gradient-brand);
  mix-blend-mode: overlay;
}

.globalCallToAction__background::after {
  background: rgba(12, 12, 12, 0.6);
}

.globalCallToAction .eyebrow {
  margin: 0;
}

/* 984px is the band's content width (1512 - 128 outer - 400 inner), which is the
   box Figma paints the heading's ramp across. */
.globalCallToAction__heading {
  width: 20.5em; /* 984 @48 */
  max-width: 100%;
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-48);
  line-height: 1.15; /* was 1.1 */
  color: var(--color-white);
}

@media (max-width: 1200px) {
  .missionVisionCards {
    padding-inline: 0;
    width: calc(100% - (var(--gutter) * 2));
    margin-inline: auto;
  }
  .globalCallToAction__band {
    padding-inline: var(--space-9);
  }
}

@media (max-width: 900px) {
  .globalCallToAction {
    padding-inline: 0;
    width: calc(100% - (var(--gutter) * 2));
    margin-inline: auto;
  }
  .globalCallToAction__band {
    padding: var(--space-8) var(--space-5);
  }
}

@media (max-width: 900px) {
  .missionVisionIntro {
    padding-block: var(--space-9);
    padding-inline: 0;
    width: calc(100% - (var(--gutter) * 2));
    margin-inline: auto;
  }
  .missionVisionCards {
    flex-direction: column;
    align-items: stretch;
  }
  .missionVisionCards__slot {
    height: auto;
    padding: 0;
  }
  .missionVisionCard {
    padding: var(--space-7) var(--space-4);
  }
  /* Both hover rules removed 2026-09-17. They only existed to cancel the desktop
     growth here, where the slot has no padding to grow into; with the growth gone
     they would themselves have changed the padding on hover. Restore alongside
     the desktop rule:
       .missionVisionCards__slot:hover .missionVisionCard {
         margin: 0;
         padding-inline: var(--space-5);
       }
       .missionVisionCards__slot:hover .moreSolutions__card--narrow {
         padding-inline: var(--space-7);
       } */
}

@media (max-width: 900px) {
  .siteHeader {
    flex-wrap: wrap;
    gap: var(--space-4);
  }
}

/* Anchor targets (footer deep links). The header is not sticky, so this is
   breathing room above the landed section, not header clearance.
   #leadership and #ourCompanies are the mega menu's Leadership and Our
   Companies links. */
#leadership,
#ourCompanies,
#peopleEngagement,
#eciExcellenceClub {
  scroll-margin-top: var(--space-8);
}

/* --------------------------------------------------------------------------
   Stat band (Figma frames 254 / 255)
   Full-bleed 3x2 grid between the hero and the intro statement. Cells are
   504px in Figma (3 x 504 = 1512), running edge to edge with no gutter.
   Borders are collapsed with negative margins, as in .statisticsGrid.
   -------------------------------------------------------------------------- */
.statisticBand {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  background: var(--color-black);
  margin-top: clamp(1px, 0.13vw, 2.5px); /* was 2px */
}

.statisticBand__cell {
  border: 1px solid var(--color-border-mid);
  border-image: var(--gradient-line-1) 1;
  margin: -1px 0 0 -1px;
  padding-block: clamp(24.25px, 3.21vw, 61.6px); /* was 48.5px */
  padding-inline: clamp(24.25px, 3.21vw, 61.6px); /* was 48.5px */
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: var(--space-5);
  /* Same Block 1 hover as .statisticRow: brand wash plus a 16px nudge right. */
  transition:
    background-image 0.2s ease,
    padding-left 0.2s ease;
}

.statisticBand__cell:hover {
  background-image: var(--gradient-hover);
  padding-left: calc(clamp(24.25px, 3.21vw, 61.6px) + 16px); /* base + 16 */
}

.statisticBand__value {
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-40);
  line-height: 1.15; /* was 0.8; Figma 32px on 40px */
}

.statisticBand__label {
  font-size: var(--font-18);
  line-height: 1.15; /* was 0.833; Figma 15px on 18px */
  letter-spacing: 0.1px;
}

@media (max-width: 1000px) {
  .statisticBand {
    grid-template-columns: repeat(2, 1fr);
  }
}
@media (max-width: 600px) {
  .statisticBand {
    grid-template-columns: 1fr;
  }
  .statisticBand__cell {
    padding: var(--space-6) var(--space-6);
  }
  .statisticBand__cell:hover {
    padding-left: calc(var(--space-6) + 16px);
  }
}

/* --------------------------------------------------------------------------
   Generic dark section
   -------------------------------------------------------------------------- */
.section {
  padding-block: var(--space-9);
  padding-inline: 0;
  width: 91.53%;
  max-width: calc(var(--contentMax) * 0.9153);
  margin-inline: auto;
}

.section--tight {
  padding-block: var(--space-8);
}
.section--panel {
  background: #1a1a1a;
}

/* Leader intro (photo + 5 stat blocks) */
.leaderIntro {
  background: var(--color-black);
  padding: var(--space-10) 0;
}

.leaderIntro__statement {
  padding-inline: 0;
  /* Percentage widths polish 2026-09-24: Figma text 403:160 in Frame 263 is
     912px of the 1512 page, 912 / 1512 = 60.32%. Was 91.53% (F1 2026-09-18;
     before that the cap was calc(900px - (var(--gutter) * 2))). */
  width: 60.32%;
  max-width: calc(var(--contentMax) * 0.6032);
  margin: 0 auto var(--space-10) auto;
  padding-block: var(--space-9);
  text-align: center;
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-24);
  line-height: 1.5;
}

/* Width steps below 1400; max-width stays at the Figma fraction. Each step
   changes the width by 150px or less: phones 91.53%, tablets 80%, laptops 65%. */
@media (max-width: 1399px) {
  .leaderIntro__statement {
    width: 65%;
  }
}

@media (max-width: 900px) {
  .leaderIntro__statement {
    width: 80%;
  }
}

@media (max-width: 600px) {
  .leaderIntro__statement {
    width: 91.53%;
  }
}

.leaderIntro__body {
  display: flex;
  align-items: stretch;
  max-width: var(--contentMax);
  margin-inline: auto;
  padding-inline: 0 var(--gutter);
  gap: 0;
}

/* PlaceholderImage 365:952 is self-stretch with the photo absolute inset-0
   object-cover inside it, so the LIST sets the row height and the photo conforms.
   As a bare flex item the img's own portrait ratio (1836 x 3264 at 500 wide =
   ~889px) drove the flex line instead, and the stat rows stopped short of it.
   The frame contributes no intrinsic height, so stretch now flows the right way. */
.leaderIntro__imageFrame {
  position: relative;
  width: 500px;
  max-width: 40%;
  flex-shrink: 0;
}

.leaderIntro__image {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.leaderIntro__list {
  flex: 1;
  padding-left: var(--space-8);
  display: flex;
  flex-direction: column;
}

.leaderIntro__list .statisticRow {
  border: 1px solid var(--color-border-mid);
  border-image: var(--gradient-line-1) 1;
  border-top-width: 0;
  padding-block: clamp(20.25px, 2.68vw, 51.5px); /* was 40.5px */
  padding-inline: clamp(24.25px, 3.21vw, 61.6px); /* was 48.5px */
}
.leaderIntro__list .statisticRow:first-child {
  border-top-width: 1px;
}

.statisticRow h3 {
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-24);
  margin-bottom: var(--clamp-rem-16);
}

.statisticRow p {
  font-size: var(--font-16);
  letter-spacing: 0.1px;
}

/* Block 1 Default (626:1286) → Gradient (626:1285) — the same hover the markets
   cells take, and .statisticRow is the other Block 1 consumer. Type selector is load
   bearing: both wrappers set the padding shorthand at (0,2,0), so a bare
   `.statisticRow:hover` would tie and lose to whichever comes later in the file. */
.statisticRow {
  transition:
    background-image 0.2s ease,
    padding-left 0.2s ease;
}
div.statisticRow:hover {
  background-image: var(--gradient-hover);
  padding-left: calc(clamp(24.25px, 3.21vw, 61.6px) + 16px); /* was 64.5px, = base + 16 */
}

@media (max-width: 900px) {
  /* HOME-10 2026-09-24: stacked, the desktop left bleed is dropped so photo and
     cards sit centred with an even gutter (was 0 left / gutter right). */
  .leaderIntro__body {
    flex-direction: column;
    padding-inline: var(--gutter);
  }
  /* F3: 2/1 is the measured stacked proportion (535 x 260 = 2.058). */
  .leaderIntro__imageFrame {
    width: 100%;
    max-width: 100%;
    aspect-ratio: 2 / 1;
  }
  .leaderIntro__list {
    padding-left: 0;
    padding-top: var(--space-6);
  }
}

/* --------------------------------------------------------------------------
   Our Solutions / Rotating cards
   -------------------------------------------------------------------------- */
/* Frame fill on InfoBlocks (298:913). Not the shared --gradient-bg-stops: the
   gradient handles were dragged in Figma, so it holds flat black for the top
   half and only ramps over the bottom. Solved by regressing the Figma render's
   vertical profile — mean error 0.57/255, i.e. exact. See the frame-fill note in
   memory; these numbers can't be re-read from the MCP tools. */
/* Tag-qualified 2026-09-15: WordPress body_class() adds the page slug to <body>,
   so a bare .solutions rule also matched <body> on /solutions/ and laid the whole
   page out as the component (flex column, align-items:center, padding, gradient) —
   which squeezed the hero to 1757px inside a 2545px body. Same hazard for .contact
   on /contact/. Keep component classes tag-qualified when their name equals a slug. */
section.solutions {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: var(--space-8) var(--space-8) var(--space-10);
  background: linear-gradient(180deg, var(--color-black) 51.5%, var(--color-teal-dark) 100%);
}

.solutions__intro {
  max-width: min(900px, 100%);
  margin-bottom: var(--space-10);
}

.rotatingCards {
  width: 100%;
  max-width: 1384px;
  margin-inline: auto;
  text-align: left;
}

/* Figma 626:2373: the tab bar ("Frame 264") is 46px tall and the card below it
   starts at y=94, so the gap is 48px — there was none here at all. Each tab frame
   is 46 = 22px of text + 24px below it, which the 2px active underline sits in;
   32px of padding made the bar 10px too tall and pushed everything down with it. */
/* Sticky so the tabs stay usable while the cards stack under them — each tab
   jumps to its card (js/rotating-cards.js). The fill stops the cards showing
   through as they slide up behind the bar. */
.rotatingCards__tabs {
  scrollbar-width: none; /* HOME-03: hide the OS bar, still swipe/drag scrolls */
  position: sticky;
  top: 0;
  z-index: 3;
  background: var(--color-black);
  padding-top: var(--space-5);
  display: flex;
  gap: var(--space-8);
  border-bottom: 1px solid transparent;
  border-image: var(--gradient-line-2) 1;
  overflow-x: auto;
  margin-bottom: var(--space-7);
}

/* No deck on mobile (Sam, 2026-09-24): js/rotating-cards.js leaves the cards
   as a plain column at 900px and below, so the tab bar has nothing to drive.
   Revert: _backups/rotating-cards-pre-mobile-stack-20260924/. */
@media (max-width: 900px) {
  .rotatingCards__tabs {
    display: none;
  }
}

.rotatingCards__tab {
  padding-bottom: clamp(11px, 1.46vw, 28px); /* was 22px */
  font-family: var(--font-heading);
  font-weight: 400;
  font-size: var(--font-20);
  line-height: 1.15; /* was 1.1; Figma 22px on 20px */
  color: var(--color-white);
  border-bottom: 2px solid transparent;
  white-space: nowrap;
}

/* Smaller tab labels on mobile (Sam, 2026-09-24). */
@media (max-width: 900px) {
  .rotatingCards__tab {
    font-size: var(--font-16);
  }
}

.rotatingCards__tab.isActive {
  font-weight: 600;
  background: var(--gradient-brand);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  /* Same flattened-stroke defect as .linkCallToAction: read off the isolated render of
     626:2373, the active tab's rule ramps green→blue across that tab's own width
     (167px) — x=0 (64,209,159), centre (55,170,192), x=max (48,141,216). */
  border-image: var(--gradient-brand) 1;
}

/* Figma's "Rotating Card" (0:12 inside 626:2373) is a fixed 1384 x 750 frame —
   it does not hug its content. The content block ("Frame 248", 712x462) sits at
   y=224 with 64px below it, so the surplus height all collects above the icon.
   Hugging content gave 597.6px, 152px short. min-height rather than height so
   narrower viewports can still grow when the copy wraps to more lines. */
/* The four cards, in one column without JS. js/rotating-cards.js adds
   .rotatingCards--deck and turns them into the Figma deck (626:2373 "Rotating
   Card"): the front card at full size, and the cards behind it peeking above its
   top edge, smaller and higher each step back — 0.971 / 0.942 / 0.916 scale,
   28 / 53 / 69px up (1344 / 1304 / 1268 of 1384 wide; tops at y 41 / 16 / 0
   against the front card's 69). No tilt: Figma's deck is flat. Scroll or a tab
   brings the next card up into the front. */
.rotatingCards__stack {
  display: flex;
  flex-direction: column;
  gap: var(--space-7);
}

.rotatingCards--deck .rotatingCards__tabs {
  position: static;
  padding-top: 0;
  background: none; /* the pinned deck never slides under it */
  justify-content: space-between; /* Figma spreads the four tabs across the width */
}

/* One grid cell holds all four cards, so they share the tallest card's height.
   The top padding is the room the peeking cards need (set from JS so it scales
   with the viewport); the bottom padding keeps the front card's drop shadow.
   The clip hides only what sits below that — the incoming card waits there —
   and leaves the peeks and shadows above and beside the deck alone. */
.rotatingCards--deck .rotatingCards__stack {
  display: grid;
  /* HOME-06: an implicit auto track sized to the widest card's min-content
     (996px at 1000), overflowing the 900px deck. */
  grid-template-columns: minmax(0, 1fr);
  gap: 0;
  padding-top: var(--deckPeek, 69px);
  padding-bottom: var(--space-7);
  clip-path: inset(-100vh -100vw 0 -100vw);
}

.rotatingCards--deck .rotatingCards__slot {
  grid-area: 1 / 1;
}

.rotatingCards--deck .rotatingCards__panel {
  height: 100%;
}

/* Phones and small tablets (no mockup at these widths). The stacked card is
   taller than the screen, so in the deck the photo moves above the copy, the two
   48px copy gaps drop to 24, and the photo shrinks to whatever height is left
   once the tabs, the peeks and the copy fit on screen — js/rotating-cards.js
   sets --deckCard to that and adds .rotatingCards--deckFit. If even the copy
   cannot fit, neither is set: the photo keeps its 2:1 and the deck pins by its
   bottom edge, so only the top of the photo is lost. */
@media (max-width: 900px) {
  .rotatingCards--deck .rotatingCards__image {
    order: -1;
  }
  .rotatingCards--deckFit .rotatingCards__panel {
    height: var(--deckCard);
  }
  .rotatingCards--deckFit .rotatingCards__image {
    flex: 1 1 0;
    min-height: 0;
    aspect-ratio: auto;
  }
  .rotatingCards--deck .rotatingCards__info {
    flex: 0 0 auto;
  }
  .rotatingCards--deck .rotatingCards__kicker,
  .rotatingCards--deck .rotatingCards__description {
    margin-bottom: var(--clamp-rem-24);
  }
}

.rotatingCards__panel {
  display: flex;
  background: var(--color-panel-dark); /* 4185:3729 — #161616, not the page black */
  transform-origin: top center;
  /* Figma's 750, but short screens keep the whole deck (tabs, peeks and card)
     in view while it is pinned; the content needs about 520. */
  min-height: clamp(520px, calc(100svh - 240px), 750px);
  border: 1px solid var(--color-border-mid);
  border-image: var(--gradient-line-1) 1;
  box-shadow: 0 12px 30px 0 rgba(0, 0, 0, 0.25);
}

.rotatingCards__info {
  flex: 1;
  min-width: 0;
  padding: var(--space-8) var(--space-8);
  display: flex;
  flex-direction: column;
  /* Not centred: in Figma the stack is anchored to the bottom inset (ends 64px
     above the frame edge) and the 750px frame's slack sits above it. */
  justify-content: flex-end;
  /* No flex gap: Figma nests these in two frames with different rhythms — icon +
     heading + kicker are a 16px-gap group ("Frame 258"), and only below that does
     the 48px rhythm to the paragraph and the button apply ("Frame 248"). A single
     48px gap compounded with the per-element margins below and gave 64/64/80/96
     where the design has 16/16/48/48. Derived from absolute y in 626:2373: icon
     ends 96, h2 at 112, h2 ends 228, kicker at 244, group ends 272, p at 320,
     p ends 364, button at 412. */
  gap: 0;
}

.rotatingCards__icon {
  width: 96px;
  height: 96px;
  margin-bottom: var(--space-4);
}

.rotatingCards__heading {
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-48);
  line-height: 1.2;
  margin-bottom: var(--clamp-rem-16);
}

.rotatingCards__kicker {
  font-family: var(--font-body);
  font-weight: 500;
  font-size: var(--font-20);
  letter-spacing: 1px;
  text-transform: uppercase;
  background: var(--gradient-brand);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  margin-bottom: var(--clamp-rem-48);
  text-wrap: pretty; /* HOME-04: keeps the trademark symbol off a line of its own */
}

.rotatingCards__description {
  font-size: var(--font-16);
  letter-spacing: 0.1px;
  margin-bottom: var(--clamp-rem-48);
}

.rotatingCards__image {
  width: 544px;
  max-width: 40%;
  flex-shrink: 0;
  object-fit: cover;
}

/* --------------------------------------------------------------------------
   Per-panel accents — the four named frames on the Components page
   (4185:3727 / :3748 / :3770 / :3829). Each solution carries its own ramp on the
   kicker and its own stroke colour on the button, and its icon keeps the
   artwork's own aspect rather than a shared 96px square. The build had one brand
   ramp and one 96px square on all four.
   -------------------------------------------------------------------------- */
/* background-image, never the `background` shorthand: the shorthand resets
   background-clip to border-box, which paints the ramp as a solid bar behind
   transparent text instead of through the glyphs. */
.rotatingCards__panel--homeLowVoltage .rotatingCards__kicker {
  background-image: var(--gradient-brand);
}
/* Each panel strokes its button with its own ramp, not a flat stop-0 hex —
   same border-image treatment as the base .button. */
.rotatingCards__panel--homeLowVoltage .button--outline {
  border-image: var(--gradient-brand) 1;
}

.rotatingCards__panel--homeHighVoltage .rotatingCards__kicker {
  background-image: var(--gradient-orange);
}
.rotatingCards__panel--homeHighVoltage .button--outline {
  border-image: var(--gradient-orange) 1; /* Orange Gradient stop 0 */
}
.rotatingCards__panel--homeHighVoltage .rotatingCards__icon {
  width: 51.17px; /* 4185:3758 — 51.167 x 64 */
  height: 64px;
}

.rotatingCards__panel--homeControlBoxes .rotatingCards__kicker {
  background-image: var(--gradient-control-box);
}
.rotatingCards__panel--homeControlBoxes .button--outline {
  border-image: var(--gradient-control-box) 1; /* Red Gradient stop 0 */
}
.rotatingCards__panel--homeControlBoxes .rotatingCards__icon {
  width: 71px; /* 4185:3780 — 71 x 64 */
  height: 64px;
}

.rotatingCards__panel--homeEngineeredComponents .rotatingCards__kicker {
  background-image: var(--gradient-blue);
}
.rotatingCards__panel--homeEngineeredComponents .button--outline {
  border-image: var(--gradient-blue) 1; /* Blue Gradient stop 0 */
}
.rotatingCards__panel--homeEngineeredComponents .rotatingCards__icon {
  width: 64px; /* 4185:3839 — 64 x 64 */
  height: 64px;
}


@media (max-width: 900px) {
  /* Stacked, the 750px floor would just add dead space above the icon. */
  .rotatingCards__panel {
    flex-direction: column;
    min-height: 0;
  }
  .rotatingCards__info {
    justify-content: flex-start;
  }
  /* F3: 2/1 is the measured stacked proportion (493 x 240 = 2.054). */
  .rotatingCards__image {
    width: 100%;
    max-width: 100%;
    aspect-ratio: 2 / 1;
  }
}

/* --------------------------------------------------------------------------
   Stats grid (Our Commitment / Delivering Value)
   -------------------------------------------------------------------------- */
.commitment {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-9);
  text-align: center;
  padding-block: var(--space-9);
  /* Frame fill on 403:230 — was a flat #1c2624, which is nowhere in the design.
     Unlike .solutions, this one is the shared Background Gradient style at its
     documented stops, just pointing down: teal at the top, black at the bottom.
     Verified against the Figma render, mean error 0.90/255. */
  background: linear-gradient(to bottom, var(--gradient-bg-stops));
}

/* Figma 626:1173 — eyebrow +16 heading, +48 lede, +48 button. The 48s come
   from .sectionLead's own block margins, so the .button needs no extra margin. */
/* HOME-09 2026-09-24: Figma Frame 283 (626:1173) is 680px of the 1512 page,
   680 / 1512 = 44.97%. Was max-width: min(900px, 100%), with no width. */
.commitment__intro {
  width: 44.97%;
  max-width: calc(var(--contentMax) * 0.4497);
}

/* Width steps below the 1400 design width; max-width stays at the Figma
   fraction. Tuned so each step changes the width by 150px or less: phones
   91.53%, tablets 78%, laptops 62% then 52%. */
@media (max-width: 1399px) {
  .commitment__intro {
    width: 52%;
  }
}

@media (max-width: 1199px) {
  .commitment__intro {
    width: 62%;
  }
}

@media (max-width: 900px) {
  .commitment__intro {
    width: 78%;
  }
}

@media (max-width: 600px) {
  .commitment__intro {
    width: 91.53%;
  }
}

.statisticsGrid {
  width: 100%;
  max-width: 1160px;
  margin-inline: auto;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0;
  text-align: left;
}

.statisticsGrid .statisticCard {
  border: 1px solid var(--color-border-light);
  padding-block: clamp(12.25px, 1.62vw, 31.1px); /* was 24.5px */
  padding-inline: clamp(12.25px, 1.62vw, 31.1px); /* was 24.5px */
  margin: -1px 0 0 -1px;
}

.statisticsGrid .statisticCard h3 {
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-20);
  margin-bottom: var(--clamp-rem-16);
}

.statisticsGrid .statisticCard p {
  font-size: var(--font-16);
  letter-spacing: 0.1px;
}

.statisticsGrid__divider {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-6);
  padding: var(--space-7) 0;
}

.statisticsGrid__divider h3 {
  flex: 1;
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-36);
  text-align: center;
}

.statisticsGrid__mark {
  width: 140px;
  height: 140px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  border: 1px solid var(--color-border-light);
  position: relative;
}
.statisticsGrid__mark::before,
.statisticsGrid__mark::after {
  content: '';
  position: absolute;
  border: 1px solid var(--color-border-light);
  border-radius: 50%;
  inset: -22px;
}
.statisticsGrid__mark::after {
  inset: -44px;
}
.statisticsGrid__mark img {
  width: 64px;
  height: 58px;
}

@media (max-width: 900px) {
  .statisticsGrid {
    grid-template-columns: 1fr;
  }
  .statisticsGrid .statisticCard {
    margin: -1px 0 0 0;
  }
  .statisticsGrid__divider {
    flex-direction: column;
  }
  .statisticsGrid__mark::before,
  .statisticsGrid__mark::after {
    display: none;
  }
}

/* --------------------------------------------------------------------------
   Value grid — Figma Frame 384 (1321:792) + Frame 385 (1321:793) in Frame 310
   -------------------------------------------------------------------------- */
/* Frame 310 (626:1057) stacks Frame 384, the divider (Frame 309) and Frame 385
   45px apart — the section's 96px rhythm applies between the intro and this
   stack, not inside it. Restoring the divider means dropping it in as the
   middle child; the 45px either side is already right. */
.valueStack {
  width: 100%;
  max-width: 1384px;
  margin-inline: auto;
  display: flex;
  flex-direction: column;
  gap: clamp(22.5px, 2.98vw, 57.2px); /* was 45px */
}

/* The cards are NOT a contiguous grid: they are four separate 494.286 x 155
   boxes at x=0 / x=889.714, y=0 / y=200, leaving a 395.43px channel down the
   middle that holds only the connector vectors. 494.286 / 395.43 / 494.286 is
   exactly 5fr / 4fr / 5fr of 1384, so the channel is a real grid column rather
   than a gap — the connectors live in it and stay aligned as it scales. */
.valueGrid {
  /* Frame 384/385 geometry, clamped: 45px row gap and a 76px top pad on the
     lower grid. The connectors are absolutely positioned across both, so they
     read these same variables — a bare px offset drifts out of alignment the
     moment either clamp leaves its floor, which is what was wrong here. Card
     rows do NOT scale (minmax(155px, auto)), so offsets measured inside a row
     stay in px. */
  --valueGrid-rowGap: clamp(22.5px, 2.98vw, 57.2px);
  --valueGridLower-pad: clamp(38px, 5.03vw, 96.6px);
  --valueGrid-rowHeight: 155px;
  width: 100%;
  margin-inline: auto;
  display: grid;
  grid-template-columns: 5fr 4fr 5fr;
  /* 45px, not a spacing token: 200 (row 2 top) - 155 (row height). */
  grid-template-rows: minmax(155px, auto) minmax(155px, auto);
  row-gap: var(--valueGrid-rowGap);
  text-align: left;
}

.valueCard:nth-child(1) {
  grid-column: 1;
  grid-row: 1;
}
.valueCard:nth-child(2) {
  grid-column: 3;
  grid-row: 1;
}
.valueCard:nth-child(3) {
  grid-column: 1;
  grid-row: 2;
}
.valueCard:nth-child(4) {
  grid-column: 3;
  grid-row: 2;
}
.valueLinks--upper {
  grid-column: 2;
  grid-row: 1;
}
.valueLinks--lower {
  grid-column: 2;
  grid-row: 2;
}

/* 24.5px all round. Figma also puts a 4px bottom pad on the inner text column
   (626:1063), but folding that in overflows the 155px box once the 1px border
   is counted under border-box — three lines of 22.4px leading plus 53px of
   padding plus 4px comes to 156.2 in 153px of content box, which pushed every
   row to 158.2 and the grid to 361. Dropping it holds the cards at exactly 155
   and the grid at 355, at the cost of the text sitting ~1.5px lower than
   Figma's own 24.5 / 35.5 offsets. That rhythm matters more: the connector y
   offsets below are calibrated to 155 / 45 / 155.
   Figma top-aligns On-Time Delivery (626:1070) at 24.5 while centring the other
   short card at 35.5 — an 11px inconsistency in the file, not intent, so all
   four centre here. */
.valueCard {
  min-height: 155px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--space-4);
  padding-block: clamp(12.25px, 1.62vw, 31.1px); /* was 24.5px */
  padding-inline: clamp(12.25px, 1.62vw, 31.1px); /* was 24.5px */
  /* Not flat, despite the MCP reporting `border-[#c8c8c8]`: measured off an
     isolated render of 626:1062, this is the Line Gradient profile in #c8c8c8 —
     left/right edges at 0.935, fading to transparent at the centre of the top and
     bottom runs. border-image's slicing reproduces that exactly, same as
     .leaderCard does with --gradient-line-1. */
  border: 1px solid var(--color-border-light);
  border-image: var(--gradient-line-3) 1;
}

/* Mobile gap raised from --space-4 (Sam, 2026-09-24). */
@media (max-width: 900px) {
  .valueCard {
    gap: var(--space-8);
  }
}

.valueCard h3 {
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-20);
  line-height: 1.15; /* was 1; Figma 20px on 20px */
}

.valueCard p {
  font-size: var(--font-16);
  line-height: 1.4;
  letter-spacing: 0.1px;
}

/* Connector channel. Each vector is a 1px white elbow with a 2.667px-radius
   dot at each end — the SVG paths are filled white, so these are brighter than
   the #c8c8c8 card borders. Drawn in CSS rather than as four SVG assets so the
   1px strokes and round dots survive the channel scaling with the viewport. */
.valueLinks {
  position: relative;
  pointer-events: none;
}

.valueLink {
  position: absolute;
}

.valueLink::before,
.valueLink::after {
  content: '';
  position: absolute;
  width: 5.33px;
  height: 5.33px;
  border-radius: 50%;
  background: var(--color-white);
}

/* Vectors 14/15: rule at y=63 spanning the full channel (495 -> 889), stem
   down the centre (x=692) to y=305. */
.valueLink--upper {
  left: 0;
  right: 0;
  top: 63px;
  border-top: 1px solid var(--color-white);
}
.valueLink--upper::before {
  left: -2.67px;
  top: -2.17px;
}
.valueLink--upper::after {
  right: -2.67px;
  top: -2.17px;
}

/* 92px of row 1 below the rule, then the row gap, then 105px into row 2. */
.valueLink--stem {
  left: calc(50% - 0.5px);
  top: 63px;
  height: calc(92px + var(--valueGrid-rowGap) + 105px);
  border-left: 1px solid var(--color-white);
}
.valueLink--stem::before {
  display: none;
}
.valueLink--stem::after {
  left: -2.17px;
  bottom: -2.67px;
}

/* Vectors 11/13: elbows at y=235 (35 into row 2), turning down 95px at 28px
   either side of centre (x=664 and x=720). */
.valueLink--lowerLeft,
.valueLink--lowerRight {
  top: 35px;
  height: 95px;
  width: calc(50% - 28px);
  border-top: 1px solid var(--color-white);
}

.valueLink--lowerLeft {
  left: 0;
  border-right: 1px solid var(--color-white);
}
.valueLink--lowerLeft::before {
  left: -2.67px;
  top: -2.17px;
}
.valueLink--lowerLeft::after {
  right: -2.17px;
  bottom: -2.67px;
}

.valueLink--lowerRight {
  right: 0;
  border-left: 1px solid var(--color-white);
}
.valueLink--lowerRight::before {
  right: -2.67px;
  top: -2.17px;
}
.valueLink--lowerRight::after {
  left: -2.17px;
  bottom: -2.67px;
}

/* --- Frame 385 (1321:793), 1384 x 431 ------------------------------------
   Same grid and cards, but the connectors rise out of the channel toward the
   divider rather than descending, and they attach at different offsets, so this
   is NOT a straight vertical mirror of Frame 384. Figma puts the card rows at
   y=76 and y=276 of a 431-tall frame; the 76px pad is the clearance the rising
   stems need above the first row. Cards 626:1092 / 1097 / 1101 / 1105. */
.valueGrid--lower {
  padding-top: var(--valueGridLower-pad);
}

/* Updated 2026-09-24 to the current Figma (Frame 385 is now 1384 x 355, rows at
   y=0 / 200): Vectors 16/17 attach 72px into the first row and rise 118px, so
   the dots sit 46px above it. Was: rules at y=98 — 22px into the first row — turning up 98px at
   x=664 and x=720 to the frame top, dotted at the card edge and at the top of
   each stem. Same elbows as Frame 384's lower pair, flipped vertically. */
.valueLink--riseLeft,
.valueLink--riseRight {
  top: calc(var(--valueGridLower-pad) * -46 / 76);
  height: calc(var(--valueGridLower-pad) * 46 / 76 + 72px); /* 72px into row 1 */
  width: calc(50% - 28px);
  border-bottom: 1px solid var(--color-white);
}

.valueLink--riseLeft {
  left: 0;
  border-right: 1px solid var(--color-white);
}
.valueLink--riseLeft::before {
  left: -2.67px;
  bottom: -2.17px;
}
.valueLink--riseLeft::after {
  right: -2.17px;
  top: -2.67px;
}

.valueLink--riseRight {
  right: 0;
  border-left: 1px solid var(--color-white);
}
.valueLink--riseRight::before {
  right: -2.67px;
  bottom: -2.17px;
}
.valueLink--riseRight::after {
  left: -2.17px;
  top: -2.67px;
}

/* Updated 2026-09-24: Vectors 18/19 now attach 72px into the second row, and the
   centre stem rises 286px from there, to 14px above the first row. Was: the long rule at y=259, which lands 17px ABOVE the second row
   — inside the row gap — with the centre stem rising 235px from it to y=24.
   Anchored to row 2 so it stays pinned to the lower cards if they grow. */
.valueLink--ruleLow {
  left: 0;
  right: 0;
  top: 72px;
  border-top: 1px solid var(--color-white);
}
.valueLink--ruleLow::before {
  left: -2.67px;
  top: -2.17px;
}
.valueLink--ruleLow::after {
  right: -2.67px;
  top: -2.17px;
}

/* 72px of row 2, the gap, all of row 1, then 14px above it (was 28px of the
   gap, row 1, and 52 of the pad's 76). */
.valueLink--stemUp {
  left: calc(50% - 0.5px);
  top: calc((var(--valueGrid-rowGap) + var(--valueGrid-rowHeight) + var(--valueGridLower-pad) * 14 / 76) * -1);
  height: calc(var(--valueGrid-rowGap) + var(--valueGrid-rowHeight) + var(--valueGridLower-pad) * 14 / 76 + 72px);
  border-left: 1px solid var(--color-white);
}
.valueLink--stemUp::before {
  display: none;
}
.valueLink--stemUp::after {
  left: -2.17px;
  top: -2.67px;
}

/* --- Frame 309 (626:1078), 1384 x 329 ------------------------------------
   The divider between the two card grids. Nothing here is tokenised: the 40px
   gaps, the three ring diameters and the 36px type are all raw values in the
   file (`get_variable_defs` on this node returns only the zero token). */
.valueDivider {
  display: flex;
  align-items: center;
  gap: 40px;
}

.valueDivider h3 {
  flex: 1;
  min-width: 0;
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-36);
  line-height: 1.15; /* was 1.04 */
  text-align: center;
}

/* Three concentric 1px rings — 329, 286 and 219 — drawn as SVG circles rather
   than borders (border-image cannot follow border-radius). Their stroke is the
   --gradient-line-3 profile, which on a circle puts the strongest arc at 3 and 9
   o'clock and a clean gap at 12 and 6, AND each ring carries a different
   strength: 20% / 60% / 100% outward-in, so the assembly fades outward. Both the
   ramp and the per-ring strength are invisible to the MCP, which reports all
   three as a flat #c8c8c8. Stops and stroke-opacity live in the markup.
   Everything derives from --mark so one value rescales the whole assembly. */
.valueDivider__mark {
  --mark: 329px;
  position: relative;
  flex: 0 0 var(--mark);
  width: var(--mark);
  height: var(--mark);
}

.valueDivider__rings {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
}

/* Figma sits the mark 16px right of and 10.41px above the ring centre — the
   asymmetric padding on Frame 306 (14 top / 36 left / 4 right / 36 bottom).
   That is its optical centre, so the offset is kept rather than corrected. */
/* Pulse waves (Sam, 2026-09-24, after codepen.io/peeke/pen/BjxXZa and
   kirupa.com's pulsing circle): four rings ripple out from behind the logo past
   the outer Figma ring and fade, a quarter cycle apart, so there are always
   several waves in flight. Stroke is the rings' own #c8c8c8. Off for reduced
   motion. */
.valueDivider__pulses {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.valueDivider__pulse {
  position: absolute;
  inset: 0;
  border: 2px solid rgba(200, 200, 200, 0.45);
  border-radius: 50%;
  opacity: 0;
  animation: valueRingPulse 6s cubic-bezier(0.215, 0.61, 0.355, 1) infinite;
}

.valueDivider__pulse:nth-child(2) {
  animation-delay: 1.5s;
}

.valueDivider__pulse:nth-child(3) {
  animation-delay: 3s;
}

.valueDivider__pulse:nth-child(4) {
  animation-delay: 4.5s;
}

@keyframes valueRingPulse {
  0% {
    transform: scale(0.45);
    opacity: 0;
  }
  10% {
    opacity: 1;
  }
  100% {
    transform: scale(1.3);
    opacity: 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .valueDivider__pulse {
    animation: none;
  }
}

.valueDivider__mark img {
  position: absolute;
  top: 50%;
  left: 50%;
  width: calc(var(--mark) * 151 / 329);
  height: calc(var(--mark) * 136.172 / 329);
  transform: translate(calc(-50% + var(--mark) * 16 / 329), calc(-50% - var(--mark) * 10.41 / 329));
  z-index: 1; /* above the pulse rings */
}

/* Below ~1200 the cards need more than 155px for their copy, so the rows stop
   matching the connectors' fixed y offsets — drop the channel and close up to
   an even two-up. With the connectors gone, Frame 385's clearance band goes
   with them, and the rings shrink to leave the headings room.
   HOME-07 (2026-09-24): raised from 1200 to 1399 so the flush-edge diagram
   never shows below 1400. */
@media (max-width: 1399px) {
  .valueStack {
    padding-inline: 0;
    width: calc(100% - (var(--gutter) * 2));
    margin-inline: auto;
  }
  .valueGrid {
    grid-template-columns: 1fr 1fr;
    column-gap: var(--space-6);
  }
  .valueGrid--lower {
    padding-top: 0;
  }
  .valueDivider__mark {
    --mark: 240px;
  }
  .valueCard:nth-child(2),
  .valueCard:nth-child(4) {
    grid-column: 2;
  }
  .valueLinks {
    display: none;
  }
}

/* HOME-07 (2026-09-24): the 1384px stack reaches the screen edges below the
   design width, so 1400-1511 takes the page gutter. Rows stay at 155px, so the
   connectors keep their alignment. */
@media (min-width: 1400px) and (max-width: 1511px) {
  .valueStack {
    width: calc(100% - (var(--gutter) * 2));
  }
}

@media (max-width: 900px) {
  .valueGrid {
    grid-template-columns: 1fr;
  }
  .valueCard:nth-child(1),
  .valueCard:nth-child(2),
  .valueCard:nth-child(3),
  .valueCard:nth-child(4) {
    grid-column: 1;
    grid-row: auto;
  }
  .valueDivider {
    flex-direction: column;
    gap: var(--space-6);
    padding: var(--space-8) 0;
  }
  .valueDivider h3 {
    flex: none;
  }
  .valueDivider__mark {
    --mark: 200px;
  }
}

/* --------------------------------------------------------------------------
   Megatrends
   -------------------------------------------------------------------------- */
/* section-scoped: WordPress adds the page slug as a body class, so a bare
   .megatrends here also matched <body> on /megatrends/ and shrink-wrapped main. */
section.megatrends {
  /* No top padding: the 96 above this section is the wrapper's gap. */
  padding-block: 0 var(--space-8);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-8);
  text-align: center;
}

.megatrends__intro {
  /* HOME-02: the gutter keeps the heading and button off the phone's edges
     (the section itself is full width). */
  max-width: min(900px, calc(100% - (var(--gutter) * 2)));
  margin: 0 auto var(--space-8);
}

/* Figma 409:76 — eyebrow +16 heading, +48 button (no lede in this section) */
.megatrends__intro .button {
  /* text-to-button gap: 48px in Figma */
  margin-top: var(--clamp-rem-48);
}

.megatrends__grid {
  padding-inline: 0;
  width: 91.53%;
  max-width: calc(var(--contentMax) * 0.9153);
  margin-inline: auto;
  display: grid;
  /* minmax(0, 1fr), not 1fr: a bare 1fr track has a min-content floor, so the
     nowrap "Learn About ..." links held the cards wider than the grid (HOME-02). */
  grid-template-columns: repeat(4, minmax(0, 1fr));
  row-gap: var(--space-4);
  column-gap: var(--space-4);
  margin-bottom: var(--space-8);
  text-align: left;
}

.megatrendCard {
  border: 1px solid var(--color-border-mid);
  border-image: var(--gradient-line-1) 1;
  padding: var(--space-5) var(--space-5);
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}

/* Mobile gap (Sam, 2026-09-24). */
@media (max-width: 900px) {
  .megatrendCard {
    gap: var(--space-7);
  }
}

/* Frame 272 / 271 / 273 (443:183, 443:186, 443:189, 443:192) — all 80 x 80. The
   exported SVG is the WHOLE frame: it carries its own 1px ring as
   `<rect rx="39.5">` stroked with the brand ramp, plus the glyph inside it. So
   the img fills the box at 80 and there is no CSS border — a `2px solid
   var(--color-brand-teal)` here used to draw a second, thicker, FLAT ring around
   the SVG's own gradient one. Verified against the isolated render of card 1
   (409:310): the ring measures 80 x 80 at x 25-104 inside the card's 25 padding.
   The glyph is a different size in every card (34x34, 24x40, 33.449x30, 41x30)
   and each is centred by its own 80 canvas, so nothing here sizes the glyph. */
.megatrendCard__icon {
  width: 80px;
  height: 80px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.megatrendCard__icon img {
  width: 100%;
  height: 100%;
}

.megatrendCard h3 {
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-22);
  line-height: 1.2;
}

.megatrendCard p {
  font-size: var(--font-16);
  line-height: 1.4;
  flex: 1;
}

/* HOME-02 (2026-09-23): 2-up from 1200 (four ~270px cards were too narrow for
   their copy between 1020 and 1220), 1-up at 600. The card link and the intro
   button may wrap rather than force width. */
.megatrendCard .linkCallToAction {
  max-width: 100%;
}
@media (max-width: 1200px) {
  .megatrends__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
@media (max-width: 600px) {
  .megatrends__grid {
    grid-template-columns: minmax(0, 1fr);
    row-gap: var(--space-6);
    column-gap: var(--space-6);
  }
  .megatrends__intro .button {
    white-space: normal;
    max-width: 100%;
  }
}

/* --------------------------------------------------------------------------
   Markets segments (Figma Frame 326, 710:4559 — redesigned 2026-08-04)
   --------------------------------------------------------------------------
   One section, two bordered panels. The section gradient runs UPWARDS here
   (the old electrification band ran to the left), over the shared stops. */
/* Frame 412 (1935:2444): the heading block sits above the two panels, so the
   section is now a column and the old flex row moved to .marketsSegment__panels. */
.marketsSegment {
  display: flex;
  flex-direction: column;
  /* Bottom spacing is the .marketsMegatrends gap, not this section's. */
  padding: var(--space-8) var(--gutter) 0;
  max-width: var(--contentMax);
  margin-inline: auto;
}

/* Frame 328 (710:4561) — the full-bleed frame holding BOTH the markets panels
   (Frame 412) and the megatrends (Frame 411). Its fill is not emitted by the
   MCP; solved off the node render by least-squares on the green and blue
   channels of a 40px left-edge column over the full 1778px height (no content
   reaches that column). Stops 13.25% / 93.00%, MAE 0.29/255 on GB, 0.47 across
   RGB. NOT the shared --gradient-bg-stops read bottom-up (8.173% / 90.865%),
   which fits nearly 6x worse at MAE 1.68 — the handles were dragged, as on
   .companiesIntro. The ramp belongs to the pair, not to either section: it
   begins inside the markets block and finishes at the foot of the megatrends.
   .marketsSegment used to carry a gradient of its own, which stopped at
   --contentMax and never reached the megatrends at all. */
.marketsMegatrends {
  background: linear-gradient(180deg, var(--color-black) 13.25%, #0e343d 93%);
  /* Figma stacks Frame 412 (markets) and Frame 411 (megatrends) 96px apart
     inside Frame 328 — 840 -> 936. The build was summing .marketsSegment's
     96px bottom padding, .megatrends' 64px top padding and the intro's 64px top
     margin, so the gap came out at 224 (284 once the clamps hit max). The gap
     belongs to this wrapper; the three contributors below are zeroed. */
  display: flex;
  flex-direction: column;
  gap: var(--space-9);
}

/* Frame 248 (1935:2438) — centred, 89 tall, 64px above the panels. */
.marketsSegment__intro {
  text-align: center;
  margin-bottom: var(--space-8);
}

.marketsSegment__panels {
  display: flex;
  align-items: stretch;
  gap: var(--space-4);
}

/* Mobile gap raised from --space-4 (Sam, 2026-09-24). */
@media (max-width: 900px) {
  .marketsSegment__panels {
    gap: var(--space-8);
  }
}

/* Container 1339:1719 / 1339:1734. Both flex:1; the 460px cap on the narrow one
   is what splits Figma's 1384px of content into 908 + 16 + 460. */
.marketsPanel {
  flex: 1;
  min-width: 0;
  border: 1px solid #ebebeb;
  border-image: var(--gradient-line-2) 1;
  padding-block: clamp(12.5px, 1.65vw, 31.7px); /* was 25px */
  padding-inline: clamp(12.5px, 1.65vw, 31.7px); /* was 25px */
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}

.marketsPanel--narrow {
  max-width: 460px;
}

/* Frame 388 — the 80px icon (its teal ring is part of the SVG, unlike
   .megatrendCard__icon where the ring is a CSS border) + the panel title. */
.marketsPanel__head {
  display: flex;
  align-items: center;
  gap: var(--space-5);
}

.marketsPanel__icon {
  flex-shrink: 0;
  line-height: 0;
}
.marketsPanel__icon img {
  display: block;
  width: 80px;
  height: 80px;
}

.marketsPanel__head h3 {
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-24);
  line-height: 1.2;
}

.marketsPanel__body {
  display: flex;
  align-items: stretch;
  flex: 1;
  min-height: 0;
}

/* Frame 250 / Frame 249 — a column of cells, gap 0. */
.marketsPanel__column {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Each cell overlaps its neighbour by 1px so the shared edge reads as a single
   rule, the way Figma's centre-aligned strokes do. Padding-block is 23.5 rather
   than the 24.5 the MCP reports: with border-box the 1px stroke is inside the
   box, and 23.5 + 32 + 23.5 + 2 lands the cell on Figma's 81px exactly. */
.marketsPanel__column > li {
  border: 1px solid var(--color-border-mid);
  border-image: var(--gradient-line-1) 1;
  padding-block: clamp(11.75px, 1.55vw, 29.8px); /* was 23.5px */
  padding-inline: clamp(24.25px, 3.21vw, 61.6px); /* was 48.5px */
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-16);
  line-height: 2; /* Figma 32px on 16px */
  transition:
    background-image 0.2s ease,
    padding-left 0.2s ease;
}

/* Block 1 Default (626:1286) → Gradient (626:1285): the Hover Gradient fill
   plus padding-left 48.5 → 64.5 (--sds-size-space-1200 → 1600). The border and
   every other property are unchanged between the two variants. The spacer and
   the CTA cell are not Block 1 instances, so neither takes the state. */
.marketsPanel__column > li:not(.marketsPanel__spacer):not(.marketsPanel__callToActionCell):hover {
  background-image: var(--gradient-hover);
  padding-left: calc(clamp(24.25px, 3.21vw, 61.6px) + 16px); /* was 64.5px, = base + 16 */
}

.marketsPanel__column > li + li {
  margin-top: -1px;
}
.marketsPanel__column + .marketsPanel__column {
  margin-left: -1px;
}

/* Block 14 (1339:1885) — a transparent cell holding the row open. */
.marketsPanel__spacer {
  opacity: 0;
}
.marketsPanel__spacer::before {
  content: '';
  display: block;
  height: 32px;
}

/* The CTA is the column's last cell and takes whatever height is left. The
   selector has to out-specify `.marketsPanel__column > li` above, which carries a
   type selector — a bare class loses to it and the cell keeps the cell padding. */
.marketsPanel__column > li.marketsPanel__callToActionCell {
  border: 0;
  padding: 0;
  flex: 1;
  min-height: 0;
  display: flex;
  margin-top: -1px;
}

.marketsPanel__callToAction {
  flex: 1;
  max-width: none;
  justify-content: flex-start;
  padding-block: clamp(8.5px, 1.12vw, 21.5px); /* was 17px */
  padding-inline: clamp(24.5px, 3.24vw, 62.2px); /* was 49px */
}

/* This CTA is a .button--primary, so it inherits the fill change — but not the
   arrow nudge: its 49px inset is a panel-cell measurement, and .button--primary's
   hover would otherwise collapse it to 17px. */
.marketsPanel__callToAction:hover {
  padding-right: clamp(24.5px, 3.24vw, 62.2px); /* was 49px, re-asserts the base */
}

/* HOME-01 (2026-09-23). This rule used to stack .marketsSegment, which is
   already a column, so the panels never stacked and E & I overflowed by up to
   97px between ~1100 and 800.
   1410 and under: the cells' wide 48.5px-based inset tightens so the two-up
   row keeps its labels on one line for longer. */
@media (max-width: 1410px) {
  .marketsPanel__column > li {
    padding-inline: var(--space-6);
  }
  .marketsPanel__column > li:not(.marketsPanel__spacer):not(.marketsPanel__callToActionCell):hover {
    padding-left: calc(var(--space-6) + 16px);
  }
}

/* 1300 and under: the two panels stack, the narrow one un-caps, and the
   spacer cell (it only existed to line the two CTAs up side by side) goes.
   Below ~1250 the side-by-side E & I CTA no longer fits its cell. */
@media (max-width: 1300px) {
  .marketsSegment__panels {
    flex-direction: column;
  }
  .marketsPanel--narrow {
    max-width: none;
  }
  .marketsPanel__spacer {
    display: none;
  }
}

@media (max-width: 700px) {
  .marketsPanel__body {
    flex-direction: column;
  }
  .marketsPanel__column + .marketsPanel__column {
    margin-left: 0;
    margin-top: -1px;
  }
  .marketsPanel__column > li {
    padding-inline: var(--space-5);
  }
  /* Keep the hover indent proportional once the cells lose their wide inset. */
  .marketsPanel__column > li:not(.marketsPanel__spacer):not(.marketsPanel__callToActionCell):hover {
    padding-left: calc(var(--space-5) + 16px);
  }
}

/* --------------------------------------------------------------------------
   ECI Family / Acquisitions
   -------------------------------------------------------------------------- */
/* Background moved up here from .family__logos (that block is commented out of
   index.html for now). NOTE: still the unlicensed, visibly watermarked Adobe
   Stock comp — must be replaced before launch. */
.family {
  position: relative;
  overflow: hidden;
  padding-block: var(--space-9);
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
  /* Figma 298:1171 carries a VIDEO fill; .family__video below plays it. The still
     stays as the paint under the video — first frame, reduced motion, and any
     browser that refuses to autoplay. Same footage: the 4096x2304 original is a
     frame of 3 -AdobeStock_1952550739.mov (MAE 4.58 against frame 0). */
  background: url('../assets/images/acquisition-network-bg.png') center / cover no-repeat;
}

/* Child combinator for the same reason .hero__video uses one: `.family > *` below
   puts every child at z-index 1, and at equal specificity source order would lift
   the video above the content. width/height are required — an absolutely
   positioned replaced element resolves auto to its intrinsic 1920x1080. */
.family > .family__video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: 0;
  pointer-events: none;
}

.family > * {
  position: relative;
  z-index: 1;
}

@media (prefers-reduced-motion: reduce) {
  .family > .family__video {
    display: none;
  }
}

/* Figma 416:94 — eyebrow +16 heading, +48 lede, +48 button. Block flow rather
   than a flex column, so the three gaps can differ. */
.family__intro {
  padding-inline: 0;
  width: 31.21%;
  /* cap minus 2 gutters: the old rule put the gutter INSIDE this box, so the
     rendered measure was always cap - 2*gutter, not cap. This block is
     left-aligned in a full-bleed parent, so the gutter that used to be its
     left padding becomes a start margin. */
  /* F1 2026-09-18: cap was calc(600px - (var(--gutter) * 2)). Converted to a --contentMax fraction so the
     multiplier matches the width, per the front-end skill's width rule.
     Reverse by restoring the value above. */
  max-width: calc(var(--contentMax) * 0.3121);
  margin-inline-start: var(--gutter);
}

/* Percentage widths polish 2026-09-24: Figma 416:94 is 472 of 1512 = 31.21% from
   1400 up. Narrower screens step wider; each step changes the width by 150px or
   less (was one jump from 437px to 1098px at 1200). max-width stays at the
   Figma fraction. Phones keep the page gutter rule further down. */
@media (max-width: 1399px) {
  .family__intro {
    width: 40%;
  }
}

@media (max-width: 1199px) {
  .family__intro {
    width: 50%;
  }
}

@media (max-width: 999px) {
  .family__intro {
    width: 62%;
  }
}

@media (max-width: 900px) {
  .family__intro {
    width: 75%;
  }
}

@media (max-width: 600px) {
  .family__intro {
    width: calc(100% - (var(--gutter) * 2));
  }
}

.family__intro h2 {
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-48);
  line-height: 1.2;
  margin-bottom: var(--clamp-rem-48);
}

.family__intro p {
  font-size: var(--font-16);
  letter-spacing: 0.1px;
  line-height: 1.4;
}

/* Gradient kicker 1794:2578, added under the h2 2026-08-25. Same uppercase
   16px/1px treatment as .eyebrow, on --gradient-brand. Figma's group gap is 16px,
   so the h2 tightens to that when the kicker follows it. */
.family__intro h2:has(+ .family__kicker) {
  margin-bottom: var(--clamp-rem-16);
}

/* 1794:2578 is a whole text node on the ramp, not a highlighted span, so the
   gradient goes on the element itself — the .gradientText host/span pattern
   above does not apply. Same shape as .rotatingCards__kicker. */
.family__kicker {
  font-family: var(--font-body);
  font-weight: 500;
  font-size: var(--font-16);
  line-height: 1.15; /* was 0.938; Figma 15px on 16px */
  letter-spacing: 1px;
  text-transform: uppercase;
  width: max-content;
  max-width: 100%;
  background-image: var(--gradient-brand);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.family__intro > p:not(.eyebrow) {
  margin-bottom: var(--clamp-rem-48);
}

/* Frame 275 (414:74) — the clip only. The rotated band inside it is Frame 274
   (414:75), which is the same node as Global Locations' Frame 274, so the paint,
   rotation and loop all come from the shared .logoTicker rules further down.
   Full-bleed (no gutter), and no top margin: .family's own 64px gap is the
   Figma gap. The section background lives on .family, so this is transparent. */
.family__logos {
  position: relative;
  overflow: hidden;
  height: 267.52px;
}

.family__outcomes {
  display: flex;
  gap: 0;
  max-width: calc(var(--contentMax) * 0.9153);
  margin-inline: auto;
  padding-inline: 0;
  width: 91.53%;
}

.family__outcomes .outcomeCard {
  flex: 1;
  border: 1px solid var(--color-border-mid);
  border-image: var(--gradient-line-1) 1;
  padding-block: clamp(24.25px, 3.21vw, 61.6px); /* was 48.5px */
  padding-inline: clamp(24.25px, 3.21vw, 61.6px); /* was 48.5px */
  margin-left: -1px;
}

.family__outcomes .outcomeCard h4 {
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-24);
  line-height: 1.2;
}

@media (max-width: 900px) {
  .family__outcomes {
    flex-direction: column;
  }
  .family__outcomes .outcomeCard {
    margin-left: 0;
    margin-top: -1px;
  }
}

/* --------------------------------------------------------------------------
   Success stories
   -------------------------------------------------------------------------- */
.success {
  padding-block: var(--space-9) 0;
  background: var(--color-black);
}

.success__intro {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-7);
  text-align: center;
  /* Figma 416:278 is max-w-[680px] as of 2026-09-16 — it was 872 when this was
     built, and narrowed when the lede (1794:2581) was added to the column. */
  padding-inline: 0;
  /* Percentage widths polish 2026-09-24: 680 / 1512 = 44.97%. Was 91.53% (F1
     2026-09-18; before that the cap was 680px). */
  width: 44.97%;
  max-width: calc(var(--contentMax) * 0.4497);
  margin: 0 auto var(--space-10);
}

/* Width steps below 1400; max-width stays at the Figma fraction. Same bands as
   .commitment__intro: each step changes the width by 150px or less. */
@media (max-width: 1399px) {
  .success__intro {
    width: 52%;
  }
}

@media (max-width: 1199px) {
  .success__intro {
    width: 62%;
  }
}

@media (max-width: 900px) {
  .success__intro {
    width: 78%;
  }
}

@media (max-width: 600px) {
  .success__intro {
    width: 91.53%;
  }
}

/* Figma nests the eyebrow + heading in their own 16px-gap group, with the
   parent's 48px gap applying only between that group and the button. */
/* Figma 1794:2581 — the lede between the heading group and the CTA, inside the
   680 column. The gradient sits on "manufacturing and engineering challenges",
   which is where Figma's own text node stops; the doc runs the sentence on, and
   the doc supersedes, so the span keeps Figma's phrase and the rest is plain. */
.success__lead {
  display: flex;
  flex-direction: column;
  gap: var(--clamp-rem-16);
  font-size: var(--font-16);
  line-height: 1.4;
  letter-spacing: 0.1px;
}

.success__lead .gradientText {
  font-weight: 600;
}

/* The doc's closing paragraph, below the value grids. Figma has no node for it
   in this position, so it takes .sectionLead's 800px measure rather than the
   section width — 91.53% of a wide viewport is far too long a line for body
   copy. */
/* HOME-09 2026-09-24: was max-width: min(50em, 100%) (800px at 16px), with no
   width, so it ran edge to edge below 900.
   Percentage widths polish 2026-09-24: no Figma frame (copy-doc paragraph), so it
   takes .commitment__intro's Frame 283 fraction, 680 / 1512 = 44.97%, and the
   same steps, so the two line up. */
.commitment__closing {
  width: 44.97%;
  max-width: calc(var(--contentMax) * 0.4497);
  margin: var(--space-8) auto 0;
  text-align: center;
  font-size: var(--font-16);
  line-height: 1.4;
  letter-spacing: 0.1px;
}

@media (max-width: 1399px) {
  .commitment__closing {
    width: 52%;
  }
}

@media (max-width: 1199px) {
  .commitment__closing {
    width: 62%;
  }
}

@media (max-width: 900px) {
  .commitment__closing {
    width: 78%;
  }
}

@media (max-width: 600px) {
  .commitment__closing {
    width: 91.53%;
  }
}

.success__introHead {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--clamp-rem-16);
  width: 100%;
}

.success__introHead .eyebrow {
  margin-bottom: 0;
}

.successGrid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  row-gap: var(--space-5);
  column-gap: var(--space-5);
  padding-block: 0 var(--space-10);
  padding-inline: 0;
  width: 91.53%;
  max-width: calc(var(--contentMax) * 0.9153);
  margin-inline: auto;
}

.successCard {
  position: relative;
  height: auto;
  min-height: 360px;
  display: flex;
  align-items: flex-end;
  padding: var(--space-5) var(--space-5);
  overflow: hidden;
}

.successCard--wide {
  grid-column: 1 / -1;
}

.successCard img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: 0;
}

.successCard::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(to left, rgba(12, 12, 12, 0.85), rgba(12, 12, 12, 0));
  z-index: 1;
}

.successCard__body {
  position: relative;
  z-index: 2;
  background: rgba(12, 12, 12, 0.65);
  padding: var(--space-5) var(--space-5);
  /* Percentage widths polish 2026-09-24: % of the card's content box (card is
     680 / 1384 wide with 24px padding). Figma 306 / 632 = 48.42%. Was 306px.
     Nested in a capped card, so no --contentMax cap is needed. */
  width: 48.42%;
  max-width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: var(--clamp-rem-24);
}

/* Figma 410 / 1336 = 30.69%. Was 410px, which with growing padding pushed the
   heading to 3 lines above 1620 (HOME-13). */
.successCard--wide .successCard__body {
  width: 30.69%;
}

/* Width steps; each changes the width by 150px or less within a layout. The drop
   at 900/901 comes from the cards going two-up, not from these values. */
@media (max-width: 1511px) {
  .successCard--wide .successCard__body {
    width: 33%;
  }
}

@media (max-width: 1399px) {
  .successCard__body {
    width: 55%;
  }
  .successCard--wide .successCard__body {
    width: 36%;
  }
}

@media (max-width: 1199px) {
  .successCard__body {
    width: 75%;
  }
  .successCard--wide .successCard__body {
    width: 45%;
  }
}

@media (max-width: 900px) {
  .successCard__body,
  .successCard--wide .successCard__body {
    width: 75%;
  }
}

@media (max-width: 600px) {
  .successCard__body,
  .successCard--wide .successCard__body {
    width: 100%;
  }
}

/* Figma "Frame 282" — heading + paragraph are their own 24px-gap group, and the
   parent's space-between only distributes the leftover down to the Button Set. */
.successCard__text {
  display: flex;
  flex-direction: column;
  gap: var(--clamp-rem-24);
}

.successCard__body h3 {
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-32);
  text-transform: capitalize;
  line-height: 1.4;
}

.successCard__body p {
  font-size: var(--font-16);
  letter-spacing: 0.1px;
}

@media (max-width: 900px) {
  .successGrid {
    grid-template-columns: 1fr;
  }
}

/* --------------------------------------------------------------------------
   Life at ECI
   -------------------------------------------------------------------------- */
.life {
  position: relative;
  display: flex;
  justify-content: flex-end;
  padding: var(--space-9) var(--gutter);
  background: var(--color-black);
  overflow: hidden;
}

/* Photo layer, the same pattern as the People page's .lifeBand (Sam,
   2026-09-24). Was life-at-eci.png, which had the dark falloff baked into the
   pixels; now the clean photo ("Production Mexico", mirrored so the subject
   sits left) with the falloff drawn in CSS: the Safety band's right-hand ramp. */
.life__background {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
}

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

.life__background::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(
    to right,
    rgba(12, 12, 12, 0) 0%,
    rgba(12, 12, 12, 0.529) 40%,
    #0c0c0c 100%
  );
}

/* No scrim here. Figma 417:835 is a solid #0c0c0c fill with the photo laid over it
   at 100% — and the photo is opaque, so the fill never shows. Verified by placing
   the exported fill (center/cover) against the node render: MAE 0.52/255 across the
   whole image area, i.e. the render IS the raw photo. The overlay this replaces
   (to right, 0.15 -> 0.92 @60%) was invented; the design relies on the photo's own
   falloff to the right for panel contrast. */

.life__panel {
  position: relative;
  z-index: 1;
  /* Percentage widths polish 2026-09-24: % of .life's content box (1512 - 2 x 64
     gutter = 1384). Figma panel 417:836 is 580, 580 / 1384 = 41.91%. Was
     max-width: min(580px, 100%). */
  width: 41.91%;
  max-width: calc(var(--contentMax) * 0.4191);
  display: flex;
  flex-direction: column;
  gap: var(--space-7);
}

.life__panel h2 {
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-48);
  line-height: 1.2;
  margin-bottom: var(--clamp-rem-24);
}

.life__intro > p {
  font-size: var(--font-16);
  letter-spacing: 0.1px;
  line-height: 1.4;
}

.life__why h3 {
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-24);
  letter-spacing: 0.1px;
  margin-bottom: var(--clamp-rem-32);
}

.life__list {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}

/* Figma draws each rule as its own 2px "Line 20/21/22" rotated 90deg, with the full
   brand ramp running end to end along that one line — green at the top, blue at the
   bottom, restarting on every item (the exported SVGs are 44px and 66px long, i.e.
   the item heights, each carrying #40D39F -> #38ABC1 50% -> #2F84E2). A flat teal
   stroke, or one ramp shared down the whole list, is wrong on both counts.
   Gap from rule to text is 19px, not 16. */
.life__list li {
  display: flex;
  border-left: 2px solid transparent;
  border-image: linear-gradient(
      180deg,
      var(--color-brand-green) 0%,
      var(--color-brand-teal) 50%,
      var(--color-brand-blue) 100%
    )
    1;
  padding-left: 19px;
}

/* HOME-08 (2026-09-24): was `.life__list strong`, orphaned when <strong> was
   removed site-wide. Figma 417:874: title Inter Medium 16 on its own line,
   description Inter Regular 16 directly below (no gap). */
.life__listTitle {
  display: block;
  font-family: var(--font-body);
  font-weight: 500;
}
.life__list span {
  font-size: var(--font-16);
}

/* Width steps; each changes the width by 150px or less within a layout. The drop
   at 900/901 is the panel moving from left to right, not these values. */
@media (max-width: 1399px) {
  .life__panel {
    width: 48%;
  }
}

@media (max-width: 1199px) {
  .life__panel {
    width: 58%;
  }
}

@media (max-width: 900px) {
  .life {
    justify-content: flex-start;
  }
  /* Copy runs across the photo here, so it needs an even base, as .lifeBand does. */
  .life__background::after {
    background: rgba(12, 12, 12, 0.7);
  }
  .life__panel {
    width: 80%;
    max-width: 100%;
  }
}

@media (max-width: 600px) {
  .life__panel {
    width: 100%;
  }
}

/* --------------------------------------------------------------------------
   Latest news
   -------------------------------------------------------------------------- */
.news {
  padding-block: var(--space-10);
  padding-inline: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-7);
  width: 87.3%;
  max-width: calc(var(--contentMax) * 0.873);
  margin-inline: auto;
}

/* Mobile width (Sam, 2026-09-24): the standard 91.53% gutter width, not 87.3%. */
@media (max-width: 900px) {
  .news {
    width: 91.53%;
    max-width: calc(var(--contentMax) * 0.9153);
  }
}

/* Figma 440:181 — eyebrow +16 heading, +48 lede, +48 button. Block flow rather
   than a flex column, so the three gaps can differ. */
.news__intro {
  max-width: min(600px, 100%);
}

.news__intro h2 {
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-48);
  line-height: 1.2;
  margin-bottom: var(--clamp-rem-48);
}

.news__intro p {
  font-size: var(--font-16);
  letter-spacing: 0.1px;
  line-height: 1.4;
}

.news__intro > p:not(.eyebrow) {
  margin-bottom: var(--clamp-rem-48);
}

/* Frame 413 (1995:5856). Same bar as .rotatingCards__tabs — the #ebebeb rule the
   MCP reports flat is the already-solved --gradient-line-2 ramp — but the tabs
   are 12px uppercase with 32px side padding, and Figma marks PRESS RELEASES
   (1995:5859) as the active one. */
.newsTabs {
  display: flex;
  border-bottom: 1px solid transparent;
  border-image: var(--gradient-line-2) 1;
  margin-bottom: var(--space-6);
  overflow-x: auto;
}

.newsTabs__tab {
  padding-block: var(--space-3); /* was 12px */
  padding-inline: var(--space-6);
  font-family: var(--font-body);
  font-weight: 400;
  font-size: var(--font-12);
  line-height: 1.333; /* Figma 16px on 12px */
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--color-white);
  border-bottom: 2px solid transparent;
  white-space: nowrap;
}

/* Smaller news tabs on mobile (Sam, 2026-09-24). */
@media (max-width: 900px) {
  .newsTabs__tab {
    font-size: var(--font-14);
  }
}

.newsTabs__tab.isActive {
  font-weight: 600;
  background: var(--gradient-brand);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  border-image: var(--gradient-brand) 1;
}

/* Two featured posts per tab from 2026-09-21, so the four-column row Figma drew
   became two columns of double the width. Only the tab panels are hidden — the
   selector keys off data-panel so any future untabbed .newsGrid still renders. */
.newsGrid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  row-gap: var(--space-6);
  column-gap: var(--space-6);
}

.newsGrid[data-panel] {
  display: none;
}

.newsGrid[data-panel].isActive {
  display: grid;
}

.newsCard {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}

/* F3 2026-09-18: fixed height -> aspect-ratio. 5/3 is the measured proportion
   in the four-column grid (297 x 180 = 1.652). This is the one that changes most
   on narrow screens: the card used to stay 180 tall while its column grew to
   511, squashing the photo — now it keeps its shape. */
.newsCard__image {
  aspect-ratio: 16 / 9; /* by request 2026-09-22, was Figma's 5 / 3 */
  width: 100%;
  max-width: 100%;
  object-fit: cover;
}

/* Card copy steps up with the column. At four-up the card was 297 wide and 20/16
   sat right; at two-up it is ~627, where the same sizes read as a small caption
   floating in a wide box. One stop each, so the card grows with its image rather
   than only the photograph getting bigger. */
/* The photo and the title both link to the post, like the Read More link. */
.newsCard__imageLink {
  display: block;
}
.newsCard h3 a,
.newsCard h3 a:visited {
  color: inherit;
  text-decoration: none;
}
.newsCard h3 a:hover {
  text-decoration: underline;
}

.newsCard h3 {
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-28);
  line-height: 1.2;
}
.newsCard p {
  font-size: var(--font-18);
  line-height: 1.35;
}

/* Below 600 the grid is one column again, so the copy goes back to the sizes
   Figma drew for a single-column card. */
@media (max-width: 600px) {
  .newsCard h3 {
    font-size: var(--font-20);
  }
  .newsCard p {
    font-size: var(--font-16);
    line-height: 1.22;
  }
}

@media (max-width: 600px) {
  /* One column: more space between cards, a set gap inside each (Sam,
     2026-09-24). */
  .newsGrid {
    grid-template-columns: 1fr;
    row-gap: var(--space-8);
  }
  .newsCard {
    gap: var(--space-5);
  }
  .news {
    padding-block: var(--space-8);
    padding-inline: 0;
    width: 91.53%;
    max-width: calc(var(--contentMax) * 0.9153);
    margin-inline: auto;
  }
}

/* --------------------------------------------------------------------------
   Culture band (People page, Figma Frame 263 = 731:1338)
   The same photo-band component as .globalCallToAction (909:4623) — 1px Line Gradient 1
   border, background image under a brand ramp in mix-blend overlay and a flat
   rgba(12,12,12,0.6) veil — so it borrows those three background rules wholesale.
   Only the frame padding and the content differ: the outer frame here is 0/64
   rather than 48/64, and the band holds a 24px statement instead of a 48px
   heading + button.
   -------------------------------------------------------------------------- */
.cultureBand {
  background: var(--color-black);
  padding-block: 0;
  padding-inline: 0;
  width: 91.53%;
  max-width: calc(var(--contentMax) * 0.9153);
  margin-inline: auto;
}

.cultureBand__band {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-6);
  padding-block: var(--space-9);
  padding-inline: clamp(100px, 13.23vw, 254px); /* was 200px */
  border: 1px solid transparent;
  border-image: var(--gradient-line-1) 1;
  text-align: center;
  overflow: hidden;
}

.cultureBand__band > * {
  position: relative;
  z-index: 1;
}

.cultureBand__background {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
}

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

.cultureBand__background::before,
.cultureBand__background::after {
  content: '';
  position: absolute;
  inset: 0;
}

.cultureBand__background::before {
  background: var(--gradient-brand);
  mix-blend-mode: overlay;
}

.cultureBand__background::after {
  background: rgba(12, 12, 12, 0.6);
}

.cultureBand .eyebrow {
  margin: 0;
}

/* 984px is the band's content width (1512 - 128 outer - 400 inner) and so the
   box Figma paints the ramp across; "Our core values" shows only its green head.
   Golos Text Medium for that span, Regular for the sentence around it. */
.cultureBand__statement {
  width: 41em; /* 984 @24 */
  max-width: 100%;
  margin: 0;
  font-family: var(--font-heading);
  font-weight: 400;
  font-size: var(--font-24);
  line-height: 1.5;
  color: var(--color-white);
}

.cultureBand__statement .gradientText {
  font-weight: 500;
}

@media (max-width: 1200px) {
  .cultureBand__band {
    padding-inline: var(--space-9);
  }
}

@media (max-width: 900px) {
  .cultureBand {
    padding-inline: 0;
    width: calc(100% - (var(--gutter) * 2));
    margin-inline: auto;
  }
  .cultureBand__band {
    padding: var(--space-8) var(--space-5);
  }
}

/* --------------------------------------------------------------------------
   Our Values ring (People page, Figma InfoBlocks 730:1232 > Group 9 = 824:1692)
   Group 9's own box is 917.44 x 724.22 inside the 1512 frame, so the stage is
   60.68% wide and every length inside it is a cqw of that stage -- the ring,
   the beams and the type all scale as one illustration rather than drifting
   apart at intermediate widths.
   Hub centre measured at (462.72, 444) within the box = 50.44% / 61.31%.
   Satellite angle and radius are per-value because Figma's placement is not
   perfectly regular; they are measured, not idealised (recorded in the digest).
   -------------------------------------------------------------------------- */
.valuesRing {
  background: var(--color-black);
  padding-block: clamp(80px, 10.58vw, 203.1px) 0; /* was 160px 0 */
  width: 100%;
  display: flex;
  justify-content: center;
}

/* 96px between Group 9 and Frame 247; the lede's own 160px top padding is
   InfoBlocks' and belongs above the ring now, not between the two. */
.valuesRing + .peopleIntro {
  padding-block-start: var(--space-9); /* 96px */
}

.valuesRing__stage {
  position: relative;
  width: 60.68%;
  max-width: calc(var(--contentMax) * 0.6068);
  aspect-ratio: 917.44 / 724.22;
  container-type: inline-size;
}

/* Frame 304 824:1708 -- 448px, blur 8.6, radial ramp from #40d39f to a
   transparent #2f84e2 at r=203 (Figma's r=10 through a 20.3 scale matrix).

   2026-09-21: `closest-side` added. Without an explicit size a radial-gradient
   defaults to farthest-CORNER, so the 90.6% stop landed at 0.906 x 317px = 287px
   instead of the intended 0.906 x 224px = 203px. The ramp was stretched 41% past
   the shape, leaving the glow 2.3-3.0x too bright in the band just outside the
   hub (measured against the Figma node render: r 0.15-0.20 read 82 vs Figma's 36,
   r 0.20-0.25 read 53 vs 18) and far too green, because the blue end of the ramp
   never arrived. closest-side pins 100% to the half-width, which is the radius
   the 90.6% was derived against.

   Corner radius is Figma's 164.5 of 448 rather than a circle. It makes no visible
   difference now the ramp is transparent well inside the corners, but it is what
   the frame actually is.

   Blur stays at half Figma's LAYER_BLUR radius (17.2), which is the same
   figma-radius/2 convention the beam SVG exports with (stdDeviation 15.95 for a
   31.9 blur). Confirmed, not assumed: blur(17.2) was tested against the node
   render and scored 7.09 MAE versus 7.05 for blur(8.6) — indistinguishable, so
   the doubling hypothesis is dead and the /2 convention stands. Expressed in cqw
   so it tracks the stage instead of freezing at the design width.

   SOLVED PAINT -- stop at 80%, measured, not derived. The transform maths gives
   0.5 / 1.0992 = 0.4549 of the frame, i.e. 203px of the 224 half-width = 90.6%,
   and that is what was here. Against the node render 90.6% still leaves the halo
   just outside the disc 31% too bright (46.76 vs Figma's 35.78 at r 0.15-0.20).
   80% lands at 34.31 there and improves whole-image MAE from 7.05 to 6.50; every
   band beyond r 0.25 is identical either way. Rejected near-miss: 90.6%, the
   derived value. Do not "correct" this back to the transform figure -- it has
   been tested and it fits worse. */
.valuesRing__glow {
  position: absolute;
  left: 50.44%;
  top: 61.31%;
  width: 48.83cqw;
  aspect-ratio: 1;
  translate: -50% -50%;
  border-radius: 36.72%;
  background: radial-gradient(circle closest-side at 50% 50%, #40d39f 0%, rgba(47, 132, 226, 0) 80%);
  filter: blur(0.937cqw); /* 8.6px at the 917.44 design width */
}

.valuesRing__beams {
  position: absolute;
  inset: 0;
}

/* One export, eight rotations. The bar's bright end is at the foot of the SVG,
   so rotate-then-translate on the negative Y axis points it back at the hub
   without a second flip. 87.115 x 511.892 is the export's own box, blur bleed
   included; the bar itself sits dead centre of it. */
.valuesRing__beam {
  position: absolute;
  left: 50.44%;
  top: 61.31%;
  width: 9.5cqw;
  height: auto;
  transform-origin: 50% 50%;
  transform: translate(-50%, -50%) rotate(var(--beamAngle)) translateY(calc(var(--beamRadius) * -1));
}

.valuesRing__beam--1 { --beamAngle: -18.67deg; --beamRadius: 25.03cqw; }
.valuesRing__beam--2 { --beamAngle: 16.77deg; --beamRadius: 24.76cqw; }
.valuesRing__beam--3 { --beamAngle: -54.65deg; --beamRadius: 25.27cqw; }
.valuesRing__beam--4 { --beamAngle: 53.46deg; --beamRadius: 24.56cqw; }
.valuesRing__beam--5 { --beamAngle: -90.6deg; --beamRadius: 26.01cqw; }
.valuesRing__beam--6 { --beamAngle: 90.62deg; --beamRadius: 25.13cqw; } /* was 89.4; Rectangle 15 measures 90.62 */
.valuesRing__beam--7 { --beamAngle: -125.66deg; --beamRadius: 26.56cqw; }
.valuesRing__beam--8 { --beamAngle: 126.86deg; --beamRadius: 25.85cqw; }

/* Frame 407 1590:16607 -- 250px, rgba(12,12,12,0.6) fill.

   2026-09-21: the ring was `1px solid #0c0c0c`, i.e. invisible against a black
   page. Figma's stroke is a LINEAR GRADIENT -- #0c0c0c -> #ebebeb at 50% ->
   #0c0c0c, running left to right -- and the read tools flatten a gradient to its
   stop-0 fallback, which here is the black. Exactly the case the Figma skill
   warns about: a flat hex is not evidence of flat paint. In the Figma render it
   is a clearly visible light rim across the top and bottom of the disc.

   border-image cannot do this: it ignores border-radius, so a 1px gradient ring
   on a circle has to be painted as a background and masked to the ring. The
   padding value IS the stroke width (Figma 1px, INSIDE). */
.valuesRing__hub {
  position: absolute;
  left: 50.44%;
  top: 61.31%;
  width: 27.25cqw;
  aspect-ratio: 1;
  translate: -50% -50%;
  border-radius: 50%;
  background-color: rgba(12, 12, 12, 0.6);
  /* Figma effect GLASS (radius 4) has no CSS equivalent -- its refraction,
     depth and dispersion are not expressible. A backdrop blur at the same
     radius is the closest honest approximation of the material. */
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  display: flex;
  align-items: center;
  justify-content: center;
}

.valuesRing__hub::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 50%;
  padding: 1px;
  background: linear-gradient(90deg, #0c0c0c 0%, #ebebeb 50%, #0c0c0c 100%);
  -webkit-mask:
    linear-gradient(#000 0 0) content-box,
    linear-gradient(#000 0 0);
  mask:
    linear-gradient(#000 0 0) content-box,
    linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
  pointer-events: none;
}

/* Group 6 824:1709 -- the two wordmark groups composed into one 188 x 74.65
   lockup, since Figma splits "OUR" and "VALUES" across separate vector groups. */
.valuesRing__hubLockup {
  width: 20.49cqw;
  height: auto;
}

/* Icon Circle 1590:16385. The component box is 100 x 110 with the label hanging
   26px above its top edge -- justify-content: flex-end plus visible overflow is
   what Figma's justify-end on a 110px box actually does. */
.valuesRing__point {
  position: absolute;
  left: 50.44%;
  top: 61.31%;
  width: 10.9cqw;
  height: 11.99cqw;
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  gap: 1.31cqw; /* 12px */
  transform-origin: 50% 50%;
  transform: translate(-50%, -50%) rotate(var(--pointAngle)) translateY(calc(var(--pointRadius) * -1));
}

.valuesRing__point--integrity { --pointAngle: -0.5deg; --pointRadius: 42.4cqw; }
.valuesRing__point--accountability { --pointAngle: 36.2deg; --pointRadius: 41.07cqw; }
.valuesRing__point--customerFocus { --pointAngle: 71.7deg; --pointRadius: 41.42cqw; }
.valuesRing__point--growthMindset { --pointAngle: 108.4deg; --pointRadius: 41.98cqw; }
.valuesRing__point--respect { --pointAngle: -36.6deg; --pointRadius: 41.24cqw; }
.valuesRing__point--ownership { --pointAngle: -71.9deg; --pointRadius: 42.06cqw; }
.valuesRing__point--safety { --pointAngle: -108.1deg; --pointRadius: 42.46cqw; }

/* The ramp paints across the whole text node in Figma, so it is hung on the
   label itself rather than on an inner span. 20px Golos Medium at 1512. */
.valuesRing__label {
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: clamp(12px, 2.18cqw, 20px);
  line-height: 1.2;
  white-space: nowrap;
  background-image: var(--gradient-brand);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

/* 0.75px #40d39f at rest. Hover swaps in variant 810:763's paint set: the ramp
   as a 20% fill, the ramp again as the stroke, and a 20px #40d39f glow. All
   seven hover variants are identical, so one rule covers them. */
.valuesRing__disc {
  position: relative;
  width: 10.9cqw;
  aspect-ratio: 1;
  border-radius: 50%;
  border: 0.75px solid var(--color-brand-green);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: box-shadow 0.3s ease-out, border-color 0.3s ease-out;
}

/* The stroke ramp. A gradient border needs a real paint box, and border-image
   ignores border-radius, so it is a masked 0.75px band instead. */
.valuesRing__disc::before {
  content: "";
  position: absolute;
  inset: -0.75px;
  border-radius: 50%;
  padding: 0.75px;
  background-image: var(--gradient-brand);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude;
  opacity: 0;
  transition: opacity 0.3s ease-out;
}

/* The fill ramp. Figma rotates this one 90deg and leaves the stroke horizontal. */
.valuesRing__disc::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background-image: linear-gradient(180deg, #40d39f 0%, #38abc1 50%, #2f84e2 100%);
  opacity: 0;
  transition: opacity 0.3s ease-out;
}

.valuesRing__point:hover .valuesRing__disc,
.valuesRing__point:focus-visible .valuesRing__disc {
  border-color: transparent;
  box-shadow: 0 0 20px var(--color-brand-green);
}

.valuesRing__point:hover .valuesRing__disc::before,
.valuesRing__point:focus-visible .valuesRing__disc::before {
  opacity: 1;
}

.valuesRing__point:hover .valuesRing__disc::after,
.valuesRing__point:focus-visible .valuesRing__disc::after {
  opacity: 0.2;
}

/* Counter-rotated so the glyph stays upright while its satellite is turned --
   Figma does the same with a -37 / -73 / -110 wrapper inside each instance. */
.valuesRing__icon {
  position: relative;
  height: auto;
  rotate: calc(var(--pointAngle) * -1);
}

.valuesRing__icon--integrity { width: 3.543cqw; }
.valuesRing__icon--accountability { width: 3.324cqw; }
.valuesRing__icon--customerFocus { width: 3.815cqw; }
.valuesRing__icon--growthMindset { width: 3.106cqw; }
.valuesRing__icon--respect { width: 3.815cqw; }
.valuesRing__icon--ownership { width: 3.815cqw; }
.valuesRing__icon--safety { width: 3.27cqw; }

@media (prefers-reduced-motion: reduce) {
  .valuesRing__disc,
  .valuesRing__disc::before,
  .valuesRing__disc::after {
    transition: none;
  }
}

/* Below 900px the ring cannot hold its type: at 320px the discs land near 35px
   and the labels near 7px. The satellites become an upright two-column list and
   the hub moves above them; the cards are unchanged. There is no mobile frame
   for Group 9 in Figma, so this is a build decision, not a measurement. */
@media (max-width: 900px) {
  .valuesRing {
    padding-block: var(--space-9) 0;
  }
  .valuesRing__stage {
    width: calc(100% - (var(--gutter) * 2));
    max-width: none;
    aspect-ratio: auto;
    container-type: normal;
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: var(--clamp-rem-32);
    justify-items: center;
  }
  .valuesRing__glow,
  .valuesRing__beams {
    display: none;
  }
  .valuesRing__hub {
    position: static;
    grid-column: 1 / -1;
    width: 250px;
    max-width: 100%;
    translate: none;
  }
  .valuesRing__hubLockup {
    width: 188px;
    max-width: 75%;
  }
  .valuesRing__point {
    position: static;
    width: 100%;
    height: auto;
    transform: none;
    gap: var(--clamp-rem-12);
  }
  .valuesRing__label {
    font-size: var(--font-16);
    white-space: normal;
    text-align: center;
  }
  .valuesRing__disc {
    width: 100px;
    order: -1;
  }
  .valuesRing__icon {
    rotate: none;
  }
  .valuesRing__icon--integrity { width: 32.5px; }
  .valuesRing__icon--accountability { width: 30.5px; }
  .valuesRing__icon--customerFocus { width: 35px; }
  .valuesRing__icon--growthMindset { width: 28.5px; }
  .valuesRing__icon--respect { width: 35px; }
  .valuesRing__icon--ownership { width: 35px; }
  .valuesRing__icon--safety { width: 30px; }
}

/* --------------------------------------------------------------------------
   Value popup overlay (Figma iFrame Card 1794:2583 and the six 2045:* siblings)
   A 600px circle, rgba(22,22,22,0.75) behind a 1px #40d39f ring and a 30px
   glow of the same green, 64px padding, 48px between the icon/title group and
   the body, 16px inside that group.
   The prototype opens it as an overlay that moves in from the top over 300ms,
   ease-out. That slide is commented out below at the client's request; the card
   now appears in place and only the backdrop fades. .isEntered still drives the
   backdrop, matching .leaderBio.
   Figma gives the card no close control -- Esc and a backdrop click dismiss it,
   and .valuePopup__close is the assistive-tech equivalent.
   -------------------------------------------------------------------------- */
.valuePopup {
  position: fixed;
  inset: 0;
  margin: auto;
  width: 39.68%; /* 600 of 1512 */
  max-width: calc(var(--contentMax) * 0.3968);
  min-width: min(600px, calc(100% - (var(--gutter) * 2)));
  aspect-ratio: 1;
  height: auto;
  max-height: none;
  padding: clamp(32px, 4.23vw, 81.2px); /* was 64px */
  border: 1px solid var(--color-brand-green);
  border-radius: 50%;
  background-color: rgba(22, 22, 22, 0.75);
  box-shadow: 0 0 30px var(--color-brand-green);
  color: var(--color-white);
  overflow: hidden;
  /* Figma's MOVE_IN from TOP, asked to be dropped 2026-09-18 — the card reads
     better appearing in place than sliding the height of the viewport. The
     backdrop still fades, so the open is not a hard cut. Uncomment these two
     rules and the .isEntered block below to put the slide back. */
  /* translate: 0 -100vh; */
  /* transition: translate 0.3s ease-out; */
}

/* .valuePopup.isEntered {
  translate: 0 0;
} */

.valuePopup::backdrop {
  background-color: rgba(12, 12, 12, 0.6);
  opacity: 0;
  transition: opacity 0.3s ease-out;
}

.valuePopup.isEntered::backdrop {
  opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
  .valuePopup,
  .valuePopup::backdrop {
    transition: none;
  }
}

.valuePopup__inner {
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--clamp-rem-48); /* 48px */
}

.valuePopup__head {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--clamp-rem-16); /* 16px */
}

.valuePopup__icon {
  width: 32.5px;
  height: auto;
}

.valuePopup__title {
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-48);
  line-height: 1.2;
  text-align: center;
  margin: 0;
}

.valuePopup__text {
  font-size: var(--font-20);
  line-height: 1.4;
  letter-spacing: 0.1px;
  text-align: center;
  margin: 0;
}

/* The card stays a circle at every width (Sam, 2026-09-24; it squared off
   below 900 until then). To fit Safety's and Customer Focus's copy, the type
   and gaps step down instead. Padding is a % of the width, so the text box
   scales with the circle. Measured: the longest copy fits at 360. */
@media (max-width: 900px) {
  .valuePopup {
    min-width: 0;
    width: calc(100% - (var(--gutter) * 2));
    max-width: 88%; /* was 600px (Sam, 2026-09-24) */
    padding: 11%;
  }

  .valuePopup__inner {
    gap: var(--clamp-rem-16);
  }

  .valuePopup__head {
    gap: var(--clamp-rem-8);
  }

  .valuePopup__title {
    font-size: var(--font-48);
  }

  .valuePopup__text {
    font-size: var(--font-14);
  }
}

@media (max-width: 600px) {
  .valuePopup {
    width: calc(100% - 24px);
    padding: 10%;
  }

  .valuePopup__inner {
    gap: var(--clamp-rem-12);
  }

  .valuePopup__icon {
    width: 40px;
  }

  .valuePopup__title {
    font-size: var(--font-32);
  }

  .valuePopup__text {
    line-height: 1.35;
    letter-spacing: 0;
  }
}

/* --------------------------------------------------------------------------
   Values lede (People page, Figma InfoBlocks 730:1232 > Frame 247 = 730:1233)
   -------------------------------------------------------------------------- */
/* Frame 247 is a 900-wide centred text block; the 160px block padding is
   InfoBlocks'. The .sectionLead default 800px measure is widened to 900 and its
   auto margins dropped, since the padding here carries the spacing. */
.peopleIntro {
  background: var(--color-black);
  padding-block: clamp(80px, 10.58vw, 203.1px); /* was 160px */
  padding-inline: 0;
  width: 91.53%;
  max-width: calc(var(--contentMax) * 0.9153);
  margin-inline: auto;
  display: flex;
  justify-content: center;
}

.peopleIntro .sectionLead {
  width: 100%;
  max-width: 900px;
  margin: 0;
}

@media (max-width: 900px) {
  .peopleIntro {
    padding-block: var(--space-9);
  }
}

/* --------------------------------------------------------------------------
   Our Culture wrapper (People page, Figma Frame 252 = 726:477)
   Holds the culture band, Social Responsibility and Inclusion & Belonging.
   Figma spaces its three children 120px apart and leaves 184px below the last.
   -------------------------------------------------------------------------- */
.peopleCulture {
  background: var(--color-black);
  display: flex;
  flex-direction: column;
  gap: clamp(60px, 7.94vw, 152.4px); /* was 120px */
  padding-bottom: clamp(92px, 12.17vw, 233.7px); /* was 184px */
}

/* --------------------------------------------------------------------------
   Inclusion & Belonging (People page, Figma Frame 285 = 732:1358)
   A centred 900px intro with no block padding of its own — 225 = 15 eyebrow
   + 16 + 58 heading + 48 + 88 lede. Same rhythm as every other ECI intro.
   -------------------------------------------------------------------------- */
.inclusion {
  padding-inline: 0;
  width: 91.53%;
  max-width: calc(var(--contentMax) * 0.9153);
  margin-inline: auto;
}

.inclusion__inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-7);
  max-width: 900px;
  margin-inline: auto;
  text-align: center;
}

.inclusion__head {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--clamp-rem-16);
  width: 100%;
}

.inclusion__head .eyebrow {
  margin-bottom: 0;
}

/* Text node 732:1362 is the full 900, so the ramp spans it and "Belonging"
   lands on the blue tail. */
.inclusion .sectionHeading {
  width: 18.75em;
  max-width: 100%;
} /* 900 @48 */

.inclusion__lead {
  margin: 0;
  font-size: var(--font-16);
  line-height: 1.4;
  letter-spacing: 0.1px;
  width: 100%;
}

/* --------------------------------------------------------------------------
   Life at ECI photo bands — Safety (732:1366) and People Engagement (732:1392)
   One component: a full-bleed photo with a 580px text column, 96px block and
   64px inline padding. Safety puts the column right and lays a scrim under it;
   People Engagement puts it left and has no scrim layer at all in Figma.
   -------------------------------------------------------------------------- */
.lifeBand {
  position: relative;
  display: flex;
  align-items: center;
  /* Full-bleed: the artwork is a `position:absolute; inset:0` child, so this box
     must stay viewport-wide or the image is cropped. Padding is the inset. */
  padding: var(--space-9) var(--space-8);
  background: var(--color-black);
  overflow: hidden;
}

.lifeBand--right {
  justify-content: flex-end;
}

/* Both frames are taller than their copy — Figma fixes 732:1392 at 650 and
   732:1366 at 709, so the photo, not the text, sets the band height. Without
   these the Engagement band collapses to 425 and shows a third less of the
   image than the design does. */
.lifeBand {
  min-height: 650px;
}
.lifeBand--right {
  min-height: 709px;
}

.lifeBand__background {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
}

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

/* people-engagement-v2.jpg (2026-09-23) — frame the subject a little above centre */
.lifeBand--peopleEngagement .lifeBand__background img {
  object-position: center 40%;
}

/* The left-hand variant (People Engagement, 732:1392) DOES carry a scrim — the
   earlier note here claiming Figma has none was wrong. Solved off the node
   render the same way: source photo placed center/cover, then per-column alpha
   of a flat overlay against the composite. It is a clean full-width linear
   ramp, opaque at the left edge falling to zero at the right — sampled alpha
   0.998 / 0.802 / 0.503 / 0.201 / 0.006 at 0/20/50/80/100%, alpha-MAE 0.0036
   against a straight line. Overlay #0c0c0c, full-band MAE 2.77/255 (#0b0b0b
   scores 2.74, inside the noise of the re-exported asset, so the brand black
   stands).

   CONFIRMED 2026-09-21 by reading the paint via use_figma: two stops, #0c0c0c
   a=1 -> a=0, gradientTransform row 0 [1, 0, 0] so t = u — a plain full-width
   left-to-right ramp. The fitted value was already right. Its sibling below was
   not, so do not assume one validates the other. */
.lifeBand .lifeBand__background::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(to right, #0c0c0c 0%, rgba(12, 12, 12, 0) 100%);
}

/* Safety (732:1366). Corrected 2026-09-21 by READING the paint via use_figma
   rather than fitting it from the node render, which is what the previous
   two attempts here did and why both were wrong.

   Figma holds a THREE-stop linear gradient whose gradientTransform row 0 is
   [-1, 0, 1], i.e. t = 1 - u, so the stops mirror onto the CSS axis:

       Figma t=0.0  a=1.0      -> CSS 100%  #0c0c0c
       Figma t=0.6  a=0.52885  -> CSS  40%  alpha 0.529
       Figma t=1.0  a=0.0      -> CSS   0%  transparent

   The old value claimed zero alpha across the whole left half and a straight
   ramp from 50.48%. At 40% that painted nothing where Figma paints 53% black —
   the ramp starts at the left edge and is curved, not flat-then-linear. Fitting
   it from the render missed this because the photo is already dark on that side,
   so a half-strength black overlay barely moves the composite. Must follow the
   rule above so the right-hand variant does not keep the left ramp — equal
   specificity. */
.lifeBand--right .lifeBand__background::after {
  background: linear-gradient(
    to right,
    rgba(12, 12, 12, 0) 0%,
    rgba(12, 12, 12, 0.529) 40%,
    #0c0c0c 100%
  );
}

.lifeBand__copy {
  position: relative;
  z-index: 1;
  flex: 1 0 0;
  min-width: 0;
  max-width: 580px;
  display: flex;
  flex-direction: column;
  gap: var(--clamp-rem-32);
  color: var(--color-white);
}

.lifeBand__head {
  display: flex;
  flex-direction: column;
  gap: var(--clamp-rem-16);
}

.lifeBand__head .eyebrow {
  margin-bottom: 0;
}

.lifeBand .sectionHeading {
  text-align: left;
  width: auto;
  max-width: 100%;
  margin-inline: 0;
}

.lifeBand__body {
  font-size: var(--font-16);
  line-height: 1.4;
  letter-spacing: 0.1px;
}

/* Figma separates the paragraphs with an empty 16px/1.4 line. */
.lifeBand__body p {
  margin: 0;
}
.lifeBand__body p + p {
  margin-top: var(--clamp-rem-24); /* Figma 22px -> nearest step */
}

/* "Our goal is simple:" is Inter Bold carrying the brand ramp. The generic
   :has(> .gradientText) host rule already paints the ramp across this <p>. */
.lifeBand__body strong {
  font-weight: 700;
}

@media (max-width: 900px) {
  .peopleCulture {
    gap: var(--space-9);
    padding-bottom: var(--space-9);
  }
  .inclusion {
    padding-inline: 0;
    width: calc(100% - (var(--gutter) * 2));
    margin-inline: auto;
  }

  /* Full bleed on mobile (Sam, 2026-09-24), same as .companiesIntro: the band
     and its photo run edge to edge, and the copy carries the page gutter. */
  .lifeBand {
    padding-block: var(--space-8);
    padding-inline: 0;
    width: 100%;
    margin-inline: 0;
  }
  .lifeBand__copy {
    flex: 0 0 auto;
    width: calc(100% - (var(--gutter) * 2));
    max-width: none;
    margin-inline: auto;
  }

  /* With the copy full-width the photo needs a readable base under all of it. */
  .lifeBand--right .lifeBand__background::after,
  .lifeBand .lifeBand__background::after {
    content: '';
    position: absolute;
    inset: 0;
    background: rgba(12, 12, 12, 0.7);
  }
}

/* --------------------------------------------------------------------------
   Careers CTA (People page, Figma 726:666)
   -------------------------------------------------------------------------- */
.careersCallToAction {
  background: var(--color-black);
  padding-block: clamp(64px, 8.47vw, 162.6px); /* was 128px */
  padding-inline: 0;
  width: 91.53%;
  max-width: calc(var(--contentMax) * 0.9153);
  margin-inline: auto;
}

/* One 48px rhythm between all four children — eyebrow+heading group, lede,
   prompt, button — exactly as Frame 726:667 stacks them. */
/* Width rule, 2026-09-21. Was `max-width: 900px` with no `width` at all, so the
   block sat outside the --contentMax system entirely — missed by the F1 audit,
   which listed it as neither converted nor deliberately-excluded.

   Now an explicit `width: 100%` of its parent with the 900px reading measure
   expressed as a --contentMax fraction: 900 / 1920 = 0.46875. Behaviour is
   byte-identical to the old rule at every width — full width of the parent until
   that exceeds 900px, capped at 900 after — but the magic number is gone and the
   cap moves with --contentMax like every other cap in the build.

   Deliberately NOT given the parent's 0.9153 the way F1 did its ten. That
   multiplier belongs to .careersCallToAction, and reusing it here would widen
   this centred block to 1346px — the ~180-character measure F1 is on record as
   regretting. A reading measure and a layout cap are not the same number. */
.careersCallToAction__inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-7);
  width: 100%;
  max-width: calc(var(--contentMax) * 0.46875); /* 900px at --contentMax 1920 */
  margin-inline: auto;
  text-align: center;
}

/* Same nested 16px-gap pair every ECI section intro uses (Frame 726:668). */
.careersCallToAction__head {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--clamp-rem-16);
  width: 100%;
}

.careersCallToAction__head .eyebrow {
  margin-bottom: 0;
}

/* Heading text node 726:670 is the full 900 wide, so the brand ramp spans the
   whole measure and "it's a journey." shows the teal->blue tail of it. */
.careersCallToAction .sectionHeading {
  width: 18.75em;
  max-width: 100%;
} /* 900 @48 */

.careersCallToAction__lead {
  font-size: var(--font-16);
  line-height: 1.4;
  letter-spacing: 0.1px;
  width: 100%;
}

/* Figma renders the two paragraphs with a blank line between them; 22px is that
   empty 16px/1.4 line. The paragraphs themselves carry no other margin. */
.careersCallToAction__lead p {
  margin: 0;
}
.careersCallToAction__lead p + p {
  margin-top: clamp(11px, 1.46vw, 28px); /* was 22px */
}

.careersCallToAction__prompt {
  font-size: var(--font-24);
  font-weight: 700;
  line-height: 1.4;
  letter-spacing: 0.1px;
  margin: 0;
}

@media (max-width: 900px) {
  .careersCallToAction {
    padding-block: var(--space-8);
  }
}

/* --------------------------------------------------------------------------
   FAQ
   -------------------------------------------------------------------------- */
/* Full-bleed so the gradient spans the viewport; width is constrained on
   .faq__inner instead. Bottom stop is the teal the footer starts on. */
.faq {
  background: linear-gradient(to top, var(--gradient-bg-stops));
  padding-block: var(--space-10);
}

.faq__inner {
  display: flex;
  gap: var(--space-9);
  padding-inline: 0;
  /* Matches .moreSolutions__cards rather than the 91.53% gutter width the band
     used on the Resources page. */
  width: 78.84%;
  max-width: calc(var(--contentMax) * 0.7884);
  margin-inline: auto;
}

/* 333px is the Figma column, but as a hard flex-basis it stayed 333 wide while the
   answers column absorbed every pixel of the squeeze between 1200 and 900. As a
   shrinkable basis it is identical whenever there is free space — i.e. all of
   desktop — and gives ground proportionally below that, down to a floor that
   still fits "Frequently Asked Questions" on three lines. */
.faq__heading {
  flex: 0 1 333px;
  min-width: 15em;
}
.faq__heading h2 {
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-48);
  line-height: 1.2;
}

.faq__list {
  flex: 1;
}

.faqItem {
  border-bottom: 1px solid var(--color-border-faint);
}

.faqItem__question {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding: clamp(8px, 1.06vw, 20.4px) 0 clamp(8.5px, 1.12vw, 21.5px); /* was 16px, 17px */
  text-align: left;
  font-size: var(--font-16);
}

.faqItem__question svg {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
  transition: transform 0.2s ease;
}

.faqItem.isOpen .faqItem__question svg {
  transform: rotate(180deg);
}

.faqItem__answer {
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.25s ease;
}

.faqItem.isOpen .faqItem__answer {
  max-height: 200px;
}

.faqItem__answer p {
  padding-bottom: var(--space-5);
  font-size: var(--font-14);
  color: rgba(255, 255, 255, 0.7);
  max-width: 640px;
}

/* Same 1200px handover .moreSolutions__cards makes: below it the fixed
   percentage gives way to the gutter so the band keeps its edge margin. */
@media (max-width: 1200px) {
  .faq__inner {
    padding-inline: 0;
    width: calc(100% - (var(--gutter) * 2));
    margin-inline: auto;
  }
}

@media (max-width: 900px) {
  .faq__inner {
    flex-direction: column;
    gap: var(--space-6);
  }
  .faq__heading {
    flex-basis: auto;
    min-width: 0;
  }
}

/* --------------------------------------------------------------------------
   Footer
   -------------------------------------------------------------------------- */
/* Redesigned 2026-08-10 (Homepage footer 1590:26295). Was a flat
   --color-teal-dark; the footer now carries the same vertical wash as the rest
   of the page furniture — black at the top falling to teal at the bottom, which
   is the existing --gradient-bg-stops pair read bottom-up. */
.siteFooter {
  position: relative;
  overflow: hidden;
  background: linear-gradient(to top, var(--gradient-bg-stops));
  padding: var(--space-7) var(--gutter);
}

.siteFooter__top {
  display: flex;
  gap: var(--space-9);
  max-width: var(--contentMax);
  margin-inline: auto;
  position: relative;
  z-index: 1;
}

/* Frame 410 (1622:29950): logo over a social row, 96px apart. */
.siteFooter__brand {
  display: flex;
  flex-direction: column;
  gap: var(--space-9);
  flex-shrink: 0;
}

/* Footer logo swapped 2026-09-15 to the new mark (Figma 2829:2651, "Layer_1"),
   which is 177x53 where the old Inline-Logo-FC-Inverted was 250x46. The header
   still uses logo-eci-inverted.svg — only the footer mark changed. */
.siteFooter__logo {
  display: block;
  /* The 2026 lockup is 294.21 x 82.99 (3.545) where the old mark was 177 x 53
     (3.340). aspect-ratio rather than a height, so the box follows the artwork
     and the 100%/100% <img> inside it cannot stretch. */
  width: 177px;
  aspect-ratio: 294.21 / 82.99;
  flex-shrink: 0;
}

/* SITE-04: the wordmark took 49% of the viewport at 360. Phones get it 25%
   smaller; the aspect-ratio keeps the artwork's proportions. */
@media (max-width: 700px) {
  .siteFooter__logo {
    width: 133px;
  }
}
.siteFooter__logo img {
  display: block;
  width: 100%;
  height: 100%;
}

/* Button List 1622:29951 */
.siteFooter__social {
  display: flex;
  gap: var(--space-4);
  align-items: center;
}
.siteFooter__social a {
  display: block;
}
.siteFooter__social img {
  display: block;
  width: 24px;
  height: 24px;
}

.siteFooter__columns {
  flex: 1;
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  row-gap: var(--space-5);
  column-gap: var(--space-5);
}

.footerColumn p.eyebrow {
  font-family: var(--font-heading);
  font-size: var(--font-10);
  letter-spacing: 1px;
  margin-bottom: var(--clamp-rem-12);
}

.footerColumn ul {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.footerColumn a {
  font-size: var(--font-12);
}

/* Larger footer links on mobile (Sam, 2026-09-24). */
@media (max-width: 900px) {
  .footerColumn a {
    font-size: var(--font-14);
  }

  .footerColumn p.eyebrow {
    font-size: var(--font-12);
    margin-bottom: var(--clamp-rem-16);
  }
}

/* Frame 406 1590:26408 — the bottom row. Figma stacks it 12px under the columns
   block (Frame 320's gap) and lays it out as copyright + mark, 12px apart, top
   aligned. The 40px that used to be folded into this margin belongs to the
   copyright column alone (Container:margin 1590:26409) and is set there, so the
   mark can sit level with the row's top rather than 40px down. */
.siteFooter__bottom {
  max-width: var(--contentMax);
  margin-inline: auto;
  margin-top: var(--space-3); /* was 12px */
  /* Flex, as Figma has it, and so the legal block's 40px top margin cannot
     collapse into this one — collapsed, it drags the mark down with it. */
  display: flex;
  align-items: flex-start;
  position: relative;
  z-index: 1;
}

/* Container:margin 1590:26409 -> Container 1590:26410. 40px above the rule, 25px
   below it. Width stops 339.018px short of the content edge — the mark's 327.018
   column plus the row's 12px gap — which is why Figma's rule does not run under
   the mark.
   The rule is NOT flat white. 1590:26410's stroke is a GRADIENT_LINEAR, read off
   the node with use_figma 2026-09-01 because get_design_context flattens it to its
   stop-0 fallback and emits `border-t border-white`. Two stops, both #ffffff:
   alpha 1 at 0%, alpha 0 at 89.904%; gradientTransform is identity, so it runs
   left to right and the last ~10% of the rule is already fully transparent.
   Top edge only (strokeTopWeight 1, the other three 0), strokeAlign INSIDE. */
.siteFooter__legal {
  width: calc(100% - 327.018px - var(--space-3));
  margin-top: clamp(20px, 2.65vw, 50.9px); /* was 40px */
  border-top: 1px solid transparent;
  border-image: linear-gradient(to right, #ffffff 0%, rgba(255, 255, 255, 0) 89.904%) 1;
  padding-top: clamp(12.5px, 1.65vw, 31.7px); /* was 25px */
  font-size: var(--font-12);
}

/* Group 11 1590:26413, 327.018 x 295.052, a single #133E48 path (the same
   --color-panel the old 300px "ECI" wordmark used). Figma parents it in the
   bottom row, top-aligned with the copyright column and flush with the 1384
   content edge, where it overruns the footer and is clipped by the footer's own
   overflow. Anchored to the row's top, not the footer's bottom: the bleed then
   follows from the footer's height instead of being pinned to one viewport. */
.siteFooter__mark {
  position: absolute;
  top: 0;
  right: 0;
  width: 327.018px;
  height: 295.052px;
  pointer-events: none;
  user-select: none;
}

@media (max-width: 1000px) {
  .siteFooter__top {
    flex-direction: column;
    gap: var(--space-9);
  }
  .siteFooter__columns {
    grid-template-columns: repeat(3, 1fr);
  }
  .siteFooter__mark {
    display: none;
  }
  .siteFooter__legal {
    width: 100%;
  }
  .footerColumn {
    padding-bottom: var(--space-8);
  }
}
/* SITE-03: a 2-col grid stretches each row to its tallest column, so the gap
   above a heading varied 12-65px. Multi-column flow gives every heading the
   same gap. */
@media (max-width: 600px) {
  .siteFooter__columns {
    display: block;
    column-count: 2;
    column-gap: var(--space-5);
  }
  .footerColumn {
    break-inside: avoid;
  }
}

/* --------------------------------------------------------------------------
   Global Locations map — Figma Map instance 1939:3841 (component set 1939:3834)
   -------------------------------------------------------------------------- */
.locationMap {
  /* Region switch (map pan, pin fade, list fade). CSS ease-in-out is
     (0.42, 0, 0.58, 1); this pulls both handles in for a slightly stronger
     ease at each end. Sam, 2026-09-23 — Figma's was 0.3s ease-out. */
  --regionSwitch: 0.7s cubic-bezier(0.55, 0, 0.45, 1);
  width: 95.5%; /* 1444 of 1512 */
  max-width: calc(var(--contentMax) * 0.955);
  margin-inline: auto;
  padding-top: var(--space-5);
}

@media (max-width: 900px) {
  .locationMap {
    width: calc(100% - (var(--gutter) * 2));
  }
}

/* Frame 264 (1939:2898) */
.locationMap__tabs {
  position: relative;
  display: flex;
  margin-bottom: var(--space-4);
}

/* Line Gradient Light Grey, stroke inside the bar's bottom edge */
.locationMap__tabs::after {
  content: '';
  position: absolute;
  inset: auto 0 0;
  height: 1px;
  background: var(--gradient-line-2);
}

.locationMap__tab {
  position: relative;
  z-index: 1;
  flex: 1 1 0;
  min-width: 0;
  padding: 0 var(--space-4) calc(var(--space-5) - 2px); /* Figma's 24px includes the 2px rule */
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: var(--font-16);
  line-height: 2;
  text-transform: uppercase;
  color: var(--color-border-mid);
  background: none;
  border: 0;
  border-bottom: 2px solid transparent;
  cursor: pointer;
}

/* Smaller region tabs on mobile (Sam, 2026-09-24). */
@media (max-width: 900px) {
  .locationMap__tab {
    font-size: var(--font-14);
  }
}

.locationMap__tab:focus-visible {
  outline: 2px solid var(--color-brand-green);
  outline-offset: -2px;
}

/* Button Gradient on both the label and the 2px rule; the label ramp spans the
   word (text node), the rule spans the tab (tab frame) */
.locationMap__tab.isActive {
  border-image: var(--gradient-brand) 1;
}

.locationMap__tab.isActive .locationMap__tabLabel {
  background: var(--gradient-brand);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

/* Rotating Card (1939:2905) — 1444 x 704, clips; height comes from the map's ratio */
.locationMap__card {
  display: flex;
  overflow: hidden;
  box-shadow: 0 12px 30px 0 rgba(0, 0, 0, 0.25);
}

@media (max-width: 900px) {
  .locationMap__card {
    flex-direction: column;
  }
}

/* Frame 249 (1939:2906) — flex 1, max 450 */
.locationMap__listWrap {
  position: relative;
  flex: 0 0 clamp(300px, 31.16%, 450px);
}

/* Stacked: a fixed-height scroll viewport, so the height is the point */
@media (max-width: 900px) {
  .locationMap__listWrap {
    flex: none;
    height: min(70svh, 560px);
  }
}

.locationMap__list {
  position: absolute;
  inset: 0;
  margin: 0;
  padding: 0;
  list-style: none;
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: none; /* Figma's cards run the full 450; the clipped last card signals the scroll */
}

.locationMap__list::-webkit-scrollbar {
  display: none;
}

.locationMap__list:not([hidden]) {
  animation: locationMapFadeIn var(--regionSwitch);
}

@media (prefers-reduced-motion: reduce) {
  .locationMap__list:not([hidden]) {
    animation: none;
  }
}

@keyframes locationMapFadeIn {
  from {
    opacity: 0;
  }
}

/* InfoBlocks (1939:2989) */
.locationMap__map {
  position: relative;
  flex: 1 1 0;
  min-width: 0;
  aspect-ratio: 994 / 704;
  overflow: hidden;
}

@media (max-width: 900px) {
  .locationMap__map {
    order: -1;
    flex: none;
    width: 100%;
  }
}

/* InfoBlocks is 728 tall in a 704 card — the bottom 24px is clipped */
.locationMap__canvas {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  aspect-ratio: 994 / 728;
  overflow: hidden;
  isolation: isolate;
}

/* Radial fill, multiply over the photo — gradientTransform from 1939:2989 */
.locationMap__canvas::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
  background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 994 728' preserveAspectRatio='none'><defs><radialGradient id='g' gradientUnits='userSpaceOnUse' cx='0' cy='0' r='10' gradientTransform='matrix(14.2 36.4 -49.7 17.916 355 364)'><stop offset='0' stop-color='%23ffffff'/><stop offset='0.5' stop-color='%2340d39f'/><stop offset='1' stop-color='%230c0c0c'/></radialGradient></defs><rect width='994' height='728' fill='url(%23g)'/></svg>") center / 100% 100% no-repeat;
  mix-blend-mode: multiply;
  pointer-events: none;
}

/* The whole 4096x2234 map, sized so the canvas is Figma's crop window
   (0.4076783 x 0.5501930 of the image); pins ride on an identical layer */
.locationMap__world,
.locationMap__pins {
  position: absolute;
  top: 0;
  left: 0;
  width: 245.29%;
  height: 181.754%;
  transform: translate(-3.302%, -6.513%);
  transition: transform var(--regionSwitch);
}

@media (prefers-reduced-motion: reduce) {
  .locationMap__world,
  .locationMap__pins {
    transition: none;
  }
}

.locationMap[data-region="europe"] .locationMap__world,
.locationMap[data-region="europe"] .locationMap__pins {
  transform: translate(-34.999%, -6.513%);
}

.locationMap[data-region="asia"] .locationMap__world,
.locationMap[data-region="asia"] .locationMap__pins {
  transform: translate(-59.232%, -6.513%);
}

.locationMap__world {
  background: url('../assets/images/global-locations-map-v2-6400.webp') 0 0 / 100% 100% no-repeat; /* 6400x3491 WebP q80 (750KB, was a 1.4MB JPEG) from Sam's 8448 v2; covers the 1384px max panel at ~1.9x. Same resolution, near-identical detail (2026-09-24) */
}

.locationMap__pins {
  z-index: 2;
  overflow: visible;
  pointer-events: none;
}

.locationMap__pinGroup {
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--regionSwitch);
}

@media (prefers-reduced-motion: reduce) {
  .locationMap__pinGroup {
    transition: none;
  }
}

.locationMap[data-region="americas"] .locationMap__pinGroup[data-region="americas"],
.locationMap[data-region="europe"] .locationMap__pinGroup[data-region="europe"],
.locationMap[data-region="asia"] .locationMap__pinGroup[data-region="asia"] {
  opacity: 1;
  pointer-events: auto; /* only the shown region's pins take hover (js/location-map.js) */
}

/* Pins scale with the map; below 600 they would drop to ~5px, so hold them
   larger. A hovered card's pins grow 1.2x on top of that (js/location-map.js). */
.locationMap__pins {
  --pinScale: 1;
}

@media (max-width: 600px) {
  .locationMap__pins {
    --pinScale: 1.75;
  }
}

.locationMap__pinGroup image,
.locationMap__pin,
.locationMap__hqMark {
  transform-box: fill-box;
  transform-origin: center;
  transform: scale(var(--pinScale));
  transition: transform 0.3s ease-out;
}

.locationMap__pin.isHighlighted,
.locationMap__hq.isHighlighted .locationMap__hqMark {
  transform: scale(calc(var(--pinScale) * 1.2));
}

.locationMap__pin.isHighlighted {
  animation: locationMapPinPulse 1.2s ease-in-out infinite;
}

.locationMap__hq.isHighlighted .locationMap__hqMark {
  animation: locationMapHqPulse 1.2s ease-in-out infinite;
}

@media (prefers-reduced-motion: reduce) {
  .locationMap__pinGroup image,
  .locationMap__pin,
  .locationMap__hqMark {
    transition: none;
  }

  .locationMap__pin.isHighlighted,
  .locationMap__hq.isHighlighted .locationMap__hqMark {
    animation: none;
  }
}

/* Glow swells from Figma's 4-unit blur to a second 10-unit halo and back */
@keyframes locationMapPinPulse {
  50% {
    filter: drop-shadow(0 0 4px var(--pinGlow)) drop-shadow(0 0 10px var(--pinGlow));
  }
}

/* 0%/100% restate the HQ's SVG glow filter (stdDeviation 4) so it can tween */
@keyframes locationMapHqPulse {
  0%,
  100% {
    filter: drop-shadow(0 0 4px #60acff);
  }
  50% {
    filter: drop-shadow(0 0 4px #60acff) drop-shadow(0 0 10px #60acff);
  }
}

/* CSS-painted pins (Ellipse 37 gold / Ellipse 61 green). REVERSIBLE: the
   Figma SVG pins (assets/icons/location-pin-*.svg) are the other build —
   `python tools/location-map-pins.py svg` swaps the markup back; these rules
   and the `image` selector above can both stay.
   Figma paints the dot at 80% and its glow (stdDeviation 4) only OUTSIDE the
   dot. A CSS drop-shadow also paints under the dot, so an 80% fill let it
   show through (+30 levels, MAE 5/255). The fills below are Figma's 80% colour
   pre-blended over #0c0c0c and opaque: MAE 1.4 (gold) / 1.3 (green) against
   the Figma filter, measured in Chrome. Cost: land and overlapping pins no
   longer show 20% through the dot. Glow lengths are SVG user units, so it
   scales with the map. */
.locationMap__pin {
  stroke-width: 1;
}

.locationMap__pin--gold {
  fill: rgb(205, 150, 18); /* #fdb813 @ 0.8 over #0c0c0c */
  stroke: #ffde8e;
  --pinGlow: #fdb813;
  filter: drop-shadow(0 0 4px var(--pinGlow));
}

.locationMap__pin--green {
  fill: rgb(54, 171, 130); /* #40d39f @ 0.8 over #0c0c0c */
  stroke: #88ffd5;
  --pinGlow: #40d39f;
  filter: drop-shadow(0 0 4px var(--pinGlow));
}

/* Dual-role sites (MANUFACTURING + SALES/ENGINEERING), one pin per card —
   not in Figma (Sam, 2026-09-23). Purple = #a750ff, the middle stop of
   --gradient-control-box; stroke is a light tint of it, like the other two. */
.locationMap__pin--purple {
  fill: rgb(136, 66, 206); /* #a750ff @ 0.8 over #0c0c0c */
  stroke: #d9b3ff;
  --pinGlow: #a750ff;
  filter: drop-shadow(0 0 4px var(--pinGlow));
}

/* Frame 413 (1939:3022) */
.locationMap__hq circle {
  fill: rgba(47, 132, 226, 0.8);
  stroke: #77d2ff;
  stroke-width: 1;
}

.locationMap__hq text {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 11px; /* SVG user units — scales with the map */
  fill: var(--color-white);
  text-anchor: middle;
  dominant-baseline: central;
}

/* Block 5 (939:4847) — Default 939:4848 / Hover 939:4853 */
.locationCard {
  position: relative;
  display: flex;
  gap: var(--space-3);
  padding: clamp(20px, 2.646vw, 80px) var(--space-5);
  border: 1px solid var(--color-border-mid);
  border-image: var(--gradient-line-1) 1;
  transition: padding-left 0.3s ease-out;
}

@media (prefers-reduced-motion: reduce) {
  .locationCard {
    transition: none;
  }
}

.locationCard + .locationCard {
  margin-top: -1px;
}

.locationCard::before {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--gradient-hover);
  opacity: 0;
  transition: opacity 0.3s ease-out;
  pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
  .locationCard::before {
    transition: none;
  }
}

/* .isHighlighted = the card's pin is hovered on the map */
.locationCard:hover,
.locationCard.isHighlighted {
  padding-left: var(--space-6);
}

.locationCard:hover::before,
.locationCard.isHighlighted::before {
  opacity: 1;
}

/* Logos 2 (939:5841) — 27 x 25 slot, mark centred vertically */
.locationCard__mark {
  position: relative;
  flex: 0 0 27px;
  height: 25px;
  display: flex;
  align-items: center;
}

.locationCard__mark img {
  display: block;
}

.locationCard__body {
  position: relative;
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--clamp-rem-16);
  overflow-wrap: anywhere;
}

.locationCard__name {
  margin: 0;
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-20);
  line-height: 1.2;
  color: var(--color-white);
}

.locationCard__address {
  font-family: var(--font-body);
  font-style: normal;
  font-size: var(--font-14);
  line-height: 1.4;
  color: var(--color-white);
}

.locationCard__address a {
  color: inherit;
  text-decoration: none;
}

.locationCard__role {
  margin: 0;
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-14);
  line-height: 1.2;
  background: var(--gradient-brand);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

/* The role line doubles as the pin legend — not in Figma (Sam, 2026-09-23).
   Manufacturing-only = gold pin = Figma "Orange Gradient"; dual-role = purple
   pin = Figma "Red Gradient" (#a750ff at its centre). Sales/engineering-only
   and HQ keep the brand ramp above (green pin / HQ marker). background-image,
   not the shorthand, so background-clip: text survives. */
.locationCard__role--manufacturing {
  background-image: var(--gradient-orange);
}

.locationCard__role--dual {
  background-image: var(--gradient-control-box);
}

/* --------------------------------------------------------------------------
   Our Companies intro — Figma Frame 285 (909:4172), Global Locations
   -------------------------------------------------------------------------- */
/* Frame 325 sits 128px down inside the 784.5px section, with 64px left below it.
   The section's own content (Frame 338) is 900 wide and centred. Frame 275, the
   acquired-brand logo strip that would follow 64px later, is intentionally not
   built, so the section closes straight after the lede. */
.companiesIntro {
  position: relative;
  overflow: hidden;
  /* Figma rebuilt this as "ECI Family" 4178:3477 (the old 909:4172 is gone), which
     carries a video fill like the homepage twin — .companiesIntro__video plays it
     and the poster is the paint underneath, replacing the solved 909:4172 gradient.
     The rejected-near-miss note for that ramp stays in the node digest. */
  background: url('../assets/videos/family-network-poster.jpg') center / cover no-repeat;
  /* Padding is load-bearing: .companiesLogos cancels it with a matching negative
     inline margin to run the logo band full-bleed, so this cannot become a width. */
  padding: clamp(64px, 8.47vw, 162.6px) var(--space-8) var(--space-8); /* was 128px */
}

/* Child combinator for the same specificity reason as .hero__video and
   .family__video; width/height because an absolutely positioned replaced element
   resolves auto to its intrinsic size. */
.companiesIntro > .companiesIntro__video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: 0;
  pointer-events: none;
}

.companiesIntro > * {
  position: relative;
  z-index: 1;
}

/* Top scrim, the same treatment as .hero::after. NOT from the Figma design —
   added 2026-09-23 at the user's request. z-index 0 + last in tree order puts
   it over the video (also 0) and under the content (1). */
.companiesIntro::after {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 25%;
  min-height: 100px;
  background: linear-gradient(180deg, rgba(0, 0, 0, 1), rgba(0, 0, 0, 0));
  z-index: 0;
  pointer-events: none;
}

/* Bottom scrim, the mirror of ::after — added 2026-09-24 at the user's
   request. ::before is first in tree order, so it needs z-index 1 to paint
   over the video (0); the content (also 1) comes later and still sits on top. */
.companiesIntro::before {
  content: "";
  position: absolute;
  bottom: 0;
  left: 0;
  width: 100%;
  height: 25%;
  min-height: 100px;
  background: linear-gradient(0deg, rgba(12, 12, 12, 1), rgba(0, 0, 0, 0));
  z-index: 1;
  pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
  .companiesIntro > .companiesIntro__video {
    display: none;
  }
}

/* 4178:3531 — the text is now the LEFT half of a two-column row (the right half
   is an empty transparent rect the video shows through), not a centred 900px
   block. 660 of the 1384 content width = 47.69%. */
.companiesIntro__block {
  width: 47.69%;
  max-width: calc(var(--contentMax) * 0.4769);
  margin-inline: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-7); /* 48px, heading group -> lede */
  text-align: left;
}

/* Figma's Frame 258: the eyebrow+heading pair is its own 16px-gap frame. */
.companiesIntro__headingGroup {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--clamp-rem-16);
}

.companiesIntro__headingGroup .eyebrow {
  margin: 0;
}

/* 4178:3534 — fills the left column and reads left, like .family__intro h2. The
   shared .sectionHeading base centres and auto-margins, which this has to undo. */
.companiesIntro .sectionHeading {
  width: 100%;
  max-width: 100%;
  margin-inline: 0;
  text-align: left;
}

.companiesIntro__lead {
  font-size: var(--font-16);
  line-height: 1.4;
  letter-spacing: 0.1px;
}

/* --------------------------------------------------------------------------
   Our Companies logo ticker — Figma Frame 275 (939:6031) / Frame 274 (939:6032)
   -------------------------------------------------------------------------- */
/* Frame 275 is a full-bleed 1512 x 267.52 clipping frame sitting 64px below the
   intro block, so it has to break out of .companiesIntro's 64px inline padding.
   Frame 274 is the band inside it: 1625.54 x 105.19, rotated 5.75deg
   counter-clockwise (so -5.75deg in CSS, same as the homepage's original
   .family__logosStrip). Its rotated bounding box is 1627.90 x 267.52 — exactly
   Frame 275's size — and its centre sits at (756.00, 133.78), i.e. dead centre of
   the clip, so centring and rotating about the centre reproduces Figma exactly.
   The band is widened to 112vw so it still overhangs both edges above 1628px.

   Vertical insets come from Frame 273's coordinates inside 274 (y=18.56,
   height 60.50, so 26.13 below). The padding the MCP reports (38.57/46.13) does
   not reconcile with the frame's own 105.19 height: 274 is a FIXED-height
   CENTER/CENTER auto-layout whose 145.19px of padding+content overflows by 40.01,
   and centring that overflow gives 38.57 - 20.005 = 18.56 exactly. */
.companiesLogos {
  margin: clamp(32px, 4.23vw, 81.2px) calc(var(--space-8) * -1) 0; /* was 64px */
  height: 267.52px;
  position: relative;
  overflow: hidden;
}

/* Frame 274's real paint, read off the node rather than the design context, which
   emits neither the fill nor the effects: a #0c0c0c fill at 0.2, a GLASS effect
   (radius 15, refraction 0.48, depth 49, lightAngle -45, lightIntensity 0.2,
   dispersion 0.61) and a DROP_SHADOW (0 / +4 / 20 / black 0.25).

   Only two parts of the glass have a CSS equivalent. The 15px radius is the
   backdrop blur. The light is a 1px specular line on the band's own top and
   bottom edges: measured off the homepage render (where the backdrop is the hero
   video, so the effect is actually visible) it is a white overlay at alpha 0.052
   on the top edge and 0.025 on the bottom, constant across all 1512px — the
   -45deg light angle never shows because the band's left and right edges sit
   outside the clip. Refraction, depth and dispersion have no CSS analogue and are
   dropped; over a smooth backdrop they contribute nothing measurable anyway
   (an isolated render of the band over flat white matches the 0.2 fill alone
   to within 1/255). The drop shadow is kept for fidelity even though Frame 275
   clips it to the four triangular corners the rotated band leaves behind. */
.logoTicker {
  position: absolute;
  top: 50%;
  left: 50%;
  width: max(1625.54px, 112vw);
  height: 105.19px;
  transform: translate(-50%, -50%) rotate(-5.75deg);
  padding-block: clamp(9.28px, 1.23vw, 23.6px) clamp(13.065px, 1.73vw, 33.2px); /* was 18.56px, 26.13px */
  background: rgba(12, 12, 12, 0.2);
  -webkit-backdrop-filter: blur(15px);
  backdrop-filter: blur(15px);
  box-shadow:
    0 4px 20px 0 rgba(0, 0, 0, 0.25),
    inset 0 1px 0 0 rgba(255, 255, 255, 0.052),
    inset 0 -1px 0 0 rgba(255, 255, 255, 0.025);
  overflow: hidden;
}

/* One set is 897px of logos (Figma's 896.54, rounded to whole px on the img
   width attributes) + 6 x 120.995px of gap = 1622.97px. Translating the track by
   exactly that distance lands copy 2 where copy 1 started, so the loop is
   seamless. Four copies keep the band filled for the whole travel: the band is
   now up to 112vw wide, so the requirement is travel + band width < 4 x 1622.97,
   which holds to a ~4340px viewport. */
.logoTicker__track {
  display: flex;
  width: max-content;
  padding-left: 48.4px; /* Frame 273's x inside Frame 274 — the frame-0 offset */
  animation: logoTicker 35s linear infinite;
  will-change: transform;
}

@keyframes logoTicker {
  from {
    transform: translateX(0);
  }
  to {
    transform: translateX(-1622.97px);
  }
}

.logoTicker__set {
  flex-shrink: 0;
  display: flex;
  align-items: center; /* every logo is centred on Frame 273's 60.50px axis */
  gap: 120.995px;
  padding-right: 120.995px; /* the seam gap, so set 1 -> set 2 matches the rest */
  margin: 0;
  list-style: none;
}

.logoTicker__set img {
  display: block;
}

/* Figma's static frame is the honest fallback when motion is unwelcome. */
@media (prefers-reduced-motion: reduce) {
  .logoTicker__track {
    animation: none;
  }
}

/* --------------------------------------------------------------------------
   Acquisition outcomes — Figma Frame 277 (939:6073), Global Locations
   -------------------------------------------------------------------------- */
/* Three equal 461.33px cells butted edge to edge inside 64px gutters, 155px tall
   (48.5px padding around a 58px two-line block). The #818181 stroke the MCP
   reports is the Line Gradient 1 style, so it is drawn with border-image; the
   slice leaves the vertical edges solid and fades the horizontal ones out at
   their centres, which is what Figma renders. Cells overlap by 1px so a shared
   divider stays a hairline rather than doubling. */
.outcomes {
  background: var(--color-black);
  display: flex;
  align-items: stretch;
  padding-inline: 0;
  width: 91.53%;
  max-width: calc(var(--contentMax) * 0.9153);
  margin-inline: auto;
}

.outcomes__cell {
  flex: 1 0 0;
  min-width: 0;
  padding-block: clamp(24.25px, 3.21vw, 61.6px); /* was 48.5px */
  padding-inline: clamp(24.25px, 3.21vw, 61.6px); /* was 48.5px */
  border: 1px solid transparent;
  border-image: var(--gradient-line-1) 1;
}

.outcomes__cell + .outcomes__cell {
  margin-left: -1px;
}

.outcomes__cell p {
  margin: 0;
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-24);
  line-height: 1.2;
  color: var(--color-white);
}

@media (max-width: 900px) {
  /* Full bleed on mobile (Sam, 2026-09-24): the section and its video run
     edge to edge, and the text block carries the page gutter instead. */
  .companiesIntro {
    padding-block: var(--space-9);
    padding-inline: 0;
    width: 100%;
    margin-inline: 0;
  }
  .companiesIntro__block {
    width: calc(100% - (var(--gutter) * 2));
    max-width: none;
    margin-inline: auto;
  }
  .outcomes {
    flex-direction: column;
    padding-inline: 0;
    width: calc(100% - (var(--gutter) * 2));
    margin-inline: auto;
  }
  .outcomes__cell {
    padding: var(--space-7) var(--space-5);
  }
  .outcomes__cell + .outcomes__cell {
    margin-left: 0;
    margin-top: -1px;
  }
}

/* --------------------------------------------------------------------------
   Acquisition philosophy — Figma Frame 333 (939:6132), Global Locations
   -------------------------------------------------------------------------- */
/* Two stacked rows 64px apart inside 128px vertical padding. Row 1 (Frame 284)
   is a two-up: copy left, an empty transparent placeholder right that only
   reserves the half. Row 2 (Frame 262) is the .leaderIntro__body pattern with
   the image on the right instead of the left, so it reuses .statisticRow wholesale. */
.philosophy {
  background: var(--color-black);
  padding: clamp(64px, 8.47vw, 162.6px) 0; /* was 128px */
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
}

.philosophy__intro {
  display: flex;
  align-items: center;
  gap: var(--space-8);
  max-width: calc(var(--contentMax) * 0.9153);
  margin-inline: auto;
  padding-inline: 0;
  width: 91.53%;
}

.philosophy__introCopy {
  flex: 1 0 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--clamp-rem-48); /* 48px */
}

/* Figma's Frame 258 again: eyebrow + heading are their own 16px-gap frame. */
.philosophy__headingGroup {
  display: flex;
  flex-direction: column;
  gap: var(--clamp-rem-16);
}

.philosophy__headingGroup .eyebrow {
  margin: 0;
}

.philosophy .sectionHeading {
  text-align: left;
  width: 13.75em; /* 939:6137 — 660px text node @ 48px */
  max-width: 100%;
  /* The base .sectionHeading centres itself with margin-inline: auto, which
     pulls this 660px node off the column's left edge. */
  margin-inline: initial;
}

.philosophy__lead {
  font-size: var(--font-16);
  line-height: 1.4;
  letter-spacing: 0.1px;
}

/* Inter Regular, not the Medium of .eyebrow, and it carries the brand ramp.
   Currently unused — the markup was removed from global-locations.html; kept
   because the doc still carries the line. */
.philosophy__lookingFor {
  font-size: var(--font-16);
  line-height: 1.4;
  letter-spacing: 1px;
  text-transform: uppercase;
}

.philosophy__introMedia {
  flex: 1 0 0;
  min-width: 0;
  align-self: stretch;
  min-height: 353px;
}

.philosophy__body {
  display: flex;
  align-items: flex-start;
  max-width: var(--contentMax);
  margin-inline: auto;
  width: 100%;
}

/* Full-bleed to the right edge in Figma, so no right gutter on the image. */
.philosophy__list {
  flex: 1;
  min-width: 0;
  padding-inline: var(--gutter);
  display: flex;
  flex-direction: column;
}

.philosophy__list .statisticRow {
  border: 1px solid var(--color-border-mid);
  border-image: var(--gradient-line-1) 1;
  border-top-width: 0;
  padding-block: clamp(20.25px, 2.68vw, 51.5px); /* was 40.5px */
  padding-inline: clamp(24.25px, 3.21vw, 61.6px); /* was 48.5px */
}
.philosophy__list .statisticRow:first-child {
  border-top-width: 1px;
}

.philosophy__image {
  width: 500px;
  max-width: 40%;
  flex-shrink: 0;
  align-self: stretch;
  object-fit: cover;
}

/* Frame 262 (939:6132) mirrored: photo flush to the LEFT edge, statisticRow
   list to its right. */
.philosophy--globalLocationsAcquisition .philosophy__body {
  flex-direction: row-reverse;
}

@media (max-width: 900px) {
  .philosophy--globalLocationsAcquisition .philosophy__body {
    flex-direction: column;
  }
}

@media (max-width: 900px) {
  .philosophy {
    padding: var(--space-9) 0;
  }
  .philosophy__intro {
    flex-direction: column;
    align-items: stretch; /* PEOPLE-01: was flex-start, which let the 13.75em heading widen the column past the screen */
  }
  .philosophy__introMedia {
    display: none;
  }
  .philosophy__body {
    flex-direction: column;
    align-items: stretch; /* PEOPLE-03: list fills the column, even gutters */
  }
  /* F3: 2/1 is the measured stacked proportion (559 x 260 = 2.150).
     2026-09-24 (with HOME-10): stacked, the photo takes the list's gutter on
     both sides so the column is centred (was full-bleed). */
  .philosophy__image {
    width: calc(100% - (var(--gutter) * 2));
    max-width: calc(100% - (var(--gutter) * 2));
    align-self: center;
    aspect-ratio: 2 / 1;
    order: -1;
  }
  /* Matches .leaderIntro__list: space between the stacked photo and the list. */
  .philosophy__list {
    padding-top: var(--space-6);
  }
}

/* Social Responsibility (People page, Figma Frame 333 = 732:1365).
   Figma uses the same Frame 333 component on both pages — split intro over a
   statisticRow list with a flush-right photo — so this only carries the deltas:
   the outer frame is 64px block padding rather than 128 (1229 = 64 + 203 + 64
   gap + 834 + 64), and the empty Rectangle 1 beside the intro is 203 tall here
   rather than 353. There is also no "What We Look For" gradient label.
   The photo used to be the same asset as the Global Locations frame's. Corrected
   2026-09-21: they are now two different shots — this one is portrait 1328x1760
   (726:481), Global Locations is landscape (939:6149) — and the build already
   ships them as separate files. */
.socialResponsibility {
  padding-block: var(--space-8);
}
.socialResponsibility .philosophy__introMedia {
  min-height: 203px;
}

/* Frame 262 here is mirrored against the Global Locations frame: the photo is
   flush to the LEFT edge and the statisticRow list sits to its right. */
.socialResponsibility .philosophy__body {
  flex-direction: row-reverse;
}

@media (max-width: 900px) {
  .socialResponsibility .philosophy__body {
    flex-direction: column;
  }
}

/* --------------------------------------------------------------------------
   Our Companies grid — Global Locations
   Figma Frames 348 / 374 / 375 / 376 / 377 (948:833, 948:1192, 948:1211,
   948:1230, 948:1402)
   -------------------------------------------------------------------------- */
/* Each Figma frame is a 1512-wide row: 160px side gutters, 32px between the two
   580x650 slots, 32px of bottom padding and no gap of its own — which is why the
   five frames stack seamlessly into one wrapping list with a 32px gap in both
   axes. 1512 - 320 gutters - 32 gap = 1160, i.e. two 580px slots exactly. */
/* The band's fill and gutters sit on the <section>, as they do on every other
   section here; the <ul> is only the flex track. */
.companies {
  background: var(--color-black);
  padding-block: 0 var(--space-6);
  padding-inline: 0;
  width: 78.84%;
  max-width: calc(var(--contentMax) * 0.7884);
  margin-inline: auto;
}

.companiesGrid {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  row-gap: var(--space-6);
  column-gap: var(--space-6);
}

/* flex-basis rather than `flex: 1 0 0` so the ninth card keeps the 580px column
   width and sits on the left of the final row, as Frame 377 does — its second
   slot (948:1404) is an empty placeholder and is not built. */
/* F2 2026-09-18: height -> min-height. These carry a full supplier description
   plus a Learn More control, and the longest one already sits close to 650. */
.companiesGrid__item {
  flex: 0 1 calc(50% - (var(--space-6) / 2));
  min-width: 0;
  min-height: 650px;
  padding: var(--space-3) var(--space-3); /* Figma's 12px slot padding around the card */
  display: flex;
}

.companyCard {
  position: relative;
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: var(--space-8) var(--space-8);
  overflow: hidden;
  background: var(--color-black);
  /* #818181 is Line Gradient 1 flattened to its first stop by the MCP. */
  border: 1px solid var(--color-border-mid);
  border-image: var(--gradient-line-1) 1;
}

.companyCard__background {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0.2;
  pointer-events: none;
}

/* 948:1232 offsets its fill left by 55.81% at 155.77% width, which hides ~36%
   off the left edge and nothing off the right. */
.companyCard__background--right {
  object-position: 100% 50%;
}

.companyCard__body {
  position: relative;
  flex: 1;
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-9);
}

/* The "Logo 3" box is a fixed 276.141 x 121.177 slot in every card; the marks
   themselves vary in aspect ratio and are contained inside it. */
.companyCard__logo {
  width: 276px;
  height: 121px;
  max-width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* width/height rather than max-*: the BHC and ASI marks have small intrinsic
   sizes (150x45 and 184x76) and would otherwise sit at that size instead of
   scaling up to the slot the way they do on the canvas. */
.companyCard__logo img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

/* Stacked one-up on mobile the 276x121 logos dominated the card (Sam,
   2026-09-24). The box scales down evenly (200 / 276 = 0.725 both ways), so the
   balance between the logos set in Figma is kept. */
@media (max-width: 900px) {
  .companyCard__logo {
    width: 200px;
    height: 88px;
  }
}

@media (max-width: 1200px) {
  .companies {
    padding-inline: 0;
    width: calc(100% - (var(--gutter) * 2));
    margin-inline: auto;
  }
}

@media (max-width: 900px) {
  .companiesGrid {
    flex-direction: column;
    flex-wrap: nowrap;
  }
  .companiesGrid__item {
    flex: 0 0 auto;
    min-height: 420px;
    padding: 0;
  }
  .companyCard {
    padding: var(--space-7) var(--space-5);
  }
  .companyCard__body {
    gap: var(--space-8);
  }
}

/* --------------------------------------------------------------------------
   Solutions > hero  (Figma "Solutions - Main" Hero / 1158:1305)
   -------------------------------------------------------------------------- */
/* Same 634px frame and top-aligned body as the Careers hero, with two deltas:
   the inline inset is 64 rather than 96 (the frame's px is --sds-size-space-1600),
   and the measure is the homepage's 800 — so .hero__content and .hero__title's
   default 13.79em gradient box both apply unchanged.
   Unlike About/Locations/Careers the photo is NOT held at 80% opacity here; it
   sits opaque on the #0c0c0c fill, so the scrim is exactly Figma's two layers:
   a left-to-right #0c0c0c 1 -> 0 @59.615% under the copy, and a vertical
   0 -> 0.5 @69.231% -> 1 that lands the section on black. No compositing needed. */
.hero--solutions,
.hero--solutionsLowVoltage,
.hero--solutionsHighVoltage,
.hero--solutionsControlBoxes,
.hero--solutionsEngineeringComponents,
.hero--engineering,
.hero--operationalCapabilities,
.hero--markets,
.hero--megatrend,
.hero--resources,
.hero--resourcesSuccess,
.hero--resourcesStory,
.hero--resourcesFaq,
.hero--resourcesNewsroom,
.hero--contact {
  min-height: fit-content;
  height: 70.4444svh; /* was min-height: 634px, the Figma frame on a 900px viewport */
}

/* Each page template declares its own photograph below. The bare modifier is
   Solutions - Main's own hero (1543:983); the five product pages override it. */
.hero--solutions {
  background-image: url('../assets/images/solutions-hero-main.jpg');
}

.hero--solutions::before,
.hero--solutionsLowVoltage::before,
.hero--solutionsHighVoltage::before,
.hero--solutionsControlBoxes::before,
.hero--solutionsEngineeringComponents::before,
.hero--engineering::before,
.hero--operationalCapabilities::before,
.hero--markets::before,
.hero--megatrend::before,
.hero--resources::before,
.hero--resourcesSuccess::before,
.hero--resourcesStory::before,
.hero--resourcesFaq::before,
.hero--resourcesNewsroom::before,
.hero--contact::before {
  background:
    linear-gradient(90deg, #0c0c0c 0%, rgba(12, 12, 12, 0) 59.615%),
    linear-gradient(180deg, rgba(12, 12, 12, 0) 0%, rgba(12, 12, 12, 0.5) 69.231%, #0c0c0c 100%);
}

/* Operational Capabilities hero (1259:1769) — same 634px frame and horizontal
   scrim as .hero--solutions, but its vertical layer starts at 0.2 rather than 0,
   so the photo is knocked back slightly from the very top. */
.hero--operationalCapabilities {
  background-image: url('../assets/images/opcap-hero.jpg');
}

/* Markets hero (1352:1917) reads identically to Operational Capabilities — same
   634px frame, same 59.615% horizontal wash, same 0.2 -> 0.5 -> 1 vertical — so
   it shares the scrim below and only swaps the photograph. */
/* Re-issued in Figma 2026-09-22 (hero 1559:5477) and no longer the same
   photograph as the Megatrends landing hero, so the shared rule is split.
   .hero--megatrend keeps markets-hero.jpg; its own Figma node was not re-checked
   this pass. */
.hero--markets {
  background-image: url('../assets/images/markets-hero-electrification.jpg');
}

/* Data Centers has its own hero photograph in Figma (1566:6695), where the other
   market pages still share the Electrification shot above. Per-page rule so the
   shared default stays put. */
.hero--marketDataCenters {
  background-image: url('../assets/images/market-data-centers-hero.jpg');
}

/* Per-page market hero photographs, pulled 2026-09-22 (hero node per page in
   .figma-cache/…-market-detail-template.md). */
.hero--marketDriverSafety {
  background-image: url('../assets/images/market-driver-safety-hero.jpg');
}

.hero--marketAgriculture {
  background-image: url('../assets/images/market-agriculture-hero.jpg');
}

.hero--marketIndustrial {
  background-image: url('../assets/images/market-industrial-hero.jpg');
}

.hero--marketElectricVehicles {
  background-image: url('../assets/images/market-commercial-evs-hero.jpg');
}

.hero--marketSmartLighting {
  background-image: url('../assets/images/market-commercial-lighting-hero.jpg');
}

.hero--marketMedical {
  background-image: url('../assets/images/market-medical-devices-hero.jpg');
}

.hero--marketAerospace {
  background-image: url('../assets/images/market-aerospace-hero.jpg');
}

.hero--marketSemiconductor {
  background-image: url('../assets/images/market-semiconductor-hero.jpg');
}

.hero--marketResidentialHvac {
  background-image: url('../assets/images/market-residential-hvac-hero.jpg');
}

.hero--marketCommercialHvac {
  background-image: url('../assets/images/market-commercial-hvac-hero.jpg');
}

.hero--marketAppliances {
  background-image: url('../assets/images/market-appliances-hero.jpg');
}

.hero--megatrend {
  background-image: url('../assets/images/markets-hero.jpg');
}

/* Megatrends hero photographs, pulled 2026-09-22. Landing 1574:12045; details
   AI 1576:12620, Electrification 1576:13088, Automation 1576:13425,
   Connected Systems 1576:13831. */
.hero--megatrends {
  background-image: url('../assets/images/megatrends-hero.jpg');
}

.hero--megatrendAi {
  background-image: url('../assets/images/megatrend-ai-and-digitalization-hero.jpg');
}

.hero--megatrendElectrification {
  background-image: url('../assets/images/megatrend-electrification-hero.jpg');
}

.hero--megatrendAutomation {
  background-image: url('../assets/images/megatrend-automation-hero.jpg');
}

.hero--megatrendConnected {
  background-image: url('../assets/images/megatrend-smart-and-connected-systems-hero.jpg');
}

/* Appliance & HVAC hero (1470:1590) — same frame and scrim, different photo. */
.hero--marketsApplianceHvac {
  background-image: url('../assets/images/markets-appliance-hvac-hero.jpg');
}

/* Electrification & Industrial hero (1559:5477) — own photo, pulled 2026-09-22.
   .hero--markets keeps the older shot as the shared fallback. */
.hero--marketsElectrificationIndustrial {
  background-image: url('../assets/images/markets-electrification-industrial-hero.jpg');
}

.hero--operationalCapabilities::before,
.hero--solutionsLowVoltage::before, /* 1543:2862 — vertical layer opens at 0.2, re-read 2026-09-15 */
.hero--markets::before,
.hero--megatrend::before {
  background:
    linear-gradient(90deg, #0c0c0c 0%, rgba(12, 12, 12, 0) 59.615%),
    linear-gradient(180deg, rgba(12, 12, 12, 0.2) 0%, rgba(12, 12, 12, 0.5) 69.231%, #0c0c0c 100%);
}

.hero--solutions .siteHeader,
.hero--solutionsLowVoltage .siteHeader,
.hero--solutionsHighVoltage .siteHeader,
.hero--solutionsControlBoxes .siteHeader,
.hero--solutionsEngineeringComponents .siteHeader,
.hero--engineering .siteHeader,
.hero--operationalCapabilities .siteHeader,
.hero--markets .siteHeader,
.hero--megatrend .siteHeader,
.hero--resources .siteHeader,
.hero--resourcesSuccess .siteHeader,
.hero--resourcesStory .siteHeader,
.hero--resourcesFaq .siteHeader,
.hero--resourcesNewsroom .siteHeader,
.hero--contact .siteHeader {
  width: 91.53%;
  max-width: calc(var(--contentMax) * 0.9153);
}

.hero--solutions .hero__body,
.hero--solutionsLowVoltage .hero__body,
.hero--solutionsHighVoltage .hero__body,
.hero--solutionsControlBoxes .hero__body,
.hero--solutionsEngineeringComponents .hero__body,
.hero--engineering .hero__body,
.hero--operationalCapabilities .hero__body,
.hero--markets .hero__body,
.hero--megatrend .hero__body,
.hero--resources .hero__body,
.hero--resourcesSuccess .hero__body,
.hero--resourcesStory .hero__body,
.hero--resourcesFaq .hero__body,
.hero--resourcesNewsroom .hero__body,
.hero--contact .hero__body {
  align-items: flex-start;
  padding-inline: 0;
  width: 91.53%;
  max-width: calc(var(--contentMax) * 0.9153);
}

/* 1243:2181 stacks pill -> title at 24 and 1243:2180 title-group -> lede at 32,
   which is what .hero__pill and the rule below already carry. */
/* 1543:1038 is 760 wide, not the 800 the base .hero__content defaults to (that 800
   is the homepage's 298:847). Scoped to this page deliberately: `.hero--solutions`
   is shared by 32 pages and only 1543:982 has been measured — every hero measured
   so far (People, About, Locations, Careers, this) is 760, so the other 31 are
   likely 40px wide too, but that is unverified. Widen the selector once checked. */
.hero--solutionsMain .hero__content {
  max-width: min(760px, 100%);
}

.hero--solutions .hero__title,
.hero--solutionsLowVoltage .hero__title,
.hero--solutionsHighVoltage .hero__title,
.hero--solutionsControlBoxes .hero__title,
.hero--solutionsEngineeringComponents .hero__title,
.hero--engineering .hero__title,
.hero--operationalCapabilities .hero__title,
.hero--markets .hero__title,
.hero--megatrend .hero__title,
.hero--resources .hero__title,
.hero--resourcesSuccess .hero__title,
.hero--resourcesStory .hero__title,
.hero--resourcesFaq .hero__title,
.hero--resourcesNewsroom .hero__title,
.hero--contact .hero__title {
  margin-bottom: var(--clamp-rem-32);
}

.hero--solutions .hero__subtitle,
.hero--solutionsLowVoltage .hero__subtitle,
.hero--solutionsHighVoltage .hero__subtitle,
.hero--solutionsControlBoxes .hero__subtitle,
.hero--solutionsEngineeringComponents .hero__subtitle,
.hero--engineering .hero__subtitle,
.hero--operationalCapabilities .hero__subtitle,
.hero--markets .hero__subtitle,
.hero--megatrend .hero__subtitle,
.hero--resources .hero__subtitle,
.hero--resourcesSuccess .hero__subtitle,
.hero--resourcesStory .hero__subtitle,
.hero--resourcesFaq .hero__subtitle,
.hero--resourcesNewsroom .hero__subtitle,
.hero--contact .hero__subtitle {
  max-width: 100%;
  margin-bottom: 0;
}

/* --------------------------------------------------------------------------
   Solutions > statement  (Figma "Solutions - Main" InfoBlocks / 1264:3303)
   -------------------------------------------------------------------------- */
/* A single centred 24px paragraph on black, 160px block padding, 900px measure.
   The gradient host is the <p> itself, whose box is that same 900 — so the
   "fully integrated" span replays the full ramp, matching the Figma render. */
.solutionsStatement {
  background: var(--color-black);
  padding-block: clamp(80px, 10.58vw, 203.1px); /* was 160px */
  padding-inline: 0;
  width: 91.53%;
  max-width: calc(var(--contentMax) * 0.9153);
  margin-inline: auto;
}

.solutionsStatement p {
  /* Percentage widths polish 2026-09-24: Figma's 900 statement sits in the
     band's 1384 content box, 900 / 1384 = 65.03% (nested, so no --contentMax
     cap). Was a fixed max-width of 900px. Narrower screens step wider; each
     step changes the width by 150px or less. */
  width: 65.03%;
  max-width: 100%;
  margin-inline: auto;
  font-family: var(--font-heading);
  font-weight: 400;
  font-size: var(--font-24);
  line-height: 1.5;
  text-align: center;
  color: var(--color-white);
}

@media (max-width: 1399px) {
  .solutionsStatement p {
    width: 72%;
  }
}

@media (max-width: 1199px) {
  .solutionsStatement p {
    width: 80%;
  }
}

@media (max-width: 900px) {
  .solutionsStatement p {
    width: 86%;
    text-align: left; /* both variants (Sam, 2026-09-24) */
  }
}

@media (max-width: 600px) {
  .solutionsStatement p {
    width: 100%;
  }
}

@media (max-width: 900px) {
  .solutionsStatement {
    width: calc(100% - (var(--space-6) * 2));
    padding-block: var(--space-9);
  }
}

/* --------------------------------------------------------------------------
   Solutions > the four solution sections
   Frames 333 / 379 / 380 / 381 = 1158:1447, 1243:2392, 1245:1386, 1245:1696
   -------------------------------------------------------------------------- */
/* One layout, four instances. Everything that varies between them is a custom
   property set on the modifier class: the accent ramp, the soft-light wash over
   the medallion art, the check colour, and the medallion photo's opacity. */
.solution {
  background: var(--color-black);
  display: flex;
  flex-direction: column;
  gap: var(--space-9);
  padding-block: var(--space-9);
}

/* Frame 333 alone opens on 64 rather than 96 — it follows the statement band. */
.solution--lowVoltage {
  padding-top: var(--space-8);
}

/* `--check-ramp` points at the matching <linearGradient> in the page's defs
   block — see .benefit__check for why the check needs a real SVG paint server
   rather than the CSS ramp beside it. */
.solution--lowVoltage {
  --accent-gradient: var(--gradient-brand);
  --accent-wash: #40d39f;
  --accent-mid: #38abc1;
  --check-ramp: url('#ramp-brand');
  --medallion-opacity: 0.1;
}
.solution--controlBox {
  --accent-gradient: var(--gradient-control-box);
  --accent-wash: #e828a8;
  --accent-mid: #a750ff;
  --check-ramp: url('#ramp-cb');
  --medallion-opacity: 0.2;
}
.solution--highVoltage {
  --accent-gradient: var(--gradient-orange);
  --accent-wash: #ff8800;
  --accent-mid: #fba440;
  --check-ramp: url('#ramp-hv');
  --medallion-opacity: 0.2;
  --ring-color: #ffde8e;
  --ring-glow: #fdb813;
}
.solution--engineeredComponents {
  --accent-gradient: var(--gradient-blue);
  --accent-wash: #0166b3;
  --accent-mid: #49a0ff;
  --check-ramp: url('#ramp-cp');
  --medallion-opacity: 0.2;
  --ring-color: #a8ecff;
  --ring-glow: #a8ecff;
}

/* ---- top half: copy + medallion (Frame 284) ---- */
.solution__top {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-8);
  padding-inline: 0;
  width: 91.53%;
  max-width: calc(var(--contentMax) * 0.9153);
  margin-inline: auto;
}

.solution__copy {
  flex: 1 0 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--clamp-rem-48);
}

.solution__head {
  display: flex;
  flex-direction: column;
  gap: var(--clamp-rem-32);
}

.solution__head h2 {
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-48);
  line-height: 1.2;
  color: var(--color-white);
  margin: 0;
}

/* The kicker is the section's ramp clipped to the glyphs. Its Figma box is the
   full copy column, so the whole ramp plays across the line. */
.solution__kicker,
.solution__benefitsLabel {
  margin: 0;
  background-image: var(--accent-gradient);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  text-transform: uppercase;
  letter-spacing: 1px;
}

/* Corrected 2026-08-03. The kicker had no paint box of its own, so as a block in
   a stretch flex column it took the full 828 of the copy column and the ramp was
   stretched across that — every glyph got a compressed slice and the line died
   around teal instead of reaching blue. Figma's kicker text nodes are AUTO-WIDTH,
   one per section and all narrower than the column: 486 (`1158:1451`), 634
   (`1243:2396`), 610 (`1245:1390`), 655 (`1245:1700`).
   `max-content` is the exact equivalent of an auto-width text node — the box is
   the text, whatever the type is doing at this breakpoint — so it needs no
   per-section pin and no em arithmetic, unlike the fixed-width headings above.
   The text is left-aligned in a left-aligned column, so narrowing the box moves
   nothing: this is a gradient-only change. */
.solution__kicker {
  font-family: var(--font-body);
  font-weight: 500;
  font-size: var(--font-20);
  line-height: 1.15; /* was 0.75; Figma 15px on 20px */
  width: max-content;
  max-width: 100%;
}

.solution__body {
  font-size: var(--font-16);
  line-height: 1.4;
  letter-spacing: 0.1px;
  color: var(--color-white);
}

/* Same empty-line paragraph break the life bands use. */
.solution__body p {
  margin: 0;
}
.solution__body p + p {
  margin-top: var(--clamp-rem-24); /* Figma 22px -> nearest step */
}

/* ---- medallion: 492x428 art plate around a 300px mark ---- */
/* Three stacked layers in Figma: the photo held at 10-20%, a flat accent at
   soft-light, then a radial vignette that sinks the plate's edges into the
   page. The vignette's ellipse is 246 x 214 — exactly half the plate — so it
   is expressed as a 100%/100% ellipse rather than px. */
/* The three layers must paint photo -> wash -> vignette -> mark, and the wash
   needs its own blend mode, so they cannot all be background layers on one box.
   Tree order does the stacking: ::before (photo), the veil span (wash), ::after
   (vignette), then the mark lifted above with z-index. */
/* Corrected 2026-08-03. The vignette's ellipse was written `100% 100%`, on the
   reasoning that its 246 x 214 radii were "half the plate". They are — but a
   radial-gradient percentage is the RADIUS as a share of that dimension, so half
   the plate is `50% 50%`, and `100%` made the ellipse twice the size it should
   be. Effect: the falloff never completed inside the box, so the plate edges
   stayed lifted instead of sinking into the page.
   Read straight off Figma's own gradientTransform on 1264:4028 —
   matrix(0 21.4 -24.6 0 246 214) against r=10 puts the semi-axes at exactly
   246 x 214 about the centre (246, 214), i.e. 50% of 492 x 428. Cross-checked
   against the composited render along y=214: with these radii the measured
   columns at x = 0/49/98/123/172 reproduce to within ~1.5/255; at `100%` they
   are wrong by 20-90. */
/* Corrected 2026-08-03. This carried `isolation: isolate`, which was the single
   biggest mismatch on the page: it gave the soft-light veil a transparent
   backdrop, and soft-light against nothing paints the source at full strength —
   so the plate glowed saturated #40d39f instead of reading as a dark disc with a
   faint green cast. In Figma the wash blends against the page black beneath it,
   which is what removing the isolation restores.
   The tell: Figma's own `contentsOnly` render shows the *same* bright green,
   because isolating the node is exactly what that flag does. A blend-mode layer
   cannot be verified from an isolated render — measure it composited on the page.
   Composited, Figma's plate plateaus at rgb(0,18,16); soft-light green over a
   near-black backdrop reproduces that to ~1/255, the full-strength green is out
   by ~170 on the green channel. Do not reinstate the isolation: the mark still
   stacks correctly above the three layers on tree order plus its own z-index. */
.solution__medallion {
  position: relative;
  flex-shrink: 0;
  width: 492px;
  aspect-ratio: 492 / 428; /* was height: 428px */
  display: flex;
  align-items: center;
  justify-content: center;
}

.solution__medallion::before,
.solution__medallion::after,
.solution__medallionVeil {
  content: '';
  position: absolute;
  inset: 0;
}

.solution__medallion::before {
  background: var(--medallion-image) center / cover no-repeat;
  opacity: var(--medallion-opacity);
}

.solution__medallionVeil {
  background: var(--accent-wash);
  mix-blend-mode: soft-light;
}

.solution__medallion::after {
  background-image: radial-gradient(
    ellipse 50% 50% at 50% 50%,
    rgba(12, 12, 12, 0) 30%,
    rgba(13, 13, 13, 0.5) 60%,
    #0d0d0d 100%
  );
}

.solution__mark,
.solution__ring {
  position: relative;
  z-index: 1;
}

.solution--lowVoltage .solution__medallion {
  /* 1546:3476 — Figma's wash is the harness photo we already ship (MAE 0.0). */
  --medallion-image: url('../assets/images/solutions-lv-harness-photo.jpeg');
}
.solution--controlBox .solution__medallion {
  --medallion-image: url('../assets/images/solutions-cb-medallion-bg.jpg');
}
.solution--highVoltage .solution__medallion {
  --medallion-image: url('../assets/images/solutions-hv-medallion-bg.jpg');
}
.solution--engineeredComponents .solution__medallion {
  --medallion-image: url('../assets/images/solutions-cp-medallion-bg.jpg');
}

/* LV and CB draw their own ring inside the SVG, which Figma bleeds 4% past the
   300px box — hence 324. HV and CP instead put a real 300px bordered circle
   around a 108px glyph. */
.solution__mark {
  width: 324px;
  height: 324px;
  display: block;
}

/* LV-03: once .solution__top stacks, the medallion mark has nothing beside it and
   takes 87% of the viewport at 360. Phones get it ~30% smaller; 701px and up keep
   the designed 324. */
@media (max-width: 700px) {
  .solution__mark {
    width: 227px;
    height: 227px;
  }
}

.solution__ring {
  width: 300px;
  height: 300px;
  border: 2px solid var(--ring-color);
  border-radius: 50%;
  box-shadow: 0 0 12px 0 var(--ring-glow);
  display: flex;
  align-items: center;
  justify-content: center;
}

.solution__ring img {
  height: 108px;
  width: auto;
  display: block;
}

/* ---- bottom half: photo + benefit list (Frame 262) ---- */
.solution__bottom {
  display: flex;
  align-items: stretch;
}

.solution__photo {
  flex-shrink: 0;
  width: 500px;
}

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

.solution__benefits {
  flex: 1 0 0;
  min-width: 0;
  padding-inline: var(--space-8);
}

.solution__benefitsLabel {
  font-family: var(--font-body);
  font-weight: 400;
  font-size: var(--font-16);
  line-height: 1.4;
  padding-bottom: var(--space-6);
}

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

/* LV-02: same missing spacing rule as LV-01 — the label and the list had no gap
   between their boxes. Phone and tablet only, matching LV-01's range and step. */
@media (max-width: 900px) {
  .benefitList {
    margin-top: var(--clamp-rem-24);
  }
}

/* Same Line Gradient 1 border as .outcomes, stacked instead of in a row, so the
   shared edge between two blocks overlaps by 1px and stays a hairline. */
.benefit {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  padding-block: clamp(20.25px, 2.68vw, 51.5px); /* was 40.5px */
  padding-inline: clamp(24.25px, 3.21vw, 61.6px); /* was 48.5px */
  border: 1px solid transparent;
  border-image: var(--gradient-line-1) 1;
}

.benefit + .benefit {
  margin-top: -1px;
}

/* Block 1 Check Default (787:745) → Check Hover (787:748) — the same two deltas
   as Block 1's Default/Gradient pair, so this reuses --gradient-hover: the
   Hover Gradient fill, and padding-left 48.5 → 64.5 (space-1200 → 1600), which
   carries the check and its label 16px right together. Nothing else moves — the
   Line Gradient 1 border, the 16px glyph gap, the 40.5 block padding, the 105px
   height and the label's own colour are all identical across the two variants,
   and the check glyph does not change colour or gain a disc.
   Hover Gradient is a single shared style in Figma, so the wash is the brand
   ramp on all four solution sections rather than each section's own accent —
   unlike .benefit__check just below, which really is per-section. */
.benefit {
  transition:
    background-image 0.2s ease,
    padding-left 0.2s ease;
}

.benefit:hover {
  background-image: var(--gradient-hover);
  padding-left: calc(clamp(24.25px, 3.21vw, 61.6px) + 16px); /* was 64.5px, = base + 16 */
}

/* Corrected 2026-08-03. This was a flat `--accent-mid`, which is only the ramp's
   middle stop — right at the glyph's centre and wrong at both ends. Figma paints
   the section's FULL accent ramp across the check itself. Measured off 1:1
   isolated renders of Block 1 in two sections: LV runs (64,210,159)=#40d39f at
   the glyph's left edge through (56,173,190)=#38abc1 at its centre, and HV runs
   (255,221,142)=#ffde8e through (250,166,68)=#fba440 to #40d39f — i.e. each
   section's own ramp, not a shared one. Identical colour at differing y confirms
   it is purely horizontal.
   The ramp spans the glyph, not the 20px component box (t=0 lands on the first
   opaque pixel), which is exactly what an objectBoundingBox paint server gives —
   hence the plain `<linearGradient>` per section in each page's defs block, with
   no gradientUnits. A CSS gradient cannot paint an SVG stroke, so the ramp has to
   be a real paint server; the per-section indirection stays in a custom property
   so it matches how every other varying value here is carried.
   `color` is kept as the fallback for the no-defs case. */
.benefit__check {
  flex-shrink: 0;
  width: 20px;
  height: 20px;
  color: var(--accent-mid);
}

.benefit__check path {
  stroke: var(--check-ramp, currentColor);
}

.benefit p {
  margin: 0;
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-24);
  line-height: 1.15; /* was 0.833; Figma 20px on 24px */
  color: var(--color-white);
}

@media (max-width: 1200px) {
  .solution__top {
    flex-direction: column;
    align-items: flex-start;
  }
  .solution__medallion {
    width: 100%;
    max-width: 492px;
    align-self: center;
  }
}

@media (max-width: 900px) {
  .solution {
    gap: var(--space-8);
  }
  .solution__top {
    padding-inline: 0;
    width: calc(100% - (var(--gutter) * 2));
    margin-inline: auto;
  }

  .solution__kicker {
    line-height: 1.4;
  }
  .solution__bottom {
    flex-direction: column;
  }
  /* F3: 7/4 is the measured stacked proportion (559 x 320 = 1.747). */
  .solution__photo {
    width: 100%;
    max-width: 100%;
    aspect-ratio: 7 / 4;
  }
  .solution__benefits {
    padding-inline: 0;
    width: calc(100% - (var(--gutter) * 2));
    margin-inline: auto;
    padding-top: var(--space-8);
  }
  .benefit {
    padding: var(--space-7) var(--space-5);
  }
  /* Same specificity trap as .marketsPanel__column > li: .benefit:hover beats this
     bare class whatever the order, so the indent has to be re-derived here or the
     row would jump to the desktop 64.5. */
  .benefit:hover {
    padding-left: calc(var(--space-5) + 16px);
  }
  .benefit p {
    line-height: 1.3;
  }
}

/* Mirrored band. Frame 334 on Solutions > Low Voltage (1546:3469) is this same
   component flipped horizontally, and Figma builds the flip by moving the nodes
   rather than by a variant, so nothing in the design context hints at it — the
   geometry is the only tell. Measured off the page metadata:

     canonical (1158:1447)   copy 64..892  | medallion 956..1448
                             photo 0..500  | benefits  564..1448
     mirrored  (1546:3469)   medallion 64..556 | copy    620..1448
                             benefits  64..948 | photo  1012..1512

   Both halves keep the 64px inset, the 64px gutter, the 828 copy column, the 492
   plate, the 500 photo and the 884 benefits column — only the sides swap, and the
   photo bleeds off the right edge instead of the left. So row-reverse on the two
   halves is the whole change and the markup is untouched.

   Scoped above each half's own stacking breakpoint (1200 for the top, 900 for the
   bottom): row-reverse on a two-class selector would otherwise outrank the bare
   `flex-direction: column` in those media queries and wedge the mobile layout
   sideways. When stacked, both variants keep the heading first — reading order
   beats mirroring a side-by-side arrangement that no longer exists. */
@media (min-width: 1201px) {
  .solution--mirrored .solution__top {
    flex-direction: row-reverse;
  }
}

@media (min-width: 901px) {
  .solution--mirrored .solution__bottom {
    flex-direction: row-reverse;
  }
}

/* --------------------------------------------------------------------------
   Careers  (Figma "People - Careers" 736:3573)
   --------------------------------------------------------------------------
   Rebuilt clean-room from the frame on 2026-09-16, replacing the 2026-08-02
   build. Every measurement is the 1512-wide frame's own number, converted with
   the project clamp formula: clamp(N/2, (N / 1512) * 100vw, N * 1.2698).
   The old blocks (.hero--careers, .careersIntro, .whyEci, .offerCard,
   .paycomSlot, .notices, .noticeCard, .hiring, .lifeBand--careers,
   .excellenceClubBand, .pillars, .pillarCard) were removed with it.
   -------------------------------------------------------------------------- */

/* --------------------------------------------------------------------------
   Hero  (736:3574)
   -------------------------------------------------------------------------- */
/* 1512 x 634. Column with gap 96, pb 96, px 64, and the body pinned to the TOP
   of the leftover space (items-start), so the pill sits high rather than
   centred. */
.careersHero {
  position: relative;
  /* No isolation (2026-09-24): it trapped the mobile menu drawer (z 50) under
     the page-level .navigationShader (z 40). The body is already black, so the
     z-index -1 photo layer still paints over the same base without it. */
  display: flex;
  flex-direction: column;
  gap: var(--space-9);
  height: auto;
  min-height: clamp(317px, 41.93vw, 805.1px); /* was 634 */
  padding-block: 0 var(--space-9);
  padding-inline: 0;
  color: var(--color-white);
}

/* The photo is a frame fill, which the MCP never emits. Its 80% opacity over
   the #0c0c0c base was solved by measurement on 2026-08-25 and cannot be
   re-read from the file — do not "correct" it to 100%. */
.careersHero__background {
  position: absolute;
  inset: 0;
  z-index: -1;
  background-image: url('../assets/images/careers-hero.jpg');
  background-size: cover;
  background-position: center;
  opacity: 0.8;
}

/* Single vertical scrim, read straight off the frame: no horizontal arm on this
   hero, unlike About / People / Global Locations. */
.careersHero__scrim {
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(
    180deg,
    rgba(12, 12, 12, 0) 0%,
    rgba(12, 12, 12, 0.5) 69.231%,
    #0c0c0c 100%
  );
}

/* The frame's px 64 puts the nav on the same 1384/1512 measure as the copy.
   styles.css ships .siteHeader at 87.3%, which is a narrower inset than this
   frame asks for, so the hero restates it. */
/* z-index dropped 2026-09-17: at (0,2,0) this beat `header > .siteHeader` and
   pinned the header to 1, level with .careersHero__body, so the mega menu panel
   rendered under the hero copy on this page only. The 1 was only ever lifting
   the header above the -1 background and scrim, which the general rule's 3 does
   just as well. position: relative stays — it is what the z-index applies to. */
.careersHero .siteHeader {
  position: relative;
  width: 91.53%;
  max-width: calc(var(--contentMax) * 0.9153);
}

.careersHero__body {
  position: relative;
  z-index: 1;
  flex: 1 0 0;
  display: flex;
  align-items: flex-start;
  width: 91.53%;
  max-width: calc(var(--contentMax) * 0.9153);
  margin-inline: auto;
}

/* 1243:2173 — a 760 measure holding pill+title (gap 24) then the lede (gap 32). */
.careersHero__content {
  width: 100%;
  max-width: 760px;
  display: flex;
  flex-direction: column;
  gap: var(--clamp-rem-32);
}

.careersHero__headline {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--clamp-rem-24);
}

/* 1243:2175 — 48/9 padding on a horizontal ramp that is transparent at both
   ends and #38abc1 at mid, with top and bottom borders on the same ramp. The
   MCP flattens both to rgba(64,211,159,0); the alpha profile was solved off an
   isolated render (0.25 / 0.49 / 0.99 at 12.5 / 25 / 50%). */
.careersHero__pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding-block: clamp(4.5px, 0.6vw, 11.4px); /* was 9 */
  padding-inline: var(--clamp-rem-48);
  border-block: 1px solid transparent;
  border-image: linear-gradient(
      90deg,
      rgba(64, 211, 159, 0) 0%,
      rgba(56, 171, 193, 1) 50%,
      rgba(47, 132, 226, 0) 100%
    )
    1;
  background: linear-gradient(
    90deg,
    rgba(64, 211, 159, 0) 0%,
    rgba(56, 171, 193, 0.48) 50%,
    rgba(47, 132, 226, 0) 100%
  );
  font-family: var(--font-body);
  font-weight: 500;
  font-size: var(--font-14);
  line-height: 1.15;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  margin: 0;
}

/* 1243:2177 is min-w-full inside the 760 container, so 760 — not the glyphs —
   is the box the "Next" ramp is painted across. */
.careersHero__title {
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-58);
  line-height: 1.1;
  text-transform: capitalize;
  width: 13.1em; /* 760 @58 */
  max-width: 100%;
  margin: 0;
}

.careersHero__lede {
  font-size: var(--font-20);
  line-height: 1.4;
  letter-spacing: 0.1px;
  margin: 0;
}

@media (max-width: 900px) {
  .careersHero .siteHeader,
  .careersHero__body {
    width: calc(100% - (var(--gutter) * 2));
  }
}

/* --------------------------------------------------------------------------
   Join section  (InfoBlocks 736:3635)
   -------------------------------------------------------------------------- */
/* 1512 x 1232: 160 block padding, a 900 centred lead, 96, then the Why Join ECI
   band. The Background Gradient sits on a transform of [[0,-1,1],[1,0,0]] —
   t = 1 - y — so the ramp runs UPWARD: black at the top, teal at the bottom,
   meeting .jobBoard's downward copy on a continuous seam. */
.joinSection {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-9);
  padding-block: clamp(80px, 10.58vw, 203.1px); /* was 160 */
  padding-inline: 0;
  background: linear-gradient(to top, var(--gradient-bg-stops));
}

/* 736:3636 — max-w-900 inside a frame with px 0, so 900 is the real measure. */
.joinSection__lead {
  /* Percentage widths polish 2026-09-24: Figma 736:3636 is 900px of the 1512
     page, 900 / 1512 = 59.52%. Was 91.53% (F1 2026-09-18; before that the cap
     was 900px). Narrower screens step wider; each step changes the width by
     150px or less. */
  width: 59.52%;
  max-width: calc(var(--contentMax) * 0.5952);
  display: flex;
  flex-direction: column;
  gap: var(--clamp-rem-48);
  text-align: center;
}

@media (max-width: 1399px) {
  .joinSection__lead {
    width: 64%;
  }
}

@media (max-width: 900px) {
  .joinSection__lead {
    width: 80%;
  }
}

@media (max-width: 600px) {
  .joinSection__lead {
    width: 91.53%;
  }
}

/* 736:3924 — Golos at two weights in one node: body text Regular, the
   highlighted clause Medium. The ramp hangs on the whole 900 node (the shared
   :has(> .gradientText) rule in styles.css paints it), so the highlight shows
   only the slice of the ramp under it, exactly as on the canvas. */
.joinSection__statement {
  font-family: var(--font-heading);
  font-weight: 400;
  font-size: var(--font-24);
  line-height: 1.5;
  margin: 0;
}

.joinSection__statement .gradientText {
  font-weight: 500;
}

.joinSection__note {
  font-size: var(--font-16);
  line-height: 1.4;
  letter-spacing: 0.1px;
  margin: 0;
}

/* Frame 329 (736:3926) — pt 120, pb 0, gap 32. It has no fill of its own; the
   parent's ramp shows through. */
.joinBand {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
  padding-block: var(--space-10) 0;
}

.joinBand__header {
  width: 91.53%;
  max-width: calc(var(--contentMax) * 0.9153);
  margin-inline: auto;
}

/* 736:3928 is 660 of the 1384 inset row, with a 64 gap to an invisible
   rgba(217,217,217,0) spacer of the same width — i.e. exactly half the row less
   half the gap, not "50% minus a full gap". */
.joinBand__intro {
  width: calc((100% - var(--space-8)) / 2);
  min-width: min(100%, 420px);
  display: flex;
  flex-direction: column;
  gap: var(--clamp-rem-48);
}

.joinBand__headingGroup {
  display: flex;
  flex-direction: column;
  gap: var(--clamp-rem-16);
}

.joinBand__headingGroup .eyebrow {
  margin: 0;
}

.joinBand__heading {
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-48);
  line-height: 1.2;
  margin: 0;
}

.joinBand__copy {
  font-size: var(--font-16);
  line-height: 1.4;
  letter-spacing: 0.1px;
  margin: 0;
}

/* 736:3955 sits at lh 1.2, tighter than the copy above it. */
.joinBand__offerLabel {
  font-size: var(--font-16);
  line-height: 1.2;
  margin: 0;
}

/* Testimonials 736:3934 clips the row at the frame edge: 64 left inset, none on
   the right, so the sixth card runs off-canvas. Drag/overflow behaviour comes
   from .overflowTrack in styles.css. */
.joinBand__scroll {
  display: flex;
  gap: var(--space-4);
  padding: 0 0 var(--space-4) var(--space-8);
  margin: 0;
  list-style: none;
}

/* Block 3-8 (736:3956 ff) — 440 x 180, 25/33 padding, content centred. */
.benefitCard {
  flex: 0 0 440px;
  height: auto;
  min-height: 180px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding-block: clamp(16.5px, 2.18vw, 41.9px); /* was 33 */
  padding-inline: clamp(12.5px, 1.65vw, 31.7px); /* was 25 */
  scroll-snap-align: start;
  /* Line Gradient 1 — #818181 is only its first stop. */
  border: 1px solid var(--color-border-mid);
  border-image: var(--gradient-line-1) 1;
}

.benefitCard:last-child {
  margin-right: var(--space-4);
}

.benefitCard p {
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-24);
  line-height: 1.4;
  margin: 0;
}

@media (max-width: 900px) {
  .joinSection {
    padding-block: var(--space-9);
  }
  .joinBand {
    padding-block: var(--space-9) 0;
  }
  .joinBand__header {
    width: calc(100% - (var(--gutter) * 2));
  }
  .joinBand__intro {
    width: 100%;
    min-width: 0;
  }
  .joinBand__scroll {
    padding-left: var(--gutter);
  }
  .benefitCard {
    flex-basis: min(440px, 82vw);
  }
}

/* --------------------------------------------------------------------------
   Job board  (Frame 263 / 736:3642)
   -------------------------------------------------------------------------- */
/* Figma still holds a 900-tall "PAYCOM HERE" placeholder here. The live embed
   replaces it, so only the frame's own paint survives: the Background Gradient
   style, run downward to meet .joinSection's upward copy. */
.jobBoard {
  padding-inline: 0;
  background: linear-gradient(180deg, var(--gradient-bg-stops));
}

.jobBoard__panel {
  width: 91.53%;
  max-width: calc(var(--contentMax) * 0.9153);
  margin-inline: auto;
  background: rgba(200, 200, 200, 0.15);
  border: 1px solid var(--color-border-mid);
  border-image: var(--gradient-line-1) 1;
}

/* 500 is Paycom's recommended frame height; the board scrolls inside it. */
.jobBoard__embed {
  display: block;
  width: 100%;
  height: auto;
  min-height: 500px;
  aspect-ratio: 2.7638;
  border: none;
}

/* --------------------------------------------------------------------------
   Benefits notices  (Frame 264 / 747:301)
   -------------------------------------------------------------------------- */
/* 1512 x 520 — 64 inline / 32 block frame padding, two cards at 24. */
.policyNotices {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  padding-block: var(--space-6);
  padding-inline: 0;
  width: 91.53%;
  max-width: calc(var(--contentMax) * 0.9153);
  margin-inline: auto;
}

/* Block 1 / Block 2 are instances of one component (626:1283 title + 626:1284
   body) used nowhere else in the build. Figma's 48.5 / 40.5 rounds to the 48
   token and a raw 40. */
.policyCard {
  display: flex;
  flex-direction: column;
  gap: var(--clamp-rem-16);
  padding: clamp(20px, 2.65vw, 50.9px) var(--space-7); /* was 40.5 / 48.5 */
  border: 1px solid var(--color-border-mid);
  border-image: var(--gradient-line-1) 1;
}

/* 24px type on a 20px line box — single-line in the file, so the tight leading
   only shows if it ever wraps. */
.policyCard__title {
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-24);
  line-height: 1.15;
  margin: 0;
}

/* The ramp hangs on the whole body text node, not on the link, so the link
   shows only the slice of the ramp beneath it — teal here, not a full
   green-to-blue replay. */
.policyCard__body {
  font-size: var(--font-16);
  line-height: 1.4;
  letter-spacing: 0.1px;
  background-image: var(--gradient-brand);
  -webkit-background-clip: text;
  background-clip: text;
}

.policyCard__body p {
  margin: 0;
}

/* 747:305 carries an empty paragraph between its two blocks — a blank line at
   the body's own leading, not a spacing token. */
.policyCard__body p + p {
  margin-top: 1.4em;
}

.policyCard__body a {
  font-weight: 700;
  text-decoration: underline;
  text-underline-position: from-font;
}

@media (max-width: 900px) {
  .policyNotices {
    width: calc(100% - (var(--gutter) * 2));
  }
  .policyCard {
    padding: var(--space-6) var(--space-5);
  }
}

/* --------------------------------------------------------------------------
   Hiring process  (Frame 328 / 736:3996)
   -------------------------------------------------------------------------- */
/* 1512 x 2012: 128 block padding, then Frame 258 (837:732) stacking the 900
   intro and the 967 x 1413 step diagram at 96. */
.processSection {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-9);
  padding-block: clamp(64px, 8.47vw, 162.6px); /* was 128 */
  padding-inline: 0;
  background: var(--color-black);
}

.processSection__intro {
  /* Percentage widths polish 2026-09-24: Figma 837:733 is 900px of the 1512
     page, 900 / 1512 = 59.52%. Was 91.53% (F1 2026-09-18; before that the cap
     was 900px). Narrower screens step wider; each step changes the width by
     150px or less. */
  width: 59.52%;
  max-width: calc(var(--contentMax) * 0.5952);
  display: flex;
  flex-direction: column;
  gap: var(--clamp-rem-48);
  text-align: center;
}

@media (max-width: 1399px) {
  .processSection__intro {
    width: 64%;
  }
}

@media (max-width: 900px) {
  .processSection__intro {
    width: 80%;
  }
}

@media (max-width: 600px) {
  .processSection__intro {
    width: 91.53%;
  }
}

.processSection__headingGroup {
  display: flex;
  flex-direction: column;
  gap: var(--clamp-rem-16);
}

.processSection__headingGroup .eyebrow {
  margin: 0;
}

.processSection__heading {
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-48);
  line-height: 1.2;
  margin: 0;
}

/* 837:737 runs at lh 1.6, looser than the 1.4 every other lede on the page
   uses, and carries a second, italic line. */
.processSection__lede {
  font-size: var(--font-16);
  line-height: 1.6;
  letter-spacing: 0.1px;
  margin: 0;
}

/* Group 4 (837:738) is a 967 x 1413 scatter, not a list: the four circles sit
   at fixed offsets and a single stroke threads them. Held as a ratio box with
   percentage offsets so the whole diagram scales as one. */
.processDiagram {
  position: relative;
  /* Percentage widths polish 2026-09-24: Figma Group 4 837:738 is 967px of
     the 1512 page, 967 / 1512 = 63.96%. Was 91.53% (F1 2026-09-18), which drew
     the diagram 1.4x too big. Laptops step wider so the discs keep room for
     their copy; each step changes the width by 150px or less. The stacked
     layout at 900px and below is set further down. */
  width: 63.96%;
  max-width: calc(var(--contentMax) * 0.6396);
  aspect-ratio: 967 / 1413;
}

@media (max-width: 1399px) {
  .processDiagram {
    width: 74%;
  }
}

@media (max-width: 1199px) {
  .processDiagram {
    width: 85%;
  }
}

/* The steps are a list; the connector is not, so it sits outside the <ol> and
   the list fills the same coordinate box. */
.processDiagram__list {
  position: absolute;
  inset: 0;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Vector 20 (837:739) — 587.5 x 1057 at (193.5, 183.5) inside the group. */
.processDiagram__connector {
  position: absolute;
  left: 20.01%;
  top: 12.99%;
  width: 60.76%;
  height: 74.8%;
  overflow: visible;
}

/* Icon Circle 2 (1590:16651 and instances) — 380 circle, 48/72 padding. */
.processStep {
  position: absolute;
  width: 39.3%; /* 380 of 967 */
  aspect-ratio: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--clamp-rem-16);
  padding-block: clamp(36px, 4.76vw, 91.4px); /* was 72 */
  padding-inline: var(--space-7);
  /* The stroke is Line Gradient 1, not flat #818181 — measured off the isolated
     render of 837:738: grey at the disc's left/right extremes (112/89 of 255)
     falling to the page black at top and bottom, i.e. the horizontal ramp's
     transparent centre. border-image ignores border-radius, so the ramp is a
     border-box background layer under a padding-box fill. */
  border: 1px solid transparent;
  border-radius: 1000px;
  background:
    linear-gradient(var(--color-black), var(--color-black)) padding-box,
    var(--gradient-line-1) border-box;
  text-align: center;
}

.processStep--careersApply {
  left: 13.13%;
  top: 0;
}
.processStep--careersReview {
  left: 60.7%;
  top: 25.55%;
}
.processStep--careersInterview {
  left: 0;
  top: 45.79%;
}
.processStep--careersOffer {
  left: 47.98%;
  top: 73.11%;
}

/* The 80 ring is a fixed-size sibling of a fixed-size circle, so its 41 radius
   and 9 padding stay raw px rather than scaling independently of it. */
.processStep__number {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 80px;
  height: 80px;
  padding: 9px;
  /* The ring is the brand ramp, not flat #40d39f: sampled green at 180deg, teal
     at both 90 and 270 and blue at 0, so it is the 90deg ramp, NOT the vertical
     one the numeral inside takes. The element's own background is spoken for by
     background-clip: text, so the ring is a masked pseudo-element. */
  position: relative;
  border: 2px solid transparent;
  border-radius: 41px;
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-40);
  line-height: 1.2;
  color: transparent;
  background-image: linear-gradient(
    180deg,
    var(--color-brand-green) 0%,
    var(--color-brand-teal) 50%,
    var(--color-brand-blue) 100%
  );
  -webkit-background-clip: text;
  background-clip: text;
}

.processStep__number::before {
  content: '';
  position: absolute;
  inset: -2px;
  padding: 2px;
  border-radius: inherit;
  background: var(--gradient-brand);
  -webkit-mask:
    linear-gradient(#000 0 0) content-box,
    linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
  pointer-events: none;
}

.processStep__caption {
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-24);
  line-height: 1.2;
  margin: 0;
}

/* Below the card breakpoint the scatter stops working — 380 circles cannot sit
   side by side — so the four steps stack in reading order. */
@media (max-width: 900px) {
  .processDiagram {
    width: 91.53%;
    aspect-ratio: auto;
    max-width: 380px;
  }
  .processDiagram__list {
    position: static;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-7);
  }
  .processDiagram__connector {
    display: none;
  }
  .processStep {
    position: static;
    width: 85%;
  }
}

/* --------------------------------------------------------------------------
   Why ECI photo band  (Frame 330 / 736:3671)
   -------------------------------------------------------------------------- */
/* 1512 x 681 — 64 inline / 96 block padding, copy pinned right on a 580
   measure. */
.storyBand {
  position: relative;
  display: flex;
  align-items: center;
  padding-block: var(--space-9);
  padding-inline: 0;
  min-height: clamp(340px, 45.04vw, 864.7px); /* was 681 */
  color: var(--color-white);
}

.storyBand__background {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
}

.storyBand__background img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 20%; /* keeps the faces (17-25% down the photo) in frame once the band gets wider than the photo */
  display: block;
}

/* Solved against the isolated render of 736:3671, by dividing the render out by
   the source photograph per column: alpha is dead linear across the full 1512 —
   0.046 at 4.2%, 0.249 at 25%, 0.495 at 50%, 0.747 at 75%, 1.00 at the right
   edge. MAE 6.8/255, against 40.7 for the 50.48% start this rule used to carry
   and 40.3 for the 50% two-stop the MCP reports. The 50.48% figure is real but
   belongs to .lifeBand--right on the People page; it was carried over here in
   error. Do not "correct" this back to a half-width ramp. */
.storyBand__background::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(to right, rgba(12, 12, 12, 0) 0%, #0c0c0c 100%);
}

/* The frame's px 64 inset, held by a wrapper so the copy itself only has to be
   the 580 measure Figma gives it. */
.storyBand__inner {
  position: relative;
  z-index: 1;
  display: flex;
  justify-content: flex-end;
  width: 91.53%;
  max-width: calc(var(--contentMax) * 0.9153);
  margin-inline: auto;
}

.storyBand__copy {
  flex: 1 0 0;
  min-width: 0;
  max-width: 580px;
  display: flex;
  flex-direction: column;
  gap: var(--clamp-rem-32);
}

.storyBand__head {
  display: flex;
  flex-direction: column;
  gap: var(--clamp-rem-16);
}

.storyBand__head .eyebrow {
  margin: 0;
}

.storyBand__heading {
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-48);
  line-height: 1.2;
  margin: 0;
}

.storyBand__body {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--clamp-rem-32);
  font-size: var(--font-16);
  line-height: 1.4;
  letter-spacing: 0.1px;
}

.storyBand__body p {
  margin: 0;
}

/* 1779:2334 is Button Gradient 3 WITH a 1px #40d39f stroke — the shared
   .button--primary carries the brand ramp instead, so the flat green is
   restated here. */
.storyBand .button--primary {
  border: 1px solid var(--color-brand-green);
  border-image: none;
}

@media (max-width: 900px) {
  .storyBand__inner {
    width: calc(100% - (var(--gutter) * 2));
  }
  .storyBand__copy {
    max-width: none;
  }
  .storyBand__background::after {
    background: rgba(12, 12, 12, 0.7);
  }
}

/* --------------------------------------------------------------------------
   Excellence Club band  (Frame 333 / 748:444)
   -------------------------------------------------------------------------- */
/* 1512 x 675 — 64 inline / 96 block padding, two flex-1 columns at 96, the copy
   capped at 580 and the emblem card 483 tall. */
.mentorBand {
  position: relative;
  display: flex;
  padding-block: var(--space-9);
  padding-inline: 0;
  color: var(--color-white);
}

.mentorBand__background {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
}

.mentorBand__background img {
  position: absolute;
  width: 100%;
  height: 100%;
  display: block;
  object-fit: cover;
}

.mentorBand__background::after {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--color-brand-green);
  mix-blend-mode: multiply;
}

.mentorBand__inner {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  gap: var(--space-9);
  width: 91.53%;
  max-width: calc(var(--contentMax) * 0.9153);
  margin-inline: auto;
}

.mentorBand__copy {
  flex: 1 0 0;
  min-width: 0;
  max-width: 580px;
  display: flex;
  flex-direction: column;
  gap: var(--clamp-rem-32);
}

.mentorBand__head {
  display: flex;
  flex-direction: column;
  gap: var(--clamp-rem-16);
}

.mentorBand__head .eyebrow {
  margin: 0;
}

.mentorBand__heading {
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-48);
  line-height: 1.2;
  margin: 0;
}

.mentorBand__body {
  font-size: var(--font-16);
  line-height: 1.4;
  letter-spacing: 0.1px;
}

.mentorBand__body p {
  margin: 0;
}

.mentorBand__body p + p {
  margin-top: 1.4em;
}

/* 749:304 — 483 tall, 93 top / 118 bottom padding, a 30px green glow, and a 1px
   left padding Figma uses to nudge the emblem off-centre. */
.mentorCard {
  flex: 1 0 0;
  min-width: 0;
  height: auto;
  min-height: 483px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--clamp-rem-32);
  padding-block: clamp(46.5px, 6.15vw, 118.1px) clamp(59px, 7.8vw, 149.8px); /* was 93 / 118 */
  background: rgba(12, 12, 12, 0.55);
  /* Same stroke as .market__panel — the brand ramp, which the MCP reported flat
     as #40d39f. Square corners, so border-image is safe here. */
  border: 1px solid transparent;
  border-image: var(--gradient-brand) 1;
  box-shadow: 0 0 30px 0 rgba(64, 211, 159, 0.5);
  text-align: center;
}

.mentorCard__mark {
  display: block;
  width: 220px;
  height: auto;
  aspect-ratio: 220 / 157;
}

.mentorCard__text {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--clamp-rem-16);
  width: 100%;
}

.mentorCard__title {
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-40);
  line-height: 1.2;
  margin: 0;
}

.mentorCard__text .eyebrow {
  margin: 0;
}

@media (max-width: 900px) {
  .mentorBand__inner {
    flex-direction: column;
    gap: var(--space-7);
    width: calc(100% - (var(--gutter) * 2));
  }
  .mentorBand__copy {
    max-width: none;
  }
  .mentorCard {
    flex: 0 0 auto;
    width: 100%;
  }
}

/* --------------------------------------------------------------------------
   Development pillars  (Frame 331 / 740:4072)
   -------------------------------------------------------------------------- */
/* 1512 x 1977 on flat black — 128 block padding, then intro / grid / outro at
   96. */
.pillarSection {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-9);
  padding-block: clamp(64px, 8.47vw, 162.6px); /* was 128 */
  padding-inline: 0;
  background: var(--color-black);
}

.pillarSection__intro,
.pillarSection__outro {
  /* Percentage widths polish 2026-09-24: Figma 749:330 / 749:340 is 900px of the 1512
     page, 900 / 1512 = 59.52%. Was 91.53% (F1 2026-09-18; before that the cap
     was 900px). Narrower screens step wider; each step changes the width by
     150px or less. */
  width: 59.52%;
  max-width: calc(var(--contentMax) * 0.5952);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--clamp-rem-48);
  text-align: center;
}

@media (max-width: 1399px) {
  .pillarSection__intro,
  .pillarSection__outro {
    width: 64%;
  }
}

@media (max-width: 900px) {
  .pillarSection__intro,
  .pillarSection__outro {
    width: 80%;
  }
}

@media (max-width: 600px) {
  .pillarSection__intro,
  .pillarSection__outro {
    width: 91.53%;
  }
}

.pillarSection__headingGroup {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--clamp-rem-16);
  width: 100%;
}

.pillarSection__headingGroup .eyebrow {
  margin: 0;
}

.pillarSection__heading {
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-48);
  line-height: 1.2;
  margin: 0;
}

.pillarSection__lede {
  font-size: var(--font-16);
  line-height: 1.4;
  letter-spacing: 0.1px;
  margin: 0;
}

/* Frame 334 (837:647) is two rows of two, gap 24 both ways. The cards are
   flex-1 capped at 420 — 360 is only the base component's own width. */
.pillarGrid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 420px));
  justify-content: center;
  gap: var(--space-5);
  width: 91.53%;
  max-width: calc(var(--contentMax) * 0.9153);
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Block 3/4/5 (837:777 and instances) — 420 x 480, 48.5 padding, title pinned
   top and body bottom with the line graphic between. */
/* Figma distributes the three children with space-between, which bottom-flushes
   the body and so starts it at a different y in every card (a 3-line body drops
   ~29px below a 4-line one). Requested instead: every body starts at the SAME y
   and the cards run ragged at the bottom. That needs a fixed stack from the top,
   which in turn needs the title to reserve its tallest case (2 lines) so the
   graphic below it cannot shift. Deliberate departure from 837:777 — do not
   "restore" space-between. */
.developmentCard {
  height: auto;
  min-height: 480px;
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  gap: var(--space-5);
  padding: var(--space-7);
  overflow: hidden;
  border: 1px solid var(--color-border-mid);
  border-image: var(--gradient-line-1) 1;
}

/* Unlike every other gradient heading on the site this ramp runs top-to-bottom
   (bg-gradient-to-b on 837:769) and is painted on the heading itself, since the
   whole line is gradient rather than one highlighted span. */
.developmentCard__title {
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-40);
  line-height: 1.15;
  margin: 0;
  color: transparent;
  background-image: linear-gradient(
    180deg,
    var(--color-brand-green) 0%,
    var(--color-brand-teal) 50%,
    var(--color-brand-blue) 100%
  );
  -webkit-background-clip: text;
  background-clip: text;
  /* Two lines at this line-height, reserved whether the title wraps or not, so
     the graphic and body sit at the same y in all four cards. */
  min-height: 2.3em;
}

/* 1590:16724 "Frame 386" — a 118.5-tall line drawing, kept as <img> rather than
   inline SVG because the four files would otherwise collide on gradient ids.
   Frame 386 always holds FOUR <vector> children and each Block in Frame 334
   (837:647) hides the ones it does not use, giving a 1 -> 2 -> 3 -> 4 prong
   progression down the cards:
     837:1162 Learn & Reflect  1 prong   frame 55.298  -> svg 56.851
     837:1179 Grow & Inspire   2 prongs  frame 122.597 -> svg 124.15
     837:1192 Make an Impact   3 prongs  frame 189.895 -> svg 191.447
     837:1205 Network          4 prongs  frame 257.193 -> svg 258.747
   (svg width = frame + 1.553 stroke bleed.) The count is the design, not an
   export artefact — the files are sliced from the 4-prong master to match.
   They carry preserveAspectRatio="none", hence the fixed height and object-fit. */
.developmentCard__graphic {
  display: block;
  /* The card column is items-start in Figma (837:768). Without this the flex
     default stretches the image to the full content width and height: auto then
     scales it up — Grow & Inspire came out 296 x 284 instead of 124 x 118.5. */
  align-self: flex-start;
  width: auto;
  height: 118.5px;
  max-width: 100%;
  object-fit: contain;
}

/* Regular, not the Medium get_design_context reports (font-['Golos_Text:Medium']
   font-medium). Solved off the isolated render of 837:1179: ink coverage over
   the body block is 0.1676, against 0.1700 for Golos Text 400 and 0.2009 for
   500 — a 20% miss. Ink width agrees (Figma 289, 400 gives 288.1, Inter 400
   only 280.8), so the family is right and the weight was not. */
.developmentCard__body {
  font-family: var(--font-heading);
  font-weight: 400;
  font-size: var(--font-24);
  line-height: 1.2;
  margin: 0;
}

@media (max-width: 900px) {
  .pillarSection {
    padding-block: var(--space-9);
  }
  .pillarGrid {
    grid-template-columns: minmax(0, 420px);
  }
  .developmentCard {
    min-height: 420px;
    gap: var(--space-8);
  }
}

/* --------------------------------------------------------------------------
   Engineering > hero  (Figma "Solutions - Engineering" Hero / 1264:3709)
   -------------------------------------------------------------------------- */
/* Structurally identical to the Solutions > Main hero (1158:1305): 634 tall,
   64px inline inset, an 800px left-aligned measure, and the same two-layer
   scrim — a left-to-right #0c0c0c 1 -> 0 @59.615% plus a vertical
   0 -> 0.5 @69.231% -> 1. So this page borrows .hero--solutions outright and
   only swaps the photo. */
.hero--engineering {
  background-image: url('../assets/images/solutions-hero-engineering.jpg');
}

/* --------------------------------------------------------------------------
   Engineering > our engineering process  (Figma Frame 258 / 1275:752)
   -------------------------------------------------------------------------- */
/* The wrapper itself has zero block padding — it is a flat 96px-gap stack of
   intro -> card grid -> outro, and the outro carries its own 96px of padding,
   which is what closes the section against the FAQ below. */
.process {
  background: var(--color-black);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-9);
}

.process__intro,
.digitalFlow__intro {
  padding-inline: 0;
  width: 91.53%;
  /* cap minus 2 gutters: the old rule put the gutter INSIDE this box, so the
     rendered measure was always cap - 2*gutter, not cap. */
  /* F1 2026-09-18: cap was calc(900px - (var(--gutter) * 2)). Converted to a --contentMax fraction so the
     multiplier matches the width, per the front-end skill's width rule.
     Reverse by restoring the value above. */
  max-width: calc(var(--contentMax) * 0.9153);
}

/* 1469:1405 is a 660 column at x=64 inside the 1384 of content — the intro is
   left-aligned on its own measure, exactly like .partnership__intro (2970:4655).
   Centred on the full width until the 2026-09-21 //br. */
.process .sectionHeading,
.process__intro .sectionLead {
  width: 660px;
  max-width: 100%;
  text-align: left;
  margin-inline: 0;
}

/* 1275:753 is a 48px-gap stack of (eyebrow + heading) -> lede, and .eyebrow
   already carries the inner 16. The lede is the last child here, so its
   default trailing 48 would double up on the wrapper's 96. */
.process__intro .sectionLead {
  margin-bottom: 0;
}

/* 1469:1412 is a single wrapping flex row of four EQUAL cards (each `flex: 1 0 0`
   in Figma), 16px gap, 64px inline padding. The old alternating 580/780 bases
   are gone with the 2x2 grid they belonged to. */
.process__grid {
  width: 91.53%;
  max-width: calc(var(--contentMax) * 0.9153);
  margin-inline: auto;
  /* <ol>: kill the UA list indent. */
  padding-inline: 0;
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  row-gap: var(--space-4);
  column-gap: var(--space-4);
  counter-reset: process;
}

.processCard {
  flex: 1 1 0;
  min-width: 0;
  counter-increment: process;
  display: flex;
}

/* The whole card is the click target — Figma hangs the ON_CLICK overlay on
   Block 2 itself, not on its Button Set, so the card is the <button> and the
   LEARN MORE affordance inside it is a <span>. Nesting a real button inside a
   button is invalid HTML and the inner one would swallow the click. */
.processCard__trigger {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: var(--space-8);
  height: auto;
  min-height: 399px; /* Figma 1469:1413 */
  padding: clamp(24.25px, 3.21vw, 97px); /* was 48.5px */
  text-align: left;
  cursor: pointer;
  border: 1px solid var(--color-border-mid);
  border-image: var(--gradient-line-1) 1;
  /* 2026-09-21 //br: read 1469:1413's real fills via use_figma — the card is this
     vertical wash ALONE, over the page's own #0c0c0c; Frame 14 and Frame 326 both
     have empty fills, so there is no photo beneath it in the design. The photo
     layer here was carried over from the old 2x2 Block 4/Block 6 cards, which did
     have one. Measured: Figma card interior 23.6 luma vs 23.2 background (flat);
     with the photo the build read 43.1 vs 17.0. Restore by re-adding
     url('../assets/images/engineering-process-card-bg-PLACEHOLDER-watermarked.png')
     center / cover no-repeat as a second background layer. */
  background: linear-gradient(
    180deg,
    var(--color-black) 0%,
    rgba(12, 12, 12, 0.5) 82.692%,
    var(--color-black) 100%
  );
}

.processCard__head {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}

/* 40px Golos Medium on a VERTICAL ramp (`bg-gradient-to-b` in the Figma output),
   not the horizontal brand ramp every other gradient on this page uses. */
.processCard__number {
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-40);
  line-height: 1.2;
  color: transparent;
  background-image: linear-gradient(180deg, #40d39f 0%, #38abc1 50%, #2f84e2 100%);
  -webkit-background-clip: text;
  background-clip: text;
  width: max-content;
}

.processCard__title {
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-24);
  line-height: 1.2;
  color: var(--color-white);
}

/* Figma now sets this at 14px — the site default — where the old wide card set
   it a step up at 16. */
.processCard__callToAction {
  align-self: flex-start;
}

/* Hover is a component variant swap in Figma (2025:15256 "Property 1=Hover -
   Button"), smart-animate 300ms ease-out. */
.processCard__trigger:hover,
.processCard__trigger:focus-visible {
  border-image: var(--gradient-brand) 1;
}

@media (max-width: 1200px) {
  .processCard {
    flex-basis: calc((100% - var(--space-4)) / 2);
    flex-grow: 0;
  }
}

@media (max-width: 900px) {
  .processCard {
    flex-basis: 100%;
  }
  .processCard__trigger {
    min-height: 0;
    gap: var(--space-7);
  }
}

/* --------------------------------------------------------------------------
   Engineering process overlays — Figma " Profile Engineering 1-4"
   1470:1442 / 1470:1506 / 1470:1529 / 1470:1545
   -------------------------------------------------------------------------- */
/* Figma: ON_CLICK on each Block 2 opens its panel as an OVERLAY, MOVE_IN from
   TOP, 300ms, ease-out. Built on the .capabilityProfile pattern — a centred
   popup rather than an edge slide-out, because the panel is 664x469-555 and
   fits as-is. Driven by js/slide-out-panel.js via data-engineering.

   NOTE: the equivalent MOVE_IN on the People page's .valuePopup was removed at
   the user's request on 2026-09-18. This one follows Figma; if the same call is
   made here, drop the transform rules below and keep the opacity fade. */
/* W-04 2026-09-22: cap was `max-width: 664px`, the panel's Figma frame width.
   Converted to a --contentMax fraction so the multiplier matches the 91.53%
   width, per the front-end skill's width rule. This was one of the three rules
   the 2026-09-18 F1 audit deliberately left on a px cap; that decision was
   reversed on request.

   CONSEQUENCE: at --contentMax 1920 the cap is now 1346px, so the modal is
   roughly twice its designed 664px width on any viewport above ~1470px.
   To reverse: restore `max-width: 664px` and delete this comment. */
.engineeringProfile {
  position: fixed;
  width: 91.53%;
  max-width: calc(var(--contentMax) * 0.9153);
  height: fit-content; /* modal <dialog> pins block-start AND block-end to 0, so
                          `auto` stretches the box and kills `margin: auto` */
  margin: auto;
  padding: 0;
  border: 1px solid var(--color-border-mid);
  border-image: var(--gradient-line-1) 1;
  box-shadow: 0 12px 30px 0 rgba(0, 0, 0, 0.25);
  background: transparent;
  color: var(--color-white);
  overflow: visible;
  opacity: 0;
  transform: translateY(-24px);
  transition: opacity 0.3s ease-out, transform 0.3s ease-out;
}

.engineeringProfile.isEntered {
  opacity: 1;
  transform: translateY(0);
}

.engineeringProfile::backdrop {
  background: rgba(12, 12, 12, 0.6);
}

.engineeringProfile__inner {
  display: flex;
  flex-direction: column;
  gap: var(--space-7);
  padding: clamp(32px, 4.23vw, 128px); /* was 64px */
  background: rgba(12, 12, 12, 0.8);
  backdrop-filter: blur(12px);
}

.engineeringProfile__head {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}

.engineeringProfile__heading {
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-40);
  line-height: 1.2;
}

.engineeringProfile__kicker {
  font-size: var(--font-20);
  line-height: 1.4;
  letter-spacing: 1px;
  text-transform: uppercase;
}

.engineeringProfile__body {
  display: flex;
  flex-direction: column;
  gap: var(--space-7);
}

.engineeringProfile__body p {
  font-size: var(--font-16);
  line-height: 1.2;
}

.engineeringProfile__footer {
  display: flex;
  align-items: center;
}

/* Back is the only dismiss control — the design has no close glyph. Its arrow
   is the standard icon rotated 180, same as .capabilityProfile__back. */
.engineeringProfile__back {
  border: 1px solid var(--color-brand-green);
  padding: var(--clamp-rem-16) 25px;
  font-size: var(--font-16);
  letter-spacing: 1.2px;
}

.engineeringProfile__back svg {
  transform: rotate(180deg);
}

/* --------------------------------------------------------------------------
   One Digital Flow — Figma Frame 452 (2988:6708)
   -------------------------------------------------------------------------- */
.digitalFlow {
  background: var(--color-black);
  display: flex;
  flex-direction: column;
  align-items: center;
  /* 2988:6708 spaces its three blocks 64 apart (346->410 and 679->743), not the
     96 that separates this section from .process. Was --space-9 until the
     2026-09-21 //br. */
  gap: var(--space-8);
  padding-block: var(--space-9);
}

.digitalFlow__intro {
  width: 91.53%;
  /* F1 2026-09-18: cap was calc(900px - (var(--gutter) * 2)). Converted to a --contentMax fraction so the
     multiplier matches the width, per the front-end skill's width rule.
     Reverse by restoring the value above. */
  max-width: calc(var(--contentMax) * 0.9153);
}

/* 2970:4890 is a 668 column at x=64, left-aligned — same treatment as
   .process__intro and .partnership__intro. Centred until the 2026-09-21 //br. */
.digitalFlow .sectionHeading,
.digitalFlow__intro .sectionLead {
  width: 668px;
  max-width: 100%;
  text-align: left;
  margin-inline: 0;
}

.digitalFlow__intro .sectionLead:last-child {
  margin-bottom: 0;
}

/* Positioning box for the flow chain's .trackNav (2026-09-23). Full width of
   the section, so the arrows' right offset measures from the page edge, as on
   .capability__cards; .flowChain keeps its own 95.767% right-flush measure. */
.digitalFlow__rail {
  position: relative;
  align-self: stretch;
}

/* 2988:6710 lays seven 200px steps and six 32px arrow gutters out to 1592px
   inside a 1448px frame, i.e. it overflows its own container in Figma. Built as
   a scroll rail so the overflow is reachable instead of clipped. */
.flowChain {
  /* 2988:6710 sits at x=64 with width 1448 in a 1512 frame — it runs to the RIGHT
     EDGE with no gutter that side, so the 7th step is deliberately clipped and
     that clipping is the affordance telling you the row scrolls. Same treatment
     as .capability__cards; it was 91.53% centred until the 2026-09-21 //br. */
  width: 95.767%;
  max-width: calc(var(--contentMax) * 0.95767);
  margin-left: auto;
  margin-right: 0;
  padding-inline: 0;
  list-style: none;
  display: flex;
  align-items: flex-start;
  /* Seven 200px steps with six 32px arrow gutters = 1592. The gutters were 0,
     which butted the labels together and left the connector's -49.5px offset —
     which is (32 + 67) / 2, i.e. derived FROM this gutter — sitting wrong. */
  gap: var(--space-6);
  overflow-x: auto;
  counter-reset: flow;
  /* The house pattern hides the OS bar and leans on the clipped last item
     instead; a raw light scrollbar was printing across the full rail. */
  scrollbar-width: none;
}

.flowChain::-webkit-scrollbar {
  display: none;
}

/* .flowChain is also an .overflowTrack (drag to scroll on desktop). Its step
   icons are <img>s, and a native image drag would swallow the pointer, so they
   are taken out of hit-testing — they are decorative (aria-hidden). */
.flowChain img {
  -webkit-user-drag: none;
  pointer-events: none;
}

.flowStep {
  flex: 0 0 200px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-6);
  text-align: center;
}

/* The connector is a 67px rule inside a 32px gutter frame, i.e. it deliberately
   bleeds past its own box on both sides. Drawn as a ::after on the step rather
   than as seven more list items, so the markup stays one item per real step.
   2026-09-21 //br: read 2988:6723 via use_figma — strokeWeight 2, dashPattern
   [1, 6], and the brand ramp, not the flat green a 1px dotted border gave. The
   ramp cannot ride a border, so it is a masked background bar. */
.flowStep + .flowStep::before {
  content: '';
  position: absolute;
  top: 75px; /* half the 150px circle */
  width: 67px;
  height: 2px;
  /* Figma centres each 67px rule on its 32px gutter frame (2988:6723 et al),
     which is also the centre of the gap between two circles. Two things have to
     be right for that: the offset must derive from var(--space-6), because the
     gutter is fluid and a fixed -49.5px only lands at 1512; and it must be `left`,
     not `margin-left`. With no `left`, the box takes its static position inside a
     column flex with align-items:center, and a negative margin then feeds back
     into that centring — halving its own effect and leaving the rule sitting over
     the circle rather than in the gap. `left` is measured from the step's padding
     box, so the geometry is explicit. */
  left: calc(var(--space-6) / -2 - 33.5px);
  background-image: var(--gradient-brand);
  -webkit-mask-image: repeating-linear-gradient(to right, #000 0 1px, transparent 1px 7px);
  mask-image: repeating-linear-gradient(to right, #000 0 1px, transparent 1px 7px);
}

.flowStep + .flowStep {
  position: relative;
}

/* 2026-09-21 //br: 2988:6712's stroke is the brand ramp at 0.75, not the flat
   green it was built with — read via use_figma, which is the only tool that
   returns it. border-image ignores border-radius, so the ramp is a masked
   pseudo-element, the same technique as .moreSolutions__ring::before. */
.flowStep__icon {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 150px;
  height: 150px;
  padding: 4.5px;
  border: 0.75px solid transparent;
  border-radius: 500px;
  flex-shrink: 0;
}

.flowStep__icon::before {
  content: '';
  position: absolute;
  inset: 2px;
  padding: 2px;
  border-radius: inherit;
  background: var(--gradient-brand);
  -webkit-mask:
    linear-gradient(#000 0 0) content-box,
    linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
  pointer-events: none;
}

.flowStep__icon img {
  width: 65px;
  height: 65px;
}

.flowStep__label {
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-24);
  line-height: 1.2;
  color: var(--color-white);
}

.flowOutcomes {
  width: 91.53%;
  max-width: calc(var(--contentMax) * 0.9153);
  margin-inline: auto;
}

.flowOutcomes__label {
  font-size: var(--font-16);
  letter-spacing: 1px;
  text-transform: uppercase;
  color: transparent;
  background-image: var(--gradient-brand);
  -webkit-background-clip: text;
  background-clip: text;
  width: max-content;
  margin-bottom: var(--clamp-rem-16);
}

/* Block 1/7/9/8 at 346 wide — the .benefit component, so the Line Gradient 1
   rule and the 24px title match the four already on this page. */
.flowOutcomes__list {
  padding-inline: 0;
  list-style: none;
  display: flex;
  flex-wrap: wrap;
}

.flowOutcome {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  align-items: flex-start;
  gap: var(--clamp-rem-16);
  padding: clamp(20.25px, 2.68vw, 81px) clamp(24.25px, 3.21vw, 97px); /* was 40.5 / 48.5 */
  border: 1px solid var(--color-border-mid);
  border-image: var(--gradient-line-1) 1;
}

.flowOutcome__check {
  width: 20px;
  flex-shrink: 0;
  margin-top: 0.35em;
}

.flowOutcome__label {
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-24);
  line-height: 1.2;
  color: var(--color-white);
}

@media (max-width: 900px) {
  .flowOutcome {
    flex-basis: 100%;
  }
  .flowStep__label {
    font-size: var(--font-20);
  }
}


/* --------------------------------------------------------------------------
   Engineering Partnership Models — Figma Frame 390 (2970:4562)
   -------------------------------------------------------------------------- */
/* Full-bleed Background Gradient band, the same token the story pages' .storyWhy
   uses. Body-width, so no max-width — see the --contentMax exception. */
.partnership {
  width: 100%;
  /* Same stops as .storyWhy, opposite direction: that band fades teal UPWARD
     into the teal rows below it, this one carries the teal at the TOP and
     settles to black at the bottom. Direction read off the render, not the
     token — the MCP reports the style name only, with an empty value. */
  background: linear-gradient(to bottom, var(--gradient-bg-stops));
  padding-block: var(--space-8);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-7);
}

.partnership__intro {
  width: 91.53%;
  max-width: calc(var(--contentMax) * 0.9153);
  margin-inline: auto;
}

/* 2970:4655 is a 660 column inside the 1384 of content — the intro does NOT run
   the full measure, unlike the centred intros elsewhere on this page. */
.partnership__intro .sectionHeading,
.partnership__intro .sectionLead {
  width: 660px;
  max-width: 100%;
}

/* .sectionLead is centred and auto-margined by default; Frame 437 (2970:4655)
   sets this one left inside its own 660 column. */
.partnership__intro .sectionHeading,
.partnership__intro .sectionLead {
  text-align: left;
  margin-inline: 0;
}

.partnership__intro .sectionLead {
  margin-bottom: 0;
}

.partnership__label {
  width: 91.53%;
  max-width: calc(var(--contentMax) * 0.9153);
  margin-inline: auto;
  font-size: var(--font-16);
  letter-spacing: 1px;
  text-transform: uppercase;
  color: transparent;
  background-image: var(--gradient-brand);
  -webkit-background-clip: text;
  background-clip: text;
}

.partnership__row {
  width: 91.53%;
  max-width: calc(var(--contentMax) * 0.9153);
  margin-inline: auto;
  display: flex;
  align-items: stretch;
  gap: var(--space-8);
}

/* 4045:6816 (595) beside Frame 332 (725) over 1384 of content once the 64 gap
   is taken out — 595 + 64 + 725 = 1384. */
.partnership__models {
  flex: 0 1 calc((100% - var(--space-8)) * 595 / 1320);
  min-width: 0;
  padding-inline: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

/* The three rows stack with no gap — each carries its own 1px rule, so
   consecutive rows share an edge exactly as they do in Figma. */
.partnerModel {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  padding: clamp(24.25px, 3.21vw, 97px); /* was 48.5px */
  border: 1px solid var(--color-border-mid);
  border-image: var(--gradient-line-1) 1;
}

.partnerModel__title {
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-28);
  line-height: 1.2;
  color: var(--color-white);
}

.partnerModel__kicker {
  font-size: var(--font-16);
  line-height: 1.4;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: transparent;
  background-image: var(--gradient-brand);
  -webkit-background-clip: text;
  background-clip: text;
  width: max-content;
  max-width: 100%;
}

.partnerModel__body {
  font-size: var(--font-14);
  line-height: 1.4;
  letter-spacing: 0.1px;
}

/* Frame 332: photo, then a flat rgba(12,12,12,0.5) hold, then #133e48 at
   mix-blend-mode: overlay. The blend layer is invisible to get_design_context's
   own output and only shows in the render — it is what tips the plate teal. */
.partnerQuote {
  flex: 0 1 calc((100% - var(--space-8)) * 725 / 1320);
  min-width: 0;
  position: relative;
  margin: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-5);
  padding-inline: clamp(32px, 4.23vw, 128px); /* was 64px */
  padding-block: clamp(107px, 14.15vw, 428px); /* was 214px */
  border: 1px solid var(--color-border-mid);
  border-image: var(--gradient-line-1) 1;
  overflow: hidden;
}

.partnerQuote__background {
  position: absolute;
  inset: 0;
  background: url('../assets/images/engineering-partnership-quote.jpg') center / cover no-repeat;
}

.partnerQuote__background::before,
.partnerQuote__background::after {
  content: '';
  position: absolute;
  inset: 0;
}

.partnerQuote__background::before {
  background: rgba(12, 12, 12, 0.5);
}

.partnerQuote__background::after {
  background: #133e48;
  mix-blend-mode: overlay;
}

.partnerQuote__mark {
  position: relative;
  width: 50px;
  height: 35px;
  flex-shrink: 0;
  align-self: flex-start;
}

.partnerQuote__mark--close {
  transform: rotate(180deg);
  align-self: flex-end;
}

/* Half-size quote marks on mobile (Sam, 2026-09-24). */
@media (max-width: 900px) {
  .partnerQuote__mark {
    width: 25px;
    height: 17.5px;
  }
}

.partnerQuote__text {
  position: relative;
  flex: 1 1 auto;
  min-width: 0;
  margin: 0;
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-28);
  line-height: 1.4;
  color: var(--color-white);
}

@media (max-width: 1200px) {
  .partnership__row {
    flex-direction: column;
  }
  .partnership__models,
  .partnerQuote {
    flex-basis: auto;
  }
  .partnerQuote {
    padding-block: var(--space-8);
  }
}

/* --------------------------------------------------------------------------
   Engineering > Digital Tools  (Figma Frame 333 / 1275:1177)
   -------------------------------------------------------------------------- */
/* The .solution component again, at the brand ramp. Frame 262 is byte-for-byte
   the .solution__bottom of the four Solutions > Main sections — 500px photo,
   64px inset, an 884px benefit column, the same 40.5/48.5 Line-Gradient-1
   blocks, the same 24px/20px titles — so all of that is inherited. Only the top
   half and the section rhythm differ, and that is this whole block. */
.solution--tools {
  --accent-gradient: var(--gradient-brand);
  --accent-mid: var(--color-brand-teal);
  --check-ramp: url('#ramp-brand');
  /* 64 throughout rather than the 96 the four Solutions sections use. */
  gap: var(--space-8);
  padding-block: var(--space-8);
}

/* Frame 284 here is two equal 660 columns, not the 828 copy + 492 medallion of
   the other instances — so the copy column stops at half the inset width. */
.solution--tools .solution__plate {
  flex: 1 0 0;
  min-width: 0;
  align-self: stretch;
}

/* 1275:1180 is the standard 16px eyebrow + heading pair, so .eyebrow's own
   bottom margin supplies the step and the head's own gap must stand down —
   otherwise the two stack to 48. */
.solution--tools .solution__head {
  gap: 0;
}

/* Frame 262 photo 2982:6110 (500x466). Figma crops left-of-centre and flush to
   the top; centre reads MAE 59 against the render, 17%/0% reads 2.21. */
.solution--tools .solution__photo img {
  object-position: 17% 0%;
}

/* 1275:1211 pads the label 24 rather than the 32 the other instances use. */
.solution--tools .solution__benefitsLabel {
  padding-bottom: var(--space-5);
}

@media (max-width: 1200px) {
  /* Nothing occupies the plate, so at one column it would only add dead space. */
  .solution--tools .solution__plate {
    display: none;
  }
}

/* --------------------------------------------------------------------------
   Engineering > Certifications  (Figma Frame 335 / 1338:1225)
   --------------------------------------------------------------------------
   Full-bleed band, 1512 x 747. Three stacked paints on the frame: the photo, a
   flat #40d39f at multiply, then a vertical #0c0c0c scrim that is transparent at
   69.231% and solid at both ends. The first two are one background pair blended
   with background-blend-mode; the scrim is ::after, since blend-mode would fold
   it into the multiply as well. STILL A WATERMARKED, UNLICENSED ADOBE STOCK COMP
   (and only 1000 x 560, so it upscales on a 1512 band) — replace before launch. */
.certifications {
  position: relative;
  isolation: isolate;
  display: flex;
  align-items: center;
  gap: var(--space-8);
  padding: var(--space-9) var(--gutter);
  background-image:
    linear-gradient(var(--color-brand-green), var(--color-brand-green)),
    url('../assets/images/certifications-bg.jpg');
  background-size: cover, cover;
  background-position: center, center;
  background-repeat: no-repeat, no-repeat;
  background-blend-mode: multiply, normal;
}

.certifications::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background: linear-gradient(
    to top,
    var(--color-black) 0%,
    rgba(12, 12, 12, 0) 69.231%,
    var(--color-black) 100%
  );
}

/* 1338:1226 — flex:1 with a 560 cap, so the grid takes the remaining 824. */
.certifications__panel {
  flex: 1;
  min-width: 0;
  max-width: 560px;
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
  padding: var(--space-8) var(--space-8);
  background: rgba(12, 12, 12, 0.55);
  border: 1px solid var(--color-brand-green);
  box-shadow: 0 0 30px 0 rgba(64, 211, 159, 0.5);
}

/* Note this band does NOT follow the house 16/48/48 intro rhythm — Figma has
   eyebrow →16→ heading →32→ lede here (1338:1229 gap 16, 1338:1228 gap 32). */
.certifications__head {
  display: flex;
  flex-direction: column;
  gap: var(--clamp-rem-16);
}

.certifications__head h2 {
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-48);
  line-height: 1.2;
  width: 9em; /* 1338:1231  432 @48 — the panel's 560 less 64 padding each side */
  max-width: 100%;
}

.certifications__lead {
  font-size: var(--font-16);
  letter-spacing: 0.1px;
  line-height: 1.4;
}

/* Right Column Panel 1338:1233 — 4 x 3, gap 32 both ways. */
.certifications__grid {
  flex: 1;
  min-width: 0;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  row-gap: var(--space-6);
  column-gap: var(--space-6);
  margin: 0;
  padding: 0;
  list-style: none;
}

.certificationCard {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: clamp(6px, 0.79vw, 15.2px); /* was 12px */
  text-align: center;
}

/* 2026-09-21: the white disc is gone. Figma replaced the 12 placeholder glyphs
   (circle-x / app-window / shield-check on a 64px white circle) with the real
   cert marks, which sit directly on the band in a 64-tall box at their own
   widths — RoHS 108, AS9100 140, IPC 112, CSA 57. A 64px circle cannot hold
   them. Restore by re-adding width/height 64, border-radius 50%, a white
   background and the 1px #e2e8f0 border. */
.certificationCard__logo {
  flex-shrink: 0;
  height: 64px;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Each mark carries its own Figma width/height as HTML attributes and is sized
   by them. Do NOT set width/height here: `auto` OVERRIDES the presentational
   attribute, and the two raster marks (ISO 9001, ESD) then paint at their
   intrinsic 198 and 354 instead of 64 and 84. */
.certificationCard__logo img {
  display: block;
  max-width: 100%;
  max-height: 64px;
}

.certificationCard__labels {
  display: flex;
  flex-direction: column;
  gap: var(--clamp-rem-4);
  width: 100%;
}

.certificationCard__name {
  font-weight: 700;
  font-size: var(--font-12);
}
.certificationCard__description {
  font-size: var(--font-10);
  line-height: 1.3;
}

@media (max-width: 1200px) {
  .certifications {
    flex-direction: column;
    align-items: stretch;
  }
  .certifications__panel {
    max-width: none;
  }
  .certifications__head h2 {
    width: auto;
  }
}

@media (max-width: 700px) {
  .certifications__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .certifications__panel {
    padding: var(--space-6) var(--space-6);
  }
}

/* --------------------------------------------------------------------------
   Solutions > More of What We Offer  (Figma Frame 389 / 1355:2745)
   --------------------------------------------------------------------------
   1512 x 1037, and its Frame 348 is the same Block 4 pair as About's .missionVisionCards
   (881:2671), so the card chrome is inherited and only the deltas live here.
   Frame 285 above it is `py 32 px 64`, sitting under the section's own 48px top
   padding and 0 bottom.
   These are Block 4's Yellow variants (1355:2488 Default / 1355:2509 Hover), which
   carry the same three hover deltas as Green and Blue, so the hover rules up at
   .missionVisionCards__slot cover this pair too — only --mv-glow is redeclared here. */
.moreSolutions {
  padding-top: var(--space-7);
  background: var(--color-black);
}

.moreSolutions__intro {
  padding-block: var(--space-6);
  padding-inline: 0;
  width: 91.53%;
  max-width: calc(var(--contentMax) * 0.9153);
  margin-inline: auto;
}

/* 1355:2413 — eyebrow →16→ heading, both centred in a 900px box. .eyebrow's own
   16px bottom margin is the gap, so no flex gap is needed. */
.moreSolutions__intro .eyebrow {
  text-align: center;
}

/* About's row is `0 160px 96px`; Frame 348 here is `64px 160px`. */
.moreSolutions__cards {
  padding-block: var(--space-8);
  padding-inline: 0;
  width: 78.84%;
  max-width: calc(var(--contentMax) * 0.7884);
  margin-inline: auto;
}

/* Figma narrows only the second card's side padding to 48, but unlike
   .missionVisionCard--vision it stays vertically centred — so this is a padding-only
   delta, not that modifier. */
.moreSolutions__card--narrow {
  padding-inline: var(--space-7);
}

/* The body gains a button, so the rhythm deepens: 48 between the copy group and
   the button (1355:2547), 24 inside the group (1355:2548). */
.moreSolutions__body {
  gap: var(--clamp-rem-48);
}

.moreSolutions__head {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--clamp-rem-24);
  width: 100%;
}

/* Whole-element brand ramp, not a .gradientText span: these eyebrows are
   shrink-wrapped nowrap nodes, so the element box already equals the Figma text
   node — the same reason .rotatingCards__kicker is painted this way. */
.moreSolutions__head .eyebrow {
  margin: 0;
  background-image: var(--gradient-brand);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

@media (max-width: 1200px) {
  .moreSolutions__cards {
    padding-inline: 0;
    width: calc(100% - (var(--gutter) * 2));
    margin-inline: auto;
  }
}

@media (max-width: 900px) {
  .moreSolutions__cards {
    flex-direction: column;
    align-items: stretch;
  }
  /* Scoped: About's .missionVisionCards keeps its own fixed-height slots. */
  .moreSolutions__cards .missionVisionCards__slot {
    height: auto;
  }
  /* SITE-06: the CTA cards with no medallion image (Solutions hub, Operational
     Capabilities, Engineering, Megatrends, the markets pages, legal pages) need
     far less than 650px once stacked. */
  .moreSolutions__cards .missionVisionCards__slot:not(:has(img)) {
    min-height: 420px;
  }
}

/* --------------------------------------------------------------------------
   Solutions > Operational Capabilities — the three "capability" bands
   Frames 326 / 382 / 383 = 1259:2493, 1259:2549, 1264:2866
   -------------------------------------------------------------------------- */
/* One layout, three instances: a two-column intro (copy + media placeholder)
   over a horizontally scrolling row of Block 3 photo cards. Section rhythm from
   Figma: 96 top / 48 bottom padding, 64 between intro and the card row. The teal
   modifier is the shared --gradient-bg-stops pointing left, which puts the first
   stop (#0e343d) at the right edge and black at the left — matching Frame 382. */
.capability {
  background: var(--color-black);
  padding: var(--space-9) 0 var(--space-7);
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
}

.capability--teal {
  background: linear-gradient(to left, var(--gradient-bg-stops));
}

/* Frame 284 / 285: two equal columns, 64px gutter, 64px inline inset. */
.capability__intro {
  display: flex;
  align-items: center;
  gap: var(--space-8);
  padding-inline: 0;
  width: 91.53%;
  max-width: calc(var(--contentMax) * 0.9153);
  margin-inline: auto;
}

/* Frame 325 is 660 of the 1384 content width — the other half is Rectangle 1,
   a fully transparent rect in Figma with nothing in it. Nothing is drawn there,
   so there is no element for it; the copy just holds its half-width measure. */
.capability__copy {
  flex: 0 1 calc(50% - var(--space-8) / 2);
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--clamp-rem-48); /* Frame 325 stacks the head group -> body at 48 */
  word-break: break-word;
}

.capability__head {
  display: flex;
  flex-direction: column;
  gap: var(--clamp-rem-24); /* Frame 258: heading -> subhead at 24 */
}

.capability__head h2 {
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-48);
  line-height: 1.2;
  color: var(--color-white);
}

/* Whole-element brand ramp: the subheading IS the gradient (not a highlighted
   word), and its Figma text-node box is the full 660 copy column, so the ramp
   runs edge to edge across both wrapped lines. */
.capability__subheading {
  font-family: var(--font-body);
  font-weight: 500;
  font-size: var(--font-20);
  line-height: 1.4;
  letter-spacing: 1px;
  text-transform: uppercase;
  background-image: var(--gradient-brand);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  width: 100%;
}

.capability__body {
  font-size: var(--font-16);
  line-height: 1.4;
  letter-spacing: 0.1px;
  color: var(--color-white);
}

/* Horizontal drag-to-scroll track. Also the JS hook for js/overflow-track.js. */
.overflowTrack {
  display: flex;
  flex-direction: row;
  overflow-x: auto;
  overflow-y: hidden;
  cursor: grab;
  user-select: none;
  -webkit-user-select: none;
  scroll-behavior: auto;
  touch-action: pan-x;
  scrollbar-width: none;
}

/* Testimonials frame: scrolls horizontally, and the track is now held to the
   same 91.53% content measure as the rest of the page rather than being inset
   64px from the left edge. */
/* Figma Frame 14 (1546:3664 and its siblings on the other four Solutions pages)
   sits at x=64 with width 1448 inside a 1512 frame: 64 + 1448 = 1512, so the
   track starts at the standard left gutter and runs to the RIGHT EDGE of the
   page with no gutter on that side — the last card is deliberately clipped, and
   that clipping is the affordance telling you the row scrolls.

   1448/1512 = 95.767%, pushed right by margin-left: auto. It was 91.53% centred,
   which gave it an equal gutter on both sides and hid the overflow cue. */
/* overflow was auto/hidden here until 2026-09-23. The .capability__track inside is
   the scroller (.overflowTrack), so this box never overflowed; it is visible now
   so the prev/next arrows can sit above it without being clipped. */
/* LV-10: left edge pinned to the 91.53% content column (64px = 4.233% at 1512),
   right edge runs to the page edge. Was width 95.767% + max-width 1839px +
   margin-left: auto, which drifted right above 1920. */
.capability__cards {
  position: relative;
  margin-left: max(4.233%, calc((100% - var(--contentMax) * 0.9153) / 2));
  margin-right: 0;
}

.capability__track {
  display: flex;
  gap: var(--space-4); /* 16px between cards */
  align-items: stretch;
}

/* Leading inset for the card scroller on mobile (Sam, 2026-09-24). */
@media (max-width: 900px) {
  .capability__track {
    padding-left: 12vw;
  }
}

/* .trackNav — prev/next arrows for drag-scroll rows (js/track-nav.js): every
   .capability__track and the Engineering .flowChain. NOT in Figma: layout after
   britech.com's cardCarouselContainer (Sam, 2026-09-23). Two square outline
   buttons over the track's right end, in the gap above it. Was right-aligned to
   the 91.53% content edge via right: max(4.422%, calc((100vw - var(--contentMax)
   * 0.9153) / 2)); now --space-4 from the box's right (= page) edge.
   Its wrapper must be position: relative and share the row's right (= page)
   edge. Shown only while the row overflows (JS); mouse/trackpad only: touch swipes. */
.trackNav {
  display: none;
  position: absolute;
  bottom: calc(100% + var(--space-4));
  right: var(--space-4); /* 16px in from the page edge (Sam, 2026-09-23) */
  gap: var(--space-3);
}

@media (hover: hover) and (min-width: 901px) {
  .trackNav:not([hidden]) {
    display: flex;
  }
}

.trackNav__arrow {
  display: flex;
  align-items: center;
  justify-content: center;
  width: clamp(44px, 3.17vw, 61px); /* 48 at 1512; 44 floor keeps the hit area */
  aspect-ratio: 1;
  padding: 0;
  background: transparent;
  border: 1px solid var(--color-white);
  border-radius: 4px;
  cursor: pointer;
  transition: background-color 0.2s ease;
}

.trackNav__arrow img {
  width: 55%;
  height: auto;
  transition: opacity 0.2s ease;
}

/* icon-chevron.svg points down */
.trackNav__arrow--prev img {
  transform: rotate(90deg);
}

.trackNav__arrow--next img {
  transform: rotate(-90deg);
}

.trackNav__arrow:hover:not(:disabled) {
  background-color: rgba(255, 255, 255, 0.1);
}

.trackNav__arrow:focus-visible {
  outline: 2px solid var(--color-brand-green);
  outline-offset: 2px;
}

/* End of the row: the chevron fades, like Britech's 0.25 */
.trackNav__arrow:disabled {
  cursor: default;
}

.trackNav__arrow:disabled img {
  opacity: 0.25;
}

/* Block 3 (I…;1275:1026 + Button Set): a 320x400 photo card, Line Gradient 1
   border, title top-left, gradient button bottom, justified apart. */
.capabilityCard {
  position: relative;
  flex: 0 0 320px;
  width: 320px;
  height: auto;
  min-height: 400px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding-block: clamp(12.5px, 1.65vw, 31.7px); /* was 25px */
  padding-inline: clamp(12.5px, 1.65vw, 31.7px); /* was 25px */
  border: 1px solid transparent;
  border-image: var(--gradient-line-1) 1;
  isolation: isolate;
  overflow: hidden;
}

/* Operational-capabilities cards share one shot and carry no background div, so
   the default photo stays on the block. Low-Voltage's .capabilityCard--photo
   instances each supply their own .capabilityCard__background instead. */
.capabilityCard:not(.capabilityCard--photo) {
  background: url('../assets/images/opcap-card.jpg') center / cover no-repeat;
}

/* Dedicated photo layer, the house pattern (cf. .mentorBand__background).
   z-index -2 puts it under the block's own ::after scrim (-1) and under the
   in-flow panel; `isolation: isolate` on the block keeps both inside it. */
.capabilityCard__background {
  position: absolute;
  inset: 0;
  z-index: -2;
  pointer-events: none;
  background-position: center;
  background-size: cover;
  background-repeat: no-repeat;
}

/* Trailing gap so the last card doesn't sit flush against the scroll end. */
.capabilityCard:last-child {
  margin-right: var(--space-4);
}

/* Low-Voltage's track (1546:3664) was repurposed 2026-08-25 from five process
   steps to eight application markets: each card now carries its own photo on
   a .capabilityCard__background div, the title sits at the bottom at 28px, and
   there is no button. Scrim is Figma's own
   vertical ramp on the Block 3 instances. */
.capabilityCard--photo {
  justify-content: flex-end;
  position: relative;
}

.capabilityCard--photo::before {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(
    180deg,
    rgba(12, 12, 12, 0.6) 0%,
    rgba(12, 12, 12, 0.3) 58.654%,
    #0c0c0c 100%
  );
  pointer-events: none;
}

.capabilityCard--photo > *:not(.capabilityCard__background):not(.capabilityProfile) {
  position: relative;
  z-index: 1;
}

.capabilityCard--photo .capabilityCard__title {
  font-size: var(--font-28);
}

/* Scrim: #0c0c0c at top and bottom, lifting to 50% at ~82.7% down the card,
   so the title and button read against dark while the photo shows mid-card. */
.capabilityCard::before {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, #0c0c0c 0%, rgba(12, 12, 12, 0.5) 82.692%, #0c0c0c 100%);
  z-index: 0;
}

/* Block 3 Default (710:3961) → Hover (1264:2689). Two deltas, and the border is
   not one of them — Line Gradient 1 on both:
   1. the scrim's middle band clears completely. Default lifts to 50% alpha at
      82.692%; hover holds full transparency from 26.442% to 75.481%, so the
      photo reads at full strength across the middle of the card and the ramps
      compress into the top quarter and bottom quarter behind the title and
      button.
   2. padding-top 25 → 33. The bound variable is --sds-size-space-800 = 32, but
      this file sits consistently 1px above its own spacing tokens (25 over a
      24 token here, 48.5 over 48 and 17 over 16 on Button Set), so 33 is the
      real value and the delta is a round 8px. With the card height pinned at
      400 and justify-between, that pushes the title down 8px and leaves the
      button where it is.
   The photo asset differs between the two variants, but it is the same shot
   under different lighting — content noise, not a state change. The nested
   Button Set instance is byte-identical across both variants, so card hover
   deliberately does NOT drive .capabilityCard__button's own hover.
   As ever, the ::before gradient does not interpolate in Chrome or Safari — the
   scrim snaps while the padding animates. */
/* HOVER GROWTH DISABLED 2026-09-17, same pass as .missionVisionCard. This took
   padding-top from the base 25px to 33px, and the card is height: auto, so it
   grew 8px taller. The ::before scrim change below is untouched. To restore:
       .capabilityCard { transition: padding-top 0.2s ease; }
       .capabilityCard:hover { padding-top: clamp(16.5px, 2.18vw, 41.9px); }  */

.capabilityCard:hover::before {
  background: linear-gradient(
    180deg,
    #0c0c0c 0%,
    rgba(12, 12, 12, 0) 26.442%,
    rgba(12, 12, 12, 0) 75.481%,
    #0c0c0c 100%
  );
}

.capabilityCard > *:not(.capabilityCard__background):not(.capabilityProfile) {
  position: relative;
  z-index: 1;
}

.capabilityCard__title {
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-28);
  line-height: 1.2;
  color: var(--color-white);
}

/* Reuses .button (16/24 padding, 14px/1.2px label, brand border-image) and only
   swaps in the Button Gradient 3 fill: brand ramp faint at both ends (0.2) and
   fully opaque teal at the centre — the interior peak the MCP flattens away. */
.capabilityCard__button {
  background: linear-gradient(
    90deg,
    rgba(64, 211, 159, 0.2) 0%,
    rgba(56, 171, 193, 1) 50%,
    rgba(47, 132, 226, 0.2) 100%
  );
}

/* Below the desktop gutter breakpoint, drop the inset to 24 and let the copy
   run full width rather than staying pinned to half on a phone. */
@media (max-width: 900px) {
  .capability__intro {
    padding-inline: 0;
    width: calc(100% - (var(--gutter) * 2));
    margin-inline: auto;
  }
  .capability__copy {
    flex-basis: 100%;
  }
}

/* --------------------------------------------------------------------------
   Markets > the nine market bands  (Figma Frames 336-344, "Markets - ")
   --------------------------------------------------------------------------
   One repeating band, 1512 wide, height driven by copy (768-1079 in Figma).
   Each is a full-bleed photograph with two scrim layers over it, and a glass
   panel — the same treatment as .certifications — pinned to one side. The panel side
   alternates down the page: odd bands right, even bands left (.market--left).

   The photo rides on a .market__background div with a per-instance modifier
   class, so the section itself carries no photo and the scrim, panel and image
   are three separate layers. */
.market {
  position: relative;
  isolation: isolate;
  display: flex;
  align-items: center;
  padding: var(--space-9) var(--gutter);
  background-color: var(--color-black);
}

/* Dedicated photo layer, the house pattern (cf. .mentorBand__background).
   z-index -2 puts it under the block's own ::after scrim (-1) and under the
   in-flow panel; `isolation: isolate` on the block keeps both inside it. */
.market__background {
  position: absolute;
  inset: 0;
  z-index: -2;
  pointer-events: none;
  background-position: center;
  background-size: cover;
  background-repeat: no-repeat;
}

/* Two layers, exactly as Figma stacks them: a horizontal wash that darkens the
   panel side so the copy always has contrast, and a vertical one that lands the
   band on black top and bottom (transparent at 64.583%). z-index -1 puts them
   over the section's own background but under the panel. */
.market::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background:
    linear-gradient(to right, rgba(12, 12, 12, 0) 0%, var(--color-black) 100%),
    linear-gradient(
      to top,
      var(--color-black) 0%,
      rgba(12, 12, 12, 0) 64.583%,
      var(--color-black) 100%
    );
}

.market--left::after {
  background:
    linear-gradient(to left, rgba(12, 12, 12, 0) 0%, var(--color-black) 100%),
    linear-gradient(
      to top,
      var(--color-black) 0%,
      rgba(12, 12, 12, 0) 64.583%,
      var(--color-black) 100%
    );
}

/* Figma builds the offset with a transparent 500px filler beside the panel. The
   arithmetic (1384 of content, 64 gap, filler capped at 500) always resolves to
   an 820px panel, so it is set directly and the filler div is not reproduced. */
.market__panel {
  /* Figma 820 inside the band's 1384 content box (1512 - 2x64 gutter) = 59.25%.
     The percentage is of .market's content box, not the frame, because the band
     already carries --gutter padding. margin-left: auto keeps the panel right;
     .market--left flips it. */
  width: 59.25%;
  max-width: calc(var(--contentMax) * 0.5925);
  margin-left: auto;
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
  padding: var(--space-8) var(--space-8);
  background: rgba(12, 12, 12, 0.55);
  /* The stroke is the brand ramp, not flat #40d39f — the MCP flattens a gradient
     stroke to its stop-0, which is how the flat value got here. Same treatment
     already proven on the Low-Voltage page. Every other .market__panel sits on a
     Solutions page that overrides this with its own ramp, so this base rule is
     what the 12 market detail pages get. border-image ignores border-radius,
     which is safe here: the panel is square. */
  border: 1px solid transparent;
  border-image: var(--gradient-brand) 1;
  box-shadow: 0 0 30px 0 rgba(64, 211, 159, 0.5);
}

.market--left .market__panel {
  margin-left: 0;
  margin-right: auto;
}

.market__head {
  display: flex;
  flex-direction: column;
  gap: var(--clamp-rem-16);
}

.market__head .eyebrow {
  margin: 0;
}

.market__head h2 {
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-48);
  line-height: 1.2;
}

/* The 12 market detail pages only. Their .market__head h2 used to repeat the
   page h1; it now carries the paragraph's lead differentiator sentence, so it is
   a sentence-length line rather than a 2-3 word title and drops to 24. The
   panel gap tightens to match, the head and copy now reading as one statement. */
.market--marketDetail .market__head h2 {
  font-size: var(--font-24);
}

.market--marketDetail .market__panel {
  gap: var(--space-5);
}

.market__copy p {
  font-size: var(--font-16);
  letter-spacing: 0.1px;
  line-height: 1.4;
}

/* Figma separates the two paragraphs with a zero-width-space line rather than a
   gap, so the break is one line of leading: 16 x 1.4. */
.market__copy p + p {
  margin-top: var(--clamp-rem-24); /* Figma 22.4px -> nearest step */
}

/* Label + chip list, 24 apart, the label on a fixed 120px measure. */
.market__row {
  display: flex;
  align-items: flex-start;
  gap: var(--space-5);
}

.market__label {
  flex: 0 0 120px;
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-18);
  line-height: 1.2;
}

.market__chips {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-3);
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Underlined pill: brand ramp on the text, flat green on the rule. The arrow is
   an SVG so its stroke can take the same ramp via the #ramp-brand paint server —
   a CSS gradient cannot stroke a path. No background-color here: background-clip
   would crop it to the glyphs. */
.market__chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-4);
  padding-bottom: clamp(4.5px, 0.6vw, 11.5px); /* was 9px */
  border-bottom: 1px solid var(--color-brand-green);
  font-family: var(--font-body);
  font-weight: 500;
  font-size: var(--font-12);
  letter-spacing: 1.2px;
  text-transform: uppercase;
  text-decoration: none;
  background-image: var(--gradient-brand);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  transition: opacity 0.2s ease;
}

.market__chip:hover {
  opacity: 0.75;
}
.market__chip svg {
  width: 18px;
  height: 10px;
  flex-shrink: 0;
}

/* Below the panel's own width the offset stops meaning anything, so the panel
   goes full width and the horizontal wash is dropped — only the vertical scrim
   is left holding the copy against the photo. */
@media (max-width: 1000px) {
  .market__panel,
  .market--left .market__panel {
    width: 100%;
    margin-inline: 0;
  }

  .market::after,
  .market--left::after {
    background:
      linear-gradient(rgba(12, 12, 12, 0.45), rgba(12, 12, 12, 0.45)),
      linear-gradient(
        to top,
        var(--color-black) 0%,
        rgba(12, 12, 12, 0) 64.583%,
        var(--color-black) 100%
      );
  }
}

@media (max-width: 700px) {
  .market__panel {
    padding: var(--space-8) var(--space-6);
  }

  .market__row {
    flex-direction: column;
    gap: var(--space-3);
  }
  .market__label {
    flex-basis: auto;
  }
  .market__chip {
    white-space: normal;
  }
}

/* --------------------------------------------------------------------------
   Solutions > Low-Voltage EDS  (Figma page frame 1543:2861)
   --------------------------------------------------------------------------
   The page is almost entirely a recomposition of components that already exist:
   .hero--solutions, .solutionsStatement, .market, .solution--lowVoltage,
   .capability's card track, .faq and .siteFooter. Only three deltas needed
   rules of their own, and they are all below.

   Note for a later pass: the hero subtitle and the .solutionsStatement copy are
   the two body paragraphs of the .solution band further down the page, repeated
   verbatim. That is what the Figma frame does — the band is an unmodified
   instance of solutions.html's Frame 333 — not a copy/paste error here. */

/* Hero 1543:2862 — the .hero--solutions frame and both scrim layers unchanged,
   only the photograph differs, so this rides the base modifier's ::before. */
.hero--solutionsLowVoltage {
  background-image: url('../assets/images/solutions-hero-low-voltage.jpg');
}

/* Re-read 2026-08-25 off 1543:2862. Two deltas from the .hero--solutions base:
   the container 1543:2917 is 760 (the base inherits the homepage's 800), and the
   vertical arm of the scrim starts at 0.2 here, not 0. The horizontal arm is the
   same (opaque -> 0 at 59.615%). Read from the frame, not fitted. */
.hero--solutionsLowVoltage .hero__content {
  max-width: min(760px, 100%);
}

.hero--solutionsLowVoltage::before {
  background:
    linear-gradient(90deg, #0c0c0c 0%, rgba(12, 12, 12, 0) 59.615%),
    linear-gradient(180deg, rgba(12, 12, 12, 0.2) 0%, rgba(12, 12, 12, 0.5) 69.231%, #0c0c0c 100%);
}

/* Frame 326 (1546:3655) sits INSIDE the solution band rather than in a
   .capability section of its own, so the band supplies the surrounding rhythm:
   96 between the photo row and the card track, 96 trailing (Frame 334 is 1646
   tall = 64 + 428 + 96 + 466 + 96 + 400 + 96). .capability__cards already gives
   the 64px left inset and the horizontal scroll. */
.solution--lowVoltageDetail .solution__capabilities {
  margin-top: var(--space-9);
}

.solution--lowVoltageDetail {
  padding-bottom: var(--space-9);
}

/* Frame 349 (1546:3561) — the three-card variant of .moreSolutions. Frame 348 on
   the other four pages is a 2-up at `64px 160px` with a 32px gap; this row is a
   3-up at `32px 64px` with a 16px gap, and the slot height stays 650. Each card
   also drops the shared brand ramp for its own accent: the eyebrow takes the
   section ramp of the solution it links to, and the icon ring takes that ramp's
   FIRST stop as a flat colour rather than the ramp itself. */
.moreSolutions--trio {
  gap: var(--space-4);
  padding-block: var(--space-6);
  padding-inline: 0;
  width: 91.53%;
  max-width: calc(var(--contentMax) * 0.9153);
  margin-inline: auto;
}

/* Each slot carries its own card art, so every trio page gets the photo, wash
   and veil without repeating them (Control Boxes and High-Voltage were missing
   some before 2026-09-22). Page blocks further down may still override. */
.moreSolutions__slot--hv {
  --card-wash: #ff8800;
  --card-photo: url('../assets/images/solution-card-bg-high-voltage.jpg');
  --card-veil: 0.8;
  --card-accent: #ffde8e;
  --card-ramp: linear-gradient(90deg, #ffde8e 0%, #fba440 50%, #40d39f 100%);
}

.moreSolutions__slot--cb {
  --card-wash: #e828a8;
  --card-photo: url('../assets/images/solution-card-bg-control-boxes.jpg');
  --card-veil: 0.8;
  --card-accent: #fb4097;
  --card-ramp: var(--gradient-control-box);
}

.moreSolutions__slot--components {
  --card-wash: #0166b3;
  --card-photo: url('../assets/images/solution-card-bg-engineering-components.jpg');
  --card-veil: 0.8;
  --card-accent: #a8ecff;
  --card-ramp: var(--gradient-blue);
}

/* Overrides the .moreSolutions__cards rule that paints every slot's hover glow
   the shared yellow — here each card glows in its own accent. */
.moreSolutions--trio .missionVisionCards__slot {
  --mv-glow: var(--card-accent);
}

.moreSolutions--trio .moreSolutions__head .eyebrow {
  background-image: var(--card-ramp);
}

/* Three 650px cards in a 1384 content width leave ~427 each, so the eyebrow's
   authored line breaks are kept and the heading is allowed to wrap. */
.moreSolutions--trio .moreSolutions__head .eyebrow,
.moreSolutions--trio .missionVisionCard__text {
  text-wrap: pretty;
}

@media (max-width: 1200px) {
  .moreSolutions--trio {
    padding-inline: 0;
    width: calc(100% - (var(--gutter) * 2));
    margin-inline: auto;
  }
}

/* EC-01 (2026-09-23): 3 columns from 1000px, 1 column below. Card side padding
   runs 16px at 1000 to 48px at 1512 (same as before from 1512 up), and the
   nowrap CTA (~351px) may wrap so it fits the ~250px card at 1000. Scoped to
   1000-1511 so the design width and phones are untouched. */
@media (min-width: 1000px) and (max-width: 1511px) {
  .moreSolutions--trio .missionVisionCard {
    padding-inline: max(16px, calc(6.25vw - 46.5px));
  }
  .moreSolutions--trio .button {
    white-space: normal;
    text-align: center;
  }
}

/* SOL-02 (2026-09-24): from 1512 the nowrap "Learn About High-Voltage EDS" CTA
   (356px) is wider than the card's 331px content box, so its min-content
   widened the first card to 453 and shrank the gap after it to 13px. min-width: 0
   lets the three share the row equally; the centred CTA uses the side padding. */
@media (min-width: 1512px) {
  .moreSolutions--trio .missionVisionCards__slot,
  .moreSolutions--trio .missionVisionCard {
    min-width: 0;
  }
}

/* 701-999 two-up, same method as .marketGrid__slot: no grow, so the lone third
   card keeps its siblings' width and is centred rather than stretched. */
@media (max-width: 999px) {
  .moreSolutions--trio {
    flex-direction: row;
    flex-wrap: wrap;
    justify-content: center;
  }
  .moreSolutions--trio .missionVisionCards__slot {
    flex: 0 0 calc((100% - var(--space-4)) / 2);
  }
  .moreSolutions--trio .button {
    white-space: normal;
    text-align: center;
  }
}

@media (max-width: 700px) {
  .moreSolutions--trio {
    flex-direction: column;
    flex-wrap: nowrap;
    gap: var(--space-8); /* one column (Sam, 2026-09-24) */
  }
  .moreSolutions--trio .missionVisionCards__slot {
    flex: 0 0 auto;
  }
}

/* 901-999 repeats the trio's share of the max-width: 900px rules
   (.missionVisionCards, .moreSolutions__ring), so the stacked layout looks the
   same up to the 1000px switch. */
@media (min-width: 901px) and (max-width: 999px) {
  .moreSolutions--trio {
    align-items: stretch;
  }
  .moreSolutions--trio .missionVisionCards__slot {
    height: auto;
    padding: 0;
  }
  .moreSolutions--trio .missionVisionCard {
    padding: var(--space-7);
  }
  .moreSolutions--trio .moreSolutions__ring {
    width: 140px;
    height: 140px;
  }
  .moreSolutions--trio .moreSolutions__ringIcon {
    width: 36px;
    height: 36px;
  }
}

/* Low-Voltage EDS trio slot — shared by every page whose .moreSolutions--trio
   leads with Low-Voltage (Frame 349 on High-Voltage, Control Boxes, Components).
   Kept when the High-Voltage page block was deleted and rebuilt 2026-09-15. */
.moreSolutions__slot--lv {
  --card-wash: #40d39f;
  --card-photo: url('../assets/images/solution-card-bg-low-voltage.jpg');
  --card-veil: 0.9;
  --card-accent: #40d39f;
  --card-ramp: var(--gradient-brand);
}

/* --------------------------------------------------------------------------
   Solutions > Powering the World  (Figma page frame 1543:982)
   --------------------------------------------------------------------------
   The page frame was rebuilt on 2026-08-10: it is now 4897.5 tall, and the four
   full-width .solution bands solutions.html was built from are gone. In their
   place Frame 390 (1543:2588) puts the same four products into a 2x2 grid of
   Block 4 cards. Everything else on the page is an unmodified instance of a
   component that already exists here — .hero--solutions, .solutionsStatement,
   the two-card .moreSolutions, .faq and .siteFooter — so only Frame 390 needed
   rules, and they are all below.

   Frame 390 is 1751 tall = 48 top + 211 intro + 746 + 746, and each 746 row is
   the 650 slot plus 64/32 (first row) or 32/64 (second) of vertical padding. */
.productSolutions {
  padding-top: var(--space-7);
  background: var(--color-black);
}

/* .missionVisionCards' own `0 160px 96px` is replaced per row: Figma splits the
   96 that sits between the rows into 32 below the first and 32 above the second. */
.productSolutions__row {
  padding-inline: 0;
  width: 78.84%;
  max-width: calc(var(--contentMax) * 0.7884);
  margin-inline: auto;
}
.productSolutions__row--first {
  padding-block: var(--space-8) var(--space-6);
}
.productSolutions__row--second {
  padding-block: var(--space-6) var(--space-8);
}

/* Each card takes the accent of the solution it links to. Same two-variable
   pattern as .moreSolutions--trio: the eyebrow gets the full ramp, and the icon
   ring gets that ramp's FIRST stop as a flat colour rather than the ramp.
   --card-wash is the soft-light layer, which is a different colour again — it is
   the Figma *variable* for the product (Low Volt / High Volt / Control Box /
   Engineered) where --card-accent is the ramp's opening stop. */
.productSolutions__slot--lv {
  --card-accent: #40d39f;
  --card-ramp: var(--gradient-brand);
  --card-wash: #40d39f;
  --card-photo: url('../assets/images/solution-card-bg-low-voltage.jpg');
  /* the only card whose photo sits at 10% rather than 20% */
  --card-veil: 0.9;
}

.productSolutions__slot--hv {
  --card-accent: #ffde8e;
  --card-ramp: var(--gradient-orange);
  --card-wash: #ff8800;
  --card-photo: url('../assets/images/solution-card-bg-high-voltage.jpg');
  --card-veil: 0.8;
}

.productSolutions__slot--cb {
  --card-accent: #fb4097;
  --card-ramp: var(--gradient-control-box);
  --card-wash: #e828a8;
  --card-photo: url('../assets/images/solution-card-bg-control-boxes.jpg');
  --card-veil: 0.8;
}

.productSolutions__slot--components {
  --card-accent: #a8ecff;
  --card-ramp: var(--gradient-blue);
  --card-wash: #0166b3;
  --card-photo: url('../assets/images/solution-card-bg-engineering-components.jpg');
  --card-veil: 0.8;
}

/* Four stacked layers, listed here top-first as CSS requires. Reading them
   bottom-up in Figma's order:
     photo            — normal, at 10%/20% opacity
     black veil       — DERIVED. Figma puts the opacity on the image node, which a
                        background layer cannot carry, so the photo is painted
                        opaque and a #0c0c0c layer at 1 - opacity is laid over it.
                        Compositing is identical: 0.9 black over the photo equals
                        the photo at 0.1 over black.
     --card-wash      — solid accent, mix-blend-mode soft-light. Not isolated in
                        Figma either, so it is allowed to blend against the card's
                        own black as well as the photo — hence background-blend-mode
                        on the same element rather than a pseudo with isolation.
     vignette         — normal, on top of everything.
   The vignette is the one paint neither read tool returns as CSS: get_design_context
   emits it as an inline SVG radialGradient with gradientUnits="userSpaceOnUse",
   r=10 and a matrix scaling it 31.3x inside a 626 viewBox, i.e. a circle of radius
   313 centred in the box, stretched by preserveAspectRatio="none" to the card's
   real aspect. `ellipse closest-side` is that exact geometry. Stops are
   rgba(12,12,12,0) 30% -> rgba(13,13,13,0.5) 60% -> rgb(13,13,13) 100% — note the
   inner stop is 12,12,12 and the outer two are 13,13,13 in the file. */
.productSolutions__card {
  background-color: var(--color-black);
  background-image:
    radial-gradient(
      ellipse closest-side at 50% 50%,
      rgba(12, 12, 12, 0) 30%,
      rgba(13, 13, 13, 0.5) 60%,
      rgb(13, 13, 13) 100%
    ),
    linear-gradient(var(--card-wash), var(--card-wash)),
    linear-gradient(rgba(12, 12, 12, var(--card-veil)), rgba(12, 12, 12, var(--card-veil))),
    var(--card-photo);
  background-size:
    100% 100%,
    100% 100%,
    100% 100%,
    cover;
  background-position: center;
  background-repeat: no-repeat;
  /* border-box (2026-09-24): with the default padding-box the layers stopped
     1px short of the edge, so when hover made the border transparent the
     un-vignetted photo showed through as bright lines along the sides. */
  background-origin: border-box;
  background-blend-mode: normal, soft-light, normal, normal;
}

/* The High-Voltage photo is the one instance override: Figma scales it to 178.43%
   of the card width at full height and pulls it left by 18.84% of the card width,
   instead of object-fit: cover. A background-position percentage resolves against
   (container - image), which is -0.7843W here, so the left edge lands at -0.1884W
   when the position is 0.1884 / 0.7843 = 24.02%. */
.productSolutions__slot--hv .productSolutions__card {
  background-size:
    100% 100%,
    100% 100%,
    100% 100%,
    178.43% 100%;
  background-position:
    center,
    center,
    center,
    24.02% 0;
}

/* The trio cards (.moreSolutions--trio) are narrower than the grid card, so the
   fixed 178.43% size above would stretch the photo there. They keep `cover` and
   only move the focal point to the same spot: the grid crop is centred on the
   point 38.6% across the photo (2912x1632). With cover, keeping that point
   mid-card takes 28.3% at 542x640, 31.5% at 427x626 and 32.8% at 360x600 —
   30% sits inside that range at every width the trio renders. */
.moreSolutions__slot--hv .productSolutions__card {
  background-position:
    center,
    center,
    center,
    30% center;
}

/* Same three per-card deltas as .moreSolutions--trio. Figma gives no hover variant
   for these four instances, so the glow follows the trio's rule and takes each
   card's own accent rather than the shared yellow. */
.productSolutions__row .missionVisionCards__slot {
  --mv-glow: var(--card-accent);
}

.productSolutions__card .moreSolutions__head .eyebrow {
  background-image: var(--card-ramp);
}

/* Every eyebrow here runs to two lines, which the shared 15px eyebrow box would
   collide. Figma sets 1.4 on the Low- and High-Voltage cards and leaves the other
   two on the 15px box; 1.4 is taken as the intent for all four. */
.productSolutions__card .moreSolutions__head .eyebrow {
  line-height: 1.4;
}

.productSolutions__card .moreSolutions__head .eyebrow,
.productSolutions__card .missionVisionCard__text {
  text-wrap: pretty;
}

/* SOL-01 2026-09-24: the nowrap CTA set a ~414px card minimum, pushing the page
   sideways from 901 to 969. Let the label wrap only when it has to. */
.productSolutions__card .button {
  white-space: normal;
  text-align: center;
}

/* The four button labels are nowrap in Figma, and "Learn About Engineering
   Components" is the longest at 429 + 96 of padding = 525 min-content. The slot is
   `flex: 1 0 0` and so cannot shrink under that, which means a 160px gutter starts
   forcing the four cards to UNEVEN widths below about 1434px. Verified in Chrome:
   at 1512 all four are exactly 580/556, at 1318 they split 483/459/468/527. The
   gutter therefore has to relax at 1440, not at the 1200 the other card rows use. */
@media (max-width: 1440px) {
  .productSolutions__row {
    padding-inline: 0;
    width: calc(100% - (var(--gutter) * 2));
    margin-inline: auto;
  }
}

@media (max-width: 900px) {
  .productSolutions__row {
    flex-direction: column;
  }
  .productSolutions__row .missionVisionCards__slot {
    height: auto;
    min-height: 650px;
  }
}

/* --------------------------------------------------------------------------
   Markets grid — Markets - Electrification, Frame 390 (1559:6009)
   Replaced the nine full-bleed .market bands on 2026-08-10. Blocks 8/13/14/15
   are one component, so one card rule serves all nine.
   -------------------------------------------------------------------------- */
.marketGrid {
  padding-top: var(--space-7);
  background: var(--color-black);
}

/* Same intro rhythm as .moreSolutions__intro (1559:6010): eyebrow →16→ heading,
   both centred on a 900px measure, .eyebrow's own margin carrying the gap. */
.marketGrid__intro {
  padding-block: var(--space-6);
  padding-inline: 0;
  width: 91.53%;
  max-width: calc(var(--contentMax) * 0.9153);
  margin-inline: auto;
}

.marketGrid__intro .eyebrow {
  text-align: center;
}

/* Frame 349 opens on 64px and Frames 350/352 on 32, so the row rhythm is 32 top
   and bottom and only the first row takes the extra 32. */
.marketGrid__row {
  display: flex;
  justify-content: center;
  align-items: flex-start;
  gap: var(--space-4);
  padding-block: var(--space-6);
  padding-inline: 0;
  width: 91.53%;
  max-width: calc(var(--contentMax) * 0.9153);
  margin-inline: auto;
}

.marketGrid__intro + .marketGrid__row {
  padding-top: var(--space-8);
}

/* Figma's 12px-padded instance wrapper, exactly as .missionVisionCards__slot. */
.marketGrid__slot {
  flex: 1 0 0;
  min-width: 0;
  height: auto;
  min-height: 650px;
  padding: var(--space-3) var(--space-3);
  display: flex;
}

.marketCard {
  flex: 1;
  /* Without this the card's min-content width is its widest nowrap title plus
     85.5px of padding, and the one card whose title overflows would widen past
     its slot instead of letting the title overflow. */
  min-width: 0;
  position: relative;
  isolation: isolate;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-7);
  padding: var(--space-8) clamp(21.375px, 2.83vw, 54.3px); /* was 64px, now 42.75px */
  text-align: center;
  background-color: var(--color-black);
  /* #818181 is Line Gradient 1 flattened to its first stop by the MCP, as on
     every other bordered card in this file. */
  border: 1px solid var(--color-border-mid);
  border-image: var(--gradient-line-1) 1;
}

/* Dedicated photo layer, the house pattern (cf. .mentorBand__background).
   z-index -2 puts it under the block's own ::after scrim (-1) and under the
   in-flow panel; `isolation: isolate` on the block keeps both inside it. */
.marketCard__background {
  position: absolute;
  inset: 0;
  z-index: -2;
  pointer-events: none;
  background-position: center;
  background-size: cover;
  background-repeat: no-repeat;
}

/* Single vertical scrim, transparent-ish only at 29.808% — darker and higher
   than the .market band's 64.583%, because the title sits at the foot. */
.marketCard::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background: linear-gradient(
    to bottom,
    var(--color-black) 0%,
    rgba(12, 12, 12, 0.4) 29.808%,
    var(--color-black) 100%
  );
}

/* 32px Golos Regular, not the 500 of .sectionHeading. */
.marketCard__title {
  width: 100%;
  margin: 0;
  font-family: var(--font-heading);
  font-weight: 400;
  font-size: var(--font-32);
  line-height: 1.2;
}

/* Figma's card button is one nowrap line reading "Learn About Low-Voltage EDS"
   on all nine cards — a placeholder. The market name is already the title
   directly above, so the CTA is "Learn More" with the market on aria-label:
   naming each market in the visible label needs up to 563px inside a 285px
   content box, which is what tore the grid open. .button is `max-width:
   max-content` and nowrap, so cap it here as well — a longer label wraps rather
   than widening the card past its slot. */
.marketCard__cta {
  max-width: 100%;
  white-space: normal;
}

/* MKT-01 (2026-09-23): 520px floor under 1400. */
@media (max-width: 1399px) {
  .marketGrid__slot {
    min-height: 520px;
  }
}

/* Two-up with no grow, so a lone last card keeps the same width as the others
   (centred by the row's justify-content) instead of stretching full width.
   Was flex: 1 1 320px. */
@media (max-width: 1000px) {
  .marketGrid__row {
    flex-wrap: wrap;
  }
  .marketGrid__slot {
    flex: 0 0 calc((100% - var(--space-4)) / 2);
  }
}

@media (max-width: 700px) {
  .marketGrid__slot {
    flex: 0 0 100%;
  }
  .marketCard {
    padding: var(--space-7) var(--space-6);
  }
}

/* --------------------------------------------------------------------------
   Market detail pages — the nine Markets - <name> frames (1566:6694 and
   siblings). One template: hero -> statement -> .market band -> related
   material -> .moreSolutions -> footer. Everything above is reused; the
   related-material block below is the only new component.
   Frame 391 (intro) and Frame 278 (the groups) are built as one section: Figma
   splits them only because the intro sits in its own auto-layout frame.
   -------------------------------------------------------------------------- */
.relatedMaterial {
  padding-block: var(--space-9) clamp(60px, 7.94vw, 152.4px); /* was 120px */
  padding-inline: 0;
  width: 91.53%;
  max-width: calc(var(--contentMax) * 0.9153);
  margin-inline: auto;
  background: var(--color-black);
}

/* 32 above and below the 900px intro block, then 96 before the first group. */
.relatedMaterial__intro {
  padding: var(--space-6) 0;
}
.relatedMaterial__intro .eyebrow {
  text-align: center;
}

.relatedMaterial__groups {
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
  margin: var(--space-9) auto 0;
}

.relatedMaterial__group {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}

/* 32px Golos Regular, left-aligned — the row label, not a section heading. */
.relatedMaterial__label {
  margin: 0;
  font-family: var(--font-heading);
  font-weight: 400;
  font-size: var(--font-32);
  line-height: 1.2;
}

.relatedMaterial__row {
  display: flex;
  align-items: stretch;
  gap: var(--space-5);
}

/* A group with two tile rows stacks them on the same 24px gap (1574:9586). */
.relatedMaterial__rows {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}

/* 360px photo tile. One tile fills the row; two share it. The panel is pinned
   bottom-left, so the wash darkens the left edge — the mirror of .market, which
   darkens the panel side. */
.relatedTile {
  flex: 1 0 0;
  min-width: 0;
  position: relative;
  isolation: isolate;
  height: auto;
  min-height: 360px;
  display: flex;
  align-items: flex-end;
  padding: var(--space-5) var(--space-5);
  background-color: var(--color-black);
}

/* Dedicated photo layer, the house pattern (cf. .mentorBand__background).
   z-index -2 puts it under the block's own ::after scrim (-1) and under the
   in-flow panel; `isolation: isolate` on the block keeps both inside it. */
.relatedTile__background {
  position: absolute;
  inset: 0;
  z-index: -2;
  pointer-events: none;
  background-position: center;
  background-size: cover;
  background-repeat: no-repeat;
}

/* Two tiles in the file carry rgba(22,22,22,...) instead of rgba(12,12,12,...)
   for this wash (1573:7483, 1569:7437) — a stray in the file, normalised to the
   #0c0c0c every other tile uses. */
.relatedTile::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background: linear-gradient(to left, rgba(12, 12, 12, 0) 0%, rgba(12, 12, 12, 0.8) 100%);
}

.relatedTile__panel {
  width: 410px;
  max-width: 100%;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: flex-end;
  gap: var(--space-7);
  padding: var(--space-5) var(--space-5);
  background: rgba(12, 12, 12, 0.65);
}

/* More inner padding on mobile (Sam, 2026-09-24). */
@media (max-width: 900px) {
  .relatedTile__panel {
    padding: var(--space-7) var(--space-7);
  }
}

/* Figma sets Title case on this node. The copy is already title-cased, so the
   only visible effect is on the small words inside the success-story titles
   ("a" -> "A", "to" -> "To") — matched rather than corrected. */
.relatedTile__title {
  margin: 0;
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-32);
  line-height: 1.4;
  text-transform: capitalize;
}

/* Same underlined-pill recipe as .market__chip — brand ramp clipped to the
   glyphs, flat green rule, arrow stroked through the #ramp-brand paint server —
   at the 16px this component uses instead of 12px. */
/* Tile and market-card titles link to the same page as their CTA (Sam,
   2026-09-24), with no underline. */
.relatedTile__titleLink,
.marketCard__titleLink,
.missionVisionCard__textLink {
  color: inherit;
  text-decoration: none;
}

.relatedTile__cta {
  display: inline-flex;
  align-items: center;
  gap: var(--space-4);
  padding-bottom: clamp(4.5px, 0.6vw, 11.5px); /* was 9px */
  /* Same Button Set stroke as .linkCallToAction: the brand ramp across the whole
     row, not the flat #40D39F the MCP reports (that is only the ramp's stop 0). */
  border-bottom: 1px solid transparent;
  border-image: var(--gradient-brand) 1;
  font-family: var(--font-body);
  font-weight: 500;
  font-size: var(--font-16);
  letter-spacing: 1.2px;
  text-transform: uppercase;
  text-decoration: none;
  background-image: var(--gradient-brand);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  transition: opacity 0.2s ease;
}

/* Mobile gap raised from --space-4 (Sam, 2026-09-24). */
@media (max-width: 900px) {
  .relatedTile__cta {
    gap: var(--space-8);
  }
}

.relatedTile__cta:hover {
  opacity: 0.75;
}
.relatedTile__cta svg {
  width: 18px;
  height: 10px;
  flex-shrink: 0;
}

/* The market band on these pages is the .market component with no eyebrow and
   no chip rows — heading plus two paragraphs, exactly as the four Solutions
   product pages use it. Only the statement measure differs from the pages that
   came before: Frame 247 is 960 wide here, not 900. */
.solutionsStatement--detailPages p {
  /* Polish 2026-09-24: 960 / 1384 = 69.36% (was max-width: 960px). Below 1200
     it shares the standard statement's steps. */
  width: 69.36%;
}

@media (max-width: 1399px) {
  .solutionsStatement--detailPages p {
    width: 74%;
  }
}

@media (max-width: 1199px) {
  .solutionsStatement--detailPages p {
    width: 80%;
  }
}

@media (max-width: 900px) {
  .solutionsStatement--detailPages p {
    width: 86%;
  }
}

@media (max-width: 600px) {
  .solutionsStatement--detailPages p {
    width: 100%;
  }
}

@media (max-width: 1000px) {
  .relatedMaterial__row {
    flex-wrap: wrap;
  }
  .relatedTile {
    flex: 1 1 420px;
  }
}

@media (max-width: 700px) {
  .relatedMaterial {
    padding-bottom: var(--space-9);
  }
  .relatedTile {
    height: auto;
    min-height: 320px;
    padding: var(--space-4) var(--space-4);
  }
  .relatedTile__panel {
    width: 100%;
    gap: var(--space-6);
  }
}

/* --------------------------------------------------------------------------
   Megatrends landing page — Figma "Markets - Megatrends" (1574:12044)
   Reuses .marketGrid and .marketCard from markets-electrification-and-industrial.html. Three
   deltas: the hero is taller, the cards run two-up with a gradient eyebrow, and
   the grid intro carries a lede.
   -------------------------------------------------------------------------- */
/* The only 680px hero in the file; every other one is 634. */
.hero--megatrends {
  min-height: 680px;
}

/* 900px lede under the intro heading, 32 below it (1574:12111). */
.marketGrid__lede {
  max-width: 900px;
  margin: var(--clamp-rem-32) auto 0;
  font-size: var(--font-16);
  line-height: 1.4;
  letter-spacing: 0.1px;
  text-align: center;
}

/* Frame 349 opens on 64 and Frame 350 on 0, so the two rows sit 32 apart rather
   than the 64 the three-up markets grid uses. */
.marketGrid--megatrends .marketGrid__row + .marketGrid__row {
  padding-top: 0;
}

/* Block 13/15/16 are the same card as Block 8 with an eyebrow added above the
   title on a 12px gap; the 48 to the button is unchanged, so the pair becomes
   its own group inside the card. */
.marketCard__head {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--clamp-rem-12);
  width: 100%;
}

.marketCard__eyebrow {
  margin: 0;
  font-size: var(--font-14);
  letter-spacing: 1.2px;
  background-image: var(--gradient-brand);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

@media (max-width: 700px) {
  .marketGrid--megatrends .marketGrid__row + .marketGrid__row {
    padding-top: var(--space-6);
  }
}

/* --------------------------------------------------------------------------
   Megatrend detail pages — Markets - AI / Electrification 2 / Automation /
   Connected Systems (1576:12619 and siblings). One repeated two-column band
   answering six fixed questions, then the .marketCard grid three-up.
   -------------------------------------------------------------------------- */
/* The hero drops its subtitle paragraph for a gradient kicker naming the
   megatrend. Same 634px frame and scrim as every other markets hero. */
.hero__kicker {
  margin: 0;
  font-family: var(--font-body);
  font-weight: 500;
  font-size: var(--font-16);
  line-height: 1.15; /* was 1; Figma 16px on 16px */
  letter-spacing: 1.2px;
  text-transform: uppercase;
  background-image: var(--gradient-brand);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

/* Doc copy with no Figma layer: the megatrend closing line now rides in the hero
   under the kicker, so the kicker needs the text-to-text gap it never had. */
.hero--megatrend .hero__kicker:has(+ .hero__subtitle) {
  margin-bottom: var(--clamp-rem-16);
}

.qaBands {
  background: var(--color-black);
}

/* Frame 262 sits 48 inside each band frame, 64 in from the page edge, with a 32
   gutter between the columns. The left column is capped at 360 and the right
   takes the remaining 992. */
.qaBand {
  display: flex;
  align-items: flex-start;
  gap: var(--space-6);
  padding-inline: 0;
  width: 91.53%;
  max-width: calc(var(--contentMax) * 0.9153);
  margin-inline: auto;
  padding-block: clamp(24px, 3.17vw, 60.9px); /* was 48px */
}

.qaBand__label {
  flex: 1 0 0;
  min-width: 0;
  max-width: 360px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-7);
}

.qaBand__question {
  margin: 0;
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-28);
  line-height: 1.2;
}

.qaBand__body {
  flex: 1 0 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
}

/* Figma's "Block 1" — the same 40.5/48.5 Line-Gradient-1 box as .benefit, minus
   the check glyph, with 16px body copy instead of the 24px label. Kept separate
   from .benefit because that component owns a hover wash and a padding shift
   that belong to the solutions benefit rows, not to a static block of text. */
.qaBlock {
  padding-block: clamp(20.25px, 2.68vw, 51.5px); /* was 40.5px */
  padding-inline: clamp(24.25px, 3.21vw, 61.6px); /* was 48.5px */
  border: 1px solid transparent;
  border-image: var(--gradient-line-1) 1;
}

.qaBlock p {
  margin: 0;
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-16);
  line-height: 1.4;
  color: var(--color-white);
}

@media (max-width: 900px) {
  .qaBand {
    flex-direction: column;
    gap: var(--space-5);
    padding-block: var(--space-6);
  }
  .qaBand__label {
    max-width: 100%;
  }
  .qaBlock {
    padding: var(--space-6) var(--space-6);
  }
}

/* --------------------------------------------------------------------------
   Resources section — Main / Success Stories / Robotics story / FAQ /
   Newsroom / Article (1590:21497 and siblings).
   -------------------------------------------------------------------------- */
/* Resources heroes (1590:21498 / 1590:26546 / 1590:28399 / 1590:27441 / 1590:27788).
   Each frame carries its own photograph; pulled 2026-09-14. Success Stories and
   Newsroom are 540 tall rather than 634 and carry no subtitle. */
.hero--resources {
  background-image: url('../assets/images/resources-hero.jpg');
}

/* Shares resources-hero-faq.jpg with the legal family — Sam's call 2026-09-21,
   replacing the watermarked Success Stories placeholder. */
.hero--resourcesSuccess {
  background-image: url('../assets/images/resources-hero-faq.jpg');
}

/* The nine success-story heroes share .hero--resourcesStory for frame and scrim
   and take their photograph from a page modifier. Photos from
   3) Website Imagery/Final/6-SUCCESS STORIES (SS-01..09), added 2026-09-22. */
.hero--successStoryRecreationalVehicles {
  background-image: url('../assets/images/success-story-recreational-vehicles-hero.jpg');
}

.hero--successStoryHvacGovernmentContract {
  background-image: url('../assets/images/success-story-hvac-government-contract-hero.jpg');
}

.hero--successStoryApplianceZeroDefect {
  background-image: url('../assets/images/success-story-appliance-zero-defect-hero.jpg');
}

.hero--successStoryHvac72Hour {
  background-image: url('../assets/images/success-story-hvac-72-hour-restoration-hero.jpg');
}

.hero--successStorySemiconductorTimeToMarket {
  background-image: url('../assets/images/success-story-semiconductor-time-to-market-hero.jpg');
}

.hero--successStoryDataCentersCooling {
  background-image: url('../assets/images/success-story-data-centers-cooling-hero.jpg');
}

.hero--successStoryRobotics {
  background-image: url('../assets/images/success-story-robotics-hero.jpg');
}

.hero--successStoryDataCentersFirstToMarket {
  background-image: url('../assets/images/success-story-data-centers-first-to-market-hero.jpg');
}

.hero--successStoryCommercialLed {
  background-image: url('../assets/images/success-story-commercial-led-hero.jpg');
}

.hero--resourcesFaq {
  background-image: url('../assets/images/resources-hero-faq.jpg');
}

.hero--resourcesNewsroom {
  background-image: url('../assets/images/resources-hero-newsroom.jpg');
}

.hero--resourcesSuccess,
.hero--resourcesNewsroom {
  min-height: fit-content;
  height: 60svh; /* was min-height: 540px, the Figma frame on a 900px viewport */
}

.resourcesIntro {
  padding-block: 0;
  padding-inline: 0;
  width: 91.53%;
  max-width: calc(var(--contentMax) * 0.9153);
  margin-inline: auto;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-7);
  background: var(--color-black);
}

/* Figma 1590:22301 — eyebrow and heading are one group on a 16px gap, then 48
   to the button. Frame 281 is 245 tall with no padding of its own. */
.resourcesIntro__head {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  width: 100%;
}

/* Figma 1590:22303 — the heading runs the full 1384 column and sits left, so it
   drops the shared .sectionHeading centring and its 900px measure. */
.resourcesIntro .sectionHeading {
  text-align: left;
  max-width: 100%;
  margin-inline: 0;
}

/* ---- success-story tiles: .relatedTile with a body paragraph and the panel
   pinned top-and-bottom instead of bottom-aligned. */
.storyRows {
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
  padding-block: var(--space-8) clamp(60px, 7.94vw, 152.4px); /* was 120px */
  padding-inline: 0;
  width: 91.53%;
  max-width: calc(var(--contentMax) * 0.9153);
  margin-inline: auto;
  background: var(--color-black);
}

.storyRows__row {
  display: flex;
  align-items: center;
  gap: var(--space-5);
}

.relatedTile--story .relatedTile__panel {
  width: 306px;
  align-self: stretch; /* was height: 100% — the tile no longer has a definite height */
  justify-content: space-between;
  gap: var(--space-5);
}

.relatedTile--story.relatedTile--wide .relatedTile__panel {
  width: 410px;
}

.relatedTile__head {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--clamp-rem-24);
  width: 100%;
}

.relatedTile__body {
  margin: 0;
  font-family: var(--font-body);
  font-size: var(--font-16);
  line-height: 1.4;
  letter-spacing: 0.1px;
}

/* ---- FAQ page: a 333px label beside a list of hairline-separated rows. */
.faqGroups {
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
  padding-block: var(--space-8) clamp(60px, 7.94vw, 152.4px); /* was 120px */
  padding-inline: 0;
  width: 91.53%;
  max-width: calc(var(--contentMax) * 0.9153);
  margin-inline: auto;
  background: var(--color-black);
}

.faqGroup {
  display: flex;
  align-items: center;
  gap: var(--space-9);
}

.faqGroup__label {
  flex: 0 0 333px;
  margin: 0;
  padding-block: var(--space-5);
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-28);
  line-height: 1.2;
}

.faqGroup__list {
  flex: 1;
  min-width: 0;
}

.faqRow {
  border-bottom: 1px solid rgba(255, 255, 255, 0.3);
}
.faqGroup__list .faqRow:last-child {
  border-bottom: 0;
}

.faqRow__question {
  width: 100%;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-4);
  padding: clamp(12px, 1.59vw, 30.5px) 0 clamp(12.5px, 1.65vw, 31.7px); /* was 24px, 25px */
  background: none;
  border: 0;
  cursor: pointer;
  text-align: left;
  font-family: var(--font-body);
  font-size: var(--font-16);
  color: var(--color-white);
}

.faqRow__question svg {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
  margin-top: clamp(1px, 0.13vw, 2.5px); /* was 2px */
  transition: transform 0.2s ease;
}
.faqRow__answer {
  display: none;
  padding-bottom: clamp(12px, 1.59vw, 30.5px); /* was 24px */
  font-size: var(--font-16);
  line-height: 1.4;
}
.faqRow.isOpen .faqRow__answer {
  display: block;
}
.faqRow.isOpen .faqRow__question svg {
  transform: rotate(180deg);
}

/* ---- newsroom -------------------------------------------------------------- */
section.newsroom {
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
  padding-block: var(--space-8) clamp(60px, 7.94vw, 152.4px); /* was 120px */
  padding-inline: 0;
  width: 91.53%;
  max-width: calc(var(--contentMax) * 0.9153);
  margin-inline: auto;
  background: var(--color-black);
}

.newsFilters {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-6);
}
.newsFilters__tabs {
  display: flex;
  align-items: center;
  gap: var(--space-6);
}
/* PARKED 2026-09-21. The "Sort by: Newest" control was removed from the markup
   "for now" — it had no sorting behind it. These rules are kept so putting the
   block back is a markup-only change; delete them if the control is dropped for
   good. With the sort gone .newsFilters has a single child, so its
   space-between simply left-aligns the tabs. */
.newsFilters__sort {
  display: flex;
  align-items: center;
  gap: var(--space-5);
}
.newsFilters__sort p {
  margin: 0;
  font-size: var(--font-14);
  font-weight: 500;
}

.newsFilters__tab {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding-block: clamp(6px, 0.79vw, 15.2px); /* was 12px */
  padding-inline: var(--space-6); /* was 32px */
  border: 1px solid #ebebeb;
  background: transparent;
  cursor: pointer;
  font-family: var(--font-body);
  font-weight: 500;
  font-size: var(--font-12);
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--color-white);
}

.newsFilters__tab--active {
  background: var(--gradient-button);
}
.newsFilters__tab svg {
  width: 16px;
  height: 16px;
}

.articleGrid {
  display: flex;
  align-items: flex-start;
  gap: var(--space-8);
}

.articleCard {
  /* Always one third of the row (rows hold three), so a short last row — e.g.
     one card on the final Newsroom page — keeps grid-sized cards instead of
     stretching to fill the width. */
  flex: 0 0 calc((100% - 2 * var(--space-8)) / 3);
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
}

/* The tag is a glass pill pinned inside the 12px inset of the image. */
.articleCard__media {
  /* 16:9 by request (2026-09-22) — deliberately strays from Figma's 232px band. */
  height: auto;
  aspect-ratio: 16 / 9;
  display: flex;
  align-items: flex-start;
  padding: var(--space-3) var(--space-3);
  position: relative;
  isolation: isolate;
  background-color: var(--color-black);
}

/* Photo layer for the card's 16:9 media band. No scrim sits between it and the
   card, so -1 is enough to clear the in-flow tag pill. */
.articleCard__mediaBackground {
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background-position: center;
  background-size: cover;
}

.articleCard__tag {
  margin: auto 0 0 0;
  padding-block: clamp(2.5px, 0.33vw, 6.3px); /* was 5px */
  padding-inline: clamp(6.5px, 0.86vw, 16.5px); /* was 13px */
  border: 1px solid var(--color-brand-green);
  box-shadow: 0 0 8px var(--color-brand-green);
  background: linear-gradient(180deg, rgba(14, 52, 61, 0.8) 9.135%, rgba(12, 12, 12, 0.8) 91.827%);
  font-family: var(--font-body);
  font-weight: 500;
  font-size: var(--font-12);
  line-height: 1.333; /* Figma 16px on 12px */
  letter-spacing: 1.2px;
  text-transform: uppercase;
}

.articleCard__title {
  margin: 0;
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-20);
  line-height: 1.15; /* was 1; Figma 20px on 20px */
}

.articleCard__excerpt {
  margin: 0;
  font-size: var(--font-16);
  line-height: 1.219; /* Figma 19.5px on 16px */
}
.articleCard__cta {
  font-size: var(--font-14);
  align-self: flex-start;
}

.pager {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-6);
}
.pager__pages {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.pager__page,
.pager__step {
  min-width: 40px;
  padding-block: clamp(4px, 0.53vw, 10.2px); /* was 8px */
  padding-inline: var(--space-3); /* was 12px */
  text-align: center;
  text-decoration: none;
  font-size: var(--font-14);
  color: var(--color-white);
}

/* NEWS-03 (2026-09-23): 8 controls at a 40px floor need ~348px, wider than a
   phone's ~312px column. Wrapping would strand the arrow on its own line, so on
   phones the row takes the column width and every control shares it equally.
   Only up to 430: from ~400 the natural 40px row already fits. */
@media (max-width: 430px) {
  .pager__pages {
    width: 100%;
  }
  .pager__page,
  .pager__step {
    flex: 1 1 0;
    min-width: 0;
    padding-inline: 0;
  }
}

.pager__page--current {
  border-bottom: 1px solid var(--color-brand-green);
}
/* The windowed pager's skipped run (wp-theme newsroom-loop.php). Same box as a
   page link so the row keeps its rhythm, but not interactive. */
.pager__gap {
  min-width: 40px;
  text-align: center;
  font-size: var(--font-14);
  color: var(--color-border-mid);
}
@media (max-width: 430px) {
  .pager__gap {
    flex: 1 1 0;
    min-width: 0;
  }
}
.pager__step--disabled {
  opacity: 0.4;
  pointer-events: none;
}
.pager__count {
  margin: 0;
  font-size: var(--font-16);
  line-height: 1.4;
  letter-spacing: 0.1px;
  color: var(--color-border-mid);
}

/* ---- article --------------------------------------------------------------- */
.hero--articleHead {
  min-height: 0;
  background: var(--color-black);
}
.hero--articleHead::before {
  content: none;
}

.articleHead {
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
  /* 64px of black above the banner — Figma puts the banner at y=130 under a 66px nav. */
  padding-block: var(--space-8) var(--space-8);
  padding-inline: 0;
  width: 91.53%;
  max-width: calc(var(--contentMax) * 0.9153);
  margin-inline: auto;
  background: var(--color-black);
}

.articleHead__banner {
  display: block;
  width: 100%;
  /* The image's own proportions (2026-09-22), not Figma's 1536 / 493 crop. The
     width/height attributes on the <img> reserve the space before it loads. */
  height: auto;
}
.articleHead__inner {
  max-width: 800px;
  display: flex;
  flex-direction: column;
  gap: var(--clamp-rem-48);
}

/* The breadcrumb reuses the .hero__pill treatment — the same Title component. */
.articleHead__crumb {
  margin: 0;
  align-self: flex-start;
  display: inline-flex;
  gap: var(--space-5);
  padding-block: clamp(4.5px, 0.6vw, 11.5px); /* was 9px */ /* 9 + 16 + 9 = the 34px Title frame */
  padding-inline: var(--space-7); /* was 48px */
  background: linear-gradient(
    90deg,
    rgba(64, 211, 159, 0) 0%,
    rgba(56, 171, 193, 0.48) 50%,
    rgba(47, 132, 226, 0) 100%
  );
  font-family: var(--font-body);
  font-weight: 500;
  font-size: var(--font-14);
  line-height: 1.15; /* was 1.143; Figma 16px on 14px */
  letter-spacing: 1.2px;
  text-transform: uppercase;
}

.articleHead__crumb a {
  color: inherit;
  text-decoration: none;
}

.articleHead__title {
  margin: 0;
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-58);
  line-height: 1.15; /* was 1.1 */
}

.articleHead__share {
  display: flex;
  align-items: center;
  gap: var(--space-4);
}
.articleHead__share p {
  margin: 0;
  font-size: var(--font-14);
  font-weight: 500;
  letter-spacing: 1.2px;
  text-transform: uppercase;
}
.articleHead__share a {
  width: 24px;
  height: 24px;
  display: grid;
  place-items: center;
  color: var(--color-white);
  text-decoration: none;
}
.articleHead__share svg {
  width: 24px;
  height: 24px;
  display: block;
}

/* Copy link. The anchor is the positioning context for its tooltip, which sits
   above the icon and fades in for two seconds after a successful copy. */
.articleHead__copy {
  position: relative;
  cursor: pointer;
}

.articleHead__copyTooltip {
  position: absolute;
  bottom: calc(100% + var(--space-2));
  left: 50%;
  transform: translateX(-50%);
  padding: 3px;
  background: var(--color-white);
  color: var(--color-black);
  font-size: var(--font-12);
  font-weight: 500;
  white-space: nowrap;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 0.2s ease, visibility 0.2s ease;
}

.articleHead__copy--copied .articleHead__copyTooltip {
  opacity: 1;
  visibility: visible;
}

/* Off-screen scratch field used by the clipboard fallback. */
.articleHead__copyBuffer {
  position: fixed;
  top: -9999px;
  left: -9999px;
  opacity: 0;
}

.articleBody {
  padding-inline: 0;
  width: 91.53%;
  max-width: calc(var(--contentMax) * 0.9153);
  margin-inline: auto;
  background: var(--color-black);
}
.articleBody .qaBlock {
  padding-block: clamp(24.25px, 3.21vw, 61.6px); /* was 48.5px */
  padding-inline: clamp(24.25px, 3.21vw, 61.6px); /* was 48.5px */
}
.articleBody .qaBlock p {
  font-weight: 400;
}
.articleBody .qaBlock p + p {
  margin-top: clamp(11.2px, 1.48vw, 28.4px); /* was 22.4px */
}
/* NEWS-04: editor-inserted images sat flush on the next paragraph. */
.articleBody .qaBlock img {
  margin-bottom: var(--clamp-rem-16);
}
/* Scoped to beat `.articleBody .qaBlock p` — the plain class lost on specificity. */
.articleBody .qaBlock p.articleBody__lede {
  font-size: var(--font-20);
  font-weight: 600;
}
.articleBody a {
  color: inherit;
  text-decoration: underline;
}

.relatedArticles {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
  padding: var(--space-9) var(--space-9);
  background: linear-gradient(to top, var(--gradient-bg-stops));
}

.relatedArticles__title {
  margin: 0;
  font-family: var(--font-heading);
  font-weight: 400;
  font-size: var(--font-32);
  line-height: 1.2;
}

/* ---- the Robotics success story -------------------------------------------- */
/* Figma 1590:28145 / 1590:28188 — Frame 133 and Frame 134 are both 1320 of 1512
   (87.3%) inside a 96px page padding, not the 91.53% the rest of the site uses. */
.storyBody {
  padding-inline: 0;
  width: 87.3%;
  max-width: calc(var(--contentMax) * 0.873);
  margin-inline: auto;
  padding-block: var(--space-9);
  background: var(--color-black);
}

/* Figma 1590:28188 is a full-bleed 1512 band carrying the Background Gradient,
   with the 1320 column inside it — so the section spans the viewport and
   .storyWhy__inner holds the measure. */
.storyWhy {
  width: 100%;
  padding-block: var(--space-9);
}
.storyWhy__inner {
  width: 87.3%;
  max-width: calc(var(--contentMax) * 0.873);
  margin-inline: auto;
  display: flex;
  align-items: flex-start;
  gap: var(--space-9);
}

.storyBody {
  display: flex;
  flex-direction: column;
  gap: var(--space-9);
}
.storyBlock {
  max-width: 992px;
}

/* Figma 1590:28147 — Background and Our Approach sit side by side as two equal
   bordered panels on a 48px gap, NOT stacked full-width blocks. */
.storyBody__columns {
  display: flex;
  align-items: stretch;
  gap: var(--space-7);
}

.storyBlock--panel {
  flex: 1 0 0;
  min-width: 0;
  max-width: none;
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  padding: var(--space-7);
  border: 1px solid transparent;
  border-image: var(--gradient-line-2) 1;
}

/* The 66px rule under each label (Figma "Line 19" — the Line Gradient Light Grey
   style the MCP flattens to a plain #ebebeb). */
.storyBlock__rule {
  display: block;
  width: 66px;
  height: 2px;
  /* Figma "Line 19" is a solid brand ramp. --gradient-line-2 fades to transparent
     at its centre (it is built for border-image slicing), which rendered this as
     two dashes with a hole in the middle. */
  background-image: var(--gradient-brand);
}

/* Figma 1590:28163 — the impact block is centred on a 1000px measure. */
.storyBlock--impact {
  max-width: none; /* .storyBlock caps at 992; the stat grid is the full 1320 */
  text-align: center;
}
.storyBlock--impact .storyBlock__heading,
.storyBlock--impact .storyBlock__lede {
  max-width: 1000px;
  margin-inline: auto;
}
.storyBlock--impact .storyBlock__label {
  align-items: center;
}
.storyBlock--impact .storyBlock__heading {
  font-size: var(--font-55); /* Figma 1590:28168 — 132 tall over two lines */
  margin-bottom: var(--clamp-rem-48); /* Figma 1590:28167 lede sits 48 below */
}

.storyBlock__label {
  display: flex;
  flex-direction: column;
  gap: var(--clamp-rem-24);
  margin: 0 0 var(--clamp-rem-24);
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-24);
  line-height: 1.2;
  background-image: var(--gradient-brand);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.storyBlock__heading {
  margin: 0 0 var(--clamp-rem-32);
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-40);
  line-height: 1.2;
}

.storyBlock p {
  font-size: var(--font-16);
  line-height: 1.4;
}
.storyBlock p + p {
  margin-top: clamp(11.2px, 1.48vw, 28.4px); /* was 22.4px */
}

/* Panel interior (Figma 1590:28150). The 24px flex gap is the entire rhythm, so
   every child margin is zeroed — these selectors have to outrank .storyBlock p
   and .storyBlock__heading, which is why they are written long-hand. */
.storyBody .storyBlock--panel > p,
.storyBody .storyBlock--panel > h2,
.storyBody .storyBlock--panel > ul {
  margin: 0;
}

.storyBody .storyBlock--panel p,
.storyBody .storyBlock--panel li {
  font-size: var(--font-18); /* Figma body copy is 18, not the 16 used above */
  line-height: 1.4;
}

.storyBody .storyBlock--panel .storyBlock__phase,
.storyBody .storyBlock--panel .storyBlock__pull {
  font-weight: 700;
}

.storyBlock__pull {
  margin-top: var(--clamp-rem-32);
  font-weight: 700;
  font-size: var(--font-18);
  line-height: 1.4;
  background-image: var(--gradient-brand);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.storyBlock__phase {
  margin-top: var(--clamp-rem-32);
  font-weight: 700;
  font-size: var(--font-18);
  line-height: 1.4;
  background-image: var(--gradient-brand);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.storyList {
  margin: 0;
  padding-left: 27px; /* Figma ms-[27px] on the list items */
  list-style: disc;
  font-size: var(--font-18);
  line-height: 1.4;
}
.storyList li + li {
  margin-top: var(--clamp-rem-12);
}
.storyBlock__lede {
  font-size: var(--font-18);
  line-height: 1.4;
}

.storyStats {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  row-gap: var(--space-8);
  column-gap: var(--space-7); /* Figma 1590:28171 columns sit 48 apart */
  margin-top: var(--space-9); /* Figma 1590:28163 — Frame 231 ends 279, Frame 234 starts 375 */
}
.storyStat {
  flex: 1 1 380px;
  max-width: 476px; /* Figma 1590:28182 — widest a stat gets on the short row */
  text-align: center;
}

.storyBlock .storyStat__figure {
  margin: 0 0 var(--clamp-rem-32); /* Figma 1590:28173 label sits 32 below */
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-40);
  line-height: 1.2;
  background-image: var(--gradient-brand);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.storyBlock .storyStat__label {
  margin: 0;
  font-size: var(--font-18);
  line-height: 1.4;
}

.storyWhy__heading {
  margin: 0 0 var(--clamp-rem-32);
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-55);
  line-height: 1.15; /* was 1.1 */
}

/* Figma 1590:28189 — Why ECI Won is two columns: a 400px heading block beside an
   824px stack of bordered check rows, not the full-width hairline list this was.
   400 + 96 + 824 = the 1320 column. */
/* Figma 1590:28188 carries the shared Background Gradient, deep teal up into
   black — this section is not flat black like the story body above it. */
.storyWhy {
  background: linear-gradient(to top, var(--gradient-bg-stops));
}

/* Its label and rule are plain white here, not the brand ramp the story body
   labels use (Figma 1590:28191 / 1590:28192). */
.storyWhy__label {
  background-image: none;
  -webkit-text-fill-color: var(--color-white);
  color: var(--color-white);
}
.storyWhy__label .storyBlock__rule {
  background-image: none;
  background-color: var(--color-white);
}

.storyWhy__intro {
  flex: 0 0 30.3%; /* 400 of 1320 */
  max-width: 400px;
}

.storyWhy__list {
  list-style: none;
  flex: 1 1 0;
  min-width: 0;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-5); /* rows pitch 126 on a 102 box = 24 apart */
}

.storyWhy__item {
  display: flex;
  align-items: center;
  gap: var(--space-6); /* text starts at x=62 after a 30px check */
  padding: var(--space-5);
  /* Figma strokes these rows with the brand ramp, not the light-grey line. */
  border: 1px solid transparent;
  border-image: var(--gradient-brand) 1;
}

.storyWhy__item p {
  margin: 0;
  font-weight: 700;
  font-size: var(--font-18);
  line-height: 1.4;
}

.storyWhy__item .benefit__check {
  width: 30px;
  height: 30px;
  /* Measured rgb(63,208,159) off the Figma render of the Check instance
     (1590:28198) — the brand green, not --accent-mid, which defaults to #38abc1
     and is redefined per section elsewhere in this file. */
  color: var(--color-brand-green);
}

/* Figma 1590:28216 is a full-bleed 1512 band filled with the Background
   Gradient's teal stop, carrying the 1320 column inside — it continues the teal
   that .storyWhy above it fades up into. */
.storyRows--more {
  width: 100%;
  max-width: none;
  padding-top: 0;
  background: var(--color-teal-dark);
}
.storyRows__inner {
  width: 87.3%;
  max-width: calc(var(--contentMax) * 0.873);
  margin-inline: auto;
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}
.storyRows--more .relatedArticles__title {
  margin-bottom: var(--clamp-rem-32);
}

/* Success-story template, responsive pass (2026-09-23, STORY-01 / STORY-02).
   900 and under: every side-by-side block stacks to one column. Stats go 2-up
   then 1-up with no grow, so an odd last stat keeps its siblings' width. */
@media (max-width: 900px) {
  .storyBody__columns {
    flex-direction: column;
  }
  .storyWhy__inner {
    flex-direction: column;
    gap: var(--space-7);
  }
  .storyWhy__intro {
    flex: 0 0 auto;
    max-width: none;
  }
  .storyWhy__list {
    flex: 0 0 auto;
    width: 100%;
  }
}
/* 2-up with no grow up to 1199. Below that the base 380px basis either fits one
   per row (901-925) or lets the lone fifth stat grow past the others (to 1199).
   From 1200 every stat hits the 476 cap, so the base rule is safe. */
@media (max-width: 1199px) {
  .storyStat {
    flex: 0 0 calc((100% - var(--space-7)) / 2);
  }
}
@media (max-width: 600px) {
  .storyStat {
    flex: 0 0 100%;
  }
}

@media (max-width: 1000px) {
  .storyRows__row,
  .articleGrid {
    flex-wrap: wrap;
  }
  /* 2-up with no grow (was flex: 1 1 300px, which stretched the third card of
     every row to full width). Single-row grids (article page, Resources) centre
     the odd card. On the Newsroom the three row grids merge into one flow
     (display: contents), so cards pair across rows and only the very last card
     can end up alone. */
  .articleGrid {
    justify-content: center;
  }
  .articleCard {
    flex: 0 0 calc((100% - var(--space-8)) / 2);
  }
  section.newsroom {
    flex-direction: row;
    flex-wrap: wrap;
    justify-content: center;
    column-gap: var(--space-8);
  }
  section.newsroom > .articleGrid {
    display: contents;
  }
  section.newsroom > :not(.articleGrid) {
    flex: 0 0 100%;
  }
  .faqGroup {
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-5);
  }
  .faqGroup__label {
    flex: 0 0 auto;
  }
  .relatedTile--story .relatedTile__panel,
  .relatedTile--story.relatedTile--wide .relatedTile__panel {
    width: 100%;
  }
}
@media (max-width: 600px) {
  .articleCard {
    flex: 0 0 100%;
  }
}

@media (max-width: 700px) {

  .newsFilters {
    flex-direction: column;
    align-items: flex-start;
  }
}

/* --------------------------------------------------------------------------
   Contact Us — Figma "Contact Us" (1599:29480)
   -------------------------------------------------------------------------- */
/* Figma labels every field only with placeholder text. Placeholders are not
   accessible names, so each input keeps a real <label> that is hidden visually
   but not from assistive tech. */
.visuallyHidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* Contact hero (1599:29709) - its own photograph, pulled 2026-09-14. */
.hero--contact {
  background-image: url('../assets/images/contact-hero.jpg');
  min-height: fit-content;
  height: 60svh; /* was min-height: 540px, the Figma frame on a 900px viewport */
}

/* Frame 185: 96px all round, 96px between the form panel and the details. */
section.contact {
  display: flex;
  align-items: flex-start;
  gap: var(--space-9);
  padding-block: var(--space-9);
  padding-inline: 0;
  width: 87.3%;
  max-width: calc(var(--contentMax) * 0.873);
  margin-inline: auto;
  background: var(--color-black);
}

/* The panel is the file's only blurred surface: a 2px #ebebeb outline over a
   12px backdrop blur, with no fill of its own. */
.contactForm {
  flex: 1 0 0;
  min-width: min(320px, 100%); /* CON-01/03: the 320 floor overflowed a 272px column at 360 */
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
  padding: var(--space-8) var(--space-8);
  border: 2px solid #ebebeb;
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
}

/* Figma sets Arial Nova here, which is not a project face — the heading uses
   the house heading font at the same 48/1.1 and -0.96px tracking. */
.contactForm__title {
  margin: 0;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: var(--font-48);
  line-height: 1.15; /* was 1.1 */
  letter-spacing: -0.96px;
}

.contactForm__fields {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
}
.contactForm__row {
  display: flex;
  gap: var(--space-5);
}
.contactForm__field {
  flex: 1 0 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
}

.contactForm input,
.contactForm textarea {
  width: 100%;
  padding: clamp(6px, 0.79vw, 15.2px) var(--space-4); /* was 12px */
  border: 1px solid #ebebeb;
  background: transparent;
  font-family: var(--font-body);
  font-size: var(--font-16);
  line-height: 1.4;
  color: var(--color-white);
}

.contactForm input {
  height: 60px;
}
.contactForm textarea {
  min-height: 167px;
  resize: vertical;
}

.contactForm input::placeholder,
.contactForm textarea::placeholder {
  color: var(--color-white);
  opacity: 1;
}

.contactForm input:focus-visible,
.contactForm textarea:focus-visible {
  outline: 2px solid var(--color-brand-green);
  outline-offset: 2px;
}

.contactForm .button {
  align-self: flex-start;
}

/* --------------------------------------------------------------------------
   Contact Form 7 overrides
   WordPress renders CF7 "Contact Form - EN" (post 7) in place of the static
   form; its template was rewritten to emit the .contactForm markup above, so
   only CF7's own wrappers and messages need handling here. None of this shows
   in the static build, where the hand-built form has no wrappers to override.
   -------------------------------------------------------------------------- */

/* html_class puts .contactForm on CF7's <form>, but the shortcode still wraps
   it in a plain .wpcf7 div, which would otherwise eat the panel's flex sizing
   from section.contact. The wrapper takes the sizing and hands the panel a full box. */
section.contact .wpcf7 {
  flex: 1 0 0;
  min-width: min(320px, 100%); /* CON-01/03: the 320 floor overflowed a 272px column at 360 */
  display: flex;
}

section.contact .wpcf7 .contactForm {
  width: 100%;
}

/* CF7 wraps every control in this span. It is the flex child of
   .contactForm__field, so the input only fills the field once the span does. */
.contactForm .wpcf7-form-control-wrap {
  display: block;
  width: 100%;
}

/* CF7's hidden bookkeeping block and its screen-reader region must not open a
   gap in the .contactForm__fields column. */
.contactForm .screen-reader-response {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.contactForm .wpcf7-form.sent .wpcf7-response-output,
.contactForm .wpcf7-form.invalid .wpcf7-response-output,
.contactForm .wpcf7-form.failed .wpcf7-response-output,
.contactForm .wpcf7-form.spam .wpcf7-response-output,
.contactForm .wpcf7-form.unaccepted .wpcf7-response-output,
.contactForm .wpcf7-form.payment-required .wpcf7-response-output,
.contactForm .wpcf7-form.aborted .wpcf7-response-output {
  display: block;
}

.contactForm .wpcf7-response-output {
  margin: 0;
  padding: clamp(6px, 0.79vw, 15.2px) var(--space-4);
  border: 1px solid #ebebeb;
  font-family: var(--font-body);
  font-size: var(--font-16);
  line-height: 1.4;
  color: var(--color-white);
}

.contactForm .wpcf7-form.sent .wpcf7-response-output {
  border-color: var(--color-brand-green);
}

.contactForm .wpcf7-form.invalid .wpcf7-response-output,
.contactForm .wpcf7-form.failed .wpcf7-response-output,
.contactForm .wpcf7-form.spam .wpcf7-response-output {
  border-color: #ff6b6b;
}

/* The per-field tip sits under its own input inside .contactForm__field, which
   is already a column, so it needs no positioning — only type and colour. */
.contactForm .wpcf7-not-valid-tip {
  margin-top: var(--clamp-rem-8);
  font-family: var(--font-body);
  font-size: var(--font-14);
  line-height: 1.4;
  color: #ff6b6b;
}

.contactForm input.wpcf7-not-valid,
.contactForm textarea.wpcf7-not-valid {
  border-color: #ff6b6b;
}

/* CF7 drops the spinner in after the submit control. Left in flow next to the
   button rather than absolutely placed, so it cannot overlap the panel edge. */
.contactForm .wpcf7-spinner {
  margin: 0 0 0 var(--space-4);
  vertical-align: middle;
}

/* 400px column: a 400x200 photo over the address block and a Get Directions
   link on the .relatedTile__cta underline treatment. */
.contactDetails {
  flex: 1 0 0;
  min-width: 0;
  max-width: 400px;
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
}

.contactDetails__photo {
  display: block;
  width: 100%;
  aspect-ratio: 400 / 200;
  object-fit: cover;
}
/* Figma 1599:29576 — place, address and contact lines are a SINGLE 189px text
   node (7 lines on a 27px leading, one of them blank), so nothing sits between
   them; only the Get Directions link is 48 below. */
.contactDetails__body {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0;
}
.contactDetails__body .relatedTile__cta {
  margin-top: var(--clamp-rem-48);
}

.contactDetails__place,
.contactDetails__address,
.contactDetails__contactLines {
  margin: 0;
  font-size: var(--font-20);
  line-height: 1.35; /* Figma 27px on 20px */
}

.contactDetails__place + .contactDetails__address {
  margin-top: 0;
}
.contactDetails__contactLines {
  margin-top: clamp(13.5px, 1.79vw, 34.4px); /* was 27px */
}
.contactDetails a {
  color: inherit;
}
.contactDetails__contactLines a {
  text-decoration: underline; /* Figma underlines the number and the email */
}

@media (max-width: 1000px) {
  /* Qualified as section.contact: WordPress adds the page slug "contact" to
     <body>, and a bare .contact here shrank and flexed the whole body. */
  section.contact {
    flex-direction: column;
    align-items: stretch; /* CON-04: the stacked form fills the column */
    gap: var(--space-8);
    padding-block: var(--space-8);
    padding-inline: 0;
    width: calc(100% - (var(--gutter) * 2));
    margin-inline: auto;
  }
  .contactDetails {
    max-width: 100%;
  }
}

@media (max-width: 700px) {
  .contactForm {
    padding: var(--space-6) var(--space-6);
  }
  .contactForm__row {
    flex-direction: column;
    gap: var(--space-6);
  }
}

/* --------------------------------------------------------------------------
   Mobile inset for the percentage-width content containers.
   MUST stay last in the file: these are single-class selectors, so a copy of
   this block placed earlier loses the cascade to the per-component rules above.
   -------------------------------------------------------------------------- */
@media (max-width: 900px) {
  /* The 18 content containers below moved from `max-width: var(--contentMax)`
     + `padding-inline: var(--gutter)` to a percentage width (the soft-margin
     rule). 91.53% reproduces the old 64px gutter exactly from 900px up, but
     under 900 the old gutter was pinned at 24px, so a percentage would drift
     up to 28px. Restore the flat inset here. */
  .container,
  .section,
  .megatrends__grid,
  .family__outcomes,
  .successGrid,
  .faq__inner,
  .philosophy__intro,
  .process__grid,
  .moreSolutions__intro,
  .marketGrid__intro,
  .marketGrid__row,
  .qaBand,
  .resourcesIntro,
  .storyRows,
  .faqGroups,
  section.newsroom,
  .articleHead,
  .storyBody {
    width: calc(100% - (var(--gutter) * 2));
  }
  /* Success-story bands (2026-09-23): .storyWhy and the "more stories"
     .storyRows--more run full viewport width at 900 and under; their inner
     column carries the flat inset instead. */
  .storyWhy,
  .storyRows.storyRows--more {
    width: 100%;
  }
  .storyWhy__inner,
  .storyRows__inner {
    width: calc(100% - (var(--gutter) * 2));
  }
  .storyRows--more .relatedTile__panel {
    padding: var(--space-7);
  }
}

/* Related tiles on mobile, every page (Sam, 2026-09-24; first set for the
   success story tiles only). */
@media (max-width: 900px) {
  .relatedTile__title {
    font-size: var(--font-48);
  }
  .relatedTile__cta {
    font-size: var(--font-14);
  }
}

/* Header + hero inset at mobile. Must stay after `.hero--solutions .siteHeader`
   / `.hero--solutions .hero__body`, which are two-class selectors and beat a
   bare `.siteHeader` wherever they appear later in the file. The second branch
   exists because the old `padding-inline: var(--gutter)` override lost that same
   specificity contest, so the solutions family has always carried its own mobile
   inset rather than the 24px `--gutter` the other pages drop to. It reproduced
   that inherited 64px until 2026-09-01, when it was cut to `--space-6` (32px) —
   64px a side left the header and hero copy too cramped on a phone. */
@media (max-width: 900px) {
  .siteHeader,
  .hero__body {
    width: calc(100% - (var(--gutter) * 2));
  }

  .hero--solutions .siteHeader,
  .hero--solutions .hero__body,
  .hero--solutionsLowVoltage .siteHeader,
  .hero--solutionsLowVoltage .hero__body,
  .hero--solutionsHighVoltage .siteHeader,
  .hero--solutionsHighVoltage .hero__body,
  .hero--solutionsControlBoxes .siteHeader,
  .hero--solutionsControlBoxes .hero__body,
  .hero--solutionsEngineeringComponents .siteHeader,
  .hero--solutionsEngineeringComponents .hero__body,
  .hero--engineering .siteHeader,
  .hero--engineering .hero__body,
  .hero--operationalCapabilities .siteHeader,
  .hero--operationalCapabilities .hero__body,
  .hero--markets .siteHeader,
  .hero--markets .hero__body,
  .hero--megatrend .siteHeader,
  .hero--megatrend .hero__body,
  .hero--resources .siteHeader,
  .hero--resources .hero__body,
  .hero--resourcesSuccess .siteHeader,
  .hero--resourcesSuccess .hero__body,
  .hero--resourcesStory .siteHeader,
  .hero--resourcesStory .hero__body,
  .hero--resourcesFaq .siteHeader,
  .hero--resourcesFaq .hero__body,
  .hero--resourcesNewsroom .siteHeader,
  .hero--resourcesNewsroom .hero__body,
  .hero--contact .siteHeader,
  .hero--contact .hero__body {
    width: calc(100% - (var(--space-6) * 2));
  }
}

/* LV-01: the intro paragraph above the accordion carries margin: 0, so the list
   sat flush against it. Phone and tablet only, where the two blocks read as one. */
@media (max-width: 900px) {
  .solution__applications {
    margin-top: var(--clamp-rem-24);
  }
}

/* Applications accordion on solutions-low-voltage (1961:4382). Figma gives rows
   1-4 a bottom rule and leaves the last one open, unlike the .faqRow default. */
.solution__applications .faqRow:last-child {
  border-bottom: 0;
}

/* --------------------------------------------------------------------------
   Per-instance photography modifiers. Each rule carries the one background-image
   its instance shows; the block rule above it owns position/size/repeat. Replaces
   the inline style="background-image:..." these elements used to carry.
   -------------------------------------------------------------------------- */

/* markets-advanced-driver-safety.html */
.market__background--marketsAdvancedDriverSafetyBand {
  background-image: url('../assets/images/market-driver-safety-band.jpg');
}
.relatedTile__background--marketsAdvancedDriverSafetyMegatrend1 {
  background-image: url('../assets/images/market-driver-safety-megatrend-1.jpg');
}
.relatedTile__background--marketsAdvancedDriverSafetyMegatrend2 {
  background-image: url('../assets/images/market-driver-safety-megatrend-2.jpg');
}
.relatedTile__background--marketsAdvancedDriverSafetySolution1 {
  background-image: url('../assets/images/market-driver-safety-solution-1.jpg');
}

/* markets-aerospace-and-defense.html */
.market__background--marketsAerospaceBand {
  background-image: url('../assets/images/market-aerospace-band.jpg');
}
.relatedTile__background--marketsAerospaceMegatrend1 {
  background-image: url('../assets/images/related-megatrend-ai.jpg');
}
.relatedTile__background--marketsAerospaceMegatrend2 {
  background-image: url('../assets/images/related-megatrend-connected-systems.jpg');
}
.relatedTile__background--marketsAerospaceMegatrend3 {
  background-image: url('../assets/images/market-aerospace-megatrend-3.jpg');
}
.relatedTile__background--marketsAerospaceSolution1 {
  background-image: url('../assets/images/market-aerospace-solution-1.jpg');
}
.relatedTile__background--marketsAerospaceSolution2 {
  background-image: url('../assets/images/market-evs-solution-2.jpg');
}

/* markets-agriculture-and-construction.html */
.market__background--marketsAgricultureBand {
  background-image: url('../assets/images/market-agriculture-band.jpg');
}
.relatedTile__background--marketsAgricultureMegatrend1 {
  background-image: url('../assets/images/market-agriculture-megatrend-1.jpg');
}
.relatedTile__background--marketsAgricultureMegatrend2 {
  background-image: url('../assets/images/market-agriculture-megatrend-2.jpg');
}
.relatedTile__background--marketsAgricultureMegatrend3 {
  background-image: url('../assets/images/market-agriculture-megatrend-3.jpg');
}
.relatedTile__background--marketsAgricultureSolution1 {
  background-image: url('../assets/images/market-agriculture-solution-1.jpg');
}
.relatedTile__background--marketsAgricultureSolution2 {
  background-image: url('../assets/images/market-agriculture-solution-2.jpg');
}
/* INTERIM PHOTO: the FINAL doc adds High-Voltage EDS as a second Agriculture &
   Construction solution; Figma's row has only two tiles, so there is no export.
   Borrows the High-Voltage card photograph, as on the Data Centers page. */
.relatedTile__background--marketsAgricultureSolution3 {
  background-image: url('../assets/images/market-evs-solution-2.jpg');
}

/* markets-appliance-and-hvac.html */
/* Appliance & HVAC market cards (Figma 1574:10800, Blocks 13 / 15 / 14).
   These replace the three .market__background--marketsApplianceHvac* rules the
   page used before its 2026-09-14 rebuild — Figma dropped the full-bleed bands
   for the .marketGrid component, so the band photos are no longer referenced. */
.marketCard__background--applianceHvacResidential {
  background-image: url('../assets/images/market-residential-hvac-card.jpg');
}
.marketCard__background--applianceHvacCommercial {
  background-image: url('../assets/images/market-commercial-hvac-card.jpg');
}
.marketCard__background--applianceHvacAppliances {
  background-image: url('../assets/images/market-home-appliances-card.jpg');
}

/* markets-home-and-specialty-appliances.html */
.market__background--marketsAppliancesBand {
  background-image: url('../assets/images/market-appliances-band.jpg');
}
.relatedTile__background--marketsAppliancesMegatrend1 {
  background-image: url('../assets/images/related-megatrend-connected-systems.jpg');
}
.relatedTile__background--marketsAppliancesSolution1 {
  background-image: url('../assets/images/market-appliances-solution-1.jpg');
}

/* markets-commercial-hvac.html */
.market__background--marketsCommercialHvacBand {
  background-image: url('../assets/images/market-commercial-hvac-band.jpg');
}
.relatedTile__background--marketsCommercialHvacMegatrend1 {
  background-image: url('../assets/images/related-megatrend-ai.jpg');
}
.relatedTile__background--marketsCommercialHvacMegatrend2 {
  background-image: url('../assets/images/related-megatrend-connected-systems.jpg');
}
.relatedTile__background--marketsCommercialHvacSolution1 {
  background-image: url('../assets/images/market-commercial-hvac-solution-1.jpg');
}
.relatedTile__background--marketsCommercialHvacSolution2 {
  background-image: url('../assets/images/related-solution-control-boxes.jpg');
}
.relatedTile__background--marketsCommercialHvacSolution3 {
  background-image: url('../assets/images/related-solution-engineered-components.jpg');
}

/* markets-data-centers.html */
.market__background--marketsDataCentersBand {
  background-image: url('../assets/images/market-data-centers-band.jpg');
}
.relatedTile__background--marketsDataCentersMegatrend1 {
  background-image: url('../assets/images/market-data-centers-megatrend-1.jpg');
}
.relatedTile__background--marketsDataCentersSolution1 {
  background-image: url('../assets/images/market-data-centers-solution-1.jpg');
}
.relatedTile__background--marketsDataCentersSolution2 {
  background-image: url('../assets/images/market-data-centers-solution-2.jpg');
}
/* INTERIM PHOTO: the FINAL doc adds High-Voltage EDS as a third Data Centers
   solution; Figma's row has only two tiles, so there is no export for it. This
   borrows the High-Voltage card photograph the Solutions pages use. */
.relatedTile__background--marketsDataCentersSolution3 {
  background-image: url('../assets/images/market-evs-solution-2.jpg');
}

/* markets-commercial-evs.html */
.market__background--marketsEvsBand {
  background-image: url('../assets/images/market-evs-band.jpg');
}
.relatedTile__background--marketsEvsMegatrend1 {
  background-image: url('../assets/images/related-megatrend-electrification-v2.jpg');
}
.relatedTile__background--marketsEvsMegatrend2 {
  background-image: url('../assets/images/related-megatrend-connected-systems.jpg');
}
.relatedTile__background--marketsEvsSolution1 {
  background-image: url('../assets/images/market-evs-solution-1.jpg');
}
.relatedTile__background--marketsEvsSolution2 {
  background-image: url('../assets/images/market-evs-solution-2.jpg');
}

/* markets-industrial-machinery-and-transportation.html */
.market__background--marketsIndustrialBand {
  background-image: url('../assets/images/market-industrial-band.jpg');
}
.relatedTile__background--marketsIndustrialMegatrend1 {
  background-image: url('../assets/images/market-industrial-megatrend-1.jpg');
}
.relatedTile__background--marketsIndustrialMegatrend2 {
  background-image: url('../assets/images/related-megatrend-connected-systems.jpg');
}
.relatedTile__background--marketsIndustrialMegatrend3 {
  background-image: url('../assets/images/related-megatrend-electrification-v2.jpg');
}
.relatedTile__background--marketsIndustrialSolution1 {
  background-image: url('../assets/images/market-industrial-solution-1.jpg');
}
.relatedTile__background--marketsIndustrialSolution2 {
  background-image: url('../assets/images/related-solution-control-boxes.jpg');
}
.relatedTile__background--marketsIndustrialSolution3 {
  background-image: url('../assets/images/market-evs-solution-2.jpg');
}

/* markets-commercial-lighting.html */
.market__background--marketsLedsBand {
  background-image: url('../assets/images/market-commercial-lighting-band.jpg');
}
.relatedTile__background--marketsLedsMegatrend1 {
  background-image: url('../assets/images/related-megatrend-ai.jpg');
}
.relatedTile__background--marketsLedsMegatrend2 {
  background-image: url('../assets/images/related-megatrend-connected-systems.jpg');
}
.relatedTile__background--marketsLedsSolution1 {
  background-image: url('../assets/images/market-leds-solution-1.jpg');
}

/* markets-electrification-and-industrial.html */
.marketCard__background--marketsMainDataCenters {
  background-image: url('../assets/images/market-data-centers.jpg');
}
.marketCard__background--marketsMainDriverSafety {
  background-image: url('../assets/images/market-driver-safety.jpg');
}
.marketCard__background--marketsMainAgricultureConstruction {
  background-image: url('../assets/images/market-agriculture-construction.jpg');
}
.marketCard__background--marketsMainIndustrialMachinery {
  background-image: url('../assets/images/market-industrial-machinery.jpg');
}
.marketCard__background--marketsMainCommercialEv {
  background-image: url('../assets/images/market-commercial-ev.jpg');
}
.marketCard__background--marketsMainAerospaceDefense {
  background-image: url('../assets/images/market-aerospace-defense.jpg');
}
.marketCard__background--marketsMainSmartLighting {
  background-image: url('../assets/images/market-smart-lighting.jpg');
}
.marketCard__background--marketsMainMedicalDevices {
  background-image: url('../assets/images/market-medical-devices.jpg');
}
.marketCard__background--marketsMainSemiconductor {
  background-image: url('../assets/images/market-semiconductor.jpg');
}

/* markets-medical-devices.html */
.market__background--marketsMedicalBand {
  background-image: url('../assets/images/market-medical-band.jpg');
}
.relatedTile__background--marketsMedicalMegatrend1 {
  background-image: url('../assets/images/related-megatrend-ai.jpg');
}
.relatedTile__background--marketsMedicalMegatrend2 {
  background-image: url('../assets/images/related-megatrend-connected-systems.jpg');
}
.relatedTile__background--marketsMedicalSolution1 {
  background-image: url('../assets/images/market-medical-solution-1.jpg');
}

/* megatrends.html */
.marketCard__background--marketsMegatrendsAi {
  background-image: url('../assets/images/megatrends-ai.jpg');
}
.marketCard__background--marketsMegatrendsElectrification {
  background-image: url('../assets/images/megatrends-electrification.jpg');
}
.marketCard__background--marketsMegatrendsAutomation {
  background-image: url('../assets/images/megatrends-automation.jpg');
}
.marketCard__background--marketsMegatrendsConnected {
  background-image: url('../assets/images/related-megatrend-connected-systems.jpg');
}

/* markets-residential-hvac.html */
.market__background--marketsResidentialHvacBand {
  background-image: url('../assets/images/market-residential-hvac-band.jpg');
}
.relatedTile__background--marketsResidentialHvacMegatrend1 {
  background-image: url('../assets/images/related-megatrend-connected-systems.jpg');
}
.relatedTile__background--marketsResidentialHvacSolution1 {
  background-image: url('../assets/images/market-residential-hvac-solution-1.jpg');
}
.relatedTile__background--marketsResidentialHvacSolution2 {
  background-image: url('../assets/images/related-solution-control-boxes.jpg');
}
.relatedTile__background--marketsResidentialHvacSolution3 {
  background-image: url('../assets/images/related-solution-engineered-components.jpg');
}

/* markets-semiconductor-equipment.html */
.market__background--marketsSemiconductorBand {
  background-image: url('../assets/images/market-semiconductor-band.jpg');
}
.relatedTile__background--marketsSemiconductorMegatrend1 {
  background-image: url('../assets/images/related-megatrend-ai.jpg');
}
.relatedTile__background--marketsSemiconductorMegatrend2 {
  background-image: url('../assets/images/market-semiconductor-megatrend-2.jpg');
}
.relatedTile__background--marketsSemiconductorSolution1 {
  background-image: url('../assets/images/market-semiconductor-solution-1.jpg');
}

/* megatrends-ai-and-digitalization.html */
.marketCard__background--megatrendsAiCard1 {
  background-image: url('../assets/images/megatrends-ai-card-1.jpg');
}
.marketCard__background--megatrendsAiCard2 {
  background-image: url('../assets/images/related-megatrend-connected-systems.jpg');
}
.marketCard__background--megatrendsAiCard3 {
  background-image: url('../assets/images/related-megatrend-electrification-v2.jpg');
}

/* megatrends-automation.html */
.marketCard__background--megatrendsAutomationCard1 {
  background-image: url('../assets/images/related-megatrend-ai-circuit-v2.jpg');
}
.marketCard__background--megatrendsAutomationCard2 {
  background-image: url('../assets/images/related-megatrend-electrification-v2.jpg');
}
.marketCard__background--megatrendsAutomationCard3 {
  background-image: url('../assets/images/related-megatrend-connected-systems.jpg');
}

/* megatrends-smart-and-connected-systems.html */
.marketCard__background--megatrendsConnectedSystemsCard1 {
  background-image: url('../assets/images/related-megatrend-ai-circuit-v2.jpg');
}
.marketCard__background--megatrendsConnectedSystemsCard2 {
  background-image: url('../assets/images/related-megatrend-electrification-v2.jpg');
}
.marketCard__background--megatrendsConnectedSystemsCard3 {
  background-image: url('../assets/images/megatrends-connected-systems-card-3.jpg');
}

/* megatrends-electrification.html */
.marketCard__background--megatrendsElectrificationCard1 {
  background-image: url('../assets/images/related-megatrend-ai-circuit-v2.jpg');
}
.marketCard__background--megatrendsElectrificationCard2 {
  background-image: url('../assets/images/megatrends-electrification-card-2.jpg');
}
.marketCard__background--megatrendsElectrificationCard3 {
  background-image: url('../assets/images/related-megatrend-connected-systems.jpg');
}

/* resources-newsroom-article.html */
/* Resources - Main "Latest News" (Figma 1995:5733). Same .articleCard as the
   newsroom, but Figma's media band here is 200 tall with the tag pinned to the
   bottom of the 12px inset rather than the top. */
/* Resources - Main only. The shared blocks below carry this page's Figma metrics;
   the homepage .news and the newsroom .articleGrid keep their own. */
.storyRows--resourcesSuccessStories {
  gap: var(--space-5); /* Figma 1590:22305 rows sit 24 apart, not 64 */
  padding-top: var(--space-10); /* Figma 120, not 64 */
}

.news--resourcesLatestNews {
  width: 91.53%;
  max-width: calc(var(--contentMax) * 0.9153); /* Figma 1384, not 1320 */
  padding-top: 0; /* Figma 1590:22326 starts at the container top */
}

/* Figma 64 between intro and the tab row. Added on the intro rather than as a
   64 gap on the section, so the tabs-to-cards spacing stays the homepage's. */
.news--resourcesLatestNews .news__intro {
  margin-bottom: var(--space-4); /* 48 section gap + 16 = 64 */
}

/* AWAITING PHOTO: newsroom posts carry no featured image yet, so the card's media
   band falls back to the same translucent fill the photo-less tiles use. Set a
   featured image on the post and the loop emits an inline background-image. */
.articleCard--awaitingPhoto .articleCard__media {
  background-color: rgba(12, 12, 12, 0.55);
  border: 1px solid transparent;
  border-image: var(--gradient-line-1) 1;
}

.articleCard__title a,
.articleCard__title a:visited {
  color: inherit;
  text-decoration: none;
}
.articleCard__title a:hover {
  text-decoration: underline;
}

.articleCard__mediaBackground--resourcesNewsroomArticleNewsPlaceholder1 {
  background-image: url('../assets/images/news-1.jpg');
}
.articleCard__mediaBackground--resourcesNewsroomArticleNewsPlaceholder2 {
  background-image: url('../assets/images/news-2.jpg');
}
.articleCard__mediaBackground--resourcesNewsroomArticleNewsPlaceholder3 {
  background-image: url('../assets/images/news-3.jpg');
}

/* resources-newsroom.html */
.articleCard__mediaBackground--resourcesNewsroomNewsPlaceholder1 {
  background-image: url('../assets/images/news-1.jpg');
}
.articleCard__mediaBackground--resourcesNewsroomNewsPlaceholder2 {
  background-image: url('../assets/images/news-2.jpg');
}
.articleCard__mediaBackground--resourcesNewsroomNewsPlaceholder3 {
  background-image: url('../assets/images/news-3.jpg');
}
.articleCard__mediaBackground--resourcesNewsroomNewsPlaceholder4 {
  background-image: url('../assets/images/news-4.jpg');
}

/* Success-story tiles take the hero photo of the story they link to (2026-09-22). */
.relatedTile__background--successStoryRecreationalVehicles {
  background-image: url('../assets/images/success-story-recreational-vehicles-hero.jpg');
}

.relatedTile__background--successStoryHvacGovernmentContract {
  background-image: url('../assets/images/success-story-hvac-government-contract-hero.jpg');
}

.relatedTile__background--successStoryApplianceZeroDefect {
  background-image: url('../assets/images/success-story-appliance-zero-defect-hero.jpg');
}

.relatedTile__background--successStoryHvac72Hour {
  background-image: url('../assets/images/success-story-hvac-72-hour-restoration-hero.jpg');
}

.relatedTile__background--successStorySemiconductorTimeToMarket {
  background-image: url('../assets/images/success-story-semiconductor-time-to-market-hero.jpg');
}

.relatedTile__background--successStoryDataCentersCooling {
  background-image: url('../assets/images/success-story-data-centers-cooling-hero.jpg');
}

.relatedTile__background--successStoryRobotics {
  background-image: url('../assets/images/success-story-robotics-hero.jpg');
}

.relatedTile__background--successStoryDataCentersFirstToMarket {
  background-image: url('../assets/images/success-story-data-centers-first-to-market-hero.jpg');
}

.relatedTile__background--successStoryCommercialLed {
  background-image: url('../assets/images/success-story-commercial-led-hero.jpg');
}


/* resources.html */

/* solutions-control-box-assemblies-and-control-panels.html */
.market__background--solutionsControlBoxesCbMarketDatacenter {
  background-image: url('../assets/images/solutions-cb-market-datacenter.jpg');
}

/* solutions-engineered-components.html */
.market__background--solutionsEngineeringComponentsEcMarketDatacenter {
  background-image: url('../assets/images/solutions-ec-market-datacenter.jpg');
}

/* solutions-high-voltage-electrical-distribution-systems.html */
.market__background--solutionsHighVoltageHvMarketDatacenter {
  background-image: url('../assets/images/solutions-hv-market-datacenter.jpg');
}

/* solutions-low-voltage-electrical-distribution-systems.html */
.market__background--solutionsLowVoltageDatacenterMarket {
  background-image: url('../assets/images/solutions-datacenter-market.jpg');
}
.capabilityCard__background--solutionsLowVoltageLvApplicationDataCenter {
  background-image: url('../assets/images/lv-application-data-center.jpg');
}
.capabilityCard__background--solutionsLowVoltageLvApplicationAdvancedDriverSafety {
  background-image: url('../assets/images/lv-application-advanced-driver-safety.jpg');
}
.capabilityCard__background--solutionsLowVoltageLvApplicationConstructionAgricultural {
  background-image: url('../assets/images/lv-application-construction-agricultural.jpg');
}

.capabilityCard__background--solutionsLowVoltageLvApplicationSpecializedDefenseVehicles {
  background-image: url('../assets/images/lv-application-defense.jpg');
}
.capabilityCard__background--solutionsLowVoltageLvApplicationMedical {
  background-image: url('../assets/images/lv-application-medical.jpg');
}
.capabilityCard__background--solutionsLowVoltageLvApplicationHvac {
  background-image: url('../assets/images/lv-application-hvac.jpg');
}
.capabilityCard__background--solutionsLowVoltageLvApplicationAppliances {
  background-image: url('../assets/images/lv-application-appliances.jpg');
}

/* --------------------------------------------------------------------------
   Solutions > Low-Voltage — 2026-09-15 full-layer re-read of 1543:2861
   -------------------------------------------------------------------------- */

/* Frame 349 (1546:3561) — the trio cards carry the same four-layer art as the
   .productSolutions cards (photo / black veil / soft-light wash / vignette),
   plus a 200px ring at 0.75px in the card accent holding a 50px ECI icon.
   Photo, wash and veil come from .productSolutions__slot--* which this page's
   slots now also set; the art itself is .productSolutions__card, shared. */
.moreSolutions--lowVoltageTrio .moreSolutions__slot--hv {
  --card-wash: #ff8800;
  --card-photo: url('../assets/images/solution-card-bg-high-voltage.jpg');
  --card-veil: 0.8;
}
.moreSolutions--lowVoltageTrio .moreSolutions__slot--cb {
  --card-wash: #e828a8;
  --card-photo: url('../assets/images/solution-card-bg-control-boxes.jpg');
  --card-veil: 0.8;
}
.moreSolutions--lowVoltageTrio .moreSolutions__slot--components {
  --card-wash: #0166b3;
  --card-photo: url('../assets/images/solution-card-bg-engineering-components.jpg');
  --card-veil: 0.8;
}

/* The ring is the slot's own brand ramp, not the flat --card-accent (which is
   only the ramp's opening stop). border-image ignores border-radius, so the
   ramp is painted by a masked pseudo-element, the same technique as
   .processStep__number::before. */
.moreSolutions__ring {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 200px;
  height: 200px;
  padding: 4.5px;
  border: 0.75px solid transparent;
  border-radius: 500px;
}

.moreSolutions__ring::before {
  content: '';
  position: absolute;
  inset: -2px;
  padding: 2px;
  border-radius: inherit;
  background: var(--card-ramp, var(--card-accent));
  -webkit-mask:
    linear-gradient(#000 0 0) content-box,
    linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
  pointer-events: none;
}

.moreSolutions__ringIcon {
  width: 50px;
  height: 50px;
  object-fit: contain;
}

/* Figma stacks ring and text 48px apart inside the card body. */
.moreSolutions--lowVoltageTrio .moreSolutions__body,
.moreSolutions--highVoltageTrio .moreSolutions__body,
.moreSolutions--controlBoxesTrio .moreSolutions__body,
.moreSolutions--engineeringComponentsTrio .moreSolutions__body {
  gap: var(--clamp-rem-48);
}

@media (max-width: 900px) {
  .moreSolutions__ring {
    width: 140px;
    height: 140px;
  }
  .moreSolutions__ringIcon {
    width: 36px;
    height: 36px;
  }
}

/* Frame 262 (1546:3479) — the replacement photo is portrait (1122x1402), so at
   the 500px column width its intrinsic height (625) outgrew the 526 row Figma
   draws. Stretching the column lets the benefits list set the height and the
   photo cover-crop into it, as the Figma frame does. Scoped to this page: the
   other .solution bands still carry landscape photos. */
.solution--lowVoltageDetail .solution__photo {
  align-self: stretch;
  position: relative;
}

/* Taking the img out of flow stops its 625px intrinsic height setting the row;
   the benefits list sets 526 and the photo cover-crops into it. */
.solution--lowVoltageDetail .solution__photo img {
  position: absolute;
  inset: 0;
}

/* Frame 379 (1546:3484) — the benefits label is now a 48px white heading in its
   own Frame 258 (1963:4426/4427) with 48px below it, not the small gradient
   eyebrow the other .solution bands carry. Scoped to this page's band. */
.solution--lowVoltageDetail .solution__benefitsLabel {
  background-image: none;
  -webkit-background-clip: border-box;
  background-clip: border-box;
  color: var(--color-white);
  text-transform: none;
  letter-spacing: normal;
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-48);
  line-height: 1.2;
  padding-bottom: var(--clamp-rem-48);
}

/* Accordion 1961:4382 — the Applications rows are 20px Golos Text Medium on a
   19.25px box, not the 16px Inter the FAQ rows this markup borrows from use. */
.solution__applications .faqRow__question span {
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-20);
}

/* Frame 336 (1543:2926) — the panel stroke reads as flat #40d39f through both read
   tools, the same flattening the High-Voltage instance already corrects for: there
   it is --gradient-orange painted with border-image (line ~7009). This page's
   instance takes the brand ramp. Assumed from that mirror, not measured. */
/* Redundant since the base .market__panel took the same ramp (2026-09-15), kept
   so the page's intent stays explicit if the base ever changes again. */
.market--solutionsLowVoltage .market__panel {
  border-color: transparent;
  border-image: var(--gradient-brand) 1;
}

/* --------------------------------------------------------------------------
   Solutions > High-Voltage EDS  (Figma page frame 1546:3992)
   --------------------------------------------------------------------------
   Rebuilt 2026-09-15 from the Figma layer, which is now a structural twin of
   Solutions - Low Voltage: same section order, same components, same mirrored
   band, same 5-row Applications accordion, same trio, no FAQ. Only the accent,
   the photography and the copy differ, so this block carries nothing but those.
   Body copy comes from the FINAL copy doc, which supersedes the Figma text.

   Derived paints (get_variable_defs returns "Orange Gradient" name-only and
   get_design_context flattens each of these to its first stop, #ffde8e):
   - hero pill fill      rgba(64,211,159,0) -> rgba(253,197,109,0.6) -> rgba(251,164,64,0)
   - hero button stroke  --gradient-orange
   - market panel stroke --gradient-orange, glow rgba(253,184,19,0.5) */

/* Hero 1546:3993 — frame and both scrim layers as .hero--solutions; photo,
   pill ramp and Contact Us stroke are the deltas. The vertical scrim opens at
   0.2 here exactly as on the Low-Voltage page. */
.hero--solutionsHighVoltage {
  background-image: url('../assets/images/solutions-hero-high-voltage.jpg');
}

.hero--solutionsHighVoltage .hero__pill {
  background: linear-gradient(
    90deg,
    rgba(64, 211, 159, 0) 0%,
    rgba(253, 197, 109, 0.6) 50%,
    rgba(251, 164, 64, 0) 100%
  );
  border-image: linear-gradient(
      90deg,
      rgba(255, 222, 142, 0) 0%,
      #fba440 50%,
      rgba(64, 211, 159, 0) 100%
    )
    1;
}

.hero--solutionsHighVoltage .button--compact {
  border-image: var(--gradient-orange) 1;
}

/* InfoBlocks 1546:4054 — statement band verbatim; only the ramp on the
   highlighted span swaps to this page's accent. */
.solutionsStatement--highVoltage :is(h1, h2, h3, p):has(> .gradientText) {
  background-image: var(--gradient-orange);
}

/* Frame 336 (1546:4057) — the .market band, panel left, no eyebrow. Stroke is
   the Orange Gradient painted with border-image (the MCP reports it flat). */
.market--solutionsHighVoltage .market__panel {
  border-color: transparent;
  border-image: var(--gradient-orange) 1;
  box-shadow: 0 0 30px 0 rgba(253, 184, 19, 0.5);
}

.market__background--solutionsHighVoltageMarket {
  background-image: url('../assets/images/solutions-hv-market-datacenter.jpg');
}

/* Frame 334 (1963:4751) — the mirrored band with the in-band card track. */
.solution--highVoltageDetail .solution__capabilities {
  margin-top: var(--space-9);
}

.solution--highVoltageDetail {
  padding-bottom: var(--space-9);
}

.solution--highVoltageDetail .solution__medallion {
  --medallion-image: url('../assets/images/solutions-hv-medallion-bg.jpg');
}

/* Same photo as the HV card (2912x1632); centre its 38.6% focal point, as
   .moreSolutions__slot--hv does. With cover at 492x428 that is 18%. */
.solution--highVoltageDetail .solution__medallion::before {
  background-position: 18% center;
}

/* Frame 262 (1963:4796) — the replacement photo is landscape 4096x2304, so it
   needs the same out-of-flow treatment the Low-Voltage band uses. */
.solution--highVoltageDetail .solution__photo {
  align-self: stretch;
  position: relative;
}

.solution--highVoltageDetail .solution__photo img {
  position: absolute;
  inset: 0;
}

/* Frame 379 (1963:4799) — 48px white heading, not the small gradient eyebrow. */
.solution--highVoltageDetail .solution__benefitsLabel {
  background-image: none;
  -webkit-background-clip: border-box;
  background-clip: border-box;
  color: var(--color-white);
  text-transform: none;
  letter-spacing: normal;
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-48);
  line-height: 1.2;
  padding-bottom: var(--clamp-rem-48);
}

/* Card track (1967:5340). FINAL PHOTOGRAPHY, placed 2026-09-22 from
   3) Website Imagery/Final/4-SOLUTIONS/High Voltage/Blocks. The four supplied
   files carry the card names, so the mapping is by name, not by file order —
   the numeric prefixes are not card order on any of these pages. */
.capabilityCard__background--solutionsHighVoltageHvApplicationCommercialEv {
  background-image: url('../assets/images/hv-application-commercial-ev.jpg');
}
.capabilityCard__background--solutionsHighVoltageHvApplicationEnergyStorage {
  background-image: url('../assets/images/hv-application-energy-storage.jpg');
}
.capabilityCard__background--solutionsHighVoltageHvApplicationIndustrialMachinery {
  background-image: url('../assets/images/hv-application-industrial-machinery.jpg');
}
.capabilityCard__background--solutionsHighVoltageHvApplicationAgricultureConstruction {
  background-image: url('../assets/images/hv-application-agriculture-construction.jpg');
}

/* Frame 349 (1546:4114) — trio card art, this page's slot-1 accent aside; the
   washes and photos are the shared .productSolutions ones. */
.moreSolutions--highVoltageTrio .moreSolutions__slot--lv {
  --card-wash: #40d39f;
  --card-photo: url('../assets/images/solution-card-bg-low-voltage.jpg');
  --card-veil: 0.9;
}

/* The statement band's highlighted phrase is the FINAL copy doc's bold run, and
   Figma sets that span to Golos Text Medium against the paragraph's Regular
   (1543:2925 / 1546:4056). .gradientText only makes the glyphs transparent, so
   the weight has to come from here or the emphasis is carried by colour alone. */
.solutionsStatement .gradientText {
  font-weight: 500;
}

/* --------------------------------------------------------------------------
   Solutions > Control Box Assemblies & Control Panels  (Figma page frame 1553:4544)
   --------------------------------------------------------------------------
   Rebuilt 2026-09-15 from the Figma layer, which is a structural twin of
   Solutions - Low Voltage: same section order, same components, same mirrored
   band, same Applications accordion, same trio (LV -> HV -> Components), no FAQ.
   Body copy comes from the FINAL copy doc, which supersedes the Figma text.

   Derived paints, carried over from the previous build of this page (measured
   then, not re-measured now — get_variable_defs returns the style names empty
   and get_design_context flattens each of these to its first stop):
   - hero pill fill      rgba(150,104,255,0) -> rgba(185,76,233,0.6) -> rgba(150,104,254,0)
   - market panel stroke --gradient-control-box (MCP reports flat #fb4097 = stop 0)
   - market panel glow   rgba(241,66,163,0.5)
   Rejected near-miss, also carried over: the hero Contact Us button on this page
   is NOT ramped — it keeps the default brand-green .button border, unlike the
   High-/Low-Voltage twins, so there is deliberately no override for it. */

.hero--solutionsControlBoxes {
  background-image: url('../assets/images/solutions-hero-control-boxes.jpg');
}

.hero--solutionsControlBoxes .hero__pill {
  background: linear-gradient(
    90deg,
    rgba(150, 104, 255, 0) 0%,
    rgba(185, 76, 233, 0.6) 50%,
    rgba(150, 104, 254, 0) 100%
  );
  border-image: linear-gradient(
      90deg,
      rgba(251, 64, 151, 0) 0%,
      #a750ff 50%,
      rgba(100, 174, 255, 0) 100%
    )
    1;
}

/* InfoBlocks 1553:4606 */
.solutionsStatement--controlBoxes :is(h1, h2, h3, p):has(> .gradientText) {
  background-image: var(--gradient-control-box);
}

/* Frame 336 (1553:4609) — .market band, panel left, no eyebrow. */
.market--solutionsControlBoxes .market__panel {
  border-color: transparent;
  border-image: var(--gradient-control-box) 1;
  box-shadow: 0 0 30px 0 rgba(241, 66, 163, 0.5);
}

.market__background--solutionsControlBoxesMarket {
  background-image: url('../assets/images/solutions-cb-market-datacenter.jpg');
}

/* Frame 334 (1963:4853) — the mirrored band with the in-band card track. */
.solution--controlBoxesDetail .solution__capabilities {
  margin-top: var(--space-9);
}

.solution--controlBoxesDetail {
  padding-bottom: var(--space-9);
}

.solution--controlBoxesDetail .solution__medallion {
  --medallion-image: url('../assets/images/solutions-cb-medallion-bg.jpg');
}

/* Frame 262 (1963:4898) — Figma uses the same 4096x2304 band photograph here as
   on High-Voltage (MAE 0.0), so both pages point at the one asset rather than
   shipping a duplicate. Same out-of-flow treatment as the other two pages. */
.solution--controlBoxesDetail .solution__photo {
  align-self: stretch;
  position: relative;
}

.solution--controlBoxesDetail .solution__photo img {
  position: absolute;
  inset: 0;
}

/* Frame 379 (1963:4901) — 48px white heading, not the small gradient eyebrow. */
.solution--controlBoxesDetail .solution__benefitsLabel {
  background-image: none;
  -webkit-background-clip: border-box;
  background-clip: border-box;
  color: var(--color-white);
  text-transform: none;
  letter-spacing: normal;
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-48);
  line-height: 1.2;
  padding-bottom: var(--clamp-rem-48);
}

/* Card track (1967:5383). FINAL PHOTOGRAPHY, placed 2026-09-22 from
   3) Website Imagery/Final/4-SOLUTIONS/Control Box Assemblies/Blocks. Four of
   the five cards were supplied; "Custom" has no file and keeps an interim
   borrow under its own name. */
.capabilityCard__background--solutionsControlBoxesCbApplicationDataCenters {
  background-image: url('../assets/images/cb-application-data-centers.jpg');
}
.capabilityCard__background--solutionsControlBoxesCbApplicationIndustrialAutomation {
  background-image: url('../assets/images/cb-application-industrial-automation.jpg');
}
.capabilityCard__background--solutionsControlBoxesCbApplicationHvac {
  background-image: url('../assets/images/cb-application-hvac.jpg');
}
.capabilityCard__background--solutionsControlBoxesCbApplicationAerospace {
  background-image: url('../assets/images/cb-application-aerospace.jpg');
}

/* Frame 349 (1553:4668) — trio card art for this page's two swapped slots. */
.moreSolutions--controlBoxesTrio .moreSolutions__slot--lv {
  --card-wash: #40d39f;
  --card-photo: url('../assets/images/solution-card-bg-low-voltage.jpg');
  --card-veil: 0.9;
}
.moreSolutions--controlBoxesTrio .moreSolutions__slot--hv {
  --card-wash: #ff8800;
  --card-photo: url('../assets/images/solution-card-bg-high-voltage.jpg');
  --card-veil: 0.8;
}

/* --------------------------------------------------------------------------
   Solutions > Engineered Components  (Figma page frame 1553:4995)
   --------------------------------------------------------------------------
   Rebuilt 2026-09-15 from the Figma layer — the fourth structural twin of
   Solutions - Low Voltage: same section order, same components, same mirrored
   band, same Applications accordion, same trio (LV -> HV -> Control Boxes),
   no FAQ. Body copy comes from the FINAL copy doc, which supersedes Figma.

   The band itself rides the existing .solution--engineeredComponents modifier, which
   already carries the cp ramp (#a8ecff -> #49a0ff 51.442% -> #40d39f), its
   --accent-wash #0166b3 and the icon-solution-cp.svg glyph.

   Derived paints, carried over from the previous build of this page (measured
   then, not re-measured now):
   - hero pill fill         rgba(64,211,159,0) -> rgba(94,177,255,0.6) -> rgba(64,211,159,0)
   - market panel stroke    cp ramp (MCP reports flat #a8ecff = stop 0)
   - market panel glow      rgba(89,173,254,0.5)
   Rejected near-miss, also carried over: the hero Contact Us stroke here is a
   genuine flat #40d39f, not a ramp — same as Control Boxes, unlike the two
   Voltage pages — so it deliberately has no override. */

.hero--solutionsEngineeringComponents {
  background-image: url('../assets/images/solutions-hero-engineering-components.jpg');
}

.hero--solutionsEngineeringComponents .hero__pill {
  background: linear-gradient(
    90deg,
    rgba(64, 211, 159, 0) 0%,
    rgba(94, 177, 255, 0.6) 50%,
    rgba(64, 211, 159, 0) 100%
  );
  border-image: linear-gradient(
      90deg,
      rgba(168, 236, 255, 0) 0%,
      #49a0ff 51.442%,
      rgba(64, 211, 159, 0) 100%
    )
    1;
}

/* InfoBlocks 1553:5057 */
.solutionsStatement--engineeringComponents :is(h1, h2, h3, p):has(> .gradientText) {
  background-image: var(--gradient-blue);
}

/* Frame 336 (1553:5060) — .market band, panel left, no eyebrow. */
.market--engineeringComponents .market__panel {
  border-color: transparent;
  border-image: var(--gradient-blue) 1;
  box-shadow: 0 0 30px 0 rgba(89, 173, 254, 0.5);
}

/* Frame 334 (1963:4955) — the mirrored band with the in-band card track. */
.solution--engineeringComponentsDetail .solution__capabilities {
  margin-top: var(--space-9);
}

.solution--engineeringComponentsDetail {
  padding-bottom: var(--space-9);
}

.solution--engineeringComponentsDetail .solution__medallion {
  --medallion-image: url('../assets/images/solutions-ec-medallion-bg.jpg');
}

/* Frame 262 (1963:5000) — Figma uses the same 4096x2304 band photograph on this
   page as on High-Voltage and Control Boxes (MAE 0.0), so all three point at the
   one neutrally-named asset. Same out-of-flow treatment as its siblings. */
.solution--engineeringComponentsDetail .solution__photo {
  align-self: stretch;
  position: relative;
}

.solution--engineeringComponentsDetail .solution__photo img {
  position: absolute;
  inset: 0;
}

/* Frame 379 (1963:5003) — 48px white heading, not the small gradient eyebrow. */
.solution--engineeringComponentsDetail .solution__benefitsLabel {
  background-image: none;
  -webkit-background-clip: border-box;
  background-clip: border-box;
  color: var(--color-white);
  text-transform: none;
  letter-spacing: normal;
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-48);
  line-height: 1.2;
  padding-bottom: var(--clamp-rem-48);
}

/* Card track (1967:5426). FINAL PHOTOGRAPHY, placed 2026-09-22 from
   3) Website Imagery/Final/4-SOLUTIONS/Engineering components/Blocks. The
   supplied "Dill Blox" file is the Modular Power Distribution Blocks card. */
.capabilityCard__background--solutionsEngineeringComponentsEcApplicationInjectionMolding {
  background-image: url('../assets/images/ec-application-injection-molding.jpg');
}
.capabilityCard__background--solutionsEngineeringComponentsEcApplicationPowerDistributionBlocks {
  background-image: url('../assets/images/ec-application-power-distribution-blocks.jpg');
}
.capabilityCard__background--solutionsEngineeringComponentsEcApplicationOvermolding {
  background-image: url('../assets/images/ec-application-overmolding.jpg');
}
.capabilityCard__background--solutionsEngineeringComponentsEcApplicationEngineeredComponents {
  background-image: url('../assets/images/ec-application-engineered-components.jpg');
}
.capabilityCard__background--solutionsEngineeringComponentsEcApplicationConnectors {
  background-image: url('../assets/images/ec-application-connectors.jpg');
}
.capabilityCard__background--solutionsEngineeringComponentsEcApplicationPcb {
  background-image: url('../assets/images/ec-application-pcb.jpg');
}

/* Frame 349 (1553:5117) — trio card art for this page's three slots. */
.moreSolutions--engineeringComponentsTrio .moreSolutions__slot--lv {
  --card-wash: #40d39f;
  --card-photo: url('../assets/images/solution-card-bg-low-voltage.jpg');
  --card-veil: 0.9;
}
.moreSolutions--engineeringComponentsTrio .moreSolutions__slot--hv {
  --card-wash: #ff8800;
  --card-photo: url('../assets/images/solution-card-bg-high-voltage.jpg');
  --card-veil: 0.8;
}
.moreSolutions--engineeringComponentsTrio .moreSolutions__slot--cb {
  --card-wash: #e828a8;
  --card-photo: url('../assets/images/solution-card-bg-control-boxes.jpg');
  --card-veil: 0.8;
}

/* --------------------------------------------------------------------------
   Solutions > Operational Capabilities — card photography (Figma 1259:1768)
   --------------------------------------------------------------------------
   Rebuilt 2026-09-15. Until now every Block 3 card on this page shared one
   opcap-card.jpg; Figma gives each card its own photograph, paired
   here by reading the per-card image constants from the row's design context
   (not by eye — the card scrim makes visual pairing unreliable).
   Card art itself is the shared .capabilityCard--photo recipe: photo under a
   #0c0c0c -> rgba(12,12,12,0.3) 50% -> rgba(12,12,12,0.6) vertical scrim. */
.capabilityCard__background--opcapPrimaryLeadPrep {
  background-image: url('../assets/images/opcap-primary-lead-prep.jpg');
}
.capabilityCard__background--opcapSecondaryLeadPrep {
  background-image: url('../assets/images/opcap-secondary-lead-prep.jpg');
}
.capabilityCard__background--opcapAssembly {
  background-image: url('../assets/images/opcap-assembly.jpg');
}
.capabilityCard__background--opcapTesting {
  background-image: url('../assets/images/opcap-testing.jpg');
}
.capabilityCard__background--opcapPackagingKittingLogistics {
  background-image: url('../assets/images/opcap-packaging-kitting-logistics.jpg');
}
.capabilityCard__background--opcapPcbMfg {
  background-image: url('../assets/images/opcap-pcb-mfg.jpg');
}
.capabilityCard__background--opcapKittingSequenced {
  background-image: url('../assets/images/opcap-kitting-sequenced.jpg');
}
/* FINAL PHOTOGRAPHY, placed 2026-09-22 from 5-ENG CAPABILITIES/
   "High Speed Data - Coax Cable.png". Replaces the borrowed Data Centers market
   shot this card carried while no export existed. */
.capabilityCard__background--opcapHighSpeedData {
  background-image: url('../assets/images/opcap-high-speed-data.jpg');
}
.capabilityCard__background--opcapHighVoltageMfg {
  background-image: url('../assets/images/opcap-high-voltage-mfg.jpg');
}
.capabilityCard__background--opcapMfgAutomation {
  background-image: url('../assets/images/opcap-mfg-automation.jpg');
}
.capabilityCard__background--opcapDigitalMfg {
  background-image: url('../assets/images/opcap-digital-mfg.jpg');
}
.capabilityCard__background--opcapAiQuality {
  background-image: url('../assets/images/opcap-ai-quality.jpg');
}

/* .capabilityCard--photo bottom-aligns its caption for the Solutions detail
   pages (caption only, no button). The Operational Capabilities cards use the
   same photo recipe but Figma's Block 3 is a two-part card — 28px title pinned
   to the top inset, LEARN MORE pinned to the bottom — so the band's own cards
   go back to space-between. Scoped to section.capability, which the Solutions
   pages' in-band track (.solution > .capability__cards) does not match. */
section.capability .capabilityCard--photo {
  justify-content: space-between;
}

/* Frame 390 (1543:2588) — the Solutions - Main 2x2 card grid carries the same
   200px accent ring + 50px glyph as the .moreSolutions--trio cards, so it reuses
   .moreSolutions__ring (these cards already use .moreSolutions__body/__head).
   Glyphs are the file's own 47px "ECI Icons" exports, not the medallion files:
   icon-solution-lv/cb already bake a ring into their 324 box and would have
   drawn a second ring inside this one. */
.productSolutions__card .moreSolutions__body {
  gap: var(--clamp-rem-48);
}

/* The FINAL copy doc bolds the lead differentiator sentence in each market
   band's paragraph; the band's body copy is otherwise Inter Regular 16. */
.market__copy strong {
  font-weight: 600;
}

/* INTERIM PHOTO: the FINAL doc lists four megatrends for Aerospace & Defense;
   Figma's row has three, so there is no export for Electrification. */
.relatedTile__background--marketsAerospaceMegatrend4 {
  background-image: url('../assets/images/megatrends-electrification.jpg');
}
/* INTERIM PHOTO: the FINAL doc adds Control Box Assemblies & Control Panels as a
   second Semiconductor Equipment solution; Figma's row has one tile only. */
.relatedTile__background--marketsSemiconductorSolution2 {
  background-image: url('../assets/images/solution-card-bg-control-boxes.jpg');
}

/* INTERIM PHOTO: the FINAL doc lists AI & Digitalization as a second megatrend
   for Residential HVAC; Figma's row carries one tile, so there is no export. */
.relatedTile__background--marketsResidentialHvacMegatrend2 {
  background-image: url('../assets/images/megatrends-ai.jpg');
}
/* INTERIM PHOTO: the FINAL doc lists AI & Digitalization as a second megatrend
   for Home & Specialty Appliances; Figma's row carries one tile, so there is no export. */
.relatedTile__background--marketsAppliancesMegatrend2 {
  background-image: url('../assets/images/megatrends-ai.jpg');
}

/* --------------------------------------------------------------------------
   Legal template — Figma "Legal Template - Basic" 2976:4411
   -------------------------------------------------------------------------- */

/* The hero frame is **540**, not the 634 every other inner page uses, so this
   family cannot join the .hero--resources height group above. Same two scrim
   layers as that group though, and the vertical one starts at 0.2 like
   .hero--operationalCapabilities rather than at 0 — so it declares its own.
   Reusable: privacy-policy and modern-slavery-statement are the same template,
   and each would add its own photo modifier beside .hero--termsConditions. */
.hero--legal {
  min-height: fit-content;
  height: 60svh; /* Figma 540 on a 900px viewport */
}

.hero--legal::before {
  background:
    linear-gradient(90deg, #0c0c0c 0%, rgba(12, 12, 12, 0) 59.615%),
    linear-gradient(
      180deg,
      rgba(12, 12, 12, 0.2) 0%,
      rgba(12, 12, 12, 0.5) 69.231%,
      #0c0c0c 100%
    );
}

/* Shares resources-hero-faq.jpg with .hero--resourcesFaq — the same photograph,
   confirmed by diffing Figma's export against the shipped file (MAE 0.0), not by
   the filename. .hero--errorNotFound borrows it too: the 404 has no Figma layer,
   so it takes the legal family's photo rather than introducing a new one. */
.hero--termsConditions,
.hero--privacyPolicy,
.hero--forSuppliers,
.hero--forCustomers,
.hero--modernSlavery,
.hero--errorNotFound {
  background-image: url('../assets/images/resources-hero-faq.jpg');
}

/* Container 2976:4467 — 96 above the panel, 120 below it. */
.legalPanel {
  padding-block: var(--space-9) var(--space-10);
  padding-inline: 0;
  background: var(--color-black);
}

/* Block 1 2976:4760 at 1384 of 1512. The border is the Line Gradient 1 style,
   which both read tools flatten to its #818181 first stop — applied here the way
   every other bordered card in the build does it, via border-image, so the side
   edges stay solid and only the top and bottom fade. */
.legalPanel__panel {
  width: 91.53%;
  max-width: calc(var(--contentMax) * 0.9153);
  margin-inline: auto;
  padding: var(--space-7);
  border: 1px solid transparent;
  border-image: var(--gradient-line-1) 1;
}

/* 2976:4763 sets one 20px Golos Medium block and switches weight for the two
   headings inside it, so heading and body share a size and differ only in
   weight. Figma separates blocks with an empty line rather than a margin; at
   20/1.4 that reads as 28px, and --clamp-rem-24 is the nearest step. */
.legalPanel__heading {
  font-family: var(--font-body);
  font-weight: 700;
  font-size: var(--font-20);
  line-height: 1.4;
  color: var(--color-white);
  margin: 0 0 var(--clamp-rem-24);
}

.legalPanel__text {
  font-family: var(--font-body);
  font-weight: 500;
  font-size: var(--font-20);
  line-height: 1.4;
  color: var(--color-white);
  margin: 0 0 var(--clamp-rem-24);
  overflow-wrap: anywhere; /* LEG-01: long URLs break instead of widening the page */
}

/* A heading that follows body copy opens a new clause, so it gets the blank line
   above it that Figma shows between the last paragraph and "Nam Libero Tempore". */
.legalPanel__text + .legalPanel__heading {
  margin-top: var(--clamp-rem-24);
}

/* Two heading levels, Privacy Policy only. The 2026-09-21 policy is the first
   legal document here with Word "Heading 2" under "Heading 1" — 9 of them under
   13 — and the template's single 20px weight-700 heading cannot show that nesting.
   Scoped to the page modifier so the Terms page, whose 25 headings are all one
   level, keeps the template exactly as Figma drew it. The clause heading steps up
   one stop to 24; the sub-clause keeps the template's own 20/700. */
.legalPanel--privacyPolicy .legalPanel__heading {
  font-size: var(--font-24);
}

.legalPanel--privacyPolicy .legalPanel__subheading {
  font-family: var(--font-body);
  font-weight: 700;
  font-size: var(--font-20);
  line-height: 1.4;
  color: var(--color-white);
  margin: 0 0 var(--clamp-rem-24);
}

.legalPanel--privacyPolicy .legalPanel__text + .legalPanel__subheading {
  margin-top: var(--clamp-rem-24);
}

.legalPanel__panel > :last-child {
  margin-bottom: 0;
}

/* Lists and links exist only in the Privacy Policy, whose source is the live
   ecintl.com page rather than the Terms PDF. The Figma legal template has
   neither, so these extend it rather than reproduce it: the list matches the
   body copy exactly and only adds the marker and its indent. */
.legalPanel__list {
  margin: 0 0 var(--clamp-rem-24);
  padding-left: var(--clamp-rem-24);
  list-style: disc;
}

.legalPanel__listItem {
  font-family: var(--font-body);
  font-weight: 500;
  font-size: var(--font-20);
  line-height: 1.4;
  color: var(--color-white);
  margin: 0 0 var(--clamp-rem-12);
}

.legalPanel__listItem::marker {
  color: var(--color-brand-green);
}

.legalPanel__listItem:last-child {
  margin-bottom: 0;
}

/* The five links are all outbound opt-out tools. Underlined rather than given the
   brand ramp: inside a wall of legal copy an underline is what reads as a link,
   and a gradient would compete with the clause headings. */
.legalPanel__text a,
.legalPanel__listItem a {
  color: var(--color-brand-green);
  text-decoration: underline;
  text-underline-offset: 2px;
}

.legalPanel__text a:hover,
.legalPanel__listItem a:hover {
  color: var(--color-white);
}

/* --------------------------------------------------------------------------
   Supplier documents — Figma "Legal Template - Complex" 2980:4765
   -------------------------------------------------------------------------- */

/* Container 2980:4821: 96 above the link row, 64 between it and the accordion,
   120 below. Content is 1384 of 1512 and sits directly on the page — unlike the
   Basic template there is no bordered panel around it. */
.supplierDocuments {
  padding-block: var(--space-9) var(--space-10);
  padding-inline: 0;
  background: var(--color-black);
}

.supplierDocuments__links,
.supplierDocuments__list {
  width: 91.53%;
  max-width: calc(var(--contentMax) * 0.9153);
  margin-inline: auto;
}

.supplierDocuments__links {
  margin-bottom: var(--space-8);
}

/* Frame 448 is nine overlapping absolutely-positioned text nodes, so its gaps
   are not measurable design values — this is the wrapping row it stands for.
   Row rhythm is taken from the 16px label and its 19.25 line box. */
.supplierDocuments__linkList {
  display: flex;
  flex-wrap: wrap;
  gap: var(--clamp-rem-16) var(--space-6);
  list-style: none;
  margin: 0;
  padding: 0;
}

/* White at rest, green on hover — settled 2026-09-17. The underline is permanent
   rather than a hover reveal: Figma draws these as plain white text, which gives
   no signal they are in-page jumps, so the rule stays and only its colour moves
   with the text. */
.supplierDocuments__link {
  font-family: var(--font-body);
  font-size: var(--font-16);
  font-weight: 400;
  line-height: 1.2; /* Figma 19.25 on 16 */
  color: var(--color-white);
  text-decoration: none;
  border-bottom: 1px solid var(--color-white);
  transition: color 0.2s ease, border-color 0.2s ease;
}

.supplierDocuments__link:hover,
.supplierDocuments__link:focus-visible {
  color: var(--color-brand-green);
  border-bottom-color: var(--color-brand-green);
}

/* A row opened from a link is scrolled to by the handler in js/script.js;
   scroll-margin keeps it clear of the top of the viewport when it lands. */
.supplierDocuments__list .faqRow {
  scroll-margin-top: var(--space-8);
}

/* Supplier document bodies (tools/supplier-copy.py). The accordion answer was
   built for a single short paragraph; these carry whole legal documents — up to
   177 paragraphs — so the paragraphs need rhythm between them and the document's
   own title needs to read as a title. Scoped to this list so every other
   .faqRow__answer on the site is untouched. */
.supplierDocuments__list .faqRow__answer > p {
  margin: 0 0 var(--clamp-rem-16);
  max-width: 100%; /* was a 90ch measure; full width asked for 2026-09-17 */
}

.supplierDocuments__list .faqRow__answer > p:last-child {
  margin-bottom: 0;
}

.supplierDoc__title {
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.5px;
}

/* --------------------------------------------------------------------------
   The Right Tools — Figma Frame 258 (2982:6141), inside Frame 333
   -------------------------------------------------------------------------- */
.toolGrid {
  background: var(--color-black);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-8);
  padding-block: var(--space-8);
}

.toolGrid__intro {
  width: 91.53%;
  /* F1 2026-09-18: cap was calc(900px - (var(--gutter) * 2)). Converted to a --contentMax fraction so the
     multiplier matches the width, per the front-end skill's width rule.
     Reverse by restoring the value above. */
  max-width: calc(var(--contentMax) * 0.9153);
  text-align: center;
}

.toolGrid .sectionHeading {
  width: 18.75em;
  max-width: 100%;
}

/* 2982:6146 is 900 wide, the same measure as the heading above it — not the
   full 1384 of the intro container. Capped at the 2026-09-21 //br. px, not the
   heading's 18.75em: em resolves against this element's own 16px, not 48px. */
.toolGrid__intro .sectionLead {
  width: 900px;
  max-width: 100%;
  margin-bottom: 0;
}

/* Two rows of three 420-wide cards with a 24 gap, centred in the 1512 frame —
   so the row is not the usual 91.53% measure but 3*420 + 2*24 = 1308. */
.toolGrid__list {
  width: 91.53%;
  max-width: calc(var(--contentMax) * 0.9153);
  margin-inline: auto;
  padding-inline: 0;
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-5);
}

/* Three per row, not six: a `flex: 1 1 0` basis lets all six share one line and
   shrink under the 420 cap, which clips the ramped titles. The basis has to
   carry the third-of-a-row explicitly for the row to break. */
.toolCard {
  flex: 1 1 calc((100% - var(--space-5) * 2) / 3);
  min-width: 0;
  max-width: 420px;
  height: auto;
  min-height: 480px; /* Figma 2985:6265 */
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: var(--space-5);
  /* ENG-04: max pinned to the 1512 value. The card is capped at 420px, so a
     padding that kept growing ate the content box and clipped titles at 2560. */
  padding: clamp(24.25px, 3.21vw, 48.5px); /* was 48.5px; max was 97px */
  border: 1px solid var(--color-border-mid);
  border-image: var(--gradient-line-1) 1;
  overflow: hidden;
}

.toolCard__head {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}

/* 40px Golos Medium at line-height 1.1 — a tighter box than the 1.2 the rest of
   this page uses, and the ramp runs the whole title. */
.toolCard__title {
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-40);
  line-height: 1.1;
}

.toolCard__body {
  font-size: var(--font-24);
  line-height: 1.2;
  color: var(--color-white);
}

.toolCard__logos {
  padding-inline: 0;
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-5);
}

/* 3D CAD is the only card with a real grid of marks — 2 columns, 3 rows. */
.toolCard__logos--grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.toolCard__logoItem img {
  display: block;
  width: 100%;
  height: auto;
  max-height: 52px;
  object-fit: contain;
  object-position: left center;
}

/* ENG-03 TRIAL (2026-09-23) — 3D CAD logos sized to equal visible area
   (5600px2: visible height = sqrt(5600 / visible ratio), divided by the PNG's
   own transparent-padding fraction). CSS-only, keyed on the file name, so no
   markup changed in either build. TO REVERT: delete this whole block, down to
   "END ENG-03 TRIAL"; the rule above (width 100%, max-height 52px) takes over. */
.toolCard__logos--grid .toolCard__logoItem {
  container-type: inline-size;
}
/* Heights scale together once the slot is narrower than SolidWorks (165px at
   34px tall): each cqw value is its px height / 165 * 100. */
.toolCard__logos--grid .toolCard__logoItem img {
  width: auto;
  max-width: 100%;
}
.toolCard__logoItem img[src$="tool-catia.png"] { height: min(39px, 23.64cqw); }
.toolCard__logoItem img[src$="tool-ptc.png"] { height: min(51px, 30.91cqw); }
.toolCard__logoItem img[src$="tool-solidworks.png"] { height: min(34px, 20.61cqw); }
.toolCard__logoItem img[src$="tool-siemens-nx.png"] { height: min(51px, 30.91cqw); }
.toolCard__logoItem img[src$="tool-autodesk-inventor.png"] { height: min(37px, 22.42cqw); }
/* END ENG-03 TRIAL */

/* Marks Figma sizes explicitly rather than letting them fill the column. */
.toolCard__logoItem--ansys img {
  width: 120px;
}
.toolCard__logoItem--bluebeam img {
  width: 220px;
  max-height: 69px;
}
.toolCard__logoItem--cableteque img {
  width: 240px;
  max-height: 50px;
}

@media (max-width: 1200px) {
  .toolCard {
    flex-basis: calc((100% - var(--space-5)) / 2);
    flex-grow: 0;
  }
}

@media (max-width: 900px) {
  .toolCard {
    flex-basis: 100%;
    min-height: 0;
  }
}


/* ============================ ERROR PAGE (404) ============================
   No Figma layer — there is no 404 design. Built from parts already in the
   system so it cannot drift from the rest of the site: the legal hero, the
   standard section rhythm, and the existing .button. Deliberately minimal.
   ========================================================================= */

.errorPage {
  padding-block: var(--space-9) var(--space-10);
  background: var(--color-black);
}

.errorPage__inner {
  width: 91.53%;
  max-width: calc(var(--contentMax) * 0.9153);
  margin-inline: auto;
}

.errorPage__code {
  font-family: var(--font-body);
  font-weight: 700;
  font-size: var(--font-20);
  line-height: 1.4;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-white);
  margin: 0 0 var(--clamp-rem-16);
}

.errorPage__heading {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: var(--font-40);
  line-height: 1.2;
  color: var(--color-white);
  margin: 0 0 var(--clamp-rem-24);
}

.errorPage__text {
  font-family: var(--font-body);
  font-weight: 500;
  font-size: var(--font-20);
  line-height: 1.4;
  color: var(--color-white);
  margin: 0 0 var(--clamp-rem-32);
  /* Keeps the measure readable once the section is wider than a comfortable
     line length; the section itself stays full width. */
  max-width: calc(var(--contentMax) * 0.4);
}

.errorPage__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--clamp-rem-16);
}

/* Below the drawer breakpoint the two buttons stack and take the full column,
   which is what every other stacked call to action on the site does. */
@media (max-width: 600px) {
  .errorPage__actions .button {
    max-width: none;
    width: 100%;
  }
}

/* --------------------------------------------------------------------------
   CookieYes banner + preference centre — themed to the site. NOT in Figma
   (Sam, 2026-09-23). Colours live in the plugin's banner settings and arrive
   as inline styles (dark panel, white text, #40D39F links and toggles, button
   fills/borders transparent). This block adds what those settings cannot:
   the site fonts, the Line Gradient hairline, and the site's button treatment.
   Scoped under the plugin's own containers so it outranks its base CSS.
   -------------------------------------------------------------------------- */
.cky-consent-container,
.cky-modal {
  font-family: var(--font-body);
}

/* !important: the plugin injects its own CSS after ours at the same specificity
   (border: 1px solid; box-shadow), so a tie goes to it. */
.cky-consent-container .cky-consent-bar {
  border-width: 1px 0 0 !important;
  border-style: solid !important;
  border-image: var(--gradient-line-1) 1 !important; /* their border shorthand resets it */
  box-shadow: 0 -12px 30px 0 rgba(0, 0, 0, 0.35) !important;
}

.cky-consent-container .cky-title,
.cky-modal .cky-preference-title {
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--font-18);
  line-height: 1.2;
}

.cky-consent-container .cky-notice-des,
.cky-consent-container .cky-notice-des p,
.cky-modal .cky-preference-content-wrapper,
.cky-modal .cky-accordion-header-des {
  font-size: var(--font-14);
  line-height: 1.4;
}

.cky-consent-container .cky-policy {
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* Buttons: the site's .button — uppercase body type on a brand-gradient border */
.cky-consent-container .cky-btn,
.cky-modal .cky-btn {
  font-family: var(--font-body);
  font-weight: 500;
  font-size: var(--font-12);
  line-height: 1.2;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  padding: var(--clamp-rem-12) var(--clamp-rem-16);
  border: 1px solid transparent;
  border-image: var(--gradient-brand) 1;
  border-radius: 0;
  transition: background 0.2s ease;
}

.cky-consent-container .cky-btn:hover,
.cky-modal .cky-btn:hover {
  opacity: 1; /* the plugin fades hovered buttons to 0.8 */
}

/* Accept All = .button--primary: soft gradient fill, full brand ramp on hover */
.cky-consent-container .cky-btn-accept,
.cky-modal .cky-btn-accept {
  background-image: var(--gradient-button);
}

.cky-consent-container .cky-btn-accept:hover,
.cky-modal .cky-btn-accept:hover {
  background-image: var(--gradient-brand);
}

/* Reject / Customise / Save = .button--outline: clear until hovered */
.cky-consent-container .cky-btn-reject:hover,
.cky-consent-container .cky-btn-customize:hover,
.cky-modal .cky-btn-reject:hover,
.cky-modal .cky-btn-preferences:hover {
  background-image: var(--gradient-button);
}

.cky-modal .cky-preference-center {
  border-radius: 0;
  border: 1px solid transparent;
  border-image: var(--gradient-line-1) 1;
}

.cky-modal .cky-preference-header,
.cky-modal .cky-footer-wrapper,
.cky-modal .cky-accordion {
  border-color: #2a2a2a;
}

.cky-modal .cky-btn-close img,
.cky-consent-container .cky-banner-btn-close img {
  filter: invert(1); /* the plugin's close glyph is dark */
}


/* --------------------------------------------------------------------------
   Text reveal (Sam, 2026-09-24, after duxotwatches.com). js/text-reveal.js
   marks headings, eyebrows, hero copy and section leads as .textRevealItem;
   each fades up 24px as it enters the viewport, 0.12s apart when several
   arrive together. `translate` rather than `transform`, so nothing that
   already uses a transform is disturbed. html.textReveal is set by the inline
   head script (off for reduced motion, and removed after 3s if the JS fails).
   -------------------------------------------------------------------------- */
html.textReveal .textRevealItem:not(.revealDone) {
  transition:
    opacity 1.1s cubic-bezier(0.25, 1, 0.5, 1) var(--revealDelay, 0s),
    translate 1.1s cubic-bezier(0.25, 1, 0.5, 1) var(--revealDelay, 0s);
}

html.textReveal .textRevealItem:not(.isRevealed) {
  opacity: 0;
  translate: 0 24px;
}

/* Before the JS has tagged anything, hide the above-the-fold hero copy so it
   does not flash in and then fade. The 3s fallback in <head> lifts this. */
html.textReveal:not(.textRevealReady) :is(.hero__pill, .hero__title, .hero__subtitle, .hero__lede, .hero__kicker, .hero__actions, .careersHero__content > *) {
  opacity: 0;
}
