/*
Theme Name: Sight Power
Description: Sight Power marketing site design, on the Astra parent for WordPress compatibility.
Template: astra
Version: 1.0.0
*/

@import url('https://fonts.googleapis.com/css2?family=Manrope:wght@300;400;500;600;700;800&family=Koulen&family=Inria+Sans:ital,wght@0,400;1,300&display=swap');

:root {
  --sp-blue-900: rgb(3, 35, 84);
  --sp-blue-800: rgb(31, 72, 135);
  --sp-blue-700: rgb(50, 76, 142);
  --sp-blue-600: rgb(59, 109, 186);
  --sp-blue-500: rgb(21, 77, 162);
  --sp-blue-400: rgb(40, 124, 252);
  --sp-amber-500: rgb(255, 189, 94);
  --sp-amber-100: rgb(255, 219, 141);
  --sp-violet-500: rgb(151, 71, 255);
  --sp-ink: rgb(61, 61, 61);
  --sp-black: rgb(0, 0, 0);
  --sp-white: rgb(255, 255, 255);
  --sp-gray-050: rgb(246, 246, 246);
  --sp-gray-100: rgb(234, 234, 234);
  --sp-gray-150: rgb(227, 227, 227);
  --sp-gray-200: rgb(203, 203, 203);
  --sp-gray-250: rgb(185, 185, 185);
  --sp-gray-300: rgb(173, 173, 173);
  --sp-gray-350: rgb(166, 166, 166);
  --sp-gray-400: rgb(155, 155, 155);
  --sp-gray-450: rgb(150, 150, 150);
  --sp-gray-500: rgb(138, 138, 138);
  --sp-gray-550: rgb(120, 120, 120);
  --sp-gray-600: rgb(115, 115, 115);

  --text-body: var(--sp-ink);
  --text-heading: var(--sp-blue-500);
  --text-label: var(--sp-black);
  --text-inverse: var(--sp-white);
  --text-muted: var(--sp-gray-600);
  --text-link: var(--sp-blue-500);
  --text-link-hover: var(--sp-blue-400);

  --surface-page: var(--sp-white);
  --surface-section: var(--sp-gray-050);
  --surface-card: var(--sp-white);

  --border-default: var(--sp-gray-300);
  --border-accent: var(--sp-amber-500);

  --brand-primary: var(--sp-blue-500);
  --brand-accent: var(--sp-amber-500);
  --brand-accent-tertiary: var(--sp-violet-500);

  --cta-bg: var(--sp-amber-500);
  --cta-text: var(--sp-black);

  --font-display: "Koulen", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-body: "Manrope", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-accent-italic: "Inria Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;

  --display-2xl: 130px;
  --display-xl: 90px;
  --display-lg: 77px;
  --display-md: 35px;
  --display-sm: 24px;
  --display-xs: 23px;
  --display-2xs: 19px;

  --body-2xl: 60px;
  --body-xl: 53px;
  --body-lg: 43px;
  --body-md-2: 40px;
  --body-md: 28px;
  --body-base-lg: 26px;
  --body-base: 20px;
  --body-sm-lg: 18px;
  --body-sm: 16px;
  --body-xs: 14px;
  --body-2xs: 12px;

  --weight-display: 400;
  --weight-light: 300;
  --weight-regular: 400;
  --weight-medium: 500;
  --weight-semibold: 600;
  --weight-bold: 700;
  --weight-extrabold: 800;

  --leading-tight: 1.0;
  --leading-display: 1.01;
  --leading-snug: 1.1;
  --leading-normal: 1.15;
  --leading-relaxed: 1.27;
  --tracking-tight: -0.02em;

  --space-1: 6px; --space-2: 8px; --space-3: 10px; --space-4: 18px; --space-5: 20px;
  --space-6: 24px; --space-7: 30px; --space-8: 43px; --space-9: 44px; --space-10: 60px; --space-11: 66px;
  --space-page-x: 80px;
  --space-section-y: 88px;

  --radius-xs: 6px; --radius-sm: 8px; --radius-md: 10px; --radius-lg: 15px; --radius-pill: 100px;
  --border-width-hairline: 1px; --border-width-thick: 2px; --border-width-heavy: 8px;

  --page-max-width: 1440px;
  --content-max-width: 1280px;
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  margin: 0;
  background: var(--surface-page);
  font-family: var(--font-body);
  color: var(--text-body);
  font-weight: var(--weight-regular);
}
h1, h2, h3 { font-family: var(--font-display); font-weight: var(--weight-display); margin: 0; }
a { color: var(--text-link); text-decoration: none; }
a:hover { color: var(--text-link-hover); }
img { max-width: 100%; display: block; }
p { line-height: var(--leading-relaxed); }

.sp-fill {
  background: linear-gradient(160deg, var(--sp-gray-100), var(--sp-gray-050));
  border-radius: var(--radius-md);
  overflow: hidden;
}
.sp-fill img,
.sp-fill .elementor-widget-container,
.sp-fill .elementor-widget-container img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  border-radius: inherit;
}

/* Elementor migration: our own sections/columns already define their own
   max-width via an inner wrapper class (sp-header, sp-section-inner,
   sp-content-inner, sp-hero, etc.), so Elementor's default "boxed" 1140px
   cap on .elementor-container is redundant and, since our page/content max
   widths are wider (1280-1440px), was silently squishing every section. */
.elementor-section.elementor-section-boxed > .elementor-container {
  max-width: none;
}
.sp-header-logo-col.elementor-column { flex: 0 0 auto; width: auto; }
.sp-header-nav-col.elementor-column { flex: 1 1 auto; width: auto; min-width: 0; display: flex; justify-content: flex-end; }

/* Elementor migration: make Elementor's own column/section wrapper divs
   layout-transparent ONLY where explicitly marked, so a flex/grid CSS class
   (sp-collage, sp-card, etc.) can still treat its Elementor-rendered children
   as if they were direct children, matching the pre-Elementor markup. Never
   applied automatically -- only columns/sections we explicitly tag. */
.elementor-column.sp-flexthru > .elementor-element-populated,
.elementor-column.sp-flexthru > .elementor-element-populated > .elementor-widget-wrap,
.elementor-section.sp-flexthru > .elementor-container {
  display: contents;
}

/* Elementor's global "Space Between Widgets" kit setting adds a default
   margin-bottom to every non-last widget, which stacks on top of the
   sp-collage flex gap and doubles the spacing between collage images.
   Zero it out here so the flex gap is the only source of spacing. */
.sp-collage > .elementor-widget:not(:last-child),
.sp-collage .elementor-widget-wrap > .elementor-widget:not(:last-child),
.sp-collage-side-stack > .elementor-widget:not(:last-child),
.sp-collage-side-stack .elementor-widget-wrap > .elementor-widget:not(:last-child),
.sp-card > .elementor-widget:not(:last-child),
.sp-card .elementor-widget-wrap > .elementor-widget:not(:last-child) {
  margin-bottom: 0 !important;
}

/* Figma's 3 solution cards share one vertical rhythm: ~50px heading-to-image,
   44px image-to-text, ~20px text-to-button. The base flex gap only gives one
   uniform value, so add the extra as margin-top on the specific sibling that
   needs more room above it. */
.sp-collage-row { margin-top: 40px; }
.sp-collage .elementor-widget-text-editor { margin-top: 34px; }
.sp-collage .elementor-widget-html { margin-top: 10px; }
/* Card 1's collage has a 3rd standalone image below the 2-up row (unlike
   cards 2/3, which top out at one .sp-collage-side/.sp-fill block of
   393px); left at the base .sp-card .sp-fill height:393px it made card 1's
   whole image stack ~594px vs 393px for the others, pushing its "Discover"
   link far below the other two cards' links once .sp-cards stretches all
   three columns to match the tallest. Match the row tiles' own height so
   the total (191.5 + 10 gap + 191.5) lines back up with 393px. */
.elementor-element-1cbb38d.sp-fill { height: 191.5px; }
/* Pin each card's "Discover ..." link to the bottom of its (stretched,
   equal-height) column instead of following directly under the text with
   leftover blank space below it. */
.sp-card .elementor-widget-html { margin-top: auto; }
.sp-card:not(.sp-collage) > .elementor-widget-wrap > .sp-title-box + * {
  margin-top: 30px;
}
.sp-card:not(.sp-collage) .elementor-widget-text-editor { margin-top: 24px; }

.sp-footer-links .elementor-icon-list-icon { display: none; }
.sp-footer-links .elementor-icon-list-items { gap: 8px; }
.sp-footer-links .elementor-icon-list-item { margin: 0; }

.sp-nav .xpro-elementor-horizontal-navbar-nav { list-style: none; }

/* The plugin's own toggler CSS sets `background: 0 0`, which only resets
   background-position -- it never actually sets background-color to
   transparent, so the button falls back to the browser's native <button>
   face color (inconsistent contrast against its #2b2b2b icon depending on
   the visitor's OS/browser theme), and it defines no hover/focus state at
   all. Pin both explicitly here instead of relying on the browser default. */
.sp-nav .xpro-elementor-horizontal-menu-toggler {
  background-color: transparent;
  color: var(--sp-ink);
  border-radius: var(--radius-sm);
  transition: background-color 150ms ease, color 150ms ease;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
/* The plugin renders this as a FontAwesome fa-bars glyph, whose baked-in bar
   thickness/spacing is a squarer, thicker-barred icon than Figma's spec (a
   wide 22x19px icon with thin 2px bars, generous gaps). font-size can't fix
   that -- it scales the whole glyph uniformly, not the bar-to-gap ratio --
   so replace the glyph with a plain box-shadow-drawn bar icon at Figma's
   exact proportions instead. Same <button>/<i> elements, same toggle JS/
   collapse mechanism -- only the icon's own paint changes. */
.sp-nav .xpro-elementor-horizontal-menu-toggler i.fa-bars {
  font-size: 0;
  display: block;
  width: 22px;
  height: 2px;
  background-color: currentColor;
  box-shadow: 0 8.5px 0 currentColor, 0 -8.5px 0 currentColor;
}
.sp-nav .xpro-elementor-horizontal-menu-toggler:hover,
.sp-nav .xpro-elementor-horizontal-menu-toggler:focus-visible {
  background-color: var(--surface-section);
  color: var(--sp-blue-400);
}

/* Close button (shown inside the open off-canvas panel) matches the
   toggler's treatment above -- same transparent/ink-color resting state,
   same hover/focus highlight -- instead of the plugin's own filled
   #e8e8e8 circle, which read as a different, disconnected control. */
.sp-nav .xpro-elementor-horizontal-menu-close {
  background-color: transparent;
  color: var(--sp-ink);
  border-radius: var(--radius-sm);
  transition: background-color 150ms ease, color 150ms ease;
}
.sp-nav .xpro-elementor-horizontal-menu-close:hover,
.sp-nav .xpro-elementor-horizontal-menu-close:focus-visible {
  background-color: var(--surface-section);
  color: var(--sp-blue-400);
}

/* Elementor migration: one-off layout modifiers previously expressed as inline styles */
.sp-gap-66 { gap: 66px; }
.sp-gap-60 { display: flex; gap: 60px; flex-wrap: wrap; }
.sp-gap-30 { gap: 30px; }
.sp-gap-26 { display: flex; gap: 26px; flex-wrap: wrap; }
.sp-collage-about { flex: 1 1 320px; max-width: 676px; height: 425px; }
.sp-about-copy p, .sp-about-copy { flex: 1 1 320px; margin: 0; font-family: var(--font-body); font-size: var(--body-sm-lg); line-height: 1.5; color: var(--text-body); }
.sp-participation-heading, .sp-participation-heading h2 { margin: 0 0 12px; font-family: var(--font-body); font-weight: var(--weight-bold); font-size: var(--body-md-2); letter-spacing: var(--tracking-tight); color: var(--text-body); }
.sp-participation-copy p, .sp-participation-copy { margin: 0; font-family: var(--font-body); font-size: var(--body-sm-lg); color: var(--text-body); }
.sp-fill--brand {
  background: linear-gradient(135deg, var(--sp-blue-800), var(--sp-blue-500) 55%, var(--sp-blue-400));
}

.sp-header {
  width: 100%;
  max-width: var(--page-max-width);
  margin: 0 auto;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 20px var(--space-page-x);
  box-sizing: border-box;
  gap: 24px;
  flex-wrap: wrap;
}
.sp-logo img { width: 148px; height: 65px; object-fit: contain; }
.sp-nav {
  width: 100%;
  max-width: 996px;
  box-sizing: border-box;
}
.sp-nav .xpro-elementor-horizontal-navbar {
  width: 100%;
  height: 100%;
  display: flex;
  margin: 0;
  padding: 0;
}
.sp-nav a,
.sp-nav .xpro-elementor-horizontal-navbar-nav > li > a {
  font-family: var(--font-display);
  font-weight: var(--weight-display);
  font-size: var(--display-2xs);
  line-height: 100%;
  color: var(--text-body);
  transition: color 150ms ease;
}
.sp-nav li.current-menu-item > a,
.sp-nav .xpro-elementor-horizontal-navbar-nav > li.current-menu-item > a { color: var(--brand-primary); }
.sp-nav a:hover,
.sp-nav .xpro-elementor-horizontal-navbar-nav > li > a:hover { color: var(--text-link-hover); }

/* Desktop nav bar: the pill-shaped bar, fixed height and single-line nowrap
   layout only make sense above the widget's own "tablet" collapse breakpoint
   (1024px, matching responsive_show=tablet on the header's xpro-horizontal-menu
   widget). Below that the widget's own off-canvas panel/toggler CSS takes
   over completely; these rules must stay out of its way (esp. overflow/
   height/width on the wrapper it also uses for the fixed off-canvas panel)
   rather than fight its fixed positioning and sizing. */
/* Desktop pill nav only renders when .is-nav-collapsed is absent from
   .sp-header -- see nav-fit.js, which measures the nav's real content
   width against the space actually available next to the logo and adds
   that class the moment it stops fitting, rather than relying on a
   guessed fixed breakpoint. */
@media (min-width: 1025px) {
  .sp-header:not(.is-nav-collapsed) .sp-nav {
    height: 54px;
    border-radius: var(--radius-sm);
    background-color: var(--surface-section);
    overflow: hidden;
    display: flex;
    align-items: stretch;
  }
  .sp-header:not(.is-nav-collapsed) .sp-nav .xpro-elementor-horizontal-navbar-wrapper {
    width: 100%;
    height: 100%;
    display: flex;
    margin: 0;
    padding: 0;
  }
  .sp-header:not(.is-nav-collapsed) .sp-nav ul {
    list-style: none;
    margin: 0;
    display: flex;
    flex-wrap: nowrap;
    gap: 16px;
    justify-content: center;
    align-items: center;
    padding: 9px 24px;
    height: 100%;
    box-sizing: border-box;
  }
  .sp-header:not(.is-nav-collapsed) .sp-nav a,
  .sp-header:not(.is-nav-collapsed) .sp-nav .xpro-elementor-horizontal-navbar-nav > li > a {
    text-align: center;
    white-space: nowrap;
    padding: 0;
    margin: 0;
    min-width: 0;
  }
}

/* Forces the same off-canvas panel/toggler treatment the plugin's own CSS
   provides at <=1024px (xpro-responsive.css, hardcoded and not tied to
   Elementor's configurable breakpoints), but driven by .is-nav-collapsed
   instead of a viewport media query, so it also activates above 1024px
   whenever the nav genuinely doesn't fit next to the logo. Values mirror
   that plugin block so the two hand off without a visual seam. */
.sp-header.is-nav-collapsed .xpro-elementor-horizontal-menu-toggler-wrapper {
  display: block;
}
.sp-header.is-nav-collapsed .xpro-elementor-horizontal-navbar-wrapper {
  position: fixed;
  height: 100vh;
  width: 400px;
  max-width: 100%;
  right: 0;
  top: 0;
  text-align: right;
  background-color: #f5f5f5;
  padding: 30px;
  overflow: auto;
  z-index: 999;
  transform: translate3d(100%, 0, 0);
  transition: transform 0.5s;
}
.sp-header.is-nav-collapsed .xpro-elementor-horizontal-navbar-wrapper.active {
  transform: translate3d(0, 0, 0);
}
.sp-header.is-nav-collapsed .xpro-elementor-horizontal-menu-close {
  display: inline-flex;
}
.sp-header.is-nav-collapsed .xpro-elementor-horizontal-navbar-nav {
  flex-direction: column;
  align-items: flex-start;
  padding-top: 20px;
}
.sp-header.is-nav-collapsed .xpro-elementor-horizontal-navbar-nav > li {
  width: 100%;
}
.sp-header.is-nav-collapsed .xpro-elementor-horizontal-navbar-nav > li > a {
  width: 100%;
  padding: 20px 0;
  justify-content: flex-start;
  white-space: normal;
}

.sp-hero {
  position: relative;
  width: 100%;
  max-width: var(--content-max-width);
  margin: 0 auto;
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-sizing: border-box;
  padding: 56px 0 56px;
  display: flex;
  flex-direction: column;
  color: var(--text-inverse);
  background-size: cover;
  background-position: center;
}
.sp-hero-gif {
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center;
  opacity: 0.9;
  z-index: 0;
}
.sp-hero-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0.55;
  z-index: 0;
}
.sp-hero::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background-image:
    linear-gradient(245.94deg, rgba(0,0,0,0) 47.56%, rgba(0,0,0,0.42) 73.26%),
    linear-gradient(180deg, rgba(65,67,128,0.11) 0%, rgba(27,27,97,0.39) 100%);
}
.sp-hero-kicker, .sp-hero-body-wrap {
  position: relative;
  z-index: 2;
}
.sp-hero-kicker {
  text-align: center;
  padding: 0 20px;
  font-family: var(--font-display);
  font-weight: var(--weight-display);
  font-size: clamp(40px, 6vw, var(--display-2xl));
  line-height: 1;
  white-space: nowrap;
}
.sp-hero-body-wrap { display: flex; flex-direction: column; gap: 11px; padding: 40px 85px 0; }
.sp-hero-tint {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: none;
  pointer-events: none;
  background-image: linear-gradient(180deg, rgba(21, 77, 162, 0.55) 0%, rgba(3, 35, 84, 0.8) 100%);
}
.sp-hero-contact {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: none;
  flex-direction: column;
  padding: 40px 85px;
  box-sizing: border-box;
}
.sp-hero-contact-close {
  appearance: none;
  -webkit-appearance: none;
  -moz-appearance: none;
  position: absolute;
  top: 32px;
  right: 40px;
  width: 48px;
  height: 48px;
  min-width: 48px;
  min-height: 48px;
  max-width: 48px;
  max-height: 48px;
  box-sizing: border-box;
  margin: 0;
  padding: 0;
  font: inherit;
  line-height: 0;
  box-shadow: none;
  outline: none;
  border-radius: var(--radius-pill);
  border: 1.5px solid var(--sp-white);
  background: transparent;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  color: var(--sp-white);
  transition: background-color 150ms ease;
}
.sp-hero-contact-close:hover { background-color: rgba(255, 255, 255, 0.15); }
.sp-hero-contact-title {
  margin: 0 100px 32px 0;
  font-family: var(--font-body);
  font-weight: var(--weight-bold);
  font-size: var(--body-md-2);
  letter-spacing: var(--tracking-tight);
  color: var(--sp-white);
}
.sp-hero-contact-form { display: flex; flex-direction: column; gap: 24px; flex: 1; min-height: 0; }
.sp-hero-contact-row { display: flex; gap: 60px; flex-wrap: wrap; }
.sp-hero-contact-field {
  flex: 1 1 200px; display: flex; flex-direction: column; gap: 10px;
}
.sp-hero-contact-field span {
  font-family: var(--font-body); font-weight: var(--weight-bold); font-size: var(--body-sm); color: var(--sp-white);
}
.sp-hero-contact-field input {
  height: 44px; background: var(--sp-white); border: 1px solid var(--border-default); border-radius: var(--radius-sm);
  padding: 0 16px; font-family: var(--font-body); font-size: var(--body-sm-lg); color: var(--text-body);
  box-sizing: border-box; width: 100%;
}
.sp-hero-contact-field input:focus { outline: none; border-color: var(--brand-primary); }
.sp-hero-contact-message {
  display: flex; flex-direction: column; gap: 10px; flex: 1; min-height: 0;
}
.sp-hero-contact-message span {
  font-family: var(--font-body); font-weight: var(--weight-bold); font-size: var(--body-sm); color: var(--sp-white);
}
.sp-hero-contact-message textarea {
  flex: 1; min-height: 120px; resize: vertical; background: var(--sp-white); border: none; border-radius: var(--radius-md);
  padding: 18px 20px; font-family: var(--font-body); font-size: var(--body-sm-lg); color: var(--text-body);
  box-sizing: border-box; width: 100%;
}
.sp-hero-contact-message textarea:focus { outline: none; }
.sp-hero-contact-submit {
  align-self: flex-start;
  display: inline-flex; align-items: center; gap: 10px;
  border: none; border-radius: var(--radius-sm); background-color: var(--brand-primary); color: var(--sp-white);
  padding: 14px 24px; font-family: var(--font-body); font-weight: var(--weight-bold); font-size: var(--body-sm);
  letter-spacing: 0.02em; text-transform: uppercase; cursor: pointer; transition: background-color 150ms ease;
}
.sp-hero-contact-submit:hover { background-color: var(--sp-blue-400); }
.sp-hero-contact-submit:disabled { opacity: 0.6; cursor: not-allowed; }
.sp-form-error {
  margin: 0;
  font-family: var(--font-body);
  font-weight: var(--weight-medium);
  font-size: var(--body-sm);
  color: var(--sp-amber-500);
}
.sp-hero-contact .sp-form-error { margin-top: -8px; }
.sp-hero-contact-sent { position: relative; flex: 1; display: none; flex-direction: column; }
.sp-hero-sent-subtitle { margin: 0; font-family: var(--font-body); font-size: var(--body-sm-lg); color: var(--sp-white); }
.sp-hero-sent-graphic { position: absolute; right: 0; top: 50%; transform: translateY(-20%); width: 70%; max-width: 820px; }
.sp-hero-sent-graphic img { width: 100%; height: auto; display: block; }
.sp-hero-title-box {
  display: inline-flex;
  align-items: center;
  width: fit-content;
  max-width: 100%;
  padding: 0 10px;
  height: 61px;
  box-sizing: border-box;
  border-bottom: 2px solid var(--border-accent);
  margin-bottom: 19px;
  overflow: hidden;
}
.sp-hero-title-box span {
  font-family: var(--font-body);
  font-weight: var(--weight-bold);
  font-size: clamp(24px, 4.2vw, var(--body-lg));
  line-height: 1.15;
  color: var(--brand-accent);
  white-space: nowrap;
}
.sp-title-box {
  display: inline-flex;
  align-items: center;
  justify-content: flex-start;
  width: fit-content;
  padding: 0 10px;
  height: 61px;
  box-sizing: border-box;
  border-bottom: 2px solid var(--border-accent);
}
.sp-title-box span {
  font-family: var(--font-display);
  font-size: var(--display-xs);
  line-height: 100%;
  color: var(--sp-black);
  white-space: nowrap;
}
.sp-title-box--lg {
  justify-content: center;
  width: 100%;
  padding: 0 0 25px 0;
  height: auto;
  border-bottom: 8px solid var(--border-accent);
}
.sp-title-box--lg span {
  font-family: var(--font-display);
  font-size: var(--display-xl);
  color: var(--sp-black);
  line-height: 100%;
}
.sp-hero-body {
  margin: 0;
  max-width: 904px;
  font-family: var(--font-body);
  font-weight: var(--weight-medium);
  font-size: var(--body-base-lg);
  line-height: 1.18;
  min-height: calc(1.18em * 4);
}
.sp-hero-controls { display: flex; gap: 21px; margin-top: 20px; }
.sp-arrow-btn {
  appearance: none;
  -webkit-appearance: none;
  -moz-appearance: none;
  box-sizing: border-box;
  width: 44px; height: 44px; min-width: 44px; min-height: 44px; max-width: 44px; max-height: 44px;
  border-radius: 50%;
  border: 1.5px solid var(--brand-accent) !important;
  background: transparent !important;
  color: var(--brand-accent) !important;
  padding: 0; margin: 0; font: inherit; line-height: 0; box-shadow: none; outline: none;
  display: inline-flex; align-items: center; justify-content: center; flex: 0 0 auto;
  cursor: pointer;
}
.sp-arrow-btn svg { display: block; width: 16px; height: 12px; flex-shrink: 0; }
.sp-arrow-btn svg path { stroke: currentColor !important; }
.sp-arrow-btn:hover { background: var(--brand-accent) !important; color: var(--sp-black) !important; }
.sp-hero-cta { margin-top: 12px; }
.sp-cta {
  display: inline-flex; align-items: center; justify-content: center;
  width: 228px; height: 72px;
  border-radius: var(--radius-md);
  background-color: var(--cta-bg);
  border: none;
  font-family: var(--font-display);
  font-weight: var(--weight-display);
  font-size: var(--display-sm);
  color: var(--cta-text);
  cursor: pointer;
  transition: filter 150ms ease, transform 100ms ease;
}
.sp-cta:hover { filter: brightness(0.93); color: var(--cta-text); }
.sp-cta:active { transform: scale(0.98); }
.sp-cta--small { width: 170px; height: 54px; font-size: 18px; }

.sp-discover {
  display: inline-flex; align-items: center; gap: 7px;
  font-family: var(--font-body);
  font-weight: var(--weight-medium);
  font-size: var(--body-sm);
  color: var(--brand-primary);
  white-space: nowrap;
  transition: color 150ms ease;
}
.sp-discover svg path { stroke: var(--brand-primary); transition: stroke 150ms ease; }
/* Figma's "Download" component (About page) defines Default/Hover variants
   for this exact text+chevron pattern -- both just swap brand-primary
   (sp-blue-500) for sp-blue-400 on hover, the same shift every other CTA
   on the site already uses (.sp-cta, .sp-btn, .sp-hero-contact-submit).
   This link/button had no :hover rule at all, so it read as inert/static
   next to those. */
.sp-discover:hover { color: var(--sp-blue-400); }
.sp-discover:hover svg path { stroke: var(--sp-blue-400); }
/* .sp-discover is also used as a real <button> for the About page's
   "Show More" resource-cards toggle (previously an inert, unstyled <span>
   with no click handler) -- reset the browser's default button chrome so
   it reads identically to the .sp-discover <a> links elsewhere. */
.sp-discover-toggle {
  appearance: none !important; -webkit-appearance: none !important; -moz-appearance: none !important;
  background: none !important; border: none !important; border-radius: 0 !important;
  box-shadow: none !important; text-shadow: none !important;
  padding: 0 !important; margin: 0; cursor: pointer;
  font: inherit; color: var(--brand-primary) !important;
  outline: none;
}
.sp-discover-toggle:hover { color: var(--sp-blue-400) !important; }
.sp-discover-toggle:focus-visible { outline: 2px solid var(--brand-primary); outline-offset: 2px; }
.sp-discover-chevron { transition: transform 200ms ease; }
.sp-discover-toggle.is-open .sp-discover-chevron { transform: rotate(180deg); }
/* The 3 "more" cards are now individual .sp-resource-card items inside the
   SAME .sp-resource-grid as the visible 4 (not a separate wrapping grid --
   that was wrapping to its own independent row instead of continuing the
   same flex-wrap sequence, stranding the 4th visible card alone with a big
   gap when only 3 fit per row). Browsers' UA stylesheet sets
   [hidden]{display:none}, but that's lower priority than any author rule,
   so .sp-resource-card's own display:flex would otherwise win and show it
   anyway -- restate display:none here to actually hide it. */
.sp-resource-card[hidden] { display: none; }

.sp-section { width: 100%; box-sizing: border-box; padding: var(--space-section-y) var(--space-page-x); }
.sp-section--tinted { background-color: var(--surface-section); }
/* Missing width:100% meant this was a shrink-to-fit flex item (Elementor's
   .elementor-container child, no flex-grow), sized to whatever its content's
   own intrinsic/preferred width happened to be rather than actually
   stretching out to the max-width cap -- so two sections using the exact
   same .sp-section-inner wrapper could render at very different widths
   depending on how wide their content naturally wanted to be (e.g. About
   page: the resource-card row's 4 wrapped cards pushed it close to the cap,
   while the contact form's percentage-width children gave it nothing to
   shrink-fit against, so it collapsed to roughly the heading's width
   instead). Force it to actually reach the cap every time. */
.sp-section-inner { width: 100%; max-width: var(--content-max-width); margin: 0 auto; display: flex; flex-direction: column; gap: 43px; box-sizing: border-box; }

.sp-solutions-row { display: flex; gap: 60px; flex-wrap: wrap; }
.sp-solutions-row > span, .sp-solutions-row > .elementor-widget { flex: 1 1 300px; }
.sp-row-col { flex: 1 1 300px; min-width: 0; }
.sp-eyebrow { font-family: var(--font-display); font-size: var(--display-lg); line-height: var(--leading-display); color: var(--brand-primary); }
.sp-lead { font-family: var(--font-body); font-size: var(--body-sm-lg); line-height: 1.5; color: var(--text-body); }
.sp-cards { display: flex; gap: 24px; flex-wrap: wrap; }
.sp-card { flex: 1 1 260px; display: flex; flex-direction: column; gap: 20px; }
.sp-card .sp-fill { height: 393px; }
.sp-card p { margin: 0; font-family: var(--font-body); font-weight: var(--weight-semibold); font-size: var(--body-sm-lg); color: var(--text-body); }

/* "Benefits for the Client" section (Home, 162): the illustration image
   pairs visually with the "Converting data into money!" line at the very
   end of the long 10-item checklist, not the block as a whole -- with the
   row now top-aligned (see .sp-content-inner align-items above) the image
   would float far above that line instead of sitting next to it, so anchor
   just this column to the bottom of the row instead. */
.elementor-element-a098c1b { align-self: flex-end; }

.sp-feature-block {
  display: flex;
  flex-direction: column;
  /* .sp-section-inner (the cards/solutions-row sections) caps at
     content-max-width and centers; this sibling pattern had no such cap, so
     its wider content drifted outward from the section above/below it
     (visible as the two edges no longer sharing a left/right line). */
  max-width: var(--content-max-width);
  margin: 0 auto;
  width: 100%;
}
.sp-feature-block--reverse .sp-feature-inner { flex-direction: row-reverse; }
.sp-feature-eyebrow {
  display: flex; justify-content: space-between; align-items: center;
  border-bottom: 2.5px solid var(--sp-gray-200);
  padding-bottom: 20px; margin-bottom: 40px;
  font-family: var(--font-body); font-weight: var(--weight-bold); font-size: var(--body-sm); color: var(--text-body);
}
.sp-feature-inner { display: flex; gap: 60px; align-items: flex-start; flex-wrap: wrap; }
.sp-feature-col { flex: 1 1 320px; min-width: 0; }
.sp-feature-inner p { flex: 1 1 320px; margin: 0; font-family: var(--font-body); font-size: var(--body-sm-lg); line-height: 1.5; color: var(--text-body); }
.sp-feature-inner .sp-fill { flex: 1 1 320px; align-self: stretch; min-height: 320px; }

.sp-collage { display: flex; flex-direction: column; gap: 10px; }
.sp-collage-row { display: flex; gap: 10px; flex: 0 0 auto; }
.sp-collage .sp-fill { flex: 1; }

.sp-collage-side { display: flex; gap: 10px; height: 393px; }
.sp-collage-side .sp-fill { flex: 1; }
/* The Mineshaft Inspection home teaser's lone left-side image column never
   got an explicit flex-basis class (unlike .sp-collage-side-stack on its
   sibling), so with the default Elementor flex-basis:auto/flex-grow:0 it
   sized to the image's raw intrinsic width instead of sharing the row 50/50
   -- squeezing the sibling (flex:1, flex-basis:0%) column to 0 width, and
   collapsing this column's own height to 0 since nothing constrained it.
   Same root cause as the documented column_size+gap+flex-wrap bug in
   [[project_sightpower_sitewide_task]]: an Elementor column with no explicit
   flex sizing is unreliable next to one that has it. :not() (not a plain
   child combinator -- sp-flexthru's .elementor-container is display:contents
   and sits between .sp-collage-side and its columns) targets whichever
   column ISN'T the stack, so this doesn't need the column's own
   _elementor_data touched. */
.sp-collage-side .elementor-column:not(.sp-collage-side-stack) {
  flex: 1 1 0%;
  min-width: 0;
}
.sp-collage-side .elementor-column:not(.sp-collage-side-stack) .elementor-widget-wrap,
.sp-collage-side .elementor-column:not(.sp-collage-side-stack) .sp-fill {
  height: 100%;
}
.sp-collage-side-stack { flex: 1; display: flex; flex-direction: column; gap: 10px; }
.sp-collage-side-stack .sp-fill { flex: 1; }
.sp-collage-row .sp-fill { height: 191.5px; }
.sp-collage-side-stack .sp-fill { flex: 0 0 191.5px; height: 191.5px; }
.sp-fill.sp-collage-bottom { flex: 0 0 191.5px; height: 191.5px; }

/* About page (285) "Our Participation" preview row: Elementor's own
   column-gap-default class relies on 10px padding on each column's
   .elementor-element-populated wrapper for the visual gap between the 3
   event photos, but .sp-flexthru (needed here so .sp-block-card's own flex
   column treats the image/caption as direct children) turns that same
   wrapper into display:contents, which drops the padding entirely -- the
   cards end up touching edge to edge. Put the gap back explicitly on the
   row's own flex container instead of relying on Elementor's padding trick. */
.elementor-element-bf8e0da > .elementor-container { gap: 24px; }
.sp-block-card { width: 100%; max-width: 409px; border-radius: var(--radius-sm); background-color: var(--surface-section); display: flex; flex-direction: column; gap: 19px; padding-bottom: 18px; box-sizing: border-box; }
/* A fixed 240px height stayed constant while the card's own width shrank
   from the 409px desktop max-width down to the mobile viewport, so the
   effective crop got progressively tighter/taller at small widths and cut
   into the photos (a head/shoulder at the frame edge on mobile, per the
   Edits.docx mobile screenshot) -- aspect-ratio keeps the same crop
   proportions (409:240, unchanged at desktop) at any width instead. */
.sp-block-card .sp-fill { aspect-ratio: 409 / 240; height: auto; border-radius: var(--radius-sm) var(--radius-sm) 0 0; }
.sp-block-card p { margin: 0; padding: 0 18px; font-family: var(--font-body); font-weight: var(--weight-semibold); font-size: var(--body-sm-lg); line-height: 24px; color: var(--text-body); text-align: center; }

.sp-contact { background-color: var(--surface-section); padding: var(--space-section-y) var(--space-page-x); box-sizing: border-box; width: 100%; }
.sp-contact h3 { margin: 0 0 30px; font-family: var(--font-body); font-weight: var(--weight-bold); font-size: var(--body-md-2); letter-spacing: var(--tracking-tight); color: var(--text-body); }
/* Was capped at 640px, leaving the textarea (and the row above it)
   noticeably narrower than the rest of the page's content column --
   stretch to fill the available width like every other content block. */
.sp-contact-form { display: flex; flex-direction: column; gap: 24px; max-width: 100%; width: 100%; }
.sp-contact-row { display: flex; gap: 24px; flex-wrap: wrap; }
.sp-contact-form input, .sp-contact-form textarea {
  height: 44px; border-radius: var(--radius-sm); border: 1px solid var(--border-default);
  padding: 0 16px; font-family: var(--font-body); font-size: var(--body-sm); color: var(--text-body);
  box-sizing: border-box; width: 100%;
}
.sp-contact-form input::placeholder, .sp-contact-form textarea::placeholder { color: var(--text-muted); }
.sp-contact-form textarea { height: auto; padding: 16px; resize: vertical; }
.sp-contact-form button {
  align-self: flex-start;
  height: 54px; padding: 0 24px; border-radius: var(--radius-md); border: none;
  background-color: var(--cta-bg) !important; color: var(--cta-text) !important; font-family: var(--font-display); font-size: 18px; font-weight: var(--weight-bold); cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center; gap: 8px; white-space: nowrap;
}
.sp-contact-sent { font-family: var(--font-body); font-size: var(--body-sm-lg); color: var(--text-body); display: none; }
.sp-contact-field { display: flex; flex-direction: column; gap: 10px; flex: 1 1 200px; }
.sp-contact-field span, .sp-contact-message span { font-family: var(--font-body); font-weight: var(--weight-bold); font-size: var(--body-sm); color: var(--text-body); }
.sp-contact-message { display: flex; flex-direction: column; gap: 10px; }

/* Figma's "Docs" grid (About component, node 2188:4046) specs: 26px gap
   between cards, each card a static 300.5x265 box (19px icon-to-text gap,
   20px padding) -- flex:1 1 220px let cards grow to fill the row's leftover
   width instead of staying that fixed size, stretching noticeably wider
   than Figma once there were only 3-4 per row. min-height (not a hard
   height) keeps the 265px look for short titles while still letting the
   longer ones (e.g. "AR/XR Extension to SightPower Mineshaft Inspection
   Automated System") wrap without clipping -- Figma itself overrides those
   specific card instances to hug-content height for the same reason. */
.sp-resource-grid { display: flex; gap: 26px; flex-wrap: wrap; }
.sp-resource-card {
  flex: 0 1 303px; width: 303px; max-width: 100%; box-sizing: border-box;
  border: 1px solid var(--border-default); border-radius: 8.5px;
  padding: 24px; display: flex; flex-direction: column; justify-content: flex-start; gap: 19px; min-height: 267px;
  text-decoration: none; color: inherit;
  transition: border-color 150ms ease;
}
.sp-resource-card:hover { border-color: var(--brand-primary); }
/* tile.svg has a 1px rule spanning nearly the full card width (x:1-301.5
   of 303, i.e. edge-to-edge inside the card's own border) separating the
   icon zone from the title -- breaks out of the card's 24px padding via
   negative margins since there was no such divider in the markup at all. */
.sp-resource-divider { display: block; height: 1px; background-color: var(--border-default); margin: 0 -24px; }
/* Figma keeps the icon-to-title gap fixed at 19px regardless of card
   height, with any leftover vertical room living below the title instead --
   space-between was stretching that same slack into the icon/title gap on
   short-title cards, making the icon look bigger/lower than Figma's spec. */
/* Figma sizes this icon at ~98x110 (roughly a third of the 303px card
   width) and centers it above the left-aligned title -- the old 48px width
   plus the default block left-alignment made it read as a small, oddly
   placed corner icon instead of the large centered mark Figma shows. */
.sp-resource-card img { width: 98px; height: auto; display: block; align-self: center; }
/* Figma's title text node (master "Block" component, node 2188:4016):
   18px, Manrope SemiBold, 24px fixed line-height -- was using body-sm
   (16px) at medium (500) weight with default line-height. */
.sp-resource-card p { margin: 0; font-family: var(--font-body); font-weight: var(--weight-semibold); font-size: 18px; line-height: 24px; color: var(--text-body); }

@media (max-width: 600px) {
  /* About's mobile resource cards: Figma specs a 15px gap between cards
     (not the unscoped 24px) and ~20px card padding with a 19px icon-to-text
     gap (not 24px/40px) -- confirmed via the .fig source (site_new.grida1,
     node 2953:3969 'Docs' children). */
  .sp-resource-grid { gap: 15px; }
  .sp-resource-card { padding: 20px; gap: 19px; min-height: 0; }
}

.sp-footer { width: 100%; background-color: var(--surface-section); border-top: 1px solid var(--border-default); box-sizing: border-box; }
/* Same width-cap fix as .sp-footer-cols/.sp-header: this band's border-
   bottom spans the element's own box, and with no max-width that box was
   the full .sp-footer width, so above page-max-width viewports the
   underline ran wider than the (now-capped) columns beneath it instead of
   sharing their edges. */
.sp-footer-band { border-bottom: 1px solid var(--border-default); padding: 50px 10px; display: flex; justify-content: center; width: 100%; max-width: var(--page-max-width); margin: 0 auto; box-sizing: border-box; }
.sp-footer-band span { font-family: var(--font-display); font-weight: var(--weight-display); font-size: clamp(24px, 6.5vw, var(--display-xl)); line-height: 1.1; color: var(--text-body); white-space: nowrap; text-align: center; }
/* Same pattern as the .sp-content-section/.sp-content-inner combo fixed
   elsewhere: padding and the row's own width live on the same element with
   no separate max-width cap, so above ~1600px viewports (page-max-width +
   2x page-x padding) the footer's columns run wider than every other
   section's content column above it and stop lining up on the left/right
   edges. Cap at page-max-width so, after the 80px padding on each side is
   subtracted, the actual column content lands at content-max-width --
   exactly like every .sp-section-inner-based section. */
.sp-footer-cols { display: flex; gap: 80px; padding: 60px var(--space-page-x); box-sizing: border-box; flex-wrap: wrap; width: 100%; max-width: var(--page-max-width); margin: 0 auto; }
.sp-footer-col1 { flex: 1 1 400px; display: flex; flex-direction: column; justify-content: space-between; gap: 24px; }
.sp-footer-tagline { font-family: var(--font-body); font-size: var(--body-xl); letter-spacing: var(--tracking-tight); line-height: 1.27; color: var(--text-body); }
.sp-footer-copy { font-family: var(--font-body); font-size: var(--body-xs); letter-spacing: var(--tracking-tight); color: var(--text-body); }
.sp-footer-col2 { flex: 2 1 500px; display: flex; justify-content: space-between; gap: 40px; flex-wrap: wrap; }
.sp-footer-links { display: flex; flex-direction: column; gap: 8px; }
.sp-footer-links a { font-family: var(--font-body); font-weight: var(--weight-medium); font-size: var(--body-sm); color: var(--text-body); }
.sp-footer-links a:hover { color: var(--text-link-hover); }
.sp-footer-offices { display: flex; flex-direction: column; justify-content: space-between; gap: 24px; }
.sp-footer-offices div { font-family: var(--font-body); font-size: var(--body-2xs); color: var(--text-body); line-height: 1.6; }
.sp-footer-email { font-family: var(--font-body); font-weight: var(--weight-medium); font-size: var(--body-2xs); color: var(--text-body); }
.sp-footer-social { display: flex; gap: 8px; }
.sp-social { width: 27px; height: 27px; border-radius: 8px; display: inline-flex; align-items: center; justify-content: center; }
.sp-footer-arrow-wrap { display: flex; align-items: flex-end; }
.sp-back-to-top {
  width: 85px; height: 85px; border-radius: var(--radius-pill); border: none; cursor: pointer;
  background-color: var(--brand-primary); display: inline-flex; align-items: center; justify-content: center;
  transition: background-color 150ms ease;
}
.sp-back-to-top:hover { background-color: var(--sp-blue-400); }

.sp-basic-page { max-width: var(--content-max-width); margin: 0 auto; padding: var(--space-section-y) var(--space-page-x); box-sizing: border-box; }
.sp-basic-page h1 { font-family: var(--font-display); font-size: var(--display-lg); color: var(--brand-primary); margin-bottom: 24px; }
.sp-basic-page .entry-content { font-family: var(--font-body); font-size: var(--body-sm-lg); line-height: 1.6; color: var(--text-body); }
.sp-basic-page .entry-meta { font-family: var(--font-body); font-size: var(--body-sm); color: var(--text-muted); margin-bottom: 12px; }

.sp-heading-md { margin: 0; font-family: var(--font-body); font-weight: var(--weight-bold); font-size: var(--body-md); line-height: 1.25; letter-spacing: var(--tracking-tight); color: var(--text-body); }

.sp-content-section { width: 100%; box-sizing: border-box; padding: 86px var(--space-page-x); }
.sp-content-section--tinted { background-color: var(--surface-section); }
/* Secondary pages (Solutions, Technology, Expertise & Advisory, Digital
   Mine, Mineshaft Inspection, Smart City, Our Participation) put both
   .sp-content-section (padding + tint) and .sp-content-inner (max-width:
   content-max-width + margin:auto centering) on the SAME element. Home's
   equivalent sections split these across two nested elements instead
   (.sp-section, full-bleed padding/background, wrapping .sp-section-inner,
   which centers at content-max-width) -- collapsing both roles onto one
   box means the max-width caps the padding-box itself, so the tinted
   background stops ~content-max-width wide instead of reaching the
   viewport edge like Home's sections do, AND the padding then eats into
   that already-capped box, leaving less room for the actual content than
   Home gets (content-max-width minus 2x padding, instead of up to the full
   content-max-width). Bump the cap to page-max-width (content-max-width +
   the two page-x paddings that get consumed) so the inner content column
   ends up content-max-width wide like Home, and full-bleed the tint via a
   viewport-wide pseudo-element so the background matches too. */
.sp-content-section.sp-content-inner { max-width: var(--page-max-width); position: relative; }
.sp-content-section.sp-content-inner.sp-content-section--tinted::before {
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  left: 50%;
  width: 100vw;
  transform: translateX(-50%);
  background-color: var(--surface-section);
  z-index: -1;
}
.sp-content-inner { width: 100%; box-sizing: border-box; max-width: var(--content-max-width); margin: 0 auto; display: flex; gap: 60px; align-items: flex-start; flex-wrap: wrap; }
.sp-content-inner--reverse { flex-direction: row-reverse; }
.sp-content-text { flex: 1 1 320px; display: flex; flex-direction: column; gap: 30px; }
/* Same double-spacing bug the mobile .sp-lead rules below document (Elementor's
   own margin-bottom on the widget PLUS the inner <p>'s ~1.75em margin both
   stack on top of this container's flex `gap`), but here at desktop width,
   most visible on Mineshaft Inspection's 8 stacked .sp-lead requirement
   blurbs under "Major Technical Requirements" -- each short one-liner ended
   up ~68px apart (30 gap + two uncancelled paragraph margins) instead of the
   intended 30px rhythm. Unlike the mobile .sp-lead + .sp-lead rules further
   down, these are genuinely distinct list items (not one Figma text node
   split across widgets), so just cancel the double margin -- do not zero the
   gap between them. */
.sp-content-text .sp-lead { margin-bottom: 0; }
.sp-content-text .sp-lead p { margin: 0; }
.sp-content-hero { display: flex; flex-direction: column; gap: 9px; }
.sp-content-image { flex: 1 1 320px; align-self: stretch; min-height: 340px; }

.sp-participation-hero-inner { width: 100%; box-sizing: border-box; max-width: var(--content-max-width); margin: 0 auto; display: flex; gap: 60px; align-items: center; flex-wrap: wrap; }
.sp-participation-hero-text { flex: 1 1 320px; display: flex; flex-direction: column; gap: 30px; }
.sp-participation-hero-image { flex: 1 1 320px; height: 400px; border-radius: var(--radius-xs); }
.sp-timeline-item { width: 100%; border-top: 1px solid var(--border-default); box-sizing: border-box; padding: 60px var(--space-page-x); }
.sp-timeline-inner { width: 100%; box-sizing: border-box; max-width: var(--content-max-width); margin: 0 auto; display: flex; gap: 60px; align-items: flex-start; flex-wrap: wrap; }
.sp-timeline-image { flex: 1 1 320px; align-self: stretch; min-height: 320px; }
.sp-timeline-text { flex: 1 1 320px; display: flex; flex-direction: column; gap: 20px; }
.sp-timeline-inner .elementor-column:has(.sp-timeline-image),
.sp-timeline-inner .elementor-column:has(.sp-timeline-text) { flex: 1 1 320px; min-width: 0; }

/* Interactive tab component ("Comprehensive Digital Mine System" family --
   used on the Solutions page as "Solutions Built on Mine Advisor" tabs).
   Panels reuse .sp-content-section / .sp-content-inner / .sp-content-text /
   .sp-content-image / .sp-fill / .sp-lead already established for every
   other alternating text/image section on the site. */
.sp-tabs { width: 100%; }
.sp-tabs-nav { width: 100%; background-color: var(--surface-page); box-sizing: border-box; }
.sp-tabs-nav-inner {
  max-width: var(--content-max-width);
  margin: 0 auto;
  display: flex;
  padding: 30px var(--space-page-x) 0;
  box-sizing: border-box;
}
.sp-tabs-tab {
  appearance: none; -webkit-appearance: none; -moz-appearance: none;
  flex: 1 1 0; min-width: 0;
  background: transparent !important; border: none !important; border-radius: 0 !important;
  box-shadow: none !important; cursor: pointer;
  padding: 0 10px 16px !important; margin: 0; font: inherit;
  display: flex; justify-content: center;
}
.sp-tabs-tab-label {
  font-family: var(--font-body); font-weight: var(--weight-semibold);
  font-size: var(--body-sm-lg); line-height: 1.3; text-align: center;
  color: var(--sp-gray-600);
  transition: color 150ms ease;
}
.sp-tabs-tab.is-active .sp-tabs-tab-label { font-weight: var(--weight-bold); color: var(--text-body); }
.sp-tabs-track {
  position: relative;
  max-width: var(--content-max-width);
  margin: 0 auto;
  height: 5px;
  background-color: var(--sp-gray-200);
}
/* Track indicator width/position were hardcoded for exactly 3 tabs (33.33%
   segments at 0/33.33/66.67%) -- correct for Solutions/Digital Mine/
   Expertise & Advisory (3 tabs each) but Mineshaft Inspection only has 2
   tabs, so its indicator was stuck at one-third width and never reached the
   second tab's full span. Drive both from --sp-tabs-count/--sp-tabs-index
   custom properties (set by the shared tab script below, on init and on
   each click) so this works for any tab count instead of assuming 3. */
.sp-tabs-track::before {
  content: ''; position: absolute; top: 0;
  width: calc(100% / var(--sp-tabs-count, 3));
  left: calc((100% / var(--sp-tabs-count, 3)) * var(--sp-tabs-index, 0));
  height: 100%;
  background-color: var(--brand-primary);
  transition: left 200ms ease;
}
.sp-tabs-track::after {
  content: ''; position: absolute; top: -13px;
  left: calc((100% / var(--sp-tabs-count, 3)) * (var(--sp-tabs-index, 0) + 0.5) - 12px);
  width: 0; height: 0;
  border-left: 12px solid transparent;
  border-right: 12px solid transparent;
  border-bottom: 13px solid var(--brand-primary);
  transition: left 200ms ease;
}
.sp-tabs-panel { display: none; }
.sp-tabs-nav-toggle {
  display: none;
  width: 100%;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  background: var(--surface-page) !important;
  border: none !important;
  border-radius: 0 !important;
  box-shadow: none !important;
  cursor: pointer;
  padding: 18px var(--space-page-x) !important;
  margin: 0;
  font: inherit;
  box-sizing: border-box;
}
.sp-tabs-nav-toggle-label {
  font-family: var(--font-body);
  font-weight: var(--weight-bold);
  font-size: var(--body-sm-lg);
  color: var(--text-body) !important;
  text-align: left;
  line-height: 1.3;
}
.sp-tabs-nav-toggle-icon {
  display: inline-flex;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 22px;
  height: 16px;
  flex: 0 0 auto;
}
.sp-tabs-nav-toggle-icon span {
  display: block;
  width: 100%;
  height: 2px;
  background-color: var(--brand-primary);
  transition: transform 150ms ease, opacity 150ms ease;
}
.sp-tabs-nav.is-open .sp-tabs-nav-toggle-icon span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.sp-tabs-nav.is-open .sp-tabs-nav-toggle-icon span:nth-child(2) { opacity: 0; }
.sp-tabs-nav.is-open .sp-tabs-nav-toggle-icon span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

.sp-tabs-panel.is-active { display: block; }
.sp-content-inner--stacked { flex-direction: column; align-items: stretch; }
.sp-content-inner--stacked .sp-content-text { flex: none; text-align: center; max-width: 900px; margin: 0 auto; }
.sp-content-inner--stacked .sp-content-image { flex: none; min-height: 0; aspect-ratio: 1680 / 920; align-self: stretch; }


/* Feature-block image collages (Digital Mine / Mineshaft Inspection) need to
   stretch to match the text column's height, same as a lone .sp-fill already
   does via .sp-feature-inner .sp-fill -- extending that rule to the collage
   wrappers keeps new multi-image feature sections visually consistent with
   the existing single-image ones instead of collapsing to content height. */
.sp-feature-inner .sp-collage,
.sp-feature-inner .sp-collage-side,
.sp-content-inner .sp-collage,
.sp-content-inner .sp-collage-side { flex: 1 1 320px; align-self: stretch; min-height: 320px; }

/* Bug: .sp-feature-inner .sp-fill / .sp-content-inner .sp-fill (min-height:
   320px, further up this file) is a descendant selector, so it also matches
   every individual .sp-fill INSIDE a collage above -- not just a lone image
   -- forcing each collage tile (big top image and the two small side-by-side
   ones alike) to the full 320px stretch height meant for a single image.
   Confirmed on both the Smart City and Digital Mine home teasers: all 3
   collage images were rendering at a uniform 320px tall instead of the
   intended big-letterbox + two-near-square proportions. Higher specificity
   (3 classes vs 2) restores each tile's own collage sizing regardless of
   source order; the collage wrapper itself keeps its 320px stretch above. */
.sp-feature-inner .sp-collage-row .sp-fill,
.sp-feature-inner .sp-collage-side .sp-fill,
.sp-feature-inner .sp-collage-side-stack .sp-fill,
.sp-content-inner .sp-collage-row .sp-fill,
.sp-content-inner .sp-collage-side .sp-fill,
.sp-content-inner .sp-collage-side-stack .sp-fill { min-height: 0; }

/* The collage's own lead/top image (not nested in a -row/-side/-side-stack)
   has no explicit height rule anywhere to fall back on -- it was relying on
   the broad .sp-feature-inner .sp-fill min-height:320px above, which is
   roughly right at desktop widths but badly overshoots Figma's wide
   letterbox ratio (361:194) at mobile widths. `>` doesn't reach it (an
   sp-flexthru .elementor-widget-wrap sits between .sp-collage and its
   "direct" children as a real, display:contents DOM node), and a plain
   descendant selector would also re-catch the row/side/side-stack images
   already fixed above, so exclude those explicitly. Left as min-height:320
   at desktop (close enough to Figma there already, ~318px expected vs 320
   actual); only overridden for mobile inside the @media block below. */
.sp-feature-inner .sp-collage .sp-fill:not(.sp-collage-row .sp-fill):not(.sp-collage-side .sp-fill):not(.sp-collage-side-stack .sp-fill),
.sp-content-inner .sp-collage .sp-fill:not(.sp-collage-row .sp-fill):not(.sp-collage-side .sp-fill):not(.sp-collage-side-stack .sp-fill) { min-height: 0; height: auto; flex: 0 0 auto; }

/* The 1.86 fallback ratio above was measured off ONE teaser (Smart City) and
   wrongly generalized -- Digital Mine and Mineshaft Inspection's own collages
   use visibly different source-photo proportions in Figma (measured per
   image directly from the local .fig: node 2953:3011 for Digital Mine's lead
   image is 361:160, node 2953:3039 for Smart City is 361:194 -- a real,
   not-approximated 15% difference), so one shared ratio can't be correct for
   all three at once. Target each image by its stable filename instead of a
   shared class, so each teaser gets its own exact Figma ratio regardless of
   which Elementor widget ID it happens to have. */
.sp-fill:has(> img[src*="home-digital-mine-hero"]) { aspect-ratio: 361 / 160; }
.sp-fill:has(> img[src*="home-digital-mine.png"]),
.sp-fill:has(> img[src*="home-digital-mine-contour"]) { aspect-ratio: 175.5 / 165; height: auto; min-height: 0; }
.sp-fill:has(> img[src*="home-smartcity-1"]) { aspect-ratio: 361 / 194; }
.sp-fill:has(> img[src*="home-smartcity-2"]),
.sp-fill:has(> img[src*="home-smartcity-3"]) { aspect-ratio: 175.5 / 174; height: auto; min-height: 0; }
/* Mineshaft Inspection uses the left-tall + right-stacked-pair layout
   (.sp-collage-side), not the top-big + bottom-pair one above -- Figma
   specs it as 175.5:302 (left) and 175.5:146 x2 (right stack), not the
   generic 191.5px row height every other .sp-collage-side-stack uses. The
   row's own fixed height:393px (from the base .sp-collage-side rule) is
   also a plain guess from before this was measured -- replace it with an
   aspect-ratio matching Figma's actual 361:302 "Frame pics" container so it
   scales correctly at any width instead of a flat desktop-guessed number. */
.sp-collage-side:has(img[src*="home-mineshaft-1"]) { height: auto; min-height: 0; aspect-ratio: 361 / 302; }
.sp-fill:has(> img[src*="home-mineshaft-1"]) { height: 100%; }
.sp-fill:has(> img[src*="home-mineshaft-2"]),
.sp-fill:has(> img[src*="home-mineshaft-3"]) { aspect-ratio: 175.5 / 146; height: auto; min-height: 0; flex: 0 0 auto; }

.sp-stack { display: flex; flex-direction: column; gap: 24px; }

.sp-list-plain { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 10px; }
.sp-list-plain li { position: relative; padding-left: 20px; font-family: var(--font-body); font-size: var(--body-sm-lg); line-height: 1.5; color: var(--text-body); }
.sp-list-plain li::before { content: ''; position: absolute; left: 0; top: 10px; width: 5px; height: 5px; border-radius: 50%; background-color: var(--text-body); }

.sp-btn {
  display: inline-flex; align-items: center; gap: 16px;
  background-color: var(--brand-primary); color: var(--sp-white);
  border-radius: var(--radius-md); padding: 18px 26px;
  font-family: var(--font-display); font-weight: var(--weight-display); font-size: var(--display-2xs);
  letter-spacing: 0.02em; text-decoration: none; white-space: nowrap;
  transition: background-color 150ms ease;
}
.sp-btn:hover { background-color: var(--sp-blue-400); color: var(--sp-white); }
.sp-btn-arrow {
  width: 30px; height: 30px; border-radius: 50%; border: 1.5px solid rgba(255,255,255,0.6);
  display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0;
}
.sp-btn-arrow svg path { stroke: var(--sp-white); }

.sp-icon-panel { border: 1px solid var(--border-default); border-radius: var(--radius-md); padding: 50px 40px; box-sizing: border-box; }
.sp-icon-grid { display: flex; flex-wrap: wrap; gap: 50px 20px; }
.sp-icon-item { flex: 1 1 340px; display: flex; flex-direction: column; align-items: center; gap: 18px; text-align: center; }
.sp-icon-item svg { width: 46px; height: 46px; color: var(--brand-primary); flex-shrink: 0; }
.sp-icon-item img { width: 72px; height: 72px; object-fit: contain; flex-shrink: 0; }
.sp-icon-item svg path, .sp-icon-item svg circle, .sp-icon-item svg rect, .sp-icon-item svg line { stroke: var(--brand-primary); }
.sp-icon-item span { font-family: var(--font-body); font-weight: var(--weight-semibold); font-size: var(--body-sm-lg); color: var(--text-body); max-width: 260px; }

.sp-challenge-grid { display: flex; flex-wrap: wrap; gap: 24px; }
.sp-challenge-card {
  flex: 1 1 380px; box-sizing: border-box;
  border: 1px solid var(--border-default); border-radius: var(--radius-md);
  padding: 30px; display: flex; flex-direction: column; gap: 46px;
  text-decoration: none;
  transition: border-color 150ms ease, box-shadow 150ms ease;
}
.sp-challenge-card:hover { border-color: var(--brand-primary); box-shadow: 0 4px 16px rgba(21, 77, 162, 0.1); }
.sp-challenge-card-top { display: flex; align-items: flex-start; justify-content: space-between; gap: 20px; }
.sp-challenge-card-top svg { width: 40px; height: 40px; flex-shrink: 0; color: var(--text-body); }
.sp-challenge-card-top > img { width: 64px; height: 64px; object-fit: contain; flex-shrink: 0; }
.sp-challenge-card-top svg path, .sp-challenge-card-top svg circle, .sp-challenge-card-top svg rect, .sp-challenge-card-top svg line { stroke: var(--text-body); }
.sp-challenge-card-arrow {
  width: 61px; height: 61px; border-radius: 50%; border: 2px solid var(--sp-gray-300);
  display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; color: var(--text-body);
  transition: background-color 150ms ease, border-color 150ms ease;
}
.sp-challenge-card-arrow svg path { stroke: var(--text-body); transition: stroke 150ms ease; }
.sp-challenge-card:hover .sp-challenge-card-arrow { background-color: var(--brand-primary); border-color: var(--brand-primary); }
.sp-challenge-card:hover .sp-challenge-card-arrow svg path { stroke: var(--sp-white); }
.sp-challenge-card-title { margin: 0; font-family: var(--font-body); font-weight: var(--weight-bold); font-size: var(--body-sm-lg); color: var(--text-body); }

.sp-benefits-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 16px; }
.sp-benefits-list li { display: flex; align-items: flex-start; gap: 14px; font-family: var(--font-body); font-size: var(--body-sm-lg); line-height: 1.4; color: var(--text-body); }
.sp-benefits-check { width: 22px; height: 22px; flex-shrink: 0; border-radius: 6px; background-color: var(--brand-primary); display: inline-flex; align-items: center; justify-content: center; margin-top: 2px; }
.sp-benefits-check svg { width: 13px; height: 10px; display: block; }
.sp-benefits-tagline { margin: 6px 0 0; font-family: var(--font-body); font-weight: var(--weight-bold); font-size: var(--body-md); color: var(--text-body); }
.sp-eyebrow--ink { color: var(--text-body); }

@media (max-width: 700px) {
  .sp-header, .sp-hero-body-wrap, .sp-solutions-row, .sp-footer-cols { padding-left: var(--space-6); padding-right: var(--space-6); }
  /* .sp-feature-inner used to be the only source of side margin here (its
     parent .sp-feature-block had no padding/max-width of its own), but
     .sp-feature-block now mirrors .sp-section-inner (max-width + auto
     margin, see above) and already sits inside .sp-section's own
     --space-page-x padding -- so this extra 24px was stacking on top of
     that, leaving Home's "Digital Mine" block indented ~24px further than
     every .sp-section-inner-based block beside it (e.g. Home mobile). */
  .sp-hero-body-wrap { padding: 24px 24px 0; }
  /* Figma's mobile frames for every sp-tabs instance (Solutions 309, Digital
     Mine 297, Expertise & Advisory 299, Mineshaft Inspection 304) have no
     tab-switcher at all -- each tab's label is its own always-visible
     "Title1" heading directly above its content block, all stacked
     sequentially (confirmed across all 4 pages via the .fig source: e.g.
     Solutions node 2953:3251, Digital Mine node 2953:3479, each just a
     plain heading+content pair, no toggle/dropdown component exists in
     Figma). The desktop tab-switcher (toggle button opening a dropdown,
     one panel visible at a time) was previously carried over to mobile
     unchanged, hiding 2 of 3 (or more) sections behind a click -- replaced
     here with a flat stack: drop the switcher chrome, promote each label to
     a plain heading via display:contents (same technique as the
     image-before-text reorder fixes elsewhere in this file), and force
     every panel visible instead of just .is-active. */
  .sp-tabs { display: flex; flex-direction: column; }
  .sp-tabs-nav-toggle, .sp-tabs-track { display: none; }
  .sp-tabs-nav, .sp-tabs-nav-inner { display: contents; }
  .sp-tabs-tab {
    flex: 0 0 auto;
    width: calc(100% - 2 * var(--space-page-x));
    margin: 32px var(--space-page-x) 0;
    box-sizing: border-box;
    justify-content: flex-start;
    padding: 0 10px 8px !important;
    border: none !important;
    border-bottom: 3px solid var(--brand-primary) !important;
    pointer-events: none;
    cursor: default;
  }
  .sp-tabs-tab-label, .sp-tabs-tab.is-active .sp-tabs-tab-label {
    text-align: left;
    font-weight: var(--weight-bold);
    color: var(--text-body);
  }
  /* Figma's tab panels sit on a uniform near-white background throughout,
     including behind the heading -- the panel's own .sp-content-section--
     tinted class (gray-050) was creating a visible white-heading/gray-panel
     banding effect once the heading became a plain sibling element via the
     display:contents promotion above. Force true white to match. */
  .sp-tabs-panel.sp-content-section--tinted { background-color: var(--surface-page); }
  .sp-tabs-panel { display: block !important; }
  .sp-tabs-tab[data-tab-target="0"] { order: 0; }
  .sp-tabs-panel[data-tab-panel="0"] { order: 1; }
  .sp-tabs-tab[data-tab-target="1"] { order: 2; }
  .sp-tabs-panel[data-tab-panel="1"] { order: 3; }
  .sp-tabs-tab[data-tab-target="2"] { order: 4; }
  .sp-tabs-panel[data-tab-panel="2"] { order: 5; }
  .sp-tabs-tab[data-tab-target="3"] { order: 6; }
  .sp-tabs-panel[data-tab-panel="3"] { order: 7; }
  .sp-tabs-tab[data-tab-target="4"] { order: 8; }
  .sp-tabs-panel[data-tab-panel="4"] { order: 9; }
  .sp-tabs-tab[data-tab-target="5"] { order: 10; }
  .sp-tabs-panel[data-tab-panel="5"] { order: 11; }
}

/* Mobile layout pass (Figma "Mobile" section, 393px frames), driven by the
   same CSS-custom-property architecture the rest of the site uses -- most
   sections already reflow correctly via flex-wrap at this width, so only
   the tokens actually consumed by non-hero elements need shrinking here.
   Explicitly excludes --display-2xl/--body-lg/--body-base-lg (hero-only
   tokens) and --display-xs/--display-2xs (nav font, must stay untouched per
   standing site-wide constraint) so the hero and the hamburger nav are
   never affected by this block. */
@media (max-width: 600px) {
  /* Our Participation (310) intro hero: Figma order is Title -> Image -> Body text, but the text column groups heading+both paragraphs together. Break the text column apart via display:contents so the image column can slot between title and body. */
  .sp-participation-hero-text { display: contents; }
  .sp-participation-hero-inner .sp-eyebrow { order: 1; }
  .sp-participation-hero-inner .elementor-column:has(.sp-participation-hero-image) { order: 2; }
  .sp-participation-hero-inner .sp-lead { order: 3; }

  /* About (285) 'Our Participation' event-card row: Figma order is Belo Horizonte, GeoIgnite 2025, CEMI-MICA South Africa -- live DOM order is GeoIgnite, CEMI-MICA, Belo. Scoped by this section's unique elementor-element id + image filename since the 3 columns share identical sp-block-card classes. */
  .elementor-element-bf8e0da .elementor-column:has(img[src*="event-3-belo"]) { order: 1; }
  .elementor-element-bf8e0da .elementor-column:has(img[src*="event-1"]) { order: 2; }
  .elementor-element-bf8e0da .elementor-column:has(img[src*="event-2-cemi"]) { order: 3; }

  :root {
    --space-page-x: 20px;
    --space-section-y: 48px;
    --display-lg: 40px;
    --body-md: 20px;
    --body-md-2: 18px;
    --body-xl: 23px;
  }

  /* Hero (Home, 162) kicker + rotating title clip/overflow instead of
     wrapping on mobile. Both are set to white-space:nowrap with only a
     shrink-to-floor clamp() for sizing -- with no wrap allowed, once text
     is wider than its box at the clamp floor it just overflows/gets cut
     off instead of dropping to a second line. Confirmed via the .fig
     source (site_new.grida1, Home Mobile frame 2953:2967): the kicker
     ('A DIGITAL MINE COMPANY') and hero title ('Turning Complexity into
     Clarity', and the other 8 rotating slide titles) both sit in a fixed-
     width ~358px text container and are expected to wrap across multiple
     lines on mobile, not shrink to one line. Confirmed live before this
     fix (CDP, 393px): the title span's natural width was 361px against a
     fit-content parent box capped near 305px with overflow:hidden, so
     "Turning Complexity into Clarity" was being clipped mid-word. Fix
     scoped to mobile only -- desktop's single-line nowrap treatment is
     unaffected and this is the only mobile-only change made to the hero. */
  .sp-hero-kicker { white-space: normal; }
  .sp-hero-title-box { height: auto; overflow: visible; }
  .sp-hero-title-box span { white-space: normal; }

  /* .sp-content-section hardcodes 86px top/bottom padding (never tied to
     --space-section-y), and .sp-content-inner/.sp-feature-inner hardcode a
     60px stack gap -- both untouched by the token overrides above. Figma's
     mobile frames pack sections edge-to-edge with near-zero gap between
     stacked title/image/body elements (measured directly from the .fig
     source), so the un-scaled 86px+60px combo was the single largest
     contributor to mobile pages running 1.3-1.8x taller than Figma
     sitewide. */
  .sp-content-section { padding: 32px var(--space-page-x); }
  .sp-content-inner, .sp-feature-inner { gap: 24px; }

  /* .sp-timeline-item (Our Participation only) hardcodes 60px padding and
     .sp-timeline-inner a 60px gap, and .sp-timeline-image forces every event
     photo to a uniform 320px tall -- Figma's mobile timeline packs each
     block tighter (photo heights per block genuinely vary 199-376px, but
     mostly cluster 250-280px) and none of this was scoped to mobile. */
  .sp-timeline-item { padding: 32px var(--space-page-x); }
  .sp-timeline-inner { gap: 24px; }
  .sp-timeline-image { min-height: 260px; }

  /* .sp-content-image hardcodes a 340px min-height (with object-fit:cover)
     unscoped for all breakpoints -- Figma's mobile .sp-content-inner images
     vary in true height per photo (measured 181-229px across Land
     Cadastre's 4 images alone -- no single fixed ratio fits all of them),
     because Figma just displays each source photo at its own natural
     aspect ratio rather than center-cropping it into a uniform box. A
     fixed aspect-ratio here (first attempt: 16/9) overcorrected pages whose
     real photos are taller than that (Solutions, Digital Mine, Expertise &
     Advisory all dropped below 1.0x once tried). Letting each image render
     at its own natural intrinsic ratio instead matches Figma per-page
     without guessing one shared number. */
  /* NOTE: reverted an earlier attempt at height:auto + object-fit:contain
     here -- these images are raw theme-asset URLs (not WP media-library
     attachments), so the rendered <img> has no width/height HTML
     attributes; relying on the browser knowing its natural size before/
     without load collapsed any image not covered by the exact per-hash
     rules below to ~1px. A fixed (smaller-than-before) min-height keeps a
     defined box regardless of load state; the exact per-hash rules below
     override this floor for the 3 pages with precise Figma measurements. */
  .sp-content-image { min-height: 210px; }

  /* .sp-content-text's 30px internal gap (between eyebrow/heading/image/
     paragraphs stacked in one column) also overshoots Figma's measured
     ~20px internal spacing at this breakpoint. */
  .sp-content-text { gap: 20px; }

  /* Exact per-image aspect ratios read directly from each image node's own
     Figma container size (fill fit:contain, so the container's own w/h IS
     the intended display box) for the pages with the largest remaining
     live-vs-Figma gaps -- the generic natural-ratio fallback above works
     reasonably sitewide but these 3 pages' real photos don't all match
     their own natural ratio closely enough, so exact figures win here.
     Matched by embedded image hash, same pattern as the Home teaser fix. */
  .sp-fill:has(> img[src*="391a0dc70bc55efa"]) { min-height: 0; aspect-ratio: 361 / 193; }
  .sp-fill:has(> img[src*="25f692c244f3a3c3"]) { min-height: 0; aspect-ratio: 361 / 229; }
  .sp-fill:has(> img[src*="380fe61c6a0086cf"]) { min-height: 0; aspect-ratio: 361 / 181; }
  .sp-fill:has(> img[src*="c4ced13896a58166"]) { min-height: 0; aspect-ratio: 361 / 203; }
  .sp-fill:has(> img[src*="889a2c27d913022b"]) { min-height: 0; aspect-ratio: 361 / 229; }
  .sp-fill:has(> img[src*="0e4c966a10127ea4"]) { min-height: 0; aspect-ratio: 361 / 201; }
  .sp-fill:has(> img[src*="6efaa92bdddae8c7"]) { min-height: 0; aspect-ratio: 361 / 257; }
  .sp-fill:has(> img[src*="5a78a123850d513e"]) { min-height: 0; aspect-ratio: 361 / 221; }
  .sp-fill:has(> img[src*="75855cbfafe979a2"]) { min-height: 0; aspect-ratio: 361 / 325; }
  .sp-fill:has(> img[src*="a5763da1be75b6d4"]) { min-height: 0; aspect-ratio: 361 / 225; }
  .sp-fill:has(> img[src*="4e711a339763bc8c"]) { min-height: 0; aspect-ratio: 361 / 236; }
  .sp-fill:has(> img[src*="9077b0805a12f114"]) { min-height: 0; aspect-ratio: 361 / 186; }

/* Solutions page's 9 alternating 'services' section images -- same
   generic 210px fallback issue, exact ratios read from each image's own
   Figma mobile-frame container (361 wide basis), matched by embedded
   image hash. Also its default-active tab panel image (solutions-tab-1,
   a non-hash custom filename, matched by name instead), Figma ratio
   361:240 (same template size as other tab-style panels sitewide). */
.sp-fill:has(> img[src*="8bce180186e70215"]) { min-height: 0; aspect-ratio: 361 / 228; }
.sp-fill:has(> img[src*="66d2147d86d945a6"]) { min-height: 0; aspect-ratio: 361 / 406; }
.sp-fill:has(> img[src*="1ba31270f49b55c3"]) { min-height: 0; aspect-ratio: 361 / 406; }
.sp-fill:has(> img[src*="f9d38856f1dbca1b"]) { min-height: 0; aspect-ratio: 361 / 328; }
.sp-fill:has(> img[src*="1fedbb36b82f8f39"]) { min-height: 0; aspect-ratio: 361 / 328; }
.sp-fill:has(> img[src*="fe97738bd74c7edb"]) { min-height: 0; aspect-ratio: 361 / 328; }
.sp-fill:has(> img[src*="dd44a206b1b9d933"]) { min-height: 0; aspect-ratio: 361 / 328; }
.sp-fill:has(> img[src*="5d18b0ada81e66a4"]) { min-height: 0; aspect-ratio: 361 / 349; }
.sp-fill:has(> img[src*="91de56c8bb4853ca"]) { min-height: 0; aspect-ratio: 361 / 349; }
.sp-fill:has(> img[src*="solutions-tab-1"]) { min-height: 0; aspect-ratio: 361 / 240; }

/* Mining and Geology's 4 alternating section images, same generic 210px
   fallback issue, exact ratios from the .fig mobile frame. */
.sp-fill:has(> img[src*="a76d9a88b1378b55"]) { min-height: 0; aspect-ratio: 361 / 273; }
.sp-fill:has(> img[src*="3da1e3c3b3700cef"]) { min-height: 0; aspect-ratio: 361 / 194; }
.sp-fill:has(> img[src*="9fc3be2aecbeac63"]) { min-height: 0; aspect-ratio: 361 / 235; }
.sp-fill:has(> img[src*="7c3842f4e09dd43a"]) { min-height: 0; aspect-ratio: 361 / 257; }

/* Smart City's 5 alternating section images, same fix. */
.sp-fill:has(> img[src*="9a306698baf0097f"]) { min-height: 0; aspect-ratio: 361 / 263; }
.sp-fill:has(> img[src*="6883f153ca321309"]) { min-height: 0; aspect-ratio: 361 / 242; }
.sp-fill:has(> img[src*="6fa0cc4802cbdee2"]) { min-height: 0; aspect-ratio: 361 / 204; }
.sp-fill:has(> img[src*="20c1674b2ee25fea"]) { min-height: 0; aspect-ratio: 361 / 216; }
.sp-fill:has(> img[src*="ac0f62ee69e312c3"]) { min-height: 0; aspect-ratio: 361 / 203; }

/* Mine Planning Automation's 6 alternating section images, same fix. */
.sp-fill:has(> img[src*="e652a2fc47d44a50"]) { min-height: 0; aspect-ratio: 361 / 257; }
.sp-fill:has(> img[src*="785ac278986e05da"]) { min-height: 0; aspect-ratio: 361 / 229; }
.sp-fill:has(> img[src*="afc3298ae2d8c2c8"]) { min-height: 0; aspect-ratio: 361 / 228; }
.sp-fill:has(> img[src*="451911893a6d1718"]) { min-height: 0; aspect-ratio: 361 / 257; }
.sp-fill:has(> img[src*="a117b4324f39f8ca"]) { min-height: 0; aspect-ratio: 361 / 171; }
.sp-fill:has(> img[src*="59a3de1a360f9214"]) { min-height: 0; aspect-ratio: 361 / 171; }

/* Digital Mine's 'Digital Twin for Mining Operations' image widget uses
   plain .sp-fill (no .sp-content-image class), which has NO defined
   height anywhere -- .sp-fill img sets height:100% of its parent, but the
   parent itself never gets a height, collapsing the whole image to 0px.
   This is a real bug at any breakpoint, not mobile-specific: confirmed via
   getBoundingClientRect (0 height) at 393px viewport. Figma's own mobile
   node for this image is 361:171. */
.sp-fill:has(> img[src*="b9936ec06ce3647c"]) { min-height: 0; aspect-ratio: 361 / 171; }

/* Expertise & Advisory (299) alternating-section images */
.sp-fill:has(> img[src*="6426f95cbfa66428"]) { min-height: 0; aspect-ratio: 361 / 213; }
.sp-fill:has(> img[src*="5f9b30c3a13350c5"]) { min-height: 0; aspect-ratio: 361 / 258; }
.sp-fill:has(> img[src*="6044f4fbf5bf26f9"]) { min-height: 0; aspect-ratio: 361 / 204; }
.sp-fill:has(> img[src*="d28390cef22a37b1"]) { min-height: 0; aspect-ratio: 361 / 242; }
.sp-fill:has(> img[src*="90ac4e0d657f73e5"]) { min-height: 0; aspect-ratio: 361 / 242; }
.sp-fill:has(> img[src*="c1c795b0808c9ef5"]) { min-height: 0; aspect-ratio: 361 / 177; }

  /* .sp-footer-band already self-scales via clamp(), but its floor (24px)
     and vw coefficient (6.5vw) were tuned for tablet/desktop and undershoot
     badly at phone widths (~25px computed at 393px vs Figma's 50px) -- a
     dedicated mobile clamp tuned to this range fixes it without touching
     the shared --display-xl token (whose only other consumer,
     .sp-title-box--lg, has no confirmed mobile spec yet). */
  /* Base rule sets white-space:nowrap (fine at desktop widths, where the
     clamp keeps it short enough) -- at mobile widths even the clamped size
     doesn't fit "Data That Drives Mining" on one line, so it was overflowing
     off the right edge of the viewport instead of wrapping like Figma's own
     mobile frame does (wraps across ~2-3 lines there). */
  .sp-footer-band span { font-size: clamp(36px, 12.5vw, 56px); white-space: normal; }

  /* The other --display-xl consumer named in the comment above (About page's
     "WHO WE ARE" heading): same nowrap-overflow issue -- "WHO WE ARE" ran
     off the left/right edges of the mobile viewport at full desktop size
     instead of wrapping or shrinking. Same clamp for visual consistency
     with the footer band. */
  .sp-title-box--lg span { font-size: clamp(36px, 12.5vw, 56px); white-space: normal; }

  /* .sp-heading-md is used both as a small subtitle under a big .sp-eyebrow
     AND, on several pages (Digital Mine's "Platform Capabilities and Key
     Features", Mineshaft Inspection's "Major Technical Requirements", etc.),
     as the ONLY heading for a whole section -- in the latter role it needs
     to read as a real heading. --body-md (its font-size source) already
     drops from 28px to 20px at this breakpoint for ordinary body copy,
     which left those standalone section titles barely distinguishable from
     the paragraph text below them. Keep the desktop size for headings
     specifically instead of following the body-copy shrink. */
  .sp-heading-md { font-size: 28px; }

  .sp-btn {
    width: 100%;
    box-sizing: border-box;
    justify-content: space-between;
    border-radius: var(--radius-sm);
  }

  .sp-icon-panel { padding: 24px 20px; }
  .sp-icon-grid { gap: 24px; }
  .sp-icon-item img { width: 100px; height: 100px; }
  .sp-challenge-card { gap: 20px; }

  /* Every alternating text/image section in the Figma mobile frames reads
     Title -> Image -> Body text -> Button, but the live markup splits text
     and image into two side-by-side flex children that (once wrapped to a
     single column here) render in DOM order: the whole text column
     (title+body+button) first, then the image after. Forcing the image
     column first gets close to Figma's order with one rule instead of
     reordering widgets in every section's _elementor_data; --reverse
     sections already put the image first via row-reverse, so this is a
     no-op there and only changes the non-reverse ones. */
  /* `order` only has effect on the element that is ACTUALLY the direct
     flex item -- with sp-flexthru, that's the .elementor-column itself
     (its own .elementor-element-populated/.elementor-widget-wrap children
     are display:contents, but the column box is real and IS what
     .sp-content-inner's flex layout sees), not the .sp-content-image/
     .sp-fill widget several display:contents layers further down. Select
     the column that CONTAINS the image widget via :has(). */
  /* CORRECTED: the above (single order:-1 on the whole image column) only
     got the image column above the WHOLE text column, i.e. Image -> Title ->
     Subtitle -> Body -> Button -- confirmed wrong against Figma's actual
     mobile render (title/subtitle come FIRST, then images, THEN body), and
     confirmed by the user pointing at a fresh Figma export. Figma wants:
     Title -> Subtitle -> Images -> Body -> Button. `order` can only reorder
     DIRECT flex items, and title/subtitle/body/button all live inside ONE
     text column together -- so instead of moving the whole column, make
     the TEXT column itself (not the image column) `display: contents` at
     mobile ONLY, promoting its individual widgets (heading, subtitle,
     paragraphs, button) to be direct flex items of .sp-feature-inner /
     .sp-content-inner alongside the (untouched, still-one-unit) image
     column, then give each an explicit order. Desktop is completely
     unaffected (this whole block is inside the >= 600px-excluded media
     query, and the image column itself is never made `contents`, so its
     own internal .sp-collage layout stays intact). */
  .sp-feature-inner .sp-feature-col.sp-stack:not(.sp-collage),
  .sp-content-inner .sp-content-text { display: contents; }

  .sp-feature-inner .sp-eyebrow,
  .sp-content-inner .sp-eyebrow { order: 1; }
  .sp-feature-inner .sp-heading-md,
  .sp-content-inner .sp-heading-md { order: 2; }
  .sp-feature-inner .sp-collage,
  .sp-feature-inner .sp-collage-side,
  .sp-feature-inner .sp-feature-col:not(.sp-stack),
  .sp-content-inner .elementor-column:has(.sp-content-image) { order: 3; }
  .sp-feature-inner .sp-lead,
  .sp-content-inner .sp-lead { order: 4; }
  .sp-feature-inner .elementor-widget-html:has(.sp-btn),
  .sp-content-inner .elementor-widget-html:has(.sp-btn) { order: 5; }
  .sp-feature-inner .elementor-widget-html:not(:has(.sp-btn)),
  .sp-content-inner .elementor-widget-html:not(:has(.sp-btn)) { order: 4; }

  /* ESG (298) 'Digital transformation enables organizations to:' section: Figma places its closing globe/plant image AFTER all 3 Environmental/Social/Governance Impact lists, not at the generic order:3 slot (which assumes a single heading+body+image pattern). This section has 3 grouped sub-lists between heading and image, so the image needs to sort after all of them (order:4 lead/html). Scoped by this section's unique element id to avoid affecting the many other .sp-content-inner sections that DO want the generic order:3 image placement. */
  .elementor-element-bb3b2d9 .elementor-column:has(.sp-content-image) { order: 5; }

  /* the flex `gap` on .sp-content-inner/.sp-feature-inner already spaces the
     reordered widgets apart -- their own leftover margin-bottom (inherited
     from Elementor/theme defaults, ~24px) stacks on top of that gap and
     double-spaces every pair, most visible where a section has multiple
     .sp-lead paragraph widgets in a row. Zero it out at mobile. */
  .sp-feature-inner .sp-eyebrow, .sp-content-inner .sp-eyebrow,
  .sp-feature-inner .sp-lead, .sp-content-inner .sp-lead,
  .sp-timeline-inner .sp-lead, .sp-participation-hero-inner .sp-lead, .sp-stack .sp-lead,
  .sp-feature-inner .elementor-widget-html, .sp-content-inner .elementor-widget-html { margin-bottom: 0; }

  /* The margin-bottom:0 above zeroes the .sp-lead DIV (the Elementor widget
     wrapper) itself, but the raw <p> INSIDE that div carries its own
     separate ~31.5px margin-bottom (Elementor's own default paragraph
     spacing, e.g. 1.75em at this font-size) that the outer rule never
     touched. Since the div is a plain block box (not a new block-formatting
     context), that inner margin still renders as real height inside the
     div rather than being cancelled, leaving a residual gap even after the
     div-level fixes above and the flex-gap-cancelling rules below --
     confirmed via getBoundingClientRect on the <p> elements directly,
     visible as a real (not just measured-on-the-wrapper) blank gap between
     consecutive paragraphs on Land Cadastre and Our Participation. Zero the
     inner <p> too so the outer flex `gap` is the only source of spacing. */
  .sp-feature-inner .sp-lead p, .sp-content-inner .sp-lead p,
  .sp-timeline-inner .sp-lead p, .sp-participation-hero-inner .sp-lead p, .sp-stack .sp-lead p { margin: 0; }

  /* Two consecutive .sp-lead "paragraphs" -- whether authored as several <p>
     tags inside ONE raw-html widget (the tabs panels) or as several SEPARATE
     Elementor text-editor widgets each wrapped in its own .sp-lead div (the
     normal sitewide pattern, e.g. Land Cadastre's elementor-element-82e76d8/
     -9fb0145/-239dfe2/-498cc8e) -- become direct flex-item siblings once
     promoted above, so each pair still gets the same 24px flex `gap` as any
     other pair of distinct widgets, splitting what Figma renders as ONE
     continuous text block into visibly separate chunks. Confirmed via the
     .fig source across many pages (e.g. Land Cadastre node 2188:2575/
     2953:4339, Solutions node 2953:3249) that these are literally one Figma
     text node with a plain single line-break between "paragraphs" -- no
     paragraph gap at all, just the next text line. Cancel the gap between
     any two adjacent .sp-lead elements (no tag qualifier, so it matches
     both the <p class="sp-lead"> and the div.sp-lead widget-wrapper shape)
     so they read as one blob, same as Figma; a heading/image/button still
     gets the full 24px gap before or after a paragraph since those pairs
     don't match this selector. */
  .sp-feature-inner .sp-lead + .sp-lead,
  .sp-content-inner .sp-lead + .sp-lead { margin-top: -24px; }

  /* Same blob-splitting bug, different containers: .sp-timeline-inner (Our
     Participation's 10 event cards, each with 2-3 consecutive .sp-lead
     widgets), .sp-participation-hero-inner, and .sp-stack (the generic
     flex-column utility -- e.g. Home's "Nutshell" title+list column, which
     is the REAL immediate flex parent even though the outer row carries
     .sp-solutions-row; that outer class's own 60px gap never actually
     applies to these two widgets, only .sp-stack's 24px does -- verified via
     getComputedStyle before picking the cancel value, don't assume the
     nearest-named-looking ancestor is the real flex parent) all promote
     their .sp-lead children to direct flex items the same way, but each
     uses its own gap value instead of the 24px above. */
  .sp-timeline-inner .sp-lead + .sp-lead { margin-top: -20px; }
  .sp-stack .sp-lead + .sp-lead { margin-top: -24px; }
  .sp-participation-hero-inner .sp-lead + .sp-lead { margin-top: -60px; }

  /* Home's "SightPower Technology in a Nutshell" section nests title+bullet-list
     as two side-by-side columns inside one .sp-solutions-row section, with the
     icon-panel as a separate sibling widget below that whole row. Figma wants
     Title -> Icon Panel -> List, but DOM/desktop order is Title+List (as one row)
     -> Icon Panel. Making the row itself display:contents promotes its two
     columns to be real siblings of the icon-panel widget, then explicit order
     interleaves them correctly. Scoped by element ID since none of the 3 pieces
     carry a distinguishing class of their own. */
  /* .sp-solutions-row is reused for 3 different section pairs on this page --
     only THIS one (id 4fdfb57, title+icon-panel+list) needs its row promoted
     to interleave with a 3rd sibling widget below; scope by element id, not
     the shared class, so the other 2 unrelated title+paragraph pairs (which
     render fine as-is) aren't forced into contents too. */
  .elementor-element-4fdfb57 { display: contents; }
  /* .sp-row-col's flex:1 1 300px is sized for the desktop horizontal row;
     once promoted into the outer vertical stack via display:contents above,
     that same flex-basis is reinterpreted along the vertical (height) axis
     instead, distorting box height and overlapping the next section. Reset
     to natural content height for the promoted mobile context. */
  .elementor-element-b6420be, .elementor-element-d28d964 { flex: 0 0 auto; }
  .elementor-element-b6420be { order: 1; }
  .elementor-element-ba35947 { order: 2; }
  .elementor-element-d28d964 { order: 3; }

  /* Home's "Precision Data Smarter Decisions" section (.sp-content-inner): its
     title/subtitle/caption headings default to order:0 (no sp-eyebrow/
     sp-heading-md class of their own), and its image widget DOES carry
     sp-content-image (an Elementor-applied default not visible in saved
     widget settings), so the generic .sp-content-inner .elementor-column:has
     (.sp-content-image) rule above already fixes the image at order:3 --
     no override needed or possible there without fighting its specificity.
     The bullet list's generic order:4 (from the html-widget catch-all,
     specificity 0,2,0) puts it AFTER the image, but Figma wants it BEFORE.
     Pull the list down to order:2 (a deliberate tie with the subtitle --
     DOM order breaks the tie correctly, subtitle precedes list) using an
     equal-specificity 2-class selector so source order decides the winner. */
  .elementor-element-3b4dcd1 { order: 1; }
  .elementor-element-7e81d49 { order: 2; }
  .elementor-element-14b48a0 { order: 6; }
  .sp-content-inner .elementor-widget-html.elementor-element-3a8de6a { order: 2; }

  /* .sp-calc-commodities uses a fixed non-shrinking flex-basis for the
     desktop side-by-side layout -- at mobile widths that overflows the
     viewport instead of stacking, so let both columns go full-width. */
  .sp-calc-commodities,
  .sp-calc-fields { flex: 1 1 100%; }

  /* Real <table> markup doesn't reflow at narrow widths; scope it to a
     scrollable block instead of letting it force page-wide overflow. */
  .sp-table { display: block; overflow-x: auto; -webkit-overflow-scrolling: touch; }
#downloads { scroll-margin-top: 24px; }
}

.sp-tabs-panel-inner {
  width: 100%; max-width: var(--content-max-width); margin: 0 auto; box-sizing: border-box;
  padding: 60px var(--space-page-x); display: flex; flex-direction: column; gap: 30px;
}

.sp-table { width: 100%; border-collapse: collapse; }
.sp-table th, .sp-table td {
  text-align: left; padding: 14px 20px; font-family: var(--font-body); font-size: var(--body-sm);
  color: var(--text-body); border: 1px solid var(--border-default); box-sizing: border-box;
}
.sp-table th { background-color: var(--surface-section); font-weight: var(--weight-bold); }
.sp-table tbody tr:nth-child(even) td { background-color: var(--surface-section); }
.sp-table td:last-child { color: #666666; white-space: nowrap; }

.sp-calc { display: flex; gap: 40px; flex-wrap: wrap; align-items: flex-start; }
.sp-calc-commodities {
  display: flex; flex-direction: column; flex: 0 0 260px;
  border: 1px solid var(--border-default); border-radius: var(--radius-sm); overflow: hidden;
}
.sp-calc-commodities .sp-calc-commodity {
  appearance: none; -webkit-appearance: none; border: none; border-radius: 0; border-bottom: 1px solid var(--border-default);
  text-align: left; padding: 20px 24px; background-color: var(--surface-page);
  font-family: var(--font-body); font-weight: var(--weight-semibold); font-size: var(--body-sm-lg);
  color: var(--text-body); cursor: pointer; transition: background-color 150ms ease, color 150ms ease;
}
.sp-calc-commodities .sp-calc-commodity:last-child { border-bottom: none; }
.sp-calc-commodities .sp-calc-commodity.is-active { background-color: var(--brand-primary); color: var(--sp-white); }
.sp-calc-fields {
  flex: 1 1 400px; display: flex; flex-direction: column;
  border: 1px solid var(--border-default); border-radius: var(--radius-sm); overflow: hidden;
}
.sp-calc-field-row {
  display: flex; align-items: center; justify-content: space-between; gap: 20px;
  padding: 14px 24px; border-bottom: 1px solid var(--border-default);
  font-family: var(--font-body); font-size: var(--body-sm); color: var(--text-body);
}
.sp-calc-field-row:last-child { border-bottom: none; }
.sp-calc-field-row input {
  width: 120px; height: 36px; border: 1px solid var(--border-default); border-radius: var(--radius-sm);
  padding: 0 12px; font-family: var(--font-body); font-size: var(--body-sm); text-align: right; box-sizing: border-box;
}
.sp-calc-output { background-color: var(--surface-section); }
.sp-calc-output span { font-weight: var(--weight-bold); }
.sp-calc-output-value { color: var(--text-muted) !important; }

/* This section's column is bare .sp-flexthru with no .sp-section-inner/
   .sp-content-inner wrapper (unlike the sibling .sp-topic-card-icons-flat
   section further down, which gets its cap from .sp-section-inner), so the
   grid just filled the section's full padded width with no cap -- wider
   than every other capped content block around it. */
.sp-topic-grid { display: flex; flex-wrap: wrap; gap: 40px 37px; width: 100%; box-sizing: border-box; max-width: var(--content-max-width); margin: 0 auto; }
.sp-topic-card { flex: 1 1 380px; max-width: 406px; display: flex; flex-direction: column; gap: 24px; }
/* Figma orders each topic card Title -> Icon -> List, but the markup is
   authored icon-div first, then h4, then list -- a genuine order bug, not
   just a mobile-narrowing artifact, since .sp-topic-card's flex-column isn't
   viewport-gated. Reorder via flex order rather than editing hand-authored
   HTML content. */
.sp-topic-card h4 { order: 1; }
.sp-topic-card-icon { order: 2; display: flex; align-items: center; justify-content: center; height: 140px; }
.sp-topic-card ul { order: 3; }
.sp-topic-card-icon img { max-width: 140px; max-height: 140px; object-fit: contain; }
.sp-topic-card h4 { margin: 0; font-family: var(--font-body); font-weight: var(--weight-bold); font-size: var(--body-md); color: var(--text-body); }
.sp-topic-card-icons-flat { display: flex; flex-wrap: wrap; gap: 40px 37px; }
.sp-topic-card-flat { flex: 1 1 340px; max-width: 380px; display: flex; flex-direction: column; align-items: center; text-align: center; gap: 18px; }
.sp-topic-card-flat img { width: 90px; height: 90px; object-fit: contain; }
.sp-topic-card-flat span { font-family: var(--font-body); font-weight: var(--weight-semibold); font-size: var(--body-sm-lg); color: var(--text-body); max-width: 300px; }

@media (max-width: 600px) {
  /* Digital Mine's 6-card topic grid uses square 140px icons everywhere
     (rule above, unscoped), but Figma's mobile frame specs each icon at
     183x183 (confirmed via the .fig source: 'Frame pics' containers are
     269 tall centering a 183x183 icon). Placed right after the unscoped
     rule (not in the earlier shared mobile @media block further up the
     file) so it wins the cascade at equal specificity -- source order,
     not just media-query presence, decides ties. Scoped to mobile only;
     desktop wasn't audited against this task's mobile-only brief. */
  .sp-topic-card-icon { height: 183px; }
  .sp-topic-card-icon img { max-width: 183px; max-height: 183px; }

  /* Same cascade-order issue for the 6 'Platform Capabilities' flat icons:
     forced to a uniform 90x90 square by the unscoped rule above, but
     Figma's mobile frame shows each icon at its own natural width
     (90-173px) within a shared 121px height box (object-fit:contain
     already set, just needs the right bounding box instead of a forced
     square -- confirmed per-icon via the .fig source, e.g. dm-icon-8's
     Figma node is 173x121, dm-icon-4's is 90x121). */
  .sp-topic-card-flat img { width: auto; height: 121px; max-width: 173px; }

  /* Card-internal spacing: Figma's mobile topic cards space title->icon at
     30px and icon->list at 44px (not the uniform 24px flex gap used here),
     and space cards apart at 32px not 40px -- confirmed via the .fig source
     (site_new.grida1, node 2953:3358 and siblings). */
  .sp-topic-grid { gap: 32px 37px; }
  .sp-topic-card { gap: 30px; }
  .sp-topic-card ul { margin-top: 14px; }
}

.sp-safety-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; }
.sp-safety-icon { display: flex; align-items: center; justify-content: center; }
.sp-safety-icon img { width: 100%; max-width: 260px; object-fit: contain; }
.sp-safety-card { border: 1px solid var(--border-default); border-radius: var(--radius-md); padding: 24px; box-sizing: border-box; background-color: var(--surface-section); }
.sp-safety-card h4 { margin: 0 0 10px; font-family: var(--font-body); font-weight: var(--weight-bold); font-size: var(--body-md); color: var(--text-body); }
.sp-safety-card p { margin: 0; font-family: var(--font-body); font-size: var(--body-sm-lg); line-height: 1.5; color: var(--text-body); }
@media (max-width: 900px) { .sp-safety-grid { grid-template-columns: 1fr; } }

.sp-capability-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; }
.sp-capability-card { border-radius: var(--radius-md); background-color: var(--surface-section); padding: 32px; box-sizing: border-box; display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; }
.sp-capability-card-body h4 { margin: 0 0 14px; font-family: var(--font-body); font-weight: var(--weight-bold); font-size: var(--body-md); color: var(--text-body); }
.sp-capability-card-body ul { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 8px; }
.sp-capability-card-body li { position: relative; padding-left: 18px; font-family: var(--font-body); font-size: var(--body-sm-lg); line-height: 1.5; color: var(--text-body); }
.sp-capability-card-body li::before { content: ''; position: absolute; left: 0; top: 9px; width: 5px; height: 5px; border-radius: 50%; background-color: var(--text-body); }
.sp-capability-card-icon { flex-shrink: 0; width: 48px; height: 48px; }
.sp-capability-card-icon img { width: 100%; height: 100%; object-fit: contain; }
@media (max-width: 900px) { .sp-capability-grid { grid-template-columns: 1fr; } }

/* Mobile override appended at EOF (not inside the earlier @media 600px block)
   -- .sp-capability-card's own base rule lives later in this file than that
   earlier block, so same-specificity overrides placed there lose the cascade
   tie-break by source order regardless of the media condition. Appending here
   guarantees this wins. AI Assistant (295) only uses .sp-capability-*. */
@media (max-width: 600px) {
  .sp-capability-grid { gap: 16px; }
  .sp-capability-card { padding: 20px; gap: 10px; }
  .sp-capability-card-body h4 { margin-bottom: 10px; }
  .sp-capability-card-body ul { gap: 6px; }
}

/* AI Assistant (295) "Key Capabilities" section: unlike every other
   sp-content-inner section, neither column here uses .sp-content-text/
   .sp-content-image (which normally supply flex:1 1 320px), so both
   columns fell back to flex:0 1 auto content-based sizing -- Elementor's
   own _column_size (35/65) width% never applied either, so both columns
   sized to their full content width (1120px each) and flex-wrap:wrap on
   .sp-content-inner forced them onto separate stacked rows instead of
   sitting side by side. Scoped by element-id (not a shared class) since
   this markup variant is unique to this section. */
.elementor-element-d8c9302.elementor-column { flex: 35 1 370px; min-width: 0; }
.elementor-element-1fa7035.elementor-column { flex: 65 1 680px; min-width: 0; }

/* Site Footer (312), mobile: Figma stacks the footer content Tagline ->
   Nav links -> Offices/contact -> Social icons -> Copyright last, but the
   copyright text-editor widget lives inside the same column as the tagline
   heading (both children of .sp-footer-col1), so it renders second overall
   instead of last. Unwrap col1 via display:contents (same technique used
   for .sp-participation-hero-text / .sp-tabs-nav above) so the tagline and
   copyright become direct flex items of .sp-footer-cols alongside the other
   columns, then order all of them explicitly to push copyright to the end. */
@media (max-width: 600px) {
  .sp-footer-col1 { display: contents; }
  .sp-footer-col1 > .elementor-widget-wrap { display: contents; }
  .sp-footer-tagline { order: 1; }
  .elementor-element-930d282 { order: 2; }
  .sp-footer-offices { order: 3; }
  .sp-footer-arrow-wrap { order: 4; }
  .sp-footer-copy { order: 5; }
}
