/* ------------------------------------------------------------------
   Elementor compatibility layer.

   styles.css was written against hand-authored markup. Elementor wraps
   every widget in .elementor-element > .elementor-widget-container, and
   swaps some tags for its own. Where our CSS targets a CLASS we keep it
   via _css_classes and nothing is needed. This file only re-points the
   handful of rules that targeted a TAG Elementor replaced.

   No design decisions live here. Values are all inherited from tokens.
   ------------------------------------------------------------------ */

/* Elementor's default kit paints headings its own cyan and resets line-height
   to 1, at .elementor-heading-title (0,1,0) — which outranks our `h1, h2, h3`
   tag rule (0,0,1). Inheriting is NOT the fix: that pulls body line-height and
   drops letter-spacing. Re-assert the real values from styles.css line 16. */
.elementor-heading-title {
	color: inherit;
	font-family: inherit;
	font-size: inherit;
	font-weight: inherit;
	line-height: var(--lh-tight);
	letter-spacing: -0.015em;
	margin: 0;
	text-wrap: balance;
}

/* Widget wrappers must not become layout boxes of their own: a wrapper
   sitting between a grid and its item breaks every direct-child rule.
   Collapsing them puts the real <p>/<h2>/<img> back in the grid, which is
   where styles.css expects to find it. */
.elementor-widget-container { display: contents; }
/* NOT text-editor or html widgets. Those were display:contents until we found
   it silently breaks scroll reveals: motion.js tags them .rv, but an element
   with display:contents generates no box, so IntersectionObserver can never
   report it as intersecting and .is-in is never applied. They keep a normal
   block box; the two rules that needed the wrapper gone are handled below. */

/* ---- buttons: our .btn class lands on the wrapper, the anchor is inside ---- */
.elementor-widget-button.btn { display: inline-flex; padding: 0; border: 0; background: none; }
.btn > .elementor-button,
.btn .elementor-button {
	display: inline-flex; align-items: center; justify-content: center; gap: var(--s2);
	font: inherit; font-size: var(--fs-sm); font-weight: 600;
	padding: 0.8125rem var(--s4); border-radius: var(--radius);
	text-decoration: none; border: 1px solid transparent; cursor: pointer;
	background: none; color: inherit;
	transition: background-color 140ms ease, color 140ms ease, border-color 140ms ease, transform 90ms ease;
}
.btn-primary .elementor-button { background: var(--accent); color: var(--accent-ink); }
.btn-primary .elementor-button:hover { filter: brightness(0.92); }
.btn-ghost .elementor-button { border-color: var(--line); color: var(--ink); background: var(--paper); }
.btn-ghost .elementor-button:hover { border-color: var(--ink-3); }
.band-dark .btn-ghost .elementor-button { background: transparent; color: var(--dark-ink); border-color: var(--dark-line); }
.btn-dark .elementor-button { background: var(--ink); color: var(--paper); }
.btn-urgent .elementor-button { background: var(--urgent); color: var(--urgent-ink); }
.elementor-button-content-wrapper, .elementor-button-text { display: contents; }

/* ---- images ----
   styles.css sizes tile photos with aspect-ratio and used height:100% only
   because the img was a direct child. Through Elementor's wrapper that
   percentage has no basis to resolve against, so it collapses. Let the
   aspect-ratio do the work it was always doing. */
.tile .elementor-widget-image { display: block; }
.tile .elementor-widget-image img { height: auto; }
.shot .elementor-widget-image { display: block; height: 100%; }

/* ---- text-editor replaces <p>/<blockquote> with a bare div ---- */
.statement .stmt-q {
	margin: var(--s4) 0 0;
	font-size: clamp(1.65rem, 3.6vw, 2.65rem); line-height: 1.16;
	font-weight: 640; letter-spacing: -0.022em; max-width: 20ch; text-wrap: balance;
}

/* Elementor puts a 20px gap under every widget that isn't last. Our stylesheet
   owns vertical rhythm (.stack, .stack-lg, section padding), so that gap is
   pure drift: it pushed the page ~300px taller and lifted tile captions off
   the bottom of their photo. */
.elementor-widget:not(:last-child) { margin-block-end: 0; }

/* Same story one level up: every Elementor container ships a 10px padding and
   a 20px gap. styles.css already owns spacing through `section` padding,
   `.wrap` gutters and the `.stack` rhythm, so Elementor's defaults are drift.
   Zero them and let the design system be the only source of spacing. */
/* Reset them through Elementor's OWN custom properties, not with flat
   declarations. A flat `gap: 0` here would also beat .hero-grid / .tiles /
   .steps, which set gap legitimately. Zeroing the variables leaves Elementor's
   declaration in place at its own specificity, so our classes still win. */
.e-con, .e-con-inner {
	--padding-block-start: 0px; --padding-block-end: 0px;
	--padding-inline-start: 0px; --padding-inline-end: 0px;
	--gap: 0px; --row-gap: 0px; --column-gap: 0px;
}

/* ---- flex direction ----
   Elementor sets --flex-direction: column on every container. Our stylesheet
   declares `display:flex` on rows that expect the CSS default (row) and never
   restates direction, so they came out stacked. */
/* Set it through Elementor's variable: its own rule is `.e-con.e-flex` (0,2,0)
   and outranks a plain class, so a flat `flex-direction: row` loses. */
/* Elementor's own rule is `.e-con.e-flex` (0,2,0), so a single class loses on
   both the property AND the variable. Match its specificity.
   This list is every `display: flex` rule in styles.css that does not also
   declare a direction, i.e. every one that expects the CSS default of row. */
/* Specificity is .e-con.e-flex (0,3,0 with the class) because Elementor's
   base-mobile.css re-declares these variables and loads AFTER this file. At
   0,2,0 the desktop was right and the mobile silently reverted. */
.e-con.e-flex.btn-row, .e-con.e-flex.hdr-in, .e-con.e-flex.chips,
.e-con.e-flex.tm-score, .e-con.e-flex.tm-by, .e-con.e-flex.ftr-legal,
.e-con.e-flex.in,
.e-con.e-flex.ticks, .e-con.e-flex.trust {
	--flex-direction: row;
	flex-direction: row;
	/* Elementor containers also default to flex-wrap: wrap. None of these rows
	   asked to wrap, and the review byline did: the avatar and the name stacked,
	   adding 48px to every card. Rules that DO want wrapping (.btn-row, .chips)
	   declare flex-wrap directly in styles.css and still win. */
	--flex-wrap: nowrap;
}

/* The heading widget's wrapper keeps body line-height, which pads the service
   row index. It exists only to hold the class, so give it the heading rhythm. */
.elementor-widget-heading { line-height: var(--lh-tight); }

/* ---- intrinsic width ----
   Elementor pins every container to `width: var(--width)` = 100%. Plain divs
   size themselves, so anything relying on intrinsic width broke: the hero
   image's negative-margin bleed was capped at its grid column, and the
   contact alert filled its column instead of shrinking under
   `.cta-block { justify-items: start }`. `auto` still fills in normal flow,
   so this restores the source behaviour rather than changing it. */
.e-con { --width: auto; }

/* One exception: .wrap is the only rule in styles.css using `margin-inline:
   auto`, and auto margins on a flex item switch off stretching — so with an
   intrinsic width every .wrap shrank to its text and centred, taking .srv,
   .faq, the statement quote and the CTA strip with it. .wrap wants the full
   line and caps itself with max-width, so give that one 100% back. */
.e-con.wrap { --width: 100%; }

/* ---- section padding ----
   `section { padding-block: var(--s7) }` is a tag rule (0,0,1) and lost to
   Elementor's `.e-con { padding-block: var(--padding-*) }` (0,1,0), so every
   section without its own class rendered with zero padding — 5 sections,
   ~683px of the page-height gap. Feed the default through Elementor's own
   variables so class rules like .hero / .pad-xl / .tight still win. */
section.e-con {
	--padding-block-start: var(--s7);
	--padding-block-end: var(--s7);
}


/* Elementor prints the text widget as whitespace + <p> + whitespace. With the
   wrapper now a real box those stray text nodes form their own line boxes and
   pad it (8px per service row). Zero the wrapper's line-height and give the
   real element its rhythm back; rules that set their own (.stmt-q at 1.16)
   are more specific and still win. */
.elementor-widget-text-editor { line-height: 0; }
.elementor-widget-text-editor > * { line-height: var(--lh-body); }

/* Two rules that assumed the text node was the direct child. With a real
   wrapper in between, re-point them at the wrapper. */
.srv-item > .elementor-widget-text-editor { grid-column: 2 / -1; }
@media (min-width: 900px) { .srv-item > .elementor-widget-text-editor { grid-column: auto; } }
/* .stars sets line-height:0 on its span; the wrapper would re-introduce the
   body rhythm and add 9px to every review card. */
.tm > .elementor-widget-html { line-height: 0; }

/* styles.css hides the row arrow below 900px, but that display:none sits on
   the <span> inside the widget. The wrapper stayed visible and kept its grid
   cell, adding an empty third row and 8px to every service row. Mirror the
   breakpoint onto the wrapper. */
.elementor-widget-html:has(> .srv-go) { display: none; }
@media (min-width: 900px) { .elementor-widget-html:has(> .srv-go) { display: block; } }

/* hello-elementor's reset sets its own line-height on form labels and on
   h4-h6. styles.css only declares a tight line-height for h1-h3 and lets
   everything else inherit the body rhythm, so the parent theme was winning
   by default: 9px per form field, and 5px per footer column heading. */
.field label { line-height: var(--lh-body); }
h4, h5, h6 { line-height: var(--lh-body); }

/* A `1fr` grid track floors at the min-content of its item, so the mobile call
   bar could not compress and pushed the page 2px wide. The live build clears
   390 by 1.5px, which is luck rather than design. */
.callbar .call { min-width: 0; }

/* ---- ::before collision ----
   Elementor reserves ::before on every container for its background-overlay
   feature and hard-sizes it to width:100%; height:100%. styles.css also uses
   ::before for real content - the lime step number on .step - which is
   positioned with `left` and expects shrink-to-fit. Elementor's 100% stretched
   it to the full column, overflowing .step by 22px and pushing the whole
   mobile page 2px wide. We use no Elementor background overlays, so hand the
   pseudo-element its natural sizing back. */
.e-con::before { width: auto; height: auto; }

/* Exception: the process rail IS a drawn line, so it needs its explicit 1px
   height back. `height: auto` above collapses an empty absolute pseudo to 0,
   which silently deleted the hairline that divides the four steps. */
.steps.e-con::before { height: 1px; }


/* ---- cards are COLUMNS, not rows ----
   .card and .card-photo were in the row list above. They are not rows:
   styles.css line 210 declares `flex-direction: column`. Forcing row laid the
   photo, heading, paragraph and "Learn more" side by side in a 534px box, so
   every card collapsed to ~146px instead of 577px. Who-we-serve lost 865px of
   its height that way. Same specificity as Elementor's `.e-con.e-flex`, plus
   the variable, because base-mobile.css re-declares it after this file. */
.e-con.e-flex.card, .e-con.e-flex.card-photo {
	--flex-direction: column;
	flex-direction: column;
	--flex-wrap: nowrap;
}

/* The photo is the first thing in the card and must not be squeezed by the
   copy under it: in a column flex box an image is a flex ITEM, and Elementor's
   wrapper gives it `flex: 0 1 auto`, so it shrinks. styles.css sized it with
   aspect-ratio, which only holds if the item is allowed its own height. */
.card-photo > .elementor-widget-image.shot-thumb { flex: none; width: 100%; }
.card-photo > .elementor-widget-image.shot-thumb img {
	display: block; width: 100%; height: auto;
	aspect-ratio: 4 / 3; object-fit: cover;
}

/* ---- the card's "Learn more" line ----
   styles.css sizes it with `margin-top: auto; padding-top; margin-bottom`,
   which only works on a block-level flex item. In the static build the <span>
   was a direct child of the flex card, so it was blockified. Elementor puts an
   html widget in between, leaving the span inline - and vertical margin and
   padding do nothing on an inline box. Every card came out ~29px short, which
   stacked to 213px on a four-card mobile page. Re-point the rule at the
   wrapper and let the span be a block again. */
.card > .elementor-widget-html:has(> .more) { margin-top: auto; }
.card .elementor-widget-html > .more { display: block; }
