/* =========================================================================
   Chapman's Construction Essex - design stylesheet
   =========================================================================
   Scoped to .ch-site / .ch-home, which are content-marker body classes, so a
   duplicated page or a backup draft still renders fully styled.

   Values are the approved design's own. Its tokens are color-mix(in oklab, ..)
   expressions; the hex values below are what the browser actually resolves
   them to, measured rather than estimated.

   The AUTHORITATIVE HEADING BLOCK at the very bottom of this file must stay
   last. Salient sizes every heading below 999px with
   `.wpb_wrapper hN.vc_custom_heading { font-size: N !important }` = (0,2,2),
   which beats a plain `.ch-x` (0,2,0) even with !important. The block wins at
   (0,3,0) because specificity compares class count before element count, and
   it carries size, line-height, colour AND margin per context for the same
   reason.
   ========================================================================= */

/* ------------------------------------------------------------------ 1. tokens */

.ch-site {
  --teal:       #215777;
  --teal-deep:  #18445d;
  --teal-dark:  #0e2d3d;
  --teal-mid:   #4e7791;
  --teal-wash:  #eaeff2;
  --teal-line:  #ccd8e0;

  --ink:        #0e2c38;
  --body:       #44585f;
  --muted:      #5a6e76;
  --soft:       #6b7c85;
  --line:       #e4eaed;
  --line-2:     #dde4e8;
  --line-3:     #eef2f3;
  --ground:     #f5f7f8;
  --lightteal:  #9fc4d2;
  --footink:    #a9c4ce;

  --display:    'Sora', system-ui, sans-serif;
  --text:       'Plus Jakarta Sans', system-ui, sans-serif;

  /* The design's 1280 is the container INCLUDING its gutters, which leaves a
     1194px content strip at 1440. The client asked for at least 1280 of
     content, so the wrap is 1280 plus both gutters: every section, the header,
     the band and the footer share it, so the edges still align. */
  --wrap:       calc(1300px + 2 * var(--gut));
  --gut:        clamp(18px, 3vw, 44px);
  --rhythm:     clamp(64px, 8vw, 108px);
}

/* ------------------------------------------------- 2. page shell + rhythm */

.ch-site,
.ch-site #ajax-content-wrap {
  font-family: var(--text);
  color: var(--ink);
  line-height: 1.62;
  -webkit-font-smoothing: antialiased;
}

.ch-site .container-wrap,
.ch-site #ajax-content-wrap { background: #fff; }

/* Salient caps every page row inside .container.main-content (max-width = the
   Theme Options container PLUS 90px of side padding). Releasing it lets each
   section span the real layout width with no negative margins and no scrollbar
   arithmetic, and then ONE rule reproduces "max-width N centred inside clamp()
   gutters" exactly. Never use type="full_width_content" once this is released:
   Salient applies left:50% expecting to escape a container that is no longer
   there, and the row jumps half a viewport right. */
.ch-site .container-wrap .container.main-content {
  max-width: none !important;
  width: 100% !important;
  padding: 0 !important;
  margin: 0 !important;
}
.ch-site .container-wrap { padding: 0 !important; }
.ch-site .main-content > .row { margin-bottom: 0 !important; }

/* Salient rows are content-box, so side padding is ADDED to 100% and pushes
   content past the viewport; and Salient prints an INLINE
   `padding-top:0;padding-bottom:0` on every row, which beats any stylesheet
   rule without !important. All four sides are stated here for that reason. */
.ch-site .ch-section,
.ch-site .ch-section.wpb_row {
  box-sizing: border-box !important;
  width: 100% !important;
  margin: 0 !important;
  padding-top: var(--rhythm) !important;
  padding-bottom: var(--rhythm) !important;
  padding-left: max(var(--gut), calc((100% - var(--wrap)) / 2 + var(--gut))) !important;
  padding-right: max(var(--gut), calc((100% - var(--wrap)) / 2 + var(--gut))) !important;
}

/* Salient carries the grid's negative gutter on the row's column wrapper, which
   pulls the whole content strip ~12px left of the section's own padding edge.
   Measured: strip x 103.3 against a padding edge of 115.25. */
.ch-site .ch-section > .row_col_wrap_12 {
  width: 100% !important;
  margin-left: 0 !important;
  margin-right: 0 !important;
}
.ch-site .ch-section .row_col_wrap_12_inner {
  margin-left: 0 !important;
  margin-right: 0 !important;
  width: 100% !important;
}

.ch-site .wpb_column,
.ch-site .vc_column-inner { padding: 0 !important; }
.ch-site .wpb_row { margin-bottom: 0 !important; }
.ch-site .wpb_content_element,
.ch-site .wpb_text_column { margin-bottom: 0 !important; }
.ch-site .wpb_text_column p:last-child { margin-bottom: 0; padding-bottom: 0; }
.ch-site .wpb_text_column p { margin: 0; padding: 0; }

/* Salient's clearfix ::before/::after become FLEX or GRID items the moment a
   row is flexed or gridded: under flex the first and last child are each inset
   by one gap; under grid they silently consume cells and columns land in the
   wrong tracks. One consolidated kill list - add to it whenever another row is
   gridded. */
.ch-site .ch-about > .row_col_wrap_12::before,   .ch-site .ch-about > .row_col_wrap_12::after,
.ch-site .ch-svcpage > .row_col_wrap_12::before, .ch-site .ch-svcpage > .row_col_wrap_12::after,
.ch-site .ch-contact > .row_col_wrap_12::before, .ch-site .ch-contact > .row_col_wrap_12::after,
.ch-site .ch-svc__grid > .row_col_wrap_12_inner::before,     .ch-site .ch-svc__grid > .row_col_wrap_12_inner::after,
.ch-site .ch-why__grid > .row_col_wrap_12_inner::before,     .ch-site .ch-why__grid > .row_col_wrap_12_inner::after,
.ch-site .ch-partner__grid > .row_col_wrap_12_inner::before, .ch-site .ch-partner__grid > .row_col_wrap_12_inner::after,
.ch-site .ch-head > .row_col_wrap_12_inner::before,          .ch-site .ch-head > .row_col_wrap_12_inner::after,
.ch-site .ch-feat__grid > .row_col_wrap_12_inner::before,    .ch-site .ch-feat__grid > .row_col_wrap_12_inner::after,
.ch-site .ch-step__grid > .row_col_wrap_12_inner::before,    .ch-site .ch-step__grid > .row_col_wrap_12_inner::after,
.ch-site .ch-ben__grid > .row_col_wrap_12_inner::before,     .ch-site .ch-ben__grid > .row_col_wrap_12_inner::after,
.ch-site .ch-trust > .row_col_wrap_12_inner::before,         .ch-site .ch-trust > .row_col_wrap_12_inner::after,
.ch-site .ch-faqs > .row_col_wrap_12::before,                .ch-site .ch-faqs > .row_col_wrap_12::after,
.ch-site .ch-gal .portfolio-items::before,                   .ch-site .ch-gal .portfolio-items::after,
.ch-site #footer-widgets .container > .row::before,          .ch-site #footer-widgets .container > .row::after,
.ch-site #copyright .container > .row::before,               .ch-site #copyright .container > .row::after {
  display: none !important;
}

/* Salient's vc_col-sm-* are percentage widths with grid margins; inside our own
   grid tracks they would apply a second time. */
.ch-site .ch-about > .row_col_wrap_12 > .wpb_column,
.ch-site .ch-svcpage > .row_col_wrap_12 > .wpb_column,
.ch-site .ch-contact > .row_col_wrap_12 > .wpb_column,
.ch-site .ch-svc__grid > .row_col_wrap_12_inner > .wpb_column,
.ch-site .ch-why__grid > .row_col_wrap_12_inner > .wpb_column,
.ch-site .ch-feat__grid > .row_col_wrap_12_inner > .wpb_column,
.ch-site .ch-step__grid > .row_col_wrap_12_inner > .wpb_column,
.ch-site .ch-ben__grid > .row_col_wrap_12_inner > .wpb_column,
.ch-site .ch-trust > .row_col_wrap_12_inner > .wpb_column,
.ch-site .ch-faqs > .row_col_wrap_12 > .wpb_column,
.ch-site .ch-partner__grid > .row_col_wrap_12_inner > .wpb_column {
  width: 100% !important;
  margin: 0 !important;
  float: none !important;
  min-width: 0;
}

/* The WPBakery FRONTEND editor wraps every column in an extra div.vc_element
   and moves the vc_col-sm-* class onto that wrapper, so a selector naming
   .wpb_column misses the element carrying the width. Target grid children
   generically as well. */
.ch-site .ch-about > .row_col_wrap_12 > .vc_element,
.ch-site .ch-svcpage > .row_col_wrap_12 > .vc_element,
.ch-site .ch-contact > .row_col_wrap_12 > .vc_element,
.ch-site .ch-svc__grid > .row_col_wrap_12_inner > .vc_element,
.ch-site .ch-why__grid > .row_col_wrap_12_inner > .vc_element,
.ch-site .ch-feat__grid > .row_col_wrap_12_inner > .vc_element,
.ch-site .ch-step__grid > .row_col_wrap_12_inner > .vc_element,
.ch-site .ch-ben__grid > .row_col_wrap_12_inner > .vc_element,
.ch-site .ch-trust > .row_col_wrap_12_inner > .vc_element,
.ch-site .ch-faqs > .row_col_wrap_12 > .vc_element,
.ch-site .ch-partner__grid > .row_col_wrap_12_inner > .vc_element {
  width: 100% !important;
  margin: 0 !important;
  float: none !important;
  min-width: 0;
}

/* ------------------------------------------------------- 3. shared pieces */

/* The design's section eyebrow is an INLINE <span>, so the line box it occupies
   is the PARENT's strut (1.62 x 1rem = 25.92px), not its own 19.18px. A Text
   Block renders a block-level <p>, which would sit 6.7px shorter at every one
   of the eleven eyebrows on the page. Stating the strut as the line-height
   reproduces the design's vertical rhythm exactly. */
.ch-site .ch-eyebrow p {
  font-family: var(--display);
  font-weight: 700;
  font-size: .74rem;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--teal);
  line-height: 1.62rem;
}
/* Where the design's own span IS display:block it owns its line box, so these
   contexts take the natural line-height instead. */
.ch-site .ch-hero .ch-eyebrow p,
.ch-site .ch-partners .ch-eyebrow p,
.ch-site .ch-contact__form .ch-eyebrow p { line-height: 1.62; }

.ch-site .ch-eyebrow--hero p {
  font-size: clamp(.68rem, 1vw, .78rem);
  letter-spacing: .3em;
  color: var(--lightteal);
}
.ch-site .ch-eyebrow--light p { color: var(--lightteal); }
.ch-site .ch-partners .ch-eyebrow p { font-size: .72rem; }
.ch-site .ch-contact__form .ch-eyebrow p { font-size: .7rem; }

.ch-site .ch-body p,
.ch-site .ch-lead p { color: var(--body); font-size: 1.06rem; text-wrap: pretty; }
.ch-site .ch-lead--narrow p { max-width: 40ch; }
.ch-site .ch-lead--center p { max-width: 62ch; margin-left: auto !important; margin-right: auto !important; text-align: center; }
.ch-site .ch-lead--light p { color: #c3d9e2; }
.ch-site .ch-lead--muted p { color: var(--footink); font-size: 1rem; margin-top: 14px !important; }
.ch-site .ch-body + .ch-body { margin-top: 18px !important; }

/* Buttons. Every variant states the BAND it belongs to in its name, because a
   variant built for a dark band renders invisible on a light one and vice
   versa - the single most repeated defect on comparable builds.

   Every nectar_btn on this site carries Salient's own colour-override params
   (see ch_btn() in build/_lib.php), which makes Salient tag it
   data-color-override="true". Without that tag its dynamic stylesheet paints
   the text with `body.material .nectar-button.see-through.accent-color[...]
   { color: <accent> !important }` at (0,5,1) - which is how four "Take a look"
   links and the "Get in touch" button shipped as teal on teal. The values
   below are now the only ones in play; the !important is for Salient's inline
   background-color on regular buttons. */
.ch-site .nectar-button.ch-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--display);
  font-weight: 700;
  font-size: .78rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  line-height: 1.2;
  padding: 1.25em 2.4em !important;
  border: 0 !important;
  border-radius: 0 !important;
  box-shadow: none !important;
  transition: background .2s ease, color .2s ease, transform .2s ease, box-shadow .2s ease;
}
.ch-site .nectar-button.ch-btn > span { display: block; color: inherit !important; }

.ch-site .nectar-button.ch-btn--white        { background: #fff !important; color: var(--teal-deep) !important; }
.ch-site .nectar-button.ch-btn--white:hover  { background: var(--teal) !important; color: #fff !important;
                                               transform: translateY(-2px);
                                               box-shadow: 0 14px 28px -14px rgba(9,32,42,.55) !important; }

/* see-through: Salient writes a 2px solid border in the override colour; the
   design wants a 1.4px half-transparent rule, so the border is restated */
.ch-site .nectar-button.ch-btn--ghost        { background: transparent !important; color: #fff !important;
                                               border: 1.4px solid rgba(255,255,255,.55) !important; }
.ch-site .nectar-button.ch-btn--ghost:hover  { background: rgba(255,255,255,.14) !important; color: #fff !important;
                                               border-color: rgba(255,255,255,.9) !important; }

.ch-site .nectar-button.ch-btn--teal         { background: var(--teal) !important; color: #fff !important;
                                               font-size: .74rem; letter-spacing: .16em; padding: 1.3em 2.2em !important; }
.ch-site .nectar-button.ch-btn--teal:hover   { background: var(--teal-deep) !important; color: #fff !important;
                                               transform: translateY(-2px);
                                               box-shadow: 0 14px 28px -14px rgba(9,32,42,.55) !important; }

.ch-site .nectar-button.ch-btn--sm {
  font-family: var(--text); font-weight: 700; font-size: .98rem;
  letter-spacing: normal; text-transform: none;
  padding: .9em 1.6em !important; gap: .55em;
}
.ch-site .nectar-button.ch-btn--sm::after { content: ""; width: 16px; height: 16px; flex: 0 0 auto;
  background: currentColor; -webkit-mask: var(--ic-arrow) center/contain no-repeat; mask: var(--ic-arrow) center/contain no-repeat; }

/* Text links: the design's inline "See how we work" style with a sliding arrow. */
.ch-site .nectar-button.ch-tlink {
  display: inline-flex; align-items: center; gap: 9px;
  background: none !important; box-shadow: none !important; border: 0 !important;
  padding: 0 !important; border-radius: 0 !important;
  font-family: var(--text); font-weight: 700; font-size: 1rem;
  letter-spacing: normal; text-transform: none;
  color: var(--teal-deep) !important;
  transition: color .2s ease;
}
.ch-site .nectar-button.ch-tlink > span { color: inherit !important; }
.ch-site .nectar-button.ch-tlink::after {
  content: ""; width: 17px; height: 17px; flex: 0 0 auto;
  background: currentColor;
  -webkit-mask: var(--ic-arrow) center/contain no-repeat; mask: var(--ic-arrow) center/contain no-repeat;
  transition: transform .22s ease;
}
.ch-site .nectar-button.ch-tlink:hover { color: var(--teal) !important; }
.ch-site .nectar-button.ch-tlink:hover::after { transform: translateX(4px); }
.ch-site .nectar-button.ch-tlink--light,
.ch-site .nectar-button.ch-tlink--light:hover { color: #fff !important; }

.ch-site {
  --ic-arrow: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12h14M13 6l6 6-6 6'/%3E%3C/svg%3E");
  /* a map pin (the earlier teardrop read as a heart at 19px) */
  --ic-pin: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 10c0 6-8 12-8 12s-8-6-8-12a8 8 0 0 1 16 0z'/%3E%3Ccircle cx='12' cy='10' r='3'/%3E%3C/svg%3E");
  --ic-tel: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72c.13.96.36 1.9.7 2.81a2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45c.9.34 1.85.57 2.81.7A2 2 0 0 1 22 16.92z'/%3E%3C/svg%3E");
  --ic-check: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E");
  --ic-mail: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.1' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='2' y='4' width='20' height='16' rx='2'/%3E%3Cpath d='m2 7 10 6 10-6'/%3E%3C/svg%3E");
  --ic-wa: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.1' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8z'/%3E%3C/svg%3E");
  --ic-clip: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.1' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21.44 11.05l-9.19 9.19a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48'/%3E%3C/svg%3E");
  --ic-fb: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23000'%3E%3Cpath d='M14 9h3V5.5h-3c-2.2 0-4 1.8-4 4V12H7.5v3.5H10V22h3.5v-6.5H16L16.5 12H13.5V9.5c0-.3.2-.5.5-.5z'/%3E%3C/svg%3E");
  --ic-ig: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2'%3E%3Crect x='3' y='3' width='18' height='18' rx='5'/%3E%3Ccircle cx='12' cy='12' r='3.6'/%3E%3Ccircle cx='17.2' cy='6.8' r='1.1' fill='%23000'/%3E%3C/svg%3E");
}

/* Section head: copy left, action right, baseline aligned. */
/* The head block carries the gap to the grid below it. That margin has to sit
   on the ROW, not on its inner wrapper: the row is a .wpb_row, and the
   section-level `margin: 0 !important` reset above would otherwise be the last
   word on it. */
.ch-site .ch-head { margin-bottom: clamp(34px, 4vw, 52px) !important; }
.ch-site .ch-head > .row_col_wrap_12_inner {
  display: flex; flex-wrap: wrap; gap: 24px;
  align-items: flex-end; justify-content: space-between;
}
/* the head is a FLEX row, not one of the CSS grids, so its two columns keep
   their own widths and must be excluded from the width:100% grid reset above */
.ch-site .ch-head > .row_col_wrap_12_inner > .wpb_column,
.ch-site .ch-head > .row_col_wrap_12_inner > .vc_element {
  width: auto !important; margin: 0 !important; float: none !important; min-width: 0;
}
/* no flex-basis: the design lets the copy shrink to its content and the
   button wrap underneath on its own, so a guessed breakpoint would move the
   break away from where the design puts it */
.ch-site .ch-head .ch-head__copy { flex: 0 1 auto; max-width: 560px; min-width: 0; }
.ch-site .ch-head .ch-head__action { flex: 0 0 auto; width: auto !important; }
.ch-site .ch-head--center > .row_col_wrap_12_inner { justify-content: center; }
.ch-site .ch-head--center .ch-head__copy { max-width: 640px; margin: 0 auto; text-align: center; flex: 1 1 100%; }

/* ---------------------------------------------------------------- 4. header */

/* 88px bar: the client's cropped logo carries no whitespace, so 56px of
   artwork reads larger than the bundle logo did at 78px, and the bar can come
   down from the design's 104px without the brand shrinking. */
.ch-site #header-outer {
  background: #fff !important;
  border-bottom: 1px solid var(--line);
  box-shadow: none !important;
  transition: box-shadow .25s ease;
  padding: 0 !important;
}
/* brand rule along the very top of the page */
.ch-site #header-outer::before {
  content: ""; position: absolute; left: 0; right: 0; top: 0; height: 3px;
  background: var(--teal); z-index: 2;
}
.ch-site #header-outer.ch-scrolled { box-shadow: 0 6px 24px -12px rgba(14,44,56,.22) !important; }
/* Salient's fixed header reserves its room with this spacer; the design's
   sticky header occupies flow the same way, so it stays visible. */
.ch-site #header-space { display: block !important; background: #fff; }
.ch-site #header-outer #top { padding: 0 !important; }

/* The main header's container is `#header-outer #top > .container`, NOT a
   direct child of #header-outer. Writing the rule for the direct child only
   leaves the header content ~90px inside the page sections. */
.ch-site #header-outer #top > .container {
  max-width: none !important;
  width: 100% !important;
  padding-inline: max(var(--gut), calc((100% - var(--wrap)) / 2 + var(--gut))) !important;
}

/* Salient's .span_9 renders 3px past its own row because of the percentage
   grid, and no padding tuning fixes it. Replace the grid with flex. */
.ch-site #header-outer #top > .container > .row {
  display: flex; align-items: center;
  gap: clamp(14px, 2vw, 30px);
  height: 94px;
  margin: 0 !important;
}
.ch-site #header-outer #top > .container > .row::before,
.ch-site #header-outer #top > .container > .row::after { display: none !important; }
.ch-site #header-outer #top > .container > .row > .col {
  float: none !important; margin: 0 !important; width: auto !important;
  padding: 0 !important; min-height: 0;
}
.ch-site #header-outer #top .col.span_3 { flex: 0 0 auto; margin-right: auto !important; }
.ch-site #header-outer #top .col.span_9 { flex: 1 1 auto; min-width: 0; display: flex;
  align-items: center; justify-content: flex-end; gap: clamp(14px, 2vw, 28px); }

.ch-site #header-outer #logo { display: flex; align-items: center; padding: 0; margin: 0; height: auto; }
.ch-site #header-outer #logo img { height: 74px !important; width: auto !important; max-height: none !important; display: block; }

/* nav holds two lists side by side: the menu and Salient's ul.buttons, which
   carries the header text widget (phone + CTA) and the burger. */
.ch-site #header-outer #top nav { width: auto; float: none !important; display: flex; align-items: center; gap: clamp(14px, 2vw, 28px); }
/* Salient's clearfix ::after on the nav column becomes a flex item that
   collects one gap after the CTA, holding it 28px short of the container
   edge (the same trap as the gridded rows, one level up). */
.ch-site #header-outer #top nav::before,
.ch-site #header-outer #top nav::after,
.ch-site #header-outer #top .col.span_9::before,
.ch-site #header-outer #top .col.span_9::after { display: none !important; content: none !important; }
.ch-site #header-outer #top nav > ul.sf-menu { display: flex; align-items: center; gap: clamp(18px, 2vw, 30px); float: none; }
.ch-site #header-outer #top nav > ul.sf-menu > li { margin: 0 !important; padding: 0 !important; list-style: none; }
.ch-site #header-outer #top nav > ul.sf-menu > li::before,
.ch-site #header-outer #top nav > ul.sf-menu > li::marker { content: none !important; }
.ch-site #header-outer #top nav > ul.sf-menu > li > a {
  padding: 0 !important; line-height: 1.62;
  font-family: var(--display) !important; font-weight: 600 !important;
  font-size: .8rem !important; letter-spacing: .13em !important;
  text-transform: uppercase; color: #3e565f !important; white-space: nowrap;
  transition: color .2s ease;
}
.ch-site #header-outer #top nav > ul.sf-menu > li > a:hover { color: var(--teal) !important; }
/* Salient uppercases .menu-title-text, not the anchor, and draws its animated
   nav underline as a pseudo on the same span. Its pseudos are cleared and a
   2px brand underline grows from the left on hover instead. Scoped to #top nav
   so the reset can never reach a secondary bar. */
.ch-site #header-outer #top nav > ul.sf-menu > li > a .menu-title-text {
  position: relative; display: inline-block; padding-bottom: 5px; text-transform: uppercase;
}
.ch-site #header-outer #top nav > ul.sf-menu > li > a::before,
.ch-site #header-outer #top nav > ul.sf-menu > li > a::after,
.ch-site #header-outer #top nav > ul.sf-menu > li > a .menu-title-text::before { content: none !important; background: none !important; }
.ch-site #header-outer #top nav > ul.sf-menu > li > a .menu-title-text::after {
  content: "" !important; position: absolute; left: 0; right: 0; bottom: 0; height: 2px;
  background: var(--teal) !important; opacity: 1 !important;
  transform: scaleX(0); transform-origin: left center;
  transition: transform .25s ease;
  width: auto !important; margin: 0 !important; top: auto !important;
}
.ch-site #header-outer #top nav > ul.sf-menu > li > a:hover .menu-title-text::after { transform: scaleX(1); }

/* Salient renders the header text widget (phone + CTA) into ul.buttons beside
   the search icon and the burger. Round 3 hid that whole list above the burger
   breakpoint, which also hid the phone and the CTA until round 7 caught it.
   Now only the burger and the search go; the list itself stays in the row with
   Salient's floats and reserved widths cleared. */
.ch-site #header-outer #top nav > ul.buttons {
  display: flex !important; align-items: center; gap: clamp(14px, 2vw, 22px);
  float: none !important; margin: 0 !important; padding: 0 !important; min-width: 0 !important; width: auto !important;
}
.ch-site #header-outer #top nav > ul.buttons > li {
  float: none !important; margin: 0 !important; padding: 0 !important; list-style: none; line-height: 1; height: auto !important;
}
.ch-site #header-outer #top nav > ul.buttons > li::before,
.ch-site #header-outer #top nav > ul.buttons > li::marker { content: none !important; }
.ch-site #header-outer #top nav > ul.buttons > li.slide-out-widget-area-toggle,
.ch-site #header-outer #top nav > ul.buttons > li#search-btn { display: none !important; }
.ch-site #header-outer #top nav > ul.buttons > li.nectar-header-text-content-wrap { display: flex !important; align-items: center; }

/* phone: a hairline divider separates it from the navigation */
.ch-site #header-outer .ch-hphone {
  display: flex; align-items: center; gap: 9px;
  font-weight: 700; color: var(--teal-deep); font-size: .95rem; white-space: nowrap;
  padding-left: clamp(14px, 2vw, 24px); border-left: 1px solid var(--line);
  line-height: 1; min-height: 28px;
  transition: color .2s ease;
}
.ch-site #header-outer .ch-hphone:hover { color: var(--teal); }
.ch-site #header-outer .ch-hphone::before {
  content: ""; width: 16px; height: 16px; flex: 0 0 auto; background: var(--teal);
  -webkit-mask: var(--ic-tel) center/contain no-repeat; mask: var(--ic-tel) center/contain no-repeat;
}
.ch-site #header-outer .ch-hcta {
  display: inline-flex; align-items: center;
  background: var(--teal); color: #fff;
  font-family: var(--display); font-weight: 700; font-size: .76rem;
  letter-spacing: .12em; text-transform: uppercase;
  padding: 1.1em 1.8em; white-space: nowrap;
  transition: background .18s ease, transform .18s ease, box-shadow .18s ease;
}
.ch-site #header-outer .ch-hcta:hover {
  background: var(--teal-deep); color: #fff;
  transform: translateY(-1px);
  box-shadow: 0 12px 24px -12px rgba(9,32,42,.55);
}

/* Salient renders the header text widget into ul.buttons; that ul is hidden
   above, so the widget is lifted out into the header row instead. */
.ch-site #header-outer #top .col.span_9 .nectar-header-text-content,
.ch-site #header-outer #top .widget_text {
  display: flex; align-items: center; gap: clamp(14px, 2vw, 22px); margin: 0; padding: 0;
  background: none !important;
}
.ch-site #header-outer #top .widget_text .textwidget,
.ch-site #header-outer #top .col.span_9 .nectar-header-text-content > div { display: flex; align-items: center; gap: clamp(14px, 2vw, 22px); }

/* ------------------------------------------- 5. off-canvas (Salient chrome)
   Never in a design file: it ships 32px on #3452ff with a #ff1053 close
   button and renders the primary AND secondary menus into one list. The
   design's phone menu is a full-screen WHITE panel. Colours are set in Theme
   Options; the geometry is here. */

.ch-site #slide-out-widget-area,
.ch-site #slide-out-widget-area.fullscreen-alt {
  background: #fff !important;
  width: 100% !important;
  padding-right: 0 !important;
  scrollbar-width: none;
}
.ch-site #slide-out-widget-area::-webkit-scrollbar { width: 0; height: 0; }
.ch-site #slide-out-widget-area .inner-wrap { width: 100% !important; margin-right: 0 !important; margin-top: 0 !important; }
.ch-site #slide-out-widget-area-bg { background: #fff !important; opacity: 1 !important; }
/* The panel is a full-height flex column so the two CTAs can sit at the bottom
   on `margin-top:auto`, exactly as the design does. Salient ships .inner as a
   plain block, which would leave them directly under the last menu item. */
.ch-site #slide-out-widget-area .inner-wrap { display: flex; flex-direction: column; height: 100%; }
.ch-site #slide-out-widget-area .inner {
  display: flex; flex-direction: column; flex: 1 1 auto;
  padding: 20px clamp(18px, 5vw, 28px) 28px !important;
  text-align: left !important;
}
.ch-site #slide-out-widget-area .bottom-meta-wrap { display: none; }

/* Salient caps the menu at 280px and centres it; the design runs the links the
   full width of the panel with a rule under each. The theme's own rule is
   `#slide-out-widget-area.fullscreen-alt .menu-wrap` at (1,2,0) in
   salient-dynamic-styles.css, which loads AFTER this file, so matching its
   specificity only re-creates the tie. body. takes it to (1,3,0). */
/* Salient insets the menu container by 35px of its own PADDING, which reads as
   a width cap: 351 - 35.1 - 35.1 = 280.8. The links are full width once it is
   zeroed; no width rule was ever the problem. */
body.ch-site #slide-out-widget-area .off-canvas-menu-container { padding: 0 !important; }
body.ch-site #slide-out-widget-area .off-canvas-menu-container,
body.ch-site #slide-out-widget-area.fullscreen-alt .menu-wrap,
body.ch-site #slide-out-widget-area.fullscreen-alt .menu-wrap ul,
body.ch-site #slide-out-widget-area.fullscreen-alt .menu-wrap li {
  width: 100% !important; max-width: none !important;
  /* horizontal only: a blanket margin reset here also wipes the 20px the design
     puts between the brand row and the first menu item */
  margin-left: 0 !important; margin-right: 0 !important;
  text-align: left !important; float: none !important;
}
/* The design's overlay covers the whole screen, header included. Salient parks
   the panel below the fixed header, so the logo stays visible above an open
   menu and the panel scrolls under it. */
/* The header keeps painting above the panel (z-index 9999 over 9997) with the
   burger turned into an X, so the panel sits BELOW the header where Salient
   puts it, and that X is the single close control. A second close box inside
   the panel read as two, and the wordmark duplicated the visible logo. */
.ch-site #slide-out-widget-area .off-canvas-menu-container { margin-top: 4px !important; }
.ch-site #slide-out-widget-area .menu-wrap:empty { display: none; }

.ch-site #slide-out-widget-area .off-canvas-menu-container li a {
  font-family: var(--display) !important; font-weight: 700 !important;
  font-size: 1.45rem !important; letter-spacing: -.02em !important;
  line-height: 1.3 !important;
  color: var(--ink) !important; text-transform: none !important;
  text-align: left !important;
  padding: 17px 0 !important; border-bottom: 1px solid var(--line);
  display: block !important; width: 100% !important;
}
.ch-site #slide-out-widget-area .off-canvas-menu-container li a:hover { color: var(--teal) !important; }
.ch-site #slide-out-widget-area .off-canvas-menu-container ul { list-style: none; }
.ch-site #slide-out-widget-area .off-canvas-menu-container li::before,
.ch-site #slide-out-widget-area .off-canvas-menu-container li::marker { content: none !important; }

/* Salient tints .nectar-header-text-content rgba(0,0,0,.1) inside the panel,
   which paints a grey band behind the two CTAs. */
.ch-site #slide-out-widget-area .nectar-header-text-content {
  background: none !important; padding: 0 !important;
  margin-top: auto !important; padding-top: 32px !important;
  order: 3; width: 100%;
}
.ch-site #slide-out-widget-area .nectar-header-text-content > div,
.ch-site #slide-out-widget-area .widget_text .textwidget {
  display: flex; flex-direction: column; gap: 12px; width: 100%;
}
.ch-site #slide-out-widget-area .widget { order: 4; }
.ch-site #slide-out-widget-area .off-canvas-menu-container { order: 2; }
.ch-site #slide-out-widget-area .ch-ocm-brand { order: 0; }
.ch-site #slide-out-widget-area .slide_out_area_close { order: 1; }
/* The header-text widget is repeated into the panel by Salient, outside
   #header-outer, so the header rules above never reach these copies and they
   measured white-on-white. Both pills are stated in full here. */
body.ch-site #slide-out-widget-area .ch-hphone {
  display: flex !important; align-items: center; justify-content: center; gap: 9px;
  min-height: 52px; background: #fff !important; color: var(--teal-deep) !important;
  font-family: var(--text); font-weight: 700; font-size: 1rem; padding: .9em 1.6em;
  box-shadow: inset 0 0 0 1.6px var(--line-2); border: 0;
}
body.ch-site #slide-out-widget-area .ch-hphone::before {
  content: ""; width: 16px; height: 16px; flex: 0 0 auto; background: var(--teal);
  -webkit-mask: var(--ic-tel) center/contain no-repeat; mask: var(--ic-tel) center/contain no-repeat;
}
body.ch-site #slide-out-widget-area .ch-hcta {
  display: flex !important; align-items: center; justify-content: center;
  min-height: 52px; background: var(--teal) !important; color: #fff !important;
  font-family: var(--text); font-weight: 700; font-size: 1rem;
  letter-spacing: normal; text-transform: none; padding: .9em 1.6em;
}

/* The close control has two independent alignment traps: Salient paints its
   own accent circle as ::before (animated from scale(0), so it is invisible
   until the menu opens), and it centres .close-wrap with top/left:50% PLUS a
   translate - overriding only the transform leaves the 50% offsets. */
/* Brand wordmark and close control form the design's 68px top row. The close is
   absolutely positioned inside the panel rather than made a flex sibling,
   because Salient renders it before the brand and reordering a control the
   keyboard reaches is worse than placing it. */
.ch-site #slide-out-widget-area .ch-ocm-brand { display: none; }
/* Gated on .open: forcing display on a control Salient parks at 0x0 would
   otherwise paint a stray cross over the header on every page load. */
.ch-site #slide-out-widget-area .slide_out_area_close { display: none !important; }
.ch-site .slide_out_area_close::before { content: none !important; }
.ch-site .slide_out_area_close .close-wrap {
  position: static !important; transform: none !important;
  top: auto !important; left: auto !important;
  width: 24px !important; height: 24px !important;
}
.ch-site .slide_out_area_close .close-line { background-color: var(--teal-deep) !important; }

/* Salient staggers the panel contents in with per-element transforms on the
   LIST ITEMS, not just their container. An interrupted animation leaves an item
   resting part-way: measured here with "FAQs" sitting at y=434 inside "Why Us"
   at 408-473, so the two overlapped and one was not the topmost element at its
   own centre. Remove the transforms outright rather than timing them. */
.ch-site #slide-out-widget-area .inner .off-canvas-menu-container,
.ch-site #slide-out-widget-area .inner .widget,
.ch-site #slide-out-widget-area .off-canvas-menu-container ul,
.ch-site #slide-out-widget-area .off-canvas-menu-container li,
.ch-site #slide-out-widget-area .off-canvas-menu-container li a,
.ch-site #slide-out-widget-area .nectar-header-text-content {
  transform: none !important;
  opacity: 1 !important;
  transition: none !important;
}

/* Burger and mobile call button, both from the design. */
.ch-site #header-outer .slide-out-widget-area-toggle a {
  width: 48px; height: 48px; display: flex; align-items: center; justify-content: center;
  background: var(--teal); border-radius: 0; transition: background .2s ease;
}
/* while the panel is open the same control is the close: the design's
   teal-wash plate with a teal-deep cross */
body.ch-site #header-outer.side-widget-open .slide-out-widget-area-toggle a,
body.ch-site #header-outer .slide-out-widget-area-toggle a.open { background: var(--teal-wash) !important; }
/* the open-state cross is Salient's .close-line pair, not the burger's .lines;
   the material skin colours it with a
   body.mobile.material[data-header-color] ... !important rule, so this has to
   outrank that: (1,6,2) */
body.ch-site.material #header-outer.side-widget-open .slide-out-widget-area-toggle a .close-line,
body.ch-site.material #header-outer .slide-out-widget-area-toggle a.open .close-line,
.ch-site #header-outer.side-widget-open .slide-out-widget-area-toggle .close-line,
.ch-site #header-outer .slide-out-widget-area-toggle a.open .close-line,
.ch-site #header-outer .slide-out-widget-area-toggle a.open .lines,
.ch-site #header-outer .slide-out-widget-area-toggle a.open .lines::before,
.ch-site #header-outer .slide-out-widget-area-toggle a.open .lines::after { background-color: var(--teal-deep) !important; }
.ch-site #header-outer .slide-out-widget-area-toggle .lines-button { transform: none; padding: 0; }
.ch-site #header-outer .slide-out-widget-area-toggle .lines,
.ch-site #header-outer .slide-out-widget-area-toggle .lines::before,
.ch-site #header-outer .slide-out-widget-area-toggle .lines::after { background-color: #fff !important; }

/* ------------------------------------------------------------------ 6. hero */

/* white sections state their own ground: the design does, and a section that
   relies on the page background breaks the moment one is added above it. */
.ch-site .ch-section.ch-about,
.ch-site .ch-section.ch-svcpage { background: #fff; }

.ch-site .ch-section.ch-hero {
  position: relative;
  /* its own stacking context, so the negative-z layers below stay inside it */
  isolation: isolate;
  min-height: min(78vh, 720px);
  display: grid;
  overflow: hidden;
  background: var(--ink);
  padding-top: 0 !important;
  padding-bottom: 0 !important;
}
/* Layers, lowest first: Salient's own background (the first photograph, so
   nothing depends on script), the slideshow, then the copy in normal flow.
   The copy column chain is unpositioned on purpose: that makes the hero the
   containing block of the slideshow row, which can then cover the whole band
   rather than only the column's own height. */
.ch-site .ch-hero .row-bg-wrap { z-index: -2; }
.ch-site .ch-hero .row-bg { background-size: cover !important; background-position: center center !important; }
.ch-site .ch-hero > .row_col_wrap_12 { position: static; align-self: center; }
.ch-site .ch-hero .ch-hero__col,
.ch-site .ch-hero .ch-hero__col > .vc_column-inner,
.ch-site .ch-hero .ch-hero__col > .vc_column-inner > .wpb_wrapper { position: static !important; }

.ch-site .ch-hero__col > .vc_column-inner > .wpb_wrapper {
  max-width: 900px; margin: 0 auto; text-align: center;
  padding: clamp(80px, 10vw, 130px) clamp(20px, 4vw, 44px);
}
.ch-site .ch-hero__lead p {
  font-size: clamp(1rem, 1.3vw, 1.14rem);
  color: #d3e3ea; margin: 20px auto 0 !important; max-width: 60ch; text-wrap: pretty;
}
.ch-site .ch-btnrow > .row_col_wrap_12_inner { display: flex; justify-content: center; }
.ch-site .ch-btnrow__col > .vc_column-inner > .wpb_wrapper {
  display: flex; flex-wrap: wrap; gap: 14px; justify-content: center; margin-top: 36px;
}
.ch-site .ch-btnrow .nectar-button { margin: 0 !important; }

/* SLIDESHOW. The inner row is lifted out of flow to cover the hero; every
   Salient wrapper inside it is flattened so each photograph can fill it. The
   first photograph shows without script; ch-site.js adds ch-slides--on and
   moves is-active every 6s, with a slow drift on the live slide. */
.ch-site .ch-hero .ch-hero__slides.wpb_row {
  position: absolute !important; inset: 0; z-index: -1;
  margin: 0 !important; padding: 0 !important; overflow: hidden; pointer-events: none;
}
.ch-site .ch-hero__slides > .row-bg-wrap { display: none; }
.ch-site .ch-hero__slides > .row_col_wrap_12_inner,
.ch-site .ch-hero__slides .ch-hero__slides-col,
.ch-site .ch-hero__slides .ch-hero__slides-col > .vc_column-inner,
.ch-site .ch-hero__slides .ch-hero__slides-col > .vc_column-inner > .wpb_wrapper {
  position: static !important; width: 100% !important; height: 100%;
  margin: 0 !important; padding: 0 !important; float: none !important; max-width: none !important;
}
.ch-site .ch-hero__slides .img-with-aniamtion-wrap {
  position: absolute !important; inset: 0; margin: 0 !important; max-width: none !important; width: auto !important;
  opacity: 0; transition: opacity 1.6s ease;
}
.ch-site .ch-hero__slides .img-with-aniamtion-wrap .inner,
.ch-site .ch-hero__slides .img-with-aniamtion-wrap .hover-wrap,
.ch-site .ch-hero__slides .img-with-aniamtion-wrap .hover-wrap-inner { position: static !important; display: block; width: 100%; height: 100%; margin: 0 !important; }
.ch-site .ch-hero__slides .wpb_wrapper > .img-with-aniamtion-wrap:first-child,
.ch-site .ch-hero__slides .img-with-aniamtion-wrap.is-active { opacity: 1; }
.ch-site .ch-hero__slides.ch-slides--on .img-with-aniamtion-wrap:not(.is-active) { opacity: 0; }
.ch-site .ch-hero__slides img.ch-hero__slide {
  position: absolute; inset: 0; width: 100% !important; height: 100% !important; max-width: none !important;
  object-fit: cover; margin: 0 !important; transform: scale(1); transition: transform 7.5s linear;
}
.ch-site .ch-hero__slides .is-active img.ch-hero__slide { transform: scale(1.06); }
/* the tint rides on the slideshow so it always sits between photograph and copy */
.ch-site .ch-hero__slides::after,
.ch-site .ch-hero > .row-bg-wrap::after {
  content: ""; display: block; position: absolute; inset: 0; z-index: 2;
  background: linear-gradient(180deg, rgba(9,32,42,.72) 0%, rgba(9,32,42,.55) 45%, rgba(9,32,42,.86) 100%);
}

/* SCROLL CUE: one chevron inside a ring that breathes outwards. */
.ch-site .ch-hero__cue {
  position: absolute; z-index: 4; bottom: 22px; left: 50%; transform: translateX(-50%);
  margin: 0 !important; padding: 0 !important;
}
.ch-site .ch-hero__cue .nectar_icon { position: relative; display: block; }
.ch-site .ch-hero__cue .nectar_icon > a { position: absolute; inset: -10px; z-index: 2; }
.ch-site .ch-hero__cue i {
  display: block; color: #fff !important; opacity: .9;
  animation: ch-cue 2.2s cubic-bezier(.45,0,.2,1) infinite;
}
.ch-site .ch-hero__cue .nectar_icon::before {
  content: ""; position: absolute; left: 50%; top: 50%; width: 46px; height: 46px; margin: -23px 0 0 -23px;
  border-radius: 50%; border: 1px solid rgba(255,255,255,.35);
  animation: ch-cue-ring 2.2s ease-out infinite;
}
.ch-site .ch-hero__cue:hover i { opacity: 1; }
@keyframes ch-cue {
  0%   { transform: translateY(-6px); opacity: 0; }
  35%  { opacity: 1; }
  70%  { transform: translateY(6px); opacity: 1; }
  100% { transform: translateY(8px); opacity: 0; }
}
@keyframes ch-cue-ring {
  0%   { transform: scale(.6); opacity: 0; }
  40%  { opacity: .9; }
  100% { transform: scale(1.35); opacity: 0; }
}
/* on a phone the CTA row would end 12px above the cue; the hero centres its
   content, so bottom margin on the row lifts the buttons by half of it */
@media (max-width: 480px) {
  .ch-site .ch-hero .ch-btnrow.wpb_row { margin-bottom: 56px !important; }
}
@media (prefers-reduced-motion: reduce) {
  .ch-site .ch-hero__cue i, .ch-site .ch-hero__cue .nectar_icon::before { animation: none; }
  .ch-site .ch-hero__slides img.ch-hero__slide, .ch-site .ch-hero__slides .img-with-aniamtion-wrap { transition: none; }
  .ch-site .ch-hero__slides .is-active img.ch-hero__slide { transform: none; }
}

/* ----------------------------------------------------------------- 7. about */

.ch-site .ch-about > .row_col_wrap_12 {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: clamp(36px, 5vw, 68px);
  align-items: center;
}
.ch-site .ch-pills .wpb_wrapper > ul,
.ch-site .ch-pills ul { list-style: none !important; display: flex; flex-wrap: wrap; gap: 12px; margin: 28px 0 0 !important; padding: 0 !important; }
/* `.wpb_text_column ul li` is (0,2,2), so a pill rule at (0,2,1) silently loses
   its padding and its ::before. A chained class gets to (0,3,2) and still
   needs !important to beat the theme reset. */
.ch-site .wpb_text_column.ch-pills ul li {
  display: inline-flex; align-items: center; gap: 9px;
  background: var(--teal-wash); color: var(--teal-deep);
  font-weight: 700; font-size: .86rem;
  padding: 9px 16px !important; margin: 0 !important; border-radius: 0;
  list-style: none !important;
}
.ch-site .wpb_text_column.ch-pills ul li::before,
.ch-site .wpb_text_column.ch-pills ul li::marker { content: none !important; }

.ch-site .ch-about__copy .ch-tlink { margin-top: 30px !important; }

.ch-site .ch-about__media > .vc_column-inner > .wpb_wrapper {
  display: grid; grid-template-columns: 1fr 1fr; gap: 16px;
}
.ch-site .ch-about__media .img-with-aniamtion-wrap { position: relative; overflow: hidden; background: var(--line); }
/* image_with_animation puts el_class on the IMG itself, so `.ch-about__img img`
   matches nothing - the wrapper is an ancestor. Size the wrapper through the
   COLUMN class and target the image as `img.ch-x`. */
.ch-site .ch-about__media .img-with-aniamtion-wrap:nth-child(1) { grid-column: 1 / -1; aspect-ratio: 16 / 10; }
.ch-site .ch-about__media .img-with-aniamtion-wrap:nth-child(2),
.ch-site .ch-about__media .img-with-aniamtion-wrap:nth-child(3) { aspect-ratio: 1 / 1; }
/* Salient ships img{height:auto!important}, which beats any class height:100%.
   Absolute + inset is immune because the offsets set the height. */
.ch-site .ch-about__media img.ch-about__img {
  position: absolute; inset: 0;
  width: 100% !important; height: 100% !important; object-fit: cover;
}
.ch-site .ch-about__media .hover-wrap,
.ch-site .ch-about__media .hover-wrap-inner { display: block; width: 100%; height: 100%; }

/* -------------------------------------------------------------- 8. services */

.ch-site .ch-section.ch-services {
  background: var(--ground);
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  padding-bottom: clamp(72px, 9vw, 120px) !important;
}
.ch-site .ch-svc__grid > .row_col_wrap_12_inner {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(30px, 3.6vw, 56px);
}
.ch-site .ch-svc {
  color: #fff;
  --ch-svc-lift:  clamp(76px, 9vw, 104px);    /* how far the panel rides up the photo */
  --ch-svc-inset: clamp(16px, 2.2vw, 30px);   /* panel inset from the card edges   */
  --ch-svc-pad:   clamp(26px, 2.7vw, 36px);   /* panel padding                     */
}

/* THE PANEL IS ONE PAINTED SURFACE.
   The card wrapper is an inline-size container, so the panel can be a single
   ::after whose top edge is the photo's bottom (85cqw, the 4/3.4 ratio) minus
   the overlap, and it lifts and darkens as one piece. Painting the panel on
   each of the four text elements instead left the title snapping to the hover
   colour while its neighbours were still fading, and hairline seams between
   the four boxes mid-transition - "some areas one colour, some another".
   Layout containment also makes the wrapper the containing block for the
   stretched link overlay. */
.ch-site .ch-svc > .vc_column-inner > .wpb_wrapper {
  position: relative; display: block;
  container-type: inline-size;
}
.ch-site .ch-svc > .vc_column-inner > .wpb_wrapper::after {
  content: ""; position: absolute; z-index: -1;
  left: var(--ch-svc-inset); right: var(--ch-svc-inset);
  top: calc(85cqw - var(--ch-svc-lift)); bottom: 0;
  background: var(--teal);
  box-shadow: 0 34px 64px -34px rgba(9,32,42,.5);
  transition: background .4s ease, transform .5s cubic-bezier(.16,.8,.28,1), box-shadow .5s ease;
}
.ch-site .ch-svc:hover > .vc_column-inner > .wpb_wrapper::after {
  background: var(--teal-deep);
  transform: translateY(-8px);
  box-shadow: 0 46px 80px -34px rgba(9,32,42,.6);
}

/* the photo sits BELOW the panel: z-index -2 inside the wrapper's own stacking
   context, so the panel's -1 overlaps it and the text above both stays static */
.ch-site .ch-svc .img-with-aniamtion-wrap {
  position: relative; z-index: -2; display: block; aspect-ratio: 4 / 3.4;
  overflow: hidden; background: var(--line-2);
}
.ch-site .ch-svc img.ch-svc__img {
  position: absolute; inset: 0; width: 100% !important; height: 100% !important;
  object-fit: cover; transition: transform 1.2s cubic-bezier(.16,.8,.28,1);
}
.ch-site .ch-svc:hover img.ch-svc__img { transform: scale(1.05); }
.ch-site .ch-svc .hover-wrap,
.ch-site .ch-svc .hover-wrap-inner { display: block; width: 100%; height: 100%; }
.ch-site .ch-svc .img-with-aniamtion-wrap::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(180deg, rgba(9,32,42,.34) 0%, rgba(9,32,42,0) 42%);
}
/* The text elements ride on the panel: transparent, in flow, and lifting with
   it on hover at the identical timing. The title now leads the panel (the
   numbered kicker went in round 7); its margins and lift live in the
   authoritative heading block at the foot of this file, because that block
   sets margin at the same specificity later in the file. */
.ch-site .ch-svc .ch-svc__blurb {
  position: relative; background: transparent !important;
  margin-left: var(--ch-svc-inset) !important; margin-right: var(--ch-svc-inset) !important;
  transition: transform .5s cubic-bezier(.16,.8,.28,1);
}
.ch-site .ch-svc:hover .ch-svc__blurb { transform: translateY(-8px); }
.ch-site .ch-svc .ch-svc__blurb { padding: 22px var(--ch-svc-pad) 0; }
.ch-site .ch-svc .ch-svc__blurb p { color: #c9dee7; font-size: 1rem; line-height: 1.66; }

/* The design's 1px divider between the title and the blurb, drawn rather than
   authored, because it is decoration and not content the client edits. */
.ch-site .ch-svc .ch-svc__title::after {
  content: ""; display: block; width: 100%; height: 1px;
  background: rgba(255,255,255,.28); margin-top: 22px;
}

/* The link stays STATIC and untransformed on purpose: its ::before is the
   stretched overlay that makes the whole card clickable, and a transform would
   turn the link into that overlay's containing block and shrink the click
   target to the link box for exactly as long as the card is hovered. Its text
   rides up with the panel by trading top padding for bottom padding instead. */
.ch-site .ch-svc .nectar-button.ch-svc__link {
  position: static !important;
  display: flex !important;
  align-items: center; justify-content: flex-start; gap: 12px;
  margin: 0 var(--ch-svc-inset) !important;
  background: transparent !important;
  padding: 26px var(--ch-svc-pad) var(--ch-svc-pad) !important;
  font-family: var(--display); font-weight: 700; font-size: .72rem;
  letter-spacing: .2em; text-transform: uppercase;
  border: 0 !important;
  transition: padding .5s cubic-bezier(.16,.8,.28,1);
}
.ch-site .ch-svc:hover .nectar-button.ch-svc__link {
  padding-top: 18px !important;
  padding-bottom: calc(var(--ch-svc-pad) + 8px) !important;
}
.ch-site .ch-svc .nectar-button.ch-svc__link > span {
  flex: 0 0 auto; color: #fff !important;
  border-bottom: 1px solid rgba(255,255,255,.45); padding-bottom: 6px;
  transition: border-color .3s ease;
}
.ch-site .ch-svc:hover .nectar-button.ch-svc__link > span { border-bottom-color: #fff; }
.ch-site .ch-svc .nectar-button.ch-svc__link::after { width: 13px; height: 13px; }
/* The whole card is one link in the design. A stretched pseudo on the single
   real anchor keeps that behaviour without wrapping the content in markup. */
.ch-site .ch-svc .nectar-button.ch-svc__link::before {
  content: ""; position: absolute; inset: 0; z-index: 3;
}

/* ------------------------------------------------------------------ 9. band */

.ch-site .ch-section.ch-band {
  position: relative; min-height: min(62vh, 560px); display: grid; overflow: hidden;
  background: var(--ink);
  padding-top: 0 !important; padding-bottom: 0 !important;
}
.ch-site .ch-band .row-bg { background-size: cover !important; background-position: center center !important; }
.ch-site .ch-band > .row-bg-wrap::after {
  content: ""; display: block; position: absolute; inset: 0; z-index: 2;
  /* even, not left-weighted: the panel is centred since round 11 */
  background: linear-gradient(180deg, rgba(9,32,42,.74) 0%, rgba(9,32,42,.62) 50%, rgba(9,32,42,.78) 100%);
}
.ch-site .ch-band > .row_col_wrap_12 {
  position: relative; z-index: 3; align-self: center; width: 100%;
  padding: clamp(52px, 7vw, 90px) 0;
}
/* Round 11: every page now closes on this band with the client's own call to
   action, so it is a centred panel rather than the design's 460px left card.
   At 460px the client's longer headlines broke into three cramped lines. */
.ch-site .ch-band__col > .vc_column-inner > .wpb_wrapper {
  max-width: 760px; margin: 0 auto; text-align: center;
  background: rgba(255,255,255,.12);
  backdrop-filter: blur(10px);
  border: 1px solid rgba(255,255,255,.24);
  padding: clamp(32px, 4vw, 52px) clamp(28px, 4vw, 56px);
  color: #fff;
}
.ch-site .ch-band__lead p {
  color: #e2edf1; font-size: 1.04rem; line-height: 1.7;
  margin: 18px auto 0 !important; max-width: 58ch;
}
.ch-site .ch-band .nectar-button.ch-btn--ghost {
  margin-top: 26px !important; font-size: .75rem; padding: 1.1em 2em !important;
  box-shadow: inset 0 0 0 1.4px rgba(255,255,255,.6);
}
.ch-site .ch-band .nectar-button.ch-btn--ghost:hover { background: #fff !important; color: var(--teal-deep) !important; }

/* ------------------------------------------------------------------- 10. why */

.ch-site .ch-section.ch-why {
  background: var(--ground);
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}
.ch-site .ch-why__grid > .row_col_wrap_12_inner {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 24px;
}
.ch-site .ch-why__card {
  background: #fff; border: 1px solid var(--line); overflow: hidden;
  transition: transform .2s ease, box-shadow .2s ease;
}
.ch-site .ch-why__card:hover { transform: translateY(-4px); box-shadow: 0 26px 52px -30px rgba(14,44,56,.42); }
.ch-site .ch-why__card .img-with-aniamtion-wrap { position: relative; display: block; height: 210px; background: var(--line); overflow: hidden; }
.ch-site .ch-why__card img.ch-why__img { position: absolute; inset: 0; width: 100% !important; height: 100% !important; object-fit: cover; }
.ch-site .ch-why__card .hover-wrap,
.ch-site .ch-why__card .hover-wrap-inner { display: block; width: 100%; height: 100%; }
.ch-site .ch-why__card .ch-why__body { padding: 0 26px 30px; text-align: center; }
.ch-site .ch-why__card .ch-why__body p { color: var(--muted); font-size: .96rem; }
.ch-site .ch-why__note { text-align: center; margin-top: 32px !important; }
.ch-site .ch-why__note p { color: var(--body); font-size: 1rem; }
.ch-site .ch-why__note a { font-weight: 700; color: var(--teal-deep); border-bottom: 1px solid var(--teal-line); }

/* --------------------------------------------------------------- 12. gallery */

.ch-site .ch-section.ch-gallery { background: var(--teal); color: #fff; }
.ch-site .ch-gallery .ch-head { margin-bottom: clamp(30px, 4vw, 46px) !important; }
.ch-site .ch-gallery .ch-head__copy { max-width: 620px; }

/* Salient renders vc_gallery through its portfolio grid, whose gutters are a
   negative row margin plus item padding. Zeroing only the margin makes every
   tile wider than its container. */
.ch-site .ch-gal .portfolio-items,
.ch-site .ch-gal .row.portfolio-items {
  display: grid !important;
  /* four across: at a 1280 strip the design's auto-fit(230) would give five
     columns and leave eight tiles as five plus three */
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 18px;
  margin: 0 !important; width: 100% !important;
  /* isotope writes an INLINE height on the container, measured from its own
     absolute layout before our grid applies. Left alone the container is one
     gap short of its rows and the last row is clipped. */
  height: auto !important;
}
/* Salient activates isotope on the portfolio grid and positions every item
   with an inline TRANSFORM. Neutralising left/top is not enough - a transform
   moves the tile without changing its computed left, so the grid looked right
   in every probe while tiles 4 to 8 sat outside the viewport. */
.ch-site .ch-gal .portfolio-items .col {
  width: 100% !important; margin: 0 !important; padding: 0 !important;
  float: none !important; left: auto !important; top: auto !important;
  position: relative !important;
  transform: none !important;
}
.ch-site .ch-gal .portfolio-items .col .inner-wrap { margin: 0 !important; }
.ch-site .ch-gal .portfolio-items .col { aspect-ratio: 4 / 3; }
.ch-site .ch-gal .portfolio-items .col .inner-wrap,
.ch-site .ch-gal .portfolio-items .col .work-item {
  height: 100% !important; width: 100% !important;
}
.ch-site .ch-gal .portfolio-items .col .work-item {
  position: relative; overflow: hidden;
  background: rgba(255,255,255,.1); margin: 0 !important;
}
.ch-site .ch-gal .portfolio-items .col .work-item img {
  position: absolute; inset: 0; width: 100% !important; height: 100% !important;
  object-fit: cover; transition: transform .5s cubic-bezier(.2,.7,.3,1);
}
.ch-site .ch-gal .portfolio-items .col:hover .work-item img { transform: scale(1.06); }

/* The gallery's link sits INSIDE the .work-info caption layer. Hiding that
   layer makes every anchor 0x0 on screen while a scripted click still
   "passes" - so the layer stays displayed and stretched, and only its caption
   children are restyled. */
.ch-site .ch-gal .work-info,
.ch-site .ch-gal .work-info-bg {
  display: block !important; position: absolute !important; inset: 0 !important;
  opacity: 1 !important; background: none !important;
}
.ch-site .ch-gal .work-info > a,
.ch-site .ch-gal .work-info a.pp,
.ch-site .ch-gal .vert-center a { position: absolute; inset: 0; display: block; cursor: zoom-in; }
.ch-site .ch-gal .work-info .vert-center { position: absolute; inset: auto 0 0 0; transform: none; padding: 0; }
/* Salient prints <h3>title</h3><p>caption</p>. The design shows ONE caption per
   tile, so the descriptive title is hidden and the attachment's caption field
   is what renders - which is also the field a client would edit in the Media
   Library. Hiding both left every tile silently captionless. */
.ch-site .ch-gal .work-info h3,
.ch-site .ch-gal .work-info .category { display: none !important; }
.ch-site .ch-gal .work-info .vert-center p {
  display: block !important;
  position: relative; z-index: 2; margin: 0;
  padding: 34px 16px 14px;
  font-family: var(--text); font-size: .84rem; font-weight: 700; line-height: 1.62;
  color: #fff; pointer-events: none;
}
.ch-site .ch-gal .work-item::after {
  content: ""; position: absolute; inset: auto 0 0 0; height: 60%;
  background: linear-gradient(to top, rgba(4,20,27,.88), rgba(4,20,27,0));
  pointer-events: none;
}
.ch-site .ch-gal .work-item .ch-gal__cap,
.ch-site .ch-gal figcaption {
  position: absolute; inset: auto 0 0 0; z-index: 2;
  padding: 34px 16px 14px; font-size: .84rem; font-weight: 700; color: #fff;
  pointer-events: none;
}

/* -------------------------------------------------------------- 14. partners */

.ch-site .ch-section.ch-partners {
  background: #fff;
  padding-top: clamp(56px, 7vw, 88px) !important;
  padding-bottom: clamp(56px, 7vw, 88px) !important;
}
.ch-site .ch-partners .ch-head--center .ch-head__copy { max-width: 620px; }
.ch-site .ch-partners .ch-head { margin-bottom: clamp(34px, 4vw, 48px) !important; }
.ch-site .ch-partner__grid > .row_col_wrap_12_inner {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(196px, 1fr)); gap: 20px;
}
.ch-site .ch-partner > .vc_column-inner {
  display: flex; flex-direction: column; background: #fff; height: 100%;
  transition: transform .22s ease;
}
.ch-site .ch-partner:hover > .vc_column-inner { transform: translateY(-5px); }
.ch-site .ch-partner > .vc_column-inner > .wpb_wrapper { display: flex; flex-direction: column; height: 100%; }
.ch-site .ch-partner .img-with-aniamtion-wrap {
  display: flex; align-items: center; justify-content: center;
  height: 120px; padding: 18px 20px; box-sizing: border-box;
}
.ch-site .ch-partner img.ch-partner__logo {
  width: 100% !important; height: 100% !important; object-fit: contain;
}
.ch-site .ch-partner .ch-partner__name {
  border-top: 1px solid var(--line); padding: 14px 18px; margin-top: auto !important; text-align: center;
}
.ch-site .ch-partner .ch-partner__name p,
.ch-site .ch-partner .ch-partner__name a {
  font-family: var(--display); font-weight: 600; font-size: .72rem; line-height: 1.45;
  letter-spacing: .12em; text-transform: uppercase; color: var(--teal-deep);
}

/* --------------------------------------------------------------- 16. contact */

.ch-site .ch-section.ch-contact { background: var(--ground); border-top: 1px solid var(--line); }
.ch-site .ch-contact > .row_col_wrap_12 {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: clamp(30px, 4vw, 48px); align-items: start;
}

.ch-site .ch-cc {
  margin-top: 16px !important;
  background: #fff; border: 1px solid var(--line);
  transition: border-color .18s ease;
}
.ch-site .ch-cc:hover { border-color: var(--teal-line); }
/* The card is a two-column GRID with every child explicitly placed. A flex row
   would lay the value and its label side by side, because they are separate
   inline children of one anchor with no wrapper to stack them - and adding a
   wrapper would mean markup inside a Text Block. Explicit placement also means
   a stray text node cannot shuffle the layout. */
.ch-site .ch-cc a {
  position: relative;
  display: grid;
  grid-template-columns: 42px 1fr;
  align-items: center;
  column-gap: 15px;
  padding: 20px 20px;
  color: var(--ink); text-decoration: none;
}
/* icon tile: the tinted plate is ::before, the glyph is a masked ::after pinned
   inside it. A masked element cannot also show an unmasked background, so a
   tile plus a glyph needs both pseudos. */
.ch-site .ch-cc a::before {
  content: ""; grid-column: 1; grid-row: 1 / 3; align-self: center;
  width: 42px; height: 42px; background: var(--teal-wash);
}
.ch-site .ch-cc a::after {
  content: ""; position: absolute; left: 31.5px; top: 50%; margin-top: -9.5px;
  width: 19px; height: 19px; background: var(--teal-deep);
  -webkit-mask-position: center; mask-position: center;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-size: contain; mask-size: contain;
}
.ch-site .ch-cc--phone a::after    { -webkit-mask-image: var(--ic-tel);  mask-image: var(--ic-tel); }
.ch-site .ch-cc--email a::after    { -webkit-mask-image: var(--ic-mail); mask-image: var(--ic-mail); }
.ch-site .ch-cc strong {
  grid-column: 2; grid-row: 1 / 3; min-width: 0; align-self: center;
  display: block; font-family: var(--display); font-weight: 600;
  font-size: 1rem; line-height: 1.62; color: var(--ink); overflow-wrap: anywhere;
}
.ch-site .ch-cc small {
  grid-column: 2; grid-row: 2; min-width: 0;
  display: block; color: var(--soft); font-weight: 600; font-size: .85rem;
  /* inline in the design, so its line box is the parent strut, not its own */
  line-height: 1.62rem;
}
.ch-site .ch-cc--email strong { font-size: .98rem; }
.ch-site .ch-cc br { display: none; }
.ch-site .ch-cc p { margin: 0; }

.ch-site .ch-hours__title { margin-top: 22px !important; }
/* The design has ONE bordered panel containing the heading, the seven rows
   and the note. Salient gives us a heading element and a Text Block, so the
   panel is drawn across both: the title carries the top and sides, the table
   carries the sides and bottom, and neither repeats the inset. */
.ch-site .ch-hours {
  background: #fff; border: 1px solid var(--line); border-top: 0;
  padding: 0 22px 20px;
  margin-top: 0 !important;
}
.ch-site .ch-hours table { width: 100%; border-collapse: collapse; margin: 0; }
/* Salient styles content tables with 10px cell padding and its own font size,
   which made every hours row 43.7px against the design 39.1. */
.ch-site .ch-hours td {
  padding: 7px 0 !important;
  border-bottom: 1px solid var(--line-3) !important;
  border-left: 0 !important; border-right: 0 !important; border-top: 0 !important;
  font-size: .93rem !important; line-height: 1.62 !important;
  background: none !important;
}
.ch-site .ch-hours tr:last-child td { border-bottom: 0 !important; }
.ch-site .ch-hours td:first-child { color: var(--body); font-weight: 600; }
.ch-site .ch-hours td:last-child  { color: var(--ink); font-weight: 700; text-align: right; }
.ch-site .ch-hours .ch-hours__note { color: var(--soft); font-size: .82rem; margin-top: 12px !important; }

/* --------------------------------------------------------------- 17. the form */

.ch-site .ch-contact__form > .vc_column-inner {
  background: #fff; border: 1px solid var(--line);
  padding: clamp(26px, 3vw, 38px) !important;
}
.ch-site .ch-form__title { margin: 12px 0 0 !important; }
.ch-site .ch-form__title::after {
  content: ""; display: block; width: 52px; height: 3px; background: var(--teal); margin: 20px 0 34px;
}

/* Never let the layout depend on CF7's autop <p>/<br>: both are rebuilt from
   the blank lines in the template every time the client saves the form.
   Dissolve them and lay the form out on a grid keyed to [data-name], so a
   renamed, reordered or added field fails SOFT to a full-width row. */
.ch-site .wpcf7-form {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 30px 26px;
}
.ch-site .wpcf7-form > p { display: contents; }
.ch-site .wpcf7-form br { display: none; }
.ch-site .wpcf7-form label {
  display: flex; flex-direction: column; gap: 10px; min-width: 0;
  grid-column: 1 / -1;
  font-family: var(--display); font-weight: 600; font-size: .68rem;
  letter-spacing: .16em; text-transform: uppercase; color: var(--soft);
}
.ch-site .wpcf7-form label:has([data-name="your-name"]),
.ch-site .wpcf7-form label:has([data-name="your-email"]),
.ch-site .wpcf7-form label:has([data-name="your-phone"]),
.ch-site .wpcf7-form label:has([data-name="your-service"]) { grid-column: span 1; }

.ch-site .wpcf7-form .wpcf7-form-control-wrap { display: block; min-width: 0; }
.ch-site .wpcf7-form input[type="text"],
.ch-site .wpcf7-form input[type="email"],
.ch-site .wpcf7-form input[type="tel"],
.ch-site .wpcf7-form select,
.ch-site .wpcf7-form textarea {
  width: 100%; border: 0; border-bottom: 1px solid var(--line-2);
  padding: 0 0 11px; background: transparent; outline: none;
  font-family: var(--text); font-weight: 400; font-size: 1rem;
  letter-spacing: normal; text-transform: none; color: var(--ink);
  border-radius: 0; box-shadow: none; min-width: 0;
  transition: border-color .2s ease;
}
.ch-site .wpcf7-form textarea { line-height: 1.6; resize: vertical; }
.ch-site .wpcf7-form input:focus,
.ch-site .wpcf7-form select:focus,
.ch-site .wpcf7-form textarea:focus { border-bottom-color: var(--teal); }
.ch-site .wpcf7-form ::placeholder { color: #9aa9b0; opacity: 1; }

/* file row */
/* The design hides the native file control and shows only the label row, which
   leaves the user with no way to see what they attached. The control stays,
   but on its OWN line under the label: beside it, its 258px intrinsic width
   ran past the panel at 1024, 820 and 360. */
.ch-site .wpcf7-form label:has(input[type="file"]) {
  flex-direction: row; flex-wrap: wrap; align-items: center; gap: 10px 14px;
  padding: 18px 20px; background: var(--ground);
  color: var(--body); font-family: var(--text); font-size: .93rem; font-weight: 600;
  letter-spacing: normal; text-transform: none; cursor: pointer;
}
.ch-site .wpcf7-form label:has(input[type="file"]) .wpcf7-form-control-wrap {
  flex: 1 1 100%; min-width: 0;
}
.ch-site .wpcf7-form input[type="file"] { max-width: 100%; box-sizing: border-box; }
.ch-site .wpcf7-form label:has(input[type="file"])::before {
  content: ""; flex: 0 0 auto; width: 19px; height: 19px; background: var(--teal);
  -webkit-mask: var(--ic-clip) center/contain no-repeat; mask: var(--ic-clip) center/contain no-repeat;
}
.ch-site .wpcf7-form input[type="file"] { border: 0; padding: 0; font-size: .85rem; }

.ch-site .wpcf7-form .wpcf7-submit {
  grid-column: 1 / -1; width: 100%;
  background: var(--teal); color: #fff; border: 0; cursor: pointer;
  font-family: var(--display); font-weight: 700; font-size: .8rem;
  letter-spacing: .16em; text-transform: uppercase;
  padding: 1.5em 1.6em !important; line-height: 1.6; border-radius: 0 !important;
  transition: background .2s ease;
}
.ch-site .wpcf7-form .wpcf7-submit:hover { background: var(--teal-deep); }
/* A required [acceptance] disables the submit with no message and no visual
   change, which clients report as "the button is broken". This form has no
   acceptance field, but the rule stays so adding one can never ship silent. */
.ch-site .wpcf7-form .wpcf7-submit:disabled,
.ch-site .wpcf7-form .wpcf7-submit:disabled:hover {
  opacity: .45; filter: grayscale(.4); cursor: not-allowed; box-shadow: none; transform: none;
}
.ch-site .wpcf7-form .wpcf7-response-output,
.ch-site .wpcf7-form .wpcf7-not-valid-tip { grid-column: 1 / -1; }
.ch-site .wpcf7-form .wpcf7-not-valid-tip {
  color: #b3261e; font-family: var(--text); font-size: .82rem;
  letter-spacing: normal; text-transform: none; margin-top: 8px;
}
.ch-site .wpcf7-form .wpcf7-response-output {
  border: 1px solid var(--line); padding: 14px 16px; margin: 8px 0 0;
  font-size: .9rem; color: var(--body);
}
.ch-site .wpcf7-spinner { grid-column: 1 / -1; }

/* Anti-spam plugins deliberately reuse the real field classes so bots cannot
   tell them apart, which means field styling hits them too. Take it out of
   flow entirely: zero layout, still in the DOM for the bot to fill. */
.ch-site .wpcf7-form [data-cf7apps-honeypot],
.ch-site .wpcf7-form [class*="honeypot"] {
  position: absolute !important; left: -9999px !important; top: auto !important;
  width: 1px !important; height: 1px !important;
  overflow: hidden !important; opacity: 0 !important; pointer-events: none !important;
}

/* ---------------------------------------------------------------- 18. footer */

/* The design's <footer> carries the whole block's padding, with the copyright
   bar INSIDE it. Salient splits that across #footer-outer > #footer-widgets +
   #copyright, so the padding goes on the outer element to match. */
.ch-site #footer-outer {
  background: var(--teal-dark); color: var(--footink);
  padding: clamp(52px, 6vw, 80px) 0 30px;
  position: relative;
}
/* the brand rule from the header, mirrored along the top of the footer */
.ch-site #footer-outer::before {
  content: ""; position: absolute; left: 0; right: 0; top: 0; height: 3px; background: var(--teal);
}
/* Salient's own footer rules are written with TWO ids
   (`#footer-outer #footer-widgets`, `#footer-outer #copyright`), so a
   `.ch-site #footer-widgets` override at (1,1,0) loses to (2,0,0) and the
   theme's 75px of padding stays. Match the id count. Its `p { padding-bottom:
   1.5em }` is masked inside a Text Block but NOT in a widget area, where it
   silently adds 20px under the strapline. It also pads the widget ROW, not
   #footer-widgets. */
.ch-site #footer-outer #footer-widgets { padding: 0 !important; border: 0; }
.ch-site #footer-outer #footer-widgets p { padding-bottom: 0; }
.ch-site #footer-outer .container,
.ch-site #footer-widgets .container {
  max-width: none !important; width: 100% !important;
  padding-inline: max(var(--gut), calc((100% - var(--wrap)) / 2 + var(--gut))) !important;
}
/* brand column wider, contact column a little wider, link columns lighter:
   four equal tracks left the two short link lists floating in empty space */
.ch-site #footer-outer #footer-widgets .container > .row {
  display: grid; grid-template-columns: 1.4fr .8fr .8fr 1.6fr;
  gap: clamp(30px, 4vw, 56px);
  margin: 0 !important; padding: 0 !important;
}
.ch-site #footer-widgets .container > .row > .col {
  width: 100% !important; margin: 0 !important; padding: 0 !important; float: none !important;
  min-width: 0;
}
.ch-site #footer-widgets .widget { margin: 0 !important; }

/* column headings carry a short brand rule beneath them */
.ch-site #footer-outer .widget h4,
.ch-site #footer-outer .widgettitle {
  color: #fff; font-family: var(--display); font-weight: 700;
  font-size: .8rem; letter-spacing: .13em; text-transform: uppercase;
  margin: 0 0 20px !important; padding-bottom: 12px; position: relative;
}
.ch-site #footer-outer .widget h4::after,
.ch-site #footer-outer .widgettitle::after {
  content: ""; position: absolute; left: 0; bottom: 0; width: 28px; height: 2px; background: var(--lightteal);
}
/* `.ascend #footer-outer #footer-widgets .widget.widget_nav_menu li` sets
   padding:4px 0 !important, which turns an 11px gap into a 45px pitch. The
   .widget class is what makes this selector match it. */
.ch-site #footer-outer #footer-widgets .widget.widget_nav_menu ul {
  list-style: none; display: flex; flex-direction: column; gap: 11px; margin: 0; padding: 0;
}
.ch-site #footer-outer #footer-widgets .widget.widget_nav_menu li {
  padding: 0 !important; margin: 0 !important; border: 0 !important;
}
.ch-site #footer-outer #footer-widgets .widget.widget_nav_menu li::before,
.ch-site #footer-outer #footer-widgets .widget.widget_nav_menu li::marker { content: none !important; }
.ch-site #footer-outer #footer-widgets .widget.widget_nav_menu li a {
  color: var(--footink); font-family: var(--text); font-size: .95rem; padding: 0; border: 0;
  display: inline-block; transition: color .2s ease, transform .2s ease;
}
.ch-site #footer-outer #footer-widgets .widget.widget_nav_menu li a:hover { color: #fff; transform: translateX(3px); }

/* brand plate: the cropped logo needs far less plate than the bundle logo did */
.ch-site .ch-foot__logo {
  display: inline-flex; align-items: center; justify-content: center;
  background: #fff; padding: 14px 20px;
  /* the plate is inline-level, so without this its line box adds ~15px of
     descender space under a block image */
  line-height: 0; vertical-align: top;
}
/* Salient ships img { margin-bottom: 15px }, which would grow the plate. */
.ch-site .ch-foot__logoimg {
  height: 58px !important; width: auto !important; max-width: none;
  display: block; margin: 0 !important;
}
.ch-site .ch-foot__strap { font-size: .95rem; color: var(--footink); margin: 22px 0 0; max-width: 32ch; text-wrap: pretty; line-height: 1.7; }
.ch-site .ch-foot__social { display: flex; gap: 10px; margin-top: 22px; }
.ch-site .ch-soc {
  display: grid; place-items: center; width: 42px; height: 42px;
  background: rgba(255,255,255,.08); border: 1px solid rgba(255,255,255,.12);
  transition: background .18s ease, border-color .18s ease, transform .18s ease;
}
.ch-site .ch-soc:hover { background: var(--teal); border-color: var(--teal); transform: translateY(-2px); }
.ch-site .ch-soc span { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
.ch-site .ch-soc::before {
  content: ""; width: 17px; height: 17px; background: #fff;
  -webkit-mask-position: center; mask-position: center;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-size: contain; mask-size: contain;
}
.ch-site .ch-soc--fb::before { -webkit-mask-image: var(--ic-fb); mask-image: var(--ic-fb); }
.ch-site .ch-soc--ig::before { -webkit-mask-image: var(--ic-ig); mask-image: var(--ic-ig); }

/* contact rows: each glyph sits in a small tinted tile, matching the socials */
.ch-site .ch-foot__touch { list-style: none; display: flex; flex-direction: column; gap: 14px; margin: 0; padding: 0; font-size: .95rem; }
.ch-site .ch-foot__touch li { display: flex; gap: 13px; align-items: flex-start; padding: 0; margin: 0; line-height: 1.6; }
.ch-site .ch-foot__touch li::marker { content: none; }
/* stated on the li itself: `.ch-foot__touch li { padding:0 }` is (0,2,1) and
   outranks a bare .ch-ft at (0,2,0), which is how the glyph tiles ended up
   painted over the first characters of every line */
/* two ids: Salient's own footer list rules are written as
   #footer-outer #footer-widgets ... li, so anything below (2,0,0) loses */
.ch-site #footer-outer #footer-widgets .col ul li.ch-ft {
  /* (2,3,2): the material skin's `.material #footer-outer #footer-widgets .col
     ul li { padding: 4px 0 !important }` is (2,2,2) and wins over anything
     shorter, which is how the tiles kept painting over the text */
  position: relative; padding: 0 0 0 47px !important; min-height: 34px;
  /* the row is a flex box centred on its cross axis and the tile is pinned to
     the row's middle, so a one-line phone number and a three-line address
     both sit on the tile's centre line (client request, round 9) */
  display: flex; align-items: center;
}
/* Salient's own footer anchor rule outranks a bare .ch-ft > a, which is how
   the 5px top padding that used to centre the text was being lost */
.ch-site #footer-outer #footer-widgets .col ul li.ch-ft > a,
.ch-site #footer-outer #footer-widgets .col ul li.ch-ft > span { display: block; padding: 0 !important; margin: 0 !important; line-height: 1.6; }
.ch-site .ch-ft::before {
  content: ""; position: absolute; left: 0; top: 50%; transform: translateY(-50%);
  width: 34px; height: 34px; background: rgba(255,255,255,.08); border: 1px solid rgba(255,255,255,.12);
}
.ch-site .ch-ft::after {
  content: ""; position: absolute; left: 9px; top: 50%; transform: translateY(-50%); width: 16px; height: 16px; background: #fff;
  -webkit-mask-position: center; mask-position: center;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-size: contain; mask-size: contain;
}
.ch-site .ch-ft--pin::after  { -webkit-mask-image: var(--ic-pin);  mask-image: var(--ic-pin); }
.ch-site .ch-ft--tel::after  { -webkit-mask-image: var(--ic-tel);  mask-image: var(--ic-tel); }
.ch-site .ch-ft--mail::after { -webkit-mask-image: var(--ic-mail); mask-image: var(--ic-mail); }
.ch-site .ch-foot__touch a { color: var(--footink); transition: color .2s ease; }
/* the email is one unbreakable line (client request); the column is sized for it */
.ch-site .ch-foot__touch .ch-ft--mail a { white-space: nowrap; }
/* it fits down to 360 (3px to spare); narrower phones may break it once */
@media (max-width: 359px) { .ch-site .ch-foot__touch .ch-ft--mail a { white-space: normal; overflow-wrap: anywhere; } }
.ch-site .ch-foot__touch a:hover { color: #fff; }

/* #copyright IS the .row, and its text lives in .col.span_5; with socials off
   the 7/12 sibling is empty and the 5/12 forces the spans onto two lines. */
.ch-site #footer-outer #copyright {
  background: var(--teal-dark); border-top: 1px solid rgba(255,255,255,.13);
  margin-top: 48px; padding: 24px 0 0;
}
.ch-site #copyright .container > .row { display: flex; margin: 0 !important; }
.ch-site #copyright .col { width: 100% !important; float: none !important; margin: 0 !important; padding: 0 !important; }
.ch-site #copyright .col.span_7 { display: none; }
.ch-site #copyright p {
  display: flex; flex-wrap: wrap; gap: 14px; justify-content: space-between;
  font-size: .84rem; color: #7e9ca8; margin: 0; line-height: 1.62;
}
.ch-site #copyright .ch-copy__a { display: block; }

/* --------------------------------------------------- 19. GDPR bar (chrome) */

.ch-site #moove_gdpr_cookie_info_bar,
#moove_gdpr_cookie_info_bar {
  background: var(--teal-dark, #0e2d3d) !important;
  border-top: 1px solid rgba(255,255,255,.13) !important;
  font-family: 'Plus Jakarta Sans', system-ui, sans-serif !important;
}
#moove_gdpr_cookie_info_bar .moove-gdpr-info-bar-container { padding: 16px 0 !important; }
#moove_gdpr_cookie_info_bar p,
#moove_gdpr_cookie_info_bar span { color: #a9c4ce !important; font-size: .9rem !important; }
#moove_gdpr_cookie_info_bar .mgbutton,
#moove_gdpr_cookie_info_bar a.mgbutton {
  background: #215777 !important; color: #fff !important;
  border-radius: 0 !important; font-family: 'Sora', system-ui, sans-serif !important;
  font-weight: 700 !important; font-size: .74rem !important;
  letter-spacing: .12em !important; text-transform: uppercase !important;
}
#moove_gdpr_cookie_info_bar .mgbutton:hover { background: #18445d !important; }

/* ============================================================ 20. RESPONSIVE
   Values are the design's own at each width. Nothing here invents a mobile
   override the design does not have. */

@media (max-width: 1100px) {
  .ch-site .ch-gal .portfolio-items,
  .ch-site .ch-gal .row.portfolio-items { grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); }
}

/* Services go one-up below 640, exactly as the design's own svcTwoUp does. */
@media (max-width: 639px) {
  .ch-site .ch-svc__grid > .row_col_wrap_12_inner { grid-template-columns: minmax(0, 1fr); }
}

/* Salient's burger appears at 1060. Above it the header keeps a real menu, so
   tighten in bands rather than moving the breakpoint. */
@media (max-width: 1200px) {
  .ch-site #header-outer #top nav > ul.sf-menu { gap: 18px; }
  .ch-site #header-outer #top nav > ul.sf-menu > li > a { font-size: .74rem !important; letter-spacing: .1em !important; }
  .ch-site #header-outer .ch-hcta { padding: 1em 1.4em; font-size: .72rem; }
  .ch-site #header-outer .ch-hphone { padding-left: 14px; }
  .ch-site #header-outer #logo img { height: 60px !important; }
  .ch-site #header-outer #top > .container > .row { height: 84px; }
}

@media (max-width: 1060px) {
  .ch-site #header-outer #top > .container > .row { height: 72px; }
  .ch-site #header-outer #logo img { height: 52px !important; }
  /* Below the breakpoint the phone + CTA move into the off-canvas panel. The
     burger is Salient's .mobile-icon toggle in the column, at every width
     below 1060; the copy of it inside ul.buttons stays hidden, or the 1000 to
     1060 band shows two. */
  .ch-site #header-outer #top nav > ul.buttons { display: flex !important; align-items: center; gap: 10px; }
  .ch-site #header-outer #top .col.span_9 > .slide-out-widget-area-toggle.mobile-icon { display: flex !important; }
  /* Salient's mobile header reverses this column's flex direction, which
     turns flex-end into the left edge between 1000 and 1060 (below 1000 the
     burger is absolutely positioned and unaffected). */
  .ch-site #header-outer #top .col.span_9 { flex-direction: row !important; justify-content: flex-end !important; gap: 0; }
  /* the emptied nav (two zero-width lists) must not keep its gaps either */
  .ch-site #header-outer #top nav { gap: 0; }
  .ch-site #header-outer #top .widget_text,
  .ch-site #header-outer #top .nectar-header-text-content { display: none !important; }
  /* the footer goes to two columns before the brand column would crush */
  .ch-site #footer-outer #footer-widgets .container > .row { grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
}

@media (max-width: 999px) {
  /* Salient pulls the secondary header 13px off the top of the screen on
     mobile with a bare #header-secondary-outer{top:-13px}. */
  .ch-site #header-secondary-outer { top: 0 !important; }
}

@media (max-width: 767px) {
  .ch-site .ch-hero { min-height: min(86vh, 640px); }
  .ch-site .ch-band > .row_col_wrap_12 { padding: clamp(52px, 9vw, 90px) 0; }
  .ch-site .ch-band__col > .vc_column-inner > .wpb_wrapper { max-width: none; }
}

@media (max-width: 480px) {
  /* Two inline-flex buttons that wrap have no row gap, and margin-bottom on an
     inline-level atomic box grows the line box on desktop too. Making them
     block-level below a phone breakpoint is the deterministic answer. */
  .ch-site .ch-btnrow__col > .vc_column-inner > .wpb_wrapper { flex-direction: column; align-items: center; }
  .ch-site .ch-btnrow .nectar-button.ch-btn { width: 100%; }
  .ch-site .ch-cc a { padding: 15px 16px; gap: 12px; }
  .ch-site .ch-cc a::after { left: 27.5px; }
  .ch-site .ch-foot__logoimg { height: 48px !important; }
}

@media (max-width: 380px) {
  /* An email address is one unbreakable token and sets the tile's minimum
     width on a small phone. */
  .ch-site .ch-cc--email strong { font-size: .82rem; }
  .ch-site .ch-foot__touch { font-size: .88rem; }
}

/* Salient's global button style writes
   body[data-button-style*="..."] button { border-radius:4px !important }
   which reaches ANY <button> on the site, including CF7's submit. */
.ch-site button,
.ch-site .wpcf7-form button,
.ch-site .wpcf7-form input[type="submit"] { border-radius: 0 !important; }

/* ------------------------------------------------ 22. round-3 polish pass */

/* Anchor targets clear the fixed 88px header instead of sliding under it. */
.ch-site .ch-section[id],
.ch-site .ch-svc[id] { scroll-margin-top: 108px; }
@media (max-width: 1060px) { .ch-site .ch-section[id] { scroll-margin-top: 84px; } }

/* Keyboard users get a visible ring; mouse users do not. */
.ch-site a:focus-visible,
.ch-site button:focus-visible,
.ch-site input:focus-visible,
.ch-site select:focus-visible,
.ch-site textarea:focus-visible {
  outline: 2px solid var(--teal) !important; outline-offset: 3px;
}
.ch-site .ch-hero a:focus-visible,
.ch-site .ch-gallery a:focus-visible,
.ch-site .ch-band a:focus-visible,
.ch-site #footer-outer a:focus-visible { outline-color: #fff !important; }

/* Six accreditation logos, full colour, no labels, each the link to its
   listing. Round 8: the section is white and the plates are gone, so the marks
   float on the page at a larger size ("less blocky"). Six across, three on
   tablet, two on phone (an explicit ladder, because auto-fit orphaned one
   logo on its own row). */
/* Five since round 12, when the client removed BookaBuilderUK. The ladder is
   explicit rather than auto-fit because auto-fit orphaned a logo on its own
   row; the last row centres so an odd count never sits hard left. */
.ch-site .ch-partner__grid > .row_col_wrap_12_inner {
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: clamp(18px, 2.4vw, 32px); align-items: center; justify-items: center;
}
.ch-site .ch-partner { width: 100%; }
@media (max-width: 1100px) { .ch-site .ch-partner__grid > .row_col_wrap_12_inner { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 600px)  { .ch-site .ch-partner__grid > .row_col_wrap_12_inner { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; } }
.ch-site .ch-partner > .vc_column-inner { background: transparent; transition: transform .22s ease; }
.ch-site .ch-partner:hover > .vc_column-inner { transform: translateY(-4px); box-shadow: none; }
/* Salient nests the image as .img-with-aniamtion-wrap > (a) > .hover-wrap >
   .hover-wrap-inner > img with auto heights, so the box sets the size and
   every wrapper is made to fill it; the mark fills the box. */
.ch-site .ch-partner .img-with-aniamtion-wrap {
  display: flex; align-items: center; justify-content: center;
  height: 180px; padding: 0; box-sizing: border-box; overflow: hidden; margin: 0;
}
.ch-site .ch-partner .img-with-aniamtion-wrap a,
.ch-site .ch-partner .hover-wrap,
.ch-site .ch-partner .hover-wrap-inner {
  display: flex; align-items: center; justify-content: center; width: 100%; height: 100%;
}
.ch-site .ch-partner img.ch-partner__logo {
  width: auto !important; height: auto !important;
  max-width: 100%; max-height: 100%; object-fit: contain;
  transition: transform .3s ease;
}
.ch-site .ch-partner:hover img.ch-partner__logo { transform: scale(1.04); }

/* Form: the field label lights up while its input is focused. */
.ch-site .wpcf7-form label:focus-within { color: var(--teal); }
.ch-site .wpcf7-form label:has(input[type="file"]):focus-within,
.ch-site .wpcf7-form label:has(input[type="file"]):hover { background: var(--teal-wash); }

/* Contact cards: a small arrow tells the eye they are links. */
.ch-site .ch-cc a { transition: border-color .18s ease, transform .18s ease; }
.ch-site .ch-cc:hover { border-color: var(--teal); }
.ch-site .ch-cc:hover a { transform: translateX(2px); }

/* Why cards: the photo eases in on hover, like the service and gallery tiles. */
.ch-site .ch-why__card img.ch-why__img { transition: transform .6s cubic-bezier(.2,.7,.3,1); }
.ch-site .ch-why__card:hover img.ch-why__img { transform: scale(1.04); }

/* Motion is decoration; honour the OS setting. */
@media (prefers-reduced-motion: reduce) {
  .ch-site *, .ch-site *::before, .ch-site *::after {
    transition-duration: .01ms !important; animation-duration: .01ms !important; scroll-behavior: auto !important;
  }
  .ch-site .ch-svc:hover > .vc_column-inner > .wpb_wrapper::after,
  .ch-site .ch-svc:hover .ch-svc__title, .ch-site .ch-svc:hover .ch-svc__blurb,
  .ch-site .ch-why__card:hover, .ch-site .ch-partner:hover > .vc_column-inner { transform: none !important; }
}

/* ------------------------------------------------ 23. instagram section */

/* profile bar: avatar plate, handle, follow button */
.ch-site .ch-ig__bar > .row_col_wrap_12_inner {
  display: flex; align-items: center; gap: 18px; flex-wrap: wrap;
  padding: 18px 22px;
  background: rgba(255,255,255,.08); border: 1px solid rgba(255,255,255,.14);
}
/* the gap to the grid lives on the row, not on the flex wrapper: Salient's
   isotope wrapper below pulls itself up and swallows a wrapper margin */
.ch-site .ch-gallery .ch-ig__bar.wpb_row { margin-bottom: 18px !important; }
.ch-site .ch-gallery .ch-gal { margin-top: 0 !important; }
.ch-site .ch-ig__bar > .row_col_wrap_12_inner::before,
.ch-site .ch-ig__bar > .row_col_wrap_12_inner::after { display: none !important; }
.ch-site .ch-ig__bar > .row_col_wrap_12_inner > .wpb_column,
.ch-site .ch-ig__bar > .row_col_wrap_12_inner > .vc_element { width: auto !important; margin: 0 !important; float: none !important; min-width: 0; }
.ch-site .ch-ig__avatar { flex: 0 0 auto; }
.ch-site .ch-ig__avatar .img-with-aniamtion-wrap {
  width: 72px; height: 72px; border-radius: 50%; overflow: hidden; background: var(--teal);
  display: flex; align-items: center; justify-content: center; padding: 0; box-sizing: border-box;
  box-shadow: 0 0 0 3px var(--teal), 0 0 0 5px rgba(255,255,255,.35);
}
.ch-site .ch-ig__avatar .hover-wrap, .ch-site .ch-ig__avatar .hover-wrap-inner { display: flex; align-items: center; justify-content: center; width: 100%; height: 100%; }
.ch-site .ch-ig__avatar img { width: 100% !important; height: 100% !important; object-fit: cover; margin: 0 !important; }
.ch-site .ch-ig__who { flex: 1 1 180px; min-width: 0; }
.ch-site .ch-ig__handle p { margin: 0; }
.ch-site .ch-ig__handle a { font-family: var(--display); font-weight: 700; font-size: 1.02rem; color: #fff; letter-spacing: -.01em; overflow-wrap: anywhere; }
.ch-site .ch-ig__handle a:hover { color: var(--lightteal); }
.ch-site .ch-ig__sub p { color: #c3d9e2; font-size: .9rem; margin: 2px 0 0; }
.ch-site .ch-ig__follow { flex: 0 0 auto; margin-left: auto; }
.ch-site .ch-ig__follow .nectar-button.ch-btn--white { gap: .55em; }
/* Salient's has-icon layout floats the <i> to a corner and writes the resting
   colour on it inline, which is why it stayed dark on the teal hover. Bring it
   into the flex row ahead of the text and let it follow the button's colour. */
/* the material skin also slides every has-icon label 18px left to clear a
   corner icon (`body.material .nectar-button.has-icon span`), at rest AND on
   hover, which is what put the label under the glyph */
.ch-site .ch-ig__follow .nectar-button.has-icon > span,
.ch-site .ch-ig__follow .nectar-button.has-icon:hover > span { padding: 0 !important; margin: 0 !important; transform: none !important; left: 0 !important; }
.ch-site .ch-ig__follow .nectar-button.has-icon > i {
  position: static !important; top: auto !important; left: auto !important; right: auto !important;
  transform: none !important; margin: 0 !important; padding: 0 !important; order: -1;
  width: auto !important; height: auto !important; line-height: 1 !important;
  font-size: 1.2em !important; color: inherit !important; opacity: 1 !important; display: inline-block;
}
.ch-site .ch-ig__follow .nectar-button.ch-btn--sm::after { display: none; }

/* square, tight grid: the Gallery page's own photographs. The service pages
   borrow this block for their photograph strips and re-shape the tiles in
   section 26, because those are landscape site photographs, not feed posts.
   The Smash Balloon rules that used to follow this went with the plugin in
   round 13: the homepage feed is the client's Trustindex widget now, and it
   brings its own stylesheet. */
.ch-site .ch-gal .portfolio-items,
.ch-site .ch-gal .row.portfolio-items { gap: 8px; }
.ch-site .ch-gal .portfolio-items .col { aspect-ratio: 1 / 1; }
.ch-site .ch-gal .portfolio-items .col .work-item { background: rgba(255,255,255,.08); }
.ch-site #sb_instagram #sbi_load .sbi_load_btn,
.ch-site #sb_instagram #sbi_load .sbi_follow_btn a {
  background: #fff !important; color: var(--teal-deep) !important; border-radius: 0 !important;
  font-family: var(--display); font-weight: 700; font-size: .78rem; letter-spacing: .14em; text-transform: uppercase;
  padding: 1.1em 2em !important; box-shadow: none !important;
}
.ch-site #sb_instagram .sbi_follow_btn a { background: var(--teal) !important; color: #fff !important; }
@media (max-width: 767px) {
  .ch-site #sb_instagram #sbi_images { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* two across on a phone, as Instagram itself lays out a profile grid */
  .ch-site .ch-gal .portfolio-items,
  .ch-site .ch-gal .row.portfolio-items { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 6px; }
  .ch-site .ch-ig__bar > .row_col_wrap_12_inner { padding: 16px; gap: 12px; }
  /* a 27-character handle must stay on one line beside a smaller avatar */
  .ch-site .ch-ig__avatar .img-with-aniamtion-wrap { width: 56px; height: 56px; }
  .ch-site .ch-ig__handle a { font-size: .85rem; }
  .ch-site .ch-ig__sub p { font-size: .84rem; }
  /* (0,4,0): must outrank the desktop bar's width:auto !important on its children */
  .ch-site .ch-ig__bar > .row_col_wrap_12_inner > .ch-ig__follow { margin-left: 0; width: 100% !important; flex: 1 1 100%; }
  .ch-site .ch-ig__follow .nectar-button,
  .ch-site .wpb_wrapper .ch-ig__follow .ch-btn { display: flex !important; justify-content: center; width: 100% !important; }
}
/* 360 leaves 222px beside the avatar; the handle measures 215px at 12.5px */
@media (max-width: 380px) {
  .ch-site .ch-ig__handle a { font-size: .78rem; }
}

/* ------------------------------------------------ 24. round-7 additions */

/* Floating WhatsApp button (printed by functions.php on every page). WhatsApp's
   deep green rather than its bright one: 4.0:1 against white and it sits with
   the site's teal. Salient's back-to-top control moves up to make room. */
.ch-wa {
  position: fixed; z-index: 9990; right: 24px; bottom: 24px;
  display: flex; align-items: center; gap: 0;
  height: 56px; min-width: 56px; padding: 0 0 0 56px; box-sizing: border-box;
  border-radius: 28px; background: #128c7e; color: #fff !important; text-decoration: none;
  box-shadow: 0 10px 24px -8px rgba(9,32,42,.55);
  transition: background .2s ease, transform .2s ease, box-shadow .2s ease, padding .25s ease;
}
.ch-wa::before {
  content: ""; position: absolute; left: 15px; top: 15px; width: 26px; height: 26px; background: #fff;
  -webkit-mask: var(--ic-wa) center/contain no-repeat; mask: var(--ic-wa) center/contain no-repeat;
}
.ch-wa__label {
  max-width: 0; overflow: hidden; white-space: nowrap; opacity: 0;
  font-family: var(--display); font-weight: 700; font-size: .82rem; letter-spacing: .04em;
  transition: max-width .25s ease, opacity .2s ease, padding .25s ease;
}
.ch-wa:hover, .ch-wa:focus-visible { background: #0f7a6e; transform: translateY(-2px); box-shadow: 0 16px 30px -10px rgba(9,32,42,.6); }
.ch-wa:hover .ch-wa__label, .ch-wa:focus-visible .ch-wa__label { max-width: 140px; opacity: 1; padding-right: 20px; }
.ch-wa:focus-visible { outline: 2px solid #fff; outline-offset: 3px; }
#to-top { bottom: 96px !important; right: 30px !important; }
@media (max-width: 767px) {
  .ch-wa { right: 16px; bottom: 16px; height: 52px; min-width: 52px; padding-left: 52px; border-radius: 26px; }
  .ch-wa::before { left: 13px; top: 13px; }
  .ch-wa:hover .ch-wa__label { max-width: 0; opacity: 0; padding-right: 0; }
}

/* Page header band on the inner pages: photograph, tint, copy. Same layer
   order as the "No job is too big" band. */
.ch-site .ch-section.ch-phead {
  position: relative; isolation: isolate; display: grid; overflow: hidden;
  min-height: clamp(300px, 34vw, 420px); background: var(--ink);
  padding-top: 0 !important; padding-bottom: 0 !important;
}
.ch-site .ch-phead .row-bg-wrap { z-index: 0; }
.ch-site .ch-phead .row-bg { background-size: cover !important; background-position: center center !important; }
.ch-site .ch-phead > .row-bg-wrap::after {
  content: ""; display: block; position: absolute; inset: 0; z-index: 2;
  background: linear-gradient(90deg, rgba(9,32,42,.82) 0%, rgba(9,32,42,.62) 55%, rgba(9,32,42,.4) 100%);
}
.ch-site .ch-phead > .row_col_wrap_12 { position: relative; z-index: 3; align-self: center; }
.ch-site .ch-phead__col > .vc_column-inner > .wpb_wrapper { max-width: 760px; padding: clamp(56px, 7vw, 96px) 0; }
.ch-site .ch-phead__lead p { color: #d3e3ea; font-size: clamp(1rem, 1.3vw, 1.14rem); margin-top: 18px !important; max-width: 58ch; }

/* Service page: photograph beside the copy. */
.ch-site .ch-svcpage > .row_col_wrap_12 {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: clamp(36px, 5vw, 68px); align-items: center;
}
.ch-site .ch-svcpage__media .img-with-aniamtion-wrap { display: block; aspect-ratio: 4 / 3; overflow: hidden; background: var(--line-2); }
.ch-site .ch-svcpage__media .inner, .ch-site .ch-svcpage__media .hover-wrap, .ch-site .ch-svcpage__media .hover-wrap-inner { display: block; width: 100%; height: 100%; }
.ch-site .ch-svcpage__media img.ch-svcpage__img { width: 100% !important; height: 100% !important; object-fit: cover; margin: 0 !important; }
.ch-site .ch-svcpage__copy .ch-pills { margin-top: 22px !important; }
.ch-site .ch-svcpage__copy .nectar-button.ch-btn--teal { margin-top: 30px !important; }

/* The contact section on its own page sits directly under the header band, so
   its heading needs no eyebrow gap above it. */
.ch-site .ch-contact--page .ch-h2 { margin-top: 0 !important; }

/* Primary nav dropdown (Services). Salient's own panel is dark; this one is
   the site's white card with the nav's own type. */
/* Each top-level item spans the full bar, so the panel hangs from the bar's
   bottom edge (not from a 26px line box a third of the way up) and the hover
   target is the whole bar height. */
.ch-site #header-outer #top nav > ul.sf-menu > li { height: 94px; display: flex; align-items: center; }
.ch-site #header-outer #top nav > ul.sf-menu > li > ul.sub-menu {
  top: 100% !important; left: 0 !important;
  background: #fff !important; border: 1px solid var(--line); box-shadow: 0 18px 40px -18px rgba(9,32,42,.35);
  padding: 8px 0 !important; min-width: 290px; margin-top: 0 !important; border-radius: 0 !important;
  white-space: nowrap;
}
@media (max-width: 1200px) { .ch-site #header-outer #top nav > ul.sf-menu > li { height: 84px; } }
.ch-site #header-outer #top nav > ul.sf-menu > li > ul.sub-menu li { margin: 0 !important; padding: 0 !important; list-style: none; }
.ch-site #header-outer #top nav > ul.sf-menu > li > ul.sub-menu li::before,
.ch-site #header-outer #top nav > ul.sf-menu > li > ul.sub-menu li::marker { content: none !important; }
.ch-site #header-outer #top nav > ul.sf-menu > li > ul.sub-menu li > a {
  display: block !important; padding: 11px 22px !important; margin: 0 !important;
  font-family: var(--display) !important; font-weight: 600 !important; font-size: .74rem !important;
  letter-spacing: .1em !important; text-transform: uppercase !important; color: var(--ink) !important;
  background: transparent !important; line-height: 1.5 !important; transition: color .18s ease, background .18s ease;
}
.ch-site #header-outer #top nav > ul.sf-menu > li > ul.sub-menu li > a:hover,
.ch-site #header-outer #top nav > ul.sf-menu > li > ul.sub-menu li.current-menu-item > a { color: var(--teal) !important; background: var(--ground) !important; }
.ch-site #header-outer #top nav > ul.sf-menu > li > ul.sub-menu li > a .menu-title-text::after { display: none !important; }
/* the parent item shows a small chevron after its label */
.ch-site #header-outer #top nav > ul.sf-menu > li.menu-item-has-children > a .menu-title-text { padding-right: 14px; }
/* The span carries 5px of bottom padding for the underline, so its 50% is
   2.5px below the text's centre line, and the V drawn from a rotated square's
   two edges has its visible weight 2.1px below the box centre. Measured
   against the caps' centre line (baseline minus half the cap height, Sora
   600 at 12.8px): a 3px lift puts the V on it. */
.ch-site #header-outer #top nav > ul.sf-menu > li.menu-item-has-children > a .menu-title-text::before {
  content: "" !important; position: absolute; right: 0; top: calc(50% - 2.5px); width: 6px; height: 6px; margin-top: 0;
  border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor;
  transform: translateY(calc(-50% - 3px)) rotate(45deg);
  background: none !important;
}
/* current page: the underline the hover draws, held. Page items only: an
   anchor item is never "current" (functions.php strips the classes WordPress
   gives it, and Salient's scroll highlighting is not wanted either). */
.ch-site #header-outer #top nav > ul.sf-menu > li.menu-item-object-page.current-menu-item > a .menu-title-text::after,
.ch-site #header-outer #top nav > ul.sf-menu > li.menu-item-object-page.current-menu-ancestor > a .menu-title-text::after,
.ch-site #header-outer #top nav > ul.sf-menu > li.menu-item-object-page.current_page_parent > a .menu-title-text::after { transform: scaleX(1); }

/* ------------------------------------- 25. inner pages (client content) */

/* TRUST STRIP. Three badges the client sets under every page title: in the
   hero they sit on the photograph, on an inner page they sit on their own
   white band under the header. */
.ch-site .ch-trust > .row_col_wrap_12_inner {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(12px, 1.6vw, 20px); margin-top: 40px;
}
/* The padding needs !important twice over: '.ch-site .wpb_text_column p' zeroes
   it, and 'p:last-child' at (0,3,1) zeroes the bottom edge again, which is what
   left these badges 33px tall and looking like a stretched rule. */
.ch-site .ch-trust__item p {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  min-height: 62px; padding: 16px 18px !important;
  font-family: var(--display); font-weight: 700;
  font-size: clamp(.72rem, .9vw, .82rem); letter-spacing: .12em; text-transform: uppercase;
  line-height: 1.45; text-align: center; color: #fff;
  border: 1px solid rgba(255,255,255,.3); background: rgba(255,255,255,.1);
}
/* the hero column is narrower than the page strip, so the longest badge wraps
   there; stretching the chain keeps all three the same height either way */
.ch-site .ch-trust__col > .vc_column-inner,
.ch-site .ch-trust__col > .vc_column-inner > .wpb_wrapper,
.ch-site .ch-trust__item,
.ch-site .ch-trust__item p { height: 100%; }
.ch-site .ch-trust__item p::before {
  content: ""; flex: 0 0 auto; width: 17px; height: 17px; background: currentColor;
  -webkit-mask: var(--ic-check) center/contain no-repeat; mask: var(--ic-check) center/contain no-repeat;
  opacity: .9;
}
/* on a white band the same badges invert to the brand teal */
.ch-site .ch-section.ch-trustband {
  background: #fff; border-bottom: 1px solid var(--line);
  padding-top: clamp(28px, 3.2vw, 44px) !important; padding-bottom: clamp(28px, 3.2vw, 44px) !important;
}
.ch-site .ch-trustband .ch-trust > .row_col_wrap_12_inner { margin-top: 0; }
.ch-site .ch-trustband .ch-trust__item p {
  color: var(--teal-deep); border-color: var(--teal-line); background: var(--teal-wash);
}
/* the band is a thin strip, so the section under it need not restate the full
   page rhythm on top of it */
.ch-site .ch-section.ch-trustband + .ch-section { padding-top: clamp(52px, 6vw, 80px) !important; }

/* FEATURE GROUPS. A named list of what a service covers: a heading, then a
   two-column grid of title + paragraph. */
.ch-site .ch-section.ch-feat { background: #fff; }
.ch-site .ch-feat__col + .ch-feat__col { margin-top: clamp(44px, 5vw, 72px); }
.ch-site .ch-feat__grid > .row_col_wrap_12_inner {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(20px, 2.2vw, 28px); margin-top: 34px;
}
/* !important, and not by preference: '.ch-site .wpb_column,
   .ch-site .vc_column-inner { padding: 0 !important }' is the base reset every column
   on the site relies on, so a card that wants padding has to say so as loudly.
   Without this the feature cards rendered with text hard against the border. */
.ch-site .ch-feat__item > .vc_column-inner {
  height: 100%; background: var(--ground); border: 1px solid var(--line);
  border-left: 3px solid var(--teal);
  padding: clamp(24px, 2.4vw, 32px) !important;
  transition: border-color .2s ease, transform .2s ease, box-shadow .2s ease;
}
.ch-site .ch-feat__item:hover > .vc_column-inner {
  border-left-color: var(--teal-deep); transform: translateY(-3px);
  box-shadow: 0 22px 40px -30px rgba(9,32,42,.5);
}
.ch-site .ch-feat__body p { color: var(--body); font-size: .98rem; line-height: 1.72; }
/* a body-only group is a paragraph, not a grid: hold it to a readable measure
   instead of letting it run the full 1300px strip */
.ch-site .ch-feat__col > .vc_column-inner > .wpb_wrapper > .ch-body p { max-width: 82ch; margin-top: 16px !important; }

/* CLOSING LINE. The sentence and button the client ends a service list with. */
.ch-site .ch-section.ch-closing {
  background: #fff;
  padding-top: 0 !important; padding-bottom: clamp(56px, 7vw, 92px) !important;
}
.ch-site .ch-closing__col > .vc_column-inner > .wpb_wrapper { text-align: center; padding-top: clamp(40px, 5vw, 64px); border-top: 1px solid var(--line); }
.ch-site .ch-closing .nectar-button.ch-btn--teal { margin-top: 28px !important; }

/* THREE STEPS. The client's "How does it work?" on the brand teal, numbered
   by a CSS counter so inserting a step renumbers the row. */
.ch-site .ch-section.ch-steps { background: var(--teal); color: #fff; }
.ch-site .ch-steps .ch-head { margin-bottom: clamp(32px, 4vw, 48px) !important; }
.ch-site .ch-step__grid > .row_col_wrap_12_inner {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(24px, 3vw, 44px); counter-reset: ch-step;
}
.ch-site .ch-step { counter-increment: ch-step; }
/* the 54px number is absolutely positioned at the top of the column, so the
   column has to reserve room for it; the base reset was zeroing that padding
   and dropping the badge straight on top of the step title */
.ch-site .ch-step > .vc_column-inner { height: 100%; padding-top: 76px !important; position: relative; }
.ch-site .ch-step > .vc_column-inner::before {
  content: counter(ch-step, decimal-leading-zero);
  position: absolute; left: 0; top: 0;
  display: grid; place-items: center; width: 54px; height: 54px;
  font-family: var(--display); font-weight: 600; font-size: 1.05rem; letter-spacing: .02em;
  color: #fff; border: 1px solid rgba(255,255,255,.45);
}
.ch-site .ch-step > .vc_column-inner::after {
  content: ""; position: absolute; left: 70px; top: 27px; right: 0; height: 1px;
  background: rgba(255,255,255,.26);
}
.ch-site .ch-step:last-child > .vc_column-inner::after { display: none; }
.ch-site .ch-step__body p { color: #c9dee7; font-size: 1rem; line-height: 1.75; }

/* BENEFIT CARDS. */
.ch-site .ch-section.ch-bens { background: var(--ground); border-top: 1px solid var(--line); }
.ch-site .ch-bens .ch-head { margin-bottom: clamp(30px, 4vw, 44px) !important; }
.ch-site .ch-ben__grid > .row_col_wrap_12_inner {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: clamp(20px, 2.4vw, 30px);
}
.ch-site .ch-ben > .vc_column-inner {
  height: 100%; background: #fff; border: 1px solid var(--line);
  padding: clamp(26px, 2.6vw, 34px) !important;
  transition: transform .2s ease, box-shadow .2s ease;
}
.ch-site .ch-ben:hover > .vc_column-inner { transform: translateY(-4px); box-shadow: 0 24px 44px -30px rgba(9,32,42,.5); }
.ch-site .ch-ben > .vc_column-inner > .wpb_wrapper::before {
  content: ""; display: block; width: 34px; height: 3px; background: var(--teal); margin-bottom: 18px;
}
.ch-site .ch-ben__body p { color: var(--body); font-size: .98rem; line-height: 1.7; }

/* FAQs. Salient's own accordion, restored for the inner pages: its 2px h3
   bars are only as wide as the inline-block h3, which reads as a short second
   line and pushes the + into the middle of the row. */
.ch-site .ch-section.ch-faqs { background: #fff; }
.ch-site .ch-faqs > .row_col_wrap_12 {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: clamp(30px, 4vw, 56px); align-items: start;
}
.ch-site .ch-faqs__copy .ch-lead--narrow p { max-width: 38ch; }
.ch-site .ch-faqs__list { margin-top: 6px; }
.ch-site .ch-faqs__list .toggles { border-top: 1px solid var(--line-2); }
.ch-site .ch-faqs__list .toggle {
  border-bottom: 1px solid var(--line-2); background: transparent;
  transition: background .3s ease; margin: 0 !important; padding: 0 !important;
}
.ch-site .ch-faqs__list .toggle.open { background: var(--ground); }
.ch-site .ch-faqs__list .toggle > h3,
.ch-site .ch-faqs__list .toggle > h3 > a {
  background: none !important; border: 0 !important; margin: 0 !important; display: block;
}
.ch-site .ch-faqs__list .toggle > h3::before,
.ch-site .ch-faqs__list .toggle > h3::after { display: none !important; content: none !important; }
.ch-site .ch-faqs__list .toggle > h3 > a {
  position: relative; padding: 24px 54px 24px 22px !important;
  font-family: var(--display) !important; font-weight: 600 !important;
  font-size: 1.02rem !important; line-height: 1.5 !important; letter-spacing: -.005em;
  color: var(--ink) !important; text-transform: none !important;
  transition: color .2s ease;
}
.ch-site .ch-faqs__list .toggle > h3 > a:hover,
.ch-site .ch-faqs__list .toggle.open > h3 > a { color: var(--teal) !important; }
/* the + / x is drawn, never an icon font: Salient's own <i> is hidden below */
.ch-site .ch-faqs__list .toggle > h3 > a::before,
.ch-site .ch-faqs__list .toggle > h3 > a::after {
  content: ""; position: absolute; right: 22px; top: 50%; background: var(--teal);
  transition: transform .3s ease, opacity .3s ease;
}
.ch-site .ch-faqs__list .toggle > h3 > a::before { width: 14px; height: 2px; margin-top: -1px; }
.ch-site .ch-faqs__list .toggle > h3 > a::after  { width: 2px; height: 14px; margin-top: -7px; right: 28px; }
.ch-site .ch-faqs__list .toggle.open > h3 > a::after { transform: rotate(90deg); opacity: 0; }
.ch-site .ch-faqs__list .toggle i { display: none !important; }
/* Salient's JS writes a FIXED inline max-height measured at init, before our
   padding applies, which clipped the longer answers. Class-driven instead. */
.ch-site .ch-faqs__list .toggle .toggle-content,
.ch-site .ch-faqs__list .toggle > div[role="region"] {
  max-height: 0 !important; overflow: hidden;
  transition: max-height .4s cubic-bezier(.2,.7,.3,1);
}
.ch-site .ch-faqs__list .toggle.open .toggle-content,
.ch-site .ch-faqs__list .toggle.open > div[role="region"] { max-height: 460px !important; }
/* the answer is a BARE TEXT NODE inside .inner-toggle-wrap, not a <p> */
/* !important: Salient's own 'div[data-style="minimal"] .toggle[...] > div
   .inner-toggle-wrap { padding: 0 0 30px }' carries two TYPE selectors, so it
   beats a four-class rule of ours and the answer lost its left inset, sitting
   22px to the left of the question it belongs to. */
.ch-site .ch-faqs__list .toggle .inner-toggle-wrap,
.ch-site .ch-faqs__list .toggle p {
  padding: 4px 54px 28px 22px !important; color: var(--body); font-size: 1rem; line-height: 1.75;
}
.ch-site .ch-faqs__list .toggle .inner-toggle-wrap p { padding: 0 !important; }
.ch-site .toggle > h3 > a:focus-visible { outline: 2px solid var(--teal) !important; outline-offset: -3px; }

/* The FAQ is a two-column split on desktop, but below the burger breakpoint
   the accordion column drops to ~360px and every question wraps to three or
   four lines. Measured at 1024, 900, 820 and 768: stacking gives the questions
   the full strip and puts each back on one line. */
@media (max-width: 1060px) {
  .ch-site .ch-faqs > .row_col_wrap_12 { grid-template-columns: minmax(0, 1fr); gap: clamp(22px, 3vw, 34px); }
  .ch-site .ch-faqs__copy .ch-lead--narrow p { max-width: 64ch; }
  .ch-site .ch-faqs__list { margin-top: 0; }
}

@media (max-width: 767px) {
  .ch-site .ch-trust > .row_col_wrap_12_inner { grid-template-columns: minmax(0, 1fr); gap: 8px; margin-top: 30px; }
  .ch-site .ch-feat__grid > .row_col_wrap_12_inner,
  .ch-site .ch-step__grid > .row_col_wrap_12_inner { grid-template-columns: minmax(0, 1fr); }
  .ch-site .ch-step > .vc_column-inner { padding-top: 66px; }
  .ch-site .ch-step > .vc_column-inner::after { display: none; }
  .ch-site .ch-faqs__list .toggle > h3 > a { padding: 20px 46px 20px 16px !important; font-size: .98rem !important; }
  .ch-site .ch-faqs__list .toggle .inner-toggle-wrap,
  .ch-site .ch-faqs__list .toggle p { padding: 4px 46px 24px 16px !important; }
}

/* ============================================================================
   21. AUTHORITATIVE HEADING BLOCK - MUST STAY LAST IN THIS FILE
   ----------------------------------------------------------------------------
   Salient sizes every heading below 999px with
     .wpb_wrapper hN.vc_custom_heading { font-size: N !important }   = (0,2,2)
   and paints every heading with the Theme Options primary text colour. A plain
   .ch-x rule is (0,2,0) and LOSES even with !important, because specificity
   compares CLASS COUNT before element count. Everything below is (0,3,0) via
   `.ch-site .wpb_wrapper .ch-x`, which wins.

   Per-context colour and margin live here too, for exactly the same reason:
   this block would otherwise override them.
   ========================================================================= */

.ch-site .wpb_wrapper .ch-hero__h1 {
  font-family: var(--display) !important;
  font-weight: 600 !important;
  font-size: clamp(2rem, 4.8vw, 3.5rem) !important;
  line-height: 1.24 !important;
  letter-spacing: -.015em !important;
  color: #fff !important;
  margin: 22px 0 0 !important;
  text-transform: none !important;
  text-wrap: pretty;
}

.ch-site .wpb_wrapper .ch-h2 {
  font-family: var(--display) !important;
  font-weight: 600 !important;
  font-size: clamp(1.7rem, 3vw, 2.4rem) !important;
  line-height: 1.24 !important;
  letter-spacing: .01em !important;
  text-transform: uppercase !important;
  color: var(--ink) !important;
  margin: 16px 0 14px !important;
  text-wrap: pretty;
}
.ch-site .wpb_wrapper .ch-h2--light { color: #fff !important; }

.ch-site .wpb_wrapper .ch-feat__h {
  font-family: var(--display) !important;
  font-weight: 600 !important;
  font-size: clamp(1.35rem, 2.1vw, 1.8rem) !important;
  line-height: 1.26 !important;
  letter-spacing: .01em !important;
  text-transform: uppercase !important;
  color: var(--ink) !important;
  margin: 10px 0 0 !important;
}

.ch-site .wpb_wrapper .ch-feat__title {
  font-family: var(--display) !important;
  font-weight: 700 !important;
  font-size: 1.04rem !important;
  line-height: 1.4 !important;
  letter-spacing: -.005em !important;
  text-transform: none !important;
  color: var(--teal-deep) !important;
  margin: 0 0 10px !important;
}

.ch-site .wpb_wrapper .ch-step__title {
  font-family: var(--display) !important;
  font-weight: 700 !important;
  font-size: 1.18rem !important;
  line-height: 1.34 !important;
  letter-spacing: -.01em !important;
  text-transform: none !important;
  color: #fff !important;
  margin: 0 0 10px !important;
}

.ch-site .wpb_wrapper .ch-ben__title {
  font-family: var(--display) !important;
  font-weight: 700 !important;
  font-size: 1.08rem !important;
  line-height: 1.36 !important;
  letter-spacing: -.005em !important;
  text-transform: none !important;
  color: var(--ink) !important;
  margin: 0 0 10px !important;
}

.ch-site .wpb_wrapper .ch-phead__h1 {
  font-family: var(--display) !important;
  font-weight: 600 !important;
  font-size: clamp(1.9rem, 3.6vw, 2.9rem) !important;
  line-height: 1.2 !important;
  letter-spacing: -.01em !important;
  color: #fff !important;
  margin: 16px 0 0 !important;
  text-transform: none !important;
  text-wrap: pretty;
}
.ch-site .wpb_wrapper .ch-h2--sm {
  font-size: clamp(1.35rem, 2.3vw, 1.85rem) !important;
  line-height: 1.28 !important;
  margin: 14px 0 0 !important;
}

.ch-site .wpb_wrapper .ch-band__h2 {
  font-family: var(--display) !important;
  font-weight: 600 !important;
  font-size: clamp(1.5rem, 2.6vw, 2.1rem) !important;
  line-height: 1.28 !important;
  letter-spacing: .01em !important;
  text-transform: uppercase !important;
  color: #fff !important;
  margin: 0 !important;
  /* No width cap: the card is 460px wide (see section 9) precisely so the
     design's own two-line break, "No job is too big" over "or too small",
     happens by natural wrapping without the <br> the editor would strip. */
  text-wrap: pretty;
}

/* The horizontal margins belong HERE, not in the services section above: this
   block sets margin at (0,3,0) and later in the file, so a per-context margin
   written anywhere else loses to it silently. */
.ch-site .wpb_wrapper .ch-svc__title {
  font-family: var(--display) !important;
  font-weight: 600 !important;
  font-size: clamp(1.2rem, 1.75vw, 1.5rem) !important;
  line-height: 1.3 !important;
  letter-spacing: .015em !important;
  text-transform: uppercase !important;
  color: #fff !important;
  margin: calc(-1 * var(--ch-svc-lift)) var(--ch-svc-inset) 0 !important;
  padding: var(--ch-svc-pad) var(--ch-svc-pad) 0 !important;
  background: transparent !important;
  position: relative;
  transition: transform .5s cubic-bezier(.16,.8,.28,1);
  text-wrap: pretty;
}
.ch-site .wpb_wrapper .ch-svc:hover .ch-svc__title { transform: translateY(-8px); }

.ch-site .wpb_wrapper .ch-why__title {
  font-family: var(--display) !important;
  font-weight: 700 !important;
  font-size: 1.1rem !important;
  line-height: 1.3 !important;
  letter-spacing: .01em !important;
  text-transform: uppercase !important;
  color: var(--ink) !important;
  margin: 0 0 12px !important;
  padding-top: 28px !important;
}


.ch-site .wpb_wrapper .ch-form__title {
  font-family: var(--display) !important;
  font-weight: 600 !important;
  font-size: clamp(1.35rem, 2vw, 1.7rem) !important;
  line-height: 1.2 !important;
  letter-spacing: .01em !important;
  text-transform: uppercase !important;
  color: var(--ink) !important;
  margin: 12px 0 0 !important;
}

.ch-site .wpb_wrapper .ch-hours__title {
  font-family: var(--display) !important;
  font-weight: 700 !important;
  font-size: .78rem !important;
  letter-spacing: .14em !important;
  text-transform: uppercase !important;
  color: var(--soft) !important;
  line-height: 1.62 !important;
  margin: 22px 0 0 !important;
  background: #fff;
  border: 1px solid var(--line);
  border-bottom: 0;
  padding: 20px 22px 14px !important;
}

/* The design closes the form panel with a small print line. It lives outside
   the CF7 template on purpose: a bare text line inside the form would be
   wrapped by CF7 autop into a <p> that our grid then has to special-case, and
   it is a paragraph the client should be able to edit without opening the form
   builder. */
.ch-site .ch-form__note p {
  color: #8b9ba2; font-size: .79rem; line-height: 1.62; text-wrap: pretty;
}
.ch-site .ch-form__note { margin-top: 18px !important; }

/* ==========================================================================
   26. ROUND 13
   Equal service cards, the service-page photograph strips, Google reviews.
   ========================================================================== */

/* SERVICE CARDS, ALL THE SAME LENGTH.
   "can these boxes be all the same length pls?" The four cards differ only
   because the client's blurbs differ, so the fix is structural rather than a
   trimmed sentence: grid-auto-rows makes BOTH rows the height of the tallest
   card, the column fills that height, and the blurb is the piece that grows,
   which pins every "Learn more" to the same baseline. The photograph must not
   be allowed to stretch with it, hence flex: 0 0 auto.
   This block sets display on .wpb_wrapper a second time, at the same four-class
   specificity as the panel block above, so it has to stay AFTER it. */
.ch-site .ch-svc__grid > .row_col_wrap_12_inner { grid-auto-rows: 1fr; }
.ch-site .ch-svc > .vc_column-inner { height: 100%; }
.ch-site .ch-svc > .vc_column-inner > .wpb_wrapper {
  display: flex; flex-direction: column; height: 100%;
}
.ch-site .ch-svc .img-with-aniamtion-wrap { flex: 0 0 auto; }
.ch-site .ch-svc .ch-svc__blurb { flex: 1 1 auto; }
/* one-up, equal heights would only pad the short cards with empty teal */
@media (max-width: 639px) {
  .ch-site .ch-svc__grid > .row_col_wrap_12_inner { grid-auto-rows: auto; }
}

/* SERVICE PAGE PHOTOGRAPH STRIP.
   The client's own photographs for that trade, between what the service covers
   and how it works. The tiles reuse the Gallery page's grid normalisation
   (.ch-gal); only the column count and the caption layer differ, and the
   caption layer goes because these attachments carry no caption to show.
   Both .ch-gal selectors have to be answered: the second one is
   '.row.portfolio-items', which is a class more specific than the first. */
.ch-site .ch-section.ch-work {
  background: var(--ground);
  border-top: 1px solid var(--line);
}
.ch-site .ch-work .ch-head { margin-bottom: clamp(28px, 3.4vw, 42px) !important; }
.ch-site .ch-work .ch-head--center .ch-head__copy { max-width: 640px; }
.ch-site .ch-work__grid .portfolio-items,
.ch-site .ch-work__grid .row.portfolio-items { gap: clamp(14px, 1.8vw, 22px); }
.ch-site .ch-work--2 .portfolio-items,
.ch-site .ch-work--2 .row.portfolio-items { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.ch-site .ch-work--3 .portfolio-items,
.ch-site .ch-work--3 .row.portfolio-items { grid-template-columns: repeat(3, minmax(0, 1fr)); }
/* landscape tiles: these are site photographs, not square feed posts, and the
   .ch-gal block this strip borrows squares them at (0,3,0). */
.ch-site .ch-work__grid .portfolio-items .col { aspect-ratio: 4 / 3; }
.ch-site .ch-work__grid .work-item::after { display: none; }
.ch-site .ch-work__grid .work-info .vert-center p { display: none !important; }
.ch-site .ch-work__grid .portfolio-items .col .work-item { background: var(--line-2); }
@media (max-width: 860px) {
  .ch-site .ch-work--3 .portfolio-items,
  .ch-site .ch-work--3 .row.portfolio-items { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 560px) {
  .ch-site .ch-work--2 .portfolio-items,
  .ch-site .ch-work--2 .row.portfolio-items,
  .ch-site .ch-work--3 .portfolio-items,
  .ch-site .ch-work--3 .row.portfolio-items { grid-template-columns: minmax(0, 1fr); }
}

/* GOOGLE REVIEWS.
   A centred panel between the feed and the accreditations, so the homepage
   runs work, reviews, listings, enquiry. The stars are drawn in CSS because
   they are decoration: the sentence underneath is the accessible text and says
   the same thing, which is why it is not hidden. */
.ch-site .ch-section.ch-reviews {
  background: var(--ground);
  border-bottom: 1px solid var(--line);
  padding-top: clamp(56px, 7vw, 88px) !important;
  padding-bottom: clamp(56px, 7vw, 88px) !important;
}
.ch-site .ch-reviews .ch-head { margin-bottom: clamp(26px, 3vw, 38px) !important; }
.ch-site .ch-reviews .ch-head--center .ch-head__copy { max-width: 620px; }
.ch-site .ch-rev > .row_col_wrap_12_inner { display: grid; justify-items: center; }
.ch-site .ch-rev__card { max-width: 620px; }
.ch-site .ch-rev__card > .vc_column-inner {
  background: #fff; border: 1px solid var(--line);
  padding: clamp(30px, 3.4vw, 46px) !important;
  text-align: center;
}
.ch-site .ch-rev__score p {
  font-family: var(--display); font-weight: 700;
  font-size: clamp(2.6rem, 5vw, 3.4rem); line-height: 1;
  color: var(--ink); letter-spacing: -.02em;
}
.ch-site .ch-rev__stars { margin-top: 12px !important; }
.ch-site .ch-rev__stars p {
  font-family: var(--display); font-weight: 700;
  font-size: .74rem; letter-spacing: .16em; text-transform: uppercase;
  color: var(--soft);
}
.ch-site .ch-rev__stars p::before {
  content: "\2605\2605\2605\2605\2605";
  display: block; margin-bottom: 14px;
  /* a deeper gold than Google's own #f4b400, which measured 1.85:1 on the
     white panel and read as washed out; this is 3.18:1, the non-text contrast
     floor, and still plainly a gold star */
  font-size: 1.5rem; letter-spacing: .14em; line-height: 1; color: #c28400;
}
.ch-site .ch-rev__body { margin-top: 16px !important; }
.ch-site .ch-rev__body p {
  color: var(--body); font-size: 1rem; line-height: 1.72;
  max-width: 44ch; margin-left: auto; margin-right: auto;
}
.ch-site .ch-rev__card .nectar-button.ch-btn--teal { margin-top: 26px !important; }

/* Trustindex renders its own widget from their CDN into the container the
   shortcode prints. Their loader measures that container to size the tiles, so
   it stays a laid-out block while it is still empty rather than being tidied
   away with ':empty { display: none }'. */
.ch-site .ch-reviews .ti-widget,
.ch-site .ch-gallery [id^="trustindex-feed-container"] { max-width: 100%; }
.ch-site .ch-gallery [id^="trustindex-feed-container"] { display: block; min-height: 1px; }

/* Trustindex styles their feed header for a WHITE page. Measured on the built
   widget, the business name comes out #000 and the handle and follower counts
   #828282, which against this section's teal is 2.03:1, and the Follow button
   is their own #4a5df9. The tiles themselves are already white cards and need
   nothing, so only the header is answered here.

   !important, and not by preference: their rules are generated per widget and
   run to seven compound parts, e.g.
   '.ti-widget[data-wkey="..."] .ti-profile-details[data-show-username="true"]
   [data-show-full-name="true"] .ti-name .ti-username'. Out-specifying that
   means copying an attribute chain that changes the moment the client toggles
   a setting in Trustindex; !important does not care what the chain is. These
   four declarations are the whole override, and they can go the day the client
   restyles the widget to a light header at their end. */
.ch-site .ch-gallery .ti-widget .ti-full-name { color: #fff !important; }
.ch-site .ch-gallery .ti-widget .ti-username,
.ch-site .ch-gallery .ti-widget .ti-header-numbers,
.ch-site .ch-gallery .ti-widget .ti-header-numbers .ti-number,
.ch-site .ch-gallery .ti-widget .ti-header-numbers .ti-number div { color: #c9dee7 !important; }
.ch-site .ch-gallery .ti-widget .ti-header-numbers .ti-number div.ti-value { color: #fff !important; }
.ch-site .ch-gallery .ti-widget .ti-header-btn .ti-btn {
  background-color: #fff !important; color: var(--teal-deep) !important;
}
.ch-site .ch-gallery .ti-widget .ti-header-btn .ti-btn:hover { background-color: #eaeff2 !important; }
