/* ==========================================================================
   Exact Core Group — premium interaction layer
   Loaded into the Elementor Global Kit custom CSS.

   Justification for custom CSS (brief permits it only where Elementor cannot):
   concentric double-bezel radii need calc(); ambient multi-layer shadows,
   magnetic hover physics, sweep underlines and staggered reveals have no
   native Elementor control. Structure stays in Elementor containers.
   ========================================================================== */

:root{
  --ec-e: cubic-bezier(.32,.72,0,1);      /* spring-ish, no ease-in-out */
  --ec-e-out: cubic-bezier(.16,1,.3,1);
  --ec-amb-1: 0 1px 2px rgba(1,62,127,.04), 0 6px 16px -6px rgba(1,62,127,.08);
  --ec-amb-2: 0 2px 4px rgba(1,62,127,.05), 0 18px 40px -12px rgba(1,62,127,.14);
  --ec-amb-3: 0 4px 8px rgba(1,62,127,.06), 0 36px 80px -20px rgba(1,62,127,.20);
}

/* The header CTA must never wrap to 3 lines. It did after the nav grew to 7
   items and the right column was narrowed to 17% — the button hit 82px inside
   an 83px header and filled it. nowrap + a height cap makes the failure
   impossible regardless of what the label is changed to. */
#header-cta{
  white-space:nowrap!important;
  max-height:48px;line-height:1.2!important;
  padding-top:13px!important;padding-bottom:13px!important}

/* ---------- responsive CTA pair (Elementor 4.2 hide_* controls are broken)
   Brief item 3's combined label "Get in Touch / Free Audit" measures 225px at
   the old 15px/26px button — 95px wider than the label it replaced. The header
   is a boxed 1320px row, so the button pushed past the viewport and gave the
   WHOLE PAGE a horizontal scrollbar at every common laptop width. Measured
   before fixing: 1024px overflowed by 62px, 1100px by 49px, 1280px by 19px;
   only ~1300px+ fitted. Proven causal by shrinking the label in-page and
   watching scrollWidth drop back to exactly the viewport width.
   Two changes, because either alone is not enough:
     1. the button is tightened (14px text, 20px sides) to buy back ~30px
     2. below 1200px the short "Free Audit" twin is used instead — the full
        label genuinely cannot sit beside the nav at those widths
   The swap point moved 767 -> 1199 for that reason. */
#header-cta{
  font-size:13.5px!important;letter-spacing:-.1px!important;
  padding-left:16px!important;padding-right:16px!important}
/* 1359/1360, measured. The full nav needs 1360px before it clears the logo:
   at 1320 the first item touches the mark and at 1280 it overlaps it by 40px.
   The compact CTA therefore stays until the full nav can actually appear. */
@media(max-width:1359px){
  #header-cta{display:none!important}
  #header-cta-m{white-space:nowrap}
}
@media(min-width:1360px){#header-cta-m{display:none!important}}

/* ---------- the brand mark must never be squeezed ------------------------
   kit.css gives every widget min-width:0 so a long string cannot force the
   page to scroll sideways. For the logo that rule is actively harmful: in a
   flex row under pressure it let the mark shrink to 34x8 at 375px, which is
   not a small logo, it is an unreadable one. The brand holds its size and the
   nav gives way instead. */
#site-header .ecg-w--image,
#dark-header .ecg-w--image{flex:0 0 auto}
/* kit.css caps every image at max-width:100% of its box. For the logo that is
   circular — the box is sized by the image — so flex resolves it against
   whatever space is left and the mark ends up arbitrarily small. The logo's
   width is specified per breakpoint by the builder; let it hold. */
#site-header .ecg-w--image img,
#dark-header .ecg-w--image img{max-width:none}



/* ---------- a post written in the editor --------------------------------
   The three hand-built articles under /blog/ carry their measure in builder
   settings: a 760px column holding 712px of 17px text. A post has no builder
   settings to inherit, so single.php would hand the_content the full 1280px
   column — which is exactly what the first published post did, 1440px of
   unbroken line length and no heading at all.
   Same measure here, so an editor-written post sits beside the designed ones
   instead of looking like a different site. Left-aligned, not centred, to
   match them. */
/* A hand-written template section gets no per-element CSS, so it has none of
   the page padding the generated sections carry — the first post rendered with
   its breadcrumb jammed into the top-left corner of the viewport. These are the
   designed articles' own measurements, read off /blog/undercoding/:
   hero 104/80/44, body 0/80/88, h1 50px. The horizontal value is the same
   boxed expression render_html emits, so the column lands in the same place. */
.ecg-post__hero {padding:104px max(32px,calc((100% - 1280px)/2)) 44px}
.ecg-post__media{padding:0    max(32px,calc((100% - 1280px)/2)) 8px}
.ecg-post__body {padding:0    max(32px,calc((100% - 1280px)/2)) 88px}
.ecg-post__rel  {padding:0    max(32px,calc((100% - 1280px)/2)) 96px}
.ecg-post__hero > .ecg-con,
.ecg-post__body > .ecg-con{max-width:772px;margin-right:auto}
.ecg-post__body .ecg-prose{max-width:712px}
/* 50px, not the kit's 66px h1: an article title is a sentence, and at 66px this
   one ran to five lines before the reader saw a word of it. */
.ecg-post__hero .ecg-h{font-size:50px;line-height:1.08;letter-spacing:-1.1px}
.ecg-post__hero .ecg-postmeta{margin-top:4px}
@media(max-width:1024px){
  .ecg-post__hero{padding:76px max(32px,calc((100% - 1280px)/2)) 36px}
  .ecg-post__hero .ecg-h{font-size:38px}
}
@media(max-width:767px){
  .ecg-post__hero{padding:56px max(20px,calc((100% - 1280px)/2)) 28px}
  .ecg-post__media{padding:0 max(20px,calc((100% - 1280px)/2)) 6px}
  .ecg-post__body {padding:0 max(20px,calc((100% - 1280px)/2)) 56px}
  .ecg-post__rel  {padding:0 max(20px,calc((100% - 1280px)/2)) 64px}
  .ecg-post__hero .ecg-h{font-size:30px}
}
/* the_content emits bare tags, so give them the prose treatment the generated
   articles get from their own markup */
.ecg-prose h3{
  font-family:Manrope,sans-serif;font-size:21px;font-weight:600;
  letter-spacing:-.3px;color:var(--e-global-color-secondary);
  margin:30px 0 10px}
.ecg-prose ul,.ecg-prose ol{margin:0 0 24px;padding-left:22px;list-style-position:outside}
.ecg-prose li{margin:0 0 8px}
.ecg-prose a{text-decoration:underline;text-underline-offset:3px}
.ecg-prose img{border-radius:16px;margin:8px 0 24px}
.ecg-prose blockquote{
  margin:24px 0;padding:18px 24px;border-left:3px solid var(--e-global-color-teal_500);
  background:var(--e-global-color-slate_50);border-radius:0 12px 12px 0}
.ecg-prose blockquote p:last-child{margin-bottom:0}

/* ---------- skip link (WCAG 2.4.1) ---------------------------------------
   header.php emits this as the first focusable element. It was never styled,
   so it rendered as visible blue text in the top-left corner of every page.
   Off-screen until focused, then anchored to the top-left where it is expected.
   Not display:none — that would take it out of the tab order and defeat the
   point of having it. */
.ecg-skip{
  position:absolute;top:0;left:-9999px;z-index:200;
  padding:12px 20px;border-radius:0 0 12px 0;
  background:#fff;color:var(--e-global-color-primary);
  font-family:Inter,sans-serif;font-size:15px;font-weight:600;
  text-decoration:none;box-shadow:0 8px 24px -8px rgba(1,62,127,.45)}
.ecg-skip:focus,.ecg-skip:focus-visible{left:0}

/* ---------- WCAG 2.4.7 focus visible (Elementor ships outline:0) ---------- */
:is(a,button,.ecg-btn,summary,[tabindex]):focus-visible{
  outline:2px solid var(--e-global-color-teal_600)!important;
  outline-offset:3px!important;border-radius:6px}
.ecg-input:focus,.ecg-field select:focus{
  outline:2px solid var(--e-global-color-teal_600)!important;
  outline-offset:1px!important;
  border-color:var(--e-global-color-teal_600)!important}

/* ---------- ambient mesh (depth without heavy gradients, Bible §5) -------- */
.ecg-mesh{position:relative;isolation:isolate}
.ecg-mesh::before{
  content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
  background:
    radial-gradient(46% 40% at 12% 0%,rgba(4,161,162,.07),transparent 62%),
    radial-gradient(40% 36% at 92% 8%,rgba(1,62,127,.06),transparent 60%)}

/* ---------- card affordance: an arrow that answers "is this clickable?" --- */
.ecg-shell .ecg-core{position:relative}
.ecg-shell .ecg-core::after{
  content:"→";position:absolute;right:26px;bottom:26px;
  font-size:15px;line-height:1;color:var(--e-global-color-teal_600);
  opacity:0;transform:translateX(-6px);
  transition:opacity .5s var(--ec-e),transform .5s var(--ec-e)}
.ecg-shell:hover .ecg-core::after{opacity:1;transform:translateX(0)}
.ecg-shell.ecg-noarrow .ecg-core::after{content:none}

/* ---------- eyebrow pill --------------------------------------------------
   Replaces bare uppercase text. Hairline capsule, optical padding.          */
.ecg-pill .ecg-h{
  display:inline-flex;align-items:center;gap:8px;
  padding:6px 14px 6px 12px;border-radius:999px;
  background:var(--e-global-color-teal_50);
  box-shadow:inset 0 0 0 1px rgba(4,161,162,.18);
  font-size:11px!important;letter-spacing:.16em!important;
}
.ecg-pill .ecg-h::before{
  content:"";width:5px;height:5px;border-radius:50%;
  background:var(--e-global-color-teal_500);flex:none}
/* keep the eyebrow on one line at phone widths */
@media(max-width:520px){
  .ecg-pill .ecg-h{
    font-size:10px!important;letter-spacing:.10em!important;
    padding:5px 12px 5px 10px}
}
.ecg-pill-dark .ecg-h{
  background:rgba(255,255,255,.06);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.14);
  color:var(--e-global-color-teal_200)!important}

/* ---------- discipline strip: hand-drawn inline SVG icons ----------------
   Inline SVG (not an icon font) so each mark inherits currentColor and its
   stroke can animate. Hairline separators, generous target size.            */
.ecg-disciplines{
  display:grid;grid-template-columns:repeat(4,1fr);width:100%}
.ecg-disc{
  display:flex;flex-direction:column;align-items:center;gap:14px;
  padding:34px 14px;text-decoration:none;text-align:center;
  color:var(--e-global-color-slate_600);
  border-left:1px solid var(--e-global-color-slate_200);
  transition:color .5s var(--ec-e),background-color .5s var(--ec-e)}
.ecg-disc:first-child{border-left:0}
/* 8 disciplines now (brief item 5), so the strip is 4x2 at desktop: reset the
   left border at the start of each row and add a top border on the second */
.ecg-disc:nth-child(4n+1){border-left:0}
.ecg-disc:nth-child(n+5){border-top:1px solid var(--e-global-color-slate_200)}
.ecg-disc__icon{
  color:var(--e-global-color-teal_600);
  transition:color .5s var(--ec-e),transform .6s var(--ec-e)}
.ecg-disc__icon svg{display:block;width:34px;height:34px}
/* slate_600 on slate_50 measured 4.35:1 — just under AA for normal text.
   `text` is the next token up and lands at 8.65:1. */
.ecg-disc__label{
  font-family:Inter,sans-serif;font-size:13.5px;font-weight:500;
  letter-spacing:-.01em;line-height:1.35;
  /* the kit styles all <a> with the accent colour; the label must stay slate */
  color:var(--e-global-color-text);transition:color .5s var(--ec-e)}
.ecg-disc:hover .ecg-disc__label{color:var(--e-global-color-secondary)}
.ecg-disc:hover{color:var(--e-global-color-secondary);background:rgba(4,161,162,.045)}
.ecg-disc:hover .ecg-disc__icon{
  color:var(--e-global-color-primary);transform:translateY(-3px)}
.ecg-disc:focus-visible{outline:2px solid var(--e-global-color-teal_600);outline-offset:-2px}
@media(max-width:1024px){
  .ecg-disciplines{grid-template-columns:repeat(3,1fr)}
  .ecg-disc:nth-child(3n+1){border-left:0}
  .ecg-disc:nth-child(n+4){border-top:1px solid var(--e-global-color-slate_200)}
}
@media(max-width:560px){
  .ecg-disciplines{grid-template-columns:repeat(2,1fr)}
  .ecg-disc{padding:24px 10px}
  .ecg-disc:nth-child(3n+1){border-left:1px solid var(--e-global-color-slate_200)}
  .ecg-disc:nth-child(odd){border-left:0}
  .ecg-disc:nth-child(n+3){border-top:1px solid var(--e-global-color-slate_200)}
  .ecg-disc__icon svg{width:28px;height:28px}
  .ecg-disc__label{font-size:12px}
}

/* ---------- double-bezel card (outer shell + inner core) ------------------ */
/* shell/core must stretch so an asymmetric bento never leaves dead space */
.ecg-shell{display:flex}
.ecg-shell > .ecg-core, .ecg-shell > .ecg-con{flex:1;width:100%}
.ecg-shell{
  border-radius:26px!important;
  background:linear-gradient(180deg,rgba(1,62,127,.05),rgba(1,62,127,.02))!important;
  box-shadow:inset 0 0 0 1px rgba(1,62,127,.07);
  transition:transform .6s var(--ec-e),box-shadow .6s var(--ec-e);
}
.ecg-core{
  border-radius:calc(26px - 7px)!important;
  background:#fff!important;
  box-shadow:var(--ec-amb-1), inset 0 1px 0 rgba(255,255,255,.9);
  transition:box-shadow .6s var(--ec-e);
}
.ecg-shell:hover{transform:translateY(-4px);box-shadow:inset 0 0 0 1px rgba(4,161,162,.35)}
.ecg-shell:hover .ecg-core{box-shadow:var(--ec-amb-3), inset 0 1px 0 rgba(255,255,255,.9)}

/* card interior detail: index numeral + rule that grows on hover */
.ecg-shell .ecg-idx .ecg-h{
  font-variant-numeric:tabular-nums;opacity:.55;transition:opacity .5s var(--ec-e)}
.ecg-shell:hover .ecg-idx .ecg-h{opacity:1}
/* On navy, .55 blends teal_200 down to ~4.0:1 — under AA for 12px text.
   .8 puts it at ~6.5:1 while keeping the numeral subordinate to the title. */
.ecg-shell-dark .ecg-idx .ecg-h{opacity:.8}
.ecg-rule{position:relative;padding-bottom:16px}
/* the rule must sit BELOW the heading, not under the first word like an
   underline — hence the padding-bottom reserving space for it */
.ecg-rule::after{
  content:"";position:absolute;left:0;bottom:0;height:2px;width:28px;
  background:var(--e-global-color-teal_500);border-radius:2px;
  transform-origin:left center;transition:transform .6s var(--ec-e)}
.ecg-shell:hover .ecg-rule::after{transform:scaleX(2.1)}

/* ---------- dark variant for the navy sections --------------------------- */
.ecg-shell-dark{
  background:rgba(255,255,255,.04)!important;
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.09)}
.ecg-shell-dark .ecg-core{
  background:rgba(255,255,255,.03)!important;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.06)}
.ecg-shell-dark:hover{box-shadow:inset 0 0 0 1px rgba(4,161,162,.5)}
.ecg-shell-dark:hover .ecg-core{box-shadow:inset 0 1px 0 rgba(255,255,255,.1)}

/* ---------- button-in-button: nested arrow, magnetic hover --------------- */
.ecg-cta .ecg-btn{
  border-radius:999px!important;position:relative;
  padding-right:14px!important;
  display:inline-flex;align-items:center;gap:14px;
  transition:transform .4s var(--ec-e),background-color .4s var(--ec-e),box-shadow .4s var(--ec-e);
  box-shadow:var(--ec-amb-2)}
.ecg-cta .ecg-btn::after{
  content:"→";flex:none;width:32px;height:32px;border-radius:50%;
  display:inline-flex;align-items:center;justify-content:center;
  background:rgba(255,255,255,.16);font-size:15px;line-height:1;
  transition:transform .5s var(--ec-e),background-color .5s var(--ec-e)}
.ecg-cta .ecg-btn:hover::after{
  transform:translate3d(3px,-1px,0) scale(1.06);background:rgba(255,255,255,.26)}
.ecg-cta .ecg-btn:active{transform:scale(.985)}
.ecg-cta-light .ecg-btn::after{background:rgba(1,62,127,.08)}
.ecg-cta-light .ecg-btn:hover::after{background:rgba(1,62,127,.14)}

/* ghost / secondary button */
.ecg-ghost .ecg-btn{
  border-radius:999px!important;
  transition:transform .4s var(--ec-e),box-shadow .4s var(--ec-e),background-color .4s var(--ec-e);
  box-shadow:inset 0 0 0 1px var(--e-global-color-slate_200)}
.ecg-ghost .ecg-btn:hover{
  box-shadow:inset 0 0 0 1px var(--e-global-color-navy_800);transform:translateY(-1px)}
.ecg-ghost .ecg-btn:active{transform:scale(.985)}

/* ---------- hero video ---------------------------------------------------- */
.ecg-hero-video{position:relative;overflow:hidden}
/* The section is content_width:boxed, and Elementor sizes the background-video
   container to that BOXED width — 1280px inside a 1728px section — so the video
   sat centred with the poster showing through as lighter bands down both edges.
   The container has to be full-bleed regardless of the content width.
   Elementor centres the <video> with left/top:50% + translate(-50%,-50%); that
   transform must be reset too, or full-bleed sizing lands off-centre.
   Elementor also nests the container inside .ecg-con, which IS that boxed
   1280px box and is position:relative (needed for the text z-index) — so
   inset:0 resolves against 1280px, not the section. Hence the 100vw breakout
   rather than inset; the section is overflow:hidden, so nothing escapes. */
.ecg-hero-video .ecg-bgvideo,
.ecg-d-hero .ecg-bgvideo{
  position:absolute!important;top:0!important;bottom:0!important;
  left:50%!important;transform:translateX(-50%)!important;
  width:100vw!important;max-width:none!important;height:100%!important;
  margin:0!important;filter:saturate(.9) contrast(1.02)}
.ecg-hero-video .ecg-bgvideo,
.ecg-d-hero .ecg-bgvideo{
  position:absolute!important;top:0!important;left:0!important;
  width:100%!important;height:100%!important;max-width:none!important;
  transform:none!important;object-fit:cover!important}
/* a soft vertical scrim so the headline never fights a bright frame */
.ecg-hero-video::after{
  content:"";position:absolute;inset:0;pointer-events:none;z-index:1;
  background:linear-gradient(100deg,rgba(0,30,87,.72) 0%,rgba(0,30,87,.46) 46%,rgba(0,30,87,.20) 100%)}
.ecg-hero-video > .ecg-con{position:relative;z-index:2}

/* ghost button sitting on the video */
.ecg-ghost-light .ecg-btn{
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.42);
  backdrop-filter:blur(6px);background:rgba(255,255,255,.06)!important}
.ecg-ghost-light .ecg-btn:hover{
  background:#fff!important;box-shadow:inset 0 0 0 1px #fff}

/* ---------- mobile: CTAs go full width -----------------------------------
   Scoped to page sections, the footer and the popup. The header CTA is
   deliberately excluded — it must stay compact beside the logo and toggle.  */
@media(max-width:767px){
  /* the widget is a flex ITEM of a row container, so it sizes to content
     unless we force the basis as well as the width */
  section .ecg-w--button,
  #site-footer .ecg-w--button,
  .ecg-popup .ecg-w--button{
    flex:1 1 100%!important;width:100%!important;max-width:100%!important}
  /* .ecg-cta sets display:inline-flex, which ignores width — override to flex */
  section .ecg-w--button .ecg-btn,
  #site-footer .ecg-w--button .ecg-btn,
  .ecg-popup .ecg-w--button .ecg-btn{
    display:flex!important;width:100%!important;
    justify-content:center;text-align:center}
  /* keep the nested arrow pinned right rather than floating mid-button */
  section .ecg-cta .ecg-btn{position:relative;padding-right:56px!important}
  section .ecg-cta .ecg-btn::after{
    position:absolute;right:12px;top:50%;transform:translateY(-50%)}
  section .ecg-cta .ecg-btn:hover::after{
    transform:translateY(-50%) translateX(3px) scale(1.06)}
  /* the CTA row is a flex item of a column container whose align-items is
     flex-start, so it shrinks to content. Force it to stretch. */
  /* width:100% kept resolving against a shrink-to-fit containing block, so
     the row is switched to block layout — block children fill by definition. */
  .ecg-btnrow{display:block!important;width:auto!important;align-self:stretch!important;
    padding-left:0!important;padding-right:0!important}
  .ecg-btnrow > .ecg-w--button{
    display:block!important;width:auto!important;max-width:none!important;
    margin:0 0 12px!important}
  .ecg-btnrow > .ecg-w--button:last-child{margin-bottom:0!important}
}

/* ---------- framed imagery: fixed frame, image drifts on hover ----------- */
.ecg-frame{overflow:hidden;border-radius:22px!important;
  box-shadow:var(--ec-amb-2);position:relative}
.ecg-frame img{
  display:block;width:100%;
  transition:transform 1.1s var(--ec-e-out);will-change:transform}
.ecg-frame:hover img{transform:scale(1.035)}
.ecg-frame::after{ /* inner hairline so the photo never floats naked */
  content:"";position:absolute;inset:0;border-radius:inherit;pointer-events:none;
  box-shadow:inset 0 0 0 1px rgba(1,62,127,.10)}

/* ---------- hero certification proof (small) ------------------------------ */
.ecg-herocert__label p{
  text-transform:uppercase;letter-spacing:.16em;font-weight:600;
  font-size:10.5px!important;opacity:.72;margin:0}
.ecg-herocert{display:flex;align-items:center;flex-wrap:wrap}
.ecg-herocert .ecg-w--image{
  background:rgba(255,255,255,.95);border-radius:9px;padding:7px 11px;
  display:inline-flex;align-items:center;
  transition:transform .5s var(--ec-e),background-color .5s var(--ec-e)}
.ecg-herocert .ecg-w--image:hover{
  transform:translateY(-2px);background:#fff}
/* marks are NOT recoloured — height-matched instead (HIPAA is wide-aspect) */
.ecg-herocert img{height:44px!important;width:auto!important;display:block}
.ecg-herocert .ecg-w--image{padding:10px 16px;border-radius:12px}
@media(max-width:767px){
  .ecg-herocert img{height:34px!important}
  .ecg-herocert .ecg-w--image{padding:8px 12px}
}

/* ---------- certification marks ------------------------------------------ */
/* the marks have different aspect ratios (HIPAA is wide, ISO/SGS square), so
   size them by HEIGHT — a fixed width made HIPAA render half the optical size */
.ecg-cert-mark{display:flex;align-items:center;justify-content:center;
  height:78px;margin-bottom:4px}
.ecg-cert-mark img{
  height:78px!important;width:auto!important;max-width:100%;object-fit:contain;
  transition:transform .6s var(--ec-e),filter .6s var(--ec-e);
  filter:saturate(.92)}
.ecg-shell:hover .ecg-cert-mark img{transform:scale(1.05);filter:saturate(1)}
/* compact row used in the footer.
   The marks are NOT recoloured — SGS/ISO usage rules generally prohibit
   altering a certification mark, so they sit on a light chip instead of being
   inverted to white. */
.ecg-certrow{display:flex;align-items:center;gap:14px;flex-wrap:wrap}
.ecg-certrow .ecg-w--image{
  background:#fff;border-radius:12px;padding:10px 16px;
  display:inline-flex;align-items:center;
  transition:transform .5s var(--ec-e),box-shadow .5s var(--ec-e)}
.ecg-certrow .ecg-w--image:hover{
  transform:translateY(-2px);box-shadow:0 10px 26px -12px rgba(0,0,0,.5)}
.ecg-certrow img{height:38px!important;width:auto!important;display:block}

/* ---------- process diagram: connected nodes ---------------------------- */
/* Light process. The dark theme carries this section on 92px outlined
   numerals; the light version was using 12px accent numerals and read as a
   faint dotted line — same information, a fraction of the presence. Same
   device here in navy, with the node rail dropped BELOW the numeral (--rail)
   so the two occupy separate bands instead of colliding. */
.ecg-step{position:relative;--rail:104px}
.ecg-bignum .ecg-h{
  -webkit-text-stroke:1.5px rgba(1,62,127,.30);
  color:transparent!important;line-height:.9;
  font-variant-numeric:tabular-nums;
  transition:-webkit-text-stroke-color .6s var(--ec-e)}
.ecg-step:hover .ecg-bignum .ecg-h{
  -webkit-text-stroke-color:var(--e-global-color-teal_500)}
.ecg-step::before{ /* the node */
  content:"";position:absolute;left:0;top:var(--rail);width:11px;height:11px;border-radius:50%;
  background:#fff;box-shadow:0 0 0 2px var(--e-global-color-teal_500);
  transition:box-shadow .5s var(--ec-e),transform .5s var(--ec-e);z-index:2}
.ecg-step::after{ /* the connector to the next node */
  content:"";position:absolute;left:11px;top:calc(var(--rail) + 5px);height:2px;width:calc(100% + 20px);
  background:linear-gradient(90deg,var(--e-global-color-teal_500),var(--e-global-color-slate_200));
  opacity:.5}
.ecg-step:last-child::after{display:none}
.ecg-step:hover::before{transform:scale(1.25);
  box-shadow:0 0 0 3px var(--e-global-color-teal_500),0 0 0 8px rgba(4,161,162,.14)}
/* Inner pages set the numeral at 76px rather than the homepage's 88px, so the
   rail has to move up with it — otherwise the step title lands on top of the
   node dot. --rail is the single knob for that. */
.ecg-step--sm{--rail:88px}
@media(max-width:1024px){.ecg-step{--rail:92px}.ecg-step--sm{--rail:80px}}
@media(max-width:767px){
  .ecg-step{--rail:74px}
  .ecg-step--sm{--rail:64px}
  .ecg-step::after{width:2px;height:calc(100% - var(--rail) - 14px);left:5px;top:calc(var(--rail) + 14px);
    background:linear-gradient(180deg,var(--e-global-color-teal_500),var(--e-global-color-slate_200))}
}

/* ---------- link sweep underline ---------------------------------------- */
.ecg-link a, #site-footer a:not(.ecg-fab){
  position:relative;text-decoration:none;
  background-image:linear-gradient(currentColor,currentColor);
  background-size:0% 1px;background-repeat:no-repeat;background-position:left 92%;
  transition:background-size .5s var(--ec-e),color .3s var(--ec-e)}
.ecg-link a:hover, #site-footer a:not(.ecg-fab):hover{background-size:100% 1px}

/* ---------- footer ------------------------------------------------------- */
#site-footer a:not(.ecg-fab){color:var(--e-global-color-slate_300)}
#site-footer a:not(.ecg-fab):hover{color:#fff}
#site-footer ul li{margin:0 0 11px}
#site-footer #footer-cta{color:var(--e-global-color-secondary)}

/* ---------- header: native CSS sticky (Elementor's JS sticky clones the
   header, which duplicated every mega-menu id) ---------------------------- */
/* the STICKY element must be the header template WRAPPER, not the header:
   the wrapper is a direct child of <body> (so it can stick for the whole page),
   whereas the header's own parent box is only 76px tall — sticky there has no
   range and the header simply scrolled away. */
.ecg-site-header{
  position:sticky!important;top:0;z-index:60}
#site-header{
  transition:box-shadow .5s var(--ec-e),background-color .5s var(--ec-e)}
#site-header.is-stuck,#site-header.ecg-stuck{
  box-shadow:0 1px 0 rgba(1,62,127,.08),0 10px 30px -18px rgba(1,62,127,.30);
  backdrop-filter:saturate(180%) blur(14px);
  background:rgba(255,255,255,.86)!important}

/* ---------- scroll reveal + SAFETY NET ------------------------------------
   Elementor sets .ecg-was-animated{opacity:0} and relies on JS to remove it.
   If that observer never fires (JS error, aggressive caching, odd viewport),
   the content stays permanently invisible. This forces anything still hidden
   after 2.5s to appear. Elementor removes the class when it genuinely animates,
   so the intended entrance animation is unaffected.                          */
/* UPDATE — the failsafe was not a safety net, it was the only thing rendering
   this content. Measured on the live homepage: 44 elements still carried
   .ecg-was-animated after load and NONE had ever received Elementor's
   .animated class, i.e. its entrance-animation handler never runs on this
   site at all. Every animated element was therefore blank for a full 2.5s and
   then popped in — most visibly on the FAQ, where the whole section is
   animated and rendered empty.
   The animations never played, so they were pure cost. Neutralised outright,
   with !important so it also covers any page not rebuilt since. */
.ecg-was-animated{opacity:1!important;transform:none!important;animation:none!important}
.ecg-reveal{will-change:transform,opacity}

/* ---------- bullet list -------------------------------------------------- */
.ecg-list{list-style:none;padding:0;margin:0}
.ecg-list li{position:relative;padding-left:24px;margin:0 0 13px}
.ecg-list li::before{content:"";position:absolute;left:0;top:.62em;width:9px;height:2px;
  border-radius:2px;background:var(--e-global-color-teal_500)}

/* ---------- accordion: Elementor floats the chevron LEFT, which pushed the
   question text 38px right of the answer text. Chevron moves right, and the
   question aligns with the answer. --------------------------------------- */
.ecg-faqs .ecg-faq__item>summary{
  display:flex!important;align-items:center;justify-content:space-between;gap:18px}
.ecg-faqs .ecg-faq__icon{
  float:none!important;order:2;margin:0!important;width:auto!important;
  flex:none;color:var(--e-global-color-accent)}
.ecg-faqs .ecg-faq__icon svg{width:15px;height:15px}
.ecg-faqs .ecg-faq__q{flex:1 1 auto;text-align:left}
.ecg-faqs .ecg-faq__a{padding-left:4px!important}

/* Elementor renders each question as an <h3>, and the kit's h3 global
   typography beats the widget's own title_typography — the questions were
   rendering at 25px/700 instead of the 18px/600 set on the widget, which is
   why they sat oddly against everything else. Forced, both themes. */
.ecg-faqs .ecg-faq__item>summary{
  font-size:18px!important;font-weight:600!important;
  letter-spacing:-.3px!important;line-height:1.45!important}
@media(max-width:767px){
  .ecg-faqs .ecg-faq__item>summary{font-size:16.5px!important}}

/* The accordion was a bare bordered list sitting on the grey ground, which
   read as unstyled next to the rest of the system. Same panel construction as
   .ecg-review: one rounded card, hairline dividers, generous hit areas. */
.ecg-faqs{
  border-radius:20px;overflow:hidden;background:#fff;
  box-shadow:inset 0 0 0 1px var(--e-global-color-slate_200),var(--ec-amb-1)}
.ecg-faqs .ecg-faq__item{
  border:0!important;
  border-top:1px solid var(--e-global-color-slate_200)!important;
  background:transparent!important}
.ecg-faqs .ecg-faq__item:first-child{border-top:0!important}
.ecg-faqs .ecg-faq__item>summary{
  padding:24px 28px!important;cursor:pointer;
  transition:background-color .35s var(--ec-e),color .35s var(--ec-e)}
.ecg-faqs .ecg-faq__item>summary:hover{background:var(--e-global-color-slate_50)!important}
/* Elementor's border_width applies to the content pane too, which drew a rule
   between an open question and its own answer — reads as a mis-drawn divider. */
.ecg-faqs .ecg-faq__a{
  padding:0 28px 26px!important;border-top:0!important;border-bottom:0!important}

/* ---------- collage (Prima-style image mosaic), light theme -------------- */
.ecg-collage{display:grid;gap:14px;width:100%;
  grid-template-columns:repeat(4,1fr);grid-auto-rows:185px}
.ecg-collage__tile{
  position:relative;overflow:hidden;border-radius:20px;
  box-shadow:var(--ec-amb-2);display:block;text-decoration:none}
.ecg-collage__tile img{width:100%;height:100%;object-fit:cover;display:block;
  transition:transform 1.1s var(--ec-e-out)}
.ecg-collage__tile:hover img{transform:scale(1.06)}
/* Scrim. The previous gradient only reached .86 at the very bottom EDGE, but
   the label sits 17px above it — so where the text actually is, the scrim was
   only ~.55-.70. Measured against the brightest 8px block under each label
   (a sheet of paper, a bright window), white text came out at 3.70-4.30:1,
   under AA. These stops hold ~.80-.92 across the whole label zone, which puts
   the same worst cases at 7.6-9.5:1. */
.ecg-collage__tile::after{
  content:"";position:absolute;inset:0;pointer-events:none;border-radius:inherit;
  background:linear-gradient(180deg,
    rgba(0,45,107,0) 0%,
    rgba(0,45,107,.06) 30%,
    rgba(0,45,107,.42) 55%,
    rgba(0,45,107,.82) 74%,
    rgba(0,45,107,.94) 100%);
  box-shadow:inset 0 0 0 1px rgba(1,62,127,.10)}
.ecg-collage__label{
  position:absolute;left:20px;right:20px;bottom:17px;z-index:2;
  font-family:Manrope,sans-serif;font-size:15px;font-weight:600;
  letter-spacing:-.2px;color:#fff;margin:0;
  text-shadow:0 1px 3px rgba(0,18,45,.55)}
.ecg-collage__stat{
  background:var(--e-global-color-secondary);color:#fff;
  display:flex;flex-direction:column;justify-content:center;
  padding:24px;border-radius:20px}
.ecg-collage__stat b{
  font-family:Manrope,sans-serif;font-size:30px;font-weight:600;
  letter-spacing:-1px;line-height:1.05;display:block}
.ecg-collage__stat span{
  font-size:13.5px;line-height:1.5;color:var(--e-global-color-slate_300);
  margin-top:8px;display:block}
/* spans */
.ecg-collage .t-wide{grid-column:span 2}
.ecg-collage .t-tall{grid-row:span 2}
@media(max-width:1024px){
  .ecg-collage{grid-template-columns:repeat(2,1fr);grid-auto-rows:150px}
  .ecg-collage .t-wide{grid-column:span 2}
}
@media(max-width:600px){
  .ecg-collage{grid-template-columns:1fr;grid-auto-rows:170px;gap:12px}
  .ecg-collage .t-wide,.ecg-collage .t-tall{grid-column:auto;grid-row:auto}
}

/* ---------- accordion polish -------------------------------------------- */
.ecg-faqs .ecg-faq__item>summary{transition:color .4s var(--ec-e)}
.ecg-faqs .ecg-faq__icon svg,
.ecg-faqs .ecg-faq__icon i{transition:transform .5s var(--ec-e)}
.ecg-faqs .ecg-faq__item>summary[open] .ecg-faq__icon{transform:rotate(180deg)}

/* ---------- stat / metric rail ------------------------------------------ */
.ecg-rail{position:relative;padding-left:20px}
.ecg-rail::before{content:"";position:absolute;left:0;top:2px;bottom:2px;width:2px;
  border-radius:2px;
  background:linear-gradient(180deg,var(--e-global-color-teal_500),transparent)}

/* ---------- reduced motion ---------------------------------------------- */
@media(prefers-reduced-motion:reduce){
  *,*::before,*::after{
    animation-duration:.01ms!important;transition-duration:.01ms!important;
    scroll-behavior:auto!important}
  .ecg-frame:hover img{transform:none}
}

/* ==========================================================================
   DARK THEME  —  /dark/  (page-id-81)
   Second version, Prima Systems-inspired. Scoped so nothing leaks into the
   light site. Accent is the brand teal, not Prima red — see build_dark.py.
   ========================================================================== */

/* the global light header/footer are suppressed; the dark page ships its own */
.page-id-81 #site-header, .page-id-81 #site-footer{display:none!important}
.page-id-81{background:#0A0B0D}

/* floating pill nav */
.ecg-d-header{
  backdrop-filter:saturate(160%) blur(16px);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.10);
  transition:background-color .5s var(--ec-e),box-shadow .5s var(--ec-e)}
.ecg-d-header.ecg-stuck{
  background:rgba(10,11,13,.88)!important;
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.14),0 18px 40px -22px #000}
.ecg-d-nav{display:flex;gap:30px;justify-content:center;margin:0}
.ecg-d-nav a{
  color:#E8EAED;text-decoration:none;font-size:14px;font-weight:500;
  opacity:.82;transition:opacity .4s var(--ec-e),color .4s var(--ec-e)}
.ecg-d-nav a:hover{opacity:1;color:#43B8B9}

/* eyebrow pill on dark */
.ecg-d-pill .ecg-h{
  display:inline-flex;align-items:center;gap:8px;
  padding:6px 15px 6px 12px;border-radius:999px;
  background:rgba(67,184,185,.10);
  box-shadow:inset 0 0 0 1px rgba(67,184,185,.30);
  font-size:11px!important;letter-spacing:.16em!important}
.ecg-d-pill .ecg-h::before{
  content:"";width:5px;height:5px;border-radius:50%;background:#43B8B9;flex:none}

/* buttons */
.ecg-d-cta .ecg-btn{
  border-radius:999px!important;display:inline-flex;align-items:center;gap:13px;
  padding-right:14px!important;font-weight:600;
  transition:transform .4s var(--ec-e),background-color .4s var(--ec-e),box-shadow .4s var(--ec-e);
  box-shadow:0 14px 34px -16px rgba(67,184,185,.75)}
.ecg-d-cta .ecg-btn::after{
  content:"→";flex:none;width:32px;height:32px;border-radius:50%;
  display:inline-flex;align-items:center;justify-content:center;
  background:rgba(10,11,13,.16);font-size:15px;line-height:1;
  transition:transform .5s var(--ec-e)}
.ecg-d-cta .ecg-btn:hover::after{transform:translate3d(3px,-1px,0) scale(1.06)}
.ecg-d-cta .ecg-btn:active{transform:scale(.985)}
.ecg-d-ghost .ecg-btn{
  border-radius:999px!important;
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.22);
  transition:box-shadow .4s var(--ec-e),background-color .4s var(--ec-e)}
.ecg-d-ghost .ecg-btn:hover{box-shadow:inset 0 0 0 1px rgba(255,255,255,.5)}

/* hero */
.ecg-d-hero{position:relative;overflow:hidden}
.ecg-d-hero::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(120% 80% at 50% 0%,rgba(67,184,185,.16),transparent 60%)}
.ecg-d-hero > .ecg-con{position:relative;z-index:2}
.ecg-herocert-dark .ecg-w--image{background:rgba(255,255,255,.94)}

/* bento mosaic */
.ecg-d-tile{
  position:relative;overflow:hidden;border-radius:20px!important;
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.08);
  padding:0!important;justify-content:flex-end}
.ecg-d-tile .ecg-w--image{position:absolute;inset:0;margin:0}
.ecg-d-tile img{width:100%;height:100%;object-fit:cover;display:block;
  transition:transform 1.1s var(--ec-e-out)}
.ecg-d-tile:hover img{transform:scale(1.06)}
/* same correction as the light collage — full strength across the label zone,
   not only at the bottom edge */
.ecg-d-tile::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(180deg,
    rgba(10,11,13,0) 0%,
    rgba(10,11,13,.06) 30%,
    rgba(10,11,13,.44) 55%,
    rgba(10,11,13,.84) 74%,
    rgba(10,11,13,.95) 100%)}
.ecg-d-tilelabel{position:relative;z-index:2;padding:0 22px 20px}
.ecg-d-tilelabel .ecg-h{text-shadow:0 1px 3px rgba(0,0,0,.6)}

/* marquee */
.ecg-d-marqwrap{overflow:hidden}
.ecg-marquee{
  overflow:hidden;border-top:1px solid rgba(255,255,255,.10);
  border-bottom:1px solid rgba(255,255,255,.10);
  padding:20px 0;transform:rotate(-1.4deg) scale(1.04);
  background:rgba(67,184,185,.05)}
.ecg-marquee__track{
  display:inline-flex;gap:26px;white-space:nowrap;
  will-change:transform;animation:ecg-marq 34s linear infinite}
.ecg-marquee__track span,
.ecg-marquee__set li{
  font-family:Manrope,sans-serif;font-size:26px;font-weight:700;
  letter-spacing:-.6px;color:rgba(232,234,237,.62)}
.ecg-marquee__track span[aria-hidden]{color:#43B8B9}
/* The band carries seven DIFFERENT lines now (see marquee.py), so the halves
   are no longer interchangeable: the track must hold two complete sets or the
   -50% keyframe jumps mid-phrase. The separator is a pseudo-element rather
   than a real node, so the dots never reach the accessibility tree or the
   crawlable text -- six stray "·" between sentences read badly in both. */
.ecg-marquee__set{
  display:inline-flex;align-items:center;gap:26px;
  margin:0;padding:0;list-style:none}
.ecg-marquee__set li::after{
  content:'\00B7';margin-left:26px;color:#43B8B9}
@keyframes ecg-marq{from{transform:translateX(0)}to{transform:translateX(-50%)}}
@media(max-width:767px){
  .ecg-marquee__track span,
  .ecg-marquee__set li{font-size:18px}
  .ecg-marquee__set{gap:16px}
  .ecg-marquee__set li::after{margin-left:16px}
}

/* Light-theme variant of the same strip (brief item 9 — bring it from /dark/
   onto the white site). Navy band rather than the dark site's translucent teal,
   so it reads as a deliberate divider on white rather than a washed-out ghost. */
.ecg-marqwrap-light{overflow:hidden}
.ecg-marquee--light{
  background:var(--e-global-color-secondary);
  border-top:0;border-bottom:0}
.ecg-marquee--light .ecg-marquee__track span,
.ecg-marquee--light .ecg-marquee__set li{color:rgba(255,255,255,.72)}
.ecg-marquee--light .ecg-marquee__track span[aria-hidden],
.ecg-marquee--light .ecg-marquee__set li::after{color:#43B8B9}

/* dark cards */
.ecg-d-card{
  border-radius:20px!important;background:#131519!important;
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.08);
  transition:transform .6s var(--ec-e),box-shadow .6s var(--ec-e)}
.ecg-d-card:hover{
  transform:translateY(-4px);
  box-shadow:inset 0 0 0 1px rgba(67,184,185,.42),0 26px 60px -30px #000}

/* icon chip */
.ecg-d-chip{
  display:inline-flex;align-items:center;justify-content:center;
  width:48px;height:48px;border-radius:14px;
  background:rgba(67,184,185,.12);color:#43B8B9;
  box-shadow:inset 0 0 0 1px rgba(67,184,185,.26);
  transition:background-color .5s var(--ec-e),transform .5s var(--ec-e)}
.ecg-d-chip svg{width:24px;height:24px}
.ecg-d-card:hover .ecg-d-chip{background:rgba(67,184,185,.22);transform:translateY(-2px)}

/* Cross-links to the other five services. This class was emitted by
   build_services.py but never defined, so the anchors rendered as one
   run-together string ("Medical billingMedical codingAR recovery…"). */
.ecg-rellinks{display:flex;flex-wrap:wrap;gap:10px;margin-top:20px}
.ecg-rellinks a{
  display:inline-flex;align-items:center;gap:8px;
  padding:9px 16px;border-radius:999px;text-decoration:none;
  font-size:14px;font-weight:600;
  color:var(--e-global-color-secondary);
  background:#fff;box-shadow:inset 0 0 0 1px var(--e-global-color-slate_200);
  transition:box-shadow .4s var(--ec-e),transform .4s var(--ec-e),color .4s var(--ec-e)}
.ecg-rellinks a::after{content:"→";opacity:.45;transition:transform .4s var(--ec-e)}
.ecg-rellinks a:hover{
  color:var(--e-global-color-accent);transform:translateY(-2px);
  box-shadow:inset 0 0 0 1px var(--e-global-color-teal_500),var(--ec-amb-1)}
.ecg-rellinks a:hover::after{transform:translateX(3px)}

/* Service-page hero medallion. Like .ecg-rellinks, these classes were emitted
   by build_services.py but never defined: the wrapper was display:inline and
   the SVG resolved to 0x0, so all six service heroes had a dead right-hand
   column. Sized here, with the discipline icon set in a soft concentric ring
   that echoes the double-bezel cards. */
.ecg-svc-markwrap{
  display:flex;align-items:center;justify-content:center;width:100%;
  min-height:260px}
.ecg-svc-markwrap .ecg-w--text{width:auto}
.ecg-svc-mark{
  display:flex;align-items:center;justify-content:center;
  width:188px;height:188px;border-radius:50%;
  color:var(--e-global-color-primary);
  background:
    radial-gradient(closest-side,rgba(255,255,255,.9),rgba(255,255,255,.55));
  box-shadow:
    inset 0 0 0 1px var(--e-global-color-slate_200),
    0 0 0 14px rgba(4,161,162,.05),
    0 0 0 15px rgba(4,161,162,.12),
    var(--ec-amb-2);
  transition:transform .6s var(--ec-e),box-shadow .6s var(--ec-e)}
.ecg-svc-mark svg{
  width:78px;height:78px;stroke:currentColor;fill:none;
  stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round}
.ecg-svc-markwrap:hover .ecg-svc-mark{
  transform:translateY(-3px);
  box-shadow:
    inset 0 0 0 1px var(--e-global-color-teal_500),
    0 0 0 14px rgba(4,161,162,.07),
    0 0 0 15px rgba(4,161,162,.20),
    var(--ec-amb-2)}
@media(max-width:1024px){
  .ecg-svc-markwrap{min-height:0;padding-top:8px}
  .ecg-svc-mark{width:132px;height:132px}
  .ecg-svc-mark svg{width:56px;height:56px}
}

/* Revenue-assessment review areas — 3x2 grid. Was six Elementor containers at
   width 48% inside a 46% column; Elementor ignored the width and stacked them
   one per row. A real CSS grid is both simpler and reliable. */
.ecg-review{
  display:grid;gap:1px;width:100%;
  /* auto-fit, NOT repeat(3,1fr). The hairline dividers are this container's
     background showing through the 1px gap, so a column with no card in it
     renders as a solid slate block — which is the grey panel that appeared on
     the nine pages whose topic filter matches only two quotes. auto-fit
     collapses the empty track instead, and the 320px floor still yields three
     columns in the 1232px container (so the homepage keeps its 3x2), two at
     tablet and one on a phone. The media queries below stay as a backstop. */
  grid-template-columns:repeat(auto-fit,minmax(min(100%,320px),1fr));
  background:var(--e-global-color-slate_200);
  border:1px solid var(--e-global-color-slate_200);
  border-radius:20px;overflow:hidden}
.ecg-review__cell{
  background:#fff;padding:32px 30px 34px;
  transition:background-color .45s var(--ec-e)}
.ecg-review__cell:hover{background:var(--e-global-color-slate_50)}
.ecg-review__n{
  display:block;font-family:Inter,sans-serif;font-size:11px;font-weight:700;
  letter-spacing:1.4px;color:var(--e-global-color-accent);
  font-variant-numeric:tabular-nums}
.ecg-review__t{
  margin:12px 0 0;font-family:Manrope,sans-serif;font-size:19px;font-weight:600;
  letter-spacing:-.3px;color:var(--e-global-color-secondary)}
.ecg-review__d{
  margin:8px 0 0;font-family:Inter,sans-serif;font-size:15px;line-height:1.7;
  color:var(--e-global-color-text)}
@media(max-width:1024px){.ecg-review{grid-template-columns:repeat(auto-fit,minmax(min(100%,280px),1fr))}}
@media(max-width:600px){
  .ecg-review{grid-template-columns:1fr}
  .ecg-review__cell{padding:26px 22px 28px}
}

/* giant outlined numeral */
.ecg-d-bignum .ecg-h{
  -webkit-text-stroke:1.5px rgba(255,255,255,.20);
  color:transparent!important;line-height:.9;
  font-variant-numeric:tabular-nums;
  transition:-webkit-text-stroke-color .6s var(--ec-e)}
.ecg-d-bignum:hover .ecg-h{-webkit-text-stroke-color:#43B8B9}

/* Dark accordion. Elementor's global slots resolve to the light theme, and the
   kit's `:root a` rule outranks single-class selectors here too, so
   the dark FAQ has to be pinned rather than inherited.
   #E8EAED on #131519 = 15.1:1 · #9AA0A8 on #131519 = 6.9:1 · teal #43B8B9 = 7.6:1 */
/* ==========================================================================
   MEGA MENU — DARK
   .ecg-mm--dark was emitted by megamenu.py from the start but never styled,
   so the dark page shipped with three plain anchor links instead. Same markup
   and same JS as light; only the skin differs.
   ========================================================================== */
/* CSS sticky, for the same reason as the light header: Elementor's sticky
   clones the header and would duplicate every mega-menu id on this page. */
#dark-header{position:sticky;top:14px;z-index:60}
/* the panel spans the header, so everything between must be static */
#dark-header .ecg-con,#dark-header .ecg-con,
#dark-header .ecg-w,#dark-header .ecg-mm--dark{position:static}

.ecg-mm--dark .ecg-mm__top,
.ecg-mm--dark .ecg-mm__trigger{color:#E8EAED!important}          /* 15.2:1 on the pill */
.ecg-mm--dark .ecg-mm__top:hover,
.ecg-mm--dark .ecg-mm__trigger:hover,
.ecg-mm--dark .ecg-mm__trigger[aria-expanded="true"]{
  color:#fff;background:rgba(255,255,255,.08)}
.ecg-mm--dark .ecg-mm__top:focus-visible,
.ecg-mm--dark .ecg-mm__trigger:focus-visible{outline-color:#43B8B9}

.ecg-mm--dark .ecg-mm__inner{
  background:#131519;border:1px solid rgba(255,255,255,.10);
  box-shadow:0 30px 80px -24px rgba(0,0,0,.85)}
.ecg-mm--dark .ecg-mm__eyebrow{color:#43B8B9}                    /* 7.9:1 on #131519 */
.ecg-mm--dark .ecg-mm__item:hover{background:rgba(255,255,255,.05)}
.ecg-mm--dark .ecg-mm__ico{background:rgba(67,184,185,.14);color:#43B8B9}
.ecg-mm--dark .ecg-mm__item:hover .ecg-mm__ico{background:#43B8B9;color:#0A0B0D}
.ecg-mm--dark .ecg-mm__txt strong{color:#E8EAED!important}       /* 15.2:1 */
.ecg-mm--dark .ecg-mm__txt em{color:#9AA0A8!important}           /* 6.9:1  */


/* promo cell — teal on near-black rather than the light theme's navy card */
.ecg-mm--dark .ecg-mm__promo{background:rgba(67,184,185,.09);
  border:1px solid rgba(67,184,185,.20)}
.ecg-mm--dark .ecg-mm__promoh{color:#E8EAED}
.ecg-mm--dark .ecg-mm__promod{color:#9AA0A8}
.ecg-mm--dark .ecg-mm__promocta{background:#43B8B9;color:#0A0B0D!important}  /* 8.3:1 */
.ecg-mm--dark .ecg-mm__promocta:hover{background:#70D1D1}
.ecg-mm--dark .ecg-mm__promoalt{color:#9AA0A8!important}
.ecg-mm--dark .ecg-mm__promoalt:hover{color:#fff!important}

/* Burger stays inside .ecg-mm, so it can be scoped normally. */
.ecg-mm--dark .ecg-mm__burger{
  background:rgba(255,255,255,.07)!important;
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.14)}
.ecg-mm--dark .ecg-mm__burger span{background:#E8EAED!important}

/* The DRAWER is portalled to <body> while open and leaves .ecg-mm entirely,
   so it carries its own modifier (set in megamenu.py). Scoping these under
   .ecg-mm--dark would silently revert them to light exactly when opened. */
.ecg-mm__bar--dark{background:#131519}
.ecg-mm__bar--dark .ecg-mm__close{
  background:rgba(255,255,255,.07)!important;color:#E8EAED!important;
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.14)}
.ecg-mm__bar--dark .ecg-mm__top,
.ecg-mm__bar--dark .ecg-mm__trigger{color:#E8EAED!important}
.ecg-mm__bar--dark .ecg-mm__top:hover,
.ecg-mm__bar--dark .ecg-mm__trigger:hover{background:rgba(255,255,255,.08);color:#fff}
.ecg-mm__bar--dark .ecg-mm__inner{
  background:#131519;border-color:rgba(255,255,255,.10)}
.ecg-mm__bar--dark .ecg-mm__txt strong{color:#E8EAED!important}
.ecg-mm__bar--dark .ecg-mm__txt em{color:#9AA0A8!important}
.ecg-mm__bar--dark .ecg-mm__ico{background:rgba(67,184,185,.14);color:#43B8B9}
.ecg-mm__bar--dark .ecg-mm__eyebrow{color:#43B8B9}
.ecg-mm__bar--dark .ecg-mm__promo{
  background:rgba(67,184,185,.09);border:1px solid rgba(67,184,185,.20)}
.ecg-mm__bar--dark .ecg-mm__promoh{color:#E8EAED}
.ecg-mm__bar--dark .ecg-mm__promod{color:#9AA0A8}
.ecg-mm__bar--dark .ecg-mm__promocta{background:#43B8B9;color:#0A0B0D!important}
.ecg-mm__bar--dark .ecg-mm__promoalt{color:#9AA0A8!important}

/* dark: undo the light panel construction above */
.ecg-d-faq .ecg-faqs{
  background:rgba(255,255,255,.03)!important;
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.10)!important}
.ecg-d-faq .ecg-faqs .ecg-faq__item{
  border-top-color:rgba(255,255,255,.10)!important}
.ecg-d-faq .ecg-faqs .ecg-faq__item>summary:hover{
  background:rgba(255,255,255,.04)!important}
.ecg-d-faq .ecg-faqs .ecg-faq__item>summary{
  background:transparent!important;
  border-color:rgba(255,255,255,.12)!important}
.ecg-d-faq .ecg-faqs .ecg-faq__item>summary a,
.ecg-d-faq .ecg-faqs .ecg-faq__item>summary{color:#E8EAED!important}
.ecg-d-faq .ecg-faqs .ecg-faq__item>summary[open],
.ecg-d-faq .ecg-faqs .ecg-faq__item>summary[open] a{
  color:#43B8B9!important}
.ecg-d-faq .ecg-faqs .ecg-faq__a{
  background:transparent!important;color:#9AA0A8!important;
  border-color:rgba(255,255,255,.12)!important}
.ecg-d-faq .ecg-faqs .ecg-faq__item{
  border-color:rgba(255,255,255,.12)!important;background:transparent!important}

/* dark photograph treatment — matches .ecg-frame on light */
.ecg-d-shot img{
  width:100%;display:block;border-radius:20px;
  box-shadow:0 0 0 1px rgba(255,255,255,.08),0 30px 60px -24px rgba(0,0,0,.8);
  filter:saturate(.92) contrast(1.02)}

/* certification chip on dark — marks never recoloured */
.ecg-d-certchip{
  background:#fff;border-radius:14px;padding:14px 20px;
  display:inline-flex;align-items:center;justify-content:center;
  width:auto!important;align-self:center}
.ecg-d-certchip img{height:62px!important;width:auto!important;display:block}

/* dark cta band */
.ecg-d-ctaband{position:relative;overflow:hidden;background:#0A0B0D}
.ecg-d-ctaband::before{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(90% 120% at 50% 100%,rgba(67,184,185,.18),transparent 62%)}
.ecg-d-ctaband > .ecg-con{position:relative;z-index:2}

/* The dark header is a fixed 26% / 48% / 26% row. At 375px that leaves 97px for
   a ~140px button, so "Get in touch" is pushed past the right edge — on the
   live site it causes the page to pan sideways; here it would simply be
   clipped. Neither is acceptable, so the three columns size to their content on
   a phone instead. Scoped to #dark-header: the main site's header already
   solves this by swapping to a compact CTA below 1200px. */
@media(max-width:767px){
  #dark-header .ecg-con{width:auto;flex:0 1 auto;min-width:0}
  #dark-header .ecg-btn{padding:10px 15px;font-size:13.5px;white-space:nowrap}
  #dark-header .ecg-w--image img{width:118px}
}

/* dark footer links */
.ecg-d-flinks{display:flex;flex-direction:column;gap:11px;margin:0}
.ecg-d-flinks a{color:#9AA0A8;text-decoration:none;
  transition:color .4s var(--ec-e)}
.ecg-d-flinks a:hover{color:#fff}
#dark-footer .ecg-d-flinks p{margin:0}

@media(prefers-reduced-motion:reduce){
  .ecg-marquee__track{animation:none}
  .ecg-d-tile:hover img{transform:none}
}

/* ==========================================================================
   MEGA MENU
   Hand-built: Elementor's Nav Menu cannot do icons + per-item descriptions +
   a promo cell. Real links inside a real <nav>, so it degrades without JS.
   ========================================================================== */
/* the panel is absolutely positioned and must span the whole header, so the
   header is the containing block and everything between it is static */
#site-header .ecg-con,#site-header .ecg-con,
#site-header .ecg-w,#site-header .ecg-mm{position:static}
.ecg-mm{display:flex;align-items:center;justify-content:flex-end;width:100%}
.ecg-mm__bar{display:flex;align-items:center;gap:6px}
.ecg-mm__group{position:static}

.ecg-mm__top,.ecg-mm__trigger{
  display:inline-flex;align-items:center;gap:6px;
  font-family:Inter,sans-serif;font-size:15px;font-weight:500;letter-spacing:-.01em;
  color:var(--e-global-color-text);background:none;border:0;cursor:pointer;
  /* 7 items in one row: they must never wrap or shrink, or a two-word label
     like "Who we work with" breaks onto a second line and doubles the header */
  white-space:nowrap;flex:none;
  /* <button> and <a> resolve line-height differently (19.2px vs inherited),
     which made the triggers 40px and the links 48px — same baseline, different
     hover pill. Pinned so all seven match. */
  line-height:1.6;min-height:46px;
  padding:0 11px;border-radius:10px;text-decoration:none;
  transition:color .35s var(--ec-e),background-color .35s var(--ec-e)}
.ecg-mm__top:hover,.ecg-mm__trigger:hover,
.ecg-mm__trigger[aria-expanded="true"]{
  color:var(--e-global-color-primary);background:var(--e-global-color-slate_50)}
.ecg-mm__trigger svg{width:15px;height:15px;transition:transform .4s var(--ec-e)}
.ecg-mm__trigger[aria-expanded="true"] svg{transform:rotate(180deg)}
.ecg-mm__top:focus-visible,.ecg-mm__trigger:focus-visible{
  outline:2px solid var(--e-global-color-teal_600);outline-offset:2px}

/* the panel */
.ecg-mm__panel{
  position:absolute;left:0;right:0;top:100%;z-index:60;
  padding:0 32px;opacity:0;transform:translateY(-8px);pointer-events:none;
  transition:opacity .28s var(--ec-e),transform .28s var(--ec-e)}
.ecg-mm__panel.is-open{opacity:1;transform:translateY(0);pointer-events:auto}
.ecg-mm__inner{
  max-width:1280px;margin:10px auto 0;display:flex;gap:34px;
  background:#fff;border-radius:22px;padding:30px;
  box-shadow:0 2px 4px rgba(1,62,127,.05),0 30px 70px -24px rgba(1,62,127,.28);
  border:1px solid var(--e-global-color-slate_200)}
.ecg-mm__col{flex:1 1 auto;min-width:0}
.ecg-mm__eyebrow{
  font-size:10.5px;font-weight:600;letter-spacing:.16em;text-transform:uppercase;
  color:var(--e-global-color-accent);margin:0 0 16px}
.ecg-mm__grid{display:grid;grid-template-columns:repeat(2,1fr);gap:6px}

.ecg-mm__item{
  display:flex;gap:14px;align-items:flex-start;padding:13px 14px;border-radius:14px;
  text-decoration:none;transition:background-color .35s var(--ec-e),transform .35s var(--ec-e)}
.ecg-mm__item:hover{background:var(--e-global-color-slate_50);transform:translateX(2px)}
.ecg-mm__item:focus-visible{outline:2px solid var(--e-global-color-teal_600);outline-offset:-2px}
.ecg-mm__ico{
  flex:none;width:38px;height:38px;border-radius:11px;
  display:grid;place-items:center;
  background:var(--e-global-color-teal_50);color:var(--e-global-color-teal_700);
  transition:background-color .35s var(--ec-e),color .35s var(--ec-e)}
.ecg-mm__ico svg{width:20px;height:20px}
.ecg-mm__item:hover .ecg-mm__ico{
  background:var(--e-global-color-teal_600);color:#fff}
.ecg-mm__txt{display:flex;flex-direction:column;gap:3px;min-width:0}
.ecg-mm__txt strong{
  font-family:Manrope,sans-serif;font-size:15px;font-weight:600;letter-spacing:-.01em;
  color:var(--e-global-color-secondary)}
.ecg-mm__txt em{
  font-style:normal;font-size:13px;line-height:1.5;color:var(--e-global-color-slate_600)}

/* Specialties panel — 28 items. Typographic three-column list rather than 28
   icon chips: at that count chips are noise, and this stays scannable. */
.ecg-mm__speccols{display:grid;grid-template-columns:repeat(3,1fr);gap:2px 18px}
.ecg-mm__speccol{display:flex;flex-direction:column}
.ecg-mm__spec{
  display:block;padding:8px 10px;border-radius:9px;text-decoration:none;
  font-family:Inter,sans-serif;font-size:14px;line-height:1.35;
  color:var(--e-global-color-secondary)!important;
  transition:background-color .3s var(--ec-e),transform .3s var(--ec-e)}
.ecg-mm__spec:hover{
  background:var(--e-global-color-slate_50);transform:translateX(2px);
  color:var(--e-global-color-primary)!important}
.ecg-mm__spec:focus-visible{outline:2px solid var(--e-global-color-teal_600);outline-offset:-2px}
.ecg-mm--dark .ecg-mm__spec,.ecg-mm__bar--dark .ecg-mm__spec{color:#E8EAED!important}
.ecg-mm--dark .ecg-mm__spec:hover,.ecg-mm__bar--dark .ecg-mm__spec:hover{
  background:rgba(255,255,255,.05);color:#fff!important}
@media(max-width:1024px){.ecg-mm__speccols{grid-template-columns:repeat(2,1fr)}}
@media(max-width:600px){.ecg-mm__speccols{grid-template-columns:1fr}}

/* ==========================================================================
   BLOG — hub index and article template
   ========================================================================== */
.ecg-blog{display:flex;flex-direction:column;gap:22px;width:100%}
.ecg-blog__lead,.ecg-blog__card{
  display:block;position:relative;overflow:hidden;border-radius:22px;
  text-decoration:none;background:#fff;
  box-shadow:inset 0 0 0 1px var(--e-global-color-slate_200),var(--ec-amb-1);
  transition:transform .5s var(--ec-e),box-shadow .5s var(--ec-e)}
.ecg-blog__lead:hover,.ecg-blog__card:hover{
  transform:translateY(-4px);
  box-shadow:inset 0 0 0 1px var(--e-global-color-teal_500),var(--ec-amb-3)}
.ecg-blog__lead img{width:100%;height:340px;object-fit:cover;display:block}
.ecg-blog__card img{width:100%;height:200px;object-fit:cover;display:block}
.ecg-blog__leadtxt,.ecg-blog__cardtxt{
  display:flex;flex-direction:column;gap:9px;padding:28px 30px 30px}
.ecg-blog__grid{display:grid;grid-template-columns:repeat(2,1fr);gap:22px}
.ecg-blog__topic{
  font-family:Inter,sans-serif;font-size:10.5px;font-weight:600;
  letter-spacing:.16em;text-transform:uppercase;
  color:var(--e-global-color-accent)}
.ecg-blog__lead strong{
  font-family:Manrope,sans-serif;font-size:30px;font-weight:600;letter-spacing:-.8px;
  line-height:1.16;color:var(--e-global-color-secondary)}
.ecg-blog__card strong{
  font-family:Manrope,sans-serif;font-size:21px;font-weight:600;letter-spacing:-.5px;
  line-height:1.22;color:var(--e-global-color-secondary)}
.ecg-blog__lead em,.ecg-blog__card em{
  font-style:normal;font-family:Inter,sans-serif;font-size:15.5px;line-height:1.62;
  color:var(--e-global-color-text)}
.ecg-blog__read{
  font-family:Inter,sans-serif;font-size:13px;color:var(--e-global-color-slate_600)}
@media(max-width:820px){
  .ecg-blog__grid{grid-template-columns:1fr}
  .ecg-blog__lead img{height:230px}
  .ecg-blog__lead strong{font-size:24px}
  .ecg-blog__leadtxt,.ecg-blog__cardtxt{padding:22px 22px 24px}
}

/* article meta row */
.ecg-postmeta{display:flex;flex-wrap:wrap;gap:10px 18px;margin:0}
.ecg-postmeta span{display:inline-flex;align-items:center;gap:8px}
.ecg-postmeta span+span::before{
  content:"";width:3px;height:3px;border-radius:50%;
  background:var(--e-global-color-slate_400);display:inline-block}

/* long-form body */
.ecg-prose h2{
  font-family:Manrope,sans-serif;font-size:27px;font-weight:600;letter-spacing:-.6px;
  line-height:1.24;color:var(--e-global-color-secondary);margin:44px 0 14px}
.ecg-prose p{margin:0 0 20px}
.ecg-prose .ecg-list{margin:0 0 24px}
.ecg-pq{
  margin:34px 0;padding:4px 0 4px 26px;border:0;
  border-left:3px solid var(--e-global-color-teal_500);
  font-family:Manrope,sans-serif;font-size:22px;font-weight:600;
  letter-spacing:-.5px;line-height:1.4;color:var(--e-global-color-secondary)}

/* related cards at the foot of an article */
.ecg-rel{display:grid;grid-template-columns:repeat(2,1fr);gap:16px}
.ecg-rel__card{
  display:flex;flex-direction:column;gap:8px;padding:24px 26px 26px;
  border-radius:18px;text-decoration:none;background:#fff;
  box-shadow:inset 0 0 0 1px var(--e-global-color-slate_200);
  transition:transform .5s var(--ec-e),box-shadow .5s var(--ec-e)}
.ecg-rel__card:hover{
  transform:translateY(-3px);
  box-shadow:inset 0 0 0 1px var(--e-global-color-teal_500),var(--ec-amb-2)}
.ecg-rel__topic{
  font-family:Inter,sans-serif;font-size:10.5px;font-weight:600;letter-spacing:.16em;
  text-transform:uppercase;color:var(--e-global-color-accent)}
.ecg-rel__card strong{
  font-family:Manrope,sans-serif;font-size:18px;font-weight:600;letter-spacing:-.4px;
  line-height:1.28;color:var(--e-global-color-secondary)}
.ecg-rel__card em{
  font-style:normal;font-family:Inter,sans-serif;font-size:14.5px;line-height:1.6;
  color:var(--e-global-color-text)}
@media(max-width:700px){.ecg-rel{grid-template-columns:1fr}}

/* ==========================================================================
   TESTIMONIALS
   Restrained on purpose. No avatars (we have no photographs of these people
   and will not generate any), no giant decorative quote glyphs, no carousel.
   The quote carries it; attribution sits underneath in small caps.
   ========================================================================== */
.ecg-quotes{
  display:grid;gap:18px;width:100%;
  grid-template-columns:repeat(auto-fit,minmax(300px,1fr))}
.ecg-quote{
  margin:0;padding:32px 32px 30px;border-radius:22px;background:#fff;
  display:flex;flex-direction:column;
  box-shadow:inset 0 0 0 1px var(--e-global-color-slate_200),var(--ec-amb-1);
  transition:transform .5s var(--ec-e),box-shadow .5s var(--ec-e)}
.ecg-quote:hover{
  transform:translateY(-3px);
  box-shadow:inset 0 0 0 1px var(--e-global-color-teal_500),var(--ec-amb-2)}
.ecg-quote blockquote{
  margin:0 0 22px;padding:0;border:0;flex:1;
  font-family:Manrope,sans-serif;font-size:17px;font-weight:500;
  line-height:1.6;letter-spacing:-.2px;
  color:var(--e-global-color-secondary)}
.ecg-quote blockquote::before{content:"\201C"}
.ecg-quote blockquote::after{content:"\201D"}
.ecg-quote figcaption{
  display:flex;flex-direction:column;gap:3px;
  padding-top:18px;border-top:1px solid var(--e-global-color-slate_200)}
.ecg-quote figcaption strong{
  font-family:Inter,sans-serif;font-size:15px;font-weight:600;
  color:var(--e-global-color-secondary)}
.ecg-quote figcaption span{
  font-family:Inter,sans-serif;font-size:13.5px;
  color:var(--e-global-color-slate_600)}
/* only rendered when a real rating exists — see testimonials.py */
.ecg-quote__stars{
  display:block;margin:0 0 14px;letter-spacing:3px;font-size:15px;
  color:var(--e-global-color-amber_500,#C8901E)}
.ecg-quotes--dark .ecg-quote{
  background:rgba(255,255,255,.04);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.09)}
.ecg-quotes--dark .ecg-quote:hover{
  box-shadow:inset 0 0 0 1px rgba(67,184,185,.42)}
.ecg-quotes--dark .ecg-quote blockquote{color:#E8EAED}
.ecg-quotes--dark .ecg-quote figcaption{border-top-color:rgba(255,255,255,.12)}
.ecg-quotes--dark .ecg-quote figcaption strong{color:#E8EAED}
.ecg-quotes--dark .ecg-quote figcaption span{color:#9AA0A8}
@media(max-width:600px){.ecg-quote{padding:26px 24px 24px}}

/* /faqs/ — jump nav + group headings */
.ecg-faqnav{display:flex;flex-wrap:wrap;gap:8px;margin:0}
.ecg-faqnav a{
  display:inline-flex;padding:7px 14px;border-radius:999px;text-decoration:none;
  font-family:Inter,sans-serif;font-size:13.5px;font-weight:500;
  color:var(--e-global-color-secondary)!important;background:#fff;
  box-shadow:inset 0 0 0 1px var(--e-global-color-slate_200);
  transition:box-shadow .35s var(--ec-e),color .35s var(--ec-e)}
.ecg-faqnav a:hover{
  color:var(--e-global-color-accent)!important;
  box-shadow:inset 0 0 0 1px var(--e-global-color-teal_500)}
.ecg-faqgroup{scroll-margin-top:110px}

/* Contact details block (/contact/). Labelled rows rather than a loose blob —
   a phone number and a postal address are the two things a practice owner
   scans for, so they get their own line and a hit target. */
.ecg-contact p,
.ecg-contact .ecg-row{
  display:grid;grid-template-columns:78px 1fr;gap:4px 14px;
  margin:0 0 16px;align-items:start}
/* the address arrives from [nexen_address] as its own <p>; it is the grid's
   second cell, not another grid */
.ecg-contact .ecg-addr{display:block;margin:0}
.ecg-contact span{
  font-family:Inter,sans-serif;font-size:12px;font-weight:600;
  letter-spacing:.12em;text-transform:uppercase;
  color:var(--e-global-color-slate_600);padding-top:4px}
.ecg-contact a{
  color:var(--e-global-color-primary)!important;text-decoration:none;
  border-bottom:1px solid rgba(1,62,127,.22);
  transition:border-color .35s var(--ec-e),color .35s var(--ec-e)}
.ecg-contact a:hover{
  color:var(--e-global-color-accent)!important;
  border-bottom-color:var(--e-global-color-teal_500)}
@media(max-width:520px){
  .ecg-contact p,
  .ecg-contact .ecg-row{grid-template-columns:1fr;gap:2px}
  .ecg-contact span{padding-top:0}
}

/* footer legal links — inline row with a hairline separator, not a stacked list */
.ecg-legal{display:flex;flex-wrap:wrap;gap:8px 20px;margin:0}
.ecg-legal a{position:relative}
.ecg-legal a+a::before{
  content:"";position:absolute;left:-10px;top:50%;transform:translateY(-50%);
  width:1px;height:12px;background:rgba(255,255,255,.22)}

/* ---------- floating WhatsApp chat button (brief item 10) ----------------
   Bottom-RIGHT deliberately: the cookie widget already occupies bottom-left,
   and two floating controls in the same corner is how you get mis-taps. */
.ecg-fab{
  position:fixed;right:20px;bottom:20px;z-index:70;
  display:inline-flex;align-items:center;gap:0;
  height:56px;padding:0 16px;border-radius:999px;
  /* WhatsApp green #25D366 is only 1.98:1 against a white page, under the 3:1
     WCAG 1.4.11 wants for a control's boundary. The fill stays (the mark is
     logo-exempt, and instant recognition is this control's whole job) and the
     boundary is carried by a two-tone ring, because a FIXED button floats over
     whatever is scrolled behind it — white sections, photography, the navy
     footer — so no single rim colour can hold 3:1 everywhere. Measured:
       inner #0B7D45  5.21:1 on white, 2.54:1 on navy  -> carries light backdrops
       outer #FFFFFF  1.00:1 on white, 13.7:1 on navy  -> carries dark backdrops
     One of the two always clears 3:1. Same principle as WCAG 2.2 focus
     appearance, which allows a two-colour indicator for exactly this reason. */
  background:#25D366;color:#fff!important;text-decoration:none;
  --fab-ring:inset 0 0 0 2px #0B7D45, 0 0 0 2px #fff;
  --fab-lift:0 6px 18px -4px rgba(0,0,0,.28),0 2px 6px rgba(0,0,0,.12);
  transition:gap .45s var(--ec-e),padding .45s var(--ec-e),
             transform .45s var(--ec-e),box-shadow .45s var(--ec-e)}
.ecg-fab svg{width:26px;height:26px;flex:none}
/* label is width-collapsed rather than display:none, so it can animate open
   and still be read by assistive tech */
.ecg-fab__label{
  max-width:0;overflow:hidden;white-space:nowrap;
  font-family:Inter,sans-serif;font-size:15px;font-weight:600;
  transition:max-width .45s var(--ec-e)}
.ecg-fab:hover,.ecg-fab:focus-visible{
  gap:10px;transform:translateY(-2px);
  --fab-lift:0 10px 24px -6px rgba(0,0,0,.34),0 3px 8px rgba(0,0,0,.14)}
/* Elementor ships `.ecg-w a{box-shadow:none}` at (0,1,1), which outranks
   .ecg-fab at (0,1,0) and silently ate the ring — the rule was in the CSSOM
   and simply lost. Beaten by matching its shape, not by !important. The shadow
   values live once, in the two custom properties above; hovering only swaps
   --fab-lift and this declaration recomputes. */
.ecg-w a.ecg-fab{box-shadow:var(--fab-ring),var(--fab-lift)}
.ecg-fab:hover .ecg-fab__label,
.ecg-fab:focus-visible .ecg-fab__label{max-width:160px}
.ecg-fab:focus-visible{outline:3px solid #0B7D45;outline-offset:4px}
@media(max-width:767px){
  .ecg-fab{right:14px;bottom:14px;height:52px;padding:0 13px}
  .ecg-fab svg{width:24px;height:24px}
  /* never expand on touch — there is no hover, and a wide pill covers content */
  .ecg-fab:hover .ecg-fab__label{max-width:0}
}
@media(prefers-reduced-motion:reduce){
  .ecg-fab,.ecg-fab__label{transition:none}
}

/* footer social row — square touch targets, brand marks never recoloured to
   their own palettes (eight brand colours in a navy footer is noise) */
.ecg-social{display:flex;flex-wrap:wrap;gap:10px;margin:0}
.ecg-social__link{
  display:inline-flex;align-items:center;justify-content:center;
  width:40px;height:40px;border-radius:11px;
  color:var(--e-global-color-slate_300)!important;
  background:rgba(255,255,255,.06);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.12);
  transition:background-color .35s var(--ec-e),color .35s var(--ec-e),
             transform .35s var(--ec-e)}
.ecg-social__link svg{width:19px;height:19px;display:block}
.ecg-social__link:hover{
  background:#fff;color:var(--e-global-color-secondary)!important;
  transform:translateY(-2px)}
.ecg-social__link:focus-visible{
  outline:2px solid var(--e-global-color-teal_500);outline-offset:2px}
/* Five tiles need 240px; the LIGHT footer's brand column is only 206px at
   1440 and 186px at 1280, so the row wraps 4 + 1 and the last icon sits alone
   looking dropped. Capping to three-per-row makes it wrap 3 + 2, which reads
   as a deliberate block. Scoped to #site-footer and to desktop only: the dark
   footer's column is wider and fits all five, and below 1025px this column
   goes full-width where five fit comfortably. Shrinking the tiles instead
   would have meant giving up the 40px touch target. */
@media(min-width:1025px){#site-footer .ecg-social{max-width:145px}}

/* footer address — kept quieter than the linked phone/email above it */
.ecg-addr{margin-top:10px;opacity:.9}

/* The FAQ page's closing CTA band is navy (#001E57). The kit's global link
   colour (#006B6C) lands at 2.51:1 on it — measured, and a WCAG AA failure that
   is live today. Links there take the band's own text colour and keep an
   underline, so they stay identifiable as links without relying on hue.
   The button in the same band is excluded: it is an <a> too, and inheriting
   there turned white-on-navy into navy-on-navy at 1.20:1. */
#e-fqcta a:not(.ecg-btn){
  color:inherit;text-decoration:underline;text-underline-offset:3px;
  text-decoration-thickness:1px}
#e-fqcta a:not(.ecg-btn):hover{color:#fff}

/* ---------- the lead form ------------------------------------------------
   Elementor Pro generated the field LAYOUT itself (its own grid, its own
   widths), so removing it takes the layout with it and leaves only the focus
   ring and the submit button below. This is that layout, rebuilt against the
   markup the plugin emits — two columns that collapse to one, fields sized to
   match the submit button they sit above.

   Contrast is measured, not estimated: error 7.50:1 on its banner, success
   5.21:1, the field border 3.39:1 on white for WCAG 1.4.11. The script that
   checks those numbers is in the same commit as this block.
   ------------------------------------------------------------------------- */
.ecg-form{display:flex;flex-wrap:wrap;gap:18px;width:100%}
.ecg-field{
  margin:0;min-width:0;flex:1 1 100%;
  display:flex;flex-direction:column;gap:7px}
/* two columns: the 18px gap is split between them, hence the -9px */
.ecg-field--w50{flex-basis:calc(50% - 9px)}
.ecg-field--w33{flex-basis:calc(33.333% - 12px)}
.ecg-field--w100{flex-basis:100%}

.ecg-input{
  /* 54px matches the submit button exactly; a 40px field under a 54px button
     was the mismatch that made this card read as two designs in one. */
  min-height:54px;padding:0 16px;
  transition:border-color .25s var(--ec-e),box-shadow .25s var(--ec-e)}
textarea.ecg-input{min-height:132px;padding:15px 16px;line-height:1.55;resize:vertical}
select.ecg-input{
  appearance:none;-webkit-appearance:none;padding-right:44px;cursor:pointer;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5l5-5' fill='none' stroke='%236F747A' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 16px center}
.ecg-input::placeholder{color:var(--e-global-color-slate_500)}
/* An unchosen select must not look like an answer. */
select.ecg-input:invalid,select.ecg-input option[value=""]{color:var(--e-global-color-slate_500)}
/* iOS zooms the viewport on focus for any field under 16px. The kit sets 15px,
   which is why the form has to override it on small screens specifically. */
@media(max-width:767px){
  .ecg-form{gap:16px}
  .ecg-field,.ecg-field--w50,.ecg-field--w33{flex-basis:100%}
  .ecg-input{font-size:16px}
}

.ecg-req{color:#A1002A;font-weight:700}

/* Status. role="status"/"alert" carry this to a screen reader; these styles are
   for everyone else. The error is NOT decorative — a form that reports failure
   quietly is the thing this whole replacement exists to avoid. */
.ecg-form__ok,.ecg-form__err{
  flex:1 1 100%;margin:0;padding:14px 16px;border-radius:10px;
  font-size:15px;line-height:1.5;border:1px solid}
.ecg-form__ok{color:#047857;background:#ECFDF5;border-color:#A7E8CB}
.ecg-form__err{color:#A1002A;background:#FFF1F3;border-color:#F3B9C4}

/* The honeypot. Hidden from sight and from assistive tech, still submitted —
   so it must not be display:none, which many bots skip. */
.ecg-hp{
  position:absolute!important;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}

/* Form submit. It is an Elementor *form* button, not .ecg-cta, so it never got
   the site's button treatment — it picked up the global 999px pill radius and
   the widget's small size, landing as a 40px pill under a column of 53px fields
   with 10px corners. Two different design languages in one card. Matched to the
   form: same radius as the inputs, same height, full width. */
.ecg-form .ecg-btn,
.ecg-form button[type="submit"]{
  border-radius:10px!important;
  /* Elementor sets min-height:40px on form buttons at a higher precedence, so
     this needs !important or the button stays 13px shorter than every field. */
  min-height:54px!important;height:auto!important;width:100%;
  display:flex!important;align-items:center;justify-content:center;
  padding:0 26px!important;
  font-family:Inter,sans-serif;font-size:16px!important;font-weight:600!important;
  box-shadow:var(--ec-amb-1);
  transition:background-color .4s var(--ec-e),transform .4s var(--ec-e),
             box-shadow .4s var(--ec-e)}
.ecg-form .ecg-btn:hover,
.ecg-form button[type="submit"]:hover{
  transform:translateY(-2px);box-shadow:var(--ec-amb-2)}
.ecg-form .ecg-field--submit{margin-top:6px}

/* EHR / PM systems — real vendor marks, see the note in build_home.py.

   The cards move (brief item 4, "two moving logo strips"). Layout and card
   styling are kept SEPARATE below: .ecg-ehr__cell is only the card, and the
   track or the wrapped grid supplies the sizing. That split is what lets the
   same cell serve both the animated strip and the reduced-motion fallback,
   which is a static wrapped grid rather than a frozen strip showing only the
   first seven logos. */
.ecg-ehr__cell{
  display:flex;align-items:center;justify-content:center;
  min-height:92px;padding:18px 20px;border-radius:16px;
  background:#fff;box-shadow:inset 0 0 0 1px var(--e-global-color-slate_200),var(--ec-amb-1);
  transition:transform .5s var(--ec-e),box-shadow .5s var(--ec-e)}
.ecg-ehr__cell:hover{
  transform:translateY(-3px);
  box-shadow:inset 0 0 0 1px var(--e-global-color-teal_500),var(--ec-amb-2)}
.ecg-ehr__cell span{
  font-family:Manrope,sans-serif;font-size:18px;font-weight:600;letter-spacing:-.4px;
  color:var(--e-global-color-secondary);text-align:center;line-height:1.25}
.ecg-ehr--dark .ecg-ehr__cell span{color:var(--e-global-color-secondary)}
.ecg-ehr__cell img{
  max-width:100%;max-height:52px;width:auto;height:auto;display:block;
  object-fit:contain;
  /* a hair of desaturation so eight competing brand palettes sit together
     without any one shouting; nowhere near enough to alter a mark */
  filter:saturate(.92);
  transition:filter .4s var(--ec-e)}
.ecg-ehr__cell:hover img{filter:saturate(1)}
/* Dark theme keeps a WHITE cell. Third-party marks are never inverted or
   recoloured — same rule the certification chips follow. */
.ecg-ehr--dark .ecg-ehr__cell{
  background:#fff;box-shadow:inset 0 0 0 1px rgba(255,255,255,.14)}
.ecg-ehr--dark .ecg-ehr__cell:hover{
  box-shadow:inset 0 0 0 1px rgba(67,184,185,.55)}
/* ------------------------------------------------------- moving strips (4)
   Two tracks, opposite directions, so the rows read as two separate lists
   rather than one long belt.

   PAUSE ON HOVER AND ON FOCUS is not decoration. The job of this section is to
   let a practice manager check whether their own system is listed, and you
   cannot scan a moving row. :focus-within covers keyboard users, for whom
   tabbing to a cell that then slides away is worse than useless.

   Seamlessness relies on translateX(-50%) with exactly two identical sets in
   the track — the second is aria-hidden so screen readers get 14 names, not
   28. Change the duplication and you must change the keyframe. */
.ecg-mstrip{
  width:100%;overflow:hidden;
  /* fade the ends instead of hard-clipping a card mid-edge */
  -webkit-mask-image:linear-gradient(90deg,transparent 0,#000 5%,#000 95%,transparent 100%);
          mask-image:linear-gradient(90deg,transparent 0,#000 5%,#000 95%,transparent 100%)}
.ecg-mstrip__track{
  display:flex;width:max-content;will-change:transform;
  animation:ecg-mstrip-l 50s linear infinite}
.ecg-mstrip--rev .ecg-mstrip__track{animation-name:ecg-mstrip-r;animation-duration:38s}
.ecg-mstrip:hover .ecg-mstrip__track,
.ecg-mstrip:focus-within .ecg-mstrip__track{animation-play-state:paused}
.ecg-mstrip__set{display:flex;flex-wrap:nowrap;gap:14px;padding-right:14px;
  margin:0;list-style:none}
.ecg-mstrip__set .ecg-ehr__cell{flex:0 0 176px}
@keyframes ecg-mstrip-l{from{transform:translateX(0)}   to{transform:translateX(-50%)}}
@keyframes ecg-mstrip-r{from{transform:translateX(-50%)}to{transform:translateX(0)}}
@media(max-width:600px){
  .ecg-mstrip__set{gap:10px;padding-right:10px}
  .ecg-mstrip__set .ecg-ehr__cell{flex-basis:150px;min-height:76px;padding:14px}
  .ecg-ehr__cell span{font-size:15.5px}
  .ecg-ehr__cell img{max-height:40px}
}
/* Reduced motion: a stopped strip would strand most of the list off-screen, so
   fall back to the wrapped centred grid and drop the duplicate set entirely. */
@media(prefers-reduced-motion:reduce){
  .ecg-mstrip{overflow:visible;-webkit-mask-image:none;mask-image:none}
  /* Both selectors, and the second is the point: `.ecg-mstrip--rev
     .ecg-mstrip__track` sets animation-name at (0,2,0), which outranks a bare
     `.ecg-mstrip__track{animation:none}` at (0,1,0) — so the payer strip kept
     animating for exactly the users who asked it not to. Matched specificity
     rather than reaching for !important. */
  .ecg-mstrip__track,
  .ecg-mstrip--rev .ecg-mstrip__track{
    animation:none;width:100%;flex-wrap:wrap;justify-content:center}
  .ecg-mstrip__set{flex-wrap:wrap;justify-content:center;width:100%;padding-right:0}
  .ecg-mstrip__set[aria-hidden="true"]{display:none}
}

/* ---------------------------------------------------------------- systems
   Wrapper for the two rows: vendor marks, then payers.

   The payer row is TEXT, not marks, and that is a legal distinction rather
   than an aesthetic one — see the PAYERS note in build_home.py. It is styled
   to look deliberately unlike the logo grid above it: no cards, no white
   tiles, nothing that reads as a wall of borrowed brands. A list of payers
   set in the site's own typeface says the true thing ("we bill these") without
   implying any of them endorses or contracts with Exact Core. */
.ecg-sys{width:100%}
.ecg-sys__lab{
  font-family:Inter,sans-serif;font-size:12.5px;font-weight:600;
  letter-spacing:.12em;text-transform:uppercase;
  /* .62 put this at 3.21:1 on the #F3F6FA band -- the only text on the site
     that failed WCAG AA once contrast was measured from rendered pixels
     rather than from the cascade. At 12.5px it needs 4.5:1; .80 gives 5.03:1
     and still reads as a muted label against the body copy. */
  color:var(--e-global-color-text);opacity:.8;
  text-align:center;margin:0 0 20px}
.ecg-sys__lab--2{margin-top:44px}
.ecg-sys--dark .ecg-sys__lab{color:#fff;opacity:.58}

/* No max-width and no wrapping here: this list now rides in a moving track,
   and constraining its width would make the two halves different sizes, which
   breaks the translateX(-50%) loop. The balanced-wrap treatment moves into the
   reduced-motion fallback at the bottom, which is the only place it applies. */
.ecg-payers{
  display:flex;gap:10px;list-style:none;margin:0;padding:0}
.ecg-payers li{
  font-family:Manrope,sans-serif;font-size:15px;font-weight:600;
  letter-spacing:-.15px;color:var(--e-global-color-secondary);
  padding:10px 18px;border-radius:999px;
  background:#fff;box-shadow:inset 0 0 0 1px var(--e-global-color-slate_200)}
.ecg-sys--dark .ecg-payers li{
  color:#fff;background:rgba(255,255,255,.06);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.16)}
@media(max-width:600px){
  .ecg-sys__lab{font-size:11.5px;margin-bottom:16px}
  .ecg-sys__lab--2{margin-top:34px}
  .ecg-payers{gap:8px}
  .ecg-payers li{font-size:13.5px;padding:8px 14px}
}
/* Reduced-motion payer row: the strip stops, so the list needs to wrap — and
   at full width ten names wrap 9 + 1, leaving the last chip alone looking like
   an oversight. Measured across 680-1120px, anything from 760 to 920 gives a
   balanced 6 + 4. */
@media(prefers-reduced-motion:reduce){
  .ecg-mstrip--rev .ecg-payers{max-width:860px;margin:0 auto}
}

/* /specialties/ index grid */
.ecg-spec{
  display:grid;gap:1px;width:100%;
  grid-template-columns:repeat(3,1fr);
  background:var(--e-global-color-slate_200);
  border:1px solid var(--e-global-color-slate_200);
  border-radius:20px;overflow:hidden}
.ecg-spec__cell{
  display:flex;flex-direction:column;gap:6px;
  background:#fff;padding:26px 26px 28px;text-decoration:none;
  transition:background-color .4s var(--ec-e)}
.ecg-spec__cell:hover{background:var(--e-global-color-slate_50)}
.ecg-spec__cell strong{
  font-family:Manrope,sans-serif;font-size:18px;font-weight:600;letter-spacing:-.3px;
  color:var(--e-global-color-secondary)}
.ecg-spec__cell em{
  font-style:normal;font-family:Inter,sans-serif;font-size:14.5px;line-height:1.6;
  color:var(--e-global-color-text)}
@media(max-width:1024px){.ecg-spec{grid-template-columns:repeat(2,1fr)}}
@media(max-width:600px){
  .ecg-spec{grid-template-columns:1fr}
  .ecg-spec__cell{padding:22px 20px 24px}
}

/* promo cell */
.ecg-mm__promo{
  flex:0 0 290px;background:var(--e-global-color-secondary);
  border-radius:16px;padding:26px 24px;display:flex;flex-direction:column}
.ecg-mm__promo .ecg-mm__eyebrow{color:var(--e-global-color-teal_200)}
.ecg-mm__promoh{
  font-family:Manrope,sans-serif;font-size:20px;font-weight:600;line-height:1.22;
  letter-spacing:-.4px;color:#fff;margin:0 0 10px}
.ecg-mm__promod{font-size:13.5px;line-height:1.6;color:var(--e-global-color-slate_300);margin:0 0 20px}
.ecg-mm__promocta{
  display:inline-flex;align-items:center;gap:8px;align-self:flex-start;
  background:#fff;color:var(--e-global-color-secondary);
  font-size:14px;font-weight:600;text-decoration:none;
  padding:11px 18px;border-radius:999px;
  transition:transform .35s var(--ec-e),background-color .35s var(--ec-e)}
.ecg-mm__promocta:hover{transform:translateY(-2px);background:var(--e-global-color-teal_200)}
.ecg-mm__promoalt{
  margin-top:14px;font-size:13px;color:var(--e-global-color-slate_300);
  text-decoration:none;align-self:flex-start}
.ecg-mm__promoalt:hover{color:#fff}

/* WCAG — Elementor's kit emits `:root a{color:accent}` at
   specificity (0,1,1), which outranks every single-class rule above. Every
   menu link was therefore rendering in accent teal regardless of what it was
   set to: "View all solutions" came out at 2.09:1 on the navy promo card,
   a clear 1.4.3 failure. Forced, with the ratio each pairing now gives. */
.ecg-mm__promoalt{color:var(--e-global-color-slate_300)!important}   /* 7.4:1 on navy_800 */
.ecg-mm__promoalt:hover{color:#fff!important}                        /* 12.9:1 */
.ecg-mm__promocta{color:var(--e-global-color-secondary)!important}   /* 13.2:1 on white */
.ecg-mm__item strong{color:var(--e-global-color-secondary)!important}
.ecg-mm__item em{color:var(--e-global-color-text)!important}
/* :not(.ecg-mm__bar--dark *) so this light !important does not follow the
   drawer into the dark header, where it rendered navy-on-near-black at 1.38:1 */
.ecg-mm__top:not(.ecg-mm--dark *):not(.ecg-mm__bar--dark *){
  color:var(--e-global-color-secondary)!important}

/* .ecg-mm__trigger is a <button>, so it inherited the kit's button background —
   a navy pill sat behind "Solutions" in both themes. It was never designed;
   the base rule says background:none. Forced transparent, both themes. */
/* The kit supplied BOTH the navy background and the white text. Removing only
   the background left white-on-white at 1:1, so the colour must be set too.
   Dark overrides this with higher specificity + !important further down. */
.ecg-mm__trigger{
  background:transparent!important;
  /* the kit's <button> styling also supplies a border and a shadow; removing
     only the background left a navy outlined pill around Solutions/Specialties */
  border:0!important;box-shadow:none!important;
  color:var(--e-global-color-text)!important}      /* 8.9:1 on white */
.ecg-mm__trigger:hover,
.ecg-mm__trigger[aria-expanded="true"]{color:var(--e-global-color-primary)!important}
.ecg-mm__trigger:hover,
.ecg-mm__trigger[aria-expanded="true"]{
  background:var(--e-global-color-slate_50)!important}
.ecg-mm--dark .ecg-mm__trigger:hover,
.ecg-mm--dark .ecg-mm__trigger[aria-expanded="true"],
.ecg-mm__bar--dark .ecg-mm__trigger:hover,
.ecg-mm__bar--dark .ecg-mm__trigger[aria-expanded="true"]{
  background:rgba(255,255,255,.08)!important;color:#fff!important}

/* drawer close button */
.ecg-mm__close{
  display:none;position:absolute;top:20px;right:20px;
  width:42px;height:42px;border:0;border-radius:12px;cursor:pointer;
  background:var(--e-global-color-slate_50);color:var(--e-global-color-primary);
  align-items:center;justify-content:center;
  transition:background-color .35s var(--ec-e)}
.ecg-mm__close:hover{background:var(--e-global-color-slate_100)}
.ecg-mm__close svg{width:19px;height:19px}
@media(max-width:1024px){.ecg-mm__close{display:flex}}

/* burger */
.ecg-mm__burger{
  display:none;width:44px;height:44px;border:0;background:var(--e-global-color-slate_50);
  border-radius:12px;cursor:pointer;position:relative}
.ecg-mm__burger span{
  position:absolute;left:13px;width:18px;height:1.8px;border-radius:2px;
  background:var(--e-global-color-primary);
  transition:transform .4s var(--ec-e),opacity .3s var(--ec-e)}
.ecg-mm__burger span:nth-child(1){top:18px}
.ecg-mm__burger span:nth-child(2){top:24px}
.ecg-mm__burger[aria-expanded="true"] span:nth-child(1){transform:translateY(3px) rotate(45deg)}
.ecg-mm__burger[aria-expanded="true"] span:nth-child(2){transform:translateY(-3px) rotate(-45deg)}

/* The theme resets bare <button> elements, and something in that stack was
   winning the background: the bars rendered navy on a navy fill, so the mobile
   menu button was invisible. Pinned explicitly. flex:none because the button
   is a flex item and was being shrunk from 44px to 34px, below the 44px
   minimum touch target. NOT scoped under .ecg-mm — the drawer is portalled to
   <body> when open, so any rule the close button needs must stand alone. */
.ecg-mm__burger{
  flex:none!important;width:44px!important;height:44px!important;
  padding:0!important;
  background:var(--e-global-color-slate_50)!important;
  border-radius:12px!important;
  box-shadow:inset 0 0 0 1px var(--e-global-color-slate_200)}
.ecg-mm__burger span{background:var(--e-global-color-primary)!important}
.ecg-mm__close{
  flex:none!important;padding:0!important;
  background:var(--e-global-color-slate_50)!important;
  color:var(--e-global-color-primary)!important;
  border:0!important;border-radius:12px!important}

/* ---- mobile / tablet drawer ---- */
/* ---------- full nav from 1080, not 1360 --------------------------------
   The burger used to take over below 1360 because the nav needs 756px at
   desktop sizing (708px of items + 8 six-pixel gaps) and, beside a 186px logo
   and the 192px CTA, that does not fit under 1360. A 1280 or 1366 laptop --
   most of them -- therefore got the phone menu.

   Measured budget at 1080: 1032px of container, minus the 186px mark, minus
   the 98px compact CTA, minus the column gaps, leaves ~728px for the nav.
   Closing the gaps to 2px and the item padding to 7px brings the nav to
   ~676px, which fits with ~50px to spare -- and does it WITHOUT shrinking the
   15px label text, so nothing gets harder to read.

   The compact "Free Audit" CTA already takes over below 1360; it has to,
   because the full label costs 94px this band does not have.

   This block has to sit AFTER the base .ecg-mm__bar/.ecg-mm__top rules --
   first time round it went near the top of the file and lost on source
   order at equal specificity, so nothing changed. */
@media(min-width:1080px) and (max-width:1359px){
  .ecg-mm__bar{gap:2px}
  .ecg-mm__top,.ecg-mm__trigger{padding-left:7px;padding-right:7px}
}

@media(max-width:1079px){
  .ecg-mm__burger{display:block}
  .ecg-mm__scrim{
    position:fixed;inset:0;background:rgba(0,45,107,.42);z-index:69;
    opacity:0;transition:opacity .4s var(--ec-e)}
  .ecg-mm__scrim.is-on{opacity:1}
  body.ecg-mm-locked{overflow:hidden}
  .ecg-mm__bar{
    position:fixed;inset:0 0 0 auto;width:min(88vw,380px);
    background:#fff;flex-direction:column;align-items:stretch;gap:2px;
    padding:96px 20px 32px;overflow-y:auto;z-index:70;
    transform:translateX(100%);transition:transform .42s var(--ec-e);
    box-shadow:-30px 0 70px -30px rgba(1,62,127,.4)}
  /* the bar is portalled to <body>, so it is no longer a descendant of .ecg-mm
     — the open state must live on the bar itself */
  .ecg-mm.is-drawer .ecg-mm__bar,
  .ecg-mm__bar.is-open{transform:translateX(0)}

  /* The drawer is portalled to <body> when it opens, which takes it OUT of
     .ecg-mm--dark — so the dark skin above stops matching and the bar keeps the
     light theme's background:#fff from the rule just above. The text colours
     already handle the portalled case (.ecg-mm__bar--dark, further down); the
     SURFACE was the one thing missed, which left the dark page's menu at
     #E8EAED on white: 1.21:1, invisible.
     #E8EAED on #131519 = 15.2:1 */
  .ecg-mm__bar--dark{background:#131519}
  .ecg-mm__bar--dark .ecg-mm__top{border-color:rgba(255,255,255,.12)}
  .ecg-mm__bar--dark .ecg-mm__txt strong{color:#E8EAED!important}
  .ecg-mm__bar--dark .ecg-mm__txt em{color:#9AA0A8!important}
  /* the kit's global a{color:#006B6C} shows through on any text in the item
     that is not wrapped in <strong>/<em> — 2.89:1 on this surface */
  .ecg-mm__bar--dark .ecg-mm__item,
  .ecg-mm__bar--dark a{color:#E8EAED}
  .ecg-mm__bar--dark .ecg-mm__eyebrow{color:#43B8B9}
  .ecg-mm__bar--dark .ecg-mm__ico{background:rgba(67,184,185,.14);color:#43B8B9}
  .ecg-mm__bar--dark .ecg-mm__close{
    background:rgba(255,255,255,.08);color:#E8EAED}
  .ecg-mm__bar--dark .ecg-mm__close:hover{background:rgba(255,255,255,.18)}
  .ecg-mm__top,.ecg-mm__trigger{
    width:100%;justify-content:space-between;padding:15px 12px;font-size:17px}
  .ecg-mm__panel{
    position:static;padding:0;opacity:1;transform:none;pointer-events:auto;
    transition:none}
  .ecg-mm__panel[hidden]{display:none}
  .ecg-mm__inner{
    flex-direction:column;gap:18px;box-shadow:none;border:0;padding:4px 0 10px;
    margin:0;border-radius:0}
  .ecg-mm__grid{grid-template-columns:1fr;gap:2px}
  .ecg-mm__promo{flex:1 1 auto}
  /* The drawer parks off-canvas at translateX(100%). That extends the
     scrollable area, so a phone can scroll 343px sideways into empty space —
     measured on the live site at 390px wide, where scrollWidth is 733.
     It has to be the ROOT, not <body>: the drawer is position:fixed, so it is
     laid out against the viewport and <body>'s own clip never contains it.
     `clip`, not `hidden`: hidden would force the other axis to `auto` and make
     the root a scroll container, breaking the sticky header. `clip` is
     compatible with `overflow-y:visible`, so vertical scrolling is untouched. */
  html{overflow-x:hidden}
}
@media(min-width:1080px){
  .ecg-mm__panel[hidden]{display:block}   /* animate rather than snap */
}

/* ---------- discipline rows, rendered by [nexen_solutions] ---------------
   The Solutions page used to build these out of Elementor containers. Now the
   plugin renders them so the client can edit the copy, which means the layout
   that used to be container settings has to exist as CSS. Same two-column
   rhythm, same divider, same numeral. */
.ecg-svcrows{display:block}
.ecg-svcrow{
  display:flex;flex-wrap:wrap;gap:48px;
  align-items:flex-start;justify-content:space-between;
  padding:46px 0 50px;
  border-bottom:1px solid var(--e-global-color-slate_200)}
.ecg-svcrow:last-child{border-bottom:0}
.ecg-svcrow__l{flex:0 1 40%;min-width:0}
.ecg-svcrow__r{flex:0 1 52%;min-width:0}
.ecg-svcrow .ecg-idx{
  display:block;font-family:Inter,sans-serif;font-size:13px;font-weight:650;
  letter-spacing:1.2px;color:var(--e-global-color-accent)}
.ecg-svcrow h2{
  font-family:Manrope,sans-serif;font-size:32px;font-weight:650;
  letter-spacing:-.8px;line-height:1.15;margin:12px 0 0;
  color:var(--e-global-color-secondary)}
.ecg-svcrow > .ecg-svcrow__l > p{
  font-size:18px;line-height:1.6;margin:14px 0 0;
  color:var(--e-global-color-text)}
.ecg-svcrow .ecg-rellinks{margin-top:20px}
@media(max-width:1024px){
  .ecg-svcrow{gap:20px}
  .ecg-svcrow__l,.ecg-svcrow__r{flex:0 1 100%}
  .ecg-svcrow h2{font-size:25px}
}

/* ---------- long-form article body + data tables ------------------------
   New with the SEO content pack: ten specialty pages and /about/ now carry
   700-word articles with "Service / Common code / Typical billing issue"
   tables, which no previous template had.

   The table scrolls inside its own wrapper rather than widening the page --
   three columns of code descriptions cannot fit a 390px phone, and letting it
   push the layout would reintroduce the horizontal-scroll bug the marquee
   already cost us once. */
.ecg-article .ecg-con > *:first-child{margin-top:0}
.ecg-tblwrap{
  width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;
  border-radius:14px;box-shadow:inset 0 0 0 1px var(--e-global-color-slate_200)}
.ecg-tbl{
  width:100%;border-collapse:collapse;font-family:Inter,sans-serif;
  font-size:15.5px;line-height:1.55;min-width:520px}
.ecg-tbl thead th{
  text-align:left;font-weight:650;font-size:13px;letter-spacing:.04em;
  text-transform:uppercase;color:var(--e-global-color-secondary);
  background:var(--e-global-color-slate_50);
  padding:14px 18px;border-bottom:1px solid var(--e-global-color-slate_200)}
.ecg-tbl tbody th{
  text-align:left;font-weight:600;color:var(--e-global-color-secondary);
  padding:14px 18px;vertical-align:top;width:34%}
.ecg-tbl tbody td{
  padding:14px 18px;vertical-align:top;color:var(--e-global-color-text)}
.ecg-tbl tbody tr + tr th,
.ecg-tbl tbody tr + tr td{border-top:1px solid var(--e-global-color-slate_200)}
.ecg-tbl tbody tr:nth-child(odd) th,
.ecg-tbl tbody tr:nth-child(odd) td{background:rgba(243,246,250,.5)}
@media(max-width:600px){
  .ecg-tbl{font-size:14.5px;min-width:460px}
  .ecg-tbl thead th,.ecg-tbl tbody th,.ecg-tbl tbody td{padding:11px 13px}
}

/* ---------- [nexen_faqs] and [nexen_testimonials] -----------------------
   These sections used to be Elementor accordion and container widgets, styled
   by widget settings. Rendered from the plugin they are plain markup, so the
   layout has to live here. Flagged by check_classes.py before they shipped
   unstyled — which is exactly the bug that check exists for. */
.ecg-faqs{width:100%}
.ecg-faq__nav{margin-bottom:40px}
.ecg-faq__group{margin:0 0 46px}
.ecg-faq__group > h2{
  font-family:Manrope,sans-serif;font-size:26px;font-weight:600;
  letter-spacing:-.6px;margin:0 0 14px;
  color:var(--e-global-color-secondary)}
.ecg-faq__item{
  border-bottom:1px solid var(--e-global-color-slate_200);
  padding:0}
.ecg-faq__item > summary{
  list-style:none;cursor:pointer;position:relative;
  padding:22px 40px 22px 0;
  font-family:Manrope,sans-serif;font-size:18px;font-weight:600;
  color:var(--e-global-color-secondary);
  transition:color .3s var(--ec-e)}
.ecg-faq__item > summary::-webkit-details-marker{display:none}
/* chevron drawn in CSS: a details/summary marker cannot be positioned reliably
   across browsers, and this rotates on open without any JS */
.ecg-faq__item > summary::after{
  content:"";position:absolute;right:6px;top:50%;
  width:9px;height:9px;margin-top:-6px;
  border-right:2px solid var(--e-global-color-accent);
  border-bottom:2px solid var(--e-global-color-accent);
  transform:rotate(45deg);
  transition:transform .35s var(--ec-e)}
.ecg-faq__item[open] > summary{color:var(--e-global-color-accent)}
.ecg-faq__item[open] > summary::after{transform:rotate(-135deg);margin-top:-2px}
.ecg-faq__item > summary:focus-visible{
  outline:2px solid var(--e-global-color-teal_600);outline-offset:3px}
.ecg-faq__a{padding:0 40px 22px 0}
.ecg-faq__a p{
  font-size:16px;line-height:1.72;margin:0 0 12px;
  color:var(--e-global-color-text)}
.ecg-faq__a p:last-child{margin-bottom:0}

.ecg-reviews{
  display:grid;gap:20px;
  grid-template-columns:repeat(auto-fit,minmax(280px,1fr))}
.ecg-review__stars{
  display:block;margin-bottom:12px;
  color:var(--e-global-color-accent);font-size:15px;letter-spacing:2px}
@media(max-width:600px){.ecg-reviews{grid-template-columns:1fr}}

/* The footer phone. Without this it broke as "+1 307-449- / 2680" on a narrow
   column — a phone number split across two lines is not a phone number. */
.ecg-nowrap{white-space:nowrap}

/* ---------- footer contact: forced blocks -------------------------------
   Elementor strips <p> wrappers placed AROUND a shortcode, so the phone, email
   and address shortcodes land as one inline run — which wrapped mid-number as
   "+1 307-449- / 2680admin@..." on mobile. Forcing the three to block level
   here restores the intended stack without needing a plugin update. */
#site-footer #e-ftcontactl a,
#site-footer #e-ftcontactl .ecg-addr{
  display:block}
#site-footer #e-ftcontactl a[href^="tel:"]{
  white-space:nowrap;margin-bottom:2px}
#site-footer #e-ftcontactl .ecg-addr{margin-top:12px}

/* ---------- footer solutions: neutralise the pill ------------------------
   [nexen_solutions style="links"] emits .ecg-rellinks, which is a white pill
   built for LIGHT backgrounds. On the navy footer it rendered as eight white
   lozenges with near-invisible text. Same markup, restyled for this context
   into the plain list the footer had before. */
#site-footer .ecg-rellinks{display:block;gap:0;margin-top:0}
#site-footer .ecg-rellinks a{
  display:block;padding:0;margin:0 0 11px;
  background:none;box-shadow:none;border-radius:0;
  font-size:15px;font-weight:400;
  color:var(--e-global-color-slate_300);
  transform:none}
#site-footer .ecg-rellinks a::after{content:none}
#site-footer .ecg-rellinks a:hover{
  color:#fff;background:none;box-shadow:none;transform:none}

/* ---------- testimonials rendered by [nexen_testimonials] ----------------
   The deployed plugin emits .ecg-reviews with <blockquote> and <figcaption>.
   Untouched, the blockquote picked up the browser's default 40px side margins
   (text wrapping every three words) and the figcaption had no styling, so name
   and role ran together as "Dr. Michael ReynoldsMedical Director". Three fixed
   columns to match the rest of the site, not auto-fit — auto-fit gave four
   cramped columns on a wide screen. */
.ecg-reviews{
  display:grid;gap:1px;width:100%;
  grid-template-columns:repeat(3,1fr);
  background:var(--e-global-color-slate_200);
  border:1px solid var(--e-global-color-slate_200);
  border-radius:20px;overflow:hidden}
.ecg-reviews .ecg-review__cell{
  display:flex;flex-direction:column;
  background:#fff;padding:32px 30px 34px;margin:0;
  transition:background-color .45s var(--ec-e)}
.ecg-reviews .ecg-review__cell:hover{background:var(--e-global-color-slate_50)}
.ecg-reviews blockquote{
  margin:12px 0 0;padding:0;border:0;          /* kill the UA 40px side margin */
  font-family:Manrope,sans-serif;font-size:17px;font-weight:500;
  line-height:1.55;letter-spacing:-.2px;
  color:var(--e-global-color-secondary)}
.ecg-reviews blockquote p{margin:0}
.ecg-reviews figcaption{
  margin-top:auto;padding-top:18px;
  font-family:Inter,sans-serif;font-size:14px;line-height:1.5}
.ecg-reviews figcaption strong{
  display:block;font-weight:600;
  color:var(--e-global-color-secondary)}
.ecg-reviews figcaption span{
  display:block;margin-top:2px;
  color:var(--e-global-color-text)}
.ecg-review__stars{
  display:block;font-size:12px;letter-spacing:2px;
  color:var(--e-global-color-accent)}
@media(max-width:1024px){.ecg-reviews{grid-template-columns:repeat(2,1fr)}}
@media(max-width:600px){
  .ecg-reviews{grid-template-columns:1fr}
  .ecg-reviews .ecg-review__cell{padding:26px 22px 28px}
}

/* ---------- method steps rendered by [nexen_solution_method] -------------
   The builder produced these as Elementor containers at width 23% with a
   heading widget for the numeral, so the existing rules target
   `.ecg-bignum .ecg-h`. Rendered from the plugin they are
   plain HTML, which needs both the row (.ecg-steps, replacing the container
   widths) and a numeral rule that does not depend on Elementor's markup. */
.ecg-steps{
  display:flex;flex-wrap:wrap;align-items:flex-start;
  gap:34px 20px;width:100%}
.ecg-steps .ecg-step{
  flex:0 1 23%;min-width:0;padding:0 14px 0 0}
.ecg-steps .ecg-bignum{
  font-family:Manrope,sans-serif;font-size:76px;font-weight:700;
  letter-spacing:-2.6px;line-height:.9;
  -webkit-text-stroke:1.5px rgba(1,62,127,.30);
  color:transparent;font-variant-numeric:tabular-nums;
  transition:-webkit-text-stroke-color .6s var(--ec-e)}
.ecg-steps .ecg-step:hover .ecg-bignum{
  -webkit-text-stroke-color:var(--e-global-color-teal_500)}
.ecg-steps .ecg-step h3{
  margin:40px 0 0;font-family:Manrope,sans-serif;font-size:19px;font-weight:600;
  letter-spacing:-.4px;color:var(--e-global-color-secondary)}
.ecg-steps .ecg-step p{
  margin:8px 0 0;font-family:Inter,sans-serif;font-size:15px;line-height:1.72;
  color:var(--e-global-color-text)}
@media(max-width:1024px){
  .ecg-steps .ecg-step{flex:0 1 47%}
  .ecg-steps .ecg-bignum{font-size:66px}
}
@media(max-width:767px){
  .ecg-steps .ecg-step{flex:0 1 100%;padding:0 0 0 26px}
  .ecg-steps .ecg-bignum{font-size:56px}
}

/* ---------- scheduler embed (Calendly / Cal.com), [nexen_booking] --------
   The widget brings its own chrome, so this is only the frame around it: a
   card that matches the rest of the page rather than a raw iframe edge. */
.ecg-booking{
  width:100%;background:#fff;border-radius:20px;overflow:hidden;
  box-shadow:inset 0 0 0 1px var(--e-global-color-slate_200),var(--ec-amb-1)}
.ecg-booking__h{
  font-family:Manrope,sans-serif;font-size:26px;font-weight:600;
  letter-spacing:-.6px;margin:0;padding:28px 30px 0;
  color:var(--e-global-color-secondary)}
.ecg-booking iframe{display:block}

/* ---------- deferred-scheduler facade -----------------------------------
   The Calendly widget no longer loads with the page (it carried 8.8 MB of its
   own plus 1.2 MB of Stripe, and fired Stripe's fingerprinting frame before
   the cookie banner was answered). This is what stands in its place until the
   visitor asks for it, sized so the card does not jump when the real widget
   replaces it. */
.ecg-booking__facade{
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:14px;min-height:280px;padding:40px 30px;text-align:center}
.ecg-booking__facade .ecg-btn{cursor:pointer;border:0;font:inherit}
.ecg-booking__load:disabled{opacity:.6;cursor:progress}
.ecg-booking__note{
  font-family:Inter,sans-serif;font-size:13.5px;margin:0;
  color:var(--e-global-color-text);opacity:.8}
@media(max-width:600px){
  .ecg-booking__facade{min-height:220px;padding:32px 20px}
}
@media(max-width:600px){
  /* Calendly's embed carries min-width:320px. With the section's 20px side
     padding a 360px phone leaves ~320px, so the widget hit its floor, overflowed
     and was CLIPPED by the overflow:hidden that rounds the corners — the event
     title, "Select a Day" and the weekend columns were all cut off.
     Fix: let the card go full-bleed on mobile and drop the floor so the widget
     can use every pixel. Square corners edge-to-edge read as deliberate; a
     rounded card with its right-hand side sliced off does not. */
  .ecg-booking{
    border-radius:0;
    margin-left:calc(-1 * var(--ecg-gutter, 20px));
    margin-right:calc(-1 * var(--ecg-gutter, 20px));
    width:calc(100% + (2 * var(--ecg-gutter, 20px)));
    box-shadow:none;
    border-top:1px solid var(--e-global-color-slate_200);
    border-bottom:1px solid var(--e-global-color-slate_200)}
  .ecg-booking .calendly-inline-widget,
  .ecg-booking iframe{
    min-width:0!important;width:100%!important;
    /* Calendly stacks the event details ABOVE the calendar on narrow screens,
       so 720px left it scrolling inside its own frame */
    height:1040px!important}
  .ecg-booking__h{font-size:21px;padding:22px 20px 0}
}

/* The booking section must vanish ENTIRELY when no scheduler URL is set —
   the shortcode renders nothing, but the heading above it is built by the
   page, so without this you get "Prefer to just pick a slot?" followed by
   empty space. :has() lets the section test its own contents. */
#book-a-call:not(:has(.ecg-booking)){display:none}

/* ---------- contact CTA pair: equal width -------------------------------
   The two buttons sized to their own text, so "Book a call" came out less
   than half the width of the assessment button stacked above it. A grid whose
   single column is max-content takes the width of the WIDER button and
   stretches both to it, so they stay matched whatever the labels become. */
#e-ctlb{
  display:grid!important;grid-template-columns:max-content;
  gap:10px;justify-items:stretch}
#e-ctlb .ecg-btn{
  width:100%;justify-content:center}

/* The button must not survive its destination: when no scheduler URL is set
   the #book-a-call section is hidden, so a button pointing at it would scroll
   nowhere. Same :has() test, asked from a common ancestor. */
body:not(:has(.ecg-booking)) #contact-book{display:none}
