/* ==========================================================================
   Infocus — Elementor bridge

   WHY THIS FILE EXISTS
   --------------------------------------------------------------------------
   When you type a class into Elementor's "Advanced > CSS Classes" field, the
   class lands on the widget's OUTER WRAPPER, not on the element inside it.

       <div class="elementor-widget elementor-widget-button btn--primary">
         <div class="elementor-button-wrapper">
           <a class="elementor-button">...</a>     <-- the thing you want styled
         </div>
       </div>

   So writing `.btn` in the CSS Classes field does NOT style the anchor.

   This file bridges the gap: it re-applies the design system in main.css to
   the elements Elementor actually renders. Load it AFTER main.css.

   The design system uses CSS custom properties (--btn-bg, --btn-fg, --btn-bd)
   which inherit down the tree — so the existing modifier classes
   (.btn--primary, .btn--outline, .btn--light, .btn--ghost-light) keep working
   from the wrapper with no changes at all. Only the base rules need bridging.
   ========================================================================== */


/* --------------------------------------------------------------------------
   0. CONTAINER DISPLAY GUARD
   --------------------------------------------------------------------------
   Elementor declares `display: var(--display)` on every container, and writes
   the value of --display into the PER-PAGE generated stylesheet, per element.
   When that file is stale — a template inserted after the last CSS build, a
   page duplicated, Element Caching serving an older copy — the variable is
   missing on some elements.

   `var(--display)` with no value and no fallback is invalid at computed-value
   time, so the property reverts to its INITIAL value. For display that is
   `inline`, not `block`. An inline box paints no background across the block
   area, so a dark section silently loses its background and any white text on
   it disappears against the page.

   Regenerating Elementor's CSS is the real fix. This makes the failure
   impossible rather than merely rare: when --display is set, this is
   identical to Elementor's own rule.
   -------------------------------------------------------------------------- */

.e-con,
.e-con > .e-con-inner {
  display: var(--display, flex);
}


/* --------------------------------------------------------------------------
   1. BUTTONS
   --------------------------------------------------------------------------
   Usage in Elementor:
     Button widget > Advanced > CSS Classes:  btn--primary
                                              btn--outline
                                              btn--light btn--lg
   Do NOT also type `btn` — the rules below already target every Elementor
   button. Only add the modifier.
   -------------------------------------------------------------------------- */

/* THE DEFAULTS LIVE ON THE WRAPPER, AT ZERO SPECIFICITY.
   --------------------------------------------------------------------------
   main.css puts the modifiers on the element that carries the class:

       .btn--light { --btn-bg: #fff; --btn-fg: var(--crimson); --btn-bd: #fff }

   In Elementor that class lands on the WRAPPER, and the custom properties are
   meant to inherit down to .elementor-button. Declaring --btn-* on the inner
   button instead would beat the inherited value outright — a local
   declaration always wins over inheritance — and every modifier would be
   silently ignored, rendering every button default crimson.

   :where() gives these zero specificity, so .btn--light (0,1,0) on the same
   element overrides them cleanly. Do NOT re-declare --btn-* on
   .elementor-button below. */
:where(.elementor-widget-button) {
  --btn-bg: var(--crimson);
  --btn-fg: #fff;
  --btn-bd: var(--crimson);
}


/* --- STRIP THE PAINT FROM THE WRAPPER -----------------------------------
   `.btn` in main.css is a plain class rule, and in Elementor that class is on
   the WRAPPER. So main.css paints the wrapper as a complete button —
   background, 1.5px border, 999px radius and .875rem/1.6rem padding — while
   the bridge paints the real <a> inside it. Every button on the site is two
   nested pills, the outer one exactly 2 x 1.6rem wider than the inner.

   On a solid background this hides, because both pills are the same colour
   and the outer one just reads as a slightly bigger button. It becomes
   visible the moment anything moves one and not the other:

     - the magnetic hover in infocus-elementor.js transforms only
       .elementor-button, so the label and its pill slide out of the
       stationary outer pill;
     - `.btn:hover { transform: translateY(-2px) }` fires on BOTH, so the
       lift is applied twice and the button jumps 4px.

   Keep the custom properties on the wrapper — they must still inherit down —
   and remove only the paint and the motion. (0,2,0) beats `.btn` at (0,1,0).
   `.btn--light` and friends set no paint of their own, only --btn-* values,
   so no modifier is affected. */
.elementor-widget-button.btn {
  padding: 0;
  border: 0;
  border-radius: 0;
  background: none;
  box-shadow: none;
}

.elementor-widget-button.btn:hover {
  transform: none;
  box-shadow: none;
}


.elementor-widget-button .elementor-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .55rem;
  padding: .875rem 1.6rem;
  border: 1.5px solid var(--btn-bd);
  border-radius: 999px;
  background: var(--btn-bg);
  color: var(--btn-fg);
  font-family: var(--font-sans);
  font-size: var(--step-0);
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: -0.005em;
  text-decoration: none;
  cursor: pointer;
  transition: transform .2s var(--ease), box-shadow .2s var(--ease),
              background-color .2s var(--ease), border-color .2s var(--ease),
              color .2s var(--ease);
}

.elementor-widget-button .elementor-button:hover {
  color: var(--btn-fg);
  transform: translateY(-2px);
  box-shadow: 0 8px 22px rgba(154, 1, 48, .26);
}

.elementor-widget-button .elementor-button:active {
  transform: translateY(0);
  transition-duration: .08s;
}

/* Size modifiers, applied from the wrapper. */
.elementor-widget-button.btn--sm .elementor-button { padding: .6rem 1.15rem; font-size: var(--step--1); }
.elementor-widget-button.btn--lg .elementor-button { padding: 1.05rem 2rem;  font-size: var(--step-1); }

/* Light-on-dark variants need their own shadow, not the crimson one. */
.elementor-widget-button.btn--light .elementor-button:hover {
  box-shadow: 0 8px 24px rgba(0, 0, 0, .28);
}
.elementor-widget-button.btn--ghost-light .elementor-button:hover {
  box-shadow: none;
}

/* Elementor's own icon slot, matched to .btn .icon */
.elementor-widget-button .elementor-button-icon svg,
.elementor-widget-button .elementor-button-icon i {
  width: 1.05em;
  height: 1.05em;
  transition: transform .2s var(--ease);
}
.elementor-widget-button .elementor-button:hover .elementor-button-icon svg {
  transform: translateX(3px);
}

/* A row of buttons: put `btn-row` on the CONTAINER holding them. */
.btn-row > .elementor-widget-button { margin: 0; }


/* --- THE DESIGN SYSTEM'S OWN <button> ELEMENTS ---------------------------
   main.css styles several bare <button>s directly — the dialog close, the
   accordion trigger, the carousel arrows. Hello Elementor also styles bare
   <button>, and where its selector wins you get a themed pill instead of the
   intended chrome: the dialog's close button, for instance, renders as a
   solid crimson circle with the icon invisible against it.

   Restate the design-system values at a specificity the theme cannot reach.
   Values from main.css:1666. */
.bio-dialog__close,
.quote-dialog .bio-dialog__close {
  width: 2.25rem !important;
  height: 2.25rem !important;
  display: grid !important;
  place-items: center;
  padding: 0 !important;
  border: 1px solid var(--line) !important;
  border-radius: 50% !important;
  background: var(--paper) !important;
  color: var(--ink) !important;
  box-shadow: none !important;
  transition: background-color .2s var(--ease), color .2s var(--ease);
}

.bio-dialog__close:hover {
  background: var(--crimson) !important;
  border-color: var(--crimson) !important;
  color: #fff !important;
}

/* The X itself — stroked, inheriting the button's colour so it flips to
   white on hover. */
.bio-dialog__close .icon,
.bio-dialog__close svg {
  width: 1rem !important;
  height: 1rem !important;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.2;
  stroke-linecap: round;
  stroke-linejoin: round;
}


/* --- THE INVISIBLE OVERLAY BUTTON ---------------------------------------
   .quote-card__open (main.css:2329) is a transparent <button> stretched over
   a whole testimonial card — `position: absolute; inset: 0` — whose only job
   is to open the dialog. It must stay invisible.

   Two things can paint it:

   1. main.css sets `background: transparent` for the REST state only. Hello
      Elementor styles bare <button> elements, including a :hover background,
      and there is no competing hover rule — so the card fills with colour
      the moment you mouse over it.

   2. If the card is rebuilt with an Elementor Button widget instead of raw
      markup, the .elementor-button rules above paint it crimson and give it
      the 2px lift — across the entire card.

   Either way the result is a solid block covering the testimonial. Pin every
   state transparent. */
.quote-card__open,
.quote-card__open:hover,
.quote-card__open:focus,
.quote-card__open:active,
.quote-card .elementor-button,
.quote-card .elementor-button:hover {
  background: transparent !important;
  border: 0 !important;
  box-shadow: none !important;
  color: inherit !important;
  transform: none !important;
  padding: 0 !important;
}

/* Keep the keyboard focus ring — the button is the only way in without a mouse. */
.quote-card__open:focus-visible {
  outline: 2px solid var(--crimson) !important;
  outline-offset: 3px;
}


/* --------------------------------------------------------------------------
   2. HEADINGS
   --------------------------------------------------------------------------
   main.css already styles h1-h6 globally, so headings mostly just work.
   These map the design system's utility classes onto the heading widget.

   Usage:  Heading widget > Advanced > CSS Classes:  eyebrow
   -------------------------------------------------------------------------- */

/* --- VERTICAL RHYTHM: RESTORE THE MARGINS ELEMENTOR ZEROES ---------------
   main.css builds spacing inside a page header from element margins:

       .breadcrumbs   margin-bottom: 1.5rem   (main.css:1118)
       .eyebrow       margin-bottom: 1rem     (main.css:194)
       h1-h4          margin: 0 0 .6em        (main.css:99)

   Elementor zeroes widget margins and sets `.elementor-heading-title
   { margin: 0 }`, both at higher specificity than the source classes. With
   container Gap 0 that leaves every block flush against the next.

   This is the legitimate case for restating values: main.css genuinely
   cannot reach these elements. Keep the numbers identical to the source.

   Do NOT solve it with container Gap instead — the spacing is uneven
   (1.5rem / 1rem / .6em), so a single gap value cannot reproduce it. */

.elementor-widget-heading .elementor-heading-title {
  margin: 0 0 .6em;
}

.e-con > .elementor-widget.breadcrumbs,
.e-con > .e-con-inner > .elementor-widget.breadcrumbs {
  margin-bottom: 1.5rem;
}

.e-con > .elementor-widget.eyebrow,
.e-con > .e-con-inner > .elementor-widget.eyebrow {
  margin-bottom: 1rem;
}


/* INHERIT, DON'T RESTATE.
   --------------------------------------------------------------------------
   `.eyebrow` (main.css:185) lands on the widget wrapper, where it works
   correctly — it is inline-flex, and its ::before draws the 28px bronze dash.
   The inner heading only needs to stop overriding what flows down to it.

   Do NOT hardcode values here. The eyebrow's colour is context-dependent:

       .eyebrow                 crimson        (light sections)
       .section--dark .eyebrow  bronze-400     (main.css:203)
       .page-head .eyebrow      bronze-400     (main.css:1115)

   An earlier version of this rule pinned `color: var(--bronze)` and
   `letter-spacing: .08em`, which forced bronze onto light-background eyebrows
   and used the wrong tracking (main.css uses .14em). Inheriting keeps every
   context correct with no values to drift. */
.elementor-widget-heading.eyebrow .elementor-heading-title {
  font: inherit;
  color: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  margin: 0;
}



/* `.v2-heading` — the standalone section title.
   --------------------------------------------------------------------------
   Same wrapper problem as .eyebrow above, same fix. main.css:1171 says

       .v2-heading { font-size: var(--step-3); margin: 0 }

   and Elementor puts the CSS class on the widget wrapper, so that size lands
   on a <div> with no text of its own. The inner h2 keeps `h2 { font-size:
   var(--step-4) }` from main.css:103 — a full step larger — because its own
   element rule beats anything inherited from the parent.

   `font-size: inherit` hands the wrapper's --step-3 down without restating a
   number, so a change to the type scale in main.css still flows through.

   The margin override matters as much as the size. The widget rule further up
   gives every heading `0 0 .6em`, but .v2-col supplies rhythm through its own
   flex gap (`gap: clamp(1.5rem, 3vw, 2.25rem)`), so a v2-heading must add
   nothing of its own or the spacing compounds.

   `.v2-heading--center` needs no rule here — text-align inherits from the
   wrapper on its own. */
.elementor-widget-heading.v2-heading .elementor-heading-title {
  font-size: inherit;
  margin: 0;
}


/* --------------------------------------------------------------------------
   3. TEXT / PROSE
   --------------------------------------------------------------------------
   Usage:  Text Editor widget > Advanced > CSS Classes:  lede
                                                         prose prose--measure
   -------------------------------------------------------------------------- */

/* NOTHING RESTATED HERE EITHER.
   `.lede` (main.css:206) and `.prose` land on the widget wrapper and work as
   written; the <p> inside inherits from them.

   An earlier version declared `font-size: inherit` on these wrappers, which
   sits at (0,2,0) and beat `.lede { font-size: var(--step-1) }` at (0,1,0) —
   so every lede rendered at body size instead of ~20px. Removed. */

/* Elementor wraps the content in a div; make the utility classes reach it. */
.elementor-widget-text-editor.prose--measure > .elementor-widget-container {
  max-width: 62ch;
}
.elementor-widget-text-editor.prose--center > .elementor-widget-container {
  margin-inline: auto;
  text-align: center;
}


/* --- BLOCKQUOTE INSIDE PROSE --------------------------------------------
   main.css declares no blockquote rule — the static site relies on the
   browser default (`margin: 1em 40px`) for the indented contact lines on the
   ISO 22000 and HACCP pages. Hello Elementor's reset can strip that, leaving
   the quote flush with the body copy.

   Stating it explicitly makes the indent deterministic. Vertical rhythm still
   comes from `.v2-col .prose > * + *`, so only the inline margin is set. */
.prose blockquote,
.elementor-widget-text-editor blockquote {
  margin-inline: 40px;
  padding: 0;
  border: 0;
  font-style: normal;
  quotes: none;
}

.prose blockquote::before,
.prose blockquote::after {
  content: none;
}


/* --------------------------------------------------------------------------
   3b. ICON BADGE
   --------------------------------------------------------------------------
   .icon-badge (main.css:294) is a 3.25rem rounded tile with a gradient
   background holding a 1.6rem stroke icon — the thing above each card
   heading in a feature grid.

   Put `icon-badge icons--stroke` on an Icon widget. The class lands on the
   widget wrapper, where .icon-badge's own sizing works as-is; only the inner
   .elementor-icon and its svg need bridging.
   -------------------------------------------------------------------------- */

.elementor-widget-icon.icon-badge .elementor-icon {
  display: grid;
  place-items: center;
  width: 100%;
  height: 100%;
  color: inherit;
  font-size: inherit;
}

.elementor-widget-icon.icon-badge svg {
  width: 1.6rem;
  height: 1.6rem;
}


/* --------------------------------------------------------------------------
   4. CONTAINERS = SECTIONS
   --------------------------------------------------------------------------
   The design system's section and container classes go straight onto
   Elementor Containers, where they work unchanged — a Container IS a div.

   Usage:  Container > Advanced > CSS Classes:  section section--sand
                                                card card--hover
                                                callout
                                                split split--reverse

   The only fix needed is neutralising Elementor's default padding so the
   design system's own spacing applies. Set the Container's padding to 0 in
   the Layout tab, or rely on the rule below.
   -------------------------------------------------------------------------- */

.e-con.section,
.e-con.card,
.e-con.callout,
.e-con.cta-band,
.e-con.page-head {
  --padding-top: 0;
  --padding-right: 0;
  --padding-bottom: 0;
  --padding-left: 0;
}

/* Boxed containers already centre themselves; stop double-constraining when
   the `container` class is also applied. */
.e-con.container > .e-con-inner {
  max-width: none;
  padding: 0;
}


/* --------------------------------------------------------------------------
   4b. CTA BAND
   --------------------------------------------------------------------------
   main.css:1002. Two columns: copy left, actions right.

   .cta-band__inner is a GRID. Elementor containers are flex and emit
   `display: var(--display)` with --display:flex at high specificity, so the
   grid never takes effect and the three blocks stack instead.

   STRUCTURE — cta-band__inner must have exactly TWO children:
       Container            copy: eyebrow, H2, lede
       Container [cta-band__actions]
           Text Editor [cta-phone]
           Container [btn-row]  ->  Button [btn--light]

   Three children makes it a three-column grid and the layout falls apart.
   -------------------------------------------------------------------------- */

/* BOXED CONTAINERS HAVE AN INNER WRAPPER.
   A container set to Content Width: Boxed renders as

       <div class="e-con e-con-boxed cta-band__inner">
         <div class="e-con-inner">          <- the children actually live here
           ...
         </div>
       </div>

   Making only the outer element a grid gives you a grid with ONE child, and
   the real children stack inside the flex wrapper. Target both, so it works
   whether the container is Boxed or Full Width. */
.e-con.cta-band__inner,
.e-con.cta-band__inner > .e-con-inner {
  display: grid !important;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 24rem), 1fr));
  gap: clamp(2rem, 5vw, 4rem);
  align-items: center;
}

.e-con.cta-band__actions,
.e-con.cta-band__actions > .e-con-inner {
  display: flex !important;
  flex-direction: column;
  gap: 1.25rem;
  align-items: flex-start;
}

@media (min-width: 62rem) {
  .e-con.cta-band__actions,
  .e-con.cta-band__actions > .e-con-inner {
    align-items: flex-end;
    text-align: right;
  }
}

/* --- STOP THE MAGNETIC EFFECT DRAGGING THE WHOLE WIDGET ------------------
   initMagnetic() (main.js:285) selects `.btn--primary, .btn--light` and
   writes an inline transform so the button drifts toward the cursor.

   On the static site those classes are on the <a> itself. In Elementor they
   land on the widget WRAPPER, so the whole widget slides — and any container
   sized around it appears to move with the pointer.

   An author !important beats a non-important inline style, so this pins the
   wrapper. infocus-elementor.js then re-applies the drift to the inner
   .elementor-button, which is what should have been moving all along. */
.elementor-widget-button.btn--primary,
.elementor-widget-button.btn--light,
.elementor-widget-button.btn--outline,
.elementor-widget-button.btn--ghost-light {
  transform: none !important;
}

/* --- AND THE HOVER SHADOW MUST NOT LAND ON THE WRAPPER EITHER ------------
   main.css:264 attaches the shadow to the modifier class:

       .btn--light:hover { box-shadow: 0 8px 24px rgba(0, 0, 0, .28); }

   On the static site that class is on the <a>, so the shadow traces a 169px
   pill. In Elementor it is on the WRAPPER, which stretches to the full width
   of its flex column — measured at 488px in the CTA band. The result is a
   large soft rectangle appearing and vanishing as the pointer crosses the
   column, nowhere near the button.

   Kill it on the wrapper. The matching `.elementor-button:hover` rules above
   already put the correct shadow on the pill itself. */
.elementor-widget-button.btn--primary:hover,
.elementor-widget-button.btn--light:hover,
.elementor-widget-button.btn--outline:hover,
.elementor-widget-button.btn--ghost-light:hover,
.elementor-widget-button.btn--primary:focus-within,
.elementor-widget-button.btn--light:focus-within {
  box-shadow: none !important;
}

/* The wrapper stretching full-width is harmless once it paints nothing, but
   shrinking it to the button keeps hit-testing honest — hover states then
   trigger over the button rather than anywhere in the column. */
.elementor-widget-button.btn--primary,
.elementor-widget-button.btn--light,
.elementor-widget-button.btn--outline,
.elementor-widget-button.btn--ghost-light {
  width: fit-content;
  max-width: 100%;
}

/* Same reason, one level up: an Elementor container defaults to --width:100%,
   so a `btn-row` inside a column-flex block fills it and `align-items:
   flex-end` has nothing left to push. Let it shrink to its buttons. */
.e-con.cta-band__actions > .e-con,
.e-con.btn-row {
  width: auto;
  max-width: 100%;
}


/* --- THE :not(.btn) GUARD DOESN'T KNOW ABOUT ELEMENTOR -------------------
   main.css tints links on dark backgrounds:

       .page-head a:not(.btn),
       .section--dark a:not(.btn),
       .hero a:not(.btn)        { color: var(--bronze-400); }

   The guard exempts buttons because on the static site they are
   <a class="btn btn--light">. Elementor renders <a class="elementor-button">,
   which the guard does not recognise — so every button inside a dark section
   or a page header turns bronze instead of using --btn-fg.

   That selector is (0,2,1); the base button rule is (0,2,0), so it loses.

   There is a matching hover rule too:

       .page-head a:not(.btn):hover,
       .section--dark a:not(.btn):hover,
       .hero a:not(.btn):hover  { color: #fff; }

   which is (0,3,1) — `:not(.btn)` counts as a class, plus `:hover`, plus the
   `a` element. Beating that needs (0,4,0), hence the extra class in the
   hover selectors below. Both states must be covered or the button reads
   correctly at rest and turns white the moment you point at it. */
.page-head .elementor-widget-button .elementor-button,
.section--dark .elementor-widget-button .elementor-button,
.hero .elementor-widget-button .elementor-button,
.cta-band .elementor-widget-button .elementor-button,
.page-head .elementor-widget-button .elementor-button:hover,
.section--dark .elementor-widget-button .elementor-button:hover,
.hero .elementor-widget-button .elementor-button:hover,
.cta-band .elementor-widget-button .elementor-button:hover,
.page-head .elementor-widget-button .elementor-button:focus,
.section--dark .elementor-widget-button .elementor-button:focus,
.hero .elementor-widget-button .elementor-button:focus,
.cta-band .elementor-widget-button .elementor-button:focus {
  color: var(--btn-fg);
}

/* The phone number. main.css:1008 sets this on the <a> itself; in Elementor
   the class sits on a Text Editor wrapper, so the link inside inherits the
   theme's link colour (bronze) instead of white. Push it down explicitly. */
.cta-phone a,
.cta-phone .elementor-widget-container > p > a {
  display: inline-flex;
  align-items: center;
  gap: .75rem;
  font-family: var(--font-display);
  font-size: var(--step-3);
  font-weight: 600;
  color: #fff;
  letter-spacing: -0.02em;
  text-decoration: none;
}

.cta-phone a:hover { color: var(--bronze-400); }

.cta-phone a .icon,
.cta-phone svg {
  width: 1.5rem;
  height: 1.5rem;
  color: var(--bronze-400);
  flex: none;
}

/* Text Editor wraps content in <p>; strip its margin so the phone sits on the
   flex baseline rather than a paragraph block. */
.cta-phone .elementor-widget-container > p { margin: 0; }


/* --------------------------------------------------------------------------
   5. ICON LISTS
   --------------------------------------------------------------------------
   Usage:  Icon List widget > Advanced > CSS Classes:  check-grid
                                                       bullet-list
   -------------------------------------------------------------------------- */

/* --- CHECK GRID ---------------------------------------------------------
   Mirrors main.css:1730 exactly. Every value here is copied from there —
   if they drift, the tiles stop matching the original.

   The class lands on the widget WRAPPER, so `.check-grid` never reaches the
   <ul> that needs to become the grid, nor the <svg> that needs to be crimson.
   Both are bridged below.

   Usage: Icon List > Advanced > CSS Classes: check-grid icons--stroke
          every item's icon: check.svg  (Upload SVG)
   -------------------------------------------------------------------------- */

.elementor-widget-icon-list.check-grid .elementor-icon-list-items {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 19rem), 1fr));
  gap: .875rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

/* Inside the 46rem reading column, two columns beat three (main.css:1273). */
.v2-col .elementor-widget-icon-list.check-grid .elementor-icon-list-items {
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
}

/* Each item is a bordered tile, not a plain list row.

   DELIBERATELY NO `background` HERE.

   main.css layers three background rules on these tiles:

       .check-grid li                     background: var(--paper)   (0,1,1)
       body.v2 .check-grid li             white -> sand gradient     (0,2,2)
       body.v2 .section--sand .check-grid li   a warmer variant      (0,3,2)

   Declaring `background: var(--paper)` here would sit at (0,3,0) and beat the
   v2 gradient — but NOT the :hover rule at (0,3,2). The tiles then render
   flat white at rest and only pick up their shading on hover.

   Leaving background out lets that cascade resolve as designed. The resting
   box-shadow (--shadow-sm) arrives the same way. */
.elementor-widget-icon-list.check-grid .elementor-icon-list-item {
  display: flex;
  gap: .75rem;
  align-items: flex-start;
  margin: 0;
  padding: 1rem 1.15rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  font-size: .95rem;
  line-height: 1.55;
  color: var(--ink-500);
}

.elementor-widget-icon-list.check-grid .elementor-icon-list-icon {
  flex: none;
  margin-top: .25rem;
  padding: 0;
}

/* THE TICK. Crimson, 1.1rem, stroked — not grey and not 1.25em.
   !important because Elementor sizes list icons through the custom property
   --e-icon-list-icon-size, which a plain selector cannot outrank. */
.elementor-widget-icon-list.check-grid .elementor-icon-list-icon svg {
  width: 1.1rem !important;
  height: 1.1rem !important;
  color: var(--crimson) !important;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Elementor centres the text against the icon, per item:

       .elementor-widget .elementor-icon-list-icon + .elementor-icon-list-text
         { align-self: center; padding-inline-start: 5px; }

   In a grid the tiles stretch to the tallest row, so a short entry ends up
   with its text floating in the middle while the tick stays at the top.
   main.css puts `align-items: flex-start` on the li, but a per-item
   align-self beats the container's align-items every time.

   The 5px inline padding also stacks on top of the .75rem gap, giving 17px
   between tick and text instead of 12px. */
.elementor-widget-icon-list.check-grid .elementor-icon-list-icon + .elementor-icon-list-text {
  align-self: flex-start;
  padding-inline-start: 0;
}

.elementor-widget-icon-list.check-grid .elementor-icon-list-text {
  white-space: normal;
  color: inherit;
  font-size: inherit;
  line-height: inherit;
  padding: 0;
}

.elementor-widget-icon-list .elementor-icon-list-icon svg {
  width: 1.25em;
  height: 1.25em;
}

/* IMPORTANT — two incompatible icon styles.
   --------------------------------------------------------------------------
   The 29 Infocus sprite icons are STROKE-based outlines:
       fill: none; stroke: currentColor; stroke-width: 1.6

   Elementor's built-in library (Font Awesome) is FILL-based solid shapes
   with no stroke at all. Applying the stroke treatment to one of those sets
   fill:none on a shape that has nothing to stroke — the icon renders, but
   completely transparent.

   So the stroke treatment is OPT-IN. Add the CSS class `icons--stroke` to an
   Icon List (or any icon widget) ONLY when its icons are uploaded Infocus
   SVGs. Leave it off for Font Awesome icons. */
.icons--stroke .elementor-icon-list-icon svg,
.icons--stroke .elementor-icon svg,
svg.infocus-icon {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}


/* --------------------------------------------------------------------------
   6. ACCORDION  (Elementor "Nested Accordion", widget type n-accordion)
   --------------------------------------------------------------------------
   Reproduces main.css:1337-1385 (.accordion) on the markup Nested Accordion
   renders:

     div.elementor-widget-n-accordion.accordion
       div.e-n-accordion
         details.e-n-accordion-item                     <- .accordion__item
           summary.e-n-accordion-item-title             <- .accordion__trigger
             span.e-n-accordion-item-title-header
               h2.e-n-accordion-item-title-text
             span.e-n-accordion-item-title-icon         <- .accordion__icon
               span.e-closed  (plus)
               span.e-opened  (minus)
           div.e-con                                    <- .accordion__panel

   The widget is driven almost entirely by --n-accordion-* custom properties,
   so most of the work here is setting values rather than out-specifying
   selectors. Only the pieces Elementor hardcodes (the icon ring, the item
   hairline, the plus/minus swap) need real rules.

   NOT the legacy "Accordion" widget. That one renders .elementor-accordion
   with .elementor-tab-title / .elementor-tab-content and shares no class
   names with this. A compatibility tail for it sits at the end of the
   section, in case an older page still uses it.

   WHY !important ON THE CUSTOM PROPERTIES
   Elementor emits per-widget defaults into the page's generated stylesheet
   for every nested accordion, whether or not the Style tab was touched:

     .elementor-80 .elementor-element.elementor-element-9b863f9 {
       --n-accordion-title-font-size: 2rem;
       --n-accordion-icon-size: 15px; }

   That selector is (0,3,0) and it is page-specific, so a plain declaration
   here loses on every page. !important on the custom property is the cheapest
   way to win, and it enforces the site rule anyway: appearance lives in CSS,
   never in the Style tab. The client can type in the Style tab all day and
   the page will not budge.
   -------------------------------------------------------------------------- */

.elementor-widget-n-accordion {

  /* Borders ---------------------------------------------------------------
     main.css draws ONE hairline under each item and one above the whole set.
     Elementor instead applies --n-accordion-border-width as a border-width
     LONGHAND on the title, and via a :where() rule on the panel container —
     giving the full box you get out of the tin. Zero it here and draw the
     single line on the <details> further down. */
  --n-accordion-border-width: 0 !important;
  --n-accordion-border-color: var(--line) !important;

  /* .accordion__trigger { padding: 1.35rem 0 } */
  --n-accordion-padding: 1.35rem 0 !important;

  /* .accordion__trigger type. Family and weight have no custom property, so
     they are set on the title element below. */
  --n-accordion-title-font-size: var(--step-1) !important;
  --n-accordion-title-normal-color: var(--ink) !important;
  --n-accordion-title-hover-color: var(--crimson) !important;
  --n-accordion-title-active-color: var(--ink) !important;

  /* Elementor ships order:-1 on the icon, which is why it renders to the LEFT
     of the title even though it comes second in the DOM. Reset the order and
     let space-between push it to the far edge. */
  --n-accordion-title-icon-order: 0 !important;
  --n-accordion-title-justify-content: space-between !important;
  --n-accordion-icon-gap: 0 1.5rem !important;

  /* .accordion__icon .icon { width: .9rem } — this sizes the GLYPH. The 2rem
     ring around it is drawn on the wrapper below. */
  --n-accordion-icon-size: .9rem !important;
  --n-accordion-icon-normal-color: var(--crimson) !important;
  --n-accordion-icon-hover-color: var(--crimson) !important;
  --n-accordion-icon-active-color: #fff !important;

  /* Items butt together; the hairline is the only separator. */
  --n-accordion-item-title-space-between: 0 !important;
  --n-accordion-item-title-distance-from-content: 0 !important;
}


/* .accordion { border-top: 1px solid var(--line) } */
.elementor-widget-n-accordion .e-n-accordion {
  border-top: 1px solid var(--line);
}

/* .accordion__item { border-bottom: 1px solid var(--line) } */
.elementor-widget-n-accordion .e-n-accordion > .e-n-accordion-item {
  border-bottom: 1px solid var(--line);
}


/* --------------------------------------------------------------------------
   The trigger
   --------------------------------------------------------------------------
   Elementor sets colour on the <summary>, but main.css sets colour on h2
   elements directly — so the heading does NOT inherit the summary's colour
   and --n-accordion-title-*-color alone leaves it black. Colour has to be
   applied to the title element itself, including the hover state.
   -------------------------------------------------------------------------- */

.elementor-widget-n-accordion .e-n-accordion .e-n-accordion-item-title-text {
  font-family: var(--font-display);
  font-weight: 600;
  line-height: 1.35;
  color: var(--ink);
  margin: 0;
  text-align: left;
  transition: color .18s var(--ease);
}

/* Take the slack so space-between pins the icon to the right edge. */
.elementor-widget-n-accordion .e-n-accordion .e-n-accordion-item-title-header {
  flex: 1 1 auto;
  min-width: 0;
}

/* .accordion__trigger:hover { color: var(--crimson) }
   Scoped to the summary, not the <details> — hovering the open panel below
   must not tint the heading. */
.elementor-widget-n-accordion .e-n-accordion .e-n-accordion-item-title:hover .e-n-accordion-item-title-text {
  color: var(--crimson);
}


/* --------------------------------------------------------------------------
   The icon ring
   -------------------------------------------------------------------------- */

/* .accordion__icon — Elementor gives this width:fit-content and no border. */
.elementor-widget-n-accordion .e-n-accordion .e-n-accordion-item-title-icon {
  flex: none;
  width: 2rem;
  height: 2rem;
  display: grid;
  place-items: center;
  border: 1px solid var(--line);
  border-radius: 50%;
  transition: transform .3s var(--ease),
              background-color .2s var(--ease),
              border-color .2s var(--ease);
}

/* Elementor swaps the plus for a minus when the item opens. v2 keeps the plus
   and rotates it 45deg into a cross, so hold the plus visible in both states
   and let the transform do the work.

   Elementor's swap rules are (0,6,0) — e.g.
     .elementor-widget-n-accordion .e-n-accordion-item[open]
       > .e-n-accordion-item-title .e-n-accordion-item-title-icon .e-opened
   Matching that by specificity alone would still depend on which stylesheet
   loads last, and Elementor's per-widget CSS is not reliably before ours.
   Two !important declarations settle it in every load order. */
.elementor-widget-n-accordion .e-n-accordion .e-n-accordion-item-title-icon .e-opened { display: none !important; }
.elementor-widget-n-accordion .e-n-accordion .e-n-accordion-item-title-icon .e-closed { display: flex !important; }

/* .accordion__trigger[aria-expanded="true"] .accordion__icon */
.elementor-widget-n-accordion .e-n-accordion .e-n-accordion-item[open] > .e-n-accordion-item-title .e-n-accordion-item-title-icon {
  transform: rotate(45deg);
  background: var(--crimson);
  border-color: var(--crimson);
}


/* --------------------------------------------------------------------------
   The panel
   --------------------------------------------------------------------------
   Nested Accordion renders each panel as a real Elementor child container, so
   it arrives with the usual container padding. Strip it and restore the
   1.5rem tail from main.css (.accordion__panel > div > *:last-child).
   -------------------------------------------------------------------------- */

.elementor-widget-n-accordion .e-n-accordion .e-n-accordion-item > .e-con {
  --padding-top: 0;
  --padding-right: 0;
  --padding-bottom: 1.5rem;
  --padding-left: 0;
}

/* .accordion__panel p, .accordion__panel ul { color: var(--ink-500);
   font-size: .975rem } — answers run one step smaller than body copy. */
.elementor-widget-n-accordion .e-n-accordion .e-n-accordion-item > .e-con p,
.elementor-widget-n-accordion .e-n-accordion .e-n-accordion-item > .e-con ul,
.elementor-widget-n-accordion .e-n-accordion .e-n-accordion-item > .e-con li {
  color: var(--ink-500);
  font-size: .975rem;
}


/* --------------------------------------------------------------------------
   Keyboard and native chrome
   -------------------------------------------------------------------------- */

.elementor-widget-n-accordion .e-n-accordion summary { list-style: none; }
.elementor-widget-n-accordion .e-n-accordion summary::-webkit-details-marker { display: none; }

/* <summary> is focusable. Elementor's default ring is faint against the
   hairlines; make it obvious. */
.elementor-widget-n-accordion .e-n-accordion .e-n-accordion-item-title:focus-visible {
  outline: 2px solid var(--crimson);
  outline-offset: 3px;
}


/* --------------------------------------------------------------------------
   Legacy "Accordion" widget — compatibility only
   --------------------------------------------------------------------------
   Kept in case an older page still holds one. New pages should use Nested
   Accordion; everything above applies to that.
   -------------------------------------------------------------------------- */

.elementor-accordion .elementor-accordion-item {
  border: 0;
  border-bottom: 1px solid var(--line);
}

.elementor-accordion .elementor-tab-title {
  padding: 1.35rem 0;
  font-family: var(--font-display);
  font-size: var(--step-1);
  font-weight: 600;
  color: var(--ink);
  background: transparent;
}

.elementor-accordion .elementor-tab-title:hover,
.elementor-accordion .elementor-tab-title.elementor-active {
  color: var(--crimson);
}

.elementor-accordion .elementor-tab-content {
  padding: 0 0 1.5rem;
  border: 0;
  color: var(--ink-500);
}


/* --------------------------------------------------------------------------
   6b. COURSE LISTINGS
   --------------------------------------------------------------------------
   Reproduces main.css:1216-1259 on Elementor containers.

     Container  .course-listings          <- the grid
       Container  .course-listing         <- one card
         Heading H3
         Text Editor  .course-listing__note      (optional)
         Text Editor  .course-listing__price
         Container    .course-listing__actions
           Button     .btn .btn--primary         ("Enrol")
           Text Editor holding <a class="link-arrow">  (optional)

   NOT bridged, deliberately:

     .link-arrow   Paste it as a raw <a class="link-arrow"> inside a Text
                   Editor. The class then sits on the anchor itself, exactly
                   as main.css:278 expects, and needs no rule here. Using a
                   Button widget instead would put the class on a wrapper and
                   drag .elementor-button's styling in with it.

     .unit-list    Paste the whole <dl class="unit-list"> into an HTML widget.
                   The markup is dl > div > dt + dd; main.css:1195 styles it
                   completely and the classes land where it expects them.
   -------------------------------------------------------------------------- */

/* The grid. Same shape as .footer__main and .cta-band__inner: Elementor
   containers are flex, so force grid — and target the Boxed inner wrapper
   too, or the cards stack inside a single grid cell. */
.e-con.course-listings,
.e-con.course-listings > .e-con-inner {
  --gap: 1rem !important;
  --row-gap: 1rem !important;
  --column-gap: 1rem !important;
  display: grid !important;
  gap: 1rem;
  grid-template-columns: 1fr;
}

/* 44rem = 704px. Sits between Elementor's Mobile Portrait (860) and its
   defaults, and needs no Elementor responsive setting — main.css owns it. */
@media (min-width: 44rem) {
  .e-con.course-listings,
  .e-con.course-listings > .e-con-inner {
    grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr));
  }
}


/* The card.
   --------------------------------------------------------------------------
   Unlike a widget class, a container class lands on the .e-con element that
   is actually painted — so background, border, radius and box-shadow from
   main.css:1225 apply with no help. Only two things need attention: padding,
   which Elementor drives through custom properties at higher specificity,
   and the flex column, so `margin-top: auto` on the actions row works. */
.e-con.course-listing {
  /* body.v2 raises only the TOP padding, to clear the 3px gradient rule. */
  --padding-top: clamp(1.5rem, 3vw, 1.9rem) !important;
  --padding-right: clamp(1.25rem, 2.5vw, 1.6rem) !important;
  --padding-bottom: clamp(1.25rem, 2.5vw, 1.6rem) !important;
  --padding-left: clamp(1.25rem, 2.5vw, 1.6rem) !important;
}

.e-con.course-listing,
.e-con.course-listing > .e-con-inner {
  display: flex !important;
  flex-direction: column;
  gap: .6rem;
}

/* If the card was left on Content Width "Boxed", the inner wrapper is the
   real flex column and must fill the card's height — otherwise the actions
   row has no slack to be pushed into and `margin-top: auto` does nothing.
   Harmless on a Full Width card, where no inner wrapper exists. */
.e-con.course-listing > .e-con-inner {
  flex: 1 1 auto;
}


/* Card title.
   main.css:1235 (`.course-listing h3`) already reaches the inner heading —
   it is a real <h3> and the selector is (0,1,1), which beats `h3 {}`. So the
   size and colour arrive on their own. Only the margin needs undoing: §2
   above gives every heading `0 0 .6em` at (0,2,0), and inside a card the
   spacing comes from the flex gap instead. */
.course-listing .elementor-widget-heading .elementor-heading-title {
  margin: 0;
}


/* Price and note.
   The classes land on the Text Editor wrapper, where font-family, size and
   colour all inherit down to the <p> correctly. Margin does not inherit, and
   `p { margin: 0 0 1.15em }` (main.css:0,0,1) still applies to it — so the
   card gains an extra 1.15em under every paragraph. This is the only value
   worth restating. */
.course-listing__price p,
.course-listing__note p {
  margin: 0;
}


/* Actions row — main.css:1252, plus the body.v2 overrides that add the
   1.1rem top padding and the hairline above it.

   SET ELEMENTOR'S VARIABLES, NOT THE PROPERTIES.
   Elementor re-reads three of these from rules that tie this file on
   specificity and load after it, so a direct declaration silently loses:

     --flex-direction  `.e-con.e-flex { --flex-direction: column }` (0,2,0)
                       feeds `.e-con-full.e-flex { flex-direction:
                       var(--flex-direction) }` (0,2,0). Declaring
                       `flex-direction: row` here ties and loses on order —
                       which is why the Enrol button and the PDF link stack
                       vertically and centre themselves.

     --margin-top      `.e-con` maps --margin-top -> --margin-block-start ->
                       margin-block-start. A plain `margin-top: auto` never
                       reaches the element, so the row stops being pinned to
                       the bottom and cards in a row lose their alignment.

     --gap             same pattern; set alongside the shorthand so both
                       paths agree.

   `margin-top: auto` is what makes two cards of unequal height line their
   Enrol buttons up along the bottom edge. */
.e-con.course-listing__actions {
  --flex-direction: row !important;
  --margin-top: auto !important;
  --gap: .75rem 1.25rem !important;
  --row-gap: .75rem !important;
  --column-gap: 1.25rem !important;

  --padding-top: 1.1rem !important;
  --padding-right: 0 !important;
  --padding-bottom: 0 !important;
  --padding-left: 0 !important;
}

.e-con.course-listing__actions,
.e-con.course-listing__actions > .e-con-inner {
  display: flex !important;
  flex-wrap: wrap;
  align-items: center;
  gap: .75rem 1.25rem;
}

/* Widgets inside a column container inherit `--container-widget-width: 100%`,
   which stretches the button wrapper across the card and centres the button
   inside it. In a row they must size to their own content. */
.e-con.course-listing__actions > .elementor-widget {
  --container-widget-width: auto;
  width: auto;
  flex: 0 0 auto;
}


/* The resting glow on a card's primary button (main.css, body.v2 block).
   `.btn--primary` sits on the Elementor WRAPPER — a box with no background —
   so the shadow floats around the widget instead of hugging the pill. Move it
   onto the painted element.

   The card-hover shadow deliberately outranks §1's button-hover shadow, which
   is also how it resolves on the static site: (0,4,1) there beats `.btn:hover`
   at (0,2,0). */
body.v2 .course-listing .elementor-widget-button.btn--primary {
  box-shadow: none;
}

body.v2 .course-listing .elementor-widget-button.btn--primary .elementor-button {
  box-shadow: 0 2px 10px rgba(154, 1, 48, .22);
}

body.v2 .course-listing:hover .elementor-widget-button.btn--primary .elementor-button {
  box-shadow: 0 6px 18px rgba(154, 1, 48, .3);
}



/* --------------------------------------------------------------------------
   6c. SECTION HEAD
   --------------------------------------------------------------------------
   A centred eyebrow + title block above a grid. Container class.

     Container  .section-head .section-head--center
       Text Editor  .eyebrow
       Heading H2   .course-picker__title
   -------------------------------------------------------------------------- */

.e-con.section-head {
  max-width: 46rem;
  /* margin-bottom must go through Elementor's variable — see 6b for why a
     plain declaration loses. */
  --margin-bottom: clamp(2rem, 4vw, 3rem) !important;
}

.e-con.section-head--center {
  margin-inline: auto;
  text-align: center;
}

/* .eyebrow is inline-flex with a ::before dash; centring its contents keeps
   the dash beside the text rather than at the far left of the block. */
.section-head--center .elementor-widget.eyebrow {
  justify-content: center;
}

/* `.course-picker__title` — same wrapper problem as .v2-heading in §2, and
   the same fix: inherit the size the wrapper already resolved. */
.elementor-widget-heading.course-picker__title .elementor-heading-title {
  font-size: inherit;
  margin: 0;
  text-transform: none;
}


/* --------------------------------------------------------------------------
   6d. COURSE PICKER AND COURSE TILES
   --------------------------------------------------------------------------
     Container  .course-picker
       Container  .course-tile            <- Link set on the container
         Container  .course-tile__media
           Image
         Container  .course-tile__body
           Text Editor  .course-tile__badge  (+ --nrt on two of three)
           Heading H3
           Text Editor
           Container  .course-tile__foot
             Text Editor  .course-tile__price
             Text Editor  holding <span class="link-arrow">

   Most of the paint arrives on its own: a container class lands on the .e-con
   element itself, so background, border, radius, shadow, overflow and the
   hover transform in main.css all apply unchanged. What needs help is
   everything Elementor drives through custom properties.
   -------------------------------------------------------------------------- */

.e-con.course-picker,
.e-con.course-picker > .e-con-inner {
  --gap: clamp(1rem, 2.5vw, 1.75rem) !important;
  --row-gap: clamp(1rem, 2.5vw, 1.75rem) !important;
  --column-gap: clamp(1rem, 2.5vw, 1.75rem) !important;
  display: grid !important;
  grid-template-columns: 1fr;
  gap: clamp(1rem, 2.5vw, 1.75rem);
}

@media (min-width: 48rem) {
  .e-con.course-picker,
  .e-con.course-picker > .e-con-inner { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (min-width: 68rem) {
  .e-con.course-picker,
  .e-con.course-picker > .e-con-inner { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* The tile. main.css paints it; only Elementor's own padding is in the way. */
.e-con.course-tile {
  /* main.css gives the tile NO gap; Elementor containers default to 20px,
     which would float the image off the body. */
  --gap: 0 !important;
  --row-gap: 0 !important;
  --column-gap: 0 !important;
  --padding-top: 0 !important;
  --padding-right: 0 !important;
  --padding-bottom: 0 !important;
  --padding-left: 0 !important;
  --flex-direction: column !important;
}

/* Elementor renders a linked container as <a class="e-con">. Stop it picking
   up link colour from the section it sits in. */
.e-con.course-tile,
.e-con.course-tile:hover {
  color: inherit;
  text-decoration: none;
}

.e-con.course-tile__media {
  --gap: 0 !important;
  --row-gap: 0 !important;
  --column-gap: 0 !important;
  --padding-top: 0 !important;
  --padding-right: 0 !important;
  --padding-bottom: 0 !important;
  --padding-left: 0 !important;
}

/* The image must fill the 16:10 box. Elementor puts two wrappers between the
   container and the <img>, and a percentage height needs an unbroken chain of
   heights to resolve against — so both wrappers get one. */
.e-con.course-tile__media > .elementor-widget-image,
.e-con.course-tile__media > .elementor-widget-image > .elementor-widget-container {
  width: 100%;
  height: 100%;
}

.e-con.course-tile__body {
  --padding-top: clamp(1.25rem, 2.5vw, 1.6rem) !important;
  --padding-right: clamp(1.25rem, 2.5vw, 1.6rem) !important;
  --padding-bottom: clamp(1.25rem, 2.5vw, 1.6rem) !important;
  --padding-left: clamp(1.25rem, 2.5vw, 1.6rem) !important;
  --flex-direction: column !important;
  --gap: .6rem !important;
  --row-gap: .6rem !important;
  --column-gap: .6rem !important;
  /* `flex: 1` in main.css — Elementor composes flex from three variables. */
  --flex-grow: 1 !important;
}

/* The badge is a pill, so the painted element must shrink to its text.
   align-self does that inside the body's flex column. */
.elementor-widget-text-editor.course-tile__badge {
  align-self: flex-start;
}

/* Elementor's Text Editor wraps its content in a <p>. On the static site the
   badge and the price are <span>s, so `.course-tile__body p` — the rule that
   sizes the description and clamps it to four lines — never touched them.
   Here it captures all three, and beats the badge and price classes because
   those sit on the WRAPPER and only reach the <p> by inheritance, which any
   direct rule outranks.

   Hand each inner <p> back to its wrapper. `font: inherit` covers size,
   weight and leading in one; the clamp and its display mode have to be undone
   by name. "View course" needs none of this — it is pasted as a real <span>,
   which is why it was the only one of the three that looked right. */
.elementor-widget-text-editor.course-tile__badge p,
.elementor-widget-text-editor.course-tile__price p {
  margin: 0;
  font: inherit;
  color: inherit;
  display: block;
  overflow: visible;
  -webkit-line-clamp: none;
}

/* Card title — main.css:  .course-tile__body h3 { font-size: var(--step-1);
   margin: 0 }. The size reaches the real <h3> on its own; §2's blanket
   `0 0 .6em` margin does not get undone by it. */
.course-tile__body .elementor-widget-heading .elementor-heading-title {
  margin: 0;
}

/* Footer row: same three variables as the course-listing actions row in §6b.
   margin-top:auto is what lines the prices up across tiles of unequal text. */
.e-con.course-tile__foot {
  --flex-direction: row !important;
  --margin-top: auto !important;
  --gap: 1rem !important;
  --row-gap: 1rem !important;
  --column-gap: 1rem !important;
  --padding-top: 1rem !important;
  --padding-right: 0 !important;
  --padding-bottom: 0 !important;
  --padding-left: 0 !important;
}

.e-con.course-tile__foot,
.e-con.course-tile__foot > .e-con-inner {
  display: flex !important;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}

.e-con.course-tile__foot > .elementor-widget {
  --container-widget-width: auto;
  width: auto;
  flex: 0 0 auto;
}


/* --------------------------------------------------------------------------
   6e. TEAM GRID AND TEAM CARDS
   --------------------------------------------------------------------------
     Container  .team-grid
       Container  .team-card
         Container  .team-card__media
           Image
         Container  .team-card__body
           Heading H3                       <- see the note below
           Text Editor  .team-card__role
           Button       .team-card__toggle  + attribute data-dialog-open|bio-N

   The five <dialog> elements go in one HTML widget at the end of the section.
   Their styling is already covered by main.css plus the close-button rule
   further up this file.

   HEADING LEVEL: the source marks the names <h2>, but main.css only ever
   styles `.team-card h3` — there is no `.team-card h2` rule anywhere. On the
   static site the names therefore render at the global h2 size, var(--step-4),
   which is up to 3.15rem inside a 16.5rem card. Build them as H3 so the CSS
   that was written for them actually applies.
   -------------------------------------------------------------------------- */

.e-con.team-grid,
.e-con.team-grid > .e-con-inner {
  --gap: clamp(1.5rem, 3vw, 2.25rem) !important;
  --row-gap: clamp(1.5rem, 3vw, 2.25rem) !important;
  --column-gap: clamp(1.5rem, 3vw, 2.25rem) !important;
  display: grid !important;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 16.5rem), 1fr));
  gap: clamp(1.5rem, 3vw, 2.25rem);
  /* so a taller card never stretches its neighbours */
  align-items: start;
}

.e-con.team-card {
  --gap: 0 !important;
  --row-gap: 0 !important;
  --column-gap: 0 !important;
  --padding-top: 0 !important;
  --padding-right: 0 !important;
  --padding-bottom: 0 !important;
  --padding-left: 0 !important;
  --flex-direction: column !important;
}

.e-con.team-card__media {
  --gap: 0 !important;
  --row-gap: 0 !important;
  --column-gap: 0 !important;
  --padding-top: 0 !important;
  --padding-right: 0 !important;
  --padding-bottom: 0 !important;
  --padding-left: 0 !important;
}

.e-con.team-card__media > .elementor-widget-image,
.e-con.team-card__media > .elementor-widget-image > .elementor-widget-container {
  width: 100%;
  height: 100%;
}

.e-con.team-card__body {
  --padding-top: clamp(1.25rem, 2.5vw, 1.6rem) !important;
  --padding-right: clamp(1.25rem, 2.5vw, 1.6rem) !important;
  --padding-bottom: clamp(1.25rem, 2.5vw, 1.6rem) !important;
  --padding-left: clamp(1.25rem, 2.5vw, 1.6rem) !important;
}

/* .team-card h3 { font-size: var(--step-1); margin-bottom: .2rem } — the size
   reaches the heading; the margin needs restating against §2. */
.team-card .elementor-widget-heading .elementor-heading-title {
  margin: 0 0 .2rem;
}

/* .team-card__role has exactly the same problem as the course-tile badge:
   `.team-card p { font-size: .93rem; color: var(--ink-500) }` in main.css hits
   the <p> Elementor generates, so the role would render as grey body text
   instead of the small uppercase crimson label its own class describes. On the
   static site the role is a <p class="team-card__role"> — the class is ON the
   paragraph, so nothing else could reach it. */
.elementor-widget-text-editor.team-card__role p {
  margin: 0;
  font: inherit;
  color: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
}

/* --- EQUAL CARD HEIGHTS ---------------------------------------------------
   main.css sets `align-items: start` on .team-grid, with the comment "so
   expanding one bio doesn't stretch its neighbours". That was written for the
   v1 card, which expanded a bio inline via .team-card__panel. In v2 the bio
   opens in a modal <dialog> and nothing expands in place — so the only thing
   `start` still does is leave a card short whenever its role fits on one line
   where its neighbours' wrap to two.

   Stretch the row instead, let the body absorb the difference, and pin the
   toggle to the bottom so every "Read bio" lines up across the row. */
.e-con.team-grid,
.e-con.team-grid > .e-con-inner {
  align-items: stretch;
}

.e-con.team-card__body {
  --flex-grow: 1 !important;
}

.e-con.team-card__body,
.e-con.team-card__body > .e-con-inner {
  display: flex !important;
  flex-direction: column;
}

.e-con.team-card__body > .elementor-widget-button.team-card__toggle,
.e-con.team-card__body > .e-con-inner > .elementor-widget-button.team-card__toggle {
  margin-top: auto;
}


/* --- BIO DIALOG AVATAR ----------------------------------------------------
   Elementor ships `.elementor img { border-radius: 0; height: auto }` at
   (0,1,1), which outranks `.bio-dialog__avatar` at (0,1,0) — so the avatar
   loses both its 12px corners and its fixed height. The height only looks
   right because the team photos happen to be square; a non-square upload
   would render at its own aspect ratio and object-fit would have nothing to
   crop against.

   Restated here at (0,2,0) because main.css genuinely cannot reach past
   Elementor's rule. Values are copied from main.css unchanged. */
.bio-dialog .bio-dialog__avatar {
  height: clamp(72px, 12vw, 104px);
  border-radius: var(--radius);
}


/* "Read bio" is a Button widget, and §1 paints EVERY .elementor-button as a
   crimson pill — it has no `.btn` guard. This toggle is a plain text link with
   an arrow, so strip the pill back off and let main.css's .team-card__toggle
   rules on the wrapper show through. */
.elementor-widget-button.team-card__toggle .elementor-button {
  padding: 0;
  border: 0;
  border-radius: 0;
  background: none;
  box-shadow: none;
  color: inherit;
  font: inherit;
  letter-spacing: inherit;
}

.elementor-widget-button.team-card__toggle .elementor-button:hover {
  transform: none;
  box-shadow: none;
  color: inherit;
}



/* --------------------------------------------------------------------------
   6f. CONTACT SPLIT
   --------------------------------------------------------------------------
     Container  .contact-split            <- the two-panel card
       Container  .contact-split__aside   <- crimson panel
         Text Editor  .contact-split__lede
         HTML         the <ul class="contact-list">
       Container  .contact-split__form    <- paper panel
         Form widget

   The radius, overflow, shadow and both panel backgrounds land on the .e-con
   elements directly, so main.css handles them. Only the grid and the padding
   need help.
   -------------------------------------------------------------------------- */

.e-con.contact-split,
.e-con.contact-split > .e-con-inner {
  --gap: 0 !important;
  --row-gap: 0 !important;
  --column-gap: 0 !important;
  display: grid !important;
  grid-template-columns: 1fr;
  gap: 0;
}

/* 60rem = 960px. The aside is a fixed 22rem column above it. */
@media (min-width: 60rem) {
  .e-con.contact-split,
  .e-con.contact-split > .e-con-inner {
    grid-template-columns: minmax(0, 22rem) minmax(0, 1fr);
  }
}

.e-con.contact-split__aside,
.e-con.contact-split__form {
  --padding-top: clamp(1.75rem, 4vw, 2.75rem) !important;
  --padding-right: clamp(1.75rem, 4vw, 2.75rem) !important;
  --padding-bottom: clamp(1.75rem, 4vw, 2.75rem) !important;
  --padding-left: clamp(1.75rem, 4vw, 2.75rem) !important;
}

/* The aside's decorative ::after and the v2 noise ::before are positioned
   against the panel, and main.css lifts real content above them with
   `.contact-split__aside > * { position: relative; z-index: 1 }`. That
   selector reaches Elementor's widget wrappers correctly — they are the
   direct children here — so nothing more is needed. */

/* .contact-split__lede is a Text Editor; the class sits on the wrapper and
   size/colour inherit down. Only the paragraph margin has to go. */
.contact-split__lede p {
  margin: 0;
}


/* --------------------------------------------------------------------------
   6g. SECTOR CARDS (home)
   --------------------------------------------------------------------------
     Container  .grid .grid--4
       Container  .sector-card          <- Link set on the container
         Image
         Container  .sector-card__body
           Heading H3                   <- see the note below
           Text Editor  <span class="link-arrow">

   HEADING LEVEL: as with .team-card, the source marks these <h2> while
   main.css only styles `.sector-card h3`. Build them as H3 so the rule
   applies. Same mismatch, same resolution.
   -------------------------------------------------------------------------- */

.e-con.grid,
.e-con.grid > .e-con-inner {
  --gap: clamp(1.25rem, 2.5vw, 2rem) !important;
  --row-gap: clamp(1.25rem, 2.5vw, 2rem) !important;
  --column-gap: clamp(1.25rem, 2.5vw, 2rem) !important;
  display: grid !important;
  grid-template-columns: 1fr;
}

@media (min-width: 40rem) {
  .e-con.grid--4,
  .e-con.grid--4 > .e-con-inner { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (min-width: 76rem) {
  .e-con.grid--4,
  .e-con.grid--4 > .e-con-inner { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

/* main.css declares `.sector-card { display: block }`, which ties Elementor's
   `display: var(--display)` on specificity and loses on load order. Set the
   variable instead — the card is a positioned block that the image fills
   absolutely, not a flex row. */
.e-con.sector-card {
  --display: block !important;
  --padding-top: 0 !important;
  --padding-right: 0 !important;
  --padding-bottom: 0 !important;
  --padding-left: 0 !important;
}

.e-con.sector-card,
.e-con.sector-card:hover {
  color: #fff;
  text-decoration: none;
}

/* The photo is absolutely positioned at z-index -2 behind the gradient, and
   its containing block is .sector-card (position: relative, isolate). It is
   nested two wrappers deep inside an Image widget, but neither wrapper is
   positioned, so `.sector-card img` in main.css still resolves against the
   card. The wrappers only need to stop reserving layout space. */
.e-con.sector-card > .elementor-widget-image,
.e-con.sector-card > .elementor-widget-image > .elementor-widget-container {
  position: static;
  line-height: 0;
}

.e-con.sector-card__body {
  --display: flex !important;
  --flex-direction: column !important;
  --justify-content: flex-end !important;
  --padding-top: clamp(1.5rem, 3vw, 2rem) !important;
  --padding-right: clamp(1.5rem, 3vw, 2rem) !important;
  --padding-bottom: clamp(1.5rem, 3vw, 2rem) !important;
  --padding-left: clamp(1.5rem, 3vw, 2rem) !important;
}

/* .sector-card h3 sets colour and size; §2's blanket heading margin has to be
   replaced with main.css's own .35rem. */
.sector-card .elementor-widget-heading .elementor-heading-title {
  margin: 0 0 .35rem;
}



/* --------------------------------------------------------------------------
   6h. NEWS LISTING (Loop Grid)
   --------------------------------------------------------------------------
   The news listing is real WordPress Posts rendered through an Elementor Loop
   Grid, so the client can publish. The page head and sidebar stay as pasted
   HTML — main.css reaches those directly and they need nothing here.

     Container  .news-layout
       Container  .news-main
         HTML       .news-main__head          (pasted)
         Loop Grid  .post-grid
       HTML       <aside class="news-side">   (pasted)

   And the Loop Item template:

     Container  .post-tile                    <- loop item root, Link: Post URL
       Container  .post-tile__media
         Image        dynamic featured image
         Text Editor  .post-tile__chip        dynamic post terms
       Container  .post-tile__body
         Heading H3   dynamic post title
         Text Editor  .post-tile__excerpt     dynamic post excerpt
         Text Editor  <span class="link-arrow">

   NOTE ON STRUCTURE: the source has an <a class="post-tile__link"> inside the
   <article>. That level is deliberately NOT reproduced — see the comment on
   .e-con.post-tile below. The Link goes on .post-tile itself.
   -------------------------------------------------------------------------- */

.e-con.news-layout,
.e-con.news-layout > .e-con-inner {
  --gap: clamp(2rem, 4vw, 3rem) !important;
  --row-gap: clamp(2rem, 4vw, 3rem) !important;
  --column-gap: clamp(2rem, 4vw, 3rem) !important;
  display: grid !important;
  grid-template-columns: 1fr;
}

/* 64rem = 1024px. The sidebar is a fixed 19rem column above it. */
@media (min-width: 64rem) {
  .e-con.news-layout,
  .e-con.news-layout > .e-con-inner {
    grid-template-columns: minmax(0, 1fr) 19rem;
  }
}

/* Elementor's Loop Grid renders THREE nested levels:

     div.elementor-widget-loop-grid.post-grid    <- the CSS class lands here
       div.elementor-widget-container
         div.elementor-loop-container.elementor-grid   <- the actual grid
           the loop items

   The grid must go on .elementor-loop-container and nowhere else. An earlier
   version of this rule also set `display: grid` on the .post-grid wrapper —
   whose single child is .elementor-widget-container. That one child then took
   one of three columns, and the tiles inside it were a third of a third:
   about 70px wide, with every title wrapping one character per line.

   !important because Elementor emits its own column count per breakpoint from
   the widget's Columns control (the elementor-grid-1 / -tablet-2 / -mobile-1
   classes) into the page's generated stylesheet, which ties this file on
   specificity and loads after it. */
/* NEUTRALISE THE WRAPPER FIRST.
   main.css:1216 declares `.post-grid { display: grid; grid-template-columns:
   ... }` as a plain class rule. On the static site that class is on the real
   grid. Here it lands on the Loop Grid WIDGET WRAPPER, so main.css turns the
   wrapper into a three-column grid whose only child is
   .elementor-widget-container — that child takes one column, and the tiles
   inside end up a third of a third: 64px, one character per line.

   Deleting the bridge's own duplicate of that rule was not enough, because
   main.css was making the wrapper a grid on its own. The wrapper has to be
   put back to block at (0,2,0). */
.elementor-widget-loop-grid.post-grid {
  display: block;
}

.post-grid .elementor-loop-container.elementor-grid {
  display: grid !important;
  grid-template-columns: 1fr !important;
  gap: clamp(1rem, 2.5vw, 1.5rem) !important;
}

@media (min-width: 40rem) {
  .post-grid .elementor-loop-container.elementor-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
  }
}

@media (min-width: 84rem) {
  .post-grid .elementor-loop-container.elementor-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr)) !important;
  }
}


/* THE CARD IS THE LINK — one level, not two.
   The source nests <a class="post-tile__link"> inside <article class="post-tile">
   and main.css puts `display:flex; height:100%` on the anchor. Reproducing
   both levels in Elementor proved error-prone: a Link set on a container
   renders the container itself as <a>, so the two are easy to mis-nest, and
   `height: 100%` then resolves against an auto-height parent and collapses.

   So the Link goes on .post-tile itself and the __link level is dropped. Both
   sets of main.css properties are merged onto the one element here. Media and
   body become direct children, and the flex column removes any need for a
   percentage height at all. */
.e-con.post-tile {
  --display: flex !important;
  --flex-direction: column !important;
  --gap: 0 !important;
  --row-gap: 0 !important;
  --column-gap: 0 !important;
  --padding-top: 0 !important;
  --padding-right: 0 !important;
  --padding-bottom: 0 !important;
  --padding-left: 0 !important;
}

.e-con.post-tile,
.e-con.post-tile:hover {
  color: inherit;
  text-decoration: none;
}

.e-con.post-tile__media {
  --gap: 0 !important;
  --row-gap: 0 !important;
  --column-gap: 0 !important;
  --padding-top: 0 !important;
  --padding-right: 0 !important;
  --padding-bottom: 0 !important;
  --padding-left: 0 !important;
}

/* Fill the 16:10 box.

   DESCENDANT selectors, not `>`. Elementor 4.2 drops the
   .elementor-widget-container div for some widgets and keeps it for others —
   the Image widget here renders <div class="elementor-widget-image"><img>
   with nothing between, while the Loop Grid still has its container. A
   direct-child chain therefore breaks on one and not the other.

   The image was 29px inside a 39px box because the chain from the aspect-ratio
   box down to the <img> was not height-definite the whole way; a percentage
   height needs every ancestor to resolve. */
.post-tile__media .elementor-widget-image,
.post-tile__media .elementor-widget-image > * {
  width: 100%;
  height: 100%;
}

/* GUARD: a percentage height needs EVERY ancestor between the aspect-ratio box
   and the <img> to resolve. If a stray container is left inside the media box —
   easy to do when rebuilding the loop template — the chain breaks there and the
   image silently drops to its natural height, leaving the --sand-200 backing
   visible below it. Making any container in that position fill keeps the chain
   intact. The media box should still hold only the Image and the chip. */
.post-tile__media > .e-con {
  width: 100%;
  height: 100%;
}

.post-tile__media .elementor-widget-image img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* The category pill. Class sits on the Text Editor wrapper, which is the
   painted element — main.css positions it. Only the text inside needs
   handing back. */
.elementor-widget-text-editor.post-tile__chip,
.elementor-widget-text-editor.post-tile__chip p {
  margin: 0;
}

.e-con.post-tile__body {
  --display: flex !important;
  --flex-direction: column !important;
  --gap: .55rem !important;
  --row-gap: .55rem !important;
  --column-gap: .55rem !important;
  --flex-grow: 1 !important;
  --padding-top: clamp(1.1rem, 2.2vw, 1.45rem) !important;
  --padding-right: clamp(1.1rem, 2.2vw, 1.45rem) !important;
  --padding-bottom: clamp(1.1rem, 2.2vw, 1.45rem) !important;
  --padding-left: clamp(1.1rem, 2.2vw, 1.45rem) !important;
}

.post-tile__body .elementor-widget-heading .elementor-heading-title {
  margin: 0;
}

/* THE EXCERPT HAS NO <p>.
   main.css sizes and clamps the summary with `.post-tile__body p`. Elementor's
   Post Excerpt dynamic tag renders BARE TEXT straight into the widget — no
   paragraph element — so that rule never matches and the excerpt rendered at
   the inherited 17px with no line clamp.

   Styling the widget itself is the fix. The class is applied explicitly in the
   template rather than relying on child position, so adding another widget to
   the card body cannot silently re-target this. */
.elementor-widget-text-editor.post-tile__excerpt,
.elementor-widget-text-editor.post-tile__excerpt p {
  margin: 0;
  font-size: .93rem;
  line-height: 1.6;
  color: var(--ink-500);
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* main.css says `.post-tile__body .link-arrow { margin-top: auto }`, but the
   .link-arrow here is a <span> inside a Text Editor — an auto margin on a
   span does nothing. The flex item is the widget wrapper, so the rule has to
   move up one level. This is what pins the "Read article" row to the bottom
   so it lines up across tiles of unequal excerpt length. */
.e-con.post-tile__body > .elementor-widget-text-editor:last-child,
.e-con.post-tile__body > .e-con-inner > .elementor-widget-text-editor:last-child {
  margin-top: auto;
  padding-top: .75rem;
}



/* --------------------------------------------------------------------------
   6i. SINGLE POST BODY
   --------------------------------------------------------------------------
   v2 has no design for a single article — every news tile links to /contact/
   and reads "Coming soon". The single-post template is therefore composed
   from existing patterns (page-head, v2-col, prose, CTA band) so it reads as
   part of the same site rather than as a new design.

   Only one thing needs bridging. Elementor's Post Content widget renders:

       <div class="elementor-widget-theme-post-content prose">
         <div class="elementor-widget-container">
           <p>…</p><h2>…</h2><ul>…</ul>

   main.css builds prose rhythm with `.v2-col .prose > * + *`, a DIRECT-child
   selector. With the class on the widget wrapper its only direct child is
   .elementor-widget-container, so nothing ever matches `* + *` and every
   paragraph sits flush against the next.

   Reaching one level deeper restores it. Everything else in .prose — heading
   sizes, paragraph colour, list styling — is written as a descendant selector
   and arrives on its own.
   -------------------------------------------------------------------------- */

.elementor-widget-theme-post-content.prose > .elementor-widget-container > * + * {
  margin-top: 1.1em;
}

.elementor-widget-theme-post-content.prose > .elementor-widget-container > h2 + *,
.elementor-widget-theme-post-content.prose > .elementor-widget-container > h3 + * {
  margin-top: .6em;
}

/* The post body's first element should sit flush with the column top. */
.elementor-widget-theme-post-content.prose > .elementor-widget-container > *:first-child {
  margin-top: 0;
}


/* --------------------------------------------------------------------------
   7. FORMS
   --------------------------------------------------------------------------
   Maps Elementor Pro's Form widget onto .form / .field from main.css:2100ish.

   Elementor renders:

     form.elementor-form
       div.elementor-form-fields-wrapper.elementor-labels-above
         div.elementor-field-group.elementor-column.elementor-col-50
           label.elementor-field-label
           input.elementor-field-textual
         div.elementor-field-group.elementor-field-type-submit.e-form__buttons
           button.elementor-button[type=submit]

   THE SUBMIT BUTTON IS NOT A BUTTON WIDGET.
   §1 paints `.elementor-widget-button .elementor-button`. A form's submit is
   inside `.elementor-widget-form`, so that selector never matches it and the
   button keeps Elementor's default grey #69727D. The previous version of this
   section declared --btn-bg / --btn-fg / --btn-bd here and then never used
   them — nothing on this element consumes those properties, so they had no
   effect at all. It has to be painted directly.
   -------------------------------------------------------------------------- */

.elementor-form .elementor-field-group > label {
  display: block;
  margin-bottom: .45rem;
  font-size: .9rem;
  font-weight: 600;
  color: var(--ink);
}

/* main.css:.field input — note 1.5px, not 1px; the thinner border reads as a
   different control at the sizes these fields are used at. */
.elementor-form .elementor-field-textual {
  width: 100%;
  padding: .8rem 1rem;
  border: 1.5px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: var(--step-0);
}

.elementor-form .elementor-field-textual:hover {
  border-color: var(--muted);
}

/* main.css uses a box-shadow ring, not an outline. An outline sits outside the
   border box and does not follow the 6px radius the same way. */
.elementor-form .elementor-field-textual:focus {
  outline: none;
  border-color: var(--crimson);
  box-shadow: 0 0 0 3px rgba(154, 1, 48, .14);
}

/* Elementor sizes the textarea by rows and leaves min-height at 40px. */
.elementor-form textarea.elementor-field-textual {
  resize: vertical;
  min-height: 8rem;
}

/* main.css:.form-actions — the rule above the submit. */
.elementor-form .elementor-field-type-submit {
  margin-top: 1.75rem;
  padding-top: 1.75rem;
  border-top: 1px solid var(--line-soft);
}

/* The submit, painted as .btn .btn--primary .btn--lg. Values copied from
   main.css's .btn and .btn--lg. */
.elementor-form .elementor-button[type="submit"] {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .55rem;
  width: auto;
  padding: 1.05rem 2rem;
  border: 1.5px solid var(--crimson);
  border-radius: 999px;
  background: var(--crimson);
  color: #fff;
  font-family: var(--font-sans);
  font-size: var(--step-1);
  font-weight: 600;
  line-height: 1.2;
  cursor: pointer;
  box-shadow: 0 0 0 rgba(154, 1, 48, 0);
  transition: transform .28s var(--ease),
              box-shadow .28s var(--ease),
              background-color .28s var(--ease),
              border-color .28s var(--ease);
}

.elementor-form .elementor-button[type="submit"]:hover {
  background: var(--crimson-800);
  border-color: var(--crimson-800);
  color: #fff;
  transform: translateY(-2px);
  box-shadow: 0 8px 22px rgba(154, 1, 48, .26);
}

.elementor-form .elementor-button[type="submit"] svg {
  width: 1.05em;
  height: 1.05em;
}

/* main.css makes the button full width below 40rem and auto above it. */
@media (max-width: 40rem) {
  .elementor-form .elementor-button[type="submit"] {
    width: 100%;
  }
}


/* --------------------------------------------------------------------------
   8. EDITOR-ONLY HELPERS
   --------------------------------------------------------------------------
   Containers with no background can be invisible in the editor, which makes
   them hard to select. This outlines them while editing only — it never
   appears on the live site.
   -------------------------------------------------------------------------- */

.elementor-editor-active .e-con.section,
.elementor-editor-active .e-con.cta-band {
  outline: 1px dashed rgba(154, 1, 48, .25);
  outline-offset: -1px;
}
