/* Service heroes for the sub-service pages. One component, three variants.
   Every selector is scoped under .svsh. No bare element selectors, no :root.

   The theme header (#reactheme-header .sticky-wrapper) is position:absolute and
   paints over this section, so the hero's field starts at y=0 and runs flush
   behind it - there is no white band and no top margin anywhere. --svsh-pad-top
   is header clearance for the COPY only; the measured header is ~170px tall.

   --svsh-field and --svsh-photopos are set per page as inline custom properties
   by render.php, from config.php.

   VARIANT A - wall extension. The photo has a flat, evenly-lit field on one side
   (measured per-column luma stddev 0.58-1.64 over the left 35%). That colour is
   the section background, so the photo's masked edge dissolves into the page.

   VARIANT B - scrim. No flat region, but the copy side is soft and bright. A
   gradient of the field colour veils it; opacity is set so the darkest pixel
   under the text still clears AA.

   VARIANT C - split field. The photo takes one half, full-bleed to the section
   edge with no frame; a solid field carries the copy on the other half. */

.svsh{
  --svsh-accent:#F64A00;
  --svsh-accent-deep:#D64000;
  --svsh-ink:#1A1A1A;
  --svsh-body:#3A4250;
  --svsh-ease:cubic-bezier(.4,0,.2,1);
  --svsh-gutter:max(24px, calc((100vw - 1320px) / 2));
 /* Measured header totals: 163px at 1920/1440, 143px at 1200, 200px at 1025,
    93px at 1023, 43px at 767, 96px at 375 - the nav wraps, so this is not a
    clean function of breakpoint. hero.js overwrites both properties with the
    real numbers; these statics only have to be right before it runs.
    --svsh-above is the space actually consumed above the hero. It is the header
    height while the header is in flow, and 0 once waypoints-sticky.min.js has
    wrapped it in the absolutely-positioned .sticky-wrapper. */
  --svsh-header:163px;
  --svsh-above:163px;
  --svsh-clear:max(0px, calc(var(--svsh-header) - var(--svsh-above)));
  /* No cap: the hero fills the viewport below the header, so the next section never
     appears on first paint and the media box stays tall enough that cover does not
     have to crop the photograph hard on wide screens. */
  --svsh-fill:calc(100vh - var(--svsh-above));
  --svsh-fill:calc(100dvh - var(--svsh-above));
  --svsh-pad-top:calc(var(--svsh-clear) + 28px);
  --svsh-pad-bottom:96px;
  --svsh-colw:min(34%, 470px);
  position:relative;
  display:block;
  box-sizing:border-box;
  margin:0;
  background:var(--svsh-field, #FAF7F5);
  color:var(--svsh-ink);
  overflow:hidden;
  isolation:isolate;
  font-family:"DM Sans",system-ui,-apple-system,"Segoe UI",Arial,sans-serif;
}
.svsh *,
.svsh *::before,
.svsh *::after{box-sizing:border-box;}

/* ---------------- media ----------------
   Absolutely positioned in A and B, so it contributes nothing to layout and
   cannot shift it: CLS from the image is structurally zero. */
/* No border, radius, shadow, outline, margin or padding on the media or the
   image - nothing that could draw an edge. object-fit is cover, never contain:
   contain is what produces letterbox bands. */
.svsh .svsh__media{
  position:absolute;inset:0;z-index:0;pointer-events:none;
  margin:0;padding:0;border:0;border-radius:0;box-shadow:none;outline:0;overflow:hidden;
}
.svsh .svsh__media picture{display:block;width:100%;height:100%;margin:0;padding:0;border:0;}
.svsh .svsh__media img{
  display:block;
  width:100%;
  height:100%;
  max-width:none;
  object-fit:cover;
  object-position:var(--svsh-photopos, center center);
  margin:0;padding:0;border:0;border-radius:0;box-shadow:none;outline:0;
}

/* ---------------- layout ---------------- */
.svsh .svsh__inner{
  position:relative;
  z-index:2;
  display:flex;
  min-height:var(--svsh-fill);
  padding:var(--svsh-pad-top) var(--svsh-gutter) var(--svsh-pad-bottom);
  align-items:center;
}
.svsh.svsh--copy-right .svsh__inner{justify-content:flex-end;}
.svsh .svsh__content{
  width:var(--svsh-colw);
  min-width:0;
  animation:svshIn 400ms var(--svsh-ease) both;
}

/* ---------------- A: wall extension ----------------
   These four are 2011x782 banner graphics (ratio 2.572) built with an empty
   left field for text. Measured: the field is flat to source x 845 (42%,
   per-column luma stddev 0.58-1.64), and dark subject content runs all the way
   to x 2010 - so the image cannot be cropped on either side without damage.

   It is therefore shown at its NATURAL aspect, full width, anchored to the
   bottom, and never object-fit cropped. When the copy makes the section taller
   than the banner, the extra height is field colour above it. On the left that
   is the banner's own colour, so nothing shows; on the right the banner's top
   row deviates from the field by up to 208/255, so the top edge is feathered
   over 16% of the image height rather than butted against the field. */
.svsh.svsh--a .svsh__media{
  position:absolute;
  left:0;
  right:0;
  bottom:0;
  top:auto;
  height:auto;
}
.svsh.svsh--a .svsh__media picture{height:auto;}
.svsh.svsh--a .svsh__media img{
  width:100%;
  height:auto;
  object-fit:fill;
  -webkit-mask-image:linear-gradient(to bottom, rgba(0,0,0,0) 0%, rgba(0,0,0,1) 22%);
          mask-image:linear-gradient(to bottom, rgba(0,0,0,0) 0%, rgba(0,0,0,1) 22%);
}
/* Insurance only: the copy already sits on the banner's own flat field, which is
   the same colour. Released well inside that field, so it cannot show a join. */
.svsh.svsh--a::before{
  content:"";
  position:absolute;
  inset:0;
  z-index:1;
  pointer-events:none;
  background:linear-gradient(to right,
    var(--svsh-field) 0%, var(--svsh-field) 40%,
    rgba(255,255,255,0) 46%);
}


/* ---------------- C: split field ----------------
   Photo occupies one half, bleeding to the section edge. No frame, no radius,
   no shadow. The other half is the solid field. */
/* Full bleed. The image reaches the right and bottom edges of the section and its
   top meets the header line exactly; nothing is inset, so there is no rectangle.
   The join with the copy is made by colour, not by an edge: --svsh-field is
   sampled from a narrow vertical strip down the side of this page's image that
   meets the copy, and the ::before ramp carries that same colour from opaque to
   transparent across --svsh-fade-a..--svsh-fade-b, a band of 200px+ at 1440. */
.svsh.svsh--c .svsh__media{left:var(--svsh-media-left, 38%);right:0;top:var(--svsh-clear);}
.svsh.svsh--c.svsh--copy-right .svsh__media{left:0;right:var(--svsh-media-left, 38%);top:var(--svsh-clear);}
.svsh.svsh--c::before{
  content:"";
  position:absolute;
  left:0;right:0;bottom:0;
  top:var(--svsh-clear);
  z-index:1;
  pointer-events:none;
  background:linear-gradient(to right,
    var(--svsh-field) 0%,
    var(--svsh-field) var(--svsh-fade-a, 38%),
    rgba(0,0,0,0) var(--svsh-fade-b, 44%));
}
.svsh.svsh--c.svsh--copy-right::before{
  background:linear-gradient(to left,
    var(--svsh-field) 0%,
    var(--svsh-field) var(--svsh-fade-a, 38%),
    rgba(0,0,0,0) var(--svsh-fade-b, 44%));
}
/* Left-edge scrim on the photograph itself.
   Used where the image's edge is darker than the field it meets. Rather than
   darkening the page to match the photo, this lifts the photo's edge up into a
   light field: the field colour at full opacity on the image's left edge, fading
   to transparent across --svsh-scrim of the MEDIA BOX width, so the distance
   scales with the image rather than the viewport.
   Width is bounded by the artwork: HR's leftmost card edge sits at source x=49,
   4.3% of the image width, which is 47px at 1440 and 43px at 1024. 5% of the box
   stays inside that at every breakpoint, so the scrim never reaches the card. */
.svsh .svsh__media::after{
  content:"";
  position:absolute;
  inset:0;
  z-index:1;
  pointer-events:none;
  background:linear-gradient(to right,
    var(--svsh-field) 0%,
    rgba(0,0,0,0) var(--svsh-scrim, 0%));
}
.svsh.svsh--copy-right .svsh__media::after{
  background:linear-gradient(to left,
    var(--svsh-field) 0%,
    rgba(0,0,0,0) var(--svsh-scrim, 0%));
}
/* The band layout stacks the image above the copy, so a left-edge scrim is
   meaningless there. */
@media (max-width:1023.98px){
  .svsh .svsh__media::after{display:none;}
}

.svsh.svsh--c .svsh__inner{min-height:var(--svsh-fill);}
.svsh.svsh--a{--svsh-colw:min(41%, 520px);}
.svsh.svsh--a .svsh__inner{min-height:max(calc(38.9vw + var(--svsh-clear)), var(--svsh-fill));} /* = 100vw / 2.572, the banner ratio, so the section is never shorter than the image */
.svsh.svsh--c .svsh__content{width:min(100%, 560px);}

/* ---------------- no photograph ----------------
 Used where a page has no artwork that can be published. A centred editorial
 column: heading, copy and both CTAs on the field at a ~60ch measure, at normal
 content height rather than full viewport, so there is no empty half. Deliberately
 NOT stretched across the full width - a long measure would read as a fallback and
 is harder to read. Reverts by giving the page an image in config.php. */
.svsh.svsh--no-image::before,
.svsh.svsh--no-image::after{display:none;}
.svsh.svsh--no-image .svsh__inner{
  min-height:0;
  justify-content:center;
  padding:calc(var(--svsh-clear) + 72px) var(--svsh-gutter) 88px;
}
.svsh.svsh--no-image .svsh__content{
  width:100%;
  max-width:60ch;
  margin-inline:auto;
  text-align:center;
}
.svsh.svsh--no-image .svsh__copy{margin-inline:auto;}
.svsh.svsh--no-image .svsh__actions{justify-content:center;}
@media (max-width:767.98px){
  .svsh.svsh--no-image .svsh__inner{padding:calc(var(--svsh-clear) + 48px) 20px 64px;}
}

/* ---------------- type ---------------- */
.svsh .svsh__title{
  margin:0 0 22px;
  padding:0;
  border:0;
  font-family:"Red Hat Display",system-ui,-apple-system,"Segoe UI",Arial,sans-serif;
  font-size:clamp(1.9rem, 1.05rem + 2.3vw, 3rem);
  line-height:1.12;
  font-weight:800;
  letter-spacing:-.02em;
  color:var(--svsh-ink);
  text-transform:none;
  overflow-wrap:break-word;
}
.svsh .svsh__accent{color:var(--svsh-accent);}

/* Optional second heading, used only where the page's hero already had one.
 Sits between the h1 and the body copy; sized between the two so it reads as a
 deck rather than competing with the h1. */
.svsh .svsh__sub{
  margin:0 0 18px;
  padding:0;
  border:0;
  font-family:"Red Hat Display",system-ui,-apple-system,"Segoe UI",Arial,sans-serif;
  font-size:clamp(1.125rem, 1rem + .45vw, 1.4375rem);
  line-height:1.3;
  font-weight:600;
  letter-spacing:-.01em;
  color:var(--svsh-body);
  text-transform:none;
}
.svsh .svsh__copy{margin:0 0 32px;}
.svsh .svsh__copy p{
  margin:0 0 14px;
  padding:0;
  font-size:clamp(1rem, .96rem + .15vw, 1.0625rem);
  line-height:1.62;
  font-weight:400;
  color:var(--svsh-body);
}
.svsh .svsh__copy p:last-child{margin-bottom:0;}
.svsh .svsh__copy span{color:inherit;}

/* ---------------- actions ---------------- */
.svsh .svsh__actions{display:flex;flex-wrap:wrap;gap:14px;margin:0;}
.svsh .svsh__btn{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  padding:16px 30px;
  border:2px solid transparent;
  border-radius:8px;
  font-family:"Red Hat Display",system-ui,-apple-system,"Segoe UI",Arial,sans-serif;
  font-size:1rem;
  line-height:1.2;
  font-weight:700;
  text-decoration:none;
  text-transform:none;
  cursor:pointer;
  transition:background-color .2s var(--svsh-ease), color .2s var(--svsh-ease), border-color .2s var(--svsh-ease);
}
/* Literals, not custom properties: no per-page value can reach these, so the
 primary CTA cannot diverge from page to page. */
.svsh .svsh__btn--primary{
  background:#D64000;
  border-color:#D64000;
  color:#FFFFFF;
}
.svsh .svsh__btn--primary:hover,
.svsh .svsh__btn--primary:focus-visible{background:#B03400;border-color:#B03400;}
.svsh .svsh__btn--secondary{
  background:#FFFFFF;
  /* Border tracks --svsh-accent so it can be darkened where the sampled field
 would otherwise leave it under the 3:1 non-text bar. Text stays literal. */
  border-color:var(--svsh-accent);
  color:#D64000;
}
.svsh .svsh__btn--secondary:hover,
.svsh .svsh__btn--secondary:focus-visible{
  background:#FFF4EE;
  border-color:var(--svsh-accent-deep);
  color:#B03400;
}
.svsh .svsh__btn:focus-visible{outline:3px solid var(--svsh-accent-deep);outline-offset:3px;}

@keyframes svshIn{
  from{opacity:0;transform:translateY(8px);}
  to{opacity:1;transform:translateY(0);}
}

/* ---------------- short viewports ----------------
 Below ~700px tall, forcing the hero to fill would push the CTAs off screen.
 Legibility beats filling: height goes auto. Variant A still has to be tall
 enough for its banner, which is sized off viewport WIDTH, not height. */
@media (max-height:699.98px){
  .svsh{--svsh-pad-top:calc(var(--svsh-clear) + 6px);--svsh-pad-bottom:40px;}
  .svsh .svsh__inner,
  .svsh.svsh--c .svsh__inner{min-height:0;}
  /* Variant A's banner is sized off viewport WIDTH (38.9vw = 560px at 1440), so
     on a wide-but-short screen it alone exceeds the fold before any copy. Let
     the section go content-driven here too and allow the banner to clip at the
     top: its top 22% is the feathered flat field, so nothing is lost, and the
     CTAs come back above the fold. */
  .svsh.svsh--a .svsh__inner{min-height:0;}
  /* With the section content-driven, the bottom-anchored banner would rise above
     the header line. Pin its top to the header instead and let it cover-crop
     from the bottom, so the crop eats the flat top field rather than the subject
     and nothing paints over the nav. */
  .svsh.svsh--a .svsh__media{top:var(--svsh-clear);bottom:0;height:auto;}
  .svsh.svsh--a .svsh__media picture{height:100%;}
  .svsh.svsh--a .svsh__media img{width:100%;height:100%;object-fit:cover;object-position:center bottom;}
  /* On a 640px-tall screen a 48px h1 costs about five lines and pushes the CTAs
     under the fold. Smaller heading, CTAs in view - legibility of the action
     beats the size of the headline here. Wide screens are unaffected. */
  .svsh .svsh__title{font-size:clamp(1.5rem, 1rem + 1.4vw, 2.25rem);margin-bottom:12px;}
  .svsh .svsh__sub{margin-bottom:8px;font-size:1.125rem;}
  .svsh .svsh__copy{margin-bottom:16px;}
}

/* ---------------- >=1600: keep the image from scaling up ----------------
 The media box widens with the viewport while the hero height is capped, so cover
 starts enlarging the image and cropping it hard. Measured on Legal: scale 0.84 at
 1440 but 1.17 at 2000, with 309px of vertical crop. Narrowing the box at wide
 viewports keeps the scale at or below 1 and the composition intact. */
@media (min-width:1600px){
  .svsh.svsh--c{--svsh-media-left:46%;}
  .svsh.svsh--c .svsh__inner{--svsh-colw:min(34%, 520px);}
}

/* ---------------- 1024-1199 ---------------- */
@media (max-width:1199.98px) and (min-width:1024px){
  .svsh{--svsh-colw:min(46%, 470px);--svsh-pad-bottom:80px;}
  .svsh .svsh__media img{object-position:78% center;}
  .svsh.svsh--copy-right .svsh__media img{object-position:22% center;}
  .svsh.svsh--c .svsh__media{left:55%;}
  .svsh.svsh--c.svsh--copy-right .svsh__media{right:55%;left:0;}
}

/* ---------------- <1024: image becomes a top band, copy below --------------- */
@media (max-width:1023.98px){
  .svsh{--svsh-pad-top:0px;--svsh-pad-bottom:64px;padding-top:var(--svsh-clear);}
  .svsh .svsh__media,
  .svsh.svsh--c .svsh__media,
  .svsh.svsh--c.svsh--copy-right .svsh__media{
    position:relative;
    inset:auto;
    left:auto;
    right:auto;
    width:100%;
    /* 50vh pushed the CTAs below the fold at 768 on the page carrying both a
       subheading and two paragraphs. Brought into line with the <768 band. */
    height:34vh;
    min-height:240px;
  }
  .svsh.svsh--a::before,
  .svsh.svsh--c::before{display:none;}
  .svsh.svsh--a .svsh__media{position:relative;inset:auto;height:auto;}
  .svsh.svsh--a .svsh__media img{height:auto;-webkit-mask-image:none;mask-image:none;}
  .svsh .svsh__inner{
    display:block;
    min-height:0;
    padding:40px 24px var(--svsh-pad-bottom);
  }
  .svsh.svsh--c .svsh__inner{min-height:0;}
  .svsh .svsh__content,
  .svsh.svsh--c .svsh__content{width:auto;max-width:640px;}
  /* Every one of these photographs has feature labels baked into it. Fitted
     whole into a 375px band that text is unreadable and reads as a fault, so
     the band crops toward the person instead. --svsh-mobpos is the measured
     skin-tone centroid of each image, set per page by render.php. */
  .svsh .svsh__media img{object-position:var(--svsh-mobpos, center center);}
}

/* ---------------- <768: shorter band ---------------- */
@media (max-width:767.98px){
  /* Band height and heading floor are both tuned so the h1, the copy and BOTH
     CTAs clear a 375x812 fold - measured, the previous 38vh band left the
     buttons about 115px below it. */
  .svsh .svsh__media,
  .svsh.svsh--c .svsh__media,
  .svsh.svsh--c.svsh--copy-right .svsh__media{height:22vh;min-height:170px;}
  .svsh .svsh__inner{padding:20px 20px 36px;}
  .svsh .svsh__title{font-size:clamp(1.6rem, 1.05rem + 2.3vw, 3rem);margin-bottom:10px;}
  .svsh .svsh__sub{font-size:1rem;margin-bottom:8px;}
  .svsh .svsh__copy{margin-bottom:16px;}
  .svsh .svsh__copy p{margin-bottom:10px;}
}

/* ---------------- <400: buttons full width, stacked ---------------- */
@media (max-width:399.98px){
  .svsh .svsh__actions{flex-direction:column;align-items:stretch;gap:12px;}
  .svsh .svsh__btn{width:100%;padding:15px 20px;}
}

@media (prefers-reduced-motion:reduce){
  .svsh .svsh__content{animation:none;}
  .svsh .svsh__btn{transition:none;}
}