/*
 Theme Name:   Divi Child Theme
 Theme URI:    https://elegantthemes.com/
 Description:  A custom child theme for the Divi parent theme.
 Author:       MPIX
 Author URI:   https://yourwebsite.com
 Template:     Divi
 Version:      1.0.0
*/

:root {
  --font-primary: "Inter", sans-serif;

  --color-primary: #f83260;
  --color-secondary: #461070;
  --color-secondary-200: #ee6c9a;
  --color-secondary-300: #f9f0ff;
  --bg-gradient-primary: linear-gradient(157deg, #db4e6a 7.18%, #461070 75.63%);
  --bg-gradient-secondary: linear-gradient(
    249deg,
    #db4e6a -19.78%,
    #461070 50.39%
  );

  --color-white: #fff;
  --color-ink: #0b1018;
  --color-cream: #fffaf7;

  --container-width: 90rem;
  --container-pad: 1.25rem;
  --gutter: 1.5rem;
}

/* --------------------------------------------------------------------------
   2. Base resets the component's spacing assumes.
   -------------------------------------------------------------------------- */
html {
  /* Lets the section's canvas (technology-shell.js) scale its rem-based
     draw sizes on very wide screens. Safe to drop this block if you don't
     want that behaviour — the canvas just falls back to a flat 16px. */
  @media (min-width: 80rem) {
    font-size: clamp(0.95rem, 1.9vmin, 14.25rem);
  }
}
body {
  font-family: "Inter", sans-serif !important;
}
h1,
h2,
h3,
h4,
h5,
h6 {
  margin: 0;
  font-family: "Inter", sans-serif !important;
}
.bg-secondary-300 {
  background-color: var(--color-secondary-300);
}
/* --------------------------------------------------------------------------
   3. Shared components used inside technology-shell's markup.
   -------------------------------------------------------------------------- */
/* Named .aqp-container (not the generic .container) — the live site's
   own Divi theme CSS already defines a ".container" class of its own
   (width:80%;max-width:1080px;margin:auto;position:relative from Divi's
   core stylesheet, plus another from Divi's compiled critical CSS), and
   since that loads AFTER this child theme's stylesheet, a same-specificity
   collision on a bare ".container" silently loses — Divi's width/margin
   wins over ours, which is what was quietly narrowing/shifting every
   section that used plain .container (verified via curl against the
   live et-core-unified.css + inlined Divi parent CSS). Namespacing this
   class removes the collision outright, regardless of stylesheet load
   order — safer than trying to out-specificity a page builder's own CSS. */

/* Was ".section-padding" in the source theme's _common.css but never
   made it into any of this file's earlier sections — used on both
   scientific-foundation and evidence-guided-direction's outer
   <section>, so without this both were missing their intended
   padding-block (3rem mobile / 5rem from 40rem up) entirely. */
/* .aqp-section-padding {
  padding-block: 3rem;
}
@media (min-width: 40rem) {
  .aqp-section-padding {
    padding-block: 5rem;
  }
} */

.aqp-bg-ink {
  background-color: var(--color-ink);
}
.aqp-text-cream {
  color: var(--color-cream);
}

/* Numbered circle badge (01, 02, 03…) used in each .tech-caption h3. */
.number-badge {
  display: inline-grid;
  place-items: center;
  width: 3.375rem;
  height: 3.375rem;
  border: 0.0625rem solid transparent;
  background:
    linear-gradient(var(--color-white), var(--color-white)) padding-box,
    var(--bg-gradient-primary) border-box;
  box-shadow:
    0 0 0 0.0625rem color-mix(in srgb, var(--color-white) 18%, transparent)
      inset,
    0 1rem 2.5rem color-mix(in srgb, var(--color-primary) 18%, transparent);
  color: var(--color-secondary);
  font-size: 1rem;
  font-weight: 760;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}

/* Base pill button — .tech-nav's "Contact us" button builds on this. */
@property --angel {
  syntax: "<angle>";
  inherits: false;
  initial-value: 254.23deg;
}
@keyframes angelMove {
  0% {
    --angel: 254.23deg;
  }
  100% {
    --angel: 90deg;
  }
}
.aqp-button {
  padding: 0.625rem 1.5rem;
  border-radius: 10rem;
  font-size: 1.125rem;
  line-height: 1.2;
  color: var(--color-white);
  border: none;
  cursor: pointer;
  font-weight: 500;
  position: relative;
  transition: all 0.3s;
  background: linear-gradient(
    var(--angel),
    var(--color-primary) -21.59%,
    var(--color-secondary) 49.64%
  );
}
.aqp-button:hover {
  animation: angelMove 0.3s linear forwards;
  box-shadow: 0 0 5px rgba(0, 0, 0, 0.5);
}

/* --------------------------------------------------------------------------
   4. Utility classes (Tailwind-style) referenced directly in the markup.
   -------------------------------------------------------------------------- */
.aqp-block {
  display: block;
}
.aqp-flex {
  display: flex;
}
.aqp-grid {
  display: grid;
}
.aqp-hidden {
  display: none;
}

.aqp-static {
  position: static;
}
.aqp-relative {
  position: relative;
}
.aqp-absolute {
  position: absolute;
}
.aqp-sticky {
  position: sticky;
}
.aqp-inset-0 {
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
}
.aqp-top-0 {
  top: 0;
}
.aqp-right-0 {
  right: 0;
}
.aqp-bottom-0 {
  bottom: 0;
}
.aqp-left-0 {
  left: 0;
}

.aqp-w-full {
  width: 100%;
}
.aqp-h-full {
  height: 100%;
}

.aqp-overflow-hidden {
  overflow: hidden;
}

.aqp-flex-col {
  flex-direction: column;
}
.aqp-items-start {
  align-items: flex-start;
}
.aqp-items-center {
  align-items: center;
}
.aqp-justify-start {
  justify-content: flex-start;
}
.aqp-justify-center {
  justify-content: center;
}
.aqp-justify-between {
  justify-content: space-between;
}
.aqp-gap-4 {
  gap: 1.5rem;
}
.aqp-gap-6 {
  gap: 1.5rem;
}
.aqp-gap-8 {
  gap: 2rem;
}

.aqp-rounded-full {
  border-radius: 9999px;
}
.aqp-opacity-0 {
  opacity: 0;
}

.aqp-font-semibold {
  font-weight: 600;
}
.aqp-font-medium {
  font-weight: 500;
}

/* --------------------------------------------------------------------------
   5. technology-shell component — verbatim from
      assets/css/components/_technology.css.
   -------------------------------------------------------------------------- */
.technology-shell {
  z-index: 50;
  isolation: isolate;
  /* Was `overflow-y: hidden` — but any overflow value other than
     `visible`/`clip` turns this box into a scroll container, and
     .tech-sticky (a descendant) then tries to stick to THIS box
     instead of the viewport. This box never scrolls internally, so the
     sticky pin silently did nothing and the JS had to fake it with a
     per-frame transform (the source of the mobile jitter). `clip` on
     the X axis keeps the heading-glow horizontal-overflow guard without
     creating a scroll container, so real `position: sticky` works. */
  overflow-x: clip;
}

/* position: sticky pins to the nearest ANCESTOR scroll container, or
   the viewport if there is none. Divi drops this section into a Code
   module wrapped in section / row / column / module elements (and
   #page-container) that can pick up overflow:hidden — from Divi
   options, from an entrance animation, or from a plugin. Any one of
   them silently breaks the pin. Force the wrappers around THIS section
   back to non-clipping (clip on X still blocks sideways scrollbars). */
/* The step animation drives scroll frame-by-frame with the positional
   window.scrollTo(x, y). Force scroll-behavior: auto on this page so a
   `scroll-behavior: smooth` (from Divi's smooth-scroll option or a
   plugin) can't turn each of those per-frame calls into its own nested
   smooth animation and stutter the transition. scheduleTechnologySnap()
   still passes behavior:"smooth" explicitly where it wants it. */
html:has(#technology) {
  scroll-behavior: auto;
}

#page-container:has(#technology) {
  overflow: visible !important;
  overflow-x: clip !important;
}
#et-main-area:has(#technology),
#main-content:has(#technology),
#et-boc:has(#technology),
.et-l:has(#technology),
.et_builder_inner_content:has(#technology),
.et_pb_section:has(#technology),
.et_pb_row:has(#technology),
.et_pb_column:has(#technology),
.et_pb_module:has(#technology),
.et_pb_code:has(#technology),
.et_pb_code:has(#technology) > .et_pb_code_inner {
  overflow: visible !important;
}
.technology-heading {
  z-index: 2;
  min-height: 100svh;
  padding-block: 6rem;
  place-items: center;
  pointer-events: none;
  /* .technology-heading-text::before's glow bleeds -4rem past each
       side of the heading text (below) for a soft halo; on narrow
       screens the text sits close to this wrapper's own edges, so that
       bleed pushed past the viewport and widened the whole document
       (horizontal scrollbar on the body). Clipping here is safe: this
       is a sibling of .technology's sticky-pinned canvas, not an
       ancestor of it, so it can't interfere with that element's
       position: sticky. */
  overflow: hidden;
}
.technology-heading {
  display: grid;
  place-items: center;
}
.technology-heading-text {
  position: relative;
  z-index: 1;
  /* calc(100% - 2rem) instead of a flat 100%: gives the text its own
       1rem breathing room on each side beyond .aqp-container's padding, so
       it doesn't read as glued to the same edge tech-nav/tech-captions
       align to just below it. */
  width: min(73.75rem, calc(100% - 2rem));
  font-size: clamp(3rem, 8vw, 7.375rem);
  margin: 0;
  line-height: 0.92;
  letter-spacing: -0.07em;
  text-align: center;
  /* Explicit rather than relying on inheriting color: cream from the
       ancestor .technology-shell.aqp-text-cream section — a host page's own
       heading CSS (e.g. a theme/page-builder's default h2 color) can
       carry real specificity and beat an inherited value regardless of
       load order, so this can't be left implicit if the component needs
       to survive being dropped into an unknown page. */
  color: var(--color-cream);
  text-shadow: 0 1rem 2rem color-mix(in srgb, var(--color-ink) 30%, transparent);
  transform: translateY(calc(var(--tech-progress, 0) * -9.375rem));
  opacity: clamp(0, calc(1 - var(--tech-progress, 0) * 12), 1);
  @media (min-width: 47.5rem) {
    font-size: clamp(3.625rem, 8vw, 7.375rem);
    text-shadow: 0 1.125rem 3rem
      color-mix(in srgb, var(--color-ink) 46%, transparent);
  }
}
.technology-heading-text::before {
  content: "";
  position: absolute;
  z-index: -1;
  /* Root cause of the horizontal-overflow bug fixed via
       .technology-heading's overflow: hidden above: this bleed used to
       be a flat -4rem on every screen, so on phones (where the text
       already fills most of the available width) it stuck out well
       past the actual viewport edge — overflow: hidden just clips that
       dead space rather than shrinking it. This scales the bleed down
       at the same width this file already treats as "narrow" (the
       existing max-width: 47.5rem tier below), so the glow now fits
       inside the section on small screens instead of relying on the
       clip alone. */
  inset: -3rem -4rem;
  background: radial-gradient(
    60% 65% at 50% 50%,
    color-mix(in srgb, var(--color-ink) 62%, transparent) 0%,
    color-mix(in srgb, var(--color-ink) 28%, transparent) 55%,
    transparent 80%
  );
  pointer-events: none;
}
@media (max-width: 47.5rem) {
  .technology-heading-text::before {
    inset: -2rem -1.25rem;
  }
}

/* .tech-sticky uses REAL `position: sticky` now (markup class .aqp-sticky
   + the rule below), exactly like the reference site — the browser pins
   it on the compositor thread, always frame-perfect with the scroll.
   The previous build faked the pin with a per-frame JS transform to
   dodge an ancestor-overflow problem; on mobile that transform lagged
   the compositor and the two fought = the vibration/jitter. The real
   fix for the ancestor problem is the overflow overrides above
   (.technology-shell + the Divi wrapper chain), not abandoning sticky.
   position: sticky also keeps this box a containing block for its
   position: absolute children (.tech-canvas, .tech-noise, .tech-nav,
   .tech-captions, .tech-progress, the ::after below). */
.tech-sticky {
  position: sticky;
  top: 0;
  z-index: 0;
  height: 100svh;
  /* 100svh (small viewport height) is deliberate: it does NOT change
     when the mobile URL bar shows/hides, so the pinned pane keeps a
     constant height through the whole scroll. 100vh / 100dvh would
     resize it mid-scroll and shift everything = jitter. Matches the
     reference site. */
}
.tech-sticky::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background: linear-gradient(
    180deg,
    transparent 42%,
    color-mix(in srgb, var(--color-ink) 58%, transparent) 74%,
    color-mix(in srgb, var(--color-ink) 92%, transparent) 100%
  );
}

.tech-canvas {
  z-index: 0;
}
.tech-noise {
  z-index: 1;
  pointer-events: none;
  mix-blend-mode: screen;
  background:
    radial-gradient(
      circle at 45% 45%,
      rgba(113, 203, 225, 0.08),
      transparent 33%
    ),
    linear-gradient(
      180deg,
      color-mix(in srgb, var(--color-ink) 8%, transparent),
      color-mix(in srgb, var(--color-ink) 22%, transparent)
    );
}

.tech-nav {
  z-index: 3;
  top: 1.5rem;
  left: 0;
  right: 0;
  margin-inline: auto;
  max-width: var(--container-width);
  padding-inline: var(--container-pad);
  box-sizing: border-box;
  opacity: clamp(0, calc((var(--tech-progress, 0) - 0.16) * 9), 1);
  pointer-events: none;
  transition: opacity 180ms ease;
}
.tech-nav .aqp-button {
  pointer-events: auto;
  border: 0.0625rem solid
    color-mix(in srgb, var(--color-cream) 24%, transparent);
  background: color-mix(in srgb, var(--color-cream) 10%, transparent);
  color: var(--color-cream);
  box-shadow: 0 1.125rem 2.625rem rgba(0, 0, 0, 0.22);
  backdrop-filter: blur(1.125rem);
}
.tech-nav .aqp-button:hover {
  border-color: transparent;
  background: var(--bg-gradient-primary);
  color: var(--color-cream);
}

.tech-logo {
  width: 14.5rem;
  height: auto;
}

.tech-captions {
  left: 0;
  right: 0;
  margin-inline: auto;
  max-width: var(--container-width);
  padding-inline: var(--container-pad);
  box-sizing: border-box;
  bottom: clamp(6rem, 15svh, 9.25rem);
  z-index: 3;
  pointer-events: none;
}

.tech-caption {
  width: min(35rem, 100%);
  opacity: var(--caption-opacity, 0);
  transform: translateY(var(--caption-y, 1.125rem));
  transition:
    opacity 220ms ease,
    transform 220ms ease;
  @media (max-width: 96rem) {
    /* Explicit 15px side inset on phones, same breakpoint this
           file already uses elsewhere for its own phone tier. */
    padding-inline: 0.9375rem;
  }
}
.tech-caption h3 {
  display: grid;
  grid-template-columns: 3.375rem minmax(0, 1fr);
  column-gap: 1rem;
  align-items: center;
  margin: 0 0 1rem;
  padding-bottom: 1rem;
  font-size: clamp(1.625rem, 3vw, 2.625rem);
  font-weight: 560;
  line-height: 1.02;
  letter-spacing: -0.07em;
  color: var(--color-cream);
  text-shadow: 0 1rem 2.75rem
    color-mix(in srgb, var(--color-ink) 70%, transparent);
  position: relative;
}
.tech-caption h3::after {
  /* Gradient divider between the heading and description, all 5
     cards. grid-column: 2 (not 1 / -1) auto-places it into a new row
     under the title text's own column — the number badge sits in
     column 1 — so it lines up flush with the heading/paragraph's left
     edge instead of starting under the badge. 24px (1.5rem) above and
     below comes from this margin-top plus the h3's own margin-bottom,
     above — no separate spacing element needed. */
  content: "";
  width: min(7rem, 100%);
  height: 0.1875rem;
  margin-top: 1.5rem;
  border-radius: 999px;
  background: var(--bg-gradient-primary);
  position: absolute;
  bottom: 0;
}
.tech-caption h3 span {
  /* Visual identity (fill, border, shadow, color, type) lives on the
     shared .number-badge class (section 3, above) — this just places
     it within the grid this h3 lays its number/title out on. */
  align-self: start;
  flex: 0 0 3.375rem;
}
.tech-caption p {
  width: min(32.5rem, 100%);
  margin: 0;
  color: color-mix(in srgb, var(--color-cream) 74%, transparent);
  font-size: clamp(0.9375rem, 1.3vw, 1.125rem);
  line-height: 1.25;
  text-shadow: 0 0.75rem 2rem
    color-mix(in srgb, var(--color-ink) 78%, transparent);
}

.tech-progress {
  left: 50%;
  bottom: clamp(3.375rem, 8svh, 5.5rem);
  z-index: 3;
  width: min(33.75rem, calc(100vw - 3.5rem));
  height: 0.5rem;
  border: 0.0625rem solid
    color-mix(in srgb, var(--color-cream) 20%, transparent);
  /* Tick marks sit at the boundary of each equal fifth (20/40/60/80%),
     matching technology-shell.js's techSnapPoints — one segment per slide. */
  background:
    linear-gradient(
      90deg,
      transparent 19.8%,
      color-mix(in srgb, var(--color-cream) 28%, transparent) 19.8%,
      color-mix(in srgb, var(--color-cream) 28%, transparent) 20.2%,
      transparent 20.2%,
      transparent 39.8%,
      color-mix(in srgb, var(--color-cream) 28%, transparent) 39.8%,
      color-mix(in srgb, var(--color-cream) 28%, transparent) 40.2%,
      transparent 40.2%,
      transparent 59.8%,
      color-mix(in srgb, var(--color-cream) 28%, transparent) 59.8%,
      color-mix(in srgb, var(--color-cream) 28%, transparent) 60.2%,
      transparent 60.2%,
      transparent 79.8%,
      color-mix(in srgb, var(--color-cream) 28%, transparent) 79.8%,
      color-mix(in srgb, var(--color-cream) 28%, transparent) 80.2%,
      transparent 80.2%
    ),
    color-mix(in srgb, var(--color-cream) 10%, transparent);
  transform: translateX(-50%);
  transition: opacity 180ms ease;
}
.tech-progress span {
  width: calc(var(--tech-progress, 0) * 100%);
  border-radius: inherit;
  background: linear-gradient(
    90deg,
    var(--color-primary),
    var(--color-secondary),
    var(--color-secondary-200)
  );
  transform-origin: left;
}

.tech-screen {
  z-index: 2;
  min-height: 100svh;
  pointer-events: none;
}
.tech-intro {
  margin-top: -100svh;
}

.tech-spacer {
  z-index: 2;
  height: 50svh;
}

.tech-part {
  padding: 0 var(--gutter);
}
.tech-part-one {
  padding-top: clamp(7.5rem, 25.4vh, 12.375rem);
  padding-bottom: 3rem;
}

.tech-copy {
  width: min(38.75rem, 100%);
  transform: translateY(calc(var(--tech-progress, 0) * -2.625rem));
  visibility: hidden;
  transition: opacity 160ms ease;
}
.tech-copy h3 {
  margin: 0 0 2.125rem;
  font-size: 2.625rem;
  line-height: 1.02;
  color: var(--color-cream);
}
.tech-copy h3 span {
  color: var(--color-secondary-200);
}
.tech-copy p {
  margin: 0 0 1.125rem;
  color: color-mix(in srgb, var(--color-cream) 78%, transparent);
  font-size: 1.0625rem;
  line-height: 1.25;
}

.tech-part-two {
  z-index: 2;
  min-height: 390svh;
  pointer-events: none;
}

.tech-part-two-title {
  min-height: 100svh;
  margin: 0;
  padding: 2.25rem var(--gutter);
}
.tech-part-two-title span {
  display: block;
  margin: 0;
  font-size: 5.75rem;
  line-height: 0.96;
  text-align: center;
}
.tech-part-two-title span:first-child {
  align-self: flex-start;
  color: var(--color-cream);
}
.tech-part-two-title span:last-child {
  align-self: flex-end;
  color: color-mix(in srgb, var(--color-cream) 78%, transparent);
}

.tech-part-two-content {
  min-height: 152svh;
  padding-top: 50svh;
  background: linear-gradient(
    to top,
    color-mix(in srgb, var(--color-ink) 78%, transparent) 25%,
    transparent
  );
}

.tech-content-inner {
  padding-block: 8rem;
}

.tech-science {
  width: min(47.5rem, 100%);
  gap: 3rem;
}
.tech-science h4 {
  margin: 0;
  font-size: 2.625rem;
  line-height: 1.04;
  color: var(--color-cream);
}
.tech-science p {
  margin: 0;
  max-width: 48.75rem;
  color: color-mix(in srgb, var(--color-cream) 78%, transparent);
  font-size: 1.125rem;
  line-height: 1.5;
}

.tech-fact {
  gap: 0.75rem;
}
.tech-fact strong {
  font-size: 3.625rem;
  line-height: 0.96;
  color: var(--color-cream);
}
.tech-fact span {
  color: color-mix(in srgb, var(--color-cream) 80%, transparent);
  font-size: 1.125rem;
}

.tech-gases span {
  min-width: 11.875rem;
  padding: 0.9375rem 1.25rem;
  border: 0.0625rem solid
    color-mix(in srgb, var(--color-cream) 28%, transparent);
  background: color-mix(in srgb, var(--color-ink) 62%, transparent);
  color: color-mix(in srgb, var(--color-cream) 85%, transparent);
  text-align: center;
  animation: gasPulse 2.8s ease-in-out infinite;
}
.tech-gases span:last-child {
  animation-delay: 1.15s;
}

@keyframes gasPulse {
  0%,
  100% {
    transform: translateY(0);
    background: var(--color-cream);
  }
  50% {
    transform: translateY(0.75rem);
    background: var(--color-secondary-200);
  }
}

@media (max-width: 56.1875rem) {
  .tech-logo {
    width: 12.375rem;
  }
  .tech-nav .aqp-button {
    min-height: 3rem;
    padding: 0 1.125rem;
  }
  .tech-progress {
    bottom: 2rem;
    width: min(20.625rem, calc(100vw - 3rem));
  }
  .tech-part-one {
    align-items: flex-end;
    padding-top: 0;
    padding-bottom: 2.625rem;
  }
  .tech-copy h3 {
    font-size: 2.125rem;
  }
  .tech-copy p {
    font-size: 1rem;
  }
  .tech-part-two-title {
    justify-content: space-between;
    gap: 0;
  }
  .tech-part-two-title span {
    font-size: 3.375rem;
  }
  .tech-part-two-title span:first-child,
  .tech-part-two-title span:last-child {
    align-self: stretch;
  }
  .tech-content-inner {
    padding-block: 2.5rem;
  }
  .tech-science {
    gap: 1.25rem;
  }
  .tech-science h4 {
    font-size: 1.75rem;
  }
  .tech-science p {
    font-size: 1rem;
  }
  .tech-gases {
    gap: 0.625rem;
  }
  .tech-gases span {
    min-width: 0;
    padding: 0.75rem 0.875rem;
    font-size: 0.75rem;
  }
  .tech-labels {
    gap: 1.5rem;
  }
  .tech-fact {
    gap: 2.25rem;
  }
  .tech-fact strong {
    font-size: 2.75rem;
  }
}

@media (max-width: 47.5rem) {
  .tech-caption h3 {
    grid-template-columns: 2.75rem minmax(0, 1fr);
  }
  .tech-caption h3 span {
    width: 2.75rem;
    height: 2.75rem;
    flex-basis: 2.75rem;
    font-size: 0.6875rem;
  }
}

/* ==========================================================================
   SCIENTIFIC FOUNDATION — "Foundation at Scale" metrics reel
   Extracted from the Aquila Path theme (assets/css/components/_metrics.css
   + every design token / shared component / utility class its markup
   relies on that technology-shell's own block above didn't already
   cover). Pairs with the metrics-reel JS appended to customfile.js and
   scientific-foundation.html (the Divi Code module) for this section's
   markup.

   Required markup skeleton:

   section.aqp-section-padding.aqp-relative[aria-label="Scientific foundation"]
     img.metrics-left-watermark
     div.metrics-scroll.aqp-relative[data-metrics-scroll]
       div.metrics-sticky.aqp-relative[data-metrics-sticky]
         .aqp-container
           .metrics-grid.aqp-grid
             .metrics-left
               p.eyebrow / h2 / p.aqp-text-gray.aqp-h6
             .metrics-right
               .metrics-viewport.aqp-relative.aqp-overflow-hidden[data-metrics-viewport]
                 .metrics-track[data-metrics-track]
                   article.metric-card[data-metric-card]   (repeatable)
                     h4, p.aqp-text-lg, p.aqp-text-lg

   External dependencies NOT covered by this block:
     - metrixbgLogo.svg — the faint left-edge watermark image. Same
       images/ folder as everything else.
     - AOS (optional) — data-aos* attributes carried over from the
       source markup for a scroll-reveal fade; see the [data-aos]
       fallback rule below for what happens without it loaded.

   STICKY PIN: .metrics-sticky uses REAL `position: sticky` (rule below),
   exactly like .tech-sticky in the technology-shell block above. The
   browser pins it on the compositor thread — always frame-perfect with
   the scroll. An earlier build faked the pin with a per-frame JS
   transform on .metrics-sticky to dodge an ancestor-overflow problem
   (Divi 5's animation runtime can set #page-container { overflow-y:
   hidden }, which turns an ancestor into a scroll container and breaks
   the native pin); on scroll that hand-computed transform lagged the
   compositor by a frame and the two fought — that was the left column's
   visible vibration/jitter. The real fix for the ancestor problem is the
   scoped overflow overrides below (:has(.metrics-scroll) on this
   component's own Divi wrapper chain), not abandoning sticky. The
   metrics-reel JS now only drives the right-hand reel (translateY on
   .metrics-track) and the tall spacer height — it never touches
   .metrics-sticky's position.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Design tokens this block needs that technology-shell's own :root
      didn't already define.
   -------------------------------------------------------------------------- */
:root {
  --color-gray: #333333;
  --color-gray-200: #101010;
  --color-gray-300: #646464;

  --text-h6: 1.0625rem;
  --text-3xl: 2rem;
  --text-lg: 1.125rem;
}
@media (min-width: 40rem) {
  :root {
    --text-h6: 1.125rem;
    --text-3xl: 2.75rem;
  }
}
@media (min-width: 64rem) {
  :root {
    --text-h6: 1.25rem;
    --text-3xl: 3.375rem;
  }
}

/* --------------------------------------------------------------------------
   2. Shared components/utilities this block needs that technology-shell's
      own utility block didn't already cover.
   -------------------------------------------------------------------------- */
h6,
.aqp-h6 {
  font-size: var(--text-h6);
  line-height: 1.2;
}
.aqp-text-3xl {
  font-size: var(--text-3xl);
  line-height: 1.1;
}
.aqp-text-lg {
  font-size: var(--text-lg);
  line-height: 1.33;
}

.aqp-text-gray {
  color: var(--color-gray);
}
.aqp-text-gray-200 {
  color: var(--color-gray-200);
}
.aqp-text-gray-300 {
  color: var(--color-gray-300);
}
.aqp-text-secondary-200 {
  color: var(--color-secondary-200);
}

.aqp-inline-flex {
  display: inline-flex;
}
.aqp-uppercase {
  text-transform: uppercase;
}
.aqp-m-0 {
  margin: 0;
}
.aqp-pt-3 {
  padding-top: 0.75rem;
}
.aqp-pb-4 {
  padding-bottom: 1rem;
}

/* Was ".section-padding" in the source theme's _common.css. */
.aqp-section-padding {
  padding-block: 3rem;
}
@media (min-width: 48rem) {
  .aqp-section-padding {
    padding-block: 4rem;
  }
}
@media (min-width: 61.31rem) {
  .aqp-section-padding {
    padding-block: 5rem;
  }
}

/* Optional AOS fallback — without the real AOS library loaded,
   [data-aos] elements just sit at this resting offset forever rather
   than disappearing or misbehaving. */
/* [data-aos="fade-up"] {
  transform: translateY(1rem);
}
[data-aos="fade-up"].aos-animate {
  transform: translateY(0);
} */

/* --------------------------------------------------------------------------
   3. scientific-foundation component — from
      assets/css/components/_metrics.css, restored to native
      `position: sticky` on .metrics-sticky (see the STICKY PIN note
      above). `top: 6rem` is the CSS offset the browser pins to; the
      metrics-reel JS reads the same 6rem into its `pinOffset` only to
      map scroll position → reel progress, never to move the element.
   -------------------------------------------------------------------------- */
.metrics-section {
  padding: clamp(3rem, 5vw, 5rem) 0;
  background: var(--color-white);
}

/* position: sticky pins to the nearest ANCESTOR scroll container, or the
   viewport if there is none. Divi drops this section into a Code module
   wrapped in section / row / column / module elements (and
   #page-container) that can pick up overflow:hidden at runtime — from
   Divi options, an entrance animation, or a plugin. Any one of them
   silently breaks the pin (that's what forced the old per-frame JS
   transform, and its jitter). Force THIS component's own wrapper chain
   back to non-clipping. Scoped with :has(.metrics-scroll) so no other
   section is touched. (#page-container is already forced visible on this
   page by the technology-shell block's :has(#technology) override;
   repeated here so this component doesn't depend on that one existing.) */
#page-container:has(.metrics-scroll) {
  overflow: visible !important;
  overflow-x: clip !important;
}
.et_pb_section:has(.metrics-scroll),
.et_pb_row:has(.metrics-scroll),
.et_pb_column:has(.metrics-scroll),
.et_pb_module:has(.metrics-scroll),
.et_pb_code:has(.metrics-scroll),
.et_pb_code:has(.metrics-scroll) > .et_pb_code_inner {
  overflow: visible !important;
}

/* Pinned fold, but capped well short of the full viewport (unlike
   .tech-sticky's 100svh) — tall enough to read as its own screen while
   pinned, short enough that centering the grid inside it doesn't leave
   big empty margins above/below the content. `top` matches the JS's
   pinOffset (6rem). The mobile/reduced-motion media query below drops
   this back to position: static for the stacked layout. */
.metrics-sticky {
  position: sticky;
  top: 8rem;
  /* height: min(70vh, 42rem); */
  display: flex;
  align-items: center;
}
.metrics-sticky > .aqp-container {
  width: 100%;
}

.metrics-grid {
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  align-items: start;
}

.metrics-left {
  position: relative;
  padding-right: clamp(1.5rem, 3vw, 3rem);
}
.metrics-left-watermark {
  position: absolute;
  left: 0;
  bottom: 0;
  max-width: 35%;
  height: auto;
  width: 80%;
}
.eyebrow {
  gap: 0.625rem;
}
.eyebrow::before {
  content: "";
  width: 1.25rem;
  height: 0.0625rem;
  background: linear-gradient(
    90deg,
    rgba(237, 106, 132, 0) 0.1%,
    #ed6a84 62.24%
  );
}
.eyebrow::after {
  content: "";
  width: 1.25rem;
  height: 0.0625rem;
  background: linear-gradient(
    270deg,
    rgba(237, 106, 132, 0) 0.1%,
    #ed6a84 62.24%
  ) !important;
}
.eyebrowp p {
  position: relative;
  display: inline-block;
  padding: 0 2rem;
}
.eyebrowp p::before {
  position: absolute;
  content: "";
  width: 1.25rem;
  height: 0.0625rem;
  background: linear-gradient(
    90deg,
    rgba(237, 106, 132, 0) 0.1%,
    #ed6a84 62.24%
  );
  left: 0px;
  top: 50%;
}
.eyebrowp p::after {
  position: absolute;
  content: "";
  width: 1.25rem;
  height: 0.0625rem;
  background: linear-gradient(
    270deg,
    rgba(237, 106, 132, 0) 0.1%,
    #ed6a84 62.24%
  ) !important;
  right: 0px;
  top: 50%;
}

/* Fade only the bottom edge, where the next card is entering — the top 3
   cards should stay fully opaque (matching the reference: only the 4th,
   incoming card is faded). A top fade too would grey out whichever card
   currently sits at the top of the 3 visible ones, which read as wrong. */
.metrics-viewport {
  height: clamp(28rem, 34vw, 36rem);
  mask-image: linear-gradient(to bottom, black 0, black 82%, transparent 100%);
  -webkit-mask-image: linear-gradient(
    to bottom,
    black 0,
    black 82%,
    transparent 100%
  );
  padding-left: 0.25rem;
}
/* .is-end is set by the metrics-reel IIFE once the last card is active —
   there's no next card left to hint at, so the fade is dropped. */
.metrics-viewport.is-end {
  mask-image: none;
  -webkit-mask-image: none;
}

.metrics-track {
  will-change: transform;
}

.metric-card {
  padding: 1.5rem 0 1.5rem 2rem;

  border-left: 0.0625rem solid
    color-mix(in srgb, var(--color-ink) 10%, transparent);
  transition: border-color 300ms ease;
  position: relative;
  &:not(:last-child) {
    border-bottom: 0.0625rem solid
      color-mix(in srgb, var(--color-ink) 10%, transparent);
  }
}

.metric-card.is-active:before {
  content: "";
  background: var(--bg-gradient-primary);
  width: 0.25rem;
  position: absolute;
  left: -0.14rem;
  top: 0;
  border-radius: 10px;
  top: 1.5rem;
  bottom: 1.5rem;
}
.metric-card.is-active h3 {
  background: var(--bg-gradient-primary);
  background-clip: text;
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}

@media (prefers-reduced-motion: reduce), (max-width: 56.1875rem) {
  .metrics-scroll {
    height: auto !important;
  }
  .metrics-sticky {
    position: static;
    top: auto;
    height: auto;
    display: block;
  }
  .metrics-grid {
    grid-template-columns: 1fr;
    gap: 1rem;
  }
  .metrics-left {
    border-right: 0;
    padding-right: 0;
  }
  .metric-card {
    padding: 1.5rem 0 1.5rem 0rem;
    border-left: none;
  }
  .metrics-viewport {
    height: auto;
    mask-image: none;
    -webkit-mask-image: none;
  }
  .metrics-track {
    transform: none !important;
  }
}

/* ==========================================================================
   EVIDENCE-GUIDED DIRECTION — "From uncertainty to evidence-guided
   direction" hover-accordion cards
   Extracted from the Aquila Path theme (assets/css/components/_advantage.css
   + every design token / shared component / utility class its markup
   relies on that the two blocks above didn't already cover).

   Doesn't use position: sticky anywhere, so it isn't exposed to the same
   Divi-animation-runtime conflict documented on .tech-sticky /
   .metrics-sticky above — the hover-accordion is pure flex-grow +
   :has(), and the background-logo drift is already transform-only
   (computed off getBoundingClientRect(), same safe technique used to
   fix the other two).

   Required markup skeleton:

   section.evidence-section.aqp-relative.aqp-overflow-hidden[aria-label="..."]
     img.evidence-bg-logo.aqp-absolute
     .aqp-container.evidence-wrap.aqp-relative
       [heading row: h2, p]
       .evidence-grid.aqp-flex
         article.evidence-card(.evidence-card-large | .evidence-card-tall)
           .evidence-image.aqp-relative.aqp-overflow-hidden
             span.evidence-number.aqp-absolute.aqp-rounded-full.number-badge
             img.aqp-w-full.aqp-h-full.aqp-object-cover
           .evidence-card-body.aqp-relative.aqp-grid
             p.evidence-kicker / h5 / .evidence-card-expand > .evidence-card-expand-inner > p, ul

   External dependencies NOT covered by this block:
     - evidencebgLogo.svg, advantage1.jpg, advantage2.jpg, advantage3.jpg
       — same images/ folder as everything else.
     - .evidence-section already carries isolation: isolate (see its own
       comment below) — that's what keeps .evidence-bg-logo's
       z-index: -1 scoped to just this section's own background instead
       of comparing against unrelated page ancestors and disappearing
       entirely. Load-bearing, not decorative — keep it if this file
       ever gets trimmed.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Design tokens this block needs that the two blocks above didn't
      already define.
   -------------------------------------------------------------------------- */
:root {
  --text-sm: 0.875rem;
}

/* --------------------------------------------------------------------------
   2. Shared components/utilities this block needs that the two blocks
      above didn't already cover.
   -------------------------------------------------------------------------- */
.aqp-text-sm {
  font-size: var(--text-sm);
  line-height: 1.1;
}
.aqp-text-secondary {
  color: var(--color-secondary);
}
.aqp-object-cover {
  object-fit: cover;
}
.aqp-pt-4 {
  padding-top: 1rem;
}
.aqp-pb-8 {
  padding-bottom: 2rem;
}
.aqp-mb-4 {
  margin-bottom: 1rem;
}
.aqp-grid-cols-12 {
  grid-template-columns: repeat(12, minmax(0, 1fr));
}
.aqp-col-span-7 {
  grid-column: span 7 / span 7;
}
/* Tailwind-style responsive prefix — only the one tier/utility pair
   (md:grid) this section's markup actually uses. */
@media (min-width: 48rem) {
  .aqp-md-grid {
    display: grid;
  }
}
@media (min-width: 76.5rem) {
  .aqp-lg-grid {
    display: grid;
  }
}

/* --------------------------------------------------------------------------
   3. evidence-guided-direction component — from
      assets/css/components/_advantage.css.
   -------------------------------------------------------------------------- */
.evidence-section {
  background: var(--bg-gradient-secondary);
  color: var(--color-cream);
  /* Scopes .evidence-bg-logo's z-index: -1 to this section's own
     stacking context — without this, the negative z-index escapes to
     compare against unrelated ancestors instead of just this
     section's own background, which is what was actually hiding it
     entirely rather than just tucking it behind the content. */
  isolation: isolate;
}
@media (min-width: 48rem) {
  span.md-block {
    display: block;
  }
}
p.ptext {
  padding-top: 1.2rem;
}
.evidence-card-body h4 {
  padding: 0px;
}
.evidence-bg-logo {
  top: 0;
  right: 0;
  width: 35rem;
  height: auto;
  z-index: -1;
  pointer-events: none;
  /* Transform is written every scroll frame by the background-logo
     parallax IIFE (customfile.js) — will-change hints the browser to
     put this on its own compositor layer up front instead of promoting
     it on the first scroll event. */
  will-change: transform;
}

.evidence-wrap {
  z-index: 1;
}
/* Explicit rather than relying on inheriting color: cream from the
   ancestor .evidence-section — same reasoning as
   .technology-heading-text above: a host page's own heading CSS (Divi's
   own base styles set an explicit color on every h1-h6, confirmed
   earlier while chasing the .container collision) can carry real
   specificity and beats an inherited value regardless of load order.
   Only the intro heading/paragraph need this — everything inside
   .evidence-card already has its own explicit color (dark text on the
   card's cream background), unaffected either way. */
.evidence-wrap h2 {
  color: var(--color-cream);
  font-weight: 600;
}
.evidence-wrap .aqp-col-span-7 p {
  color: color-mix(in srgb, var(--color-cream) 82%, transparent);
}

/* Accordion row: whichever card is hovered grows via flex-grow, width
   only — no JS, no fixed widths. Height works the other way around:
   align-items: stretch (the flexbox default) makes every card match the
   tallest one automatically, and since .evidence-image is flex: 1 1 auto,
   each card's own image absorbs whatever extra stretched height its
   card picks up — so "equal height, driven by the tallest/expanded
   card" falls out of ordinary flex layout with no measurement needed. */
.evidence-grid {
  align-items: stretch;
  gap: clamp(1.25rem, 2vw, 2.125rem);
}

.evidence-card {
  flex: 0.94 1 0%;
  min-width: 0;
  transform: none;
  /* set by the accordion IIFE (measureTallestActiveHeight) once on load
       and on resize — falls back to align-items: stretch's live/auto
       behaviour until JS runs or if it's unavailable */
  height: var(--evidence-card-h, auto);
  border: 0.0625rem solid
    color-mix(in srgb, var(--color-cream) 56%, transparent);
  border-radius: 1.5rem;
  background: var(--color-cream);
  color: var(--color-ink);
  @media (min-width: 64rem) {
    box-shadow: 0 1.875rem 5.625rem rgba(31, 7, 54, 0.28);
  }
  /* the 120ms delay is a grace period: moving the mouse from one card
       straight to the next crosses the gap in well under that, so this
       "revert to default" transition never gets a chance to start —
       .evidence-card.is-active below overrides it back to 0s so
       *becoming* the active card is always instant, only reverting is
       delayed */
  transition:
    flex-grow 450ms cubic-bezier(0.16, 1, 0.3, 1) 120ms,
    transform 260ms ease,
    box-shadow 260ms ease;
}
.evidence-card-large {
  flex: 1.96 1 0%;
}
/* .is-active is set by the accordion IIFE (mousemove-tracked, not
   :hover) so the active card survives a scroll instead of reverting the
   moment the cursor ends up somewhere else on a stationary pointer. */
.evidence-grid:has(.evidence-card.is-active) .evidence-card {
  flex-grow: 0.94;
}
.evidence-grid:has(.evidence-card.is-active) .evidence-card.is-active {
  flex-grow: 1.96;
  transition-delay: 0s;
}
@media (min-width: 64rem) {
  .evidence-card.is-active {
    /* transform: translateY(-0.5rem); */
    box-shadow: 0 2.125rem 5.5rem rgba(31, 7, 54, 0.36);
  }
}

.evidence-image {
  /* No aspect-ratio here on purpose: with one, the image's height
       reacts to the flex-grow (width) transition *as well as* the text
       reveal below fighting over the same row height at once — two
       independently-eased animations racing each other, which is what
       caused a visible dip mid-hover. With just flex: 1 1 auto, the
       image purely fills whatever the text doesn't need, so there's
       only one thing driving height changes during a hover swap.
       object-fit: cover on the <img> handles whatever size that ends
       up being without distortion. */
  flex: 1 1 auto;
  min-height: 0;
  background: color-mix(in srgb, var(--color-secondary) 8%, transparent);
}
.evidence-image::after {
  content: "";
  position: absolute;
  inset: auto 0 0;
  height: 46%;
  background: linear-gradient(to bottom, transparent, var(--color-cream) 86%);
  pointer-events: none;
}
.evidence-image img {
  transition:
    transform 700ms cubic-bezier(0.19, 1, 0.22, 1),
    filter 300ms ease;
}
.evidence-card.is-active .evidence-image img {
  transform: scale(1.045);
  filter: saturate(1.06);
}

/* Figma treatment: only the prominent card carries a colour image, the
   other two go grayscale. This rides the SAME state the accordion IIFE
   already maintains (.evidence-card.is-active, plus the .evidence-card-large
   fallback for before the pointer has picked a card) — no separate
   active-card detection. The filter transition on .evidence-image img
   above (300ms ease) carries the grayscale<->colour fade.
     - once a card is active: every card that ISN'T it → grayscale
       (the active card keeps the saturate(1.06) rule above). */
.evidence-grid:has(.evidence-card.is-active)
  .evidence-card:not(.is-active)
  .evidence-image
  img {
  filter: grayscale(100%);
}
/*   - before any card is active: the large card is the prominent one,
       so the two non-large cards → grayscale. */
.evidence-grid:not(:has(.evidence-card.is-active))
  .evidence-card:not(.evidence-card-large)
  .evidence-image
  img {
  filter: grayscale(100%);
}

.evidence-number {
  /* Visual identity (fill, border, shadow, color, type) lives on the
     shared .number-badge class (technology-shell block, above) — this
     just positions it against .evidence-image (relative), which
     .aqp-absolute (markup) anchors it to. */
  top: 1.75rem;
  left: 1.75rem;
  z-index: 2;
}

.evidence-card-body {
  flex: 0 0 auto;
  gap: 0.675rem;
  z-index: 1;
  padding: 1.25rem;
}

/* Description (paragraph + list) fades/slides in for the wide card — the
   default-wide .evidence-card-large, or whichever card is .is-active —
   and collapses for the other two. grid-template-rows: 0fr -> 1fr is
   used instead of display: none/block specifically because display
   can't transition; this can, so the reveal is an actual 300-500ms
   animation instead of an instant snap. */
.evidence-card-expand {
  display: grid;
  grid-template-rows: 0fr;
  opacity: 0;
  /* same 120ms grace period as .evidence-card's flex-grow — collapsing
       is delayed, becoming the active card's expand rule (0s, below)
       overrides it back to instant */
  transition:
    grid-template-rows 450ms cubic-bezier(0.16, 1, 0.3, 1) 120ms,
    opacity 450ms cubic-bezier(0.16, 1, 0.3, 1) 120ms;
}
.evidence-card-expand-inner {
  overflow: hidden;
  min-height: 0;
}
.evidence-card-large .evidence-card-expand {
  grid-template-rows: 1fr;
  opacity: 1;
}
.evidence-grid:has(.evidence-card.is-active)
  .evidence-card.is-active
  .evidence-card-expand {
  grid-template-rows: 1fr;
  opacity: 1;
  transition-delay: 0s;
}
.evidence-grid:has(.evidence-card.is-active)
  .evidence-card-large:not(.is-active)
  .evidence-card-expand {
  grid-template-rows: 0fr;
  opacity: 0;
}

.evidence-kicker {
  gap: 0.625rem;
  margin: 0;
}
.evidence-kicker::before {
  content: "";
  width: 1.75rem;
  height: 0.125rem;
  border-radius: 999px;
  background: var(--color-secondary);
}

.evidence-card p {
  margin: 0;
}
.evidence-card ul {
  gap: 0.25rem;
  margin: 1rem 0 0;
  padding-left: 1.1rem;
}

/* Below desktop (1024px), the hover-driven flex-grow accordion doesn't
   translate to touch — there's no cursor to widen a card, and shrinking
   three columns to fit a phone/tablet just makes all three too narrow
   to read. Below this width the row becomes a horizontal, swipe/scroll-
   snapped carousel instead: every rule here overrides the desktop
   flex-grow/hover-accordion behaviour above, not a separate layout
   bolted on next to it. Percent-based flex-basis (not a fixed px card
   width) is what makes "~1.2 cards on tablet, ~1 card + a peek on
   phone" fall out of ordinary responsive flex instead of needing a
   width recalculated per breakpoint. */
.evidence-section {
  padding: 3rem 0 3rem;
}
@media (min-width: 48rem) {
  .evidence-section {
    padding: 4rem 0 4rem;
  }
}
@media (min-width: 61.31rem) {
  .evidence-section {
    padding: 5rem 0 5rem;
  }
}
@media (max-width: 63.9375rem) {
  .evidence-grid {
    flex-wrap: nowrap;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    overflow-y: hidden;
  }
  .evidence-grid::-webkit-scrollbar {
    display: none;
  }
  .evidence-card,
  .evidence-card-large,
  .evidence-grid:has(.evidence-card.is-active) .evidence-card,
  .evidence-grid:has(.evidence-card.is-active) .evidence-card.is-active {
    /* ~1.2 cards visible on tablet — one full card, ~20% of the next
       peeking past the gap as a "swipe for more" affordance. */
    flex: 0 0 82%;
    scroll-snap-align: start;
    /* stacked/carousel cards size themselves; the desktop JS-measured
       equal height (measureTallestActiveHeight) doesn't apply once
       cards aren't sharing a row anymore */
    height: auto;
  }
  /* The hover-lift + shadow bump is a desktop mouse-hover cue; a
     trackpad-equipped tablet can still fire the mousemove that sets
     .is-active, so this neutralizes the visual side effect rather than
     relying on touch devices simply never triggering it. */

  .evidence-card.is-active {
    transform: none;
    @media (min-width: 64rem) {
      box-shadow: 0 1.875rem 5.625rem rgba(31, 7, 54, 0.28);
    }
  }

  .evidence-card.is-active .evidence-image img {
    transform: none;
    filter: none;
  }
  /* Carousel shows one card at a time, so the desktop "prominent card in
     colour, siblings grayscale" split doesn't apply — every card image
     stays full colour here. Mirrors the two desktop grayscale rules so
     it cancels exactly those. */
  .evidence-grid:has(.evidence-card.is-active)
    .evidence-card:not(.is-active)
    .evidence-image
    img,
  .evidence-grid:not(:has(.evidence-card.is-active))
    .evidence-card:not(.evidence-card-large)
    .evidence-image
    img {
    filter: none;
  }
  .evidence-image {
    flex: none;
    aspect-ratio: 16 / 9;
  }
  .evidence-card-body {
    padding: 1.25rem;
  }
  /* one full card at a time, so there's no hover-driven card to accordion
     against — content stays expanded regardless of .is-active */
  .evidence-card-expand,
  .evidence-grid:has(.evidence-card.is-active)
    .evidence-card-large:not(.is-active)
    .evidence-card-expand {
    grid-template-rows: 1fr;
    opacity: 1;
  }
  .evidence-card p:not(.evidence-kicker),
  .evidence-card li {
    font-size: 1.0625rem;
  }
  .evidence-number {
    top: 1.375rem;
    left: 1.375rem;
    width: 3.875rem;
    height: 3.875rem;
    font-size: 1.5625rem;
  }

  @media (max-width: 47.5rem) {
    .evidence-card,
    .evidence-card-large,
    .evidence-grid:has(.evidence-card.is-active) .evidence-card,
    .evidence-grid:has(.evidence-card.is-active) .evidence-card.is-active {
      /* one full card + ~12% of the next peeking in, per the phone spec */
      flex: 0 0 88%;
    }
    .evidence-number {
      width: 2.75rem;
      height: 2.75rem;
      font-size: 0.6875rem;
    }
  }
}
/* ==========================================================================
   TAB SECTION — "Tailored Solutions for the Oncology Ecosystem" audience
   tabs (For Clinicians / For Patients). Extracted from the Aquila Path
   theme: markup from templates/home.php, styles from
   assets/css/components/_tabs.css. Pairs with the tab-switching JS
   appended to customfile.js and tab-section.html (the Divi Code module)
   for this section's markup.

   Required markup skeleton:

   section.tab-section
     .aqp-container
       .tab-intro
         h2 / p
       .tab-grid
         .tab-media
           img#tabImage
         .tab-buttons[role="tablist"]
           button.tab-btn[data-tab][data-image][data-image-alt]  (repeatable)
           span.tab-underline#tabUnderline
         .tab-panel-wrap
           .tab-panel[data-panel][role="tabpanel"]  (repeatable, matches
             a .tab-btn's data-tab)

   Uses the shared --color-primary / --color-ink / --bg-gradient-primary
   tokens and .aqp-container already defined at the top of this file — no
   new design tokens needed.

   DIVI CONFLICT NOTE: every class here (.tab-section, .tab-grid,
   .tab-media, .tab-buttons, .tab-btn, .tab-underline, .tab-panel-wrap,
   .tab-panel, .tab-link, .tab-intro) and every id (#tabImage,
   #tabUnderline) was checked against the installed Divi theme's compiled
   CSS (style.min.css, style-static.min.css, module-library.css, etc.) —
   no matches. Divi's own Tabs module namespaces everything under
   .et_pb_tab / .et_pb_tabs, so there's no collision risk from either
   direction.
   ========================================================================== */

.tab-section {
  overflow: hidden;
  /* padding-block: 2.5rem; */
}
/* @media (min-width: 40rem) {
  .tab-section {
    padding-block: 5rem;
  }
} */

.tab-intro {
  padding-bottom: 2rem;
  margin-bottom: 1rem;
}
.tab-intro h2 {
  font-size: 2rem;
  font-weight: 600;
}
.tab-intro p {
  max-width: 34rem;
  padding-top: 1.5rem;
  font-size: 1.0625rem;
  line-height: 1.2;
}
@media (min-width: 48rem) {
  .tab-intro {
    display: grid;
    grid-template-columns: 1fr 1fr;
  }
}

/* .tab-media spans both rows, so its height comes FROM the buttons+panel
   column (align-self: stretch), not the other way around. */
.tab-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: auto 1fr;
  align-items: center;
  grid-template-areas: "media buttons" "media panels";
  column-gap: clamp(2.5rem, 5vw, 4.375rem);
  row-gap: clamp(1.5rem, 5vw, 2.5rem);
}

.tab-media {
  grid-area: media;
  align-self: stretch;
  position: relative;
  overflow: hidden;
  border-radius: 1.5rem;
  /* box-shadow: 0 1.5rem 3rem rgba(11, 16, 24, 0.12); */
}
.tab-media img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition:
    opacity 100ms ease,
    transform 200ms ease;
}
.tab-media img.is-switching {
  opacity: 0;
  transform: scale(0.99);
}

.tab-buttons {
  grid-area: buttons;
  align-self: start;
  position: relative;
  display: flex;
  gap: 2rem;
  border-bottom: 0.0625rem solid
    color-mix(in srgb, var(--color-ink) 12%, transparent);
}
.tab-btn {
  padding: 0 0 1rem;
  background: none;
  border: none;
  cursor: pointer;
  color: color-mix(in srgb, var(--color-ink) 55%, transparent);
  font-weight: 600;
  transition: color 300ms ease;
}
.tab-btn.is-active {
  color: var(--color-ink);
}

.tab-underline {
  position: absolute;
  bottom: -0.0625rem;
  left: 0;
  height: 0.125rem;
  width: 6.875rem;
  background: var(--bg-gradient-primary);
  transition:
    transform 400ms cubic-bezier(0.16, 1, 0.3, 1),
    width 400ms cubic-bezier(0.16, 1, 0.3, 1);
}

.tab-panel-wrap {
  grid-area: panels;
  align-self: start;
}
.tab-panel h3 {
  margin-bottom: 1rem;
  padding: 0;
}
.tab-panel p {
  max-width: 30rem;
  margin-bottom: 1.5rem;
  color: color-mix(in srgb, var(--color-ink) 65%, transparent);
}
.tab-panel.is-animating {
  animation: tabPanelIn 400ms cubic-bezier(0.16, 1, 0.3, 1);
}
@keyframes tabPanelIn {
  from {
    opacity: 0;
    transform: translateY(0.875rem);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.tab-link {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  color: var(--color-primary);
  font-weight: 600;
  text-decoration: none;
}
.tab-link svg {
  transition: transform 300ms ease;
}
.tab-link:hover svg {
  transform: translateX(0.1875rem);
}

@media (max-width: 64em) {
  /* stacked: tabs above the image, panel content below it */
  .tab-grid {
    grid-template-columns: 1fr;
    grid-template-areas:
      "buttons"
      "media"
      "panels";
    gap: clamp(1.5rem, 4vw, 2rem);
  }
  .tab-buttons {
    margin-bottom: 1.25rem;
  }
  .tab-media {
    aspect-ratio: 4 / 3;
    margin-bottom: 0.5rem;
  }
}

.advantageSlider .et_pb_slide_description {
  padding: 0px 0 2rem 0;
  margin-top: auto;
}
.advantageSlider .et_pb_slider_container_inner {
  vertical-align: bottom;
}
.advantageSlider .et_pb_slides .et_pb_slide {
  padding: 0 2rem !important;
}
.advantageSlider .et_pb_slides .et_pb_slide:before {
  content: "";
  inset: 0;
  width: 100%;
  height: 100%;
  position: absolute;
  background:
    linear-gradient(28deg, rgba(0, 0, 0, 0.8) 20.69%, rgba(0, 0, 0, 0) 45.44%),
    url(<path-to-image>) #d3d3d300 0px -121.099px / 100% 153.822% no-repeat;
}
.advantageSlider .et_pb_slides .et_pb_slide {
  aspect-ratio: 2.5 / 1;
}
.advantageSlider .et-pb-controllers {
  width: max-content !important;
  margin: 0px auto !important;
  left: 0px;
  right: 0px;
  background: color-mix(in srgb, var(--color-white) 35%, transparent);
  backdrop-filter: blur(0.25rem);
  border-radius: 999px;
  bottom: clamp(1rem, 2.5vw, 1.75rem);
  gap: 0.375rem;
  padding: 0.375rem;
  transform: translateX(-50%);
  display: flex;
}
.advantageSlider .et-pb-controllers .et-pb-active-control {
  width: 1.625rem;
  background-color: #f83260;
}
.advantageSlider .et-pb-controllers a {
  width: 0.5rem;
  height: 0.375rem;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: color-mix(in srgb, var(--color-white) 80%, transparent);
  cursor: pointer;
  transition:
    width 300ms ease,
    background-color 300ms ease;
  display: inline-block;
  margin: 0px;
}

/* ==========================================================
   Aquila Path Foundation Model Section
   ----------------------------------------------------------
   Framework diagram used inside a Divi Code module:
   Tissue Evidence  ->  APFM core  ->  Clinical Context  ->  TruGrade output.
   Ported from the reference technology.css (rules merged + de-duplicated).
   Everything is scoped to .apfm-framework; the component-local colour
   tokens (--apfm-*) do not leak and do not collide with Divi.
   Pure CSS - no JavaScript. Animations respect prefers-reduced-motion.
   ========================================================== */

.apfm-framework {
  /* component-scoped tokens */
  --apfm-plum: #461173;
  --apfm-magenta: #dc4b6a;
  --apfm-rose: #ee6c9a;
  --apfm-cream: #fffaf7;
  --apfm-gradient: linear-gradient(135deg, #dc4b6a, #992470 58%, #461173);

  position: relative;
  display: grid;
  grid-template-columns:
    minmax(210px, 0.86fr) minmax(70px, 0.28fr)
    minmax(310px, 1.08fr)
    minmax(70px, 0.28fr) minmax(210px, 0.86fr);
  grid-template-rows: auto auto;
  gap: 1rem;
  align-items: center;
}

/* ---- Input cards (Tissue Evidence / Clinical Context) ---- */
.apfm-input {
  position: relative;
  min-height: 310px;
  display: grid;
  align-content: space-between;
  gap: 24px;
  overflow: hidden;
  padding: 28px;
  border: 1px solid rgba(70, 17, 115, 0.14);
  border-radius: 28px;
  background: linear-gradient(
    145deg,
    rgba(255, 250, 247, 0.94),
    rgba(245, 237, 248, 0.88)
  );
  box-shadow: 0 24px 70px rgba(70, 17, 115, 0.1);
}
.apfm-input::after {
  content: "";
  position: absolute;
  right: -54px;
  bottom: -72px;
  width: 170px;
  aspect-ratio: 1;
  opacity: 0.04;
  background: var(--apfm-gradient);
  -webkit-mask: url("images/aquila-mark.svg") center / contain no-repeat;
  mask: url("images/aquila-mark.svg") center / contain no-repeat;
}
.apfm-input > p {
  position: relative;
  z-index: 1;
  margin: 0;
  color: rgba(11, 16, 24, 0.58);
  font-size: 14px;
  line-height: 1.2;
}
.apfm-tissue > img {
  width: 100%;
  filter: drop-shadow(0 16px 16px rgba(70, 17, 115, 0.16));
}

/* ---- Card label + number badge ---- */
.apfm-card-label {
  display: flex;
  gap: 14px;
  align-items: center;
}
.apfm-card-label strong {
  color: var(--apfm-plum);
  font-size: 13px;
  font-weight: 780;
  letter-spacing: 0.09em;
  text-transform: uppercase;
}
.apfm-num {
  display: inline-grid;
  flex: 0 0 48px;
  width: 48px;
  height: 48px;
  place-items: center;
  border: 1px solid transparent;
  border-radius: 999px;
  background:
    linear-gradient(#fffaf7, #fffaf7) padding-box,
    var(--apfm-gradient) border-box;
  color: var(--apfm-plum);
  font-size: 12px;
  font-weight: 780;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
  box-shadow: 0 12px 30px rgba(70, 17, 115, 0.12);
}

/* ---- Clinical Context: illustrative form fields ---- */
.apfm-context-fields {
  display: grid;
  gap: 14px;
}
.apfm-context-fields > span {
  position: relative;
  display: block;
  height: 46px;
  overflow: hidden;
  border: 1px solid rgba(70, 17, 115, 0.12);
  border-radius: 999px;
  background: rgba(255, 250, 247, 0.82);
}
.apfm-context-fields > span::before {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  width: 31%;
  background: rgba(70, 17, 115, 0.09);
}
.apfm-context-fields i {
  position: absolute;
  top: 50%;
  right: 14px;
  width: 44%;
  height: 5px;
  border-radius: 999px;
  background: linear-gradient(
    90deg,
    rgba(220, 75, 106, 0.26),
    rgba(70, 17, 115, 0.08)
  );
  transform: translateY(-50%);
}

/* ---- Connectors: animated gradient line + flowing dot + arrowhead ---- */
.apfm-connector {
  position: relative;
  height: 2px;
  overflow: visible;
  background: linear-gradient(
    90deg,
    rgba(70, 17, 115, 0.1) 0%,
    rgba(220, 75, 106, 0.25) 30%,
    rgba(220, 75, 106, 0.95) 50%,
    rgba(70, 17, 115, 0.12) 100%
  );
  background-size: 220% 100%;
  animation: apfmFlowLine 3.4s linear infinite;
}
.apfm-connector-right {
  animation-direction: reverse;
}
.apfm-connector-left {
  background: linear-gradient(
    90deg,
    rgba(70, 17, 115, 0.1) 0%,
    rgba(70, 17, 115, 0.9) 52%,
    rgba(153, 36, 112, 0.3) 100%
  );
  background-size: 220% 100%;
}
.apfm-connector span {
  position: absolute;
  top: 50%;
  left: 0;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--apfm-magenta);
  box-shadow:
    0 0 0 7px rgba(220, 75, 106, 0.08),
    0 0 20px rgba(220, 75, 106, 0.52);
  transform: translate(-50%, -50%);
  animation: apfmFlowRight 3.4s ease-in-out infinite;
}
.apfm-connector-right span {
  animation-name: apfmFlowLeft;
}
.apfm-connector-left span {
  background: var(--apfm-plum);
  box-shadow:
    0 0 0 7px rgba(70, 17, 115, 0.08),
    0 0 20px rgba(70, 17, 115, 0.42);
}
.apfm-connector i {
  position: absolute;
  top: 50%;
  width: 9px;
  height: 9px;
  border-top: 2px solid var(--apfm-magenta);
  border-right: 2px solid var(--apfm-magenta);
}
.apfm-connector-left i {
  right: 0;
  border-color: var(--apfm-plum);
  transform: translateY(-50%) rotate(45deg);
}
.apfm-connector-right i {
  left: 0;
  transform: translateY(-50%) rotate(-135deg);
}

/* ---- Core: Aquila Path Foundation Model card ---- */
.apfm-core {
  position: relative;
  min-height: 410px;
  display: grid;
  place-items: center;
  align-content: center;
  gap: 14px;
  overflow: hidden;
  padding: 44px 38px;
  border: 1px solid rgba(255, 250, 247, 0.16);
  border-radius: 38px;
  background:
    radial-gradient(
      circle at 76% 20%,
      rgba(220, 75, 106, 0.22),
      transparent 34%
    ),
    linear-gradient(150deg, #271132, #0f0918 68%);
  color: var(--apfm-cream);
  text-align: center;
  box-shadow:
    0 40px 100px rgba(70, 17, 115, 0.28),
    0 0 70px rgba(220, 75, 106, 0.12),
    inset 0 1px 0 rgba(255, 250, 247, 0.12);
}
.apfm-core-geometry {
  position: absolute;
  inset: 0;
  opacity: 0.24;
}
.apfm-core-geometry i {
  position: absolute;
  background: linear-gradient(
    135deg,
    rgba(220, 75, 106, 0.8),
    rgba(70, 17, 115, 0.7)
  );
  clip-path: polygon(0 0, 100% 48%, 30% 100%);
}
.apfm-core-geometry i:nth-child(1) {
  top: 5%;
  left: -8%;
  width: 78%;
  height: 44%;
  transform: rotate(14deg);
}
.apfm-core-geometry i:nth-child(2) {
  top: 22%;
  right: -9%;
  width: 66%;
  height: 52%;
  transform: rotate(-18deg);
}
.apfm-core-geometry i:nth-child(3) {
  bottom: -14%;
  left: 20%;
  width: 72%;
  height: 54%;
  transform: rotate(12deg);
}
.apfm-core-mark {
  position: relative;
  z-index: 1;
  display: grid;
  width: 88px;
  height: 88px;
  place-items: center;
  margin-bottom: 6px;
  border: 1px solid rgba(255, 250, 247, 0.2);
  border-radius: 50%;
  background: rgba(255, 250, 247, 0.06);
  backdrop-filter: blur(14px);
}
.apfm-core-mark img {
  width: 48px;
  filter: brightness(0) invert(1);
}
.apfm-core small,
.apfm-core h3,
.apfm-core p {
  position: relative;
  z-index: 1;
  margin: 0;
}
.apfm-core small {
  color: var(--apfm-rose);
  font-size: var(--gvid-ol4vltpqxo);
  font-weight: 500;
  letter-spacing: 0.18em;
}
.apfm-core h3 {
  font-size: clamp(32px, 3.2vw, 48px);
  font-weight: 700;
  line-height: 0.98;
  letter-spacing: -0.065em;
  color: var(--gcid-q6szfi0r1v);
}
.apfm-core p {
  color: #fff;
  font-size: var(--gvid-e5fzc69sip);
}

/* ---- Output: TruGrade Score card + vertical connector ---- */
.apfm-output-connector {
  position: relative;
  grid-column: 3;
  justify-self: center;
  width: 2px;
  height: 30px;
  /* margin-bottom: -20px; */
  background: linear-gradient(
    180deg,
    rgba(220, 75, 106, 0.22),
    var(--apfm-magenta)
  );
  box-shadow: 0 0 16px rgba(220, 75, 106, 0.22);
}
.apfm-output-connector::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: -1px;
  width: 9px;
  height: 9px;
  border-right: 2px solid var(--apfm-magenta);
  border-bottom: 2px solid var(--apfm-magenta);
  transform: translate(-50%, 0) rotate(45deg);
}
.apfm-output-connector span {
  position: absolute;
  top: 0;
  left: 50%;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--apfm-magenta);
  box-shadow:
    0 0 0 7px rgba(220, 75, 106, 0.08),
    0 0 18px rgba(220, 75, 106, 0.55);
  transform: translate(-50%, -50%);
  animation: apfmFlowDown 2.5s ease-in-out infinite;
}
.apfm-output {
  position: relative;
  grid-column: 3;
  justify-self: center;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 20px;
  width: min(390px, 100%);
  overflow: hidden;
  padding: 20px 24px;
  border: 1px solid rgba(220, 75, 106, 0.42);
  border-radius: 22px;
  background:
    radial-gradient(
      circle at 90% 20%,
      rgba(238, 108, 154, 0.2),
      transparent 34%
    ),
    linear-gradient(
      135deg,
      rgba(255, 250, 247, 0.98),
      rgba(245, 237, 248, 0.96)
    );
  box-shadow:
    0 24px 70px rgba(70, 17, 115, 0.14),
    0 0 0 1px rgba(220, 75, 106, 0.06);
  animation: apfmOutputGlow 4.8s ease-in-out infinite;
}
.apfm-output::before {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(
    105deg,
    transparent 20%,
    rgba(255, 255, 255, 0.72) 46%,
    transparent 70%
  );
  transform: translateX(-130%);
  animation: apfmOutputSweep 5.8s ease-in-out infinite;
}
.apfm-output > * {
  position: relative;
  z-index: 1;
}
.apfm-output > div {
  display: grid;
  gap: 5px;
}
.apfm-output span {
  color: var(--apfm-magenta);
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
.apfm-output strong {
  color: var(--apfm-plum);
  font-size: 15px;
  line-height: 1.25;
}
.apfm-output img {
  width: 42px;
}

/* ---- Keyframes ---- */
@keyframes apfmFlowLine {
  to {
    background-position: -220% 0;
  }
}
@keyframes apfmFlowRight {
  0% {
    left: 0;
    opacity: 0;
  }
  18% {
    opacity: 1;
  }
  82% {
    opacity: 1;
  }
  100% {
    left: 100%;
    opacity: 0;
  }
}
@keyframes apfmFlowLeft {
  0% {
    left: 100%;
    opacity: 0;
  }
  18% {
    opacity: 1;
  }
  82% {
    opacity: 1;
  }
  100% {
    left: 0;
    opacity: 0;
  }
}
@keyframes apfmFlowDown {
  0% {
    top: 0;
    opacity: 0;
  }
  22% {
    opacity: 1;
  }
  78% {
    opacity: 1;
  }
  100% {
    top: 100%;
    opacity: 0;
  }
}
@keyframes apfmFlowUp {
  0% {
    top: 100%;
    opacity: 0;
  }
  22% {
    opacity: 1;
  }
  78% {
    opacity: 1;
  }
  100% {
    top: 0;
    opacity: 0;
  }
}
@keyframes apfmOutputGlow {
  0%,
  100% {
    box-shadow:
      0 24px 70px rgba(70, 17, 115, 0.12),
      0 0 0 1px rgba(220, 75, 106, 0.05);
  }
  50% {
    box-shadow:
      0 28px 80px rgba(70, 17, 115, 0.17),
      0 0 0 1px rgba(220, 75, 106, 0.24),
      0 0 34px rgba(220, 75, 106, 0.16);
  }
}
@keyframes apfmOutputSweep {
  0%,
  62% {
    transform: translateX(-130%);
  }
  82%,
  100% {
    transform: translateX(130%);
  }
}

/* ---- Responsive ---- */
@media (max-width: 1180px) {
  .apfm-framework {
    grid-template-columns:
      minmax(190px, 0.8fr) 42px minmax(280px, 1fr)
      42px minmax(190px, 0.8fr);
  }
  .apfm-input {
    min-height: 290px;
    padding: 22px;
  }
  .apfm-core {
    min-height: 380px;
  }
}

@media (max-width: 980px) {
  .apfm-framework {
    grid-template-columns: 1fr 24px 1.15fr 24px 1fr;
  }
  .apfm-card-label {
    flex-direction: column;
    align-items: flex-start;
  }
  .apfm-input {
    min-height: 280px;
  }
}

@media (max-width: 767px) {
  .apfm-framework {
    grid-template-columns: 1fr;
    grid-template-rows: auto;
    gap: 18px;
  }
  .apfm-input {
    min-height: 260px;
  }
  .apfm-card-label {
    flex-direction: row;
    align-items: center;
  }

  /* stacking order */
  .apfm-tissue {
    order: 1;
  }
  .apfm-connector-left {
    order: 2;
  }
  .apfm-core {
    order: 3;
    min-height: 360px;
  }
  .apfm-connector-right {
    order: 4;
  }
  .apfm-context {
    order: 5;
  }
  .apfm-output-connector {
    order: 6;
    grid-column: 1;
    height: 34px;
    margin: 0;
  }
  .apfm-output {
    order: 7;
    grid-column: 1;
  }

  /* connectors become vertical */
  .apfm-connector {
    justify-self: center;
    width: 2px;
    height: 38px;
    background: linear-gradient(
      180deg,
      rgba(70, 17, 115, 0.1) 0%,
      rgba(220, 75, 106, 0.9) 54%,
      rgba(70, 17, 115, 0.12) 100%
    );
    background-size: 100% 220%;
  }
  .apfm-connector-left {
    background: linear-gradient(
      180deg,
      rgba(70, 17, 115, 0.1) 0%,
      rgba(70, 17, 115, 0.9) 54%,
      rgba(153, 36, 112, 0.28) 100%
    );
    background-size: 100% 220%;
  }
  .apfm-connector span {
    left: 50%;
    top: 0;
    animation-name: apfmFlowDown;
  }
  .apfm-connector-right span {
    animation-name: apfmFlowUp;
  }
  .apfm-connector-left i {
    right: auto;
    left: 50%;
    top: auto;
    bottom: 0;
    transform: translate(-50%, 0) rotate(135deg);
  }
  .apfm-connector-right i {
    left: 50%;
    top: 0;
    transform: translate(-50%, 0) rotate(-45deg);
  }

  .apfm-num {
    width: 44px;
    height: 44px;
    flex-basis: 44px;
    font-size: 11px;
  }
}

@media (max-width: 520px) {
  .apfm-core {
    border-radius: 28px;
  }
  .apfm-core h3 {
    font-size: 38px;
  }
  .apfm-output {
    border-radius: 18px;
  }
}

/* ----------------------------------------------------------------------
   MOBILE ONLY (<= 767px) — Figma composition.
   Two input cards SIDE BY SIDE above APFM, each with its OWN downward
   connector, then a full-width APFM, then TruGrade.

   Placed after the <=760px and <=520px blocks on purpose so its
   overrides win across the whole mobile range. It re-lays-out the same
   seven existing elements as a 2-column grid — no markup change, no JS:

     row 1 :  [ .apfm-tissue        ] [ .apfm-context        ]
     row 2 :  [ .apfm-connector-left] [ .apfm-connector-right]
     row 3 :  [ .apfm-core  (spans both columns)             ]
     row 4 :  [ .apfm-output-connector (spans both)          ]
     row 5 :  [ .apfm-output (spans both)                     ]

   Arrows: each connector sits in its own column, directly under its
   card, pointing DOWN into APFM. Their DIFFERENT colours are the
   existing ones from the <=760px block, untouched here:
     .apfm-connector-left  -> plum / purple  (belongs to Tissue Evidence)
     .apfm-connector (right) -> magenta / pink (belongs to Clinical Context)
   The right connector's up-arrow + apfmFlowUp (from the <=760px block)
   are the only connector rules flipped back to "down" here.

   Cards: equal-height (align-items:stretch); the two input cards switch
   to flex-column so the tissue image can grow to fill and the clinical
   description can pin to the bottom — no dead space, both card bottoms
   line up so both arrows start from the same line.

     Tissue Evidence     Clinical Context     (side by side)
           |  (purple)          |  (pink)
           v                    v
                   A P F M                    (full width)
                      |
                      v
                 TruGrade Score

   No 01 -> 02 sequence. Verified 370 / 375 / 390 / 414: no overflow,
   no clipping, both cards readable. Desktop (>=1181) and tablet
   (761-980) are untouched — they keep the 3-column row + horizontal
   connectors.
   -------------------------------------------------------------------- */
@media (max-width: 767px) {
  .apfm-framework {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    column-gap: 16px;
    row-gap: 0;
    align-items: stretch;
    position: relative;
  }

  /* row 1 — the two input cards, side by side, equal height */
  .apfm-tissue {
    grid-column: 1;
    grid-row: 1;
  }
  .apfm-context {
    grid-column: 2;
    grid-row: 1;
  }
  .apfm-input {
    display: flex;
    flex-direction: column;
    gap: 14px;
    /* horizontal padding trimmed 18px -> 12px to give the heading the
       width it needs once the number circle is gone (below) */
    padding: 18px 12px;
    min-height: 0;
  }
  /* Hide the 01 / 02 badge entirely on mobile — circle border, number
     and its reserved box all gone (display:none, not just the digit).
     The <strong> heading then occupies that space. Desktop + tablet
     keep the circle (this only lives in the <=767px block). */
  .apfm-num {
    display: none;
  }
  .apfm-card-label {
    flex-direction: column;
    align-items: flex-start;
    gap: 0;
  }
  .apfm-card-label strong {
    font-size: 12px;
    /* keep the existing 12px size; only nudge tracking 0.09em -> 0.06em
       and force one line so "TISSUE EVIDENCE" / "CLINICAL CONTEXT" don't
       wrap in the narrow 2-up column */
    letter-spacing: 0.06em;
    white-space: nowrap;
  }
  .apfm-tissue > img {
    flex: 1 1 auto;
    min-height: 120px;
    width: 100%;
    object-fit: cover;
    border-radius: 14px;
  }
  .apfm-context > p {
    margin-top: auto;
  }

  /* row 2 — one connector per card, in its own column, pointing DOWN.
     Colours stay as the <=760px block set them (left = plum,
     right = magenta) — that IS the per-card treatment. */
  .apfm-connector,
  .apfm-connector-left,
  .apfm-connector-right {
    grid-row: 2;
    justify-self: center;
    width: 2px;
    height: 50px;
    margin: 12px 0 0;
  }
  .apfm-connector-left {
    grid-column: 1;
  }
  .apfm-connector-right {
    grid-column: 2;
  }
  .apfm-connector-right span {
    animation-name: apfmFlowDown;
  }
  .apfm-connector-right i {
    left: 50%;
    right: auto;
    top: auto;
    bottom: 0;
    transform: translate(-50%, 0) rotate(135deg);
  }

  /* row 3 — APFM, full width, compact focal node */
  .apfm-core {
    grid-column: 1 / -1;
    grid-row: 3;
    width: 100%;
    min-height: 0;
    margin-top: 4px;
    padding: 26px 22px;
    gap: 8px;
  }
  .apfm-core-mark {
    width: 58px;
    height: 58px;
    margin-bottom: 0;
  }
  .apfm-core-mark img {
    width: 30px;
  }
  .apfm-core h3 {
    font-size: 28px;
  }

  /* rows 4-5 — TruGrade */
  .apfm-output-connector {
    grid-column: 1 / -1;
    grid-row: 4;
    justify-self: center;
    height: 26px;
    margin: 0.45rem;
  }
  .apfm-output {
    grid-column: 1 / -1;
    grid-row: 5;
    width: 100%;
  }
}

/* ---- Motion preference ---- */
@media (prefers-reduced-motion: reduce) {
  .apfm-connector,
  .apfm-connector span,
  .apfm-output-connector span,
  .apfm-output,
  .apfm-output::before {
    animation: none !important;
  }
}

/* ==========================================================
   Custom Logo Cursor
   ----------------------------------------------------------
   Add the class  custom-logo-cursor  to any Divi Section / Row /
   Column / Module (Advanced -> CSS ID & Classes -> CSS Class).
   Inside that element the native pointer is hidden and a circular
   brand-logo "loupe" follows the mouse (built by customfile.js).
   Desktop / fine-pointer only - touch devices keep native behaviour.

   Every size / colour below is driven by CSS variables that
   customfile.js writes from its CONFIG block, so tweak there.
   ========================================================== */

/* Hide the native cursor only while the loupe is actually on screen.
   customfile.js adds .acl-active to <html> on enter and removes it on
   leave (and it only ever runs on real fine-pointer devices), so the
   native cursor is never hidden without a replacement. The universal
   selector + !important beats Divi's own `cursor: pointer` on links,
   buttons, sliders, etc. for the duration of the hover. */
html.acl-active,
html.acl-active * {
  cursor: none !important;
}

/* The floating cursor node - created once, appended to <body>. */
.acl-cursor {
  position: fixed;
  top: 0;
  left: 0;
  z-index: var(--acl-z, 999999);
  width: var(--acl-size, 110px);
  height: var(--acl-size, 110px);
  /* centre the circle on the pointer -> JS only writes translate3d(x,y) */
  margin-top: calc(var(--acl-size, 110px) / -2);
  margin-left: calc(var(--acl-size, 110px) / -2);
  display: grid;
  place-items: center;
  border-radius: 50%;
  border: var(--acl-border, 1px solid rgba(255, 250, 247, 0.46));
  background:
    radial-gradient(
      circle at 34% 28%,
      rgba(255, 250, 247, 0.18),
      transparent 38%
    ),
    var(--acl-bg, rgba(28, 12, 38, 0.62));
  box-shadow:
    0 18px 42px rgba(28, 12, 38, 0.3),
    inset 0 1px 0 rgba(255, 250, 247, 0.18);
  -webkit-backdrop-filter: blur(var(--acl-blur, 14px));
  backdrop-filter: blur(var(--acl-blur, 14px));
  pointer-events: none; /* never intercepts clicks */
  opacity: 0; /* hidden until a target is hovered */
  transform: translate3d(-100vw, -100vw, 0);
  transition: opacity var(--acl-fade, 260ms) ease;
  will-change: transform, opacity; /* stay on its own compositor layer */
}

/* Visible state (JS toggles .is-visible on enter / leave). */
.acl-cursor.is-visible {
  opacity: var(--acl-opacity, 1);
}

/* Crosshair reticle - extends slightly past the circle, like the reference.
   Set --acl-cross to transparent (CROSSHAIR: "" in the JS) to remove it. */
.acl-cursor::before,
.acl-cursor::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  background: var(--acl-cross, rgba(238, 108, 154, 0.7));
  transform: translate(-50%, -50%);
}
.acl-cursor::before {
  width: var(--acl-cross-len, 138px);
  height: 1px;
}
.acl-cursor::after {
  width: 1px;
  height: var(--acl-cross-len, 138px);
}

/* Brand mark in the centre. */
.acl-cursor__logo {
  position: relative; /* above the crosshair pseudo-elements */
  width: var(--acl-logo-w, 48px);
  height: auto;
  opacity: 0.94;
}
.acl-cursor--tint .acl-cursor__logo {
  filter: brightness(0) invert(1); /* force the logo to solid white */
}

/* Motion-reduction: keep the loupe, drop the fade transition. */
@media (prefers-reduced-motion: reduce) {
  .acl-cursor {
    transition: none;
  }
}

/* ==========================================================
   POSITIONED TO DELIVER — 7-stage ecosystem timeline
   ----------------------------------------------------------
   Card component used inside a Divi Code module, sitting under
   the existing "Positioned to deliver" heading/paragraph in
   et_pb_section_4. Ported from the Aquila Path reference
   (/company.css .company-ecosystem block), rules merged and
   re-scoped.

   Clinical Practice -> PathNet -> Longitudinal Outcomes ->
   AI Platform (active/focal) -> Clinical Validation ->
   Commercial Deployment -> Clinical Adoption.

   Everything is scoped to .aqp-positioned-deliver; the
   component-local tokens (--aqp-*) do not leak. Every class
   (.aqp-ecosystem, .aqp-ecosystem-line, .aqp-card,
   .aqp-card--active, .aqp-card-icon, .aqp-card-icon--brand,
   .aqp-card-title, .aqp-card-subtitle, .aqp-accent) was checked
   against the installed Divi CSS — no collisions. Divi's own
   modules namespace under .et_pb_*.

   Pure CSS — no JavaScript. The travelling connector pulse
   respects prefers-reduced-motion; layout is correct with JS
   disabled.
   ========================================================== */

.aqp-positioned-deliver {
  /* component-scoped tokens */
  --aqp-cream: #fffaf7;
  --aqp-plum: #461173;
  --aqp-magenta: #dc4b6a;
  --aqp-rose: #ee6c9a;
  --aqp-card-bg: rgba(255, 250, 247, 0.045);
  --aqp-card-border: rgba(255, 250, 247, 0.12);

  box-sizing: border-box;
  width: 100%;
  max-width: 100%;
  margin: 0;
  /* contains the raised active card + connector glow so the
     component never introduces horizontal page scroll */
  overflow: hidden;
  font-family: var(--font-primary, "Inter", sans-serif);
  -webkit-font-smoothing: antialiased;
}
.aqp-positioned-deliver *,
.aqp-positioned-deliver *::before,
.aqp-positioned-deliver *::after {
  box-sizing: border-box;
}

/* ---- grid / timeline ---- */
.aqp-positioned-deliver .aqp-ecosystem {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 12px;
  padding-top: 24px; /* headroom for the raised active card */
}

/* ---- horizontal connector (desktop) ---- */
.aqp-positioned-deliver .aqp-ecosystem-line {
  position: absolute;
  left: 3%;
  right: 3%;
  top: 75px; /* passes through the icon row */
  height: 2px;
  z-index: -1;
  background: linear-gradient(
    90deg,
    var(--aqp-plum),
    #992470,
    var(--aqp-magenta)
  );
  box-shadow: 0 0 18px rgba(220, 75, 106, 0.35);
  border-radius: 2px;
}
.aqp-positioned-deliver .aqp-ecosystem-line::after {
  /* arrow head */
  content: "";
  position: absolute;
  right: 0;
  top: 50%;
  width: 9px;
  height: 9px;
  border-top: 2px solid var(--aqp-magenta);
  border-right: 2px solid var(--aqp-magenta);
  transform: translateY(-50%) rotate(45deg);
}
.aqp-positioned-deliver .aqp-ecosystem-line i {
  /* travelling signal */
  position: absolute;
  left: 0;
  top: 50%;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--aqp-rose);
  box-shadow:
    0 0 0 7px rgba(238, 108, 154, 0.08),
    0 0 20px rgba(238, 108, 154, 0.44);
  transform: translate(-50%, -50%);
  animation: aqpSignal 5.8s ease-in-out infinite;
}
@keyframes aqpSignal {
  0% {
    left: 0;
    opacity: 0;
  }
  12% {
    opacity: 1;
  }
  88% {
    opacity: 1;
    background: var(--aqp-magenta);
  }
  100% {
    left: 100%;
    opacity: 0;
    background: var(--aqp-magenta);
  }
}

/* ---- card ---- */
.aqp-positioned-deliver .aqp-card {
  position: relative;
  min-height: 230px;
  display: grid;
  align-content: start;
  justify-items: center;
  padding: 1.5rem 0.75rem;
  border: 1px solid var(--aqp-card-border);
  border-radius: 1.125rem;
  background: var(--aqp-card-bg);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  text-align: center;
  transition:
    transform 0.35s cubic-bezier(0.16, 1, 0.3, 1),
    border-color 0.35s ease,
    background-color 0.35s ease;
}
.aqp-positioned-deliver .aqp-card:hover {
  transform: translateY(-4px);
  border-color: rgba(238, 108, 154, 0.28);
}

/* ---- icon container ---- */
.aqp-positioned-deliver .aqp-card-icon {
  display: grid;
  width: 54px;
  height: 54px;
  place-items: center;
  border: 1px solid rgba(238, 108, 154, 0.34);
  border-radius: 16px;
  background:
    linear-gradient(
      145deg,
      rgba(255, 250, 247, 0.09),
      rgba(220, 75, 106, 0.04)
    ),
    #1a0d24;
  color: rgba(255, 250, 247, 0.86);
  box-shadow:
    inset 0 1px 0 rgba(255, 250, 247, 0.08),
    0 14px 34px rgba(0, 0, 0, 0.18);
}
.aqp-positioned-deliver .aqp-card-icon svg {
  width: 30px;
  height: 30px;
  overflow: visible;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.aqp-positioned-deliver .aqp-card-icon .aqp-accent {
  stroke: var(--aqp-rose);
}
/* brand mark (AI Platform) is a filled glyph, not a stroked line icon */
.aqp-positioned-deliver .aqp-card-icon--brand svg {
  width: 26px;
  height: 26px;
  fill: currentColor;
  stroke: none;
}

/* ---- typography ---- */
.aqp-positioned-deliver .aqp-card-title {
  margin: 0;
  color: var(--aqp-cream);
  font-size: var(--gvid-ol4vltpqxo);
  font-weight: 650;
  line-height: 1.2;
  letter-spacing: -0.01em;
  margin-top: 1.5rem;
}
.aqp-positioned-deliver .aqp-card-subtitle {
  margin: 0;
  color: rgba(255, 250, 247, 0.5);
  font-size: var(--gvid-e5fzc69sip);
  line-height: 1.2;
}

/* ---- active / focal card: AI Platform ---- */
.aqp-positioned-deliver .aqp-card--active {
  min-height: 246px;
  border-color: rgba(238, 108, 154, 0.55);
  background:
    radial-gradient(
      circle at 50% 12%,
      rgba(220, 75, 106, 0.26),
      transparent 42%
    ),
    rgba(255, 250, 247, 0.08);
  box-shadow:
    0 0 0 1px rgba(238, 108, 154, 0.18),
    0 24px 64px rgba(0, 0, 0, 0.28),
    0 0 46px rgba(220, 75, 106, 0.2);
  transform: translateY(-20px);
}
.aqp-positioned-deliver .aqp-card--active:hover {
  transform: translateY(-24px);
}
.aqp-positioned-deliver .aqp-card--active .aqp-card-icon {
  border-color: rgba(238, 108, 154, 0.7);
  background:
    linear-gradient(
      145deg,
      rgba(255, 250, 247, 0.16),
      rgba(220, 75, 106, 0.12)
    ),
    #25102f;
  color: var(--aqp-cream);
  box-shadow:
    inset 0 1px 0 rgba(255, 250, 247, 0.14),
    0 0 22px rgba(238, 108, 154, 0.4);
}

/* ----------------------------------------------------------
   RESPONSIVE — ~1080px is where 7 readable cards stop fitting
   a standard Divi content row, so below it the horizontal
   timeline becomes a vertical connected timeline.
   ---------------------------------------------------------- */
@media (max-width: 1080px) {
  .aqp-positioned-deliver .aqp-ecosystem {
    grid-template-columns: 1fr;
    gap: 14px;
    padding-top: 0;
    padding-left: 8px; /* room for the vertical connector */
  }

  .aqp-positioned-deliver .aqp-ecosystem-line {
    left: 53px; /* icon centre: 8 wrap pad + 18 card pad + 27 half-icon */
    right: auto;
    top: 28px;
    bottom: 28px;
    width: 2px;
    height: auto;
    background: linear-gradient(
      180deg,
      var(--aqp-plum),
      #992470,
      var(--aqp-magenta)
    );
  }
  .aqp-positioned-deliver .aqp-ecosystem-line::after {
    right: auto;
    top: auto;
    left: 50%;
    bottom: 0;
    transform: translateX(-50%) rotate(135deg); /* arrow points down */
  }
  .aqp-positioned-deliver .aqp-ecosystem-line i {
    left: 50%;
    top: 0;
    animation: aqpSignalV 5.8s ease-in-out infinite;
  }
  @keyframes aqpSignalV {
    0% {
      top: 0;
      opacity: 0;
    }
    12% {
      opacity: 1;
    }
    88% {
      opacity: 1;
      background: var(--aqp-magenta);
    }
    100% {
      top: 100%;
      opacity: 0;
      background: var(--aqp-magenta);
    }
  }

  /* horizontal card: icon left, text right, vertically centred */
  .aqp-positioned-deliver .aqp-card,
  .aqp-positioned-deliver .aqp-card--active {
    min-height: 0;
    grid-template-columns: 54px minmax(0, 1fr);
    column-gap: 16px;
    row-gap: 4px;
    align-content: center;
    justify-items: start;
    padding: 18px;
    text-align: left;
    transform: none;
  }
  .aqp-positioned-deliver .aqp-card:hover,
  .aqp-positioned-deliver .aqp-card--active:hover {
    transform: none;
  }
  .aqp-positioned-deliver .aqp-card-icon {
    grid-row: 1 / span 2;
  }
  .aqp-positioned-deliver .aqp-card--active {
    transform: none;
    box-shadow:
      0 0 0 1px rgba(238, 108, 154, 0.18),
      0 18px 44px rgba(0, 0, 0, 0.28),
      0 0 34px rgba(220, 75, 106, 0.18);
  }
}

@media (max-width: 420px) {
  .aqp-positioned-deliver .aqp-ecosystem {
    padding-left: 4px;
  }
  .aqp-positioned-deliver .aqp-ecosystem-line {
    left: 42px; /* 4 + 15 + 23 */
  }
  .aqp-positioned-deliver .aqp-card,
  .aqp-positioned-deliver .aqp-card--active {
    grid-template-columns: 46px minmax(0, 1fr);
    column-gap: 13px;
    padding: 15px;
  }
  .aqp-positioned-deliver .aqp-card-icon {
    width: 46px;
    height: 46px;
    border-radius: 14px;
  }
  .aqp-positioned-deliver .aqp-card-icon svg {
    width: 26px;
    height: 26px;
  }
  .aqp-positioned-deliver .aqp-card-icon--brand svg {
    width: 22px;
    height: 22px;
  }
  .aqp-positioned-deliver .aqp-card-title {
    font-size: 15px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .aqp-positioned-deliver .aqp-ecosystem-line i {
    animation: none;
    opacity: 0;
  }
}

/* ==========================================================
   HERITAGE CARD — animated top-edge accent line
   ----------------------------------------------------------
   Reproduces the moving border on the reference site's
   "A decade of pathology heritage" card
   (/company.css .company-origin-topline > i):

     - a ~46%-wide gradient segment (plum -> #992470 -> magenta)
       riding a faint rose track pinned to the card's TOP EDGE
       only — not around the card
     - travels left <-> right, ease-in-out, 4.8s each way,
       alternating, looping forever
     - 3px thick, follows the card's own border-radius via the
       card's overflow clip, adds a subtle inward glow

   Activated by ONE class — .aqp-heritage-card — on the existing
   Divi row/module that forms the card. No inner markup, no JS.
   Single ::after pseudo so Divi's own row ::before clearfix is
   left intact. Card dimensions, background and layout are
   untouched; only position/overflow are enforced so the line
   can anchor and clip cleanly.

   DIVI CONFLICT NOTE: .aqp-heritage-card is not present in the
   installed Divi CSS. Only ::after is used; on a flex row
   (et_flex_row, as used on this page) Divi's ::after clearfix
   is inert, so overriding it is safe.
   ========================================================== */

.aqp-heritage-card {
  position: relative;
  /* clips the 3px line to the card's rounded top corners, exactly
     like the reference card's own overflow:hidden. Does not clip
     the card's own box-shadow (outset shadows are unaffected by
     an element's own overflow). */
  overflow: hidden;
}

.aqp-heritage-card::after {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 3px;
  z-index: 2;
  pointer-events: none;
  border-top-left-radius: inherit;
  border-top-right-radius: inherit;
  /* layer 1: the travelling gradient highlight (animated position)
     layer 2: the static faint track it rides on */
  background-image:
    linear-gradient(
      90deg,
      rgba(70, 17, 115, 0) 0%,
      #461173 18%,
      #992470 50%,
      #dc4b6a 82%,
      rgba(220, 75, 106, 0) 100%
    ),
    linear-gradient(rgba(238, 108, 154, 0.16), rgba(238, 108, 154, 0.16));
  background-repeat: no-repeat, no-repeat;
  background-size:
    46% 100%,
    100% 100%;
  background-position:
    -7% 0,
    0 0;
  filter: drop-shadow(0 0 6px rgba(220, 75, 106, 0.5));
  animation: aqpHeritageLine 4.8s ease-in-out infinite alternate;
}

@keyframes aqpHeritageLine {
  from {
    background-position:
      -7% 0,
      0 0;
  }
  to {
    background-position:
      106% 0,
      0 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .aqp-heritage-card::after {
    animation: none;
    /* static gradient stub resting at the top-left, matching the
       reference's reduced-motion state */
    background-position:
      0 0,
      0 0;
  }
}

/* ==========================================================================
   AQP HERO NETWORK  —  auto-animated hero pattern (About Us hero)
   Pairs with: js/customfile.js  ->  "AQP HERO NETWORK" block
   Markup:     a Divi Code module holding  <div class="aqp-hero-network"> … </div>

   Continuous, self-running ambient motion — NO mouse/hover. Each dot drifts,
   pulses and glows on its own phase; connector lines follow the live dots.
   Everything is scoped to .aqp-hero-network — no global selectors touched.
   ========================================================================== */
.aqp-hero-network {
  /* ---- tweak these to reposition the visual, nothing else ---- */
  --aqp-hn-width: 38vw; /* fluid width on desktop            */
  --aqp-hn-max: 440px; /* hard cap so it never gets huge    */
  --aqp-hn-top: -2rem; /* vertical nudge from hero top      */
  --aqp-hn-right: 0px; /* horizontal nudge from hero right  */

  position: absolute;
  top: var(--aqp-hn-top);
  right: var(--aqp-hn-right);
  width: var(--aqp-hn-width);
  max-width: var(--aqp-hn-max);
  z-index: 2;
  pointer-events: none; /* purely decorative — never blocks hero content */
  overflow: visible; /* animated dots + halos may paint outside the box */
  -webkit-user-select: none;
  user-select: none;
}
.aqp-hero-network .aqp-hn-stage {
  position: relative;
  width: 100%;
  line-height: 0;
  overflow: visible; /* never clip the moving dots */
}
/* SAFE AREA for the moving dots.  Only the left-edge dot (cx 11) and the
   bottom-edge dot (cy 414) — with ~16.5u of drift + a ~24.5u halo — ever
   reach past the artwork box, so the viewBox is widened ONLY left & down
   (-64 0 545 488; artwork itself is still 0 0 481 424, clip-path on the
   pattern unchanged).  The element is re-scaled + negative-margined by the
   matching 545/481 & -64/481 ratios so the artwork lands in exactly its
   old pixel box: the right and top edges stay flush (no page h-scroll),
   only transparent safe-area overhangs left/bottom and overflow:visible
   lets the dots paint into it.  Ratios are width-relative → holds at every
   breakpoint. */
.aqp-hero-network .aqp-hn-svg {
  display: block;
  width: calc(100% * 545 / 481);
  height: auto;
  margin: 0 0 calc(100% * -64 / 481) calc(100% * -64 / 481);
  overflow: visible;
  filter: drop-shadow(0 8px 26px rgba(120, 40, 90, 0.1));
}
.aqp-hero-network .aqp-hn-pattern {
  opacity: 0.85;
} /* the static line pattern */

.aqp-hero-network .aqp-hn-links line {
  stroke: #b571a6;
  stroke-width: 1.3;
  stroke-linecap: round;
  opacity: 0; /* JS drives per-line opacity every frame */
}
.aqp-hero-network .aqp-hn-halo {
  fill: #f2b6c8;
  opacity: 0;
} /* JS drives the glow */
/* .aqp-hn-node dots keep their original SVG fills; JS animates cx / cy / r */

/* ---- tablet / mobile: SAME animation, just smaller & softer ---- */
@media (max-width: 980px) {
  .aqp-hero-network {
    position: static;
    width: 68%;
    max-width: 340px;
    margin: 1.5rem auto 0;
  }
  .aqp-hero-network .aqp-hn-svg {
    filter: none;
  }
  .aqp-hero-network .aqp-hn-pattern {
    opacity: 0.6;
  }
}
@media (max-width: 480px) {
  .aqp-hero-network {
    width: 78%;
  }
}

/* ---- reduced-motion: no JS runs -> plain static SVG (pattern + dots only) ---- */
@media (prefers-reduced-motion: reduce) {
  .aqp-hero-network .aqp-hn-svg {
    filter: none;
  }
}
/* ===================== end AQP HERO NETWORK ============================== */

/* ======================================================================
   AQP CUSTOM CURSOR  (desktop-only rose ring)
   ----------------------------------------------------------------------
   Matches reference aqp-website-n32c.vercel.app: 18px ring -> 48px on
   hover over links/buttons, 1px #ee6c9a, opacity .8, native cursor kept.
   Fully namespaced (#aqp-custom-cursor / .aqp-cursor--active). No body/a/
   button/* rules, no .et_pb_ overrides. The element and its follow/grow
   logic are created by the IIFE at the end of js/customfile.js.
   ====================================================================== */
@media (hover: hover) and (pointer: fine) {
  #aqp-custom-cursor {
    position: fixed;
    top: 0;
    left: 0;
    width: 18px;
    height: 18px;
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    border: 1px solid #ee6c9a;
    border-radius: 50%;
    background: transparent;
    opacity: 0;
    /* !important: the Footer Curtain injects
       `body.fc-body > *:not(.fc-spacer){pointer-events:auto}` which would
       otherwise turn this ring into an invisible click/hover shield. */
    pointer-events: none !important;
    z-index: 2147482000; /* above Divi header/menu, below the APFM loupe (2147483000) */
    transform: translate3d(-9999px, -9999px, 0);
    transition: opacity 200ms ease;
    will-change: transform, width, height, opacity;
    contain: layout style size paint;
    -webkit-backface-visibility: hidden;
    backface-visibility: hidden;
  }
  #aqp-custom-cursor.aqp-cursor--active {
    opacity: 0.8;
  }
}

@media (prefers-reduced-motion: reduce) {
  #aqp-custom-cursor {
    transition-duration: 0.01ms;
  }
}
/* ===================== end AQP CUSTOM CURSOR ============================ */
