/* =========================================================
   Advocate Travel Marketing — native.css

   Supports pages built from native Elementor widgets, so content
   and images are editable from the sidebar.

   The approach matters here. Elementor drives Container layout
   entirely through CSS variables:

       .e-con { display: var(--display);
                padding-block-start: var(--padding-block-start, ...);
                max-width: var(--width, var(--container-max-width)); }

   So rather than overriding those PROPERTIES (which also overrode
   the design system and flattened .hero, .hero__actions and the
   rest), this file only neutralises the VARIABLES. Elementor then
   computes to block / zero padding / full width, and style.css —
   which loads after Elementor's frontend CSS — wins normally at
   its own specificity. Every component keeps working without
   being re-declared here.
   ========================================================= */

/* ---------- 1. Neutralise Elementor's container variables ---------- */
.elementor .e-con.atm-el,
.elementor .e-con.atm-el > .e-con-inner {
  --display: block;
  --flex-direction: row;
  --gap: 0px;
  --row-gap: 0px;
  --column-gap: 0px;
  --padding-block-start: 0px;
  --padding-block-end: 0px;
  --padding-inline-start: 0px;
  --padding-inline-end: 0px;
  --padding-top: 0px;
  --padding-right: 0px;
  --padding-bottom: 0px;
  --padding-left: 0px;
  --margin-block-start: 0px;
  --margin-block-end: 0px;
  --margin-inline-start: 0px;
  --margin-inline-end: 0px;
  --margin-top: 0px;
  --margin-right: 0px;
  --margin-bottom: 0px;
  --margin-left: 0px;
  --width: 100%;
  --content-width: 100%;
  --container-max-width: 100%;
  --container-default-padding-block-start: 0px;
  --container-default-padding-block-end: 0px;
  --container-default-padding-inline-start: 0px;
  --container-default-padding-inline-end: 0px;
}

/* Elementor spaces widgets with a default bottom margin; the design system's
   own margins handle rhythm instead. ONLY that default is neutralised —
   margins set in a widget's Advanced tab (specificity 0,2,0) must remain
   effective, so no blanket margin:0 here. */
.elementor .e-con.atm-el > .elementor-widget,
.elementor .e-con.atm-el > .e-con-inner > .elementor-widget {
  margin-block-end: 0;
  max-width: none;
}
.elementor .e-con.atm-el .elementor-widget-container {
  margin: 0;
  padding: 0;
}

/* The hero's video sits in an HTML widget whose wrapper is a zero-height flow
   element, leaving .hero__media (position:absolute; inset:0) nothing to fill.
   The wrapper becomes the box instead. */
.elementor .e-con.atm-el.hero > .elementor-widget-html,
.elementor .e-con.atm-el.hero > .elementor-widget-html > .elementor-widget-container {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}
.elementor .e-con.atm-el.hero { position: relative; }

/* ---------- 2. Images ----------
   An Image widget nests <img> two levels deeper than the prototype did, so
   height:100% no longer resolves against the cropping box. */
.hero__media .elementor-widget-image,
.page-hero__media .elementor-widget-image,
.cta__media .elementor-widget-image,
.member__photo .elementor-widget-image,
.cap__icon .elementor-widget-image,
.svc__icon .elementor-widget-image,
.hero__media .elementor-widget-image .elementor-widget-container,
.page-hero__media .elementor-widget-image .elementor-widget-container,
.cta__media .elementor-widget-image .elementor-widget-container,
.member__photo .elementor-widget-image .elementor-widget-container,
.cap__icon .elementor-widget-image .elementor-widget-container,
.svc__icon .elementor-widget-image .elementor-widget-container {
  height: 100%;
}

/* :first-child no longer matches the <img>, which now sits inside a widget */
.svc__media > .elementor-widget-image:first-child { grid-column: 1 / -1; }
.svc__media > .elementor-widget-image:first-child img { aspect-ratio: 16/9; }
.svc__media > .elementor-widget-image:not(:first-child) img { aspect-ratio: 4/3; }

/* A collage set to "Show full images" drops every fixed box, on native
   Image widgets as well as on the collage widget's own markup. */
/* Native Image widgets carry no ratio data, so they stack full width. */
.svc__media--natural > .elementor-widget-image { flex: 0 0 100%; grid-column: 1 / -1; }
.svc__media--natural > .elementor-widget-image img,
.svc__media--natural > .elementor-widget-image:first-child img,
.svc__media--natural > .elementor-widget-image:not(:first-child) img {
  aspect-ratio: auto;
  width: 100%;
  height: auto;
  object-fit: contain;
}

/* style.css targets `.logo-wall div`, which now also matches Elementor's own
   wrapper divs. Cell styling is re-aimed at the Container; wrappers are
   neutralised. */
.elementor .e-con.atm-el.logo-wall > .e-con {
  background: none;
  display: flex;
  align-items: center;
  justify-content: flex-start;
  padding: 0;
  min-height: 0;
}
.logo-wall .elementor-widget,
.logo-wall .elementor-widget > .elementor-widget-container {
  background: none;
  padding: 0;
  min-height: 0;
  display: block;
}

/* ---------- 3. Button widgets ----------
   Visual button styling lives in the WIDGET SETTINGS (colors, typography,
   radius, padding), so the editor previews correctly and any sidebar edit
   overrides it naturally. Only what settings cannot express stays here, at
   :where() zero specificity so it never blocks an edit. */
:where(.atm-btn) .elementor-button {
  white-space: nowrap;
  transition: background .45s var(--ease), color .45s var(--ease),
              border-color .45s var(--ease), transform .25s var(--ease);
}
:where(.atm-btn) .elementor-button:hover { transform: translateY(-2px); }
:where(.atm-txt-link) .elementor-button {
  border-bottom: 1px solid transparent;
  transition: border-color .3s var(--ease);
}
:where(.atm-txt-link) .elementor-button:hover { border-bottom-color: #E8336A; }

/* The arrow is drawn here, not typed into the label, so editing the text
   cannot break or duplicate it. */
.atm-btn--arrow .elementor-button-text::after,
.atm-txt-link .elementor-button-text::after {
  content: "\2192";
  display: inline-block;
  margin-left: .7rem;
  transition: transform .3s var(--ease);
}
.atm-btn--arrow .elementor-button:hover .elementor-button-text::after,
.atm-txt-link .elementor-button:hover .elementor-button-text::after { transform: translateX(4px); }

/* Elementor stretches widgets to the container width, which pushed the two
   hero buttons onto separate lines inside .hero__actions (display:flex with
   wrap). Button widgets size to their content instead. */
body .elementor .e-con.atm-el > .elementor-widget-button,
body .elementor .e-con.atm-el > .e-con-inner > .elementor-widget-button {
  --container-widget-width: auto;
  --container-widget-flex-grow: 0;
  --width: auto;
  width: auto;
  max-width: 100%;
  flex: 0 0 auto;
}
.elementor .e-con.atm-el .elementor-button-wrapper { display: inline-block; }

/* ---------- 4. Heading widgets ----------
   Elementor owns the <h*> element, so a design-system class such as
   .hero__title can only be placed on the widget wrapper. Left alone, the
   inner <h1> keeps style.css's element rules (navy, --t-h1) and ignores the
   wrapper entirely — which is how "Your Voice in America" ended up dark navy
   on a dark hero.

   So: the inner heading inherits everything from the wrapper, and the wrapper
   carries the tag defaults via .atm-hd / .atm-hN. Those defaults are wrapped
   in :where() so they contribute ZERO specificity — any component class on
   the same wrapper (.hero__title, .sec-head h2) overrides them exactly as it
   overrode the element rules in the prototype. */
body .elementor .atm-hd .elementor-heading-title {
  font: inherit;
  color: inherit;
  letter-spacing: inherit;
  line-height: inherit;
  text-shadow: inherit;
  text-align: inherit;
  margin: 0;
  max-width: none;
}
:where(.atm-hd) {
  display: block;
  font-family: var(--f-display);
  font-weight: 700;
  line-height: 1.07;
  letter-spacing: -.015em;
  color: var(--navy);
  margin: 0 0 .5em;
}
:where(.atm-h1) { font-size: var(--t-h1); }
:where(.atm-h2) { font-size: var(--t-h2); }
:where(.atm-h3), :where(.atm-h4) { font-size: var(--t-h3); line-height: 1.2; }

/* Contexts that style.css expresses as `.x h2`, re-aimed at the wrapper */
.elementor .section--navy .atm-hd,
.elementor .page-hero .atm-hd,
.elementor .cta .atm-hd,
.elementor .member .atm-hd,
.elementor .cap .atm-hd,
.elementor .contact-card .atm-hd { color: #fff; }
.elementor .page-hero .atm-h1 { max-width: 16ch; text-shadow: 0 2px 24px rgba(7,13,24,.5); }
.elementor .cta .atm-h2 { text-shadow: 0 2px 22px rgba(7,13,24,.55); }
.elementor .member .atm-h3 { font-size: 1.2rem; margin-bottom: .15rem; }
.elementor .cap .atm-h3 { font-size: 1.3rem; margin-bottom: .6rem; }
.elementor .svc .atm-h2 { margin-bottom: .1em; }

body .elementor p, body .elementor li { font-family: var(--f-body); }

/* ---------- 5. Elementor editor visibility ----------
   Scroll reveals start at opacity:0 and are switched on by an
   IntersectionObserver in main.js. The editor re-renders elements after that
   observer runs, so re-rendered nodes never receive .is-in and the canvas
   goes blank. Inside the editor they are simply shown; the front-end
   animation is untouched. */
body.elementor-editor-active .reveal,
body.elementor-editor-active .reveal.is-in {
  opacity: 1;
  transform: none;
  transition: none;
}
body.elementor-editor-active .elementor .e-con.atm-el.page-hero__media,
body.elementor-editor-active .elementor .e-con.atm-el.hero__media,
body.elementor-editor-active .elementor .e-con.atm-el.cta__media { min-height: 40px; }

/* ---------- 8. Flex-row child sizing ----------
   These are mappings, not layout re-assertions (the generated
   native-assert.css handles those). Widgets are block-level at 100% width by
   default, which breaks rows built with justify-content. */
body .elementor .e-con.atm-el.carousel__foot > .elementor-widget,
body .elementor .e-con.atm-el.carousel__foot .elementor-widget {
  width: auto;
  max-width: 100%;
}
/* The dots + counter group was `<div style="display:flex; align-items:center;
   gap:1.25rem">` in the prototype — an anonymous wrapper whose inline style
   the compiler cannot carry into a Container. Restored here; width:auto so
   the foot's space-between keeps the View More link on the right. */
body .elementor .e-con.atm-el.carousel__foot > .e-con {
  display: flex;
  align-items: center;
  gap: 1.25rem;
  width: auto;
  max-width: 100%;
}
body .elementor .e-con.atm-el.hero > .e-con.hero__inner { width: 100%; }

/* ---------- 9. ATM Client Grid widget ----------
   The widget outputs the same markup the design system already styles, so it
   needs no visual rules — only the "Show all" button's placement, which lived
   in the page markup before. */
body .elementor .clients-more .btn { cursor: pointer; }

/* ---------- 10. ATM Case Carousel widget ----------
   The widget renders the dots + counter inside a named group rather than the
   prototype's inline-styled anonymous div. Same row, now addressable. */
body .elementor .carousel__foot-group {
  display: flex;
  align-items: center;
  gap: 1.25rem;
}

/* Widget Style controls emit `.elementor-element-XXX .carousel__dots button`
   style rules. Defaults live at :where() zero specificity so ANY sidebar
   value wins — the design still renders correctly out of the box, and the
   client can override colour, size, alignment and typography freely. */
:where(.elementor .carousel__foot) {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-top: 1.4rem;
}
:where(.elementor .clients-more) {
  display: flex;
  justify-content: center;
  margin-top: clamp(1.5rem, 3vw, 2.5rem);
}

/* ---------- 11. Inline-style utilities ----------
   The prototype used inline styles on two wrappers; the compiler maps them to
   these classes since Containers cannot carry a style attribute. Zero
   specificity via :where(), so the editor's alignment controls still win. */
:where(.elementor .e-con.atm-el.atm-center) { text-align: center; }
:where(.elementor .e-con.atm-el.atm-mt-2_5) { margin-top: 2.5rem; }
:where(.elementor .e-con.atm-el.atm-mt-2_75) { margin-top: 2.75rem; }

/* A width-auto Button widget must stay full-width in block flow so the
   wrapper (inline-block) can be centered by text-align on its container. */
.elementor .e-con.atm-el.atm-center > .elementor-widget-button { width: 100%; }

/* ---------- 12. Partner logo ----------
   style.css sizes `.partner__logo` as an <img> rule (height 54px). As an
   Image widget, that class lands on the wrapper, so the logo rendered at
   natural size and flooded the block. The size is re-aimed at the real <img>
   at 0,1,1 — above base img rules, below the widget's own Width control
   ({{WRAPPER}} img, 0,2,1) — so the sidebar can still resize it. */
.partner__logo img {
  height: 54px;
  width: auto;
}
body .elementor .e-con.atm-el > .elementor-widget-image.partner__logo {
  margin-block-end: 1.5rem;
}

/* ---------- 13. Image containment in media boxes ----------
   Elementor's Style > Height control sets a height on the <img> itself. In a
   fixed-ratio media box an oversized value used to spill past the card edge.

   Clipping is done with overflow alone. An earlier attempt added
   `max-height: 100%` to the image, which collapsed it to zero height in the
   case-study cards: their media box has no definite height of its own, so a
   percentage max-height had nothing to resolve against. Overflow needs no
   such reference, so it clips oversized images without ever hiding them. */
.elementor .e-con.atm-el.case__media,
.elementor .e-con.atm-el.member__photo,
.elementor .e-con.atm-el.partner__media,
.elementor .e-con.atm-el.hero__media,
.elementor .e-con.atm-el.page-hero__media,
.elementor .e-con.atm-el.cta__media,
.elementor .e-con.atm-el.svc__media,
.elementor .e-con.atm-el.case {
  overflow: hidden;
}

/* Width still can't exceed the box — that one has a definite reference. */
.elementor .e-con.atm-el .elementor-widget-image img {
  max-width: 100%;
}


/* ---------- 14. Case and partner media fills ----------
   Two different behaviours now:

   CASE STUDIES fill a fixed 4:3 frame (style.css). The Image widget's <img>
   sits two wrappers below the media box, so those wrappers are pinned to the
   box with position:absolute; inset:0 and the <img> covers them. The box has
   a definite height from its aspect-ratio, so height:100% on the wrappers
   resolves — this is not the indefinite-parent trap.

   PARTNER MEDIA shows the artwork at its own proportions. No frame, nothing to
   fill, so the wrappers flow normally. */
/* Same iOS Safari workaround as style.css: the frame's height comes from an
   in-flow ::after spacer with 75% padding, not from aspect-ratio, which
   WebKit resolves the wrong way round on a block-stretched item with only
   absolutely positioned children. Elementor uses ::before on .e-con for its
   background overlay; ::after is free. */
.elementor .e-con.atm-el.case__media {
  position: relative;
  width: 100%;
}
.elementor .e-con.atm-el.case__media::after {
  content: ""; display: block; width: 100%; padding-top: 75%;
}
.elementor .e-con.atm-el.case__media > .elementor-widget-image,
.elementor .e-con.atm-el.case__media .elementor-widget-image > .elementor-widget-container {
  position: absolute;
  inset: 0; top: 0; right: 0; bottom: 0; left: 0;
  width: 100%;
  height: 100%;
  /* Above the blurred backdrop drawn by .case__media::before (style.css). */
  z-index: 1;
}
.elementor .e-con.atm-el.case__media .elementor-widget-image img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: center;
}

.elementor .e-con.atm-el.partner__media > .elementor-widget-image,
.elementor .e-con.atm-el.partner__media .elementor-widget-image > .elementor-widget-container {
  position: static;
  inset: auto;
  width: 100%;
  height: auto;
}
.elementor .e-con.atm-el.partner__media .elementor-widget-image img {
  display: block;
  width: 100%;
  height: auto;
  object-fit: contain;
}

/* A Height typed in the Style tab still wins on the partner artwork; it is
   only clipped by the box's overflow, never overridden. */
.elementor .e-con.atm-el.partner__media .elementor-widget-image img[style*="height"] {
  height: auto;
}


/* ---------- 15. Case study stats band ----------
   The carousel widget renders the same .case markup, so the band styling
   carries over from style.css. These only cover the Elementor wrappers. */
body .elementor .case .stats { color: var(--navy); }
/* Columns must be at least as wide as their label, or the nowrap labels
   collide with the next column. min-width:0 (my earlier value) allowed
   exactly that. */
/* Columns must be able to shrink; max-content let a wide label push past the
   panel edge. Wrapping (see style.css) is the fallback instead. */
body .elementor .case .stats .stat,
.case .stats .stat { min-width: 0; }

/* A sideways-scrolling band hid the third stat on phones. The band stacks
   instead (responsive.css), so everything stays visible and every label stays
   on one line. */


/* ---------- 16. Case study stats as native containers ----------
   On the Our Work page the case blocks are native Elementor Containers, not
   the carousel widget. Elementor gives each Container its own flex settings
   as per-element CSS (0,2,0), which was laying the figure and its label side
   by side and pushing the third stat out of view.

   These restate the intended shape at 0,3,2 so the Container settings can't
   override them, while leaving colours and type to the normal cascade. */
body .elementor .e-con.stats,
body .elementor .e-con.atm-el.stats {
  display: grid;
  /* Content-width columns, matching style.css: labels are single-line, so the
     column only needs to be as wide as its own label. */
  grid-template-columns: repeat(3, auto);
  /* Grouped from the left, matching style.css — not spread edge to edge. */
  justify-content: start;
  align-items: start;
}

/* Gap is a :where() default too, so the Container's Gaps control works. */
:where(body .elementor .e-con.stats) {
  gap: .35rem clamp(1rem, 2.4vw, 1.9rem);
}
@supports (container-type: inline-size) {
  :where(body .elementor .e-con.stats) { column-gap: clamp(1rem, 3.6cqi, 1.9rem); }
}

/* Each stat stacks: figure above, label beneath. */
body .elementor .e-con.stats > .e-con,
body .elementor .e-con.atm-el.stats > .e-con {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: flex-start;
  gap: .2rem;
  min-width: 0;
  width: auto;
}

/* The "Impact at a glance" heading spans the full row above the figures. */
body .elementor .e-con.stats > .elementor-widget:first-child,
body .elementor .e-con.atm-el.stats > .elementor-widget:first-child {
  grid-column: 1 / -1;
  width: auto;
}

/* Widgets inside a stat must not stretch, or they re-introduce the side-by-side
   layout Elementor's defaults produced. */
body .elementor .e-con.stats .elementor-widget,
body .elementor .e-con.atm-el.stats .elementor-widget {
  width: auto;
  max-width: 100%;
  margin: 0;
}


/* ---------- 17. Stats band bleed on native containers ----------
   The band spans the copy panel edge-to-edge using negative margins equal to
   the panel's padding. That only lines up if the padding is actually the value
   the margins assume — and on these native Containers Elementor supplies its
   own padding, so the band undershot on one block and overflowed on another.

   Pinning both here means the two always agree. */
body .elementor .e-con.case__body,
body .elementor .e-con.atm-el.case__body {
  --case-pad: clamp(1.35rem, 2vw, 1.9rem);
  padding: var(--case-pad);
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 1rem;
  overflow: hidden;
}

body .elementor .e-con.case__body > .e-con.stats,
body .elementor .e-con.atm-el.case__body > .e-con.stats {
  width: auto;
  max-width: none;
  background: var(--paper);
  margin: 1.35rem calc(var(--case-pad) * -1) calc(var(--case-pad) * -1);
  border-radius: 0;
}

/* Padding sits at :where() zero specificity so the Container's own Padding
   control in the Elementor sidebar always wins. The default gives the last
   label clearance from the panel edge — it was running right up to it. */
:where(body .elementor .e-con.stats) {
  padding: 1.15rem var(--case-pad) 1.25rem;
}

/* The label sits above the figures, not inline with them. */
body .elementor .e-con.stats .stats__label,
body .elementor .e-con.stats > .elementor-widget-text-editor:first-child {
  grid-column: 1 / -1;
  color: var(--navy);
}

/* Figures take the slide accent; labels stay muted, both on the light band. */
body .elementor .e-con.stats .stat__num { color: var(--case-accent); }
body .elementor .e-con.stats .stat__label { color: var(--navy); }


/* ---------- 18. Stat label fit ----------
   Single line, always — the client asked for it explicitly and the earlier
   two-line fallback is what they were objecting to.

   The reason a fallback existed: three labels at the old size needed roughly
   540px and the copy panel offers about 460px. That is solved at source now —
   the columns are content-width rather than equal thirds (§16), and the type
   sizes itself against the panel with a container query, so three labels come
   in around 370px. Below 640px the band stacks (responsive.css), so the
   constraint disappears entirely on phones.

   All values are :where() defaults, so the sidebar still overrides them. */
:where(body .elementor .e-con.stats .stat__label),
:where(.case .stats .stat__label) {
  font-size: clamp(.6875rem, .5vw + .38rem, .78rem);
  white-space: nowrap;
  line-height: 1.35;
}
@supports (container-type: inline-size) {
  :where(body .elementor .e-con.stats .stat__label),
  :where(.case .stats .stat__label) {
    font-size: clamp(.6875rem, 2.5cqi, .78rem);
  }
}
:where(body .elementor .e-con.stats .stat__num),
:where(.case .stats .stat__num) {
  font-size: clamp(1.3rem, 1.7vw, 1.95rem);
  white-space: nowrap;
}

/* Native-container case panels are query containers too, so the labels inside
   them measure against the panel rather than the viewport. */
body .elementor .e-con.case__body,
body .elementor .e-con.atm-el.case__body { container-type: inline-size; }

/* Phones: one stat per row, figure and label side by side. */
@media (max-width: 640px) {
  body .elementor .e-con.stats,
  body .elementor .e-con.atm-el.stats { grid-template-columns: 1fr; }
  body .elementor .e-con.stats > .e-con,
  body .elementor .e-con.atm-el.stats > .e-con {
    flex-direction: row;
    align-items: baseline;
    gap: .55rem;
  }
}


/* ---------- 19. Partners page on native containers ----------
   Same situation as the case studies: these are Elementor Containers, whose
   own flex settings (0,2,0) would otherwise stack the logo and heading on top
   of one another. Structure is pinned; spacing stays adjustable below. */
body .elementor .e-con.partner,
body .elementor .e-con.atm-el.partner {
  display: grid;
  grid-template-columns: .95fr 1.05fr;
  align-items: center;
}
body .elementor .e-con.partner__body,
body .elementor .e-con.atm-el.partner__body {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}

/* The logo must keep its own proportions — it was being stretched to the
   widget's full width, which is what made it look distorted. */
body .elementor .partner__logo img,
body .elementor .elementor-widget-image.partner__logo img {
  height: 54px;
  width: auto;
  max-width: 260px;
  object-fit: contain;
}
body .elementor .e-con.partner__body > .elementor-widget-image.partner__logo {
  width: auto;
  margin: 0 0 1.25rem;
}

/* Industry partners + Pangaea */
body .elementor .e-con.industry,
body .elementor .e-con.atm-el.industry,
body .elementor .e-con.pangaea,
body .elementor .e-con.atm-el.pangaea {
  display: grid;
  grid-template-columns: minmax(180px, .8fr) 1.2fr;
  align-items: start;
}
body .elementor .e-con.pangaea { align-items: center; }

/* Spacing left open to the sidebar */
:where(body .elementor .e-con.partner) { gap: clamp(1.75rem, 4vw, 3.5rem); padding: clamp(1.5rem, 3vw, 2.75rem); }
:where(body .elementor .e-con.industry) { gap: clamp(1.75rem, 4vw, 3.5rem); padding: clamp(1.75rem, 3.5vw, 3rem); }
:where(body .elementor .e-con.pangaea) { gap: clamp(1.75rem, 4vw, 3.5rem); }


/* ---------- 20. Partners page corrections ----------
   The old site puts the logo column on the LEFT of Industry Partners and the
   copy on the right; our template has them the other way round. Ordering it
   in CSS avoids rebuilding the section. */

/* The partner logo belongs on its own line above the heading, not sitting
   beside the eyebrow. */
body .elementor .e-con.partner__body > .elementor-widget-image.partner__logo,
body .elementor .e-con.atm-el.partner__body > .elementor-widget-image.partner__logo {
  order: -1;
  align-self: flex-start;
  width: 100%;
}
body .elementor .e-con.partner__body > .elementor-widget-text-editor.eyebrow {
  order: -2;
}

/* The media column has no intrinsic height while its image is missing, so the
   panel collapses on one side. A min-height keeps the block looking
   deliberate until the image is added. */
body .elementor .e-con.partner__media:empty,
body .elementor .e-con.atm-el.partner__media:empty { min-height: 320px; }

/* Logos sit flush left in their column, at a consistent height */


/* ---------- 21. Pangaea row ----------
   Intended usage is CSS Classes = "industry pangaea", so the row inherits the
   panel and only the separator differs. If it is used with "pangaea" alone,
   these give it the same panel treatment rather than leaving it unstyled. */
body .elementor .e-con.pangaea:not(.industry),
body .elementor .e-con.atm-el.pangaea:not(.industry) {
  display: grid;
  grid-template-columns: minmax(180px, .8fr) 1.2fr;
  align-items: center;
  background: var(--paper);
}
:where(body .elementor .e-con.pangaea:not(.industry)) {
  gap: clamp(1.75rem, 4vw, 3.5rem);
  padding: clamp(1.75rem, 3.5vw, 3rem);
}

/* When it follows the Industry Partners panel, the two read as one block:
   no gap between them, a hairline rule instead. */
body .elementor .e-con.industry + .e-con.pangaea,
body .elementor .e-con.atm-el.industry + .e-con.atm-el.pangaea {
  margin-top: 0;
  border-top: 1px solid var(--line);
  border-radius: 0 0 var(--radius-lg) var(--radius-lg);
}
body .elementor .e-con.industry:has(+ .e-con.pangaea) {
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
}

/* The Pangaea lockup is wide and light — it needs no cap beyond a sensible
   maximum, and sits flush left like the other logos. */
body .elementor .e-con.pangaea .elementor-widget-image img {
  max-width: 240px;
  max-height: none;
  width: 100%;
  height: auto;
  object-fit: contain;
}


/* ---------- 22. Industry logo column ----------
   Single stacked column at a readable size, matching the old site. The
   assertion stylesheet still pins .logo-wall's grid, so these restate the
   column shape above it. */
body .elementor .e-con.atm-el.logo-wall {
  grid-template-columns: 1fr;
  background: none;
  border: 0;
}
body .elementor .e-con.atm-el.logo-wall .elementor-widget-image { width: auto; }
body .elementor .e-con.atm-el.logo-wall img {
  max-width: 230px;
  width: 100%;
  height: auto;
  max-height: 70px;
  object-fit: contain;
  object-position: left center;
}
:where(body .elementor .e-con.atm-el.logo-wall) { gap: clamp(1.1rem, 2.2vw, 1.9rem); }


/* ---------- 23. Empty containers in the editor ----------
   An empty Container on a dark panel is invisible in the canvas, so there is
   nothing to drop a widget onto. Inside the editor only, empty design-system
   containers get a dashed outline and a minimum size so they can be found and
   used as a drop target. Front end is untouched. */
body.elementor-editor-active .elementor .e-con.atm-el:not(:has(*)),
body.elementor-editor-active .elementor .e-con.atm-el:empty {
  min-height: 180px;
  outline: 2px dashed rgba(255, 255, 255, .35);
  outline-offset: -8px;
  border-radius: var(--radius);
}
body.elementor-editor-active .elementor .e-con.atm-el.partner__media:not(:has(*)),
body.elementor-editor-active .elementor .e-con.atm-el.partner__media:empty {
  min-height: 320px;
}


/* ---------- 24. Partners page polish ----------
   Logos as individual Image widgets in a 2x2 grid — a single column of five
   full-size logos was what made them tower over the copy. */

/* Pangaea sits alone, so it gets the full column width */

/* The service-partner panel lifts slightly on approach */
body .elementor .e-con.partner {
  transition: transform .6s var(--ease), box-shadow .6s var(--ease);
}
body .elementor .e-con.partner:hover {
  transform: translateY(-3px);
  box-shadow: 0 22px 60px rgba(7, 13, 24, .28);
}
body .elementor .e-con.partner__media img {
  transition: transform .9s var(--ease);
}
body .elementor .e-con.partner:hover .partner__media img { transform: scale(1.04); }

@media (max-width: 860px) {
}
@media (prefers-reduced-motion: reduce) {
  body .elementor .e-con.partner,
  body .elementor .e-con.partner__media img,
  body .elementor .e-con.partner:hover { transform: none; }
  body .elementor .e-con.partner:hover .partner__media img { transform: none; }
}


/* ---------- 25. Entrance-animation safety net ----------
   Elementor's entrance animations add `elementor-invisible` (opacity:0) and
   rely on its frontend JS to remove it. If that script is deferred, blocked or
   fails, the content never appears — correct in the editor, blank on the front
   end.

   These rules guarantee the content becomes visible regardless: immediately
   when JS is unavailable, and after a short grace period otherwise. Elementor's
   own animation still plays normally when it works — it removes the class long
   before this fires. */
html:not(.js) .elementor-invisible { opacity: 1 !important; animation: none !important; }

@keyframes atm-failsafe-show { to { opacity: 1; } }
.elementor-invisible {
  animation: atm-failsafe-show 0s linear 2.5s forwards;
}

/* The design system's own reveal never depends on Elementor's script. */
.reveal { opacity: 0; transform: translateY(18px); transition: opacity .7s var(--ease), transform .7s var(--ease); }
.reveal.is-in { opacity: 1; transform: none; }
html:not(.js) .reveal { opacity: 1; transform: none; }
.reveal[data-d="2"] { transition-delay: .08s; }
.reveal[data-d="3"] { transition-delay: .16s; }
.reveal[data-d="4"] { transition-delay: .24s; }

@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1; transform: none; transition: none; }
}


/* ==========================================================
   26. Industry partners — single source of truth
   Earlier passes left several competing rules for this column
   (one flex, one grid), which cancelled out and produced a tall
   single stack with a large void beside it. This block replaces
   them all.
   ========================================================== */

/* Logo column sits left; the copy no longer needs a wide column, so the
   split is tightened and the gap reduced. */
:where(body .elementor .e-con.atm-el.industry),
:where(body .elementor .e-con.atm-el.industry.pangaea) {
  display: grid;
  grid-template-columns: minmax(240px, .85fr) 1.15fr;
  align-items: center;
}
body .elementor .e-con.atm-el.industry > .e-con.industry__logos { order: -1; }

:where(body .elementor .e-con.atm-el.industry) {
  gap: clamp(1.5rem, 3vw, 2.75rem);
  padding: clamp(1.75rem, 3vw, 2.5rem) clamp(1.5rem, 3vw, 2.75rem);
}

/* Four logos in a 2x2 block rather than one long column — closes the void
   under them and keeps the section compact. */
/* Layout is a :where() default so the Container's own Direction, Justify,
   Align and Wrap controls in the sidebar take precedence. Out of the box it
   is a centred 2x2 block; change it in Elementor without fighting this file. */
:where(body .elementor .e-con.atm-el.industry__logos) {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  align-items: center;
  justify-items: center;
  align-content: center;
}

/* If the Container is switched to a flex direction in the sidebar, these keep
   it behaving sensibly rather than collapsing to a single stack. */
body .elementor .e-con.atm-el.industry__logos {
  min-width: 0;
}
:where(body .elementor .e-con.atm-el.industry__logos) {
  gap: clamp(1rem, 2vw, 1.75rem);
}
/* Height default only — the widget's own Width/Height controls override it. */
:where(body .elementor .e-con.atm-el.industry__logos img) { max-height: 54px; }
body .elementor .e-con.atm-el.industry__logos > .elementor-widget-image {
  width: auto;
  margin: 0;
}
/* Everything cosmetic on the logos — size, greyscale treatment, hover lift —
   is a :where() default, so the Image widget's own Width, Height, Opacity,
   CSS Filters and Hover controls in the sidebar always win. This rule at
   real specificity is what was swallowing a Width typed in the sidebar. */
:where(body .elementor .e-con.atm-el.industry__logos img) {
  max-width: 100%;
  width: auto;
  height: auto;
  object-fit: contain;
  filter: grayscale(1);
  opacity: .72;
  transition: filter .45s var(--ease), opacity .45s var(--ease), transform .45s var(--ease);
}
:where(body .elementor .e-con.atm-el.industry__logos .elementor-widget-image:hover img) {
  filter: none;
  opacity: 1;
  transform: translateY(-2px);
}

/* Pangaea has one logo, so it takes the full column at a larger size. */
:where(body .elementor .e-con.atm-el.pangaea .e-con.atm-el.industry__logos) {
  grid-template-columns: 1fr;
}
:where(body .elementor .e-con.atm-el.pangaea .e-con.atm-el.industry__logos img) { max-height: 72px; }

/* Copy column: no stray bottom margin on the last paragraph, so the panel
   closes up tightly under the text. */
body .elementor .e-con.atm-el.industry__body > .elementor-widget:last-child { margin-bottom: 0; }
body .elementor .e-con.atm-el.industry__body p:last-child { margin-bottom: 0; }

@media (max-width: 860px) {
  body .elementor .e-con.atm-el.industry,
  body .elementor .e-con.atm-el.industry.pangaea { grid-template-columns: 1fr; }
  :where(body .elementor .e-con.atm-el.industry__logos) { grid-template-columns: repeat(2, 1fr); }
}
@media (prefers-reduced-motion: reduce) {
  body .elementor .e-con.atm-el.industry__logos img { transition: none; }
}


/* ---------- 27. Contact card: office thumbnail ----------
   Luke Jones' personal contact is replaced by a thumbnail of the office, per
   the client's edit list. The person block becomes a landscape image panel
   rather than a round headshot beside a name. */
body .elementor .contact-card__person,
.contact-card__person {
  display: block;
  padding-bottom: 0;
  border-bottom: 0;
}
/* Sizing is a :where() default — the client asked for the office photo
   smaller, so it now sits at 85% of the card width with a shorter 16:9
   frame. The Image widget's own Width/Height in the sidebar override this
   if it needs nudging further. */
:where(body .elementor .contact-card__person img,
       .contact-card__person img) {
  width: 85%;
  height: auto;
  aspect-ratio: 16/9;
  border-radius: var(--radius);
  object-fit: cover;
  margin-bottom: 1.35rem;
}

/* When the office image is added as its own widget in the card */
:where(body .elementor .e-con.contact-card .elementor-widget-image.contact-card__thumb img) {
  width: 85%;
  height: auto;
  aspect-ratio: 16/9;
  object-fit: cover;
  border-radius: var(--radius);
}
:where(body .elementor .e-con.contact-card .elementor-widget-image.contact-card__thumb) {
  margin-bottom: 1.35rem;
}

/* ---------- Logo stacks ----------
   Add the class "logo-stack" to any container of partner/industry logos and
   every logo renders at the same width, centred, whatever the size of the
   uploaded file — a 90px USTOA wordmark and a 400px Signature logo come out
   equal. :where() keeps this at zero specificity, so a Width set on an
   individual Image widget in the sidebar still wins. Adjust the shared width
   per stack with --logo-w on the container if 210px doesn't suit. */
:where(.elementor .e-con.logo-stack .elementor-widget-image img,
       .logo-stack img) {
  width: min(var(--logo-w, 210px), 100%);
  height: auto;
  object-fit: contain;
}
:where(.elementor .e-con.logo-stack .elementor-widget-image) {
  width: auto;
}