/* ==========================================================================
   J Peacock Home Insulations - design stylesheet
   ==========================================================================

   Every value here is taken from the design pack:
     design/JP Header.dc.html
     design/JP Footer.dc.html
     design/J Peacock Homepage.dc.html

   Two scopes:
     .jp-site  every page  - tokens, header, top bar, off-canvas, footer,
                             mobile bar, cookie bar. Global chrome.
     .jp-home  pages carrying the homepage design (content marker jp-section).

   CONTENTS
     01  Tokens
     02  Icon masks
     03  Base + container release
     04  Section rhythm
     05  Buttons and links
     06  Top bar
     07  Header
     08  Off-canvas mobile menu
     09  Mobile action bar
     10  Hero
     11  Stats strip
     12  Towns marquee
     13  Services
     14  Spray foam
     15  About
     16  Steps
     17  Reviews
     18  Areas
     19  Contact + Contact Form 7
     20  Pre-footer CTA
     21  Footer + copyright
     22  Cookie bar
     23  Responsive
     24  AUTHORITATIVE HEADING BLOCK - must stay last, see the note there
   ========================================================================== */


/* ==========================================================================
   01  TOKENS
   Declared on .jp-site, not on .jp-home, so the footer and every other piece
   of global chrome still resolves its var() on pages that are not the
   homepage. Scoping tokens to a single page is what broke the footer on a
   previous build the moment a second page existed.
   ========================================================================== */

body.jp-site {
    --jp-orange:      #F08424;
    --jp-orange-dk:   #DE6A12;
    --jp-orange-soft: rgba(240, 132, 36, .14);
    --jp-orange-lt:   #F9B471;

    /* DARK THEME.
       The client asked for the site to go black, matching their reference
       build. The neutrals are redefined here rather than re-colouring the
       several hundred rules that consume them, so every section, card, border
       and label inverts from one place and nothing drifts out of step.

       --jp-black was doing TWO jobs, dark PANEL and primary TEXT, and a theme
       flip needs those pulling in opposite directions. They are now separate
       roles; the old name is kept only where a genuinely near-black ink is
       still wanted, such as text sitting on the accent orange. */
    --jp-black:       #0F0F0F;   /* literal near-black, no longer a surface  */
    --jp-on-accent:   #0F0F0F;   /* text on the orange, which stays light    */

    --jp-page:        #0D1116;   /* the page itself                          */
    --jp-panel:       #05070A;   /* deepest band, was a black panel on white */
    --jp-surface:     #141B22;   /* cards, was #fff                          */
    --jp-surface-2:   #1A232C;   /* raised surface, inputs                   */
    --jp-fg:          #F5F0E8;   /* primary text, was --jp-black             */

    --jp-ink:         #C9D3DD;
    --jp-body:        #9AA7B4;
    --jp-body-warm:   #B3A899;

    --jp-mute:        #8A95A1;
    --jp-mute-2:      #9AA7B4;
    --jp-mute-3:      #B6C1CC;
    --jp-mute-4:      #77828D;

    --jp-line:        rgba(255, 255, 255, .10);
    --jp-line-2:      rgba(255, 255, 255, .07);
    --jp-stone:       #141B22;
    --jp-off:         #0D1116;

    --jp-hero-lead:   #D3D0CB;
    --jp-hero-chip:   #CFCCC7;
    --jp-sf-li:       #EDEBE8;
    --jp-sf-media:    #1A1A1A;

    --jp-wrap:        1240px;
    --jp-gut:         clamp(18px, 4vw, 40px);
    --jp-rhythm:      clamp(72px, 8vw, 112px);
    --jp-head-h:      clamp(72px, 7vw, 92px);

    --jp-display:     'Sora', sans-serif;
    --jp-text:        'Plus Jakarta Sans', system-ui, sans-serif;

    /* One expression for "max-width N centred inside clamp() gutters", used by
       every section once .container.main-content is released.
       The gutter is INSIDE the 1240 box in the design, not outside it, so it is
       added to the centring offset rather than compared against it. Measured:
       at a 1425px layout width this resolves to 132.5, giving a 1160 content
       strip, which is exactly what the design renders. */
    --jp-pad-x:       calc(var(--jp-gut) + max(0px, (100% - var(--jp-wrap)) / 2));
}


/* ==========================================================================
   02  ICON MASKS
   The design draws its icons as inline SVG. Inline SVG cannot live in a Text
   Block - the editor strips it on save - so the same paths are carried here as
   masks and coloured from CSS. background-color supplies the colour, so one
   mask serves every tone.
   ========================================================================== */

body.jp-site {
    --jp-i-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");
    --jp-i-check-b: 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.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E");
    --jp-i-zoom:    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%230F0F0F' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='M21 21l-4.3-4.3M11 8v6M8 11h6'/%3E%3C/svg%3E");
    --jp-i-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.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12h14M13 6l6 6-6 6'/%3E%3C/svg%3E");
    --jp-i-chev:    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.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
    --jp-i-phone:   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.3' 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-6A19.79 19.79 0 0 1 2.12 4.18 2 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");
    --jp-i-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.5' y='4.5' width='19' height='15' rx='3'/%3E%3Cpath d='m3 7 9 6 9-6'/%3E%3C/svg%3E");
    --jp-i-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.1' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 21s-7-4.6-7-10a7 7 0 0 1 14 0c0 5.4-7 10-7 10Z'/%3E%3Ccircle cx='12' cy='11' r='2.6'/%3E%3C/svg%3E");
    --jp-i-drop:    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='M12 2s4 4.5 4 8a4 4 0 0 1-8 0c0-3.5 4-8 4-8Z'/%3E%3Cpath d='M6 14c0 4 2.7 8 6 8s6-4 6-8'/%3E%3C/svg%3E");
    --jp-i-shield:  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.3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 2 4 6v6c0 5 3.4 9.3 8 10 4.6-.7 8-5 8-10V6l-8-4Z'/%3E%3Cpath d='m9 12 2 2 4-4'/%3E%3C/svg%3E");
    --jp-i-box:     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.3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20.5 7.3 12 12l-8.5-4.7'/%3E%3Cpath d='M12 12v9.5'/%3E%3Cpath d='m3.5 7.3 8.5-4.8 8.5 4.8v9.4L12 21.5l-8.5-4.8V7.3Z'/%3E%3C/svg%3E");
    --jp-i-facebook: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23000'%3E%3Cpath d='M13.5 9H16V6h-2.5C11.6 6 10 7.6 10 9.5V11H8v3h2v7h3v-7h2.2l.3-3H13v-1.2c0-.5.2-.8.5-.8Z'/%3E%3C/svg%3E");
    --jp-i-instagram: 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.5' y='3.5' width='17' height='17' rx='5'/%3E%3Ccircle cx='12' cy='12' r='3.6'/%3E%3Ccircle cx='17' cy='7' r='1.2' fill='%23000' stroke='none'/%3E%3C/svg%3E");
    --jp-i-whatsapp: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23000'%3E%3Cpath d='M12 2a10 10 0 0 0-8.6 15.1L2 22l5-1.3A10 10 0 1 0 12 2Zm0 18a8 8 0 0 1-4.1-1.1l-.3-.2-2.9.8.8-2.8-.2-.3A8 8 0 1 1 12 20Zm4.5-5.7c-.2-.1-1.5-.7-1.7-.8s-.4-.1-.6.1l-.6.7c-.1.2-.3.2-.5.1a6.5 6.5 0 0 1-3.2-2.8c-.1-.2 0-.4.1-.5l.5-.6c.1-.2.1-.3 0-.5l-.7-1.7c-.2-.4-.4-.4-.6-.4h-.5c-.2 0-.5.1-.7.4a2.9 2.9 0 0 0-.9 2.1 5 5 0 0 0 1 2.6 10.4 10.4 0 0 0 4 3.5c1.7.7 2.4.7 3 .6a2.5 2.5 0 0 0 1.7-1.2 2 2 0 0 0 .1-1.2Z'/%3E%3C/svg%3E");
    --jp-i-burger:  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'%3E%3Cline x1='3' y1='7' x2='21' y2='7'/%3E%3Cline x1='3' y1='12' x2='21' y2='12'/%3E%3Cline x1='3' y1='17' x2='21' y2='17'/%3E%3C/svg%3E");
}

.jp-site .jp-mask {
    -webkit-mask-position: center;
            mask-position: center;
    -webkit-mask-size: contain;
            mask-size: contain;
    -webkit-mask-repeat: no-repeat;
            mask-repeat: no-repeat;
}


/* ==========================================================================
   03  BASE + CONTAINER RELEASE
   ========================================================================== */

body.jp-site {
    background: var(--jp-off);
    color: var(--jp-fg);
    font-family: var(--jp-text);
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
    overflow-x: hidden;
}

/* POSITION: STICKY NEEDS A SCROLLING ANCESTOR, and Salient takes that away.
   It sets `body { overflow: hidden }`, which makes the body its own scroll
   container that never actually scrolls, so anything sticky inside pins to a
   box that is not moving and simply scrolls away with the page. That is why
   the scroll sequence advanced correctly but the panel would not hold - the
   frames were right, the pin was not.

   Releasing it puts the viewport back in charge. Horizontal overflow is still
   contained, in two places that do not break sticky: <html> already carries
   overflow-x: hidden, and #ajax-content-wrap uses overflow-x: CLIP, which
   clips without becoming a scroll container the way `hidden` does.

   The off-canvas scroll lock is unaffected: it was already applied to <html>,
   not to the body, for exactly this class of reason. */
body.jp-site { overflow: visible; }
body.jp-site #ajax-content-wrap { overflow-x: clip; }

/* Salient caps page rows inside .container.main-content (max_container_width
   PLUS 90px of side padding). Releasing it lets each row span the real layout
   width, so a full-bleed band needs no 100vw break-out and no scrollbar
   arithmetic, and the 1240 container is then reproduced by --jp-pad-x. */
body.jp-home .container-wrap .container.main-content {
    max-width: none;
    width: 100%;
    padding: 0;
    margin: 0;
}
body.jp-home .container-wrap .container.main-content > .row {
    padding: 0;
    margin: 0;
}
/* .row carries a clearfix. It is not flexed here, but zeroing it keeps the
   released container from inheriting stray height. */
body.jp-home .container-wrap .container.main-content > .row::before,
body.jp-home .container-wrap .container.main-content > .row::after {
    display: none !important;
}

/* Salient's sticky-footer min-height is vh based and inflates the gap above the
   footer at tall viewports. */
body.jp-home .container-wrap { min-height: 0; padding-bottom: 0; }

/* WPBakery/Salient element defaults that fight every layout below. */
body.jp-site .wpb_text_column,
body.jp-site .wpb_content_element { margin-bottom: 0; }
body.jp-site .wpb_text_column p:last-child { margin-bottom: 0; padding-bottom: 0; }
/* Salient sets p { padding-bottom: 1.5em } site-wide. Inside a Text Block its
   own p:last-child reset masks that, which is why it only shows up in widget
   areas and in shortcode-rendered markup - measured 20px on the footer blurb,
   25.4px on the pre-footer lead and 23.8px on every review quote. Spacing in
   this build comes from margins, so the padding is zeroed wherever the design
   is being matched. */
body.jp-site .jp-precta p,
body.jp-site #footer-outer #footer-widgets .col p,
body.jp-site #footer-outer #copyright p,
body.jp-home .jp-rev__card blockquote p { padding-bottom: 0; }
body.jp-site .vc_custom_heading { margin: 0; }
body.jp-site .nectar_icon_wrap { margin-bottom: 0; }

/* Salient adds bullets to any ul in content, including ones we build. */
body.jp-site .jp-ticks ul,
body.jp-site .jp-areas__list ul,
body.jp-site #footer-widgets .widget_nav_menu ul {
    list-style: none !important;
    margin: 0;
    padding: 0;
}
/* Salient adds bullets to any ul in content. The marker is what has to go -
   a blanket `li::before { content:none !important }` also silences the tick
   glyphs these very lists draw with ::before, which is how the hero's three
   trust ticks came out invisible. */
body.jp-site .jp-ticks li::marker,
body.jp-site .jp-areas__list li::marker,
body.jp-site #footer-widgets .widget_nav_menu li::marker { content: none !important; }
body.jp-site .jp-ticks li { list-style: none !important; }


/* ==========================================================================
   04  SECTION RHYTHM

   The design's vertical rhythm is fluid: clamp(72px, 8vw, 112px), applied to
   the TOP of each section only, with no bottom padding except on the last one.
   A fixed number typed into a row's padding field would be correct at exactly
   one viewport width, so the rhythm lives here instead.

   Salient prints inline padding-top/padding-bottom on every row, which is why
   these two need !important. The horizontal padding is not inline, so it does
   not.

   Salient rows are content-box, so padding would be ADDED to 100% and push the
   content past the viewport. border-box on every padded row.
   ========================================================================== */

body.jp-home .jp-section {
    box-sizing: border-box;
    width: 100%;
    margin: 0 !important;              /* rows ship with ~25px margin-bottom */
    padding-top: var(--jp-rhythm) !important;
    padding-bottom: 0 !important;
    padding-left: var(--jp-pad-x);
    padding-right: var(--jp-pad-x);
}
/* Salient's percentage grid puts a NEGATIVE side margin on every row wrapper
   and a matching padding on every column, which is how its 12-column maths
   works. Left alone it drags the content 12.4px outside the padding set above,
   then pushes it back by 12.6px, so nothing lines up to the pixel and the
   compensation disappears entirely on any wrapper this stylesheet grids.
   Zeroing both makes the geometry ours, and removes a 0.25px rounding drift
   that would otherwise show up in every measurement below. */
body.jp-home .jp-section > .row_col_wrap_12,
body.jp-home .jp-section .row_col_wrap_12_inner {
    margin-left: 0 !important;
    margin-right: 0 !important;
    padding-left: 0 !important;
    padding-right: 0 !important;
}
body.jp-home .jp-section > .row_col_wrap_12 > .wpb_column,
body.jp-home .jp-section .row_col_wrap_12_inner > .wpb_column {
    padding-left: 0 !important;
    padding-right: 0 !important;
    /* Salient gives a stacked column a 25px bottom margin. Inside a grid that
       becomes extra ROW height, not a gap - measured 145.2px rows around 120.2px
       cells in the stats strip, which reads as thick grey bands between the
       white boxes instead of the design's 1px hairlines. */
    margin: 0 !important;
}
/* Salient's full-width column is 91.549% wide, not 100%: the missing 8.45% is
   what its negative row margins were putting back. With those margins zeroed
   the column has to state its own width, or a single-column section renders
   98px narrower than its row. Only vc_col-sm-12 is touched, because every
   multi-column section here sits in a grid or flex container that sizes its
   own children.

   The .vc_element pair is the same column as seen by the FRONTEND EDITOR,
   which wraps each one in an extra div and moves the vc_col-sm-12 class onto
   the wrapper; without them the editor renders every full-width section 98px
   narrower than the front end does. */
body.jp-home .jp-section > .row_col_wrap_12 > .wpb_column.vc_col-sm-12,
body.jp-home .jp-section .row_col_wrap_12_inner > .wpb_column.vc_col-sm-12,
body.jp-home .jp-section > .row_col_wrap_12 > .vc_element.vc_col-sm-12,
body.jp-home .jp-section .row_col_wrap_12_inner > .vc_element.vc_col-sm-12 { width: 100% !important; }

/* Sections whose top spacing the design sets differently. */
body.jp-home .jp-hero {
    padding-top: clamp(56px, 7vw, 96px) !important;
    padding-bottom: clamp(96px, 10vw, 140px) !important;
}
body.jp-home .jp-stats {
    padding-top: 0 !important;
    margin-top: clamp(-72px, -6vw, -56px) !important;
    position: relative;
    z-index: 2;
}
body.jp-home .jp-marquee {
    padding: 20px 0 !important;
    padding-left: 0;
    padding-right: 0;
    margin-top: clamp(56px, 6vw, 80px) !important;
    background: var(--jp-panel);
    border-top: 3px solid var(--jp-orange);
    overflow: hidden;
}
body.jp-home .jp-contact { padding-bottom: var(--jp-rhythm) !important; }

/* Sections are top-padded only, because in the light design each one flowed
   into the next on the same background and the following section's top padding
   did the separating. These three now END on a card or a panel against a band
   of a DIFFERENT colour, so with no bottom padding the cards sit hard on the
   edge of the section. They pay for their own bottom space. */
body.jp-home .jp-about,
body.jp-home .jp-steps,
body.jp-home .jp-svc { padding-bottom: var(--jp-rhythm) !important; }


/* ==========================================================================
   05  BUTTONS AND LINKS

   nectar_btn renders <a class="nectar-button ... jp-btn"><span>label</span></a>
   with Salient's own colour classes, so every visual property needs to win
   against those. The icon is a mask on ::after rather than markup, because
   markup inside a button label is not something the client can safely edit.
   ========================================================================== */

body.jp-site a.nectar-button.jp-btn,
body.jp-site .jp-precta .wp-block-button.jp-btn > a {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .6em;
    font-family: var(--jp-text);
    font-weight: 800;
    font-size: 1.02rem;
    line-height: 1.6;
    letter-spacing: 0;
    border-radius: 999px !important;
    border: 0;
    text-transform: none;
    transition: transform .18s ease, background .18s ease, border-color .18s ease, color .18s ease;
    padding: 1.05em 1.9em !important;
    margin: 0 !important;
    box-shadow: none;
}
body.jp-site a.nectar-button.jp-btn > span {
    display: inline;
    padding: 0 !important;
    font: inherit;
    letter-spacing: inherit;
    color: inherit;
}
body.jp-site a.nectar-button.jp-btn::after,
body.jp-site .jp-precta .wp-block-button.jp-btn--arrow > a::after,
body.jp-site .jp-precta .wp-block-button.jp-btn--phone > a::before {
    content: none;
}

/* icon variants */
body.jp-site a.nectar-button.jp-btn--arrow::after,
body.jp-site .jp-precta .wp-block-button.jp-btn--arrow > a::after {
    content: "";
    flex: 0 0 auto;
    width: 17px;
    height: 17px;
    background-color: currentColor;
    -webkit-mask: var(--jp-i-arrow) center/contain no-repeat;
            mask: var(--jp-i-arrow) center/contain no-repeat;
}
body.jp-site a.nectar-button.jp-btn--phone::before,
body.jp-site .jp-precta .wp-block-button.jp-btn--phone > a::before {
    content: "";
    flex: 0 0 auto;
    width: 17px;
    height: 17px;
    background-color: currentColor;
    -webkit-mask: var(--jp-i-phone) center/contain no-repeat;
            mask: var(--jp-i-phone) center/contain no-repeat;
}

/* orange solid */
body.jp-site a.nectar-button.jp-btn--orange,
body.jp-site .jp-precta .wp-block-button.jp-btn--orange > a {
    background-color: var(--jp-orange) !important;
    color: #fff !important;
    box-shadow: 0 16px 34px -14px rgba(240, 132, 36, .85);
}
body.jp-site a.nectar-button.jp-btn--orange:hover {
    transform: translateY(-2px);
    background-color: var(--jp-orange-dk) !important;
    color: #fff !important;
}
/* On the dark spray-foam panel and the pre-footer panel the design inverts the
   hover to white rather than deepening the orange. */
body.jp-site a.nectar-button.jp-btn--onDark:hover,
body.jp-site .jp-precta .wp-block-button.jp-btn--orange > a:hover {
    background-color: var(--jp-fg) !important;
    color: var(--jp-on-accent) !important;
    transform: translateY(-2px);
}

/* Solid secondary.
   This was a BLACK button on a white page. Carried onto the dark theme
   unchanged it became near-black on near-black - measured 1.1:1 against the
   page, which is invisible rather than subtle. The true inversion of "solid
   dark on light" is solid light on dark, so it is now the cream with dark ink,
   which reads instantly and still leaves the solid ORANGE as the primary
   action rather than competing with it. */
body.jp-site a.nectar-button.jp-btn--dark {
    background-color: var(--jp-fg) !important;
    color: var(--jp-on-accent) !important;
    font-size: .98rem;
    padding: 1em 1.7em !important;
}
body.jp-site a.nectar-button.jp-btn--dark:hover {
    transform: translateY(-2px);
    background-color: var(--jp-orange) !important;
    color: var(--jp-on-accent) !important;
}

/* ghost on dark */
body.jp-site a.nectar-button.jp-btn--ghost,
body.jp-site .jp-precta .wp-block-button.jp-btn--ghost > a {
    background-color: rgba(255, 255, 255, .07) !important;
    color: #fff !important;
    border: 1.5px solid rgba(255, 255, 255, .28);
    padding: 1.05em 1.7em !important;
}
body.jp-site .jp-precta .wp-block-button.jp-btn--ghost > a {
    background-color: rgba(255, 255, 255, .08) !important;
    padding: 1.05em 1.8em !important;
}
body.jp-site a.nectar-button.jp-btn--ghost:hover,
body.jp-site .jp-precta .wp-block-button.jp-btn--ghost > a:hover {
    background-color: rgba(255, 255, 255, .16) !important;
    border-color: #fff;
    color: #fff !important;
}

/* text link with a sliding arrow */
body.jp-site a.nectar-button.jp-link {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    background: none !important;
    color: var(--jp-orange-dk) !important;
    font-family: var(--jp-text);
    font-weight: 800;
    font-size: .96rem;
    line-height: 1.6;
    padding: 0 !important;
    margin: 0 !important;
    border: 0;
    border-radius: 0 !important;
    box-shadow: none !important;
    transition: color .18s ease, gap .18s ease;
}
body.jp-site a.nectar-button.jp-link > span { padding: 0 !important; font: inherit; color: inherit; }
body.jp-site a.nectar-button.jp-link::after {
    content: "";
    flex: 0 0 auto;
    width: 16px;
    height: 16px;
    background-color: currentColor;
    -webkit-mask: var(--jp-i-arrow) center/contain no-repeat;
            mask: var(--jp-i-arrow) center/contain no-repeat;
}
body.jp-site a.nectar-button.jp-link:hover { color: var(--jp-fg) !important; gap: 12px; }

/* Salient squares off EVERY <button> on the site via
   body[data-button-style*="..."] button { border-radius:4px !important }.
   Our own selector already outranks that (0,2,0 vs 0,1,1), but the theme rule
   is !important so ours has to be too. */
body.jp-site .jp-form input.wpcf7-submit { border-radius: 999px !important; }


/* ==========================================================================
   06  TOP BAR  (#header-secondary-outer)

   DOM order Salient emits is: ul#social, .nectar-center-text (tagline),
   ul.sf-menu (trust items). The design reads tagline, trust, socials, so the
   three are reordered with flex.

   .nectar-center-text is position:absolute by default, which puts it outside
   the flex flow and makes order/margin silently do nothing. It is set back to
   static first.
   ========================================================================== */

body.jp-site #header-outer #header-secondary-outer {
    background: var(--jp-panel) !important;
    border: 0;
}
body.jp-site #header-secondary-outer > .container {
    max-width: var(--jp-wrap) !important;
    width: 100% !important;
    padding: 0 var(--jp-gut) !important;
    margin: 0 auto !important;
}
body.jp-site #header-secondary-outer nav {
    display: flex;
    align-items: center;
    gap: 18px;
    height: 44px;
    float: none;
    width: 100%;
}
/* Salient's clearfix ::after becomes a flex item with order:0, so it is drawn
   BEFORE every ordered item and the row's 18px gap lands in front of the
   tagline. The tell is that the inset equals the gap exactly - measured 58
   against a 40px container edge. */
body.jp-site #header-secondary-outer nav::before,
body.jp-site #header-secondary-outer nav::after { display: none !important; }
/* .nectar-center-text is position:absolute by default, which puts it outside
   the flex flow and makes order, margin and justify-content silently do
   nothing. It also stretches and centres its text; the design has it hugging
   its content on the left. */
body.jp-site #header-secondary-outer .nectar-center-text {
    position: static !important;
    transform: none !important;
    left: auto !important;
    order: 1;
    flex: 0 0 auto;
    width: auto;
    max-width: none;
    text-align: left;
    margin: 0;
    padding: 0;
    line-height: 1;
}
body.jp-site .jp-tb__tag {
    font-family: var(--jp-display);
    font-style: italic;
    font-size: .8rem;
    font-weight: 600;
    letter-spacing: .02em;
    color: var(--jp-orange);
}

/* trust items */
body.jp-site #header-secondary-outer ul.sf-menu {
    order: 2;
    margin-left: auto !important;
    display: flex;
    align-items: center;
    gap: 16px;
    float: none;
    padding: 0;
}
body.jp-site #header-secondary-outer ul.sf-menu > li { margin: 0; padding: 0; float: none; }
body.jp-site #header-secondary-outer ul.sf-menu > li > a {
    display: flex;
    align-items: center;
    gap: 7px;
    padding: 0 !important;
    line-height: 1;
    color: var(--jp-mute-3) !important;
    cursor: default;
}
body.jp-site #header-secondary-outer ul.sf-menu > li > a > .menu-title-text {
    font-family: var(--jp-text);
    font-size: .8rem;
    font-weight: 600;
    letter-spacing: .02em;
    text-transform: none;   /* Salient uppercases .menu-title-text, not the <a> */
    color: inherit;
}
body.jp-site #header-secondary-outer ul.sf-menu > li.jp-tb-trust > a::before {
    content: "";
    flex: 0 0 auto;
    width: 13px;
    height: 13px;
    background-color: var(--jp-orange);
    -webkit-mask: var(--jp-i-check) center/contain no-repeat;
            mask: var(--jp-i-check) center/contain no-repeat;
}
/* the 1px divider the design puts after the last trust item */
body.jp-site #header-secondary-outer ul.sf-menu::after {
    content: "";
    width: 1px;
    height: 16px;
    background: #333;
    flex: 0 0 auto;
    display: block;
    position: static;
}

/* socials */
body.jp-site #header-secondary-outer ul#social {
    order: 3;
    display: flex;
    align-items: center;
    gap: 10px;
    margin: 0;
    padding: 0;
    float: none;
    list-style: none;
}
body.jp-site #header-secondary-outer ul#social li { margin: 0; padding: 0; float: none; }
/* The design's social group is exactly 65px: three 15px glyphs with two 10px
   gaps. Salient's anchors carry their own padding, which took the group to
   106px - enough to push the icons off a 360px screen once the tagline is
   beside them. Sizing the anchor, not just the glyph, is what fixes it. */
body.jp-site #header-secondary-outer ul#social a {
    display: grid;
    place-items: center;
    width: 15px;
    height: 15px;
    color: var(--jp-mute-3) !important;
    padding: 0 !important;
    margin: 0 !important;
    line-height: 1;
    transition: color .18s ease;
}
body.jp-site #header-secondary-outer ul#social a:hover { color: var(--jp-orange) !important; }
/* Salient's icon font resolves to `icomoon` in this context and the glyphs come
   out as blank 15px boxes. The design's own SVG paths are carried as masks
   instead - same shapes, no dependency on the theme's icon font. */
body.jp-site #header-secondary-outer ul#social i {
    display: block;
    width: 15px;
    height: 15px;
    font-size: 0;
    line-height: 0;
    /* the tint is stated, not inherited: Salient sets its own colour on this
       <i>, so currentColor here resolves to a dark grey, not the bar's text */
    background-color: var(--jp-mute-3);
    -webkit-mask-position: center;
            mask-position: center;
    -webkit-mask-size: contain;
            mask-size: contain;
    -webkit-mask-repeat: no-repeat;
            mask-repeat: no-repeat;
    transition: background-color .18s ease;
}
body.jp-site #header-secondary-outer ul#social a:hover i { background-color: var(--jp-orange); }
body.jp-site #header-secondary-outer ul#social i::before { content: none !important; }
body.jp-site #header-secondary-outer ul#social i.fa-facebook {
    -webkit-mask-image: var(--jp-i-facebook);
            mask-image: var(--jp-i-facebook);
}
body.jp-site #header-secondary-outer ul#social i.fa-instagram {
    -webkit-mask-image: var(--jp-i-instagram);
            mask-image: var(--jp-i-instagram);
}
body.jp-site #header-secondary-outer ul#social i.fa-whatsapp {
    -webkit-mask-image: var(--jp-i-whatsapp);
            mask-image: var(--jp-i-whatsapp);
}

/* THE BAR IS PULLED OFF THE TOP OF THE SCREEN ON A PHONE. Salient ends its own
   `@media (max-width:999px)` block with a bare `#header-secondary-outer{top:-13px}`,
   and the bar is position:relative, so 13px of the 44px strip sits above the
   viewport. Its contents stay centred on the full 44px box, so what is left
   visible is 31px with the text 1px from the top edge and 14px from the bottom.
   That lopsided gap is the cramped top bar, not the padding.

   The design has this bar at top 0 with its content centred in the full 44px,
   measured at 390: strip 0-44, tagline 12-32, icons 15-30. Restoring top:0
   restores exactly that. Desktop already computes to 0, so this is inert there.

   Keyed to 1080, OUR breakpoint, not Salient's 999. 1080 is where the trust
   items leave this bar, and the row only looks lopsided once they have gone -
   between 1000 and 1080 the tagline sat at 40 with 650px of dead space after
   the icons. Splitting the two breakpoints would leave that 80px band looking
   like the fault the client reported. */
@media (max-width: 1080px) {
    body.jp-site #header-secondary-outer { top: 0 !important; }

    /* Client's request, and a deliberate departure from the design: the design
       splits this row, tagline hard left and icons over to the right with the
       slack left over after them. Centring the pair as one group balances that
       slack evenly. The desktop bar, which still carries the trust items
       between them, keeps the design's split. */
    body.jp-site #header-secondary-outer nav { justify-content: center; }
}

/* Salient's animated nav underline reset must be scoped to #top nav, or it also
   deletes the top bar's own pseudo-elements, which is where the ticks live. */
body.jp-site #header-outer #top nav > ul.sf-menu > li > a::before { content: none; }


/* ==========================================================================
   07  HEADER  (#header-outer > header#top)

   The main header's container is `#header-outer #top > .container`, NOT a
   direct child of #header-outer. Writing the rule for the direct child leaves
   the header content 90px inside the page sections while the top bar aligns
   correctly, which reads to a client as "the logo and the nav are on different
   containers". That exact mismatch got a previous build rejected.

   Salient's percentage grid renders .span_9 three pixels past its own row's
   right edge, so the row is flexed instead.
   ========================================================================== */

/* The border-bottom belongs to header#top, which Salient already draws from
   the header-enable-border / header-border-color options. Adding a second one
   here made #header-outer 138px tall against the design's 137, and the extra
   pixel then propagated into #header-space and every section offset below it. */
body.jp-site #header-outer {
    background: rgba(13, 17, 22, .88) !important;   /* dark theme; still translucent so the blur reads */
    -webkit-backdrop-filter: blur(10px);
            backdrop-filter: blur(10px);
    border-bottom: 0;
    box-shadow: none !important;
    padding: 0 !important;
}
body.jp-site #header-outer header#top { border-bottom: 1px solid var(--jp-line); }
body.jp-site #header-outer #top > .container {
    max-width: var(--jp-wrap) !important;
    width: 100% !important;
    padding: 0 var(--jp-gut) !important;
    margin: 0 auto !important;
}
body.jp-site #header-outer #top > .container > .row {
    display: flex;
    align-items: center;
    gap: clamp(14px, 2vw, 30px);
    height: var(--jp-head-h);
    margin: 0;
    padding: 0;
}
body.jp-site #header-outer #top > .container > .row::before,
body.jp-site #header-outer #top > .container > .row::after { display: none !important; }
body.jp-site #header-outer #top > .container > .row > .col {
    float: none !important;
    margin: 0 !important;
    padding: 0 !important;
    width: auto !important;
    min-height: 0;
}
body.jp-site #header-outer #top .col.span_3 { flex: 0 0 auto; margin-right: auto !important; }
body.jp-site #header-outer #top .col.span_9 { flex: 1 1 auto; min-width: 0; }

body.jp-site #header-outer #top #logo {
    display: block;
    margin: 0;
    padding: 0;
    line-height: 0;
}
body.jp-site #header-outer #top #logo img {
    height: clamp(44px, 4.6vw, 58px) !important;
    width: auto !important;
    max-height: none !important;
    display: block;
}

/* The nav column holds ul.sf-menu (the links) then ul.buttons (the phone
   lockup, the CTA and the burger). Both are laid out on one flex line so
   margin-left:auto on the menu pushes the whole group right. */
body.jp-site #header-outer #top nav {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: clamp(14px, 2vw, 30px);
    width: 100%;
    float: none !important;
}
body.jp-site #header-outer #top nav > ul.sf-menu {
    display: flex;
    align-items: center;
    gap: clamp(14px, 1.7vw, 26px);
    float: none !important;
    margin: 0;
    padding: 0;
}
body.jp-site #header-outer #top nav > ul.sf-menu > li {
    float: none !important;
    margin: 0;
    padding: 0;
    position: relative;
}
body.jp-site #header-outer #top nav > ul.sf-menu > li > a {
    padding: 6px 0 !important;
    line-height: 1.4;
    border-bottom: 2px solid transparent;
    transition: color .18s ease, border-color .18s ease;
    white-space: nowrap;
    display: inline-flex;
    align-items: center;
    gap: 6px;
}
body.jp-site #header-outer #top nav > ul.sf-menu > li > a > .menu-title-text {
    font-family: var(--jp-text);
    font-size: .94rem;
    font-weight: 600;
    letter-spacing: 0;
    text-transform: none;
    color: var(--jp-body);
    transition: color .18s ease;
}
body.jp-site #header-outer #top nav > ul.sf-menu > li > a:hover > .menu-title-text,
body.jp-site #header-outer #top nav > ul.sf-menu > li:hover > a > .menu-title-text,
body.jp-site #header-outer #top nav > ul.sf-menu > li.current-menu-item > a > .menu-title-text {
    color: var(--jp-fg);
}
body.jp-site #header-outer #top nav > ul.sf-menu > li > a:hover,
body.jp-site #header-outer #top nav > ul.sf-menu > li:hover > a {
    border-bottom-color: var(--jp-orange);
}
/* Salient marks Home as current on every anchor link on the front page, which
   would underline four items at once. Only underline on real hover. */
body.jp-site #header-outer #top nav > ul.sf-menu > li.current-menu-item > a { border-bottom-color: transparent; }

/* Services caret */
body.jp-site #header-outer #top nav > ul.sf-menu > li.jp-nav-parent > a::after {
    content: "";
    width: 13px;
    height: 13px;
    flex: 0 0 auto;
    background-color: currentColor;
    color: var(--jp-body);
    -webkit-mask: var(--jp-i-chev) center/contain no-repeat;
            mask: var(--jp-i-chev) center/contain no-repeat;
    transition: color .18s ease;
}
body.jp-site #header-outer #top nav > ul.sf-menu > li.jp-nav-parent:hover > a::after { color: var(--jp-fg); }
body.jp-site #header-outer #top nav ul.sf-menu li .sf-sub-indicator,
body.jp-site #header-outer #top nav ul.sf-menu li a .nectar-menu-icon { display: none !important; }

/* dropdown */
body.jp-site #header-outer #top nav > ul.sf-menu > li > ul.sub-menu {
    top: calc(100% + 14px) !important;
    left: -18px !important;
    width: 290px !important;
    min-width: 290px !important;
    background: var(--jp-surface) !important;
    border: 1px solid var(--jp-line) !important;
    border-radius: 18px !important;
    padding: 10px !important;
    box-shadow: 0 26px 56px -24px rgba(15, 15, 15, .35) !important;
    display: flex;
    flex-direction: column;
    gap: 2px;
}
body.jp-site #header-outer #top nav > ul.sf-menu > li > ul.sub-menu::before,
body.jp-site #header-outer #top nav > ul.sf-menu > li > ul.sub-menu::after { display: none !important; }
body.jp-site #header-outer #top nav ul.sub-menu > li { width: 100%; border: 0 !important; }
body.jp-site #header-outer #top nav ul.sub-menu > li > a {
    display: flex !important;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 11px 13px !important;
    border-radius: 12px;
    border: 0 !important;
    transition: background .18s ease, color .18s ease;
}
body.jp-site #header-outer #top nav ul.sub-menu > li > a > .menu-title-text {
    font-family: var(--jp-text);
    font-size: .93rem;
    font-weight: 600;
    letter-spacing: 0;
    text-transform: none;
    color: var(--jp-fg);
}
/* THE DROPDOWN HOVER WAS UNREADABLE, and it took two rules to get there.
   Salient's own dynamic stylesheet fills this row with SOLID accent orange and
   whitens the label, at
     #header-outer:not([data-format="left-header"]) #top nav > ul > li:not(.megamenu) ...
   which is (2,3,5) - exactly the same weight as the rule here, so the tie was
   decided by load order and Salient won the background. The label, though, is
   targeted one level deeper at (2,4,5), so OUR colour won there: dark orange
   text on a solid orange row.

   Fixed at both ends. Salient's rule is !important TOO, so !important alone
   only re-created the tie and its background still won on load order - the
   selectors here name ul.sf-menu as well, which takes them to (2,4,6) and wins
   outright. The label becomes the LIGHT orange; measured on the composited
   row, 7.2:1.
   (White would have been the obvious choice and is wrong - white on this orange
   is only 2.6:1.) */
body.jp-site #header-outer #top nav > ul.sf-menu > li > ul.sub-menu > li > a:hover,
body.jp-site #header-outer #top nav > ul.sf-menu > li > ul.sub-menu > li > a:focus-visible {
    background: var(--jp-orange-soft) !important;
}
body.jp-site #header-outer #top nav > ul.sf-menu > li > ul.sub-menu > li > a:hover > .menu-title-text,
body.jp-site #header-outer #top nav > ul.sf-menu > li > ul.sub-menu > li > a:focus-visible > .menu-title-text {
    color: var(--jp-orange-lt) !important;
}

/* the "New" pill. It is a CSS ::after on the item class, not typed content, so
   renaming the menu item cannot break it and removing the class removes it. */
body.jp-site #header-outer #top nav ul.sub-menu > li.jp-nav-sub--new > a::after {
    content: "New";
    flex: 0 0 auto;
    font-family: var(--jp-text);
    font-size: .66rem;
    font-weight: 800;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: #fff;
    background: var(--jp-orange);
    padding: 3px 8px;
    border-radius: 999px;
    line-height: 1.5;
}

/* the phone lockup + CTA, rendered by Salient into ul.buttons */
body.jp-site #header-outer #top nav > ul.buttons {
    display: flex;
    align-items: center;
    gap: 14px;
    float: none !important;
    margin: 0 !important;
    padding: 0 !important;
    width: auto !important;
    position: static !important;
}
/* Salient puts margin-right:14px on the first li of ul.buttons. The ul itself
   ends exactly on the container edge, but that margin holds the CTA 14px short
   of it - measured at every width, and it reads as a header that does not line
   up with the sections below. The gap between the phone and the CTA is the
   ul's own flex gap, so the margin has nothing left to do. */
body.jp-site #header-outer #top nav > ul.buttons > li { margin: 0 !important; padding: 0 !important; float: none; }
body.jp-site #header-outer #top .nectar-header-text-content,
body.jp-site #header-outer #top .nectar-header-text-content > div {
    display: flex;
    align-items: center;
    gap: 14px;
    margin: 0;
    padding: 0;
}
body.jp-site #header-outer .jp-hphone,
body.jp-site .jp-hphone {
    display: flex !important;
    flex-direction: column !important;
    line-height: 1.15;
    text-align: right;
    color: var(--jp-fg) !important;
    text-decoration: none;
}
body.jp-site .jp-hphone__label {
    font-family: var(--jp-text);
    font-size: .66rem;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--jp-mute);
    font-weight: 700;
    white-space: nowrap;
}
body.jp-site .jp-hphone__num {
    font-family: var(--jp-display);
    font-weight: 800;
    font-size: 1.06rem;
    letter-spacing: -.02em;
    white-space: nowrap;
}

/* TWO numbers in the header, stacked rather than side by side.
   Measured at 1440: the pair on one line needs 267px, and only 164px is free
   between the last menu item and the Free quote button - so a single line would
   have run into the navigation. Stacked, each is ~126px and fits with room to
   spare, and the header has the vertical space already.

   The office line is deliberately the quieter of the two so the mobile stays
   the primary action, which is what the design leads with. Both are real tel:
   links. */
body.jp-site .jp-hphones {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 1px;
}
/* The office line reads on ONE line, label and number side by side, so the two
   phone lockups together stay the height of the original single one. */
/* #header-outer is carried here for weight: the base lockup rule is
   `body.jp-site #header-outer .jp-hphone` at (1,2,1) and !important, so a
   (0,2,1) override lost and the office line stayed stacked. */
body.jp-site #header-outer .jp-hphone--office,
body.jp-site .jp-hphone--office {
    flex-direction: row !important;
    align-items: baseline;
    gap: 6px;
}
body.jp-site .jp-hphone--office .jp-hphone__label { font-size: .62rem; }
body.jp-site .jp-hphone--office .jp-hphone__num {
    font-family: var(--jp-text);
    font-weight: 700;
    font-size: .82rem;
    letter-spacing: 0;
    color: var(--jp-mute-3);
}
body.jp-site .jp-hphone--office:hover .jp-hphone__num,
body.jp-site .jp-hphone--office:hover .jp-hphone__label { color: var(--jp-orange-lt); }
body.jp-site .jp-hcta {
    display: inline-flex;
    align-items: center;
    gap: .5em;
    background: var(--jp-orange);
    color: #fff !important;
    font-family: var(--jp-text);
    font-weight: 800;
    font-size: .95rem;
    line-height: 1.2;
    padding: .9em 1.5em;
    border-radius: 999px;
    white-space: nowrap;
    text-decoration: none;
    box-shadow: 0 10px 22px -10px rgba(240, 132, 36, .75);
    transition: transform .18s ease, background .18s ease;
}
body.jp-site .jp-hcta::after {
    content: "";
    width: 16px;
    height: 16px;
    flex: 0 0 auto;
    background-color: currentColor;
    -webkit-mask: var(--jp-i-arrow) center/contain no-repeat;
            mask: var(--jp-i-arrow) center/contain no-repeat;
}
body.jp-site .jp-hcta:hover { transform: translateY(-2px); background: var(--jp-orange-dk); color: #fff !important; }

/* Salient ships TWO burgers: one inside ul.buttons and one as .mobile-icon in
   .col.span_9, and it swaps between them at its own breakpoint - the ul.buttons
   one is hidden BELOW the breakpoint, which is where a burger is actually
   needed. Styling only that one leaves the mobile header with no way to open
   the menu at all, so the styling is written against both. */
body.jp-site #header-outer #top .nectar-mobile-only { display: none !important; }

body.jp-site #header-outer #top .slide-out-widget-area-toggle > div > a {
    display: grid;
    /* place-items centres the glyph in its TRACK; place-content centres the
       track in the BOX. Both are needed, and only the first was here. Salient
       sizes the track at a fixed 46px, so inside this 48px button the track was
       laid out at the start and the burger sat 1px left of centre and 1px above
       it - the reported "hamburger is not centred in its box". */
    place-items: center;
    place-content: center;
    width: 48px;
    height: 48px;
    border: 1px solid var(--jp-line);
    border-radius: 14px;
    background: var(--jp-surface);
    color: var(--jp-fg);
    padding: 0 !important;
    margin: 0 !important;
}
/* The anchor is a centred grid, but it has THREE children - Salient's line
   wrapper, its screen-reader label, and our own ::before glyph - so they stack
   in three rows and the icon rides high in the box. Everything is placed in the
   same cell instead, which keeps the label in the accessibility tree without
   letting it take part in layout. */
body.jp-site #header-outer #top .slide-out-widget-area-toggle > div > a > *,
body.jp-site #header-outer #top .slide-out-widget-area-toggle > div > a::before { grid-area: 1 / 1; }
body.jp-site #header-outer #top .slide-out-widget-area-toggle .lines-button,
body.jp-site #header-outer #top .slide-out-widget-area-toggle .lines,
body.jp-site #header-outer #top .slide-out-widget-area-toggle > div > a > span[aria-hidden] { display: none !important; }
body.jp-site #header-outer #top .slide-out-widget-area-toggle .screen-reader-text {
    position: absolute !important;
    width: 1px; height: 1px;
    overflow: hidden;
    clip: rect(1px, 1px, 1px, 1px);
    clip-path: inset(50%);
    white-space: nowrap;
}
body.jp-site #header-outer #top .slide-out-widget-area-toggle > div > a::before {
    content: "";
    width: 22px;
    height: 22px;
    background-color: currentColor;
    -webkit-mask: var(--jp-i-burger) center/contain no-repeat;
            mask: var(--jp-i-burger) center/contain no-repeat;
}

/* Salient's header is position:fixed and #header-space is what reserves room
   for it in the flow. The design's header is position:sticky, which occupies
   its own height, so the two are only equivalent while #header-space is
   present. Hiding it - the usual move for a transparent header - would slide
   the hero up underneath the header instead. It is kept, and painted the page
   colour so it never shows as a white strip. */
body.jp-site #header-space {
    display: block !important;
    background-color: var(--jp-off) !important;
    /* Salient sizes this from its own padding and logo-height options, which
       lands 3px out here. Stated explicitly instead: top bar 44 + header
       clamp(72px,7vw,92px) + the 1px border. */
    height: calc(44px + var(--jp-head-h) + 1px) !important;
}

/* Salient pads .container-wrap by 40px at the top, which the design does not. */
body.jp-home .container-wrap { padding-top: 0 !important; }


/* ==========================================================================
   08  OFF-CANVAS MOBILE MENU

   This panel is Salient chrome and never appears in a design file. On a default
   install it is 32px Open Sans on #3452ff with a #ff1053 close button, and it
   renders both the primary and the secondary menu into one list.

   It is rebuilt here as a FULL-WIDTH opaque overlay that fades, rather than
   Salient's partial drawer that slides. That is a deliberate rewrite, not a
   skin: Salient's stock behaviour caused several reported faults on this stack
   and every one of them is a timing problem rather than a styling one. Each is
   documented at the rule that fixes it.
   ========================================================================== */

/* 1. Stacking. The overlay must sit above the page; the close control, which
      Salient renders OUTSIDE the panel, must sit above the overlay, or the
      menu opens and cannot be shut. */
body.jp-site #slide-out-widget-area-bg { z-index: 9998 !important; }
body.jp-site #slide-out-widget-area { z-index: 9999 !important; }
body.jp-site .slide_out_area_close__wrap,
body.jp-site .slide_out_area_close,
body.jp-site .slide-out-widget-area-toggle { z-index: 10001 !important; }

/* 2. Colour: the design's white panel, on BOTH layers. Setting it only through
      the Theme Options key paints nothing, because Salient draws the panel on a
      separate #slide-out-widget-area-bg layer that receives the opacity but not
      the colour.

      The two extra selector parts are carried purely for weight, and the exact
      count matters. skin-material.css forces
          #slide-out-widget-area.slide-out-from-right:not(.fullscreen-alt):not(.fullscreen)
          { background-color: transparent !important }
      which is (1,3,0), the arguments of :not() counting towards specificity.
      `body.jp-site #slide-out-widget-area` is (1,1,1) and
      `body.jp-site #slide-out-widget-area.slide-out-from-right` is (1,2,1);
      both lose on the class column even though they are !important and load
      later, because specificity is compared before source order. Matching their
      :not(.fullscreen) brings this to (1,3,1) and wins. Measured before the
      fix: the panel computed to rgba(0,0,0,0) and only the layer behind it
      was painting, so the white came from the wrong element. */
body.jp-site #slide-out-widget-area.slide-out-from-right:not(.fullscreen),
body.jp-site #slide-out-widget-area-bg { background-color: var(--jp-surface) !important; }

/* 3. OPEN AND CLOSE ANIMATION, owned here rather than left to Salient.

      Salient slides .off-canvas-menu-container translateX(110px) -> 0 on open
      and back on close. An interrupted slide leaves an element resting
      part-way and its text is then clipped by the panel's own overflow:hidden,
      which is exactly the "menu opens cut off" report.

      It is replaced by a plain symmetrical fade driven by ONE class,
      jp-ocm-open, which jp-site.js mirrors from the panel's own material-open.
      material-open is added on open and removed at the START of the close, so
      it is symmetric; the body's material-ocm-open is removed 900ms later and
      would leave every rule keyed to it half-applied.

      VISIBILITY is taken over here for exactly that reason. Salient hides the
      panel with `body:not(.material-ocm-open) #slide-out-widget-area…`, so what
      is actually on screen was still being decided by the class it drops 900ms
      after the close, not by the fade. Owning both properties makes the panel's
      state a pure function of jp-ocm-open and leaves Salient's timers unable to
      affect it either way.

      visibility is transitioned rather than merely set so it can be held
      `visible` for the length of the fade-out and flip on its completion; with
      opacity alone the panel would still be swallowing taps at 0. Both
      declarations need !important to clear skin-material's own !important
      background rule and the (1,2,1) :not() selector that hides it. */
body.jp-site #slide-out-widget-area.slide-out-from-right,
body.jp-site #slide-out-widget-area-bg {
    opacity: 0 !important;
    visibility: hidden !important;
    pointer-events: none !important;
    /* .28s must match CLOSE_MS in jp-site.js */
    transition: opacity .28s ease, visibility 0s linear .28s !important;
}
body.jp-site.jp-ocm-open #slide-out-widget-area.slide-out-from-right,
body.jp-site.jp-ocm-open #slide-out-widget-area-bg {
    opacity: 1 !important;
    visibility: visible !important;
    pointer-events: auto !important;
    transition: opacity .28s ease, visibility 0s linear 0s !important;
}

/* No transform anywhere in the panel, in either direction. This is what removes
   the clipping, and it also makes the resting position readable, which a
   mid-flight transform never is.

   The panel itself is deliberately absent from the opacity half of this rule:
   it is the element being faded, and listing it here silently defeated the
   fade above, which is how the panel came to be permanently opacity:1 with
   only Salient's visibility hiding it. Its transform reset is stated on its
   own below. */
body.jp-site #slide-out-widget-area .inner-wrap,
body.jp-site #slide-out-widget-area .inner,
body.jp-site #slide-out-widget-area .off-canvas-menu-container,
body.jp-site #slide-out-widget-area .menu,
body.jp-site #slide-out-widget-area .menu > li,
body.jp-site #slide-out-widget-area .menu ul.sub-menu > li,
body.jp-site #slide-out-widget-area .nectar-header-text-content {
    transform: none !important;
    opacity: 1 !important;
}
body.jp-site #slide-out-widget-area { transform: none !important; }
body.jp-site #slide-out-widget-area .off-canvas-menu-container { transition: none !important; }

/* 4. THE PAGE MUST NOT COLLAPSE.

      Salient does not merely hide the page while the menu is open, it collapses
      it: .ocm-effect-wrap is given an inline height and overflow:hidden, undone
      in a 900ms timeout. It does that because its stock panel covers only part
      of the screen. Here the panel is a full-screen opaque overlay, so the
      collapse buys nothing, and it is what leaves a strip of page showing
      beside the menu.

      Deliberately NOT gated on the open class: Salient writes the inline height
      when the menu opens and only replaces it with 100% in that 900ms timeout,
      so a gated override would let the inline value take effect again the
      moment the menu closed and clip the whole page until the timer ran. */
body.jp-site .ocm-effect-wrap {
    height: auto !important;
    min-height: 100% !important;
    overflow: visible !important;
}
/* SALIENT SCALES THE WHOLE PAGE WRAPPER while the menu is open, and leaves it
   scaled afterwards. Its rule is
     .ocm-effect-wrap.material-ocm-open .ocm-effect-wrap-inner { transform: scale(1.007) !important }
   which is (0,3,0) and beat the (0,2,1) written here, and its own close leaves
   `material-ocm-open` on the wrapper even once the panel itself is shut. The
   result was 1px of permanent horizontal overflow after any open-and-close:
   390px scaled to 392.7. Naming .ocm-effect-wrap takes this to (0,3,1) so it
   wins whatever state that class is left in. */
body.jp-site .ocm-effect-wrap .ocm-effect-wrap-inner,
body.jp-site .ocm-effect-wrap-inner {
    transform: none !important;
    padding-top: 0 !important;
}

/* The scroll lock goes on the documentElement, applied by jp-site.js. Salient's
   own stylesheet already sets body { overflow: hidden }, so a lock on the body
   achieves nothing: the element that actually scrolls is <html>. */
html.jp-menu-open { overflow: hidden !important; }

/* 5. The close control is rendered OUTSIDE the panel, in a static
      .slide_out_area_close__wrap at the very end of the document, and is then
      positioned by JS with maths that assumes the page was scrolled to the top,
      which is what stock Salient does on open. This build preserves the
      reader's scroll position, so that assumption fails and the button lands
      off by the scroll amount.

      Pinning it to the viewport removes the dependency. Only
      .slide_out_area_close is repositioned: the __wrap is its containing block,
      so collapsing that would take the button with it. */
body.jp-site .slide_out_area_close {
    position: fixed !important;
    top: 22px !important;
    right: 18px !important;
    left: auto !important;
    bottom: auto !important;
    /* the anchor itself must carry the size: Salient leaves it 0x0 and the
       glyph then overflows its own right edge, off the screen */
    width: 44px !important;
    height: 44px !important;
    /* Gated on the menu being open. Salient reveals this control through the
       `material-ocm-open` class it adds on open, so forcing `display:block` to
       fix the sizing above ALSO forced it visible on a closed menu - a black
       cross floating over the header on every page load. The same class that
       drives the panel drives it, so the two can never disagree. */
    display: none !important;
}
body.jp-site.jp-ocm-open .slide_out_area_close { display: block !important; }
/* Salient paints its OWN accent circle as .slide_out_area_close::before and
   animates it from scale(0) on open. Left alone it arrives as a second, orange
   circle sitting off to one side of the black one. The design's close control
   is a single plain circle, so the ripple goes rather than being recoloured.
   (It reads as scale(0) while shut, so it is only visible once opened - which
   is why it survived the earlier rounds of checking.) */
body.jp-site .slide_out_area_close::before { content: none !important; }

/* Salient's close glyph is a 20px box, which is well under a usable tap
   target. It becomes a 44px circle with the cross centred inside it.

   top/left MUST be reset alongside the transform. Salient centres this span
   with `position:absolute; top:50%; left:50%` plus a matching
   translate(-50%,-50%). Overriding the transform alone left the two 50%
   offsets in force, and against a 44px button that is 22px - so the black
   circle sat exactly 22px down and 22px right of its own tap target, which is
   the misaligned background. */
body.jp-site .slide_out_area_close .close-wrap {
    display: block !important;
    position: relative !important;
    top: auto !important;
    left: auto !important;
    width: 44px !important;
    height: 44px !important;
    background-color: var(--jp-surface-2) !important;
    /* On a white panel this was a solid black disc, which needed no outline.
       On a dark panel the disc is within 1.1:1 of its background, so the RING
       is what makes it read as a button - and a UI component needs 3:1, which
       --jp-line at 10% does not reach. Measured 3.4:1 at this value. */
    border: 1px solid rgba(255, 255, 255, .38) !important;
    border-radius: 50% !important;
    transform: none !important;
}
/* These two bars ARE the cross - background-color is the glyph colour here, not
   a surface - so they stay white however the theme is painted. */
body.jp-site .slide_out_area_close .close-line {
    background-color: #fff !important;
    width: 18px !important;
    height: 2px !important;
    position: absolute !important;
    top: 50% !important;
    left: 50% !important;
    margin: 0 !important;
}
body.jp-site .slide_out_area_close .close-line1 { transform: translate(-50%, -50%) rotate(45deg) !important; }
body.jp-site .slide_out_area_close .close-line2 { transform: translate(-50%, -50%) rotate(-45deg) !important; }

/* 5b. The logo, rendered into the panel by jp_ocm_logo() on Salient's
       nectar_hook_ocm_before_menu. The open panel covers the header, so without
       it the menu opens with no brand at all and a bare gap where the header
       had been.

       It sits on the close button's own line rather than above it, so the panel
       opens looking like the header it replaced. The close button is fixed, so
       the logo is given a right margin wide enough to clear it. */
body.jp-site .jp-ocm-logo {
    order: 0;
    display: block;
    width: fit-content;
    margin: 0 62px 26px 0;   /* 44px button + 18px gutter */
    line-height: 0;
}
body.jp-site .jp-ocm-logo__img {
    display: block;
    width: auto;
    height: 44px;            /* the header's own mobile-logo-height */
    max-width: 100%;
}

/* 6. Width and padding.

      Salient's default is a 40px left inset plus padding-right:20px with a
      matching negative margin on the inner wrap, which is how it hides its own
      scrollbar. That makes the panel 20px WIDER than the screen, so a centred
      menu is centred on 205 instead of 195 at 390px, and an overflow test
      cannot catch it because the excess is clipped. All four sides are stated
      instead, and the scrollbar is suppressed properly. */
body.jp-site #slide-out-widget-area {
    width: 100% !important;
    max-width: 100vw !important;
    left: 0 !important;
    right: 0 !important;
    padding: 0 !important;
    scrollbar-width: none;
}
body.jp-site #slide-out-widget-area::-webkit-scrollbar { width: 0; height: 0; }
body.jp-site #slide-out-widget-area .inner-wrap,
body.jp-site #slide-out-widget-area .inner,
body.jp-site #slide-out-widget-area .off-canvas-menu-container,
body.jp-site #slide-out-widget-area .menu {
    width: 100% !important;
    max-width: none !important;
    margin-left: 0 !important;
    margin-right: 0 !important;
}
/* Salient centres the panel's contents vertically by putting a computed
   margin-top on .inner-wrap - measured 84.94px here. That is why the menu began
   a long way down the panel with an empty band above it, and it would have gone
   on pushing the logo off its line no matter what padding .inner was given. The
   panel is top-aligned by design, so the margin goes. */
body.jp-site #slide-out-widget-area .inner-wrap {
    margin-top: 0 !important;
    margin-bottom: 0 !important;
}
/* The top inset is now the close button's own offset, not the header's height.
   It used to be `--jp-head-h + 22px` to clear a header the panel covers anyway,
   which left a tall empty band above the first menu item with nothing in it.
   The panel carries its own logo now, so 22px puts that logo on exactly the
   same line as the close control, which is pinned at top:22px. */
body.jp-site #slide-out-widget-area .inner {
    display: flex;
    flex-direction: column;
    padding: 22px var(--jp-gut) 40px;
}
body.jp-site #slide-out-widget-area .off-canvas-menu-container { order: 1; }
body.jp-site #slide-out-widget-area .nectar-header-text-content { order: 2; }

body.jp-site #slide-out-widget-area ul,
body.jp-site #slide-out-widget-area li { list-style: none !important; margin: 0; padding: 0; text-align: left; }
body.jp-site #slide-out-widget-area li::marker { content: none !important; }

/* 7. Links.

      Salient renders every off-canvas anchor as inline-block, so it shrink-wraps
      to its own label: an item's divider then underlines only its text instead
      of spanning the panel, and the tap target is the width of the word rather
      than the whole row. Everything here is block at full width. */
body.jp-site #slide-out-widget-area .menu > li > a {
    display: block !important;
    width: 100% !important;
    font-family: var(--jp-display) !important;
    font-weight: 700 !important;
    font-size: 1.08rem !important;
    line-height: 1.4 !important;
    color: var(--jp-fg) !important;
    padding: 12px 0 !important;
    border-bottom: 1px solid var(--jp-line-2);
    text-transform: none !important;
    letter-spacing: 0 !important;
}
body.jp-site #slide-out-widget-area .menu > li > a .menu-title-text {
    font: inherit;
    color: inherit;
    text-transform: none;
    letter-spacing: inherit;
}
body.jp-site #slide-out-widget-area .menu ul.sub-menu { display: block !important; padding: 0 !important; }
body.jp-site #slide-out-widget-area .menu ul.sub-menu > li > a {
    display: block !important;
    width: 100% !important;
    font-family: var(--jp-text) !important;
    font-weight: 600 !important;
    font-size: 1rem !important;
    color: var(--jp-fg) !important;
    padding: 11px 0 !important;
    border-bottom: 1px solid var(--jp-line-2);
}
/* Same reasoning in the off-canvas panel: the dark orange was chosen against a
   white panel and measures 4.4:1 against the dark one, under the 4.5 floor.
   The light orange clears it comfortably. */
body.jp-site #slide-out-widget-area .menu > li > a:hover,
body.jp-site #slide-out-widget-area .menu > li > a:focus-visible,
body.jp-site #slide-out-widget-area .menu ul.sub-menu > li > a:hover,
body.jp-site #slide-out-widget-area .menu ul.sub-menu > li > a:focus-visible { color: var(--jp-orange-lt) !important; }

/* the Services row is a label above its children, as the design has it */
body.jp-site #slide-out-widget-area .menu li.jp-nav-parent > a { border-bottom: 0; padding: 16px 0 6px !important; }
body.jp-site #slide-out-widget-area .menu li.jp-nav-parent > a .menu-title-text {
    font-family: var(--jp-display) !important;
    font-weight: 800 !important;
    font-size: .7rem !important;
    letter-spacing: .16em !important;
    text-transform: uppercase !important;
    color: var(--jp-mute) !important;
}

/* Salient tints this block; the design has no band behind the two pills. */
body.jp-site #slide-out-widget-area .nectar-header-text-content {
    background: none !important;
    padding: 0 !important;
    width: 100%;
}
body.jp-site #slide-out-widget-area .nectar-header-text-content > div {
    display: flex;
    gap: 10px;
    margin-top: 22px;
    width: 100%;
}
body.jp-site #slide-out-widget-area .jp-hphone {
    flex: 1;
    align-items: center;
    justify-content: center;
    background: var(--jp-panel);
    color: #fff !important;
    font-weight: 800;
    padding: .95em 1em;
    border-radius: 999px;
    text-align: center;
}
body.jp-site #slide-out-widget-area .jp-hphone__label { display: none; }
/* In the panel the lockup is a row of pills, so the wrapper must not impose the
   header's vertical stack - the two numbers sit side by side and share the row
   with the Free quote pill. */
body.jp-site #slide-out-widget-area .jp-hphones {
    display: contents;
}
/* Three pills do not fit across a phone: measured at 390 the Free quote pill
   ran to 461 against a 390 panel. The row wraps, the two numbers share the
   first line and the quote button takes the second on its own. */
body.jp-site #slide-out-widget-area .nectar-header-text-content > div { flex-wrap: wrap; }
body.jp-site #slide-out-widget-area .jp-hphone { flex: 1 1 calc(50% - 5px); min-width: 0; }
body.jp-site #slide-out-widget-area .jp-hcta { flex: 1 1 100%; }
body.jp-site #slide-out-widget-area .jp-hphone--office .jp-hphone__num {
    font-family: var(--jp-text);
    font-size: .9rem;
    font-weight: 700;
    color: #fff;
}
body.jp-site #slide-out-widget-area .jp-hphone__num { font-family: var(--jp-text); font-size: .98rem; letter-spacing: 0; }
body.jp-site #slide-out-widget-area .jp-hcta {
    flex: 1;
    justify-content: center;
    font-size: .98rem;
    padding: .95em 1em;
    box-shadow: none;
}
body.jp-site #slide-out-widget-area .jp-hcta::after { display: none; }


/* ==========================================================================
   09  MOBILE ACTION BAR
   The design's fixed bottom bar. Hidden above the breakpoint; shown below it
   in section 23.
   ========================================================================== */

body.jp-site .jp-mobar {
    display: none;
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 70;
    background: rgba(15, 15, 15, .96);
    -webkit-backdrop-filter: blur(10px);
            backdrop-filter: blur(10px);
    padding: 11px clamp(14px, 4vw, 20px);
    gap: 10px;
    border-top: 2px solid var(--jp-orange);
}
body.jp-site .jp-mobar__btn {
    flex: 1;
    text-align: center;
    font-family: var(--jp-text);
    font-weight: 800;
    font-size: .98rem;
    padding: .9em 1em;
    border-radius: 999px;
    text-decoration: none;
    line-height: 1.2;
}
body.jp-site .jp-mobar__btn--call { background: var(--jp-orange); color: #fff !important; }
body.jp-site .jp-mobar__btn--quote {
    background: rgba(255, 255, 255, .1);
    border: 1.5px solid rgba(255, 255, 255, .3);
    color: #fff !important;
}


/* ==========================================================================
   10  HERO
   ========================================================================== */

body.jp-home .jp-hero {
    position: relative;
    background: var(--jp-panel) !important;
    overflow: hidden;
}
/* The design draws the photo at 50% over a black ground. Salient paints the row
   background in .row-bg, so the opacity goes there. An ::after on the row or on
   the wrapper is never painted over .row-bg, which is why both overlays hang
   off .row-bg-wrap instead. */
body.jp-home .jp-hero > .row-bg-wrap .row-bg {
    opacity: .5;
    background-size: cover !important;
}
/* DIRECT child only. As a descendant selector this painted a second copy of the
   gradient over every inner row inside the hero, which is what put a black
   stripe behind the button pair. */
body.jp-home .jp-hero > .row-bg-wrap::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 1;
    background: linear-gradient(102deg, #0F0F0F 4%, rgba(15, 15, 15, .9) 40%, rgba(15, 15, 15, .42) 78%, rgba(15, 15, 15, .62) 100%);
}
body.jp-home .jp-hero > .row-bg-wrap::before {
    content: "";
    position: absolute;
    left: -140px;
    top: -120px;
    width: 420px;
    height: 420px;
    border-radius: 50%;
    z-index: 2;
    background: radial-gradient(circle, rgba(240, 132, 36, .28), transparent 68%);
}
body.jp-home .jp-hero > .row_col_wrap_12 { position: relative; z-index: 4; }

/* The client, on the van in the hero: "make the van brighter so it's easier to
   see, the effect hides it and we want it to stand out."

   It was hidden twice over: the photograph sat at 50% over black, and the
   gradient was still 62% black at the right edge - which is where the van is.
   The copy lives in the left 62% of the row on any screen from 1281 up (a
   760px column in a 1240px container - measured 893px at 1440), so the overlay
   holds until 62% and only then falls away, while the photograph comes up to
   85%. The van's cab sits from about 65% rightward. Below 1281
   the column reaches further right, and on a phone the copy runs across the
   whole photograph, so the original values stay there untouched. */
/* Asked again on 2026-09-23 - "can this be even lighter" - with the van's cab
   circled. The previous pass left two things still dimming it: the photograph
   was at 85%, and the scrim was never fully gone (it bottomed out at 12% and
   stayed there to the right edge). So the photograph now runs at full
   brightness and the scrim reaches ZERO at 74%, which is clear of the copy: the
   text column is 760px inside a 1240px container, so it ends at about 60% of
   the viewport at 1440 and earlier on anything wider. 62% is still held at 45%
   black for the last line of the lead, and everything right of 74% is now the
   untouched photograph. */
@media (min-width: 1281px) {
    body.jp-home .jp-hero > .row-bg-wrap .row-bg { opacity: 1; }
    body.jp-home .jp-hero > .row-bg-wrap::after {
        background: linear-gradient(102deg,
            #0F0F0F 4%,
            rgba(15, 15, 15, .90) 40%,
            rgba(15, 15, 15, .45) 62%,
            rgba(15, 15, 15, 0) 74%,
            rgba(15, 15, 15, 0) 100%);
    }
}
body.jp-home .jp-hero__col > .vc_column-inner > .wpb_wrapper { max-width: 760px; }

body.jp-home .jp-hero__badge p {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    background: rgba(240, 132, 36, .14);
    border: 1px solid rgba(240, 132, 36, .42);
    color: var(--jp-orange-lt);
    /* Salient zeroes padding-bottom on the LAST <p> of a .wpb_text_column,
       which silently flattens any pill built on such a p. */
    padding: 8px 16px !important;
    border-radius: 999px;
    font-family: var(--jp-display);
    font-weight: 700;
    font-size: .72rem;
    letter-spacing: .15em;
    text-transform: uppercase;
    line-height: 1.6;
    margin: 0;
}
/* The two headline fragments are display:inline so they can share lines, and an
   inline box ignores margin-top - so the design's 22px above the headline has to
   be carried by the element before it. */
body.jp-home .jp-hero__badge { margin-bottom: 22px; }
body.jp-home .jp-hero__badge p::before {
    content: "";
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--jp-orange);
    flex: 0 0 auto;
}

/* The headline is two elements because a coloured <span> inside a heading's
   text attribute is stripped by the editor. Only the first is an <h1>. They are
   flowed inline with a PRESERVED space between them: shortcodes emit
   </h1><div> with no whitespace at all, so without this the two fragments run
   together into one unbreakable word. A plain content:" " can collapse and
   \00a0 is visible but is not a legal wrap point, so pre-wrap is required. */
body.jp-home .jp-h1 { display: inline; }
body.jp-home .jp-h1--a::after { content: " "; white-space: pre-wrap; }
/* the --b colour lives in the authoritative heading block: set here it loses to
   that block's own .jp-site .wpb_wrapper .jp-h1 { color:#fff } */

/* The design's headline is ONE balanced block. Here it is two inline headings
   instead, so each half stays separately editable and recolourable in the
   editor - but text-wrap balances a BLOCK CONTAINER, and inline boxes are not
   one. Salient's h1 default had put `balance` on the halves, where it does
   nothing, so the pair silently fell back to greedy wrapping. Measured against
   the design at 1440: three lines in both and every line top identical, but
   line 1 ran to 853 against the design's 647 and line 3 stopped at 453 against
   649 - the same headline broken at different words.

   Balancing the block the two halves share is the whole fix; that wrapper is
   already the design's 760px, so no width is involved. */
body.jp-home .jp-hero__col > .vc_column-inner > .wpb_wrapper { text-wrap: balance; }
/* text-wrap inherits, and the design's lead paragraph is not balanced */
body.jp-home .jp-hero__lead p { text-wrap: wrap; }

body.jp-home .jp-hero__lead p {
    color: var(--jp-hero-lead);
    font-size: clamp(1.02rem, 1.35vw, 1.22rem);
    max-width: 60ch;
    margin: 0;
}
body.jp-home .jp-hero__lead { margin-top: 24px; }

/* the button pair. Its own inner row so the flex gap gives a real row gap when
   the pair wraps; a margin on inline-level buttons would grow the line box on
   desktop too. */
body.jp-home .jp-btnrow { margin: 34px 0 0 !important; }
body.jp-home .jp-btnrow .row_col_wrap_12_inner::before,
body.jp-home .jp-btnrow .row_col_wrap_12_inner::after { display: none !important; }
body.jp-home .jp-btnrow__col > .vc_column-inner > .wpb_wrapper {
    display: flex;
    flex-wrap: wrap;
    gap: 14px;
}
body.jp-home .jp-btnrow__col > .vc_column-inner > .wpb_wrapper::before,
body.jp-home .jp-btnrow__col > .vc_column-inner > .wpb_wrapper::after { display: none !important; }

body.jp-home .jp-ticks--hero { margin-top: 34px; }
body.jp-home .jp-ticks--hero ul {
    display: flex;
    flex-wrap: wrap;
    gap: 10px 26px;
}
body.jp-home .jp-ticks--hero li {
    display: flex;
    align-items: center;
    gap: 9px;
    color: var(--jp-hero-chip);
    font-weight: 600;
    font-size: .92rem;
    line-height: 1.6;
}
body.jp-home .jp-ticks--hero li::before {
    content: "";
    flex: 0 0 auto;
    width: 17px;
    height: 17px;
    background-color: var(--jp-orange);
    -webkit-mask: var(--jp-i-check) center/contain no-repeat;
            mask: var(--jp-i-check) center/contain no-repeat;
}


/* ==========================================================================
   11  STATS STRIP
   ========================================================================== */

body.jp-home .jp-stats > .row_col_wrap_12 {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(200px, 100%), 1fr));
    gap: 1px;
    background: var(--jp-line);
    border: 1px solid var(--jp-line);
    border-radius: 22px;
    overflow: hidden;
    box-shadow: 0 30px 70px -34px rgba(15, 15, 15, .45);
}
/* Salient's clearfix pseudo-elements become GRID ITEMS and consume cells, which
   silently shifts every column into the wrong track. Kill them on any wrapper
   this stylesheet grids or flexes. */
body.jp-home .jp-stats > .row_col_wrap_12::before,
body.jp-home .jp-stats > .row_col_wrap_12::after { display: none !important; }

body.jp-home .jp-stat__col {
    background: var(--jp-surface);
    width: auto !important;
    float: none !important;
}
body.jp-home .jp-stat__col > .vc_column-inner { padding: 30px 26px !important; }
/* Salient centres a milestone. The design left-aligns the number and its
   subject on the same edge, which is what the cell's own padding gives. */
body.jp-home .jp-stat__col .nectar-milestone,
body.jp-home .jp-stat__col .number,
body.jp-home .jp-stat__col .subject { text-align: left !important; }
body.jp-home .jp-stat__col .number,
body.jp-home .jp-stat__col .number span {
    font-family: var(--jp-display) !important;
    font-weight: 800 !important;
    font-size: clamp(1.9rem, 3vw, 2.5rem) !important;
    letter-spacing: -.03em;
    color: var(--jp-orange) !important;
    line-height: 1 !important;
    margin: 0 !important;
}
body.jp-home .jp-stat__col .number { display: flex; align-items: baseline; justify-content: flex-start; line-height: 1 !important; }
/* The template prints an inline font-size of 62px on .symbol-wrap and Salient
   pairs it with a matching line-height, which made every stat cell 22px taller
   than the design even after the font-size was overridden. */
body.jp-home .jp-stat__col .symbol-wrap {
    font-size: clamp(1.9rem, 3vw, 2.5rem) !important;
    line-height: 1 !important;
    margin: 0;
}
body.jp-home .jp-stat__col .symbol-wrap .symbol {
    font-family: var(--jp-display);
    font-weight: 800;
    font-size: inherit;
    color: var(--jp-orange);
    letter-spacing: -.03em;
}
body.jp-home .jp-stat__col .subject {
    font-family: var(--jp-text);
    font-weight: 600;
    color: var(--jp-body);
    font-size: .93rem;
    line-height: 1.6;
    margin-top: 6px;
    padding: 0;
}


/* ==========================================================================
   12  TOWNS MARQUEE
   ========================================================================== */

body.jp-home .jp-marquee .nectar-scrolling-text-inner__text-chunk p {
    font-family: var(--jp-display);
    font-weight: 700;
    font-size: 1rem;
    color: #fff;
    letter-spacing: -.01em;
    line-height: 1.6;
    margin: 0;
    white-space: nowrap;
}
body.jp-home .jp-marquee .jp-di { color: var(--jp-orange); padding: 0 34px; }
body.jp-home .jp-marquee .nectar-scrolling-text-inner__text-chunk { padding-right: 34px; }

/* The design runs the track at `42s linear infinite` over a -50% translate.
   Salient drives its own marquee at a speed keyword, so the animation is
   restated here to match the design and stay seamless (the track is exactly two
   identical chunks, so -50% lands on the start of the second one).

   SALIENT ANIMATES A SECOND ELEMENT, and it has to be switched off explicitly.
   The track is nested: .nectar-scrolling-text-inner holds two
   .nectar-scrolling-text-inner__text-chunk children, and Salient runs
   `nectar-scrolling-text-animation` on the CHUNKS, not on the track. Setting a
   duration on the track alone therefore changed nothing anyone could see: the
   two transforms compose, and the chunk's 14s over a 2170px chunk is 155 px/s
   against the track's 27 px/s, so the chunk was supplying ~85% of the motion
   and the marquee stayed fast however far the track was slowed. Measured
   before the fix: two live animations on the element pair, 80s and 14s. */
@keyframes jp-marquee { from { transform: translateX(0); } to { transform: translateX(-50%); } }
body.jp-home .jp-marquee .nectar-scrolling-text-inner {
    display: flex;
    width: max-content;
    /* 42s over a 2155px half-track is 51 px/s, the design's own rate. It is
       restored here rather than slowed further because the marquee only ever
       READ fast: the chunk animation above was adding 155 px/s on top, so what
       was on screen was ~182 px/s, three and a half times the design. Removing
       that is the slowdown. The track is a fixed width - the text and font-size
       do not change with the viewport - so this one duration holds the same
       rate at every breakpoint. */
    animation: jp-marquee 42s linear infinite !important;
    transform: none;
}
body.jp-home .jp-marquee .nectar-scrolling-text-inner__text-chunk {
    display: flex;
    align-items: center;
    flex: 0 0 auto;
    animation: none !important;   /* see above - this is the one that was racing */
    transform: none !important;
}
@media (prefers-reduced-motion: reduce) {
    body.jp-home .jp-marquee .nectar-scrolling-text-inner { animation: none !important; }
}


/* ==========================================================================
   13  SERVICES
   ========================================================================== */

/* shared section head: copy left, action right, baselines aligned */
body.jp-home .jp-head { margin: 0 0 clamp(34px, 4vw, 52px) !important; }
body.jp-home .jp-head > .row_col_wrap_12_inner {
    display: flex;
    flex-wrap: wrap;
    gap: 28px;
    align-items: flex-end;
    justify-content: space-between;
}
body.jp-home .jp-head > .row_col_wrap_12_inner::before,
body.jp-home .jp-head > .row_col_wrap_12_inner::after { display: none !important; }
body.jp-home .jp-head__copy,
body.jp-home .jp-head__cta {
    width: auto !important;
    float: none !important;
    margin: 0 !important;
    padding: 0 !important;
}
/* The design declares `flex: 0 1 auto` with a max-width cap on the copy and
   `flex: 0 0 auto` on the action, so the pair sits side by side while there is
   room and the action wraps onto its own line when there is not. A pixel
   flex-basis here forced the copy to its max-content width once the row
   stacked, which overflowed a 390px screen by 825px. */
body.jp-home .jp-head__copy { flex: 0 1 auto; max-width: 620px; }
body.jp-home .jp-head__cta { flex: 0 0 auto; }
body.jp-home .jp-rev .jp-head__copy { max-width: 600px; }
body.jp-home .jp-areas__head .jp-head__copy { max-width: 560px; }
body.jp-home .jp-head--stack > .row_col_wrap_12_inner { display: block; }
body.jp-home .jp-head--stack .jp-head__copy { max-width: 620px; }

/* The design draws the eyebrow as an inline <span> inside a 16px/1.6 block, so
   the line it occupies is the PARENT's strut - 25.6px - not its own 11.84 x 1.6
   of 18.9px. Rendered as a block <p> here, it has to state that height itself
   or every section using an eyebrow comes out 6.7px short. */
body.jp-home .jp-eyebrow p {
    font-family: var(--jp-display);
    font-weight: 700;
    font-size: .74rem;
    letter-spacing: .16em;
    text-transform: uppercase;
    color: var(--jp-orange-dk);
    line-height: 1.6rem;
    margin: 0;
}
body.jp-home .jp-eyebrow--light p { color: var(--jp-orange); }

body.jp-home .jp-lead { margin-top: 16px; }
body.jp-home .jp-lead p {
    color: var(--jp-body);
    font-size: 1.08rem;
    margin: 0;
}
body.jp-home .jp-lead--light p { color: var(--jp-mute-3); font-size: 1.06rem; }
body.jp-home .jp-lead--warm p { color: var(--jp-body-warm); font-size: 1.06rem; }

/* card grids. auto-fit + minmax reproduces the design's own breakpoints exactly
   at every width, so no per-device column count is needed. */
body.jp-home .jp-grid { margin: 0 !important; }
body.jp-home .jp-grid > .row_col_wrap_12_inner {
    display: grid;
    gap: 24px;
}
body.jp-home .jp-grid > .row_col_wrap_12_inner::before,
body.jp-home .jp-grid > .row_col_wrap_12_inner::after { display: none !important; }
/* `> *`, not `> .wpb_column`. THE FRONTEND EDITOR WRAPS EVERY COLUMN in an
   extra `div.vc_element.vc_vc_column_inner` and puts the vc_col-sm-* width
   class on THAT wrapper, leaving .wpb_column inside it. A selector naming
   .wpb_column misses the element actually carrying the width, so Salient's
   33.333% went on applying inside each grid track: measured in the frontend
   editor, the three review cards were 121px wide in 363px tracks, which is a
   third of each. Resetting the width to auto lets the grid track size the item
   as it already does on the front end, where there is no wrapper and this
   matches the column itself, unchanged. */
body.jp-home .jp-grid > .row_col_wrap_12_inner > * {
    width: auto !important;
    float: none !important;
    margin: 0 !important;
    padding: 0 !important;
}
body.jp-home .jp-grid--svc   > .row_col_wrap_12_inner { grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr)); }
body.jp-home .jp-grid--steps > .row_col_wrap_12_inner { grid-template-columns: repeat(auto-fit, minmax(min(240px, 100%), 1fr)); gap: 20px; }
body.jp-home .jp-grid--rev   > .row_col_wrap_12_inner { grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr)); }

/* service card */
/* "Learn more" is the card's action and was 25px tall - inside the 24px AA
   floor, but not a comfortable thumb target on a phone. Given room only where
   the cards are full width, so the desktop card rhythm is untouched. */
@media (max-width: 999px) {
    body.jp-home .jp-card .jp-link {
        min-height: 44px;
        align-items: center;
    }
}

body.jp-home .jp-card > .vc_column-inner {
    position: relative;
    background: var(--jp-surface);
    border: 1px solid var(--jp-line);
    border-radius: 22px;
    overflow: hidden;
    height: 100%;
    padding: 0 !important;
    display: flex;
    flex-direction: column;
    transition: transform .22s ease, box-shadow .22s ease;
}
body.jp-home .jp-card:hover > .vc_column-inner {
    transform: translateY(-6px);
    box-shadow: 0 26px 56px -28px rgba(15, 15, 15, .4);
}
body.jp-home .jp-card > .vc_column-inner > .wpb_wrapper {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    padding-bottom: 28px;
}
body.jp-home .jp-card > .vc_column-inner > .wpb_wrapper::before,
body.jp-home .jp-card > .vc_column-inner > .wpb_wrapper::after { display: none !important; }

/* The image is full bleed while the copy is inset, so the wrapper carries no
   horizontal padding and each text child carries its own gutter instead. */
body.jp-home .jp-card .img-with-aniamtion-wrap {
    height: 214px;
    width: 100%;
    margin: 0;
    background: var(--jp-stone);
    overflow: hidden;
}
body.jp-home .jp-card .img-with-aniamtion-wrap .inner,
body.jp-home .jp-card .img-with-aniamtion-wrap .hover-wrap,
body.jp-home .jp-card .img-with-aniamtion-wrap .hover-wrap-inner { height: 100%; width: 100%; }
/* Salient ships img { height:auto !important }, which beats a class-level
   height, so the cover image needs its own !important pair. */
body.jp-home .jp-card img.jp-card__img {
    width: 100% !important;
    height: 100% !important;
    object-fit: cover;
    object-position: center 45%;
    display: block;
    aspect-ratio: auto !important;
}
body.jp-home .jp-card__badge {
    position: absolute;
    top: 14px;
    left: 14px;
    z-index: 2;
}
body.jp-home .jp-card__badge p {
    background: var(--jp-orange);
    color: #fff;
    font-weight: 800;
    font-size: .72rem;
    letter-spacing: .08em;
    text-transform: uppercase;
    padding: 7px 13px;
    border-radius: 999px;
    margin: 0;
    line-height: 1.6;
}
body.jp-home .jp-card__text { margin: 10px 24px 20px; }
body.jp-home .jp-card__text p { color: var(--jp-body); font-size: .99rem; margin: 0; }
body.jp-home .jp-card a.nectar-button.jp-link { margin: auto 24px 0 !important; align-self: flex-start; }

/* the 5px accent bar at the foot of each card */
body.jp-home .jp-card > .vc_column-inner::after {
    content: "";
    display: block;
    height: 5px;
    width: 100%;
    margin-top: auto;
}
/* The design alternated an ORANGE and a BLACK bar along the bottom of the
   cards. On a dark card the black half is invisible, so the alternation read as
   "some cards have a bar and some do not". Both are accent now - the lighter
   tint keeps the rhythm the design intended while staying clearly visible. */
body.jp-home .jp-card--orange > .vc_column-inner::after { background: var(--jp-orange); }
body.jp-home .jp-card--black  > .vc_column-inner::after { background: var(--jp-orange-lt); }


/* ==========================================================================
   14  SPRAY FOAM
   ========================================================================== */

body.jp-home .jp-sf > .row_col_wrap_12 {
    background: var(--jp-panel);
    border-radius: 32px;
    overflow: hidden;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(400px, 100%), 1fr));
}
body.jp-home .jp-sf > .row_col_wrap_12::before,
body.jp-home .jp-sf > .row_col_wrap_12::after { display: none !important; }
body.jp-home .jp-sf__copy,
body.jp-home .jp-sf__media { width: auto !important; float: none !important; margin: 0 !important; }
body.jp-home .jp-sf__copy > .vc_column-inner { padding: clamp(38px, 4.5vw, 64px) !important; }

body.jp-home .jp-sf .jp-lead--light { margin: 18px 0 28px; }
body.jp-home .jp-ticks--dark { margin-bottom: 32px; }
body.jp-home .jp-ticks--dark ul { display: flex; flex-direction: column; gap: 14px; }
body.jp-home .jp-ticks--dark li {
    display: flex;
    gap: 13px;
    align-items: flex-start;
    color: var(--jp-sf-li);
    font-weight: 600;
    font-size: 1rem;
    line-height: 1.6;
}
body.jp-home .jp-ticks--dark li::before {
    content: "";
    flex: 0 0 auto;
    width: 24px;
    height: 24px;
    border-radius: 50%;
    background-color: rgba(240, 132, 36, .18);
    margin-top: 2px;
    background-image: var(--jp-i-check-b);
    background-repeat: no-repeat;
    background-position: center;
    background-size: 13px 13px;
    /* the mask cannot also show the tinted disc, so the disc is the background
       colour and the glyph is a background-image tinted to the accent */
    filter: none;
}
/* recolour the glyph: the data URI is black, so it is masked on a pseudo layer */
body.jp-home .jp-ticks--dark li::before { background-image: none; }
body.jp-home .jp-ticks--dark li { position: relative; }
body.jp-home .jp-ticks--dark li::after {
    content: "";
    position: absolute;
    left: 5.5px;
    top: 7.5px;
    width: 13px;
    height: 13px;
    background-color: var(--jp-orange);
    -webkit-mask: var(--jp-i-check-b) center/contain no-repeat;
            mask: var(--jp-i-check-b) center/contain no-repeat;
}

body.jp-home .jp-sf__media > .vc_column-inner {
    position: relative;
    min-height: 380px;
    height: 100%;   /* the design's photo fills the panel, not just its minimum */
    background: var(--jp-sf-media);
    padding: 0 !important;
    overflow: hidden;
}
body.jp-home .jp-sf__media > .vc_column-inner > .wpb_wrapper { position: static; height: 100%; }
body.jp-home .jp-sf__media .img-with-aniamtion-wrap {
    position: absolute;
    inset: 0;
    margin: 0;
    height: 100%;
    width: 100%;
}
body.jp-home .jp-sf__media .img-with-aniamtion-wrap .inner,
body.jp-home .jp-sf__media .img-with-aniamtion-wrap .hover-wrap,
body.jp-home .jp-sf__media .img-with-aniamtion-wrap .hover-wrap-inner { height: 100%; width: 100%; }
body.jp-home .jp-sf__media img.jp-sf__img {
    width: 100% !important;
    height: 100% !important;
    object-fit: cover;
    object-position: center 40%;
    display: block;
    aspect-ratio: auto !important;
}

/* the floating white card. It is an inner row inside a TOP-LEVEL column, which
   is the only legal place for one: nested inside a vc_column_inner, WPBakery
   hoists the children out and the wrapper's CSS silently does nothing. */
body.jp-home .jp-sf__card {
    position: absolute;
    bottom: 22px;
    left: 22px;
    right: 22px;
    z-index: 2;
    margin: 0 !important;
    background: rgba(255, 255, 255, .96);
    -webkit-backdrop-filter: blur(6px);
            backdrop-filter: blur(6px);
    border-radius: 18px;
    padding: 18px 20px;
    pointer-events: none;
}
body.jp-home .jp-sf__card > .row_col_wrap_12_inner::before,
body.jp-home .jp-sf__card > .row_col_wrap_12_inner::after { display: none !important; }
body.jp-home .jp-sf__cardcol > .vc_column-inner { padding: 0 !important; }
body.jp-home .jp-sf__cardcol > .vc_column-inner > .wpb_wrapper {
    display: grid;
    grid-template-columns: 44px 1fr;
    grid-template-rows: auto auto;
    align-items: center;
    column-gap: 14px;
    line-height: 1.3;
}
body.jp-home .jp-sf__cardcol > .vc_column-inner > .wpb_wrapper::before,
body.jp-home .jp-sf__cardcol > .vc_column-inner > .wpb_wrapper::after { display: none !important; }
body.jp-home .jp-sf__cardcol .nectar_icon_wrap {
    grid-row: 1 / 3;
    width: 44px;
    height: 44px;
    border-radius: 13px;
    background: var(--jp-orange-soft);
    display: grid;
    place-items: center;
}
body.jp-home .jp-sf__cardcol .nectar_icon,
body.jp-home .jp-sf__cardcol .im-icon-wrap { display: grid; place-items: center; }
body.jp-home .jp-sf__cardcol .nectar_icon_wrap svg { width: 22px; height: 22px; }
/* nectar_icon's colour param does not reliably reach the inline SVG, so the
   fill is set per context here instead. */
/* Same correction as .jp-pt above. This section is switched off at the moment,
   so it is fixed here rather than left as a trap for whenever it is switched
   back on. */
body.jp-home .jp-sf__cardcol .nectar_icon_wrap svg path { fill: var(--jp-orange-lt) !important; }
body.jp-home .jp-sf__cardtitle { grid-column: 2; align-self: end; }
body.jp-home .jp-sf__cardtext { grid-column: 2; align-self: start; }
body.jp-home .jp-sf__cardtext p {
    color: var(--jp-body);
    font-weight: 600;
    font-size: .9rem;
    line-height: 1.3;
    margin: 0;
}


/* ==========================================================================
   15  ABOUT
   ========================================================================== */

/* DEVIATION, requested by the client: the design centres a 5/5.4 photo that
   stops well short of the copy beside it (measured 591.8 against 708.9 at
   1440). The columns are stretched instead so the photo runs the full height of
   the text. Below the stacking breakpoint the ratio comes back, because a
   stretched photo over stacked copy would be enormous. */
body.jp-home .jp-about > .row_col_wrap_12 {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(400px, 100%), 1fr));
    gap: clamp(36px, 5vw, 64px);
    align-items: stretch;
}
body.jp-home .jp-about > .row_col_wrap_12::before,
body.jp-home .jp-about > .row_col_wrap_12::after { display: none !important; }
body.jp-home .jp-about__media,
body.jp-home .jp-about__copy { width: auto !important; float: none !important; margin: 0 !important; }

/* The photo is absolutely positioned inside the stretched column, so the row's
   height is set by the COPY alone and the photo fills whatever that turns out
   to be. Chaining height:100% down instead is circular - the column sizes to
   the image while the image sizes to the column - and measured 1515px. */
body.jp-home .jp-about__media > .vc_column-inner { position: relative; padding: 0 !important; height: 100%; }
body.jp-home .jp-about__media > .vc_column-inner > .wpb_wrapper { position: static; }
body.jp-home .jp-about__media .img-with-aniamtion-wrap {
    position: absolute;
    inset: 0;
    border-radius: 28px;
    overflow: hidden;
    background: var(--jp-stone);
    box-shadow: 0 30px 70px -34px rgba(15, 15, 15, .4);
    margin: 0;
    width: 100%;
}
body.jp-home .jp-about__media .img-with-aniamtion-wrap .inner,
body.jp-home .jp-about__media .img-with-aniamtion-wrap .hover-wrap,
body.jp-home .jp-about__media .img-with-aniamtion-wrap .hover-wrap-inner { height: 100%; width: 100%; }
body.jp-home .jp-about__media img.jp-about__img {
    width: 100% !important;
    height: 100% !important;
    object-fit: cover;
    object-position: center 40%;
    display: block;
    aspect-ratio: auto !important;
}
body.jp-home .jp-about__badge {
    position: absolute;
    bottom: -18px;
    right: -10px;
    z-index: 2;
    margin: 0 !important;
    background: var(--jp-orange);
    color: #fff;
    border-radius: 20px;
    padding: 20px 24px;
    max-width: 230px;
    box-shadow: 0 22px 44px -20px rgba(240, 132, 36, .8);
}
body.jp-home .jp-about__badge > .row_col_wrap_12_inner::before,
body.jp-home .jp-about__badge > .row_col_wrap_12_inner::after { display: none !important; }
body.jp-home .jp-about__badgecol > .vc_column-inner { padding: 0 !important; }
body.jp-home .jp-about__badgetext p {
    font-weight: 600;
    font-size: .88rem;
    opacity: .92;
    margin: 6px 0 0;
    line-height: 1.6;
    color: #fff;
}

body.jp-home .jp-about__copy .jp-lead { margin-top: 18px; }
body.jp-home .jp-about__copy .jp-lead--tight { margin-top: 16px; }
body.jp-home .jp-about__copy .jp-lead p { font-size: 1.06rem; }

body.jp-home .jp-about__pts { margin: 30px 0 0 !important; }
body.jp-home .jp-about__pts > .row_col_wrap_12_inner {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(180px, 100%), 1fr));
    gap: 14px;
}
body.jp-home .jp-about__pts > .row_col_wrap_12_inner::before,
body.jp-home .jp-about__pts > .row_col_wrap_12_inner::after { display: none !important; }
body.jp-home .jp-pt { width: auto !important; float: none !important; margin: 0 !important; }
body.jp-home .jp-pt > .vc_column-inner { padding: 0 !important; }
body.jp-home .jp-pt > .vc_column-inner > .wpb_wrapper {
    display: grid;
    grid-template-columns: 40px 1fr;
    grid-template-rows: auto auto;
    column-gap: 12px;
    align-items: start;
}
body.jp-home .jp-pt > .vc_column-inner > .wpb_wrapper::before,
body.jp-home .jp-pt > .vc_column-inner > .wpb_wrapper::after { display: none !important; }
body.jp-home .jp-pt .nectar_icon_wrap {
    grid-row: 1 / 3;
    width: 40px;
    height: 40px;
    border-radius: 12px;
    background: var(--jp-orange-soft);
    display: grid;
    place-items: center;
}
body.jp-home .jp-pt .nectar_icon,
body.jp-home .jp-pt .im-icon-wrap { display: grid; place-items: center; }
body.jp-home .jp-pt .nectar_icon_wrap svg { width: 19px; height: 19px; }
/* The DARK orange was picked against the design's pale #FFF2E4 chip. On the dark
   theme that chip became a translucent orange tint over a near-black section,
   and dark orange on it measures 1.3:1 - the glyph is there and cannot be seen.
   The light orange reads on the same chip. */
body.jp-home .jp-pt .nectar_icon_wrap svg path { fill: var(--jp-orange-lt) !important; }
body.jp-home .jp-pt__title { grid-column: 2; }
body.jp-home .jp-pt__text { grid-column: 2; }
body.jp-home .jp-pt__text p {
    color: var(--jp-body);
    font-size: .92rem;
    font-weight: 500;
    line-height: 1.6;
    margin: 0;
}
body.jp-home .jp-about__copy a.nectar-button.jp-btn--dark { margin-top: 32px !important; font-size: 1rem; padding: 1.05em 1.8em !important; }


/* ==========================================================================
   16  STEPS
   The ordinal is a CSS counter, not typed content, so the page renumbers itself
   when the client inserts or deletes a card.
   ========================================================================== */

body.jp-home .jp-grid--steps > .row_col_wrap_12_inner { counter-reset: jpstep; }
body.jp-home .jp-step { counter-increment: jpstep; }
body.jp-home .jp-step > .vc_column-inner {
    background: var(--jp-surface);
    border: 1px solid var(--jp-line);
    border-radius: 22px;
    padding: 30px 26px 32px !important;
    height: 100%;
}
body.jp-home .jp-step > .vc_column-inner > .wpb_wrapper::before {
    content: "STEP " counter(jpstep, decimal-leading-zero);
    display: block;
    font-family: var(--jp-display);
    font-weight: 800;
    font-size: .8rem;
    letter-spacing: .1em;
    color: var(--jp-orange);
    line-height: 1.6;
}
body.jp-home .jp-step > .vc_column-inner > .wpb_wrapper::after { display: none !important; }
body.jp-home .jp-step__text p { color: var(--jp-body); font-size: .97rem; margin: 0; }
body.jp-home .jp-step--dark > .vc_column-inner { background: var(--jp-panel); border-color: var(--jp-panel); }
body.jp-home .jp-step--dark .jp-step__text p { color: var(--jp-mute-3); }

/* STEPS ON BLACK - client request, "make the background black like the example
   sent". Kept as one block so it can be lifted out whole if they change their
   mind; nothing above this point had to change to support it.

   The fourth card was the odd one out by being BLACK against a white section.
   On a black section that reading is gone - it would simply vanish - so the
   emphasis moves to the accent orange, which is also what carries the accent in
   the reference image the client sent. */
body.jp-home .jp-steps { background: var(--jp-panel); }
body.jp-home .jp-steps .jp-eyebrow { color: var(--jp-orange); }
body.jp-home .jp-step > .vc_column-inner {
    background: #151515;
    border-color: rgba(255, 255, 255, .12);
}
body.jp-home .jp-step__text p { color: var(--jp-mute-3); }
body.jp-home .jp-step--dark > .vc_column-inner {
    background: var(--jp-orange);
    border-color: var(--jp-orange);
}
/* Text on the accent card is the near-black, not white. White on this orange
   measures 2.6:1, which fails even the 3:1 floor for large text; the near-black
   measures 7.3:1. The card reads as the emphasised one either way. */
body.jp-home .jp-step--dark > .vc_column-inner > .wpb_wrapper::before { color: rgba(15, 15, 15, .75); }
body.jp-home .jp-step--dark .jp-step__text p { color: rgba(15, 15, 15, .82); }

/* Client asked the cards to glow orange on hover.

   The glow is a box-shadow rather than a background change, so the card keeps
   the design's colours and only gains light around it; a filled hover state
   would fight the fourth card, which is black by design.

   Hover is paired with focus-within, so reaching a card by keyboard lights it
   the same way - the card carries a link, so it is reachable that way. Both are
   inside a hover-capable media query: on a phone :hover sticks after a tap and
   would leave one card lit until something else was tapped. */
body.jp-home .jp-step > .vc_column-inner {
    transition: box-shadow .22s ease, border-color .22s ease, transform .22s ease;
}
@media (hover: hover) {
    body.jp-home .jp-step:hover > .vc_column-inner,
    body.jp-home .jp-step:focus-within > .vc_column-inner {
        border-color: var(--jp-orange);
        /* stronger and wider than it needed to be on white: a soft shadow is
           nearly invisible against a black section, so the glow carries on the
           spread rather than on the opacity alone */
        box-shadow: 0 0 0 1px var(--jp-orange), 0 0 34px -2px rgba(240, 132, 36, .55);
        transform: translateY(-3px);
    }
}
@media (prefers-reduced-motion: reduce) {
    body.jp-home .jp-step > .vc_column-inner { transition: none; }
    body.jp-home .jp-step:hover > .vc_column-inner,
    body.jp-home .jp-step:focus-within > .vc_column-inner { transform: none; }
}


/* ==========================================================================
   17  REVIEWS
   ========================================================================== */

body.jp-home .jp-stars p {
    color: var(--jp-orange);
    font-size: 1.05rem;
    letter-spacing: 2px;
    line-height: 1.6;
    margin: 0;
}
body.jp-home .jp-rev__pill > .vc_column-inner {
    display: inline-flex;
    align-items: center;
    gap: 12px;
    background: var(--jp-surface);
    border: 1px solid var(--jp-line);
    border-radius: 999px;
    padding: 10px 20px !important;
}
body.jp-home .jp-rev__pill > .vc_column-inner > .wpb_wrapper {
    display: flex;
    align-items: center;
    gap: 12px;
}
body.jp-home .jp-rev__pill > .vc_column-inner > .wpb_wrapper::before,
body.jp-home .jp-rev__pill > .vc_column-inner > .wpb_wrapper::after { display: none !important; }
body.jp-home .jp-rev__pilltext p {
    font-weight: 700;
    font-size: .92rem;
    color: var(--jp-body);
    margin: 0;
    white-space: nowrap;
}

/* The reviews are the client's live Trustindex feed now. Its markup is the
   widget's own and arrives from their CDN, so nothing here restyles the cards -
   that would break the next time Trustindex ships a change. This only gives the
   feed the section's own rhythm and stops it running full-bleed.

   The .jp-rev__card rules below are kept deliberately: the client can drop the
   old testimonial layout back in from the editor, and it would render unstyled
   if they were deleted. */
body.jp-home .jp-rev__feedrow { margin-top: 34px; }
body.jp-home .jp-rev__feed { width: 100%; }
/* Trustindex renders on a light card by default; on a dark section its own
   white panels are the contrast, so nothing is forced onto it here. */
body.jp-home .jp-rev__feed .ti-widget { margin: 0 !important; }

body.jp-home .jp-rev__card > .vc_column-inner {
    background: var(--jp-surface);
    border: 1px solid var(--jp-line);
    border-radius: 22px;
    padding: 32px 28px !important;
    height: 100%;
}
body.jp-home .jp-rev__card > .vc_column-inner > .wpb_wrapper {
    display: flex;
    flex-direction: column;
    height: 100%;
}
body.jp-home .jp-rev__card > .vc_column-inner > .wpb_wrapper::before,
body.jp-home .jp-rev__card > .vc_column-inner > .wpb_wrapper::after { display: none !important; }

/* testimonial renders a bare <blockquote> with a decorative quote glyph, a
   speech-bubble tail and its own Salient accent border. */
/* Salient renders a testimonial as a bare <blockquote> holding the quote <p>
   and then two sibling spans for the name and the subtitle. Making the
   blockquote a flex COLUMN turns those spans into separate flex items, so they
   land on two lines and each applies its own 22px top margin - measured 63px
   taller than the design. Wrapping instead keeps the quote on its own full
   width line and lets the two spans share the line below it, and
   align-content:space-between reproduces the design's flex:1 quote, which
   pushes the attribution to the bottom of an equal-height card. */
body.jp-home .jp-rev__card blockquote {
    border: 0 !important;
    background: none !important;
    padding: 0 !important;
    margin: 0 !important;
    display: flex;
    flex-wrap: wrap;
    align-content: space-between;
    flex: 1 1 auto;
}
body.jp-home .jp-rev__card blockquote::before,
body.jp-home .jp-rev__card blockquote::after { content: none !important; }
body.jp-home .jp-rev__card blockquote .image-icon,
body.jp-home .jp-rev__card blockquote .bottom-arrow { display: none !important; }
body.jp-home .jp-rev__card blockquote > p {
    color: var(--jp-body);
    font-size: .99rem;
    font-family: var(--jp-text);
    font-style: normal;
    font-weight: 400;
    line-height: 1.6;
    margin: 0;
    flex: 0 0 100%;
}
body.jp-home .jp-rev__card blockquote .testimonial-name,
body.jp-home .jp-rev__card blockquote .title {
    flex: 0 0 auto;
    font-family: var(--jp-text);
    font-size: .92rem;
    font-style: normal;
    font-weight: 600;
    line-height: 1.6;
    margin-top: 22px;
}
body.jp-home .jp-rev__card blockquote .testimonial-name { font-weight: 700; color: var(--jp-fg); }
body.jp-home .jp-rev__card blockquote .title { color: var(--jp-mute); margin-left: .35em; }


/* ==========================================================================
   17b FACEBOOK FEED
   The client's Trustindex Facebook feed, rendered by the jp-trustindex-feed
   plugin as a div the CDN loader fills in. Same contract as the reviews feed
   above: the widget's markup is Trustindex's own, so nothing here restyles the
   cards - this only gives the feed the section's rhythm.
   ========================================================================== */

/* The hairline the client asked for, separating this section from the
   reviews above it. On the row itself, so it spans the full released width. */
body.jp-home .jp-fb { border-top: 1px solid var(--jp-line); }

body.jp-home .jp-fb__feedrow { margin-top: 34px; }
body.jp-home .jp-fb__feed { width: 100%; }
body.jp-home .jp-fb__feed .ti-widget { margin: 0 !important; }

/* The widget's own stylesheet puts color:#000000 on .ti-widget-header and the
   page name inherits it - black on black here. Its selector is (0,5,0) built
   from data-attribute chains, so this carries !important instead of fighting
   the specificity. The header's secondary lines (.ti-sub, .ti-header-numbers)
   set their own grey and keep it; the Follow button styles itself. */
body.jp-home .jp-fb__feed .ti-widget-header { color: #fff !important; }


/* ==========================================================================
   18  AREAS
   ========================================================================== */

body.jp-home .jp-areas__panel { width: auto !important; float: none !important; }
body.jp-home .jp-areas__panel > .vc_column-inner {
    background: var(--jp-surface);
    border: 1px solid var(--jp-line);
    border-radius: 32px;
    padding: clamp(34px, 4.5vw, 58px) !important;
}
body.jp-home .jp-areas__head { margin-bottom: 0 !important; }
body.jp-home .jp-areas__head > .row_col_wrap_12_inner,
body.jp-home .jp-rev .jp-head > .row_col_wrap_12_inner { gap: 24px; }
body.jp-home .jp-areas__head .jp-head__copy { max-width: 560px; }
body.jp-home .jp-areas__notecol { flex: 0 1 auto; max-width: 360px; }
body.jp-home .jp-areas__note p { color: var(--jp-body); font-size: 1rem; margin: 0; }

body.jp-home .jp-areas__list {
    margin-top: 34px;
    border-top: 1px solid var(--jp-line-2);
    padding-top: 30px;
}
body.jp-home .jp-areas__list ul {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(160px, 45%), 1fr));
    gap: 10px 24px;
}
body.jp-home .jp-areas__list li {
    display: flex;
    align-items: center;
    gap: 9px;
    font-weight: 600;
    font-size: .96rem;
    color: var(--jp-ink);
    line-height: 1.6;
}
body.jp-home .jp-areas__list li::before {
    content: "";
    flex: 0 0 auto;
    width: 14px;
    height: 14px;
    background-color: var(--jp-orange);
    -webkit-mask: var(--jp-i-check-b) center/contain no-repeat;
            mask: var(--jp-i-check-b) center/contain no-repeat;
}
body.jp-home .jp-areas__list li.jp-areas__more { color: var(--jp-mute); }
body.jp-home .jp-areas__list li.jp-areas__more::before { display: none; }


/* ==========================================================================
   19  CONTACT + CONTACT FORM 7
   ========================================================================== */

/* !important because the blanket rule that zeroes Salient's percentage-grid
   padding on every row wrapper would otherwise strip this panel's own inset and
   leave the copy flush against the panel edge. */
body.jp-home .jp-contact > .row_col_wrap_12 {
    background: var(--jp-orange-soft);
    border-radius: 32px;
    /* The floor is 20px, not 34px. This inset sits INSIDE the section's own
       gutter, so on a phone the two stack: 18px of gutter plus 34px here plus
       the panel's own 26px left the form 234px wide in a 390px screen. 20px
       keeps the panel reading as a panel without eating a seventh of the
       screen; the clamp still opens up to 60px on a desktop. */
    padding: clamp(20px, 4.5vw, 60px) !important;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(380px, 100%), 1fr));
    gap: clamp(34px, 4.5vw, 56px);
    align-items: start;
    box-sizing: border-box;
}
body.jp-home .jp-contact > .row_col_wrap_12::before,
body.jp-home .jp-contact > .row_col_wrap_12::after { display: none !important; }
body.jp-home .jp-contact__info,
body.jp-home .jp-contact__form { width: auto !important; float: none !important; margin: 0 !important; }
body.jp-home .jp-contact__info > .vc_column-inner { padding: 0 !important; }

body.jp-home .jp-contact__cards { margin: 30px 0 0 !important; }
body.jp-home .jp-contact__cards > .row_col_wrap_12_inner {
    display: flex;
    flex-direction: column;
    gap: 12px;
}
body.jp-home .jp-contact__cards > .row_col_wrap_12_inner::before,
body.jp-home .jp-contact__cards > .row_col_wrap_12_inner::after { display: none !important; }
body.jp-home .jp-cc { width: auto !important; float: none !important; margin: 0 !important; }
body.jp-home .jp-cc > .vc_column-inner {
    position: relative;
    background: var(--jp-surface);
    border-radius: 18px;
    padding: 18px 20px !important;
    transition: transform .18s ease;
}
body.jp-home .jp-cc:hover > .vc_column-inner { transform: translateX(4px); }
body.jp-home .jp-cc > .vc_column-inner > .wpb_wrapper {
    display: grid;
    grid-template-columns: 44px 1fr;
    grid-template-rows: auto auto;
    align-items: center;
    column-gap: 15px;
    row-gap: 6px;   /* client: air between the label and the value */
    line-height: 1.25;
}
body.jp-home .jp-cc > .vc_column-inner > .wpb_wrapper::before,
body.jp-home .jp-cc > .vc_column-inner > .wpb_wrapper::after { display: none !important; }
body.jp-home .jp-cc .nectar_icon_wrap {
    grid-row: 1 / 3;
    width: 44px;
    height: 44px;
    border-radius: 13px;
    display: grid;
    place-items: center;
}
/* CENTRING THE GLYPH TAKES THE WHOLE CHAIN, not just the chip.
   Salient nests four boxes inside the chip:
       .nectar_icon > .im-icon-wrap > span > svg
   and it sizes .nectar_icon at a fixed 60x60 - larger than this 44x44 chip.
   Centring only the chip therefore centred a 20px glyph inside a 60px box that
   was itself sitting at the chip's top-left and overflowing it, which put the
   glyph 21px from the left edge and 3px from the right. It read as "pushed down
   and right", and no amount of place-items on the chip alone could fix it.

   Every level is now sized to the chip and centred. The unnamed inner span is
   the last trap: it is a text box, so its line-height left 3.5px of descender
   space under a 20px glyph - hence line-height 0 and a block-level svg.

   Written against .nectar_icon_wrap rather than one section, because every icon
   chip in the build nests the same way and had the same fault: the About
   section's pair were 20.5px from the left edge and 0.5px from the right,
   jammed against the side of their own chip. Each chip keeps its own SIZE
   below; only the centring is shared. */
body.jp-home .nectar_icon_wrap .nectar_icon,
body.jp-home .nectar_icon_wrap .im-icon-wrap {
    display: grid !important;
    place-items: center !important;
    width: 100% !important;
    height: 100% !important;
    margin: 0 !important;
    padding: 0 !important;
    line-height: 0 !important;
}
body.jp-home .nectar_icon_wrap .im-icon-wrap > span {
    display: grid;
    place-items: center;
    line-height: 0;
    width: auto;
    height: auto;
}
body.jp-home .nectar_icon_wrap svg { display: block; }
body.jp-home .jp-cc .nectar_icon_wrap svg { width: 20px; height: 20px; }
/* The design gives these three chips three distinct fills on a WHITE card:
   #F08424 accent, #0F0F0F near-black, #EFEBE5 stone. Carried onto the dark card
   literally, two of the three disappeared - the near-black chip sat on #141B22
   and the stone one had become #141B22 itself, which is the card, so it was not
   a chip at all. That is the "some have been adjusted" the client is seeing:
   one orange tile, one barely-there tile and one missing tile.

   Translated rather than copied. Orange still leads, as it does in the design,
   and the two secondary chips are now ONE consistent tint that reads against
   the card. They are non-text UI, so the ring carries the 3:1 they need -
   measured 3.4:1 against the card - since a fill subtle enough not to compete
   with the orange cannot reach it on its own. */
body.jp-home .jp-cc .nectar_icon_wrap {
    background: var(--jp-surface-2);
    border: 1px solid rgba(255, 255, 255, .38);
}
body.jp-home .jp-cc--phone .nectar_icon_wrap {
    background: var(--jp-orange);
    border-color: var(--jp-orange);
}
/* nectar_icon's colour param does not reliably reach the inline SVG, and its
   el_class is dropped entirely, so the fill is set from the column class. */
/* All three glyphs are white now: every chip behind them is dark or accent, so
   there is no longer a light chip needing a dark glyph the way the design's
   stone one did. */
body.jp-home .jp-cc .nectar_icon_wrap svg path { fill: #fff !important; }

body.jp-home .jp-cc__label { grid-column: 2; align-self: end; }
body.jp-home .jp-cc__label p {
    font-size: .74rem;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--jp-mute);
    font-weight: 700;
    line-height: 1.25;
    margin: 0;
}
body.jp-home .jp-cc__value { grid-column: 2; align-self: start; }
body.jp-home a.nectar-button.jp-cc__value {
    display: inline-block;
    background: none !important;
    color: var(--jp-fg) !important;
    font-family: var(--jp-display);
    font-weight: 800;
    font-size: 1.14rem;
    letter-spacing: 0;
    line-height: 1.25;
    padding: 0 !important;
    margin: 0 !important;
    border: 0;
    border-radius: 0 !important;
    box-shadow: none !important;
    text-align: left;
}
body.jp-home a.nectar-button.jp-cc__value > span { padding: 0 !important; font: inherit; color: inherit; }
body.jp-home a.nectar-button.jp-cc__value--mail { font-size: 1.02rem; word-break: break-all; }
/* Whole card clickable, without wrapping the card in an anchor - which would
   put a block-level <a> around an icon, a label and a value, and take all three
   out of the client's reach as separate elements.
   Salient gives .nectar-button position:relative, and a stretched ::after
   resolves against the nearest POSITIONED ancestor. Left relative, the overlay
   covers only the anchor's own text and the rest of the card stays dead - which
   is how it measured before this rule: a probe over the icon returned the SVG,
   not the link. */
body.jp-home a.nectar-button.jp-cc__value--stretch { position: static !important; }
body.jp-home a.nectar-button.jp-cc__value--stretch::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 2;
}
body.jp-home .jp-cc__value--static p {
    font-family: var(--jp-display);
    font-weight: 800;
    font-size: 1.02rem;
    color: var(--jp-fg);
    line-height: 1.25;
    margin: 0;
}

/* --- the form card ---------------------------------------------------- */

body.jp-home .jp-contact__form > .vc_column-inner {
    background: var(--jp-surface);
    border-radius: 24px;
    /* Floor lowered to 18px: this is the THIRD inset in a row on a phone -
       section gutter, then the contact panel, then this card - and at 26px the
       three together left the fields 232px wide on a 360px screen. */
    padding: clamp(18px, 3vw, 36px) !important;
    box-shadow: 0 30px 70px -34px rgba(15, 15, 15, .3);
}
body.jp-home .jp-form__note { margin-top: 8px; }
body.jp-home .jp-form__note p { color: var(--jp-body); font-size: .95rem; margin: 0; }
body.jp-home .jp-form__wa { margin-top: 14px; }
body.jp-home .jp-form__wa p {
    color: var(--jp-mute);
    font-size: .82rem;
    text-align: center;
    margin: 0;
}
body.jp-home .jp-form__wa a { color: var(--jp-orange-dk); font-weight: 700; }

/* CF7 rebuilds its <p> and <br> from the blank lines in the form template on
   every save, so no layout may depend on them. They are dissolved and the form
   is gridded instead.
   Fields are keyed by NAME. :nth-of-type() cannot be used: autop puts each
   label in its own <p>, so with display:contents every label is
   :nth-of-type(1) and half the fields silently render at half width.
   Every direct child defaults to the full row, so a deleted or renamed field
   fails soft rather than breaking the grid. */
body.jp-home .jp-form {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 14px;
    margin-top: 24px;
}
body.jp-home .jp-form > * { grid-column: 1 / -1; }
body.jp-home .jp-form p { display: contents; }
body.jp-home .jp-form label { display: block; grid-column: 1 / -1; }
body.jp-home .jp-form label br { display: none; }
body.jp-home .jp-form .hidden-fields-container { display: none; }

/* the design pairs phone and postcode on one row */
body.jp-home .jp-form label:has([data-name="your-phone"]),
body.jp-home .jp-form label:has([data-name="your-postcode"]) { grid-column: span 1; }

body.jp-home .jp-form label {
    font-family: var(--jp-text);
    font-weight: 700;
    font-size: .82rem;
    color: var(--jp-ink);
    line-height: 1.4;
}
body.jp-home .jp-form .wpcf7-form-control-wrap { display: block; margin-top: 7px; }
body.jp-home .jp-form input[type="text"],
body.jp-home .jp-form input[type="tel"],
body.jp-home .jp-form input[type="email"],
body.jp-home .jp-form select,
body.jp-home .jp-form textarea {
    width: 100% !important;
    box-sizing: border-box;
    border: 1.5px solid var(--jp-line) !important;
    border-radius: 13px !important;
    padding: 14px 15px !important;
    background: var(--jp-off) !important;
    color: var(--jp-fg) !important;
    outline: none;
    font-family: var(--jp-text);
    font-size: 1rem;
    font-weight: 400;
    line-height: 1.4;
    margin: 0 !important;
    box-shadow: none !important;
    transition: border-color .18s ease, background .18s ease;
}
body.jp-home .jp-form select { appearance: none; -webkit-appearance: none; }
body.jp-home .jp-form textarea { min-height: 96px; resize: vertical; }
body.jp-home .jp-form input:focus,
body.jp-home .jp-form select:focus,
body.jp-home .jp-form textarea:focus {
    border-color: var(--jp-orange) !important;
    background: var(--jp-surface) !important;
}
body.jp-home .jp-form ::placeholder { color: var(--jp-mute); opacity: 1; }

body.jp-home .jp-form input.wpcf7-submit {
    /* CF7 wraps the submit in a <p>, and that <p> is display:contents here, so
       the INPUT is the grid item - not a direct child of .jp-form, which means
       the `.jp-form > *` full-row default does not reach it. Without this the
       button renders in a single column at half width. */
    grid-column: 1 / -1;
    width: 100%;
    border: none !important;
    cursor: pointer;
    background: var(--jp-orange) !important;
    color: #fff !important;
    font-family: var(--jp-text);
    font-weight: 800;
    font-size: 1.02rem;
    padding: 1.1em 1.5em !important;
    margin-top: 6px !important;
    line-height: 1.2;
    transition: transform .18s ease, background .18s ease;
}
body.jp-home .jp-form input.wpcf7-submit:hover { transform: translateY(-2px); background: var(--jp-orange-dk) !important; }
body.jp-home .jp-form input.wpcf7-submit:disabled { opacity: .55; cursor: not-allowed; transform: none; }
/* The spinner is a sibling of the submit inside the same dissolved <p>, so it
   would otherwise take a grid cell of its own and sit on top of the button. */
body.jp-home .jp-form .wpcf7-spinner {
    position: absolute;
    margin: 0;
    pointer-events: none;
}

/* Anti-spam plugins deliberately reuse the real field classes so bots cannot
   tell them apart, which means the field styling above would hit them too. */
body.jp-home .jp-form [data-cf7apps-honeypot],
body.jp-home .jp-form [class*="honeypot"],
body.jp-home .jp-form .cf7apps-honeypot-container {
    position: absolute !important;
    left: -9999px !important;
    width: 1px !important;
    height: 1px !important;
    overflow: hidden !important;
    opacity: 0 !important;
}

body.jp-home .jp-form .wpcf7-not-valid-tip {
    color: #C0392B;
    font-size: .78rem;
    font-weight: 600;
    margin-top: 5px;
}
body.jp-home .jp-form input.wpcf7-not-valid,
body.jp-home .jp-form textarea.wpcf7-not-valid { border-color: #C0392B !important; }
body.jp-home .wpcf7 form .wpcf7-response-output {
    grid-column: 1 / -1;
    margin: 12px 0 0;
    padding: 12px 14px;
    border-radius: 13px;
    border-width: 1.5px;
    font-size: .9rem;
    font-weight: 600;
}


/* ==========================================================================
   20  PRE-FOOTER CTA
   A widget area rendered on Salient's before-footer hook, so it appears on
   every page and the client edits it once in Appearance > Widgets.
   ========================================================================== */

body.jp-site .jp-precta {
    background: var(--jp-off);
    padding: clamp(56px, 7vw, 96px) 0;
}
body.jp-site .jp-precta__inner {
    max-width: var(--jp-wrap);
    margin: 0 auto;
    padding: 0 var(--jp-gut);
    box-sizing: border-box;
}
body.jp-site .jp-precta__panel {
    background: var(--jp-panel);
    border-radius: 32px;
    padding: clamp(38px, 5vw, 68px);
    text-align: center;
    position: relative;
    overflow: hidden;
}
body.jp-site .jp-precta__panel::before {
    content: "";
    position: absolute;
    left: 50%;
    top: -160px;
    width: 520px;
    height: 320px;
    transform: translateX(-50%);
    background: radial-gradient(ellipse, rgba(240, 132, 36, .28), transparent 70%);
}
body.jp-site .jp-precta__widget { position: relative; }
body.jp-site .jp-precta__eyebrow {
    font-family: var(--jp-display);
    font-weight: 700;
    font-size: .74rem;
    letter-spacing: .16em;
    text-transform: uppercase;
    color: var(--jp-orange);
    margin: 0;
    line-height: 1.6rem;
}
body.jp-site .jp-precta__h {
    font-family: var(--jp-display) !important;
    font-weight: 700;
    color: #fff;
    font-size: clamp(1.85rem, 3.5vw, 2.8rem);
    line-height: 1.08;
    letter-spacing: -.025em;
    margin: 16px auto 0;
    max-width: 24ch;
    text-wrap: balance;
}
body.jp-site .jp-precta__lead {
    color: var(--jp-mute-3);
    font-size: 1.06rem;
    margin: 18px auto 30px;
    max-width: 52ch;
}
body.jp-site .jp-precta__btns {
    display: flex;
    flex-wrap: wrap;
    gap: 14px;
    justify-content: center;
}
body.jp-site .jp-precta .wp-block-button { margin: 0; }
body.jp-site .jp-precta .wp-block-button__link { text-decoration: none; }


/* ==========================================================================
   21  FOOTER + COPYRIGHT
   ========================================================================== */

body.jp-site #footer-outer {
    background: var(--jp-panel) !important;
    color: var(--jp-mute-2);
    padding-bottom: 28px;   /* the design's footer padding, below the copyright rule */
}
body.jp-site #footer-outer #footer-widgets {
    padding: clamp(52px, 6vw, 80px) 0 0;
    background: var(--jp-panel) !important;
    border: 0;
}
body.jp-site #footer-outer #footer-widgets > .container,
body.jp-site #footer-outer #copyright > .container {
    max-width: var(--jp-wrap) !important;
    width: 100% !important;
    padding: 0 var(--jp-gut) !important;
    margin: 0 auto !important;
}
body.jp-site #footer-outer #footer-widgets .container > .row {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(230px, 100%), 1fr));
    gap: clamp(30px, 4vw, 48px);
    margin: 0;
    padding: 0;
}
/* Salient's clearfix pseudo-elements become grid items and consume cells. The
   tell when this is missed on a FLEX row is that the first and last child are
   each inset by exactly one gap value. */
body.jp-site #footer-outer #footer-widgets .container > .row::before,
body.jp-site #footer-outer #footer-widgets .container > .row::after { display: none !important; }
body.jp-site #footer-outer #footer-widgets .container > .row > .col {
    width: auto !important;
    float: none !important;
    margin: 0 !important;
    padding: 0 !important;
}
body.jp-site #footer-outer #footer-widgets .widget { margin: 0; padding: 0; }

body.jp-site #footer-widgets .jp-foot__logo { margin: 0; }
body.jp-site #footer-widgets .jp-foot__logo img {
    height: 56px !important;
    width: auto !important;
    max-width: none;
    display: block;
}
body.jp-site #footer-widgets .jp-foot__blurb {
    font-size: .96rem;
    margin: 18px 0 0;
    max-width: 32ch;
    color: var(--jp-mute-2);
    line-height: 1.6;
}
body.jp-site #footer-widgets .jp-foot__social {
    display: flex;
    gap: 10px;
    margin: 22px 0 0;
    padding: 0;
    list-style: none;
}
body.jp-site #footer-widgets .jp-foot__social li { margin: 0; padding: 0; }
body.jp-site #footer-widgets .jp-foot__social .wp-block-social-link {
    width: 42px;
    height: 42px;
    border-radius: 13px;
    background: rgba(255, 255, 255, .08) !important;
    display: grid;
    place-items: center;
    transition: background .18s ease;
    margin: 0;
}
body.jp-site #footer-widgets .jp-foot__social .wp-block-social-link:hover { background: var(--jp-orange) !important; }
body.jp-site #footer-widgets .jp-foot__social .wp-block-social-link-anchor {
    color: #fff !important;
    fill: #fff !important;
    display: grid !important;
    place-items: center !important;
    width: 100% !important;
    height: 100% !important;
    padding: 0 !important;
    margin: 0 !important;
    line-height: 0 !important;
}
/* core/social-links ships padding on the LI as well as the anchor; left in
   place the chip is 42x42 but the anchor is 42x38, so the glyph lands in the
   top-left corner rather than the middle. */
body.jp-site #footer-widgets .jp-foot__social .wp-block-social-link { padding: 0 !important; }
body.jp-site #footer-widgets .jp-foot__social .wp-block-social-link-label { display: none; }
body.jp-site #footer-widgets .jp-foot__social svg { width: 17px; height: 17px; }

/* Salient sets .ascend #footer-outer #footer-widgets .widget.widget_nav_menu li
   { padding: 4px 0 !important }, which turns the design's 11px gap into a 45px
   pitch. Matching that selector's .widget class is what makes this win. */
body.jp-site #footer-outer #footer-widgets .widget h4,
body.jp-site #footer-widgets .jp-foot__h {
    color: #fff !important;
    font-family: var(--jp-display) !important;
    font-size: .86rem !important;
    font-weight: 700 !important;
    letter-spacing: .14em;
    text-transform: uppercase;
    line-height: 1.08;   /* the design's heading leading, not the body's */
    margin: 0 0 18px !important;
    padding: 0;
}
body.jp-site #footer-outer #footer-widgets .widget.widget_nav_menu ul {
    display: flex;
    flex-direction: column;
    gap: 11px;
    margin: 0;
    padding: 0;
}
/* Salient sets .ascend #footer-outer #footer-widgets .widget.widget_nav_menu li
   { padding: 4px 0 !important }. Matching that selector's .widget class is what
   makes this win. The li also has to state the design's 16px/1.6 line box: left
   on Salient's 14px body size the rows come out 2.2px short each. */
body.jp-site #footer-outer #footer-widgets .widget.widget_nav_menu li {
    margin: 0 !important;
    padding: 0 !important;
    border: 0 !important;
    list-style: none !important;
    font-size: 1rem;
    line-height: 1.6;
}
body.jp-site #footer-outer #footer-widgets .widget.widget_nav_menu li a {
    color: var(--jp-mute-2) !important;
    font-family: var(--jp-text);
    font-size: .96rem;
    font-weight: 400;
    line-height: inherit;
    padding: 0 !important;
    display: inline;
    transition: color .18s ease;
}
body.jp-site #footer-outer #footer-widgets .widget.widget_nav_menu li a:hover { color: var(--jp-orange) !important; }

body.jp-site #footer-widgets .jp-foot__phone {
    margin: 0;
    line-height: 1.4;
}
body.jp-site #footer-widgets .jp-foot__phone a {
    color: #fff !important;
    font-family: var(--jp-display);
    font-weight: 800;
    font-size: 1.14rem;
    transition: color .18s ease;
}
body.jp-site #footer-widgets .jp-foot__phone a:hover { color: var(--jp-orange) !important; }
body.jp-site #footer-widgets .jp-foot__line {
    margin: 13px 0 0;
    font-size: .96rem;
    color: var(--jp-mute-2);
    line-height: 1.5;
}
body.jp-site #footer-widgets .jp-foot__line a { color: var(--jp-mute-2) !important; transition: color .18s ease; }
body.jp-site #footer-widgets .jp-foot__line a:hover { color: var(--jp-orange) !important; }
body.jp-site #footer-widgets .jp-foot__line--mail a { word-break: break-all; }

/* copyright bar. Salient splits it 5/12 + 7/12; with the second column empty
   the first forces the copyright onto two lines. Flexed instead. */
body.jp-site #footer-outer #copyright {
    background: var(--jp-panel) !important;
    border: 0;
    padding: 0;
    margin-top: clamp(36px, 4vw, 52px);
}
/* #copyright IS the .row - .container is INSIDE it, holding .col.span_5 (the
   copyright text) and .col.span_7 (Salient's own social list). The text lives
   in span_5, so hiding that column removes the copyright itself. span_7 is the
   one to hide: the design puts its socials in the footer's brand column. */
body.jp-site #footer-outer #copyright > .container {
    display: flex;
    flex-wrap: wrap;
    gap: 14px;
    justify-content: space-between;
    align-items: center;
    border-top: 1px solid rgba(255, 255, 255, .12);
    padding-top: 24px !important;
    padding-bottom: 0 !important;
}
body.jp-site #footer-outer #copyright > .container::before,
body.jp-site #footer-outer #copyright > .container::after { display: none !important; }
body.jp-site #footer-outer #copyright .col.span_7 { display: none !important; }
body.jp-site #footer-outer #copyright .col.span_5 {
    width: 100% !important;
    float: none !important;
    margin: 0 !important;
    padding: 0 !important;
    flex: 1 1 auto;
}
body.jp-site #footer-outer #copyright p {
    display: flex;
    flex-wrap: wrap;
    gap: 14px;
    justify-content: space-between;
    width: 100%;
    margin: 0;
    font-size: .85rem;
    color: var(--jp-mute-4);
    line-height: 1.6;
}
body.jp-site .jp-copy__a,
body.jp-site .jp-copy__b { color: var(--jp-mute-4); }


/* ==========================================================================
   22  COOKIE BAR
   Not in the design, but the plugin is active, so it is skinned to the palette
   rather than left in the plugin's own colours.
   ========================================================================== */

body.jp-site #moove_gdpr_cookie_info_bar {
    background: var(--jp-panel) !important;
    border-top: 2px solid var(--jp-orange) !important;
    font-family: var(--jp-text) !important;
}
body.jp-site #moove_gdpr_cookie_info_bar .moove-gdpr-info-bar-container,
body.jp-site #moove_gdpr_cookie_info_bar p,
body.jp-site #moove_gdpr_cookie_info_bar span { color: var(--jp-mute-2) !important; font-family: var(--jp-text) !important; }
body.jp-site #moove_gdpr_cookie_info_bar .mgbutton,
body.jp-site #moove_gdpr_cookie_info_bar a.mgbutton {
    background: var(--jp-orange) !important;
    border-color: var(--jp-orange) !important;
    color: #fff !important;
    border-radius: 999px !important;
    font-weight: 800 !important;
    font-family: var(--jp-text) !important;
}
body.jp-site #moove_gdpr_cookie_info_bar .mgbutton:hover { background: var(--jp-orange-dk) !important; border-color: var(--jp-orange-dk) !important; }
body.jp-site #moove_gdpr_save_popup_settings_button { border-radius: 999px !important; }


/* ==========================================================================
   23  RESPONSIVE

   The design's own switch is 1080px, which is also Salient's burger
   breakpoint here. Salient's slider has a hard minimum of 1000, so 1080 is
   reachable exactly and no design value has to be compromised.

   1081px is the worst case to re-measure after any header typography change,
   because it is one pixel above the burger.
   ========================================================================== */

@media (max-width: 1080px) {
    /* The BAR stays, as the design has it - tagline on the left, socials after
       it. Only the two trust items and their divider drop out, which is what
       the design's data-wide attribute does. */
    body.jp-site #header-secondary-outer ul.sf-menu { display: none !important; }
    body.jp-site #header-secondary-outer ul.sf-menu::after { display: none !important; }

    /* the desktop menu and the phone/CTA lockup give way to the burger */
    body.jp-site #header-outer #top nav > ul.sf-menu { display: none !important; }
    body.jp-site #header-outer #top nav > ul.buttons > li.nectar-header-text-content-wrap { display: none !important; }
    body.jp-site #header-outer #top nav { display: none !important; }

    /* Salient sets flex-direction:row-reverse on this column at mobile so the
       burger, which is first in the DOM, ends up on the right. Adding
       justify-content:flex-end on top of a reversed row aligns to the LEFT,
       which is how the burger ended up next to the logo. The direction is
       stated explicitly here so the alignment reads the way it behaves. */
    body.jp-site #header-outer #top .col.span_9 {
        display: flex;
        flex-direction: row !important;
        align-items: center;
        justify-content: flex-end;
    }
    /* Salient's clearfix ::after on the column is a flex item at order 0, so it
       is laid out before the burger and justify-content:flex-end then aligns
       the PAIR, leaving the burger at the left of the column. */
    body.jp-site #header-outer #top .col.span_9::before,
    body.jp-site #header-outer #top .col.span_9::after { display: none !important; }
    body.jp-site #header-outer #top .col.span_9 > .slide-out-widget-area-toggle.mobile-icon {
        display: block !important;
        position: static !important;
        float: none !important;
        margin: 0 !important;
    }

    /* the design's fixed bottom bar */
    body.jp-site .jp-mobar { display: flex; }
    /* The design lets its fixed bar sit over the copyright. Ours clears it
       instead, by the bar's height plus the design's own 28px footer padding,
       so the last line is readable rather than half hidden. */
    body.jp-site #footer-outer { padding-bottom: calc(68px + 28px); }
}

@media (min-width: 1081px) {
    /* above the breakpoint Salient shows the ul.buttons burger; the design has
       neither, so both are hidden */
    body.jp-site #header-outer #top nav > ul.buttons > li.slide-out-widget-area-toggle,
    body.jp-site #header-outer #top .col.span_9 > .slide-out-widget-area-toggle.mobile-icon { display: none !important; }
}

/* Tablet and below: the design's grids are all auto-fit, so they collapse on
   their own. What needs saying is the pieces that are positioned. */
@media (max-width: 999px) {
    /* Stacked there is no copy beside it to match, so the photo comes back into
       flow on the design's own 5/5.4 ratio - absolute here would collapse the
       column to nothing. The BADGE stays absolute: the design keeps it hanging
       off the photo's corner at every width, and floating it into the flow
       instead added 12px and moved it away from the image. */
    body.jp-home .jp-about__media > .vc_column-inner { height: auto; }
    body.jp-home .jp-about__media .img-with-aniamtion-wrap {
        position: static;
        inset: auto;
        aspect-ratio: 5 / 5.4;
    }
}

@media (max-width: 767px) {
    /* The head keeps the design's flex declaration at every width - it wraps on
       its own. Only the cross-axis alignment changes, because once the action
       has wrapped there is nothing left to bottom-align it to. */
    body.jp-home .jp-head > .row_col_wrap_12_inner { align-items: flex-start; }

    /* the design holds the photo at 380px on a phone; 300 lost 80px of it */
    body.jp-home .jp-sf__card { left: 16px; right: 16px; bottom: 16px; padding: 16px 18px; }

    body.jp-home .jp-contact > .row_col_wrap_12 { border-radius: 24px; }
    body.jp-home .jp-areas__panel > .vc_column-inner { border-radius: 24px; }
    body.jp-home .jp-sf > .row_col_wrap_12 { border-radius: 24px; }
    body.jp-site .jp-precta__panel { border-radius: 24px; }
}

@media (max-width: 620px) {
    /* Two inline-level buttons that wrap have no row gap, and a margin on an
       inline-level box grows the line box on desktop too. Making them block
       below a phone breakpoint is deterministic; width:fit-content keeps the
       pill shape instead of stretching it. */
    body.jp-home .jp-btnrow__col > .vc_column-inner > .wpb_wrapper { flex-direction: column; align-items: flex-start; }
    body.jp-home .jp-btnrow__col a.nectar-button.jp-btn { width: fit-content; }
    body.jp-site .jp-precta__btns .wp-block-button { width: 100%; }
    body.jp-site .jp-precta__btns .wp-block-button__link { width: 100%; }

    body.jp-home .jp-form { grid-template-columns: minmax(0, 1fr); }
    body.jp-home .jp-form label:has([data-name="your-phone"]),
    body.jp-home .jp-form label:has([data-name="your-postcode"]) { grid-column: 1 / -1; }

    body.jp-home .jp-cc > .vc_column-inner > .wpb_wrapper { column-gap: 12px; }
}

@media (max-width: 420px) {
    body.jp-site .jp-mobar__btn { font-size: .92rem; padding: .85em .6em; }
    body.jp-home .jp-card .jp-h3 { margin-left: 20px !important; margin-right: 20px !important; }
    body.jp-home .jp-card__text { margin-left: 20px; margin-right: 20px; }
    body.jp-home .jp-card a.nectar-button.jp-link { margin-left: 20px !important; margin-right: 20px !important; }
}

@media (prefers-reduced-motion: reduce) {
    body.jp-site * { animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; }
}


/* ==========================================================================
   23b  INNER PAGES

   The eight inner pages are built from the blocks the design itself uses: a
   two-column hero, prose-beside-cards splits, panels, card grids, galleries
   and link tiles. They are styled BY BLOCK, never by page, so a ninth page
   needs no new CSS here.

   Everything reuses the tokens and the class vocabulary the homepage already
   sets, which is why these pages followed the site into the dark theme without
   a second pass.

   Two Salient facts run through the whole section:

     - a row's columns are FLOATED. Any block that wants a real two-column
       layout has to turn the row wrapper into a grid and switch the floats off,
       or the second column drops underneath and leaves the void beside the
       first that the client saw;

     - the moment it does, Salient's clearfix ::before/::after become grid items
       and eat one gap at each end of the row. They are display:none in every
       grid below for that reason, not for tidiness.
   ========================================================================== */

/* SCOPING. Every selector below that names a class the HOMEPAGE also uses is
   written `.jp-ip <class>`, because these rules sit later in the file than the
   homepage's and win a specificity tie outright. The unscoped version of the
   grid rule collapsed the homepage's six service cards and four process steps
   into a single 1160px column, and nothing in the suite noticed: the checks
   asked whether the homepage rendered, not whether it still had columns. The
   shared names today are .jp-grid, .jp-ticks and .jp-form__title. */


/* NO bottom padding. .jp-section already pays a full rhythm on its TOP, and the
   design's sections are `padding: clamp(64px,7vw,104px) 0 0` for the same
   reason. Adding a bottom as well made every gap between two sections 224px
   against the design's 104, which is the empty black space between blocks the
   client was looking at. The last section on the page needs none either: the
   pre-footer CTA below it brings its own. */

/* ---- the two-column blocks ----------------------------------------------
   One grid rule covers the hero and every content split. auto-fit against the
   design's own 400px minimum means these stack at exactly the width the design
   stacks at, rather than at a breakpoint picked by hand. */
body.jp-home .jp-ip--split > .row_col_wrap_12 {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(400px, 100%), 1fr));
    gap: clamp(34px, 4.5vw, 60px);
    align-items: start;
}
body.jp-home .jp-ph.jp-ip--split > .row_col_wrap_12 { align-items: center; }
body.jp-home .jp-ip--split > .row_col_wrap_12::before,
body.jp-home .jp-ip--split > .row_col_wrap_12::after { display: none !important; }
body.jp-home .jp-ip--split > .row_col_wrap_12 > div {
    width: auto !important;
    float: none !important;
    margin: 0 !important;
}
/* The breadcrumb sits above both columns, not inside the first one. */
body.jp-home .jp-crumbcol { grid-column: 1 / -1; }

/* ---- the hero ------------------------------------------------------------ */
body.jp-home .jp-ph {
    background-color: var(--jp-panel);
    /* the design's warm glow off the top right corner, as a background layer
       rather than a pseudo-element: the row's own ::before and ::after are
       Salient's clearfix and are not free to take */
    background-image: radial-gradient(420px 420px at calc(100% + 90px) -110px,
                                      rgba(240, 132, 36, .22), transparent 68%);
    background-repeat: no-repeat;
    overflow: hidden;
    padding-top: clamp(34px, 4vw, 54px) !important;
    padding-bottom: clamp(56px, 6vw, 84px) !important;
}

body.jp-home .jp-crumb { margin: 0 0 clamp(22px, 3vw, 34px) !important; }
body.jp-home .jp-crumb p {
    font-family: var(--jp-text);
    font-size: .86rem;
    font-weight: 600;
    color: var(--jp-mute);
    margin: 0;
}
body.jp-home .jp-crumb a { color: var(--jp-mute); text-decoration: none; }
body.jp-home .jp-crumb a:hover { color: var(--jp-orange-lt); }
body.jp-home .jp-crumb span { color: var(--jp-fg); }
body.jp-home .jp-crumb i { font-style: normal; color: var(--jp-mute-4); margin: 0 5px; }

/* The one word the design picks out of the headline. */
body.jp-home .jp-hi { color: var(--jp-orange); }

body.jp-home .jp-ph .jp-lead p { max-width: 58ch; }
body.jp-home .jp-ph .jp-btnrow { margin-top: 30px !important; }

/* The hero photograph. */
body.jp-home .jp-ph .jp-ip__col--b > .vc_column-inner { position: relative; }
body.jp-home .jp-ph .img-with-aniamtion-wrap {
    border-radius: 26px;
    overflow: hidden;
    margin: 0;
    background: var(--jp-surface);
    box-shadow: 0 34px 74px -34px rgba(0, 0, 0, .7);
}
/* image_with_animation puts el_class on the IMG ITSELF, not on a wrapper the
   way most elements do, so the selector has to be img.jp-ph__img. */
body.jp-home img.jp-ph__img {
    display: block;
    width: 100%;
    aspect-ratio: 5 / 3.6;
    object-fit: cover;
}

/* The badge that overlays the About hero photograph. It shares the homepage's
   badge styling; only where it sits differs. */
body.jp-home .jp-ph .jp-about__badge { bottom: -20px; left: -14px; right: auto; }

/* ---- panels --------------------------------------------------------------
   The rounded slab a section or a column sits on. */
body.jp-home .jp-panel > .vc_column-inner {
    background: var(--jp-surface);
    border: 1px solid var(--jp-line);
    border-radius: 28px;
    padding: clamp(26px, 3.5vw, 48px) !important;
    height: 100%;
    box-sizing: border-box;
}
body.jp-home .jp-panel--dark > .vc_column-inner {
    background: var(--jp-panel);
    border-color: rgba(255, 255, 255, .08);
}
body.jp-home .jp-panel .jp-lead p { color: var(--jp-mute-3); }

/* ---- grids ---------------------------------------------------------------
   Every group of tiles is one grid rule plus its own minimum. The minimum is
   the design's, carried through the extraction, so a group wraps where the
   design wraps instead of at a column count typed in by hand. */
body.jp-home .jp-ip .jp-grid > .row_col_wrap_12_inner {
    display: grid;
    /* A DECLARED track, and minmax(0,...) not 1fr. Left implicit the track sizes
       to the widest item's max-content, and plain `1fr` still floors at the
       item's min-content - either way one long address turned every contact
       tile into a 395px card inside a 375px screen. minmax(0,1fr) lets the
       track shrink and the text inside wrap instead. */
    grid-template-columns: minmax(0, 1fr);
    gap: 16px;
    align-items: stretch;
}

body.jp-home .jp-ip .jp-grid > .row_col_wrap_12_inner::before,
body.jp-home .jp-ip .jp-grid > .row_col_wrap_12_inner::after { display: none !important; }
body.jp-home .jp-ip .jp-grid > .row_col_wrap_12_inner > div {
    width: auto !important;
    float: none !important;
    margin: 0 !important;
}
body.jp-home .jp-ip .jp-grid--m240 > .row_col_wrap_12_inner { grid-template-columns: repeat(auto-fit, minmax(min(240px, 100%), 1fr)); }
body.jp-home .jp-ip .jp-grid--m250 > .row_col_wrap_12_inner { grid-template-columns: repeat(auto-fit, minmax(min(250px, 100%), 1fr)); }
body.jp-home .jp-ip .jp-grid--m260 > .row_col_wrap_12_inner { grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 1fr)); }
body.jp-home .jp-ip .jp-grid--m280 > .row_col_wrap_12_inner { grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr)); }
body.jp-home .jp-ip .jp-grid--m290 > .row_col_wrap_12_inner { grid-template-columns: repeat(auto-fit, minmax(min(290px, 100%), 1fr)); }
body.jp-home .jp-ip .jp-grid--m320 > .row_col_wrap_12_inner { grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr)); grid-column-gap: 34px; }
/* Above the stacking width the COUNT decides the arrangement, so four tiles sit
   two-by-two rather than three across with a lone orphan underneath. Below it
   the auto-fit rule above takes over and wraps where the design wraps. */
@media (min-width: 1000px) {
    body.jp-home .jp-ip .jp-grid--p2 > .row_col_wrap_12_inner { grid-template-columns: repeat(2, 1fr); }
    body.jp-home .jp-ip .jp-grid--p3 > .row_col_wrap_12_inner { grid-template-columns: repeat(3, 1fr); }
    body.jp-home .jp-ip .jp-grid--p4 > .row_col_wrap_12_inner { grid-template-columns: repeat(4, 1fr); }
}

/* The contact tiles carry an icon again. The chip is the homepage's, and the
   tile's grid has always reserved a 44px column for it - without one, every
   line of contact detail sat indented beside an empty square. */
body.jp-home .jp-ic--hours .nectar_icon_wrap {
    width: 44px;
    height: 44px;
    border-radius: 13px;
    background: rgba(240, 132, 36, .14);
    display: grid;
    place-items: center;
    margin: 0 0 14px !important;
}
body.jp-home .jp-ic--hours .nectar_icon_wrap svg path { fill: var(--jp-orange) !important; }

/* Inside a panel an unboxed tile has nothing to separate it from its
   neighbours, so questions ran together. On the open page they stay open. */
body.jp-home .jp-panel .jp-ic--plain > .vc_column-inner {
    background: var(--jp-surface-2);
    border: 1px solid rgba(255, 255, 255, .07);
    border-radius: 18px;
    padding: 22px !important;
}
body.jp-home .jp-panel--dark .jp-ic--plain > .vc_column-inner { background: rgba(255, 255, 255, .05); }

/* A column of tiles beside the prose, which is how the design stacks them. */
body.jp-home .jp-ip .jp-grid--stack > .row_col_wrap_12_inner { grid-template-columns: 1fr; gap: 14px; }
/* A split inside a panel. */
body.jp-home .jp-ip .jp-grid--split > .row_col_wrap_12_inner {
    grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr));
    gap: clamp(28px, 3.5vw, 48px);
    align-items: center;
}
body.jp-home .jp-ip .jp-grid { margin-top: 30px !important; }
body.jp-home .jp-ip .jp-grid--split { margin-top: 0 !important; }

/* ---- tiles ---------------------------------------------------------------
   Boxed or not is read from the design, not guessed: the comparison cards sit
   on a lifted surface and the FAQ answers sit open on the page. Styling both
   the same turned a readable question list into sixteen identical slabs. */
body.jp-home .jp-ic > .vc_column-inner { height: 100%; box-sizing: border-box; }

body.jp-home .jp-ic--boxed > .vc_column-inner {
    background: var(--jp-surface);
    border: 1px solid var(--jp-line);
    border-radius: 20px;
    padding: 24px !important;
    transition: border-color .22s ease, box-shadow .22s ease, transform .22s ease;
}
/* Inside a panel the tiles are already on a raised surface, so they lift once
   more rather than repeating the same colour. */
body.jp-home .jp-panel .jp-ic--boxed > .vc_column-inner {
    background: var(--jp-surface-2);
    border-color: rgba(255, 255, 255, .07);
}
body.jp-home .jp-panel--dark .jp-ic--boxed > .vc_column-inner { background: rgba(255, 255, 255, .05); }
@media (hover: hover) {
    body.jp-home .jp-ic--boxed:hover > .vc_column-inner {
        border-color: var(--jp-orange);
        box-shadow: 0 0 26px -6px rgba(240, 132, 36, .4);
        transform: translateY(-2px);
    }
}
body.jp-home .jp-ic--plain > .vc_column-inner { padding: 0 !important; }

body.jp-home .jp-ic__step p {
    font-family: var(--jp-display);
    font-weight: 800;
    font-size: .78rem;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--jp-orange);
    margin: 0 0 12px;
}
body.jp-home .jp-ic__text p {
    color: var(--jp-body);
    font-size: .96rem;
    line-height: 1.55;
    margin: 8px 0 0;
}
body.jp-home .jp-ic__text + .jp-ic__text p { margin-top: 10px; }

/* The icon chip. nectar_icon drops el_class, so this is reached through the
   column's class instead. */
body.jp-home .jp-ic .nectar_icon_wrap {
    width: 44px;
    height: 44px;
    border-radius: 13px;
    background: rgba(240, 132, 36, .14);
    display: grid;
    place-items: center;
    margin: 0 0 16px !important;
}
body.jp-home .jp-ic .nectar_icon_wrap .nectar_icon,
body.jp-home .jp-ic .nectar_icon_wrap .im-icon-wrap {
    display: grid !important;
    place-items: center !important;
    width: 100% !important;
    height: 100% !important;
    margin: 0 !important;
    padding: 0 !important;
    line-height: 0 !important;
}
body.jp-home .jp-ic .nectar_icon_wrap .im-icon-wrap > span { display: grid; place-items: center; line-height: 0; }
body.jp-home .jp-ic .nectar_icon_wrap i,
body.jp-home .jp-ic .nectar_icon_wrap [class^="iconsmind-"] { color: var(--jp-orange) !important; font-size: 21px !important; }
body.jp-home .jp-ic .nectar_icon_wrap svg { display: block; width: 21px; height: 21px; }
body.jp-home .jp-ic .nectar_icon_wrap svg path { fill: var(--jp-orange) !important; }

/* ---- tick lists ----------------------------------------------------------
   One tick treatment across the site, so a reader meets a single kind of list
   rather than a different one per page. */
body.jp-home .jp-ip .jp-ticks ul { margin: 16px 0 0; padding: 0; }
body.jp-home .jp-ip .jp-ticks li {
    position: relative;
    padding: 0 0 0 27px;
    margin: 0 0 11px;
    color: var(--jp-mute-3);
    font-weight: 600;
    font-size: .97rem;
    line-height: 1.5;
}
body.jp-home .jp-ip .jp-ticks li:last-child { margin-bottom: 0; }
body.jp-home .jp-ip .jp-ticks li::before {
    content: "";
    position: absolute;
    left: 0;
    top: .3em;
    width: 15px;
    height: 15px;
    background-color: var(--jp-orange);
    -webkit-mask: var(--jp-i-check-b) center/contain no-repeat;
            mask: var(--jp-i-check-b) center/contain no-repeat;
}

/* ---- opening hours ------------------------------------------------------- */
body.jp-home .jp-hours__list ul { margin: 14px 0 0; padding: 0; }
body.jp-home .jp-hours__list li {
    display: flex;
    justify-content: space-between;
    gap: 16px;
    font-weight: 600;
    font-size: .97rem;
    color: var(--jp-body);
    margin: 0 0 9px;
}
body.jp-home .jp-hours__list li b { color: var(--jp-fg); font-weight: 700; }

/* ---- galleries ----------------------------------------------------------- */
body.jp-home .jp-gal__cell > .vc_column-inner { height: 100%; padding: 0 !important; }
body.jp-home .jp-ip .jp-grid--gal .img-with-aniamtion-wrap,
body.jp-home .jp-ip .jp-grid--gal .img-with-aniamtion-wrap .inner,
body.jp-home .jp-ip .jp-grid--gal .img-with-aniamtion-wrap .hover-wrap,
body.jp-home .jp-ip .jp-grid--gal .img-with-aniamtion-wrap .hover-wrap-inner { height: 100%; margin: 0; }
body.jp-home img.jp-gal__img {
    display: block;
    width: 100%;
    height: 100%;
    /* one ratio for every cell, whatever the source photograph, so the rows
       line up instead of stepping */
    aspect-ratio: 4 / 3;
    object-fit: cover;
    border-radius: 18px;
}

/* ---- related services ----------------------------------------------------
   The whole tile is the link, using Salient's own column link rather than a
   button pretending to be a card. */
body.jp-home .jp-rel__cell > .vc_column-inner {
    background: var(--jp-surface);
    border: 1px solid var(--jp-line);
    border-radius: 18px;
    padding: 22px 24px !important;
    height: 100%;
    box-sizing: border-box;
    transition: border-color .22s ease, transform .22s ease;
}
@media (hover: hover) {
    body.jp-home .jp-rel__cell:hover > .vc_column-inner {
        border-color: var(--jp-orange);
        transform: translateY(-3px);
    }
}
body.jp-home .jp-rel__label p {
    font-family: var(--jp-display);
    font-weight: 700;
    font-size: 1.04rem;
    color: var(--jp-fg);
    margin: 0;
    padding-right: 28px;
    position: relative;
}
body.jp-home .jp-rel__label p::after {
    content: "";
    position: absolute;
    right: 0;
    top: 50%;
    width: 18px;
    height: 18px;
    transform: translateY(-50%);
    background-color: var(--jp-orange);
    -webkit-mask: var(--jp-i-arrow) center/contain no-repeat;
            mask: var(--jp-i-arrow) center/contain no-repeat;
}

/* ---- articles: the client's own long-form copy ---------------------------

   These sections carry passages from jpeacockinsulation.co.uk, and the longest
   ran 246 words. Poured into a full-width heading they were a wall of text with
   no design in them at all, which is exactly what the client said. Three things
   fix that: a magazine split so the measure is a column and not the container,
   paragraphs broken at their own sentence ends, and an ASIDE that travels with
   the copy instead of sitting at the top leaving a screen and a half of nothing
   beside it. */

/* The body of a feature sets as TWO BALANCED COLUMNS. That is the structure
   these sections were missing: every section in the design ends in cards, a
   gallery, a photograph or a tick list, and these ended in a ribbon of text. */
body.jp-home .jp-grid--prose { margin-top: 26px !important; }

/* Not enough copy to fill two columns, so it does not pretend to. One column at
   a reading measure - the alternative was three paragraphs split two-and-one
   with the second column ending halfway up the first. */
body.jp-home .jp-prose1 > .vc_column-inner > .wpb_wrapper { max-width: 74ch; }
body.jp-home .jp-prose1 .wpb_text_column { margin: 0 0 15px; }
body.jp-home .jp-prose1 .wpb_text_column:last-child { margin-bottom: 0; }
body.jp-home .jp-prose1 .jp-lead { margin-top: 0; }
body.jp-home .jp-prose2 > .vc_column-inner > .wpb_wrapper {
    columns: 2;
    column-gap: clamp(30px, 4vw, 58px);
}
/* A paragraph broken across the fold of two columns is harder to read than a
   slightly uneven pair of columns. */
body.jp-home .jp-prose2 .wpb_text_column {
    break-inside: avoid;
    margin: 0 0 15px;
}
body.jp-home .jp-prose2 .wpb_text_column:last-child { margin-bottom: 0; }
body.jp-home .jp-prose2 .jp-lead { margin-top: 0; }
@media (max-width: 800px) {
    body.jp-home .jp-prose2 > .vc_column-inner > .wpb_wrapper { columns: 1; }
}

/* A feature's opening paragraph is the lead, so it is set a little larger than
   the body that follows it. */
body.jp-home .jp-ip--feature > .row_col_wrap_12 > .jp-ip__col > .vc_column-inner > .wpb_wrapper > .jp-lead p {
    font-size: 1.06rem;
    max-width: 72ch;
}

/* The photograph beside a passage. PORTRAIT and sticky: at the hero's landscape
   ratio it was 413px next to 754px of copy and left a hole under it. */
body.jp-home .jp-ip .img-with-aniamtion-wrap {
    border-radius: 22px;
    overflow: hidden;
    margin: 0;
    background: var(--jp-surface);
}
/* Copy on the left, a photograph on the right, both about the same height. Used
   where a section would otherwise end in a ribbon of prose. */
body.jp-home .jp-ip--sidephoto > .row_col_wrap_12 { align-items: start; }
body.jp-home .jp-ip--sidephoto img.jp-ph__img { aspect-ratio: 4 / 3; }
body.jp-home .jp-ip--sidephoto .jp-lead { margin-top: 0; }
body.jp-home .jp-ip--sidephoto .jp-lead + .jp-lead { margin-top: 15px; }
@media (min-width: 1000px) {
    body.jp-home .jp-ip--sidephoto .jp-ip__col--b > .vc_column-inner {
        position: sticky;
        top: clamp(96px, 12vh, 132px);
    }
}

/* No rules for jp-ip--haspic / jp-ip--aside any more. Those were the shapes for
   pairing a photograph with a long passage from the live site, and the sections
   that used them were repeating the design rather than adding to it, so they
   were removed. Dead rules for shapes no page uses are how a stylesheet grows
   selectors nobody can account for. */

/* A full-width section's intro is still prose and still needs a measure; left
   alone it ran the whole 1160px container. */
body.jp-home .jp-ip .jp-ip__col > .vc_column-inner > .wpb_wrapper > .jp-lead p { max-width: 72ch; }
/* and so does a panel's, which was running the full 1160px slab */
body.jp-home .jp-panel > .vc_column-inner > .wpb_wrapper > .jp-lead p { max-width: 68ch; }

/* Two columns of prose under their own subheadings, for a comparison that is
   too long to be a pair of cards. */
body.jp-home .jp-grid--split .jp-h3 { margin-bottom: 4px; }

/* ---- gallery ------------------------------------------------------------
   WPBakery's own Image Gallery element, so the photographs open in a lightbox
   and the client manages them all from one media picker. Salient renders it
   through its portfolio grid, which is why the selectors below are portfolio
   ones rather than anything of ours. */
body.jp-home .jp-gal { margin: 0 !important; }
/* Salient's portfolio grid pays for its gutters with a NEGATIVE margin on the
   row and a matching padding on each item. Zeroing the margin (and leaving the
   padding) made every tile 30px wider than its container and pushed it past the
   edge of a 375px screen. The compensation is left intact and only the vertical
   margin is taken. */
body.jp-home .jp-gal .portfolio-items { margin-top: 0 !important; margin-bottom: 0 !important; }
body.jp-home .jp-gal .work-item {
    border-radius: 18px;
    overflow: hidden;
    background: var(--jp-surface);
}
body.jp-home .jp-gal .work-item img {
    display: block;
    width: 100%;
    height: auto;
    aspect-ratio: 4 / 3;
    object-fit: cover;
    transition: transform .5s cubic-bezier(.2, .6, .2, 1);
}
@media (hover: hover) {
    body.jp-home .jp-gal .work-item:hover img { transform: scale(1.05); }
}
/* THE LINK LIVES INSIDE .work-info.
   Hiding that layer - it holds Salient's caption, which is empty here - made
   every gallery image unclickable, while a scripted click still opened the
   lightbox and reported a pass. The layer stays, stretched and transparent,
   with only its caption text removed. */
body.jp-home .jp-gal .work-info {
    display: block !important;
    position: absolute;
    inset: 0;
    z-index: 3;
    background: none;
    padding: 0;
}
body.jp-home .jp-gal .work-info .vert-center,
body.jp-home .jp-gal .work-info h3,
body.jp-home .jp-gal .work-info p,
body.jp-home .jp-gal .work-info .post-title,
body.jp-home .jp-gal .work-info a > span { display: none !important; }

body.jp-home .jp-gal .work-info a {
    position: absolute;
    inset: 0;
    display: block;
    cursor: zoom-in;
    font-size: 0;
}

/* Something has to say the tile opens. A scrim and a magnifier on hover, and a
   visible focus ring for the keyboard. */
body.jp-home .jp-gal .work-info-bg {
    display: block !important;
    position: absolute;
    inset: 0;
    z-index: 2;
    background: rgba(5, 7, 10, .45);
    opacity: 0;
    transition: opacity .3s ease;
    pointer-events: none;
}
body.jp-home .jp-gal .work-item::after {
    content: "";
    position: absolute;
    left: 50%;
    top: 50%;
    width: 44px;
    height: 44px;
    z-index: 4;
    transform: translate(-50%, -50%) scale(.8);
    border-radius: 50%;
    background: var(--jp-orange) var(--jp-i-zoom) center / 20px 20px no-repeat;
    opacity: 0;
    transition: opacity .3s ease, transform .3s ease;
    pointer-events: none;
}
@media (hover: hover) {
    body.jp-home .jp-gal .work-item:hover .work-info-bg { opacity: 1; }
    body.jp-home .jp-gal .work-item:hover::after { opacity: 1; transform: translate(-50%, -50%) scale(1); }
}
body.jp-home .jp-gal .work-info a:focus-visible { outline: 3px solid var(--jp-orange); outline-offset: -3px; }

/* The photographs need air under the heading; the gallery element brings no top
   margin of its own and sat right on top of it. */
body.jp-home .jp-ip--gal .jp-gal { margin-top: clamp(30px, 3.5vw, 46px) !important; }

/* A gallery is the client's whole folder - 20 photographs on loft boarding, 66
   on ladders and hatches - and Salient gives a phone one column, which makes
   that page an endless ribbon of pictures. Two across on a phone halves the
   scroll and a ~165px thumbnail is still easy to pick out; these tiles exist to
   open the lightbox, not to be read in the grid.

   The width is all that changes. Salient pays for its gutters with a negative
   margin on the row and a matching padding on each item, so touching anything
   else here pushes every tile past the edge of the screen - which it did once. */
/* The two short galleries - six on insulation removal, three on loft
   insulation - are set three across instead of four, or the last row ends in a
   hole. That makes their tiles .span_4, so the phone rule has to name both or
   those two pages drop to a 33% thumbnail no one can make out. */
@media only screen and (max-width: 690px) {
    body.jp-home .jp-gal .portfolio-items .col.span_3,
    body.jp-home .jp-gal .portfolio-items .col.span_4 { width: 50% !important; }
}

/* The proof strip on Spray Foam Removal: two lines the client asked for, in
   their words, "make it stand out". A dark panel between the explanation and
   the process, the two statements side by side, the numerals in orange - the
   same highlight the design gives one word of a headline. Nothing else on the
   page is set this large in a card, which is what makes it stand out without
   shouting. */
body.jp-home .jp-ip--proof > .row_col_wrap_12 > .jp-panel--dark > .vc_column-inner {
    padding: clamp(28px, 3.4vw, 44px) clamp(24px, 3vw, 40px) !important;
    border: 1px solid rgba(240, 132, 36, .35);
}
/* The authoritative heading block (body.jp-site .wpb_wrapper .jp-h3) pins every
   h3 at 1.32rem with !important - the round-1 trap - so this has to outrank it
   or the strip sets at card-title size and stands out from nothing. */
body.jp-site .jp-ip--proof .wpb_wrapper .jp-h3 {
    font-size: clamp(22px, 2.05vw, 30px) !important;
    line-height: 1.25 !important;
    margin: 0 !important;
}
body.jp-home .jp-ip--proof .jp-h3 .jp-hi {
    font-size: 1.35em;
    line-height: 1;
}
/* the two halves read as a pair: a hairline between them on a wide screen,
   and a little air when they stack */
@media (min-width: 1000px) {
    body.jp-home .jp-ip--proof .jp-ip__half:first-child > .vc_column-inner {
        border-right: 1px solid rgba(255, 255, 255, .12);
    }
}
@media (max-width: 999px) {
    body.jp-home .jp-ip--proof .jp-ip__half + .jp-ip__half { margin-top: 18px; }
}
body.jp-home .jp-ip--gal .jp-h2 { margin-bottom: 0; }

/* The gallery is a full-width band of photographs, so its head is centred over
   them rather than hanging off the left edge. */
body.jp-home .jp-ip--gal .jp-eyebrow p,
body.jp-home .jp-ip--gal .jp-h2,
body.jp-home .jp-ip--gal .jp-lead p { text-align: center; }
body.jp-home .jp-ip--gal .jp-lead p { margin-left: auto; margin-right: auto; }

/* ---- the contact page form ---------------------------------------------- */
body.jp-home .jp-ip .jp-form__title { margin-bottom: 0 !important; }
body.jp-home .jp-form__legal p {
    color: var(--jp-mute);
    font-size: .84rem;
    text-align: center;
    margin: 14px 0 0;
}
/* The note beside a section heading is a PARAGRAPH in a flex row, so without a
   cap it claims its full natural width - measured 1100px inside a 1064px panel,
   i.e. it overflowed. The homepage's own note column carries the same cap. */
body.jp-home .jp-head__notecol { flex: 0 1 auto; max-width: 360px; }
body.jp-home .jp-head__note p { color: var(--jp-body); font-size: 1rem; margin: 0; }

/* ---- stacking ------------------------------------------------------------
   Below the split point the photograph leads and the badge comes back inside
   the frame, where at this width it would otherwise hang off the edge. */
@media (max-width: 999px) {
    body.jp-home .jp-ph .jp-about__badge { bottom: 12px; left: 12px; }
    body.jp-home .jp-ph .jp-lead p { max-width: none; }
}
@media (max-width: 690px) {
    body.jp-home .jp-panel > .vc_column-inner { border-radius: 22px; }
    body.jp-home .jp-ip .jp-grid--m320 > .row_col_wrap_12_inner { grid-column-gap: 16px; }
}

/* ==========================================================================
   24  AUTHORITATIVE HEADING BLOCK

   THIS MUST STAY LAST IN THE FILE.

   Salient overrides EVERY heading below 999px from salient-dynamic-styles.css
   with rules shaped like:

       .wpb_wrapper h2.vc_custom_heading { font-size: 26px !important }

   That selector is (0,2,1). A plain `.jp-h2 { font-size: X !important }` is
   (0,1,0) and LOSES, because specificity compares class count before element
   count - so an !important of our own is not enough. Writing them as
   `.jp-site .wpb_wrapper .jp-h2` makes them (0,3,0), which wins on class count
   alone, at every viewport, without fighting !important.

   Salient's responsive h1 rule is additionally id-scoped, which is how one
   fragment of a split headline can silently render at a different size from
   its siblings. font-size and line-height therefore carry !important on the
   shared fragment class as well.
   ========================================================================== */

body.jp-site .wpb_wrapper .jp-h1,
body.jp-site .wpb_wrapper .jp-h2,
body.jp-site .wpb_wrapper .jp-h3,
body.jp-site .wpb_wrapper .jp-h4 {
    font-family: var(--jp-display) !important;
    line-height: 1.08 !important;
    letter-spacing: -.025em;
    text-wrap: balance;
}

body.jp-site .wpb_wrapper .jp-h1 {
    color: #fff;
    font-size: clamp(2.4rem, 5.4vw, 4.35rem) !important;
    font-weight: 800 !important;
    margin: 0 !important;   /* inline: see .jp-hero__badge margin-bottom */
}
/* The design's headline is two-tone: the second half is the accent orange. It
   has to be declared HERE, at the same (0,3,0) weight as the white above it. */
body.jp-site .wpb_wrapper .jp-h1--b { color: var(--jp-orange); }

body.jp-site .wpb_wrapper .jp-h2 {
    font-size: clamp(1.95rem, 3.7vw, 2.95rem) !important;
    font-weight: 700 !important;
    color: var(--jp-fg);
    margin: 14px 0 0 !important;
}
body.jp-site .wpb_wrapper .jp-h2--light { color: #fff; font-size: clamp(1.85rem, 3.4vw, 2.7rem) !important; margin-top: 16px !important; }
/* The steps section is on black now, so its heading and card titles are white.
   Declared HERE and not beside the section, because this block is last in the
   file and a plain `.jp-h2` colour set up there weighs the same and loses on
   source order.

   Note the ORDER inside the selector: .jp-steps is the ROW and .wpb_wrapper is
   inside it, not the other way round. Written as `.wpb_wrapper .jp-steps` it
   matches nothing at all, and the heading stayed black on a black band. */
/* Inner-page headings. Declared HERE for the reason this block exists: a size
   or colour set beside the section loses to the generic .jp-h1 / .jp-h2 rules
   below, which are last in the file and weigh the same.

   The inner-page h1 is smaller than the homepage's. That headline is a full
   screen banner with nothing above it; these sit under a breadcrumb with the
   page's body copy directly beneath, and at the homepage's 4.35rem they
   swamped it. */
body.jp-site .jp-ph .wpb_wrapper .jp-ph__h {
    font-size: clamp(2rem, 3.6vw, 2.9rem) !important;
    margin: 0 !important;
    color: #fff;
}
body.jp-site .jp-fc .wpb_wrapper .jp-fc__title {
    font-size: 1.06rem !important;
    margin: 0 0 8px !important;
    color: var(--jp-fg);
}

body.jp-site .jp-steps .wpb_wrapper .jp-h2,
body.jp-site .jp-steps .wpb_wrapper .jp-step__title { color: #fff; }
body.jp-site .jp-steps .jp-step--dark .wpb_wrapper .jp-step__title { color: var(--jp-fg); }
body.jp-site .wpb_wrapper .jp-h2--areas { font-size: clamp(1.8rem, 3.2vw, 2.5rem) !important; }
body.jp-home .jp-about__copy .jp-h2 { font-size: clamp(1.9rem, 3.5vw, 2.75rem) !important; }
body.jp-home .jp-contact__info .jp-h2 { font-size: clamp(1.9rem, 3.5vw, 2.7rem) !important; }

body.jp-site .wpb_wrapper .jp-h3 {
    font-size: 1.32rem !important;
    font-weight: 700 !important;
    color: var(--jp-fg);
    margin: 0 !important;
}
body.jp-site .wpb_wrapper .jp-step__title { font-size: 1.24rem !important; margin: 14px 0 10px !important; }
body.jp-site .wpb_wrapper .jp-rev__title  { font-size: 1.14rem !important; margin: 16px 0 10px !important; }
body.jp-home .jp-step--dark .jp-step__title { color: #fff; }

/* Per-context heading MARGINS belong in this block too. Set anywhere earlier
   they are silently reset by the (0,3,0) `margin: 0 !important` above, which is
   exactly the trap this block exists to describe - it applies to the
   stylesheet's own rules, not just Salient's. */
body.jp-site .jp-card .wpb_wrapper .jp-h3 { margin: 26px 24px 0 !important; }

body.jp-site .wpb_wrapper .jp-h4 {
    font-size: 1.02rem !important;
    font-weight: 700 !important;
    color: var(--jp-fg);
    margin: 0 !important;
}
/* Three headings the design renders as plain divs inheriting a local
   line-height, not as headings on the 1.08 display leading. Matching the
   design means stating each one. */
body.jp-site .wpb_wrapper .jp-sf__cardtitle { font-size: 1rem !important; font-weight: 800 !important; line-height: 1.3 !important; }
body.jp-site .wpb_wrapper .jp-pt__title { line-height: 1.6 !important; }
body.jp-site .wpb_wrapper .jp-about__badgetitle {
    font-size: 1.4rem !important;
    font-weight: 800 !important;
    line-height: 1.1 !important;
    color: #fff;
}


/* ==========================================================================
   25  ANCHOR OFFSETS AND THE OFF-CANVAS / MOBILE-BAR HANDOFF

   Appended after the heading block on purpose: these are layout offsets, not
   heading sizes, so they do not disturb the specificity argument above.

   The header is sticky, so an anchor link would otherwise land its target
   underneath it. scroll-margin-top does this in CSS with no scroll handler.
   Top bar 44px + header clamp(72px,7vw,92px), plus a little air.
   ========================================================================== */

body.jp-site [id] { scroll-margin-top: calc(44px + var(--jp-head-h) + 12px); }

/* The fixed mobile bar and Salient's off-canvas panel both own the bottom of
   the screen. jp-site.js marks the body while the panel is open. */
body.jp-site.jp-ocm-open .jp-mobar { display: none !important; }

/* The WhatsApp plugin is standalone and knows nothing about this theme, so the
   theme moves it clear of its own fixed mobile bar rather than the plugin
   hard-coding an offset for a bar that may not exist. */
@media (max-width: 1080px) {
    body.jp-site .jp-wa { bottom: 82px; }
    body.jp-site .jp-wa__card { bottom: 128px; }
}


/* ==========================================================================
   26  SIDE POPS  (Facebook / Checkatrade / MyBuilder edge tabs)

   After the heading block on purpose, like block 25: nothing here styles a
   heading, so the specificity argument up there is undisturbed.

   Second pass, at the client's request: the first cut used the old site's
   68x241 PNG tabs and read as pasted-on. These are typeset pull-tabs at half
   that footprint - brand colours kept so each one is recognised at a glance,
   but the radii, shadow, type and hover manners come from this design.

   Behaviour is unchanged: facebook and MyBuilder are links out, the
   Checkatrade tab slides its score card out on hover (and on keyboard focus,
   which the old PNG version never offered). The card no longer shunts the
   tab aside as the 2020 build did - it emerges beside it, which is calmer
   and keeps the tab under the pointer.

   Still hidden below 1240px, the old site's own cutoff - on smaller screens
   the mobile bar and the WhatsApp button already own the edges. z-index
   stays below the header stack (Salient starts that at 1000).
   ========================================================================== */

body.jp-site .jp-pop {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    padding: 15px 0;
    cursor: pointer;
    text-decoration: none !important;
    box-shadow: 0 8px 22px rgba(0, 0, 0, .35);
    transition: transform .18s ease, filter .18s ease;
}
body.jp-site .jp-pop__label {
    writing-mode: vertical-rl;
    transform: rotate(180deg);   /* reads bottom-to-top, as the old tabs did */
    font-family: var(--jp-text);
    font-size: .74rem;
    font-weight: 700;
    letter-spacing: .05em;
    line-height: 1;
    color: #fff;
    white-space: nowrap;
}

/* facebook, on the left edge: rounded on its inner (right) corners only, so
   it reads as a tab pulled in from outside the viewport. */
body.jp-site .jp-pop--fb {
    position: fixed;
    left: 0;
    top: 200px;
    z-index: 590;
    background: #1877F2;
    border-radius: 0 10px 10px 0;
}
body.jp-site .jp-pop--fb:hover { transform: translateX(2px); filter: brightness(1.12); }

/* the right-edge pair stack in one fixed column, so their gap is stated once
   and adding a third tab someday is a one-line job */
body.jp-site .jp-pops__right {
    position: fixed;
    right: 0;
    top: 200px;
    z-index: 590;
    display: flex;
    flex-direction: column;
    gap: 8px;
}
body.jp-site .jp-pops__right .jp-pop { border-radius: 10px 0 0 10px; }

body.jp-site .jp-pop--ct { background: #E2231A; }
body.jp-site .jp-pop--mb { background: #3D87CE; }
body.jp-site .jp-pop--mb:hover { transform: translateX(-2px); filter: brightness(1.1); }
body.jp-site .jp-pop--ct:hover,
body.jp-site .jp-pop--ct:focus { filter: brightness(1.1); }
body.jp-site .jp-pop:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }

/* The score card. A fixed child, NOT a transformed one: a transform on the
   tab would become the fixed panel's containing block mid-hover and make it
   jump, which is why the ct tab brightens instead of translating. The card
   emerges to sit beside the tab, restyled as a card of this design: white
   ground, soft radius, deep shadow, the artwork rounded inside it. */
body.jp-site .jp-pop--ct .jp-pop__panel {
    position: fixed;
    top: 200px;
    right: -340px;
    width: 300px;
    z-index: 591;
    padding: 8px;
    background: #fff;
    border-radius: 16px;
    box-shadow: 0 24px 60px rgba(0, 0, 0, .5);
    opacity: 0;
    transition: right .3s ease, opacity .25s ease;
}
body.jp-site .jp-pop--ct .jp-pop__panel img {
    display: block;
    width: 100%;
    height: auto;
    border-radius: 10px;
}
body.jp-site .jp-pop--ct:hover .jp-pop__panel,
body.jp-site .jp-pop--ct:focus .jp-pop__panel,
body.jp-site .jp-pop--ct:focus-within .jp-pop__panel {
    right: 42px;
    opacity: 1;
}

@media (max-width: 1239px) {
    body.jp-site .jp-pops { display: none; }
}
